13 #include "sw/device/lib/base/multibits.h"
16 #include "rstmgr_regs.h"
19 #if defined(OPENTITAN_IS_EARLGREY)
22 #define RSTMGR_RESET_INFO_CHECK(pub_name, priv_name) \
23 static_assert(kDifRstmgrResetInfo##pub_name == \
24 (0x1 << RSTMGR_RESET_##priv_name##_BIT), \
25 "kDifRstmgrResetInfo" #pub_name \
26 " must match the register definition!")
28 RSTMGR_RESET_INFO_CHECK(Por, INFO_POR);
29 RSTMGR_RESET_INFO_CHECK(LowPowerExit, INFO_LOW_POWER_EXIT);
32 << RSTMGR_RESET_INFO_HW_REQ_OFFSET),
33 "kDifRstmgrResetInfoHwReq must match the register definition!");
36 RSTMGR_PARAM_NUM_SW_RESETS == 8,
37 "Number of software resets has changed, please update this file!");
45 RSTMGR_PARAM_NUM_SW_RESETS <= 32,
46 "Reset Enable and Control registers span across multiple registers!");
55 "Alert info dump max size has grown, please update the public define!");
56 #elif defined(OPENTITAN_IS_DARJEELING)
59 #error "dif_rstmgr does not support this top"
65 static bool alert_capture_is_locked(
mmio_region_t base_addr) {
67 mmio_region_read32(base_addr, RSTMGR_ALERT_REGWEN_REG_OFFSET);
78 mmio_region_read32(base_addr, RSTMGR_CPU_REGWEN_REG_OFFSET);
87 static bool rstmgr_software_reset_is_locked(
89 return !mmio_region_read32(
90 base_addr, RSTMGR_SW_RST_REGWEN_0_REG_OFFSET + 4 * (ptrdiff_t)peripheral);
96 static void rstmgr_software_reset_hold(
mmio_region_t base_addr,
99 bool value = hold ? false :
true;
101 base_addr, RSTMGR_SW_RST_CTRL_N_0_REG_OFFSET + 4 * (ptrdiff_t)peripheral,
110 static void rstmgr_reset_info_clear(
mmio_region_t base_addr) {
111 mmio_region_write32(base_addr, RSTMGR_RESET_INFO_REG_OFFSET, UINT32_MAX);
115 if (handle == NULL) {
121 rstmgr_reset_info_clear(base_addr);
124 for (uint32_t i = 0; i < RSTMGR_PARAM_NUM_SW_RESETS; i++) {
125 mmio_region_write32(base_addr,
126 RSTMGR_SW_RST_CTRL_N_0_REG_OFFSET + (ptrdiff_t)i * 4,
135 if (handle == NULL || peripheral >= RSTMGR_PARAM_NUM_SW_RESETS) {
142 base_addr, RSTMGR_SW_RST_REGWEN_0_REG_OFFSET + 4 * (ptrdiff_t)peripheral,
151 if (handle == NULL || is_locked == NULL ||
152 peripheral >= RSTMGR_PARAM_NUM_SW_RESETS) {
157 *is_locked = rstmgr_software_reset_is_locked(base_addr, peripheral);
164 if (handle == NULL || info == NULL) {
169 *info = mmio_region_read32(base_addr, RSTMGR_RESET_INFO_REG_OFFSET);
175 if (handle == NULL) {
181 rstmgr_reset_info_clear(base_addr);
188 if (handle == NULL) {
194 if (alert_capture_is_locked(base_addr)) {
203 mmio_region_write32(base_addr, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, enabled);
210 if (handle == NULL || state == NULL) {
217 mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET);
227 if (handle == NULL || size == NULL) {
232 *size = mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_ATTR_REG_OFFSET);
238 size_t dump_size,
size_t *segments_read) {
239 if (handle == NULL || dump == NULL || segments_read == NULL) {
246 size_t dump_size_actual =
247 mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_ATTR_REG_OFFSET);
250 if (dump_size < dump_size_actual) {
254 uint32_t control_reg =
255 mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET);
258 for (uint32_t i = 0; i < dump_size_actual; ++i) {
260 RSTMGR_ALERT_INFO_CTRL_INDEX_FIELD, i);
263 mmio_region_write32(base_addr, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET,
267 dump[i] = mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_REG_OFFSET);
270 *segments_read = dump_size_actual;
277 if (handle == NULL) {
283 if (cpu_capture_is_locked(base_addr)) {
292 mmio_region_write32(base_addr, RSTMGR_CPU_INFO_CTRL_REG_OFFSET, enabled);
299 if (handle == NULL || state == NULL) {
305 uint32_t reg = mmio_region_read32(base_addr, RSTMGR_CPU_INFO_CTRL_REG_OFFSET);
315 if (handle == NULL || size == NULL) {
320 *size = mmio_region_read32(base_addr, RSTMGR_CPU_INFO_ATTR_REG_OFFSET);
326 size_t dump_size,
size_t *segments_read) {
327 if (handle == NULL || dump == NULL || segments_read == NULL) {
334 size_t dump_size_actual =
335 mmio_region_read32(base_addr, RSTMGR_CPU_INFO_ATTR_REG_OFFSET);
338 if (dump_size < dump_size_actual) {
342 uint32_t control_reg =
343 mmio_region_read32(base_addr, RSTMGR_CPU_INFO_CTRL_REG_OFFSET);
346 for (uint32_t i = 0; i < dump_size_actual; ++i) {
348 RSTMGR_CPU_INFO_CTRL_INDEX_FIELD, i);
351 mmio_region_write32(base_addr, RSTMGR_CPU_INFO_CTRL_REG_OFFSET,
355 dump[i] = mmio_region_read32(base_addr, RSTMGR_CPU_INFO_REG_OFFSET);
358 *segments_read = dump_size_actual;
366 if (handle == NULL || peripheral >= RSTMGR_PARAM_NUM_SW_RESETS) {
371 if (rstmgr_software_reset_is_locked(base_addr, peripheral)) {
377 rstmgr_software_reset_hold(base_addr, peripheral,
true);
378 rstmgr_software_reset_hold(base_addr, peripheral,
false);
381 rstmgr_software_reset_hold(base_addr, peripheral,
true);
384 rstmgr_software_reset_hold(base_addr, peripheral,
false);
396 if (handle == NULL || asserted == NULL ||
397 peripheral >= RSTMGR_PARAM_NUM_SW_RESETS) {
403 !mmio_region_read32(handle->base_addr, RSTMGR_SW_RST_CTRL_N_0_REG_OFFSET +
404 4 * (ptrdiff_t)peripheral);
410 if (handle == NULL) {
414 mmio_region_write32(handle->base_addr, RSTMGR_RESET_REQ_REG_OFFSET,
421 size_t *sw_rst_idx) {
422 size_t sw_reset_count = dt_rstmgr_sw_reset_count(dt);
423 for (*sw_rst_idx = 0; *sw_rst_idx < sw_reset_count; ++(*sw_rst_idx)) {
424 if (dt_rstmgr_sw_reset(dt, *sw_rst_idx) == reset) {
433 if (rstmgr == NULL || codes == NULL) {
436 *codes = mmio_region_read32(rstmgr->base_addr, RSTMGR_ERR_CODE_REG_OFFSET);