Software APIs
alert_functest.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include <stdbool.h>
6 #include <stdint.h>
7 
15 #include "sw/device/lib/testing/rstmgr_testutils.h"
16 #include "sw/device/lib/testing/test_framework/check.h"
18 #include "sw/device/silicon_creator/lib/drivers/alert.h"
19 #include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
20 #include "sw/device/silicon_creator/lib/error.h"
21 
22 #include "alert_handler_regs.h"
23 #include "flash_ctrl_regs.h"
25 #include "otp_ctrl_regs.h"
26 #include "rstmgr_regs.h"
27 
28 enum {
32 };
33 
34 rom_error_t alert_no_escalate_test(void) {
35  // Configure class B alerts for phase 0 only and disable NMI signalling.
36  alert_class_config_t config = {
37  .enabled = kAlertEnableEnabled,
38  .escalation = kAlertEscalatePhase0,
39  .accum_threshold = 0,
40  .timeout_cycles = 0,
41  .phase_cycles = {1, 10, 100, 1000},
42  };
43  LOG_INFO("Configure OtpCtrlFatalMacroError as class B");
44  RETURN_IF_ERROR(alert_configure(kTopEarlgreyAlertIdOtpCtrlFatalMacroError,
45  kAlertClassB, kAlertEnableLocked));
46  LOG_INFO("Configure class B alerts");
47  RETURN_IF_ERROR(alert_class_configure(kAlertClassB, &config));
48 
49  LOG_INFO("Generate alert via test regs");
50  abs_mmio_write32(kOtpCoreBase + OTP_CTRL_ALERT_TEST_REG_OFFSET, 1);
51  uint32_t count =
52  abs_mmio_read32(kAlertBase + ALERT_HANDLER_CLASSB_ACCUM_CNT_REG_OFFSET);
53  return count == 1 ? kErrorOk : kErrorUnknown;
54 }
55 
56 rom_error_t alert_escalate_test(void) {
57  // Configure class A alerts for full escalation.
58  alert_class_config_t config = {
59  .enabled = kAlertEnableEnabled,
60  .escalation = kAlertEscalatePhase3,
61  .accum_threshold = 0,
62  .timeout_cycles = 0,
63  .phase_cycles = {1, 10, 100, 1000},
64  };
65 
66  LOG_INFO("Configure FlashCtrlFatalErr as class A");
67  RETURN_IF_ERROR(alert_configure(kTopEarlgreyAlertIdFlashCtrlFatalErr,
68  kAlertClassA, kAlertEnableEnabled));
69  LOG_INFO("Configure class A alerts");
70  RETURN_IF_ERROR(alert_class_configure(kAlertClassA, &config));
71 
72  LOG_INFO("Generate alert via test regs");
73  abs_mmio_write32(kFlashBase + FLASH_CTRL_ALERT_TEST_REG_OFFSET,
74  1u << FLASH_CTRL_ALERT_TEST_FATAL_ERR_BIT);
75  return kErrorUnknown;
76 }
77 
78 OTTF_DEFINE_TEST_CONFIG();
79 
80 bool test_main(void) {
81  status_t result = OK_STATUS();
82  uint32_t reason = rstmgr_testutils_reason_get();
83  rstmgr_alert_info_enable();
84  LOG_INFO("reset_info = %08x", reason);
85 
86  // Clear the existing reset reason(s) so that they do not appear after the
87  // next reset.
88  rstmgr_testutils_reason_clear();
89 
90  if (bitfield_bit32_read(reason, kRstmgrReasonPowerOn)) {
91  EXECUTE_TEST(result, alert_no_escalate_test);
92  EXECUTE_TEST(result, alert_escalate_test);
93  LOG_ERROR("Test failure: should have reset before this line.");
94  result = UNKNOWN();
95  } else if (bitfield_bit32_read(reason, kRstmgrReasonEscalation)) {
96  CHECK(bitfield_popcount32(reason) == 1, "Expected exactly 1 reset reason.");
97  LOG_INFO("Detected reset after escalation test");
98  } else {
99  LOG_ERROR("Unknown reset reason");
100  result = UNKNOWN();
101  }
102  return status_ok(result);
103 }