Open jettr opened 6 months ago
IMO low power exit reset is quite different from all other resets:
This means upon reset we will need to read the reset_info CSR, and regarding a comment above, for non-lowpower resets that are not intended (like software reset) we would also need to read the alert and cpu_info registers to determine what happened. The reset_info value can be used to take the low-power vs other resets path.
It seems to me there is no need to write to the CSRs mentioned above in low power exit.
Writes to the retention SRAM's CTRL CSR also shouldn't happen after low-power exit--Either bit would wipe data that owner firmware intended to keep.
For pinmux, I feel like ROM should be allowed to try to connect the ROM UART TX but not fail if the CSR is locked. Straps, on the other hand, should probably be left alone.
For pinmux, I feel like ROM should be allowed to try to connect the ROM UART TX but not fail if the CSR is locked
Seems reasonable to me either way. But yes to not failing if locked :)
Straps, on the other hand, should probably be left alone.
+1
I've added a target in #23381 to capture the ROM disassembly. The disassembly (with source) almost makes it easy enough to find all relevant register accesses, but not quite. Because of function inlining, sometimes the source emitted into the assembly is incomplete and lacks the named register. Target addresses are not always show in sw
instructions, so its also not possible to create a list of register addresses in the ROM instruction stream.
We can, however, use the disassembly to aggregate the entire list of sources that contribute code to the ROM. We can then grep those sources for register names of AON peripherals.
aggregate_srcs.sh
will find source filenames in the disassembly and create a single output which is the aggregation of all source files that contributed at least one line of code to the ROM:
#!/bin/bash
DISASSEMBLY=$1
SRCS=("sw/device/silicon_creator/rom/rom_start.S")
SRCS+=($(grep "/proc/self/cwd" ${DISASSEMBLY} | cut -f1 -d: | sed -e "s,/proc/self/cwd/,,g" -e "s,\./,,g" | sort | uniq))
grep -n . ${SRCS[@]}
Then, we can find all lines of code in the aggregated source that reference one of the AON peripherals:
./aggregate_srcs.sh bazel-out/k8-fastbuild-ST-2cc462681f62/bin/sw/device/silicon_creator/rom/mask_rom_sim_dv.dis \
| grep _REG_OFFSET \
| egrep "AON_TIMER|AST|CLKMGR|PINMUX|PWRMGR|RSTMGR|SENSOR_CTRL|SRAM_CTRL|SYSRST_CTRL"
This produces 50 lines of code that reference an AON peripheral. Not all of these lines of code necessarily contribute to the ROM, but its a constrained set of code to audit. At 1459afe, I see the following:
rom/rom_start.S:171: sw t1, PWRMGR_RESET_EN_REG_OFFSET(t0)
rom/rom_start.S:175: sw t1, PWRMGR_CFG_CDC_SYNC_REG_OFFSET(t0)
rom/rom_start.S:180: lw t0, RSTMGR_RESET_INFO_REG_OFFSET(a0)
rom/rom_start.S:187: sw t1, AON_TIMER_WDOG_BARK_THOLD_REG_OFFSET(t0)
rom/rom_start.S:190: sw t1, AON_TIMER_WDOG_BITE_THOLD_REG_OFFSET(t0)
rom/rom_start.S:194: sw t1, AON_TIMER_WDOG_CTRL_REG_OFFSET(t0)
rom/rom_start.S:207: sw t2, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET(a0)
rom/rom_start.S:214: sw t2, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET(a0)
rom/rom_start.S:232: li a1, (TOP_EARLGREY_AST_BASE_ADDR + AST_REGAL_REG_OFFSET + 4)
rom/rom_start.S:243: sw t0, CLKMGR_JITTER_ENABLE_REG_OFFSET(a0)
rom/rom_start.S:276: PINMUX_MIO_PAD_ATTR_0_REG_OFFSET)
rom/rom_start.S:284: PINMUX_MIO_PERIPH_INSEL_0_REG_OFFSET)
rom/rom_start.S:328: sw zero, AON_TIMER_WDOG_CTRL_REG_OFFSET(a0)
rom/rom_start.S:413: sw a1, SRAM_CTRL_CTRL_REG_OFFSET(a0)
lib/drivers/ast.c:37: (AST_REGAL_REG_OFFSET + sizeof(uint32_t)) / sizeof(uint32_t),
lib/drivers/ast.c:104: abs_mmio_read32(kBaseSensorCtrl + SENSOR_CTRL_STATUS_REG_OFFSET);
lib/drivers/pinmux.c:101: abs_mmio_write32(kBase + PINMUX_MIO_PERIPH_INSEL_0_REG_OFFSET +
lib/drivers/pinmux.c:118: kBase + PINMUX_MIO_PAD_ATTR_0_REG_OFFSET + pad * sizeof(uint32_t), reg);
lib/drivers/pinmux.c:168: kBase + PINMUX_MIO_OUTSEL_0_REG_OFFSET + output.mio * sizeof(uint32_t),
lib/drivers/retention_sram.c:33: abs_mmio_write32(kBase + SRAM_CTRL_CTRL_REG_OFFSET, reg);
lib/drivers/retention_sram.c:42: abs_mmio_write32(kBase + SRAM_CTRL_CTRL_REG_OFFSET, ctrl);
lib/drivers/rstmgr.c:30: abs_mmio_read32(kBase + RSTMGR_ALERT_INFO_ATTR_REG_OFFSET),
lib/drivers/rstmgr.c:34: kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET,
lib/drivers/rstmgr.c:36: info->info[i] = abs_mmio_read32(kBase + RSTMGR_ALERT_INFO_REG_OFFSET);
lib/drivers/rstmgr.c:42: abs_mmio_read32(kBase + RSTMGR_CPU_INFO_ATTR_REG_OFFSET),
lib/drivers/rstmgr.c:46: kBase + RSTMGR_CPU_INFO_CTRL_REG_OFFSET,
lib/drivers/rstmgr.c:48: info->info[i] = abs_mmio_read32(kBase + RSTMGR_CPU_INFO_REG_OFFSET);
lib/drivers/rstmgr.c:82: return abs_mmio_read32(kBase + RSTMGR_RESET_INFO_REG_OFFSET);
lib/drivers/rstmgr.c:86: abs_mmio_write32(kBase + RSTMGR_RESET_INFO_REG_OFFSET, reasons);
lib/drivers/rstmgr.c:90: abs_mmio_write32(kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 1);
lib/drivers/rstmgr.c:94: abs_mmio_write32(kBase + RSTMGR_CPU_INFO_CTRL_REG_OFFSET, 1);
lib/drivers/rstmgr.c:120: abs_mmio_read32(kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET),
lib/drivers/rstmgr.c:126: abs_mmio_read32(kBase + RSTMGR_CPU_INFO_CTRL_REG_OFFSET),
lib/drivers/rstmgr.c:155: abs_mmio_write32(kBase + RSTMGR_RESET_REQ_REG_OFFSET, kMultiBitBool4True);
lib/drivers/watchdog.c:76: kPwrMgrBase + PWRMGR_RESET_EN_REG_OFFSET,
lib/drivers/watchdog.c:80: abs_mmio_write32(kPwrMgrBase + PWRMGR_CFG_CDC_SYNC_REG_OFFSET, 1);
lib/drivers/watchdog.c:83: sec_mmio_write32(kBase + AON_TIMER_WDOG_CTRL_REG_OFFSET, kCtrlDisable);
lib/drivers/watchdog.c:84: abs_mmio_write32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET, 0);
lib/drivers/watchdog.c:85: abs_mmio_write32(kBase + AON_TIMER_WDOG_BARK_THOLD_REG_OFFSET,
lib/drivers/watchdog.c:87: sec_mmio_write32(kBase + AON_TIMER_WDOG_BITE_THOLD_REG_OFFSET,
lib/drivers/watchdog.c:104: sec_mmio_write32(kBase + AON_TIMER_WDOG_CTRL_REG_OFFSET, ctrl);
lib/drivers/watchdog.c:108: abs_mmio_write32(kPwrMgrBase + PWRMGR_CFG_CDC_SYNC_REG_OFFSET, 1);
lib/drivers/watchdog.c:113: sec_mmio_write32(kBase + AON_TIMER_WDOG_CTRL_REG_OFFSET, kCtrlDisable);
lib/drivers/watchdog.c:117: abs_mmio_write32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET, 0);
lib/drivers/watchdog.c:121: return abs_mmio_read32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET);
lib/irq_asm.S:31: sw t1, RSTMGR_RESET_REQ_REG_OFFSET(t0)
lib/shutdown.c:438: abs_mmio_write32(kBase + RSTMGR_RESET_REQ_REG_OFFSET, kMultiBitBool4True);
lib/shutdown.c:459: abs_mmio_write32(kSramCtrlBase + SRAM_CTRL_EXEC_REGWEN_REG_OFFSET, 0);
lib/shutdown.c:495: [kSramCtrlCtrlReg] "I"(SRAM_CTRL_CTRL_REG_OFFSET),
lib/shutdown.c:498: [kRstmgrResetReqReg] "I"(RSTMGR_RESET_REQ_REG_OFFSET),
My conclusions after manually reviewing all of the items above.
rom/rom_start.S:180: lw t0, RSTMGR_RESET_INFO_REG_OFFSET(a0)
lib/drivers/ast.c:104: abs_mmio_read32(kBaseSensorCtrl + SENSOR_CTRL_STATUS_REG_OFFSET);
lib/drivers/rstmgr.c:30: abs_mmio_read32(kBase + RSTMGR_ALERT_INFO_ATTR_REG_OFFSET),
lib/drivers/rstmgr.c:36: info->info[i] = abs_mmio_read32(kBase + RSTMGR_ALERT_INFO_REG_OFFSET);
lib/drivers/rstmgr.c:42: abs_mmio_read32(kBase + RSTMGR_CPU_INFO_ATTR_REG_OFFSET),
lib/drivers/rstmgr.c:48: info->info[i] = abs_mmio_read32(kBase + RSTMGR_CPU_INFO_REG_OFFSET);
lib/drivers/rstmgr.c:82: return abs_mmio_read32(kBase + RSTMGR_RESET_INFO_REG_OFFSET);
lib/drivers/rstmgr.c:120: abs_mmio_read32(kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET),
lib/drivers/rstmgr.c:126: abs_mmio_read32(kBase + RSTMGR_CPU_INFO_CTRL_REG_OFFSET),
lib/drivers/watchdog.c:121: return abs_mmio_read32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET);
lib/drivers/ast.c:37: (AST_REGAL_REG_OFFSET + sizeof(uint32_t)) / sizeof(uint32_t),
lib/shutdown.c:459: abs_mmio_write32(kSramCtrlBase + SRAM_CTRL_EXEC_REGWEN_REG_OFFSET, 0);
lib/shutdown.c:495: [kSramCtrlCtrlReg] "I"(SRAM_CTRL_CTRL_REG_OFFSET),
rom/rom_start.S:413: sw a1, SRAM_CTRL_CTRL_REG_OFFSET(a0)
rom/rom_start.S:175: sw t1, PWRMGR_CFG_CDC_SYNC_REG_OFFSET(t0)
lib/drivers/watchdog.c:80: abs_mmio_write32(kPwrMgrBase + PWRMGR_CFG_CDC_SYNC_REG_OFFSET, 1);
lib/drivers/watchdog.c:84: abs_mmio_write32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET, 0);
lib/drivers/watchdog.c:108: abs_mmio_write32(kPwrMgrBase + PWRMGR_CFG_CDC_SYNC_REG_OFFSET, 1);
lib/drivers/watchdog.c:117: abs_mmio_write32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET, 0);
lib/drivers/rstmgr.c:155: abs_mmio_write32(kBase + RSTMGR_RESET_REQ_REG_OFFSET, kMultiBitBool4True);
lib/irq_asm.S:31: sw t1, RSTMGR_RESET_REQ_REG_OFFSET(t0)
lib/shutdown.c:438: abs_mmio_write32(kBase + RSTMGR_RESET_REQ_REG_OFFSET, kMultiBitBool4True);
lib/shutdown.c:498: [kRstmgrResetReqReg] "I"(RSTMGR_RESET_REQ_REG_OFFSET),
lib/drivers/rstmgr.c:86: abs_mmio_write32(kBase + RSTMGR_RESET_INFO_REG_OFFSET, reasons);
lib/drivers/rstmgr.c:34: kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET,
rstmgr_alert_info_collect
is never called by the ROM.lib/drivers/rstmgr.c:46: kBase + RSTMGR_CPU_INFO_CTRL_REG_OFFSET,
rstmgr_cpu_info_collect
is never called by the ROM.lib/drivers/rstmgr.c:90: abs_mmio_write32(kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 1);
rstmgr_alert_info_enable
is never called by the ROM.lib/drivers/retention_sram.c:42: abs_mmio_write32(kBase + SRAM_CTRL_CTRL_REG_OFFSET, ctrl);
retention_sram_scramble
is never called by the ROM.lib/drivers/rstmgr.c:94: abs_mmio_write32(kBase + RSTMGR_CPU_INFO_CTRL_REG_OFFSET, 1);
rstmgr_cpu_info_enable
is never called by the ROM (its source appears in
the disassembly, but it never appears to be called).rom/rom_start.S:232: li a1, (TOP_EARLGREY_AST_BASE_ADDR + AST_REGAL_REG_OFFSET + 4)
CLKMGR_JITTER_REGWEN
rom/rom_start.S:243: sw t0, CLKMGR_JITTER_ENABLE_REG_OFFSET(a0)
PINMUX_MIO_PAD_ATTR_REGWEN_n
rom/rom_start.S:276: PINMUX_MIO_PAD_ATTR_0_REG_OFFSET)
lib/drivers/pinmux.c:118: kBase + PINMUX_MIO_PAD_ATTR_0_REG_OFFSET + pad * sizeof(uint32_t), reg);
PINMUX_MIO_PERIPH_INSEL_REGWEN_n
rom/rom_start.S:284: PINMUX_MIO_PERIPH_INSEL_0_REG_OFFSET)
lib/drivers/pinmux.c:101: abs_mmio_write32(kBase + PINMUX_MIO_PERIPH_INSEL_0_REG_OFFSET +
PINMUX_MIO_OUTSEL_REGWEN_n
lib/drivers/pinmux.c:168: kBase + PINMUX_MIO_OUTSEL_0_REG_OFFSET + output.mio * sizeof(uint32_t),
PWRMGR_RESET_EN_REGWEN
rom/rom_start.S:171: sw t1, PWRMGR_RESET_EN_REG_OFFSET(t0)
lib/drivers/watchdog.c:76: kPwrMgrBase + PWRMGR_RESET_EN_REG_OFFSET,
SRAM_CTRL_REGWEN
lib/drivers/retention_sram.c:33: abs_mmio_write32(kBase + SRAM_CTRL_CTRL_REG_OFFSET, reg);
RSTMGR_ALERT_REGWEN
rom/rom_start.S:207: sw t2, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET(a0)
rom/rom_start.S:214: sw t2, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET(a0)
AON_TIMER_WDOG_REGWEN
rom/rom_start.S:187: sw t1, AON_TIMER_WDOG_BARK_THOLD_REG_OFFSET(t0)
rom/rom_start.S:190: sw t1, AON_TIMER_WDOG_BITE_THOLD_REG_OFFSET(t0)
rom/rom_start.S:194: sw t1, AON_TIMER_WDOG_CTRL_REG_OFFSET(t0)
rom/rom_start.S:328: sw zero, AON_TIMER_WDOG_CTRL_REG_OFFSET(a0)
lib/drivers/watchdog.c:83: sec_mmio_write32(kBase + AON_TIMER_WDOG_CTRL_REG_OFFSET, kCtrlDisable);
lib/drivers/watchdog.c:85: abs_mmio_write32(kBase + AON_TIMER_WDOG_BARK_THOLD_REG_OFFSET,
lib/drivers/watchdog.c:87: sec_mmio_write32(kBase + AON_TIMER_WDOG_BITE_THOLD_REG_OFFSET,
lib/drivers/watchdog.c:104: sec_mmio_write32(kBase + AON_TIMER_WDOG_CTRL_REG_OFFSET, ctrl);
lib/drivers/watchdog.c:113: sec_mmio_write32(kBase + AON_TIMER_WDOG_CTRL_REG_OFFSET, kCtrlDisable);
I believe the ROM has the low-power wakeup issues already addressed:
I believe the ROM has the low-power wakeup issues already addressed:
- PINMUX: we skip re-initializing the pinmux from a low-power wakeup.
- WDOG: we skip re-initializing the watchdog from a low-power wakeup.
- RETRAM_SRAM_CTRL: we only initialize this from power-on-reset (and additional OTP defined conditions).
- CLKMGR_JITTER: we ought to lock this in the ROM or ROM_EXT to prevent it from being changed from the SKU-defined value.
- PWRMGR_RESET_EN: we enable all reset sources in the ROM. I'm not sure that we care if the owner changes it later.
- RSTMGR_ALERT_INFO: we enable this in the ROM to allow capturing alert causes in the rstmgr crashdump registers, but I'm not sure we care if the owner changes it later.
Awesome, LGTM. As long as there isn't a sec_mmio_write32()
(or similar checking that the value was actually written) for the CSRs we don't care about, then that'll do. And if I'm just comparing the two comments, then it looks like we're good!
The remaining bit would be documenting the interfaces between boot stages (including any requirements for mutable CSRs), but that's technically not part of this issue. :smile:
Description
In #22204 we would an issue with the ROM trying to reset the watchdog count down on the deep sleep resume path; this is causing an exception because the owner firmware had already locked the watchdog registers by clearing REGWEN for watchdog.
We need to audit and fix the ROM/ROM_EXT code for the deep sleep resume path for all places where it tries to write to registers that may have already been locked. @a-will has already provided a [first pass analysis] for ROM (https://github.com/lowRISC/opentitan/issues/22204#issuecomment-2060028889):
We still need to audit ROM_EXT and then fix all potential issues.