Skip to content

Commit 74d9a07

Browse files
committed
[ot] Update OpenTitan EDN SW_CMD_STS behavior
1 parent 7897936 commit 74d9a07

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

hw/opentitan/ot_edn.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,17 @@ typedef enum {
197197
EDN_ERROR, /* illegal state reached and hang */
198198
} OtEDNFsmState;
199199

200+
typedef enum {
201+
CSRNG_STATUS_SUCCESS,
202+
CSRNG_STATUS_INVALID_ACMD,
203+
CSRNG_STATUS_INVALID_GEN_CMD,
204+
CSRNG_STATUS_INVALID_CMD_SEQ,
205+
CSRNG_STATUS_RESEED_CNT_EXCEEDED,
206+
} OtCSRNGCmdStatus;
207+
200208
typedef struct {
201209
OtCSRNGState *device; /* CSRNG instance */
210+
OtCSRNGCmdStatus last_cmd_status; /* status of the last CSRNG command */
202211
qemu_irq genbits_ready; /* Set when ready to receive entropy */
203212
uint32_t appid; /* unique HW application id to identify on CSRNG */
204213
bool instantiated; /* instantiated state, not yet uninstantiated */
@@ -234,7 +243,6 @@ struct OtEDNState {
234243
uint32_t *regs;
235244

236245
unsigned reseed_counter; /* track remaining requests before reseeding */
237-
bool last_cmd_failed; /* status of the last CSRNG command */
238246
bool sw_cmd_ready; /* ready to receive command in SW port mode */
239247
OtEDNFsmState state; /* Main FSM state */
240248
OtEDNCSRNG rng;
@@ -440,12 +448,12 @@ static OtCsrngCmd ot_edn_get_last_csrng_command(OtEDNState *s)
440448
}
441449
}
442450

443-
static bool ot_edn_is_cmd_rdy(OtEDNState *s)
451+
static bool ot_edn_is_cmd_rdy(OtEDNState *s, bool check_fifo)
444452
{
445453
if (!ot_edn_is_enabled(s)) {
446454
return false;
447455
}
448-
if (ot_fifo32_is_full(&s->rng.sw_cmd_fifo)) {
456+
if (check_fifo && ot_fifo32_is_full(&s->rng.sw_cmd_fifo)) {
449457
return false;
450458
}
451459
switch (s->state) {
@@ -508,6 +516,7 @@ static int ot_edn_push_csrng_request(OtEDNState *s)
508516
&ot_edn_fill_bits, s);
509517
g_assert(c->genbits_ready);
510518
}
519+
s->regs[R_SW_CMD_STS] |= R_SW_CMD_STS_CMD_ACK_MASK;
511520
int res = ot_csrng_push_command(c->device, c->appid, c->buffer);
512521
if (res) {
513522
xtrace_ot_edn_error(c->appid, "CSRNG rejected command");
@@ -834,7 +843,7 @@ static void ot_edn_clean_up(OtEDNState *s, bool discard_requests)
834843

835844
c->instantiated = false;
836845
s->sw_cmd_ready = false;
837-
s->last_cmd_failed = false;
846+
s->rng.last_cmd_status = CSRNG_STATUS_SUCCESS;
838847
s->reseed_counter = 0;
839848
memset(c->buffer, 0, sizeof(*c->buffer));
840849
ot_fifo32_reset(&c->bits_fifo);
@@ -994,7 +1003,8 @@ static void ot_edn_csrng_ack_irq(void *opaque, int n, int level)
9941003
*/
9951004
memset(c->buffer, 0, sizeof(*c->buffer));
9961005

997-
s->last_cmd_failed = level != 0;
1006+
c->last_cmd_status =
1007+
level != 0 ? CSRNG_STATUS_INVALID_ACMD : CSRNG_STATUS_SUCCESS;
9981008

9991009
if (level) {
10001010
xtrace_ot_edn_error(c->appid, "last command failed");
@@ -1074,12 +1084,15 @@ static uint64_t ot_edn_regs_read(void *opaque, hwaddr addr, unsigned size)
10741084
case R_ERR_CODE_TEST:
10751085
val32 = s->regs[reg];
10761086
break;
1077-
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));
1087+
case R_SW_CMD_STS: {
1088+
uint32_t rdy = (uint32_t) ot_edn_is_cmd_rdy(s, false);
1089+
uint32_t reg_rdy = (uint32_t) 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->rng.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);
10821094
break;
1095+
}
10831096
case R_MAIN_SM_STATE:
10841097
switch (s->state) {
10851098
case EDN_IDLE ... EDN_ERROR:
@@ -1205,6 +1218,7 @@ static void ot_edn_regs_write(void *opaque, hwaddr addr, uint64_t val64,
12051218
s->regs[reg] = val32;
12061219
break;
12071220
case R_SW_CMD_REQ:
1221+
s->regs[R_SW_CMD_STS] &= ~R_SW_CMD_STS_CMD_ACK_MASK;
12081222
/* ignore all sw commands in auto req mode once instantiated */
12091223
if (ot_edn_is_auto_req_mode(s) && c->instantiated) {
12101224
xtrace_ot_edn_dinfo(c->appid, "ignore SW REQ", c->appid);

0 commit comments

Comments
 (0)