Skip to content

Commit 6210ee5

Browse files
committed
[ot] Update OpenTitan EDN SW_CMD_STS behavior
1 parent 325c17a commit 6210ee5

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

hw/opentitan/ot_edn.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,22 @@ struct OtEDNState {
234234
uint32_t *regs;
235235

236236
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 */
238238
bool sw_cmd_ready; /* ready to receive command in SW port mode */
239239
OtEDNFsmState state; /* Main FSM state */
240240
OtEDNCSRNG rng;
241241
OtEDNEndPoint endpoints[ENDPOINT_COUNT_MAX];
242242
OtEndpointQueue ep_requests;
243243
};
244244

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+
245253
static const uint16_t OtEDNFsmStateCode[] = {
246254
[EDN_IDLE] = 0b110000101,
247255
[EDN_BOOT_LOAD_INS] = 0b110110111,
@@ -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->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+
s->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");
@@ -1075,10 +1085,12 @@ static uint64_t ot_edn_regs_read(void *opaque, hwaddr addr, unsigned size)
10751085
val32 = s->regs[reg];
10761086
break;
10771087
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);
10821094
break;
10831095
case R_MAIN_SM_STATE:
10841096
switch (s->state) {
@@ -1205,6 +1217,7 @@ static void ot_edn_regs_write(void *opaque, hwaddr addr, uint64_t val64,
12051217
s->regs[reg] = val32;
12061218
break;
12071219
case R_SW_CMD_REQ:
1220+
s->regs[R_SW_CMD_STS] &= ~R_SW_CMD_STS_CMD_ACK_MASK;
12081221
/* ignore all sw commands in auto req mode once instantiated */
12091222
if (ot_edn_is_auto_req_mode(s) && c->instantiated) {
12101223
xtrace_ot_edn_dinfo(c->appid, "ignore SW REQ", c->appid);

0 commit comments

Comments
 (0)