Skip to content

Commit a246f25

Browse files
committed
[ot] hw/opentitan: ot_spi_device: fix HW command management
Despite the command opcodes being defined in the RTL code, there are never used. What only matters is the index in the matching command info register. Moreover, the CMD_INFO.VALID bit must be enforced for all commands, not only the SW ones. Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
1 parent 97f6846 commit a246f25

File tree

2 files changed

+27
-52
lines changed

2 files changed

+27
-52
lines changed

hw/opentitan/ot_spi_device.c

Lines changed: 26 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* QEMU OpenTitan SPI Device controller
33
*
4-
* Copyright (c) 2023-2024 Rivos, Inc.
4+
* Copyright (c) 2023-2025 Rivos, Inc.
55
*
66
* Author(s):
77
* Emmanuel Blot <eblot@rivosinc.com>
@@ -364,25 +364,10 @@ typedef enum {
364364
READ_QUAD,
365365
READ_DUAL_IO,
366366
READ_QUAD_IO,
367+
HW_COMMAND_COUNT
367368
} SpiDeviceHwCommand;
368369

369-
static const uint8_t SPI_DEVICE_HW_COMMANDS[] = {
370-
/* clang-format off */
371-
[READ_STATUS1] = 0x05u,
372-
[READ_STATUS2] = 0x35u,
373-
[READ_STATUS3] = 0x15u,
374-
[READ_JEDEC] = 0x9fu,
375-
[READ_SFDP] = 0x5au,
376-
[READ_NORMAL] = 0x03u,
377-
[READ_FAST] = 0x0bu,
378-
[READ_DUAL] = 0x3bu,
379-
[READ_QUAD] = 0x6bu,
380-
[READ_DUAL_IO] = 0xbbu,
381-
[READ_QUAD_IO] = 0xebu,
382-
/* clang-format on */
383-
};
384-
385-
#define SPI_DEVICE_CMD_HW_STA_COUNT ARRAY_SIZE(SPI_DEVICE_HW_COMMANDS)
370+
#define SPI_DEVICE_CMD_HW_STA_COUNT ((unsigned)HW_COMMAND_COUNT)
386371
#define SPI_DEVICE_CMD_HW_STA_FIRST 0
387372
#define SPI_DEVICE_CMD_HW_STA_LAST (SPI_DEVICE_CMD_HW_STA_COUNT - 1u)
388373
#define SPI_DEVICE_CMD_HW_CFG_FIRST (R_CMD_INFO_EN4B - R_CMD_INFO_0)
@@ -1123,34 +1108,24 @@ static void ot_spi_device_flash_decode_command(OtSPIDeviceState *s, uint8_t cmd)
11231108
{
11241109
SpiDeviceFlash *f = &s->flash;
11251110

1126-
/* search command slot in HW-handling commands (static group) */
11271111
if (f->state == SPI_FLASH_IDLE) {
1128-
for (unsigned ix = 0; ix < SPI_DEVICE_CMD_HW_STA_COUNT; ix++) {
1129-
if (cmd == SPI_DEVICE_HW_COMMANDS[ix]) {
1130-
f->type = SPI_FLASH_CMD_HW_STA;
1131-
f->slot = ix;
1132-
f->cmd_info = SHARED_FIELD_DP32(s->spi_regs[R_CMD_INFO_0 + ix],
1133-
CMD_INFO_OPCODE, cmd);
1134-
trace_ot_spi_device_flash_new_command("HW", cmd, f->slot);
1135-
break;
1136-
}
1137-
}
1138-
}
1139-
1140-
/* search command in other slots */
1141-
if (f->state == SPI_FLASH_IDLE) {
1142-
for (unsigned ix = SPI_DEVICE_CMD_HW_STA_COUNT;
1112+
for (unsigned ix = 0;
11431113
ix < PARAM_NUM_CMD_INFO + SPI_DEVICE_CMD_HW_CFG_COUNT; ix++) {
11441114
uint32_t val32 = s->spi_regs[R_CMD_INFO_0 + ix];
1145-
if (cmd == SHARED_FIELD_EX32(val32, CMD_INFO_OPCODE)) {
1115+
if (cmd == (uint8_t)SHARED_FIELD_EX32(val32, CMD_INFO_OPCODE)) {
11461116
if (SHARED_FIELD_EX32(val32, CMD_INFO_VALID)) {
1147-
f->type = ix < PARAM_NUM_CMD_INFO ? SPI_FLASH_CMD_SW :
1148-
SPI_FLASH_CMD_HW_CFG;
1117+
f->type =
1118+
ix < SPI_DEVICE_CMD_HW_STA_COUNT ?
1119+
SPI_FLASH_CMD_HW_STA :
1120+
(ix < PARAM_NUM_CMD_INFO ? SPI_FLASH_CMD_SW :
1121+
SPI_FLASH_CMD_HW_CFG);
11491122
f->slot = ix;
11501123
f->cmd_info = val32;
11511124
trace_ot_spi_device_flash_new_command(
1152-
f->type == SPI_FLASH_CMD_SW ? "SW" : "HW_CFG", cmd,
1153-
f->slot);
1125+
f->type == SPI_FLASH_CMD_HW_STA ?
1126+
"HW" :
1127+
(f->type == SPI_FLASH_CMD_SW ? "SW" : "HW_CFG"),
1128+
cmd, f->slot);
11541129
break;
11551130
}
11561131
trace_ot_spi_device_flash_disabled_slot(cmd, ix);
@@ -1285,24 +1260,24 @@ static void ot_spi_device_flash_decode_hw_static_command(OtSPIDeviceState *s)
12851260
{
12861261
SpiDeviceFlash *f = &s->flash;
12871262

1288-
switch (COMMAND_OPCODE(f->cmd_info)) {
1289-
case 0x05u: /* READ_STATUS_1 */
1290-
case 0x35u: /* READ_STATUS_2 */
1291-
case 0x15u: /* READ_STATUS_3 */
1263+
switch ((int)f->slot) {
1264+
case READ_STATUS1:
1265+
case READ_STATUS2:
1266+
case READ_STATUS3:
12921267
ot_spi_device_flash_decode_read_status(s);
12931268
break;
1294-
case 0x9fu: /* READ_JEDEC */
1269+
case READ_JEDEC:
12951270
ot_spi_device_flash_decode_read_jedec(s);
12961271
break;
1297-
case 0x5au: /* READ_SFDP */
1272+
case READ_SFDP:
12981273
ot_spi_device_flash_decode_read_sfdp(s);
12991274
break;
1300-
case 0x03u: /* READ_NORMAL */
1301-
case 0x0bu: /* READ_FAST */
1302-
case 0x3bu: /* READ_DUAL */
1303-
case 0x6bu: /* READ_QUAD */
1304-
case 0xbbu: /* READ_DUALIO */
1305-
case 0xebu: /* READ_QUADIO */
1275+
case READ_NORMAL:
1276+
case READ_FAST:
1277+
case READ_DUAL:
1278+
case READ_QUAD:
1279+
case READ_DUAL_IO:
1280+
case READ_QUAD_IO:
13061281
ot_spi_device_flash_decode_read_data(s);
13071282
break;
13081283
default:

hw/opentitan/trace-events

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ ot_spi_device_chr_error(const char *err) "%s"
438438
ot_spi_device_flash_byte_unexpected(uint8_t rx) "unexpected byte 0x%02x after completed command"
439439
ot_spi_device_flash_change_state(int line, const char *prev, int preval, const char *next, int nextval) "@%d: %s[%d] -> %s[%d]"
440440
ot_spi_device_flash_cross_buffer(const char *msg, uint32_t addr) "%s 0x%08x"
441-
ot_spi_device_flash_disabled_slot(uint8_t cmd, unsigned slot) "cmd 0x%02x matching disabled slot %u"
441+
ot_spi_device_flash_disabled_slot(uint8_t cmd, unsigned slot) "cmd 0x%02x matched, disabled slot %u"
442442
ot_spi_device_flash_exec(const char *cmd) "%s"
443443
ot_spi_device_flash_ignored_command(const char* msg, uint8_t cmd) "%s cmd 0x%02x"
444444
ot_spi_device_flash_new_command(const char* type, uint8_t cmd, unsigned slot) "%s CMD 0x%02X slot %u"

0 commit comments

Comments
 (0)