[sw/silicon_creator] Add rstmgr_reset() and functest
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/drivers/meson.build b/sw/device/silicon_creator/lib/drivers/meson.build
index bf761df..090375c 100644
--- a/sw/device/silicon_creator/lib/drivers/meson.build
+++ b/sw/device/silicon_creator/lib/drivers/meson.build
@@ -201,6 +201,54 @@
suite: 'mask_rom',
)
+# Mask ROM retention SRAM driver
+sw_silicon_creator_lib_driver_retention_sram = declare_dependency(
+ link_with: static_library(
+ 'sw_silicon_creator_lib_driver_retention_sram',
+ sources: [
+ hw_ip_sram_ctrl_reg_h,
+ 'retention_sram.c',
+ ],
+ dependencies: [
+ sw_silicon_creator_lib_base_abs_mmio,
+ ],
+ ),
+)
+
+test('sw_silicon_creator_lib_driver_retention_sram_unittest', executable(
+ 'sw_silicon_creator_lib_driver_retention_sram_unittest',
+ sources: [
+ 'retention_sram_unittest.cc',
+ hw_ip_sram_ctrl_reg_h,
+ 'retention_sram.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',
+)
+
+sw_silicon_creator_lib_driver_retention_sram_functest = declare_dependency(
+ link_with: static_library(
+ 'sw_silicon_creator_lib_driver_retention_sram_functest',
+ sources: ['retention_sram_functest.c'],
+ dependencies: [
+ sw_silicon_creator_lib_driver_retention_sram,
+ ],
+ ),
+)
+mask_rom_tests += {
+ 'sw_silicon_creator_lib_driver_retention_sram_functest': {
+ 'library': sw_silicon_creator_lib_driver_retention_sram_functest,
+ }
+}
+
+
# Mask ROM rstmgr driver
sw_silicon_creator_lib_driver_rstmgr = declare_dependency(
link_with: static_library(
@@ -227,12 +275,33 @@
sw_silicon_creator_lib_base_mock_abs_mmio,
],
native: true,
- c_args: ['-DMOCK_ABS_MMIO'],
- cpp_args: ['-DMOCK_ABS_MMIO'],
+ c_args: ['-DMOCK_ABS_MMIO', '-DOT_OFF_TARGET_TEST'],
+ cpp_args: ['-DMOCK_ABS_MMIO', '-DOT_OFF_TARGET_TEST'],
),
suite: 'mask_rom',
)
+
+sw_silicon_creator_lib_driver_rstmgr_functest = declare_dependency(
+ link_with: static_library(
+ 'sw_silicon_creator_lib_driver_rstmgr_functest',
+ sources: [
+ hw_ip_rstmgr_reg_h,
+ 'rstmgr_functest.c'
+ ],
+ dependencies: [
+ sw_silicon_creator_lib_base_abs_mmio,
+ sw_silicon_creator_lib_driver_rstmgr,
+ sw_silicon_creator_lib_driver_retention_sram,
+ ],
+ ),
+)
+mask_rom_tests += {
+ 'sw_silicon_creator_lib_driver_rstmgr_functest': {
+ 'library': sw_silicon_creator_lib_driver_rstmgr_functest,
+ }
+}
+
# Mask ROM alert handler driver
sw_silicon_creator_lib_driver_alert = declare_dependency(
link_with: static_library(
@@ -321,53 +390,6 @@
suite: 'mask_rom',
)
-# Mask ROM retention SRAM driver
-sw_silicon_creator_lib_driver_retention_sram = declare_dependency(
- link_with: static_library(
- 'sw_silicon_creator_lib_driver_retention_sram',
- sources: [
- hw_ip_sram_ctrl_reg_h,
- 'retention_sram.c',
- ],
- dependencies: [
- sw_silicon_creator_lib_base_abs_mmio,
- ],
- ),
-)
-
-test('sw_silicon_creator_lib_driver_retention_sram_unittest', executable(
- 'sw_silicon_creator_lib_driver_retention_sram_unittest',
- sources: [
- 'retention_sram_unittest.cc',
- hw_ip_sram_ctrl_reg_h,
- 'retention_sram.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',
-)
-
-sw_silicon_creator_lib_driver_retention_sram_functest = declare_dependency(
- link_with: static_library(
- 'sw_silicon_creator_lib_driver_retention_sram_functest',
- sources: ['retention_sram_functest.c'],
- dependencies: [
- sw_silicon_creator_lib_driver_retention_sram,
- ],
- ),
-)
-mask_rom_tests += {
- 'sw_silicon_creator_lib_driver_retention_sram_functest': {
- 'library': sw_silicon_creator_lib_driver_retention_sram_functest,
- }
-}
-
# Mask ROM watchdog driver
sw_silicon_creator_lib_driver_watchdog = declare_dependency(
link_with: static_library(
diff --git a/sw/device/silicon_creator/lib/drivers/rstmgr.c b/sw/device/silicon_creator/lib/drivers/rstmgr.c
index 3a898b5..bd8e186 100644
--- a/sw/device/silicon_creator/lib/drivers/rstmgr.c
+++ b/sw/device/silicon_creator/lib/drivers/rstmgr.c
@@ -7,6 +7,9 @@
#include <assert.h>
#include "sw/device/lib/base/bitfield.h"
+#include "sw/device/lib/base/macros.h"
+#include "sw/device/lib/base/multibits.h"
+#include "sw/device/lib/runtime/hart.h"
#include "sw/device/silicon_creator/lib/base/abs_mmio.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
@@ -68,9 +71,19 @@
}
void rstmgr_reason_clear(uint32_t reasons) {
- return abs_mmio_write32(kBase + RSTMGR_RESET_INFO_REG_OFFSET, reasons);
+ abs_mmio_write32(kBase + RSTMGR_RESET_INFO_REG_OFFSET, reasons);
}
void rstmgr_alert_info_enable(void) {
abs_mmio_write32(kBase + RSTMGR_ALERT_INFO_CTRL_REG_OFFSET, 1);
}
+
+void rstmgr_reset(void) {
+ abs_mmio_write32(kBase + RSTMGR_RESET_REQ_REG_OFFSET, kMultiBitBool4True);
+#ifdef OT_PLATFORM_RV32
+ // Wait until the chip resets.
+ while (true) {
+ wait_for_interrupt();
+ }
+#endif
+}
diff --git a/sw/device/silicon_creator/lib/drivers/rstmgr.h b/sw/device/silicon_creator/lib/drivers/rstmgr.h
index 5c9e82f..1b9c13b 100644
--- a/sw/device/silicon_creator/lib/drivers/rstmgr.h
+++ b/sw/device/silicon_creator/lib/drivers/rstmgr.h
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <stdnoreturn.h>
#ifdef __cplusplus
extern "C" {
@@ -94,6 +95,16 @@
*/
void rstmgr_alert_info_enable(void);
+/**
+ * Requests a system reset.
+ */
+#ifndef OT_OFF_TARGET_TEST
+// Omit `noreturn` to be able to test this function in off-target tests.
+noreturn
+#endif
+ void
+ rstmgr_reset(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/sw/device/silicon_creator/lib/drivers/rstmgr_functest.c b/sw/device/silicon_creator/lib/drivers/rstmgr_functest.c
new file mode 100644
index 0000000..6eadc13
--- /dev/null
+++ b/sw/device/silicon_creator/lib/drivers/rstmgr_functest.c
@@ -0,0 +1,53 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/check.h"
+#include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
+#include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
+#include "sw/device/silicon_creator/lib/error.h"
+#include "sw/device/silicon_creator/lib/test_main.h"
+
+const test_config_t kTestConfig;
+
+/**
+ * Test phases tracked in retention RAM.
+ */
+enum {
+ kTestPhaseInit = 0,
+ kTestPhaseReset = 1,
+ kTestPhaseDone = 2,
+};
+
+bool test_main(void) {
+ // Read and clear reset reason.
+ uint32_t reason = rstmgr_reason_get();
+ rstmgr_reason_clear(reason);
+ LOG_INFO("Reset reason: 0x%08x", reason);
+ // This test assumes that reset reason is unique.
+ CHECK(bitfield_popcount32(reason) == 1, "Expected exactly 1 reset reason.");
+
+ // Use the part of the retention RAM reserved for the silicon owner to store
+ // the test phase.
+ volatile uint32_t *phase = &retention_sram_get()->reserved_owner[0];
+
+ if (bitfield_bit32_read(reason, kRstmgrReasonPowerOn)) {
+ // Clear retention RAM on power-on reset.
+ retention_sram_clear();
+ // Request a system reset.
+ *phase = kTestPhaseReset;
+ rstmgr_reset();
+ CHECK(false, "Should have reset before this line."); // Unreachable
+ } else if (bitfield_bit32_read(reason, kRstmgrReasonSoftwareRequest)) {
+ LOG_INFO("Detected software reset.");
+ CHECK(*phase == kTestPhaseReset, "Unexpected test phase: 0x%08x", *phase);
+ *phase = kTestPhaseDone;
+ return true;
+ }
+ LOG_ERROR("Unknown reset reason: 0x%08x", reason);
+ return false;
+}
diff --git a/sw/device/silicon_creator/lib/drivers/rstmgr_unittest.cc b/sw/device/silicon_creator/lib/drivers/rstmgr_unittest.cc
index 8dccece..6edf499 100644
--- a/sw/device/silicon_creator/lib/drivers/rstmgr_unittest.cc
+++ b/sw/device/silicon_creator/lib/drivers/rstmgr_unittest.cc
@@ -6,6 +6,7 @@
#include "gtest/gtest.h"
#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/base/multibits.h"
#include "sw/device/silicon_creator/lib/base/mock_abs_mmio.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
@@ -54,5 +55,10 @@
rstmgr_alert_info_enable();
}
+TEST_F(RstmgrTest, Reset) {
+ EXPECT_ABS_WRITE32(base_ + RSTMGR_RESET_REQ_REG_OFFSET, kMultiBitBool4True);
+ rstmgr_reset();
+}
+
} // namespace
} // namespace rstmgr_unittest