Skip to content

Commit 0880f1a

Browse files
committed
[ot] hw/opentitan: ot_flash: Fix flash disable behaviour
In the existing flash, if you write to the `DIS` register to disable the flash, it completely removes the ability to read from or write to any of the CSRs. Referencing the documentation: https://opentitan.org/book/hw/top_earlgrey/ip_autogen/flash_ctrl/doc/theory_of_operation.html#flash-access-disable Upon disabling the flash, it should instead finish existing stateful operations, and then give a memory protection error for any further flash protocol controller initiated operations. That is; you should still be able to interact with the registers, but no new flash transactions can be started via the Flash Controller. The host-facing TL-UL adapter errors back all host initiated operations when disabled, so the disabling the relevant mem region is kept. Signed-off-by: Alex Jones <[email protected]>
1 parent 2427e8c commit 0880f1a

File tree

1 file changed

+14
-26
lines changed

1 file changed

+14
-26
lines changed

hw/opentitan/ot_flash.c

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -991,12 +991,6 @@ static uint64_t ot_flash_regs_read(void *opaque, hwaddr addr, unsigned size)
991991
(void)size;
992992
uint32_t val32;
993993

994-
if (ot_flash_is_disabled(s)) {
995-
qemu_log_mask(LOG_GUEST_ERROR, "%s: flash has been disabled\n",
996-
__func__);
997-
return 0u;
998-
}
999-
1000994
hwaddr reg = R32_OFF(addr);
1001995

1002996
switch (reg) {
@@ -1164,12 +1158,6 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64,
11641158
uint32_t pc = ibex_get_current_pc();
11651159
trace_ot_flash_io_write((uint32_t)addr, REG_NAME(reg), val32, pc);
11661160

1167-
if (ot_flash_is_disabled(s)) {
1168-
qemu_log_mask(LOG_GUEST_ERROR, "%s: flash has been disabled\n",
1169-
__func__);
1170-
return;
1171-
}
1172-
11731161
switch (reg) {
11741162
case R_INTR_STATE: {
11751163
uint32_t rw1c_mask = INTR_CORR_ERR_MASK | INTR_OP_DONE_MASK;
@@ -1205,8 +1193,6 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64,
12051193
if (ot_flash_is_disabled(s)) {
12061194
xtrace_ot_flash_error("flash controller disabled by SW");
12071195
memory_region_set_enabled(&s->mmio.mem, false);
1208-
memory_region_set_enabled(&s->mmio.csrs, false);
1209-
memory_region_set_enabled(&s->mmio.regs, false);
12101196
}
12111197
break;
12121198
case R_INIT:
@@ -1231,6 +1217,20 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64,
12311217
unsigned num = (unsigned)FIELD_EX32(val32, CONTROL, NUM);
12321218

12331219
if (start && s->op.kind == OP_NONE) {
1220+
/*
1221+
* If the flash controller is disabled by software, then (a) the
1222+
* flash protocol controller completes existing software commands,
1223+
* (b) the flash physical controller completes existing stateful
1224+
* operations, and (c) the flash protocol controller MP errors
1225+
* back all controller initiated operations.
1226+
*/
1227+
if (ot_flash_is_disabled(s)) {
1228+
qemu_log_mask(LOG_GUEST_ERROR, "%s: flash has been disabled\n",
1229+
__func__);
1230+
ot_flash_set_error(s, R_ERR_CODE_MP_ERR_MASK, 0u);
1231+
return;
1232+
}
1233+
12341234
switch (op) {
12351235
case CONTROL_OP_READ:
12361236
s->op.kind = OP_READ;
@@ -1504,12 +1504,6 @@ static uint64_t ot_flash_csrs_read(void *opaque, hwaddr addr, unsigned size)
15041504
(void)size;
15051505
uint32_t val32;
15061506

1507-
if (ot_flash_is_disabled(s)) {
1508-
qemu_log_mask(LOG_GUEST_ERROR, "%s: flash has been disabled\n",
1509-
__func__);
1510-
return 0u;
1511-
}
1512-
15131507
hwaddr csr = R32_OFF(addr);
15141508

15151509
switch (csr) {
@@ -1561,12 +1555,6 @@ static void ot_flash_csrs_write(void *opaque, hwaddr addr, uint64_t val64,
15611555
uint32_t pc = ibex_get_current_pc();
15621556
trace_ot_flash_io_write((uint32_t)addr, CSR_NAME(csr), val32, pc);
15631557

1564-
if (ot_flash_is_disabled(s)) {
1565-
qemu_log_mask(LOG_GUEST_ERROR, "%s: flash has been disabled\n",
1566-
__func__);
1567-
return;
1568-
}
1569-
15701558
bool enable = s->csrs[R_CSR0_REGWEN] & R_CSR0_REGWEN_FIELD0_MASK;
15711559
switch (csr) {
15721560
case R_CSR0_REGWEN:

0 commit comments

Comments
 (0)