@@ -234,14 +234,22 @@ struct OtEDNState {
234
234
uint32_t * regs ;
235
235
236
236
unsigned reseed_counter ; /* track remaining requests before reseeding */
237
- bool last_cmd_failed ; /* status of the last CSRNG command */
237
+ uint8_t last_cmd_status ; /* status of the last CSRNG command */
238
238
bool sw_cmd_ready ; /* ready to receive command in SW port mode */
239
239
OtEDNFsmState state ; /* Main FSM state */
240
240
OtEDNCSRNG rng ;
241
241
OtEDNEndPoint endpoints [ENDPOINT_COUNT_MAX ];
242
242
OtEndpointQueue ep_requests ;
243
243
};
244
244
245
+ enum OtCSRNGCmdStatus {
246
+ CSRNG_STATUS_SUCCESS ,
247
+ CSRNG_STATUS_INVALID_ACMD ,
248
+ CSRNG_STATUS_INVALID_GEN_CMD ,
249
+ CSRNG_STATUS_INVALID_CMD_SEQ ,
250
+ CSRNG_STATUS_RESEED_CNT_EXCEEDED ,
251
+ };
252
+
245
253
static const uint16_t OtEDNFsmStateCode [] = {
246
254
[EDN_IDLE ] = 0b110000101 ,
247
255
[EDN_BOOT_LOAD_INS ] = 0b110110111 ,
@@ -440,12 +448,12 @@ static OtCsrngCmd ot_edn_get_last_csrng_command(OtEDNState *s)
440
448
}
441
449
}
442
450
443
- static bool ot_edn_is_cmd_rdy (OtEDNState * s )
451
+ static bool ot_edn_is_cmd_rdy (OtEDNState * s , bool check_fifo )
444
452
{
445
453
if (!ot_edn_is_enabled (s )) {
446
454
return false;
447
455
}
448
- if (ot_fifo32_is_full (& s -> rng .sw_cmd_fifo )) {
456
+ if (check_fifo && ot_fifo32_is_full (& s -> rng .sw_cmd_fifo )) {
449
457
return false;
450
458
}
451
459
switch (s -> state ) {
@@ -508,6 +516,7 @@ static int ot_edn_push_csrng_request(OtEDNState *s)
508
516
& ot_edn_fill_bits , s );
509
517
g_assert (c -> genbits_ready );
510
518
}
519
+ s -> regs [R_SW_CMD_STS ] |= R_SW_CMD_STS_CMD_ACK_MASK ;
511
520
int res = ot_csrng_push_command (c -> device , c -> appid , c -> buffer );
512
521
if (res ) {
513
522
xtrace_ot_edn_error (c -> appid , "CSRNG rejected command" );
@@ -834,7 +843,7 @@ static void ot_edn_clean_up(OtEDNState *s, bool discard_requests)
834
843
835
844
c -> instantiated = false;
836
845
s -> sw_cmd_ready = false;
837
- s -> last_cmd_failed = false ;
846
+ s -> last_cmd_status = CSRNG_STATUS_SUCCESS ;
838
847
s -> reseed_counter = 0 ;
839
848
memset (c -> buffer , 0 , sizeof (* c -> buffer ));
840
849
ot_fifo32_reset (& c -> bits_fifo );
@@ -994,7 +1003,8 @@ static void ot_edn_csrng_ack_irq(void *opaque, int n, int level)
994
1003
*/
995
1004
memset (c -> buffer , 0 , sizeof (* c -> buffer ));
996
1005
997
- s -> last_cmd_failed = level != 0 ;
1006
+ s -> last_cmd_status =
1007
+ level != 0 ? CSRNG_STATUS_INVALID_ACMD : CSRNG_STATUS_SUCCESS ;
998
1008
999
1009
if (level ) {
1000
1010
xtrace_ot_edn_error (c -> appid , "last command failed" );
@@ -1075,10 +1085,12 @@ static uint64_t ot_edn_regs_read(void *opaque, hwaddr addr, unsigned size)
1075
1085
val32 = s -> regs [reg ];
1076
1086
break ;
1077
1087
case R_SW_CMD_STS :
1078
- val32 =
1079
- FIELD_DP32 (0 , SW_CMD_STS , CMD_STS , (uint32_t )s -> last_cmd_failed );
1080
- val32 = FIELD_DP32 (val32 , SW_CMD_STS , CMD_RDY ,
1081
- (uint32_t )ot_edn_is_cmd_rdy (s ));
1088
+ uint32_t rdy = ot_edn_is_cmd_rdy (s , false);
1089
+ uint32_t reg_rdy = ot_edn_is_cmd_rdy (s , true);
1090
+ val32 = s -> regs [R_SW_CMD_STS ];
1091
+ val32 = FIELD_DP32 (val32 , SW_CMD_STS , CMD_STS , s -> last_cmd_status );
1092
+ val32 = FIELD_DP32 (val32 , SW_CMD_STS , CMD_RDY , rdy );
1093
+ val32 = FIELD_DP32 (val32 , SW_CMD_STS , CMD_REG_RDY , reg_rdy );
1082
1094
break ;
1083
1095
case R_MAIN_SM_STATE :
1084
1096
switch (s -> state ) {
@@ -1205,6 +1217,7 @@ static void ot_edn_regs_write(void *opaque, hwaddr addr, uint64_t val64,
1205
1217
s -> regs [reg ] = val32 ;
1206
1218
break ;
1207
1219
case R_SW_CMD_REQ :
1220
+ s -> regs [R_SW_CMD_STS ] &= ~R_SW_CMD_STS_CMD_ACK_MASK ;
1208
1221
/* ignore all sw commands in auto req mode once instantiated */
1209
1222
if (ot_edn_is_auto_req_mode (s ) && c -> instantiated ) {
1210
1223
xtrace_ot_edn_dinfo (c -> appid , "ignore SW REQ" , c -> appid );
0 commit comments