@@ -369,15 +369,22 @@ struct TxFifo {
369
369
uint32_t num ;
370
370
};
371
371
372
+ enum CmdState {
373
+ CMD_SCHEDULED , /* command scheduled for execution, not yet handled */
374
+ CMD_ONGOING , /* command is being executed, not yet completed */
375
+ CMD_EXECUTED , /* commmand has been executed, need to be popped out */
376
+ };
377
+
372
378
/**
373
379
* Command FIFO stores commands alongs with SPI device configuration.
374
- * To fit into 64-bit word, limit supported CS lines down to 64K rather than 4G.
380
+ * To fit into 64-bit word, limit supported CS lines down to 256 rather than 4G,
381
+ * and use "int8_t" for command state.
375
382
*/
376
383
typedef struct {
377
384
uint32_t opts ; /* configopts */
378
385
uint16_t command ; /* command[15:0] */
379
386
uint8_t csid ; /* csid[7:0] */
380
- bool ongoing ; /* command is being processed */
387
+ int8_t state ; /* enum CmdState */
381
388
} CmdFifoSlot ;
382
389
383
390
static_assert (sizeof (TxFifoSlot ) == sizeof (uint64_t ),
@@ -751,6 +758,10 @@ static void ot_spi_host_step_fsm(OtSPIHostState *s, const char *cause)
751
758
s -> fsm .active = true;
752
759
ot_spi_host_update_event (s );
753
760
761
+ if (headcmd -> state == CMD_EXECUTED ) {
762
+ goto post ;
763
+ }
764
+
754
765
uint32_t command = (uint32_t )headcmd -> command ;
755
766
bool read = ot_spi_host_is_rx (command );
756
767
bool write = ot_spi_host_is_tx (command );
@@ -812,7 +823,7 @@ static void ot_spi_host_step_fsm(OtSPIHostState *s, const char *cause)
812
823
length -- ;
813
824
}
814
825
815
- bool ongoing ;
826
+ int8_t cmd_state ;
816
827
if (length ) {
817
828
/* if the transfer early ended, a stall condition has been detected */
818
829
if (write && txfifo_is_empty (s -> tx_fifo )) {
@@ -825,15 +836,16 @@ static void ot_spi_host_step_fsm(OtSPIHostState *s, const char *cause)
825
836
}
826
837
827
838
command = FIELD_DP32 (command , COMMAND , LEN , length - 1 );
828
- ongoing = true ;
839
+ cmd_state = CMD_ONGOING ;
829
840
} else {
830
841
command = FIELD_DP32 (command , COMMAND , LEN , 0 );
831
- ongoing = false ;
842
+ cmd_state = CMD_EXECUTED ;
832
843
}
833
844
834
845
headcmd -> command = (uint16_t )command ;
835
- headcmd -> ongoing = ongoing ;
846
+ headcmd -> state = cmd_state ;
836
847
848
+ post :
837
849
ot_spi_host_update_regs (s );
838
850
839
851
timer_mod_anticipate (s -> fsm_delay , qemu_clock_get_ns (OT_VIRTUAL_CLOCK ) +
@@ -863,11 +875,11 @@ static void ot_spi_host_post_fsm(void *opaque)
863
875
864
876
CmdFifoSlot * headcmd = cmdfifo_peek (s -> cmd_fifo );
865
877
uint32_t command = (uint32_t )headcmd -> command ;
866
- bool ongoing = headcmd -> ongoing ;
878
+ bool retire = headcmd -> state == CMD_EXECUTED ;
867
879
868
880
ot_spi_host_trace_status (s -> ot_id , "P>" , ot_spi_host_get_status (s ));
869
881
870
- if (! ongoing ) {
882
+ if (retire ) {
871
883
if (ot_spi_host_is_rx (command )) {
872
884
/*
873
885
* transfer has been completed, RX FIFO may need padding up to a
@@ -897,11 +909,11 @@ static void ot_spi_host_post_fsm(void *opaque)
897
909
898
910
ot_spi_host_trace_status (s -> ot_id , "P<" , ot_spi_host_get_status (s ));
899
911
900
- if (! ongoing ) {
912
+ if (retire ) {
901
913
/* last command has completed */
902
914
if (!cmdfifo_is_empty (s -> cmd_fifo )) {
903
915
/* more commands have been scheduled */
904
- trace_ot_spi_host_debug (s -> ot_id , "Next cmd" );
916
+ trace_ot_spi_host_debug (s -> ot_id , "next cmd" );
905
917
if (!ot_spi_host_is_on_error (s )) {
906
918
ot_spi_host_step_fsm (s , "post" );
907
919
} else {
@@ -1152,7 +1164,7 @@ static void ot_spi_host_io_write(void *opaque, hwaddr addr, uint64_t val64,
1152
1164
.opts = s -> config_opts [csid ],
1153
1165
.command = (uint16_t )val32 , /* only b15..b0 are meaningful */
1154
1166
.csid = csid ,
1155
- .ongoing = false ,
1167
+ .state = CMD_SCHEDULED ,
1156
1168
};
1157
1169
1158
1170
bool activate = cmdfifo_is_empty (s -> cmd_fifo ) && !s -> fsm .rx_stall &&
0 commit comments