[mask_rom] Add a driver for the rstmgr. This driver allows one to retrieve the last reset reason and enables capturing of alert escalation info during a reset. Signed-off-by: Chris Frantz <cfrantz@google.com>
diff --git a/sw/device/silicon_creator/lib/drivers/meson.build b/sw/device/silicon_creator/lib/drivers/meson.build index 77f5fa3..318e65a 100644 --- a/sw/device/silicon_creator/lib/drivers/meson.build +++ b/sw/device/silicon_creator/lib/drivers/meson.build
@@ -160,3 +160,35 @@ ), suite: 'mask_rom', ) + +# Mask ROM rstmgr driver +sw_silicon_creator_lib_driver_rstmgr = declare_dependency( + link_with: static_library( + 'sw_silicon_creator_lib_driver_rstmgr', + sources: [ + hw_ip_rstmgr_reg_h, + 'rstmgr.c', + ], + dependencies: [ + sw_silicon_creator_lib_base_abs_mmio, + ], + ), +) + +test('sw_silicon_creator_lib_driver_rstmgr_unittest', executable( + 'sw_silicon_creator_lib_driver_rstmgr_unittest', + sources: [ + 'rstmgr_unittest.cc', + hw_ip_rstmgr_reg_h, + 'rstmgr.c', + ], + dependencies: [ + sw_vendor_gtest, + sw_silicon_creator_lib_base_mock_abs_mmio, + ], + native: true, + c_args: ['-DMOCK_ABS_MMIO'], + cpp_args: ['-DMOCK_ABS_MMIO'], + ), + suite: 'mask_rom', +)
diff --git a/sw/device/silicon_creator/lib/drivers/rstmgr.c b/sw/device/silicon_creator/lib/drivers/rstmgr.c new file mode 100644 index 0000000..e3e9dd3 --- /dev/null +++ b/sw/device/silicon_creator/lib/drivers/rstmgr.c
@@ -0,0 +1,39 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +#include "sw/device/silicon_creator/lib/drivers/rstmgr.h" + +#include "sw/device/lib/base/bitfield.h" +#include "sw/device/silicon_creator/lib/base/abs_mmio.h" + +#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" +#include "rstmgr_regs.h" + +enum { + kBase = TOP_EARLGREY_RSTMGR_AON_BASE_ADDR, +}; + +rstmgr_alert_info_t rstmgr_alert_info; + +static void rstmgr_alert_info_collect(void) { + rstmgr_alert_info.length = bitfield_field32_read( + abs_mmio_read32(kBase + RSTMGR_ALERT_INFO_ATTR_REG_OFFSET), + RSTMGR_ALERT_INFO_ATTR_CNT_AVAIL_FIELD); + for (uint32_t i = 0; i < rstmgr_alert_info.length; ++i) { + abs_mmio_write32( + kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, + bitfield_field32_write(0, RSTMGR_ALERT_INFO_CTRL_INDEX_FIELD, i)); + rstmgr_alert_info.info[i] = + abs_mmio_read32(kBase + RSTMGR_ALERT_INFO_REG_OFFSET); + } +} + +uint32_t rstmgr_reason_get(void) { + rstmgr_alert_info_collect(); + return abs_mmio_read32(kBase + RSTMGR_RESET_INFO_REG_OFFSET); +} + +void rstmgr_alert_info_enable(void) { + abs_mmio_write32(kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 1); +}
diff --git a/sw/device/silicon_creator/lib/drivers/rstmgr.h b/sw/device/silicon_creator/lib/drivers/rstmgr.h new file mode 100644 index 0000000..91c50c4 --- /dev/null +++ b/sw/device/silicon_creator/lib/drivers/rstmgr.h
@@ -0,0 +1,46 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_RSTMGR_H_ +#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_RSTMGR_H_ + +#include <stddef.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Alert Infomation captured by the reset manager during the last reset. + */ +typedef struct RstMgrAlertInfo { + /** + * Length of alert information. + */ + uint32_t length; + /** + * Alert info words. + */ + uint32_t info[16]; +} rstmgr_alert_info_t; + +extern rstmgr_alert_info_t rstmgr_alert_info; + +/** + * Get the reason for the last reset. + * + * This function also captures alert information into `rstmgr_alert_info`. + */ +uint32_t rstmgr_reason_get(void); + +/** + * Enable capturing of alert info in the event of an alert escalation. + */ +void rstmgr_alert_info_enable(void); + +#ifdef __cplusplus +} +#endif +#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_RSTMGR_H_
diff --git a/sw/device/silicon_creator/lib/drivers/rstmgr_unittest.cc b/sw/device/silicon_creator/lib/drivers/rstmgr_unittest.cc new file mode 100644 index 0000000..9824d17 --- /dev/null +++ b/sw/device/silicon_creator/lib/drivers/rstmgr_unittest.cc
@@ -0,0 +1,52 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "sw/device/silicon_creator/lib/drivers/rstmgr.h" + +#include "gtest/gtest.h" +#include "sw/device/lib/base/mmio.h" +#include "sw/device/silicon_creator/lib/base/mock_abs_mmio.h" + +#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" +#include "rstmgr_regs.h" // Generated. + +namespace rstmgr_unittest { +namespace { +using ::testing::ElementsAre; + +class RstmgrTest : public mask_rom_test::MaskRomTest { + protected: + uint32_t base_ = TOP_EARLGREY_RSTMGR_AON_BASE_ADDR; + mask_rom_test::MockAbsMmio mmio_; +}; + +TEST_F(RstmgrTest, GetResetReason) { + EXPECT_ABS_READ32(mmio_, base_ + RSTMGR_ALERT_INFO_ATTR_REG_OFFSET, 5); + + EXPECT_ABS_WRITE32(mmio_, base_ + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 0x00); + EXPECT_ABS_READ32(mmio_, base_ + RSTMGR_ALERT_INFO_REG_OFFSET, 1); + EXPECT_ABS_WRITE32(mmio_, base_ + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 0x10); + EXPECT_ABS_READ32(mmio_, base_ + RSTMGR_ALERT_INFO_REG_OFFSET, 2); + EXPECT_ABS_WRITE32(mmio_, base_ + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 0x20); + EXPECT_ABS_READ32(mmio_, base_ + RSTMGR_ALERT_INFO_REG_OFFSET, 3); + EXPECT_ABS_WRITE32(mmio_, base_ + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 0x30); + EXPECT_ABS_READ32(mmio_, base_ + RSTMGR_ALERT_INFO_REG_OFFSET, 4); + EXPECT_ABS_WRITE32(mmio_, base_ + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 0x40); + EXPECT_ABS_READ32(mmio_, base_ + RSTMGR_ALERT_INFO_REG_OFFSET, 5); + + EXPECT_ABS_READ32(mmio_, base_ + RSTMGR_RESET_INFO_REG_OFFSET, 0x12345); + + EXPECT_EQ(rstmgr_reason_get(), 0x12345); + EXPECT_EQ(rstmgr_alert_info.length, 5); + EXPECT_THAT(rstmgr_alert_info.info, + ElementsAre(1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); +} + +TEST_F(RstmgrTest, EnableAlertInfo) { + EXPECT_ABS_WRITE32(mmio_, base_ + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 1); + rstmgr_alert_info_enable(); +} + +} // namespace +} // namespace rstmgr_unittest