From c8c9e52be9cfb7bd2144060ed0b2373c0c541472 Mon Sep 17 00:00:00 2001
From: Angus Gratton <gus@projectgus.com>
Date: Sat, 7 May 2016 19:14:48 +1000
Subject: [PATCH] fatal exception handler: Only dump "registers" from stack for
 fatal user exceptions

---
 core/debug_dumps.c         | 12 +++++++-----
 core/exception_vectors.S   |  5 +++++
 core/include/debug_dumps.h |  2 +-
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/core/debug_dumps.c b/core/debug_dumps.c
index 7bea87a..15396ac 100644
--- a/core/debug_dumps.c
+++ b/core/debug_dumps.c
@@ -23,7 +23,7 @@
 /* Forward declarations */
 static void IRAM fatal_handler_prelude(void);
 /* Inner parts of crash handlers marked noinline to ensure they don't inline into IRAM. */
-static void __attribute__((noinline)) __attribute__((noreturn)) fatal_exception_handler_inner(uint32_t *sp);
+static void __attribute__((noinline)) __attribute__((noreturn)) fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_stack);
 static void __attribute__((noinline)) __attribute__((noreturn)) abort_handler_inner(uint32_t *caller, uint32_t *sp);
 
 /* fatal_exception_handler called from any unhandled user exception
@@ -34,9 +34,9 @@ static void __attribute__((noinline)) __attribute__((noreturn)) abort_handler_in
  * runs from flash after fatal_handler_prelude ensures it is mapped
  * safely.
  */
-void IRAM __attribute__((noreturn)) fatal_exception_handler(uint32_t *sp) {
+void IRAM __attribute__((noreturn)) fatal_exception_handler(uint32_t *sp, bool registers_saved_on_stack) {
     fatal_handler_prelude();
-    fatal_exception_handler_inner(sp);
+    fatal_exception_handler_inner(sp, registers_saved_on_stack);
 }
 
 /* Abort implementation
@@ -148,10 +148,12 @@ static void IRAM fatal_handler_prelude(void) {
 /* Main part of fatal exception handler, is run from flash to save
    some IRAM.
 */
-static void fatal_exception_handler_inner(uint32_t *sp) {
+static void fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_stack) {
     dump_excinfo();
     if (sp) {
-        dump_registers_in_exception_handler(sp);
+        if (registers_saved_on_stack) {
+            dump_registers_in_exception_handler(sp);
+        }
         dump_stack(sp);
     }
     uart_flush_txfifo(0);
diff --git a/core/exception_vectors.S b/core/exception_vectors.S
index ba8fb25..000e742 100644
--- a/core/exception_vectors.S
+++ b/core/exception_vectors.S
@@ -69,6 +69,7 @@ DebugExceptionVector:
 
         wsr     a0, excsave2
         mov     a2, a1
+        movi    a3, 0
         call0   fatal_exception_handler
         rfi     2
 
@@ -83,6 +84,7 @@ KernelExceptionVector:
 
         break   1, 0
         mov     a2, a1
+        movi    a3, 0
         call0   fatal_exception_handler
         rfe
 
@@ -101,6 +103,7 @@ DoubleExceptionVector:
 
         break   1, 4
         mov     a2, a1
+        movi    a3, 0
         call0   fatal_exception_handler
 
 /* Reset vector at offset 0x80 is unused, as vecbase gets reset to mask ROM
@@ -259,6 +262,7 @@ LoadStoreErrorHandler:
         l32i    a4, sp, 0x10
         rsr     a1, excsave1
         mov     a2, a1
+        movi    a3, 0
         call0   fatal_exception_handler
 
         .balign 4
@@ -520,6 +524,7 @@ UserExceptionHandler:
 .LUserFailOtherExceptionCause:
         break   1, 1
         addi    a2, a1, 0x50 /* UserExceptionHandler pushes stack down 0x50 */
+        movi    a3, 1
         call0   fatal_exception_handler
 
 /* _xt_user_exit is pushed onto the stack as part of the user exception handler,
diff --git a/core/include/debug_dumps.h b/core/include/debug_dumps.h
index 1a76d26..809b87a 100644
--- a/core/include/debug_dumps.h
+++ b/core/include/debug_dumps.h
@@ -17,6 +17,6 @@ void dump_stack(uint32_t *sp);
 
    Probably not useful to be called in other contexts.
 */
-void __attribute__((noreturn)) fatal_exception_handler(uint32_t *sp);
+void __attribute__((noreturn)) fatal_exception_handler(uint32_t *sp, bool registers_saved_on_stack);
 
 #endif