13#include "sw/device/lib/base/multibits.h"
16#include "hw/top/rstmgr_regs.h"
20#define RSTMGR_RESET_INFO_CHECK(pub_name, priv_name) \
21 static_assert(kDifRstmgrResetInfo##pub_name == \
22 (0x1 << RSTMGR_RESET_INFO_##priv_name##_BIT), \
23 "kDifRstmgrResetInfo" #pub_name \
24 " must match the register definition!")
27#if defined(OPENTITAN_IS_EARLGREY)
29RSTMGR_RESET_INFO_CHECK(Por, POR);
30RSTMGR_RESET_INFO_CHECK(LowPowerExit, LOW_POWER_EXIT);
31RSTMGR_RESET_INFO_CHECK(Sw, SW_RESET);
34 << RSTMGR_RESET_INFO_HW_REQ_OFFSET),
35 "kDifRstmgrResetInfoHwReq must match the register definition!");
43 RSTMGR_PARAM_NUM_SW_RESETS <= 32,
44 "Reset Enable and Control registers span across multiple registers!");
53 "Alert info dump max size has grown, please update the public define!");
54#elif defined(OPENTITAN_IS_DARJEELING)
57#error "dif_rstmgr does not support this top"
65 mmio_region_read32(base_addr, RSTMGR_ALERT_REGWEN_REG_OFFSET);
68 return !bitfield_bit32_read(bitfield, RSTMGR_ALERT_REGWEN_EN_BIT);
76 mmio_region_read32(base_addr, RSTMGR_CPU_REGWEN_REG_OFFSET);
79 return !bitfield_bit32_read(bitfield, RSTMGR_CPU_REGWEN_EN_BIT);
83#if RSTMGR_SW_RST_REGWEN_MULTIREG_COUNT > 1
84 return RSTMGR_SW_RST_REGWEN_0_REG_OFFSET + 4 * (ptrdiff_t)p;
86 return RSTMGR_SW_RST_REGWEN_REG_OFFSET + 4 * (ptrdiff_t)p;
93static bool rstmgr_software_reset_is_locked(
95 return !mmio_region_read32(base_addr, get_regwen_reg_offset(peripheral));
99#if RSTMGR_SW_RST_CTRL_N_MULTIREG_COUNT > 1
100 return RSTMGR_SW_RST_CTRL_N_0_REG_OFFSET + 4 * (ptrdiff_t)p;
102 return RSTMGR_SW_RST_CTRL_N_REG_OFFSET + 4 * (ptrdiff_t)p;
109static void rstmgr_software_reset_hold(
mmio_region_t base_addr,
112 bool value = hold ? false :
true;
113 mmio_region_write32(base_addr, get_ctrl_n_reg_offset(peripheral), value);
121static void rstmgr_reset_info_clear(
mmio_region_t base_addr) {
122 mmio_region_write32(base_addr, RSTMGR_RESET_INFO_REG_OFFSET, UINT32_MAX);
126 if (handle == NULL) {
132 rstmgr_reset_info_clear(base_addr);
135 for (uint32_t i = 0; i < RSTMGR_PARAM_NUM_SW_RESETS; i++) {
136 mmio_region_write32(base_addr, get_ctrl_n_reg_offset(i), UINT32_MAX);
144 if (handle == NULL || peripheral >= RSTMGR_PARAM_NUM_SW_RESETS) {
150 mmio_region_write32(base_addr, get_regwen_reg_offset(peripheral), 0);
158 if (handle == NULL || is_locked == NULL ||
159 peripheral >= RSTMGR_PARAM_NUM_SW_RESETS) {
164 *is_locked = rstmgr_software_reset_is_locked(base_addr, peripheral);
171 if (handle == NULL || info == NULL) {
176 *info = mmio_region_read32(base_addr, RSTMGR_RESET_INFO_REG_OFFSET);
182 if (handle == NULL) {
188 rstmgr_reset_info_clear(base_addr);
195 if (handle == NULL) {
201 if (alert_capture_is_locked(base_addr)) {
210 mmio_region_write32(base_addr, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, enabled);
217 if (handle == NULL || state == NULL) {
224 mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET);
225 bool enabled = bitfield_bit32_read(reg, RSTMGR_ALERT_INFO_CTRL_EN_BIT);
234 if (handle == NULL || size == NULL) {
239 *size = mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_ATTR_REG_OFFSET);
245 size_t dump_size,
size_t *segments_read) {
246 if (handle == NULL || dump == NULL || segments_read == NULL) {
253 size_t dump_size_actual =
254 mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_ATTR_REG_OFFSET);
257 if (dump_size < dump_size_actual) {
261 uint32_t control_reg =
262 mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET);
265 for (uint32_t i = 0; i < dump_size_actual; ++i) {
266 control_reg = bitfield_field32_write(control_reg,
267 RSTMGR_ALERT_INFO_CTRL_INDEX_FIELD, i);
270 mmio_region_write32(base_addr, RSTMGR_ALERT_INFO_CTRL_REG_OFFSET,
274 dump[i] = mmio_region_read32(base_addr, RSTMGR_ALERT_INFO_REG_OFFSET);
277 *segments_read = dump_size_actual;
284 if (handle == NULL) {
290 if (cpu_capture_is_locked(base_addr)) {
299 mmio_region_write32(base_addr, RSTMGR_CPU_INFO_CTRL_REG_OFFSET, enabled);
306 if (handle == NULL || state == NULL) {
312 uint32_t reg = mmio_region_read32(base_addr, RSTMGR_CPU_INFO_CTRL_REG_OFFSET);
313 bool enabled = bitfield_bit32_read(reg, RSTMGR_CPU_INFO_CTRL_EN_BIT);
322 if (handle == NULL || size == NULL) {
327 *size = mmio_region_read32(base_addr, RSTMGR_CPU_INFO_ATTR_REG_OFFSET);
333 size_t dump_size,
size_t *segments_read) {
334 if (handle == NULL || dump == NULL || segments_read == NULL) {
341 size_t dump_size_actual =
342 mmio_region_read32(base_addr, RSTMGR_CPU_INFO_ATTR_REG_OFFSET);
345 if (dump_size < dump_size_actual) {
349 uint32_t control_reg =
350 mmio_region_read32(base_addr, RSTMGR_CPU_INFO_CTRL_REG_OFFSET);
353 for (uint32_t i = 0; i < dump_size_actual; ++i) {
354 control_reg = bitfield_field32_write(control_reg,
355 RSTMGR_CPU_INFO_CTRL_INDEX_FIELD, i);
358 mmio_region_write32(base_addr, RSTMGR_CPU_INFO_CTRL_REG_OFFSET,
362 dump[i] = mmio_region_read32(base_addr, RSTMGR_CPU_INFO_REG_OFFSET);
365 *segments_read = dump_size_actual;
373 if (handle == NULL || peripheral >= RSTMGR_PARAM_NUM_SW_RESETS) {
378 if (rstmgr_software_reset_is_locked(base_addr, peripheral)) {
384 rstmgr_software_reset_hold(base_addr, peripheral,
true);
385 rstmgr_software_reset_hold(base_addr, peripheral,
false);
388 rstmgr_software_reset_hold(base_addr, peripheral,
true);
391 rstmgr_software_reset_hold(base_addr, peripheral,
false);
403 if (handle == NULL || asserted == NULL ||
404 peripheral >= RSTMGR_PARAM_NUM_SW_RESETS) {
410 !mmio_region_read32(handle->
base_addr, get_ctrl_n_reg_offset(peripheral));
416 if (handle == NULL) {
420 mmio_region_write32(handle->
base_addr, RSTMGR_RESET_REQ_REG_OFFSET,
427 size_t *sw_rst_idx) {
429 for (*sw_rst_idx = 0; *sw_rst_idx < sw_reset_count; ++(*sw_rst_idx)) {
439 if (rstmgr == NULL || codes == NULL) {
442 *codes = mmio_region_read32(rstmgr->
base_addr, RSTMGR_ERR_CODE_REG_OFFSET);