Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 1 | // Copyright lowRISC contributors. |
| 2 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 3 | // SPDX-License-Identifier: Apache-2.0 |
| 4 | |
| 5 | #include "sw/device/lib/base/abs_mmio.h" |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 6 | #include "sw/device/lib/base/macros.h" |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 7 | #include "sw/device/lib/base/mmio.h" |
| 8 | #include "sw/device/lib/dif/dif_pwrmgr.h" |
| 9 | #include "sw/device/lib/dif/dif_rstmgr.h" |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 10 | #include "sw/device/lib/dif/dif_rv_core_ibex.h" |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 11 | #include "sw/device/lib/runtime/log.h" |
| 12 | #include "sw/device/lib/testing/aon_timer_testutils.h" |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 13 | #include "sw/device/lib/testing/rstmgr_testutils.h" |
| 14 | #include "sw/device/lib/testing/test_framework/check.h" |
| 15 | #include "sw/device/lib/testing/test_framework/ottf_isrs.h" |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 16 | #include "sw/device/lib/testing/test_framework/ottf_main.h" |
| 17 | |
| 18 | #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" |
| 19 | |
Alphan Ulusoy | 1801d3f | 2022-06-17 12:56:57 -0400 | [diff] [blame] | 20 | OTTF_DEFINE_TEST_CONFIG(); |
| 21 | |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 22 | /** |
| 23 | * RSTMGR CPU INFO TEST |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 24 | * |
| 25 | * This has three stages: |
| 26 | * |
| 27 | * 1. After the first startup, a illegal memory access is performed. |
| 28 | * In the exception handler, a software reset is triggered. |
| 29 | * |
| 30 | * 2. After the software reset, the CPU info dump is checked against |
| 31 | * the expected values for this single fault. The watch dog is then set up |
| 32 | * and another illegal memory access is performed. Only this time |
| 33 | * the exception handler performs another illegal read. |
| 34 | * Causing the ibex to be haulted by the alert handler. |
| 35 | * The watch dog will eventually trigger a reset. |
| 36 | * |
| 37 | * 3. After the watchdog reset, the CPU info dump is checked against |
| 38 | * the expected values for this double fault. |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 39 | */ |
| 40 | |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 41 | // CPU Dump Size and Unmapped Addresses. |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 42 | enum { |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 43 | kCpuDumpSize = 8, |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 44 | kIllegalAddr0 = 0xF0000000, |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 45 | kIllegalAddr1 = 0xF0000004, |
Timothy Chen | 9b3ebf4 | 2022-11-02 23:24:43 -0700 | [diff] [blame] | 46 | kIllegalAddr2 = 0x00000008, |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 47 | }; |
| 48 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 49 | // Declaring the labels used to calculate the expected current and next pc |
| 50 | // after a double fault. |
Timothy Chen | 9b3ebf4 | 2022-11-02 23:24:43 -0700 | [diff] [blame] | 51 | extern const uint32_t _ottf_interrupt_vector; |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 52 | |
| 53 | // The labels to points in the code of which the memory address is needed. |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 54 | extern const char kSingleFaultAddrLower[]; |
| 55 | extern const char kSingleFaultAddrUpper[]; |
| 56 | extern const char kSingleFaultAddrCurrentPc[]; |
| 57 | extern const char kSingleFaultAddrNextPc[]; |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 58 | extern const char kDoubleFaultFirstAddrLower[]; |
| 59 | extern const char kDoubleFaultFirstAddrUpper[]; |
| 60 | extern const char kDoubleFaultSecondAddrLower[]; |
| 61 | extern const char kDoubleFaultSecondAddrUpper[]; |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 62 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 63 | // A handle to the reset manager. |
| 64 | static dif_rstmgr_t rstmgr; |
| 65 | |
| 66 | // This variable is used to ensure loads from an address aren't optimised out. |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 67 | volatile static uint32_t addr_val; |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 68 | |
| 69 | /** |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 70 | * When true, the exception handler will trigger another fault, |
| 71 | * causing a double fault, |
| 72 | * otherwise it triggers a software reset. |
| 73 | */ |
| 74 | volatile static bool double_fault; |
| 75 | |
| 76 | /** |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 77 | * Overrides the default OTTF exception handler. |
| 78 | */ |
| 79 | void ottf_exception_handler(void) { |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 80 | if (double_fault) { |
| 81 | OT_ADDRESSABLE_LABEL(kDoubleFaultSecondAddrLower); |
Timothy Chen | 9b3ebf4 | 2022-11-02 23:24:43 -0700 | [diff] [blame] | 82 | mmio_region_write32(mmio_region_from_addr(kIllegalAddr2), 0, 0); |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 83 | OT_ADDRESSABLE_LABEL(kDoubleFaultSecondAddrUpper); |
| 84 | } else { |
| 85 | CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr)); |
| 86 | // Write to `addr_val` so that the 'last data access' address is |
| 87 | // a known value (the address of addr_val). |
| 88 | addr_val = 1; |
| 89 | OT_ADDRESSABLE_LABEL(kSingleFaultAddrCurrentPc); |
| 90 | wait_for_interrupt(); // Wait for the reset. |
| 91 | OT_ADDRESSABLE_LABEL(kSingleFaultAddrNextPc); |
| 92 | addr_val = 2; |
| 93 | } |
| 94 | CHECK(false, |
| 95 | "This point should be unreachable; " |
| 96 | "a reset or another fault should have occured."); |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 97 | } |
Timothy Chen | 69f0bbe | 2022-06-15 17:44:40 -0700 | [diff] [blame] | 98 | |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 99 | /** |
| 100 | * Gets, parses and returns the cpu info crash dump. |
| 101 | * |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 102 | * @param ibex A handle to the ibex. |
| 103 | * @return The cpu info crash dump. |
| 104 | */ |
| 105 | static dif_rv_core_ibex_crash_dump_info_t get_dump( |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 106 | const dif_rv_core_ibex_t *ibex) { |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 107 | size_t size_read; |
| 108 | dif_rstmgr_cpu_info_dump_segment_t dump[DIF_RSTMGR_CPU_INFO_MAX_SIZE]; |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 109 | |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 110 | CHECK_DIF_OK(dif_rstmgr_cpu_info_dump_read( |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 111 | &rstmgr, dump, DIF_RSTMGR_CPU_INFO_MAX_SIZE, &size_read)); |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 112 | CHECK(size_read == kCpuDumpSize, |
| 113 | "The observed cpu info dump's size was %d, " |
| 114 | "but it was expected to be %d", |
| 115 | size_read, kCpuDumpSize); |
Timothy Chen | 69f0bbe | 2022-06-15 17:44:40 -0700 | [diff] [blame] | 116 | |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 117 | dif_rv_core_ibex_crash_dump_info_t output; |
| 118 | CHECK_DIF_OK( |
| 119 | dif_rv_core_ibex_parse_crash_dump(ibex, dump, size_read, &output)); |
| 120 | return output; |
| 121 | } |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 122 | |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 123 | /** |
| 124 | * Holds the expected cpu info dump values for the current state. |
| 125 | */ |
| 126 | typedef struct rstmgr_cpu_info_test_exp_state { |
| 127 | uint32_t mtval; ///< The last exception address. |
| 128 | uint32_t mpec_l; ///< The last exception PC lower bound. |
| 129 | uint32_t mpec_u; ///< The last exception PC upper bound. |
| 130 | uint32_t mdaa; ///< The last data access address. |
| 131 | uint32_t mnpc; ///< The next PC. |
| 132 | uint32_t mcpc; ///< The current PC. |
| 133 | } rstmgr_cpu_info_test_exp_state_t; |
| 134 | |
| 135 | /** |
| 136 | * Holds the expected cpu info dump values for the previous state. |
| 137 | */ |
| 138 | typedef struct rstmgr_cpu_info_test_exp_prev_state { |
| 139 | uint32_t mtval; ///< The exception address for the previous crash. |
| 140 | uint32_t |
| 141 | mpec_l; ///< The last exception PC lower bound for the previous crash. |
| 142 | uint32_t |
| 143 | mpec_u; ///< The last exception PC upper bound for the previous crash. |
| 144 | } rstmgr_cpu_info_test_exp_prev_state_t; |
| 145 | |
| 146 | /** |
| 147 | * Checks the 'current' section of the cpu info dump against the given expected |
| 148 | * values. |
| 149 | * |
| 150 | * @param obs_state The cpu info crash dump's current state values. |
| 151 | * @param exp_state The expected values of the current state. |
| 152 | */ |
| 153 | static void check_state(dif_rv_core_ibex_crash_dump_state_t obs_state, |
| 154 | rstmgr_cpu_info_test_exp_state_t exp_state) { |
| 155 | CHECK(exp_state.mtval == obs_state.mtval, |
| 156 | "Last Exception Access Addr: Expected 0x%x != Observed 0x%x", |
| 157 | exp_state.mtval, obs_state.mtval); |
| 158 | CHECK(exp_state.mcpc == obs_state.mcpc, |
| 159 | "Current PC: Expected 0x%x != Observed 0x%x", exp_state.mcpc, |
| 160 | obs_state.mcpc); |
| 161 | CHECK(exp_state.mnpc == obs_state.mnpc, |
| 162 | "Next PC: Expected 0x%x != Observed 0x%x", exp_state.mnpc, |
| 163 | obs_state.mnpc); |
| 164 | CHECK(exp_state.mdaa == obs_state.mdaa, |
| 165 | "Last Data Access Addr: Expected 0x%x != Observed 0x%x", exp_state.mdaa, |
| 166 | obs_state.mdaa); |
| 167 | CHECK( |
| 168 | exp_state.mpec_l <= obs_state.mpec && obs_state.mpec < exp_state.mpec_u, |
| 169 | "The Observed MPEC, 0x%x, was not in the expected range of [0x%x, 0x%x)", |
| 170 | obs_state.mpec, exp_state.mpec_l, exp_state.mpec_u); |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * Checks the 'previous' section of the cpu info dump against the given expected |
| 175 | * values. |
| 176 | * |
| 177 | * @param obs_prev_state The cpu info crash dump's previous state values. |
| 178 | * @param exp_prev_state The expected values of the previous state. |
| 179 | */ |
| 180 | static void check_prev_state( |
| 181 | dif_rv_core_ibex_previous_crash_dump_state_t obs_prev_state, |
| 182 | rstmgr_cpu_info_test_exp_prev_state_t exp_prev_state) { |
| 183 | CHECK(exp_prev_state.mtval == obs_prev_state.mtval, |
| 184 | "Last Exception Access Addr: Expected 0x%x != Observed 0x%x", |
| 185 | exp_prev_state.mtval, obs_prev_state.mtval); |
| 186 | CHECK(exp_prev_state.mpec_l <= obs_prev_state.mpec && |
| 187 | obs_prev_state.mpec < exp_prev_state.mpec_u, |
| 188 | "The Observed Previous MPEC, 0x%x, " |
| 189 | "was not in the expected range of [0x%x, 0x%x)", |
| 190 | obs_prev_state.mpec, exp_prev_state.mpec_l, exp_prev_state.mpec_u); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | bool test_main(void) { |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 194 | dif_rv_core_ibex_crash_dump_info_t dump; |
| 195 | |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 196 | dif_aon_timer_t aon_timer; |
| 197 | dif_pwrmgr_t pwrmgr; |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 198 | dif_rv_core_ibex_t ibex; |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 199 | |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 200 | // Initialize Handles. |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 201 | CHECK_DIF_OK(dif_rstmgr_init( |
| 202 | mmio_region_from_addr(TOP_EARLGREY_RSTMGR_AON_BASE_ADDR), &rstmgr)); |
| 203 | CHECK_DIF_OK(dif_aon_timer_init( |
| 204 | mmio_region_from_addr(TOP_EARLGREY_AON_TIMER_AON_BASE_ADDR), &aon_timer)); |
| 205 | CHECK_DIF_OK(dif_pwrmgr_init( |
| 206 | mmio_region_from_addr(TOP_EARLGREY_PWRMGR_AON_BASE_ADDR), &pwrmgr)); |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 207 | CHECK_DIF_OK(dif_rv_core_ibex_init( |
| 208 | mmio_region_from_addr(TOP_EARLGREY_RV_CORE_IBEX_CFG_BASE_ADDR), &ibex)); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 209 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 210 | switch (rstmgr_testutils_reason_get()) { |
| 211 | case kDifRstmgrResetInfoPor: // The first power-up. |
| 212 | LOG_INFO("Triggering single fault."); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 213 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 214 | // Enable cpu info. |
| 215 | CHECK_DIF_OK(dif_rstmgr_cpu_info_set_enabled(&rstmgr, kDifToggleEnabled)); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 216 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 217 | double_fault = false; |
| 218 | OT_ADDRESSABLE_LABEL(kSingleFaultAddrLower); |
| 219 | addr_val = mmio_region_read32(mmio_region_from_addr(kIllegalAddr0), 0); |
| 220 | OT_ADDRESSABLE_LABEL(kSingleFaultAddrUpper); |
| 221 | CHECK(false, |
| 222 | "This should be unreachable; a single fault should have occured."); |
| 223 | break; |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 224 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 225 | case kDifRstmgrResetInfoSw: // The power-up after the single fault. |
| 226 | LOG_INFO("Checking CPU info dump after single fault."); |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 227 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 228 | dump = get_dump(&ibex); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 229 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 230 | CHECK( |
| 231 | dump.double_fault == kDifToggleDisabled, |
| 232 | "CPU Info dump shows a double fault after experiencing only a single " |
| 233 | "fault."); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 234 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 235 | check_state(dump.fault_state, |
| 236 | (rstmgr_cpu_info_test_exp_state_t){ |
| 237 | .mtval = (uint32_t)kIllegalAddr0, |
| 238 | .mpec_l = (uint32_t)kSingleFaultAddrLower, |
| 239 | .mpec_u = (uint32_t)kSingleFaultAddrUpper, |
| 240 | .mdaa = (uint32_t)&addr_val, |
| 241 | .mcpc = (uint32_t)kSingleFaultAddrCurrentPc, |
| 242 | .mnpc = (uint32_t)kSingleFaultAddrNextPc, |
| 243 | }); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 244 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 245 | LOG_INFO("Setting up watch dog and triggering a double fault."); |
| 246 | uint32_t bark_cycles = aon_timer_testutils_get_aon_cycles_from_us(100); |
| 247 | uint32_t bite_cycles = aon_timer_testutils_get_aon_cycles_from_us(100); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 248 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 249 | // Set wdog as a reset source. |
| 250 | CHECK_DIF_OK(dif_pwrmgr_set_request_sources( |
| 251 | &pwrmgr, kDifPwrmgrReqTypeReset, kDifPwrmgrResetRequestSourceTwo, |
| 252 | kDifToggleEnabled)); |
| 253 | // Setup the watchdog bark and bite timeouts. |
| 254 | aon_timer_testutils_watchdog_config(&aon_timer, bark_cycles, bite_cycles, |
| 255 | false); |
| 256 | // Enable cpu info. |
| 257 | CHECK_DIF_OK(dif_rstmgr_cpu_info_set_enabled(&rstmgr, kDifToggleEnabled)); |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 258 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 259 | double_fault = true; |
| 260 | OT_ADDRESSABLE_LABEL(kDoubleFaultFirstAddrLower); |
| 261 | addr_val = mmio_region_read32(mmio_region_from_addr(kIllegalAddr1), 0); |
| 262 | OT_ADDRESSABLE_LABEL(kDoubleFaultFirstAddrUpper); |
| 263 | CHECK(false, |
| 264 | "This should be unreachable; a double fault should have occured."); |
| 265 | break; |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 266 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 267 | case kDifRstmgrResetInfoWatchdog: // The power-up after the double fault. |
| 268 | LOG_INFO("Checking CPU info dump after double fault."); |
| 269 | |
| 270 | dump = get_dump(&ibex); |
| 271 | |
| 272 | CHECK(dump.double_fault == kDifToggleEnabled, |
| 273 | "CPU Info dump doesn't show a double fault has happened."); |
| 274 | |
Timothy Chen | 9b3ebf4 | 2022-11-02 23:24:43 -0700 | [diff] [blame] | 275 | // After #15219 was merged, the execution stops more predictably |
| 276 | // once fetch_en is dropped due to a double fault. |
| 277 | // The current pc should now always be the instruction after the |
| 278 | // instruction that issues the illegal load. |
| 279 | // The next pc is always the exception handler, because that's |
| 280 | // where execution would have gone if it had not halted |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 281 | check_state(dump.fault_state, |
| 282 | (rstmgr_cpu_info_test_exp_state_t){ |
| 283 | .mtval = (uint32_t)kIllegalAddr2, |
| 284 | .mpec_l = (uint32_t)kDoubleFaultSecondAddrLower, |
| 285 | .mpec_u = (uint32_t)kDoubleFaultSecondAddrUpper, |
| 286 | .mdaa = (uint32_t)kIllegalAddr2, |
Timothy Chen | 9b3ebf4 | 2022-11-02 23:24:43 -0700 | [diff] [blame] | 287 | .mcpc = (uint32_t)kDoubleFaultSecondAddrLower + 4, |
| 288 | .mnpc = (uint32_t)&_ottf_interrupt_vector, |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 289 | }); |
| 290 | |
| 291 | check_prev_state(dump.previous_fault_state, |
| 292 | (rstmgr_cpu_info_test_exp_prev_state_t){ |
| 293 | .mtval = (uint32_t)kIllegalAddr1, |
| 294 | .mpec_l = (uint32_t)kDoubleFaultFirstAddrLower, |
| 295 | .mpec_u = (uint32_t)kDoubleFaultFirstAddrUpper, |
| 296 | }); |
| 297 | |
Hugo McNally | 62c7b50 | 2022-10-17 20:35:48 +0100 | [diff] [blame] | 298 | return true; |
| 299 | |
| 300 | default: |
| 301 | CHECK(false, "Device was reset by an unexpected source."); |
| 302 | break; |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 303 | } |
Hugo McNally | 8c57b1f | 2022-09-29 11:33:09 +0100 | [diff] [blame] | 304 | return false; |
Jaedon Kim | a7bd795 | 2022-05-02 21:25:31 +0000 | [diff] [blame] | 305 | } |