1717 #include "memfault/panics/arch/riscv/riscv.h"
1818 #include "memfault/panics/coredump.h"
1919 #include "memfault/panics/coredump_impl.h"
20+ #include "memfault/panics/fault_handling.h"
2021
2122const sMfltCoredumpRegion * memfault_coredump_get_arch_regions (size_t * num_regions ) {
2223 * num_regions = 0 ;
@@ -42,6 +43,60 @@ void memfault_arch_fault_handling_assert(void *pc, void *lr, eMemfaultRebootReas
4243 prv_fault_handling_assert (pc , lr , reason );
4344}
4445
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+
45100void memfault_fault_handler (const sMfltRegState * regs , eMemfaultRebootReason reason ) {
46101 if (s_crash_reason == kMfltRebootReason_Unknown ) {
47102 // TODO confirm this works correctly- we should have the correct
@@ -56,7 +111,8 @@ void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason rea
56111 };
57112
58113 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 ],
60116 .trace_reason = save_info .trace_reason ,
61117 .exception_reg_state = regs ,
62118 };
@@ -66,6 +122,11 @@ void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason rea
66122 if (coredump_saved ) {
67123 memfault_reboot_tracking_mark_coredump_saved ();
68124 }
125+
126+ #if !MEMFAULT_FAULT_HANDLER_RETURN
127+ memfault_platform_reboot ();
128+ MEMFAULT_UNREACHABLE ;
129+ #endif
69130}
70131
71132size_t memfault_coredump_storage_compute_size_required (void ) {
0 commit comments