17
17
#include "memfault/panics/arch/riscv/riscv.h"
18
18
#include "memfault/panics/coredump.h"
19
19
#include "memfault/panics/coredump_impl.h"
20
+ #include "memfault/panics/fault_handling.h"
20
21
21
22
const sMfltCoredumpRegion * memfault_coredump_get_arch_regions (size_t * num_regions ) {
22
23
* num_regions = 0 ;
@@ -42,6 +43,60 @@ void memfault_arch_fault_handling_assert(void *pc, void *lr, eMemfaultRebootReas
42
43
prv_fault_handling_assert (pc , lr , reason );
43
44
}
44
45
46
+ // For non-esp-idf riscv implementations, provide a full assert handler and
47
+ // other utilities.
48
+ #if defined(__ZEPHYR__ ) && defined(CONFIG_SOC_FAMILY_ESP32 )
49
+ #include <hal/cpu_hal.h>
50
+ #include <zephyr/kernel.h>
51
+
52
+ void memfault_platform_halt_if_debugging (void ) {
53
+ if (cpu_ll_is_debugger_attached ()) {
54
+ MEMFAULT_BREAKPOINT ();
55
+ }
56
+ }
57
+
58
+ bool memfault_arch_is_inside_isr (void ) {
59
+ // Use the Zephyr-specific implementation.
60
+ //
61
+ // It's not clear if there's a RISC-V standard way to check if the CPU is in
62
+ // an exception mode. The mcause register comes close but it won't tell us if
63
+ // a trap was taken due to a non-interrupt cause:
64
+ // https://five-embeddev.com/riscv-isa-manual/latest/machine.html#sec:mcause
65
+ return k_is_in_isr ();
66
+ }
67
+
68
+ static void prv_fault_handling_assert_native (void * pc , void * lr , eMemfaultRebootReason reason ) {
69
+ prv_fault_handling_assert (pc , lr , reason );
70
+
71
+ #if MEMFAULT_ASSERT_HALT_IF_DEBUGGING_ENABLED
72
+ memfault_platform_halt_if_debugging ();
73
+ #endif
74
+
75
+ // dereference a null pointer to trigger fault
76
+ * (uint32_t * )0 = 0x77 ;
77
+
78
+ // We just trap'd into the fault handler logic so it should never be possible to get here but if
79
+ // we do the best thing that can be done is rebooting the system to recover it.
80
+ memfault_platform_reboot ();
81
+ }
82
+
83
+ MEMFAULT_NO_OPT void memfault_fault_handling_assert_extra (void * pc , void * lr ,
84
+ sMemfaultAssertInfo * extra_info ) {
85
+ prv_fault_handling_assert_native (pc , lr , extra_info -> assert_reason );
86
+
87
+ MEMFAULT_UNREACHABLE ;
88
+ }
89
+
90
+ MEMFAULT_NO_OPT void memfault_fault_handling_assert (void * pc , void * lr ) {
91
+ prv_fault_handling_assert_native (pc , lr , kMfltRebootReason_Assert );
92
+
93
+ MEMFAULT_UNREACHABLE ;
94
+ }
95
+
96
+ #elif !defined(ESP_PLATFORM )
97
+ #error "Unsupported RISC-V platform, please contact
[email protected] "
98
+ #endif // !defined(ESP_PLATFORM) && defined(__ZEPHYR__)
99
+
45
100
void memfault_fault_handler (const sMfltRegState * regs , eMemfaultRebootReason reason ) {
46
101
if (s_crash_reason == kMfltRebootReason_Unknown ) {
47
102
// TODO confirm this works correctly- we should have the correct
@@ -56,7 +111,8 @@ void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason rea
56
111
};
57
112
58
113
sCoredumpCrashInfo info = {
59
- .stack_address = (void * )regs -> sp ,
114
+ // Zephyr fault shim saves the stack pointer in s[0]
115
+ .stack_address = (void * )regs -> s [0 ],
60
116
.trace_reason = save_info .trace_reason ,
61
117
.exception_reg_state = regs ,
62
118
};
@@ -66,6 +122,11 @@ void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason rea
66
122
if (coredump_saved ) {
67
123
memfault_reboot_tracking_mark_coredump_saved ();
68
124
}
125
+
126
+ #if !MEMFAULT_FAULT_HANDLER_RETURN
127
+ memfault_platform_reboot ();
128
+ MEMFAULT_UNREACHABLE ;
129
+ #endif
69
130
}
70
131
71
132
size_t memfault_coredump_storage_compute_size_required (void ) {
0 commit comments