Software APIs
irq_asm_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/retention_sram.h"
19 #include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
20 #include "sw/device/silicon_creator/lib/error.h"
21 
23 
24 /**
25  * Exception handler written in assembly.
26  *
27  * Resets the device using the watchdog timer. Does not return.
28  */
29 extern noreturn void _asm_exception_handler(void);
30 
31 OTTF_DEFINE_TEST_CONFIG();
32 
33 // The test phases are tracked in retention RAM so that we ensure the reset
34 // happened in the correct phase of the test.
35 typedef enum TestPhase {
36  kTestPhaseInit = 0,
37  kTestPhaseReset = 1,
38  kTestPhaseDone = 2,
39 } test_phase_t;
40 
41 bool test_main(void) {
42  uint32_t reason = rstmgr_testutils_reason_get();
43  LOG_INFO("reset_info = %08x", reason);
44 
45  // Clear the existing reset reason(s) so that they do not appear after the
46  // next reset.
47  rstmgr_testutils_reason_clear();
48 
49  // Use the part of the retention SRAM reserved for the silicon owner to
50  // store the test phase.
51  uint32_t *phase = &retention_sram_get()->owner.reserved[0];
52 
53  if (bitfield_bit32_read(reason, kRstmgrReasonPowerOn)) {
54  // First execution after bootstrap: Zero out the retention RAM.
55  retention_sram_clear();
56 
57  LOG_INFO("Calling exception handler to reset device.");
58  *phase = kTestPhaseReset;
59  _asm_exception_handler();
60 
61  CHECK(false); // Unreachable.
62  } else if (bitfield_bit32_read(reason, kRstmgrReasonSoftwareRequest)) {
63  // Software reset: check that the test phase is correct.
64  CHECK(bitfield_popcount32(reason) == 1, "Expected exactly 1 reset reason.");
65  LOG_INFO("Detected reset after exception test");
66  if (*phase != kTestPhaseReset) {
67  LOG_ERROR("Test failure: expected phase %d but got phase %d",
68  kTestPhaseReset, *phase);
69  } else {
70  return true; // Pass.
71  }
72  } else {
73  LOG_ERROR("Unknown reset reason");
74  }
75  return false; // Fail.
76 }