22 * QEMU OpenTitan SRAM controller
33 *
44 * Copyright (c) 2023-2024 Rivos, Inc.
5+ * Copyright (c) 2025 lowRISC contributors.
56 *
67 * Author(s):
78 * Emmanuel Blot <[email protected] > @@ -60,6 +61,8 @@ REG32(STATUS, 0x4u)
6061 FIELD (STATUS , SCR_KEY_VALID , 3u , 1u )
6162 FIELD (STATUS , SCR_KEY_SEED_VALID , 4u , 1u )
6263 FIELD (STATUS , INIT_DONE , 5u , 1u )
64+ FIELD (STATUS , READBACK_ERROR , 6u , 1u )
65+ FIELD (STATUS , SRAM_ALERT , 7u , 1u )
6366REG32 (EXEC_REGWEN , 0x8u )
6467 FIELD (EXEC_REGWEN , EN , 0u , 1u )
6568REG32 (EXEC , 0xcu )
@@ -72,7 +75,7 @@ REG32(CTRL, 0x14u)
7275REG32 (SCR_KEY_ROTATED , 0x18u )
7376 FIELD (SCR_KEY_ROTATED , SUCCESS , 0u , 4u )
7477REG32 (READBACK_REGWEN , 0x1cu )
75- FIELD (READBACK_REGWEN , READBACK_REGWEN , 0u , 1u )
78+ FIELD (READBACK_REGWEN , EN , 0u , 1u )
7679REG32 (READBACK , 0x20u )
7780 FIELD (READBACK , EN , 0u , 4u )
7881
@@ -270,7 +273,7 @@ static void ot_sram_ctrl_reseed(OtSramCtrlState *s)
270273
271274 /*
272275 * Note: in order to keep the implementation simple, the full OT HW behavior
273- * is not reproced here (with CPU cycle delays to obtain the key, etc.
276+ * is not reproduced here (with CPU cycle delays to get the key, etc.)
274277 * Tke key retrieval is therefore synchronous, which does not
275278 * precisely emulate the HW.
276279 * Moreover the scrambling is highly simplified, as for now there is
@@ -357,6 +360,8 @@ static uint64_t ot_sram_ctrl_regs_read(void *opaque, hwaddr addr, unsigned size)
357360 case R_CTRL_REGWEN :
358361 case R_CTRL :
359362 case R_SCR_KEY_ROTATED :
363+ case R_READBACK_REGWEN :
364+ case R_READBACK :
360365 val32 = s -> regs [reg ];
361366 break ;
362367 case R_ALERT_TEST :
@@ -447,6 +452,21 @@ static void ot_sram_ctrl_regs_write(void *opaque, hwaddr addr, uint64_t val64,
447452 qemu_log_mask (LOG_UNIMP , "%s: %s R_SCR_KEY_ROTATED\n" , __func__ ,
448453 s -> ot_id );
449454 break ;
455+ case R_READBACK_REGWEN :
456+ val32 &= R_READBACK_REGWEN_EN_MASK ;
457+ s -> regs [reg ] &= val32 ; /* RW0C */
458+ break ;
459+ case R_READBACK :
460+ if (s -> regs [R_READBACK_REGWEN ]) {
461+ val32 &= R_READBACK_EN_MASK ;
462+ s -> regs [reg ] = val32 ;
463+ /* readback feature is a no-op in QEMU */
464+ } else {
465+ qemu_log_mask (LOG_GUEST_ERROR ,
466+ "%s: %s R_READBACK_REGWEN protected w/ REGWEN\n" ,
467+ __func__ , s -> ot_id );
468+ }
469+ break ;
450470 case R_STATUS :
451471 qemu_log_mask (LOG_GUEST_ERROR ,
452472 "%s: %s R/O register 0x%02" HWADDR_PRIx " (%s)\n" ,
0 commit comments