From 8b2494550be084a52073ae12e3a4acb5c2a714b1 Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Tue, 11 Nov 2025 14:14:37 +0000 Subject: [PATCH] [ot] hw/opentitan: ot_flash: Allow flash ops with uninit flash_ctrl Turns out the flash controller initialization is even more of a special case then thought. The physical flash macro needs to be initialized, but this is vendor-specific and not useful to emulate so we always just say the flash PHY is initialized. The HW should specifically allow operations on uninitialized flash, but reads specifically are handled somewhat differently. This is explained in more detail in the comment in this commit. Signed-off-by: Alex Jones --- hw/opentitan/ot_flash.c | 24 +++++++++++++++--------- tests/opentitan/data/earlgrey-tests.txt | 4 ++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/hw/opentitan/ot_flash.c b/hw/opentitan/ot_flash.c index c64f0b418549..75bb4a3ee746 100644 --- a/hw/opentitan/ot_flash.c +++ b/hw/opentitan/ot_flash.c @@ -2198,7 +2198,6 @@ static void ot_flash_init_complete(void *opaque) trace_ot_flash_op_complete(s->ot_id, OP_NAME(s->op.kind), s->op.hw, true); s->op.kind = OP_NONE; - ot_flash_process_control_op(s); } static uint64_t ot_flash_regs_read(void *opaque, hwaddr addr, unsigned size) @@ -2459,15 +2458,22 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64, s->regs[reg] = val32; /* - * SW protocol ops are not processed until the phy controller is init; - * immediately after the flash arbiter permits hw ops to read keymgr - * secrets. So, we cannot perform a sw op until the flash_ctrl is - * initialized. However, if `start` is true, the arbiter processes the - * sw request immediately after init in `ot_flash_init_complete`. + * SW protocol operations are not processed until the PHY controller is + * initialized, but the protocol controller is not required to be + * initialized (i.e. before the scrambling keys are read). In such a + * case we *can* interact with the flash - we just do not buffer + * outgoing reads, but they are still permitted. + * + * We emulate the PHY as always being initialized, so there is no need + * to check for initialization here. + * + * Note for future implementation of scrambling: there is a special + * case for scrambled pages: when reading from a scrambled page with + * the flash_ctrl uninitialized, default scrambling keys hardcoded in + * the RTL are used instead of the (not yet) loaded flash addr/data + * keys. */ - if (ot_flash_is_initialized(s)) { - ot_flash_process_control_op(s); - } + ot_flash_process_control_op(s); break; case R_ADDR: val32 &= R_ADDR_START_MASK; diff --git a/tests/opentitan/data/earlgrey-tests.txt b/tests/opentitan/data/earlgrey-tests.txt index f86976eae5e1..fb7b91afcb7b 100644 --- a/tests/opentitan/data/earlgrey-tests.txt +++ b/tests/opentitan/data/earlgrey-tests.txt @@ -439,8 +439,8 @@ pass: //sw/device/tests:example_concurrency_test_sim_qemu_rom_with_fake_keys pass: //sw/device/tests:example_concurrency_test_sim_qemu_sival_rom_ext pass: //sw/device/tests:example_test_from_flash_sim_qemu_rom_with_fake_keys pass: //sw/device/tests:example_test_from_flash_sim_qemu_sival_rom_ext -pass: //sw/device/tests:flash_ctrl_clock_freqs_test_sim_qemu_rom_with_fake_keys -pass: //sw/device/tests:flash_ctrl_clock_freqs_test_sim_qemu_sival_rom_ext +flaky: //sw/device/tests:flash_ctrl_clock_freqs_test_sim_qemu_rom_with_fake_keys # After processing commands for uninitialized flash, the timing gets tighter and this fails < 5% of the time. +flaky: //sw/device/tests:flash_ctrl_clock_freqs_test_sim_qemu_sival_rom_ext # After processing commands for uninitialized flash, the timing gets tighter and this fails < 5% of the time. pass: //sw/device/tests:flash_ctrl_info_access_lc_dev_sim_qemu_rom_with_fake_keys pass: //sw/device/tests:flash_ctrl_info_access_lc_prod_end_sim_qemu_rom_with_fake_keys pass: //sw/device/tests:flash_ctrl_info_access_lc_prod_sim_qemu_rom_with_fake_keys