From 44b4ccdfba59bbf372b0698426eb5d178c15f4c8 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 3 May 2016 15:10:46 +1000 Subject: [PATCH] Break out debug dump functions into their own compilation unit --- core/app_main.c | 70 ------------------------------ core/debug_dumps.c | 88 ++++++++++++++++++++++++++++++++++++++ core/exception_vectors.S | 10 ++--- core/include/debug_dumps.h | 29 +++++++++++++ 4 files changed, 122 insertions(+), 75 deletions(-) create mode 100644 core/debug_dumps.c create mode 100644 core/include/debug_dumps.h diff --git a/core/app_main.c b/core/app_main.c index d057598..6804ed9 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -84,8 +84,6 @@ static void IRAM set_spi0_divisor(uint32_t divisor); static void zero_bss(void); static void init_networking(uint8_t *phy_info, uint8_t *mac_addr); static void init_g_ic(void); -static void dump_excinfo(void); -static void dump_stack(uint32_t *sp); static void user_start_phase2(void); static void dump_flash_sector(uint32_t start_sector, uint32_t length); static void dump_flash_config_sectors(uint32_t start_sector); @@ -147,25 +145,6 @@ static void IRAM set_spi0_divisor(uint32_t divisor) { SPI(0).CTRL0 = SET_FIELD(SPI(0).CTRL0, SPI_CTRL0_CLOCK, clkdiv); } -// .text+0x148 -void IRAM sdk_user_fatal_exception_handler(uint32_t *sp) { - if (!sdk_NMIIrqIsOn) { - vPortEnterCritical(); - do { - DPORT.DPORT0 &= 0xffffffe0; - } while (DPORT.DPORT0 & 0x00000001); - } - Cache_Read_Disable(); - Cache_Read_Enable(0, 0, 1); - dump_excinfo(); - if (sp) - dump_stack(sp); - uart_flush_txfifo(0); - uart_flush_txfifo(1); - sdk_system_restart_in_nmi(); - halt(); -} - static void IRAM default_putc(char c) { uart_putc(0, c); @@ -335,55 +314,6 @@ static void init_g_ic(void) { } } -// .Lfunc008 -- .irom0.text+0x2a0 -static void dump_excinfo(void) { - uint32_t exccause, epc1, epc2, epc3, excvaddr, depc, excsave1; - uint32_t excinfo[8]; - - RSR(exccause, exccause); - printf("Fatal exception (%d): \n", (int)exccause); - RSR(epc1, epc1); - RSR(epc2, epc2); - RSR(epc3, epc3); - RSR(excvaddr, excvaddr); - RSR(depc, depc); - RSR(excsave1, excsave1); - printf("%s=0x%08x\n", "epc1", epc1); - printf("%s=0x%08x\n", "epc2", epc2); - printf("%s=0x%08x\n", "epc3", epc3); - printf("%s=0x%08x\n", "excvaddr", excvaddr); - printf("%s=0x%08x\n", "depc", depc); - printf("%s=0x%08x\n", "excsave1", excsave1); - sdk_system_rtc_mem_read(0, excinfo, 32); // Why? - excinfo[0] = 2; - excinfo[1] = exccause; - excinfo[2] = epc1; - excinfo[3] = epc2; - excinfo[4] = epc3; - excinfo[5] = excvaddr; - excinfo[6] = depc; - excinfo[7] = excsave1; - sdk_system_rtc_mem_write(0, excinfo, 32); -} - -/* There's a lot of smart stuff we could do while dumping stack - but for now we just dump a likely looking section of stack - memory -*/ -static void dump_stack(uint32_t *sp) { - printf("\nStack: SP=%p\n", sp); - for(uint32_t *p = sp; p < sp + 32; p += 4) { - if((intptr_t)p >= 0x3fffc000) { - break; /* approximate end of RAM */ - } - printf("%p: %08x %08x %08x %08x\n", p, p[0], p[1], p[2], p[3]); - if(p[0] == 0xa5a5a5a5 && p[1] == 0xa5a5a5a5 - && p[2] == 0xa5a5a5a5 && p[3] == 0xa5a5a5a5) { - break; /* FreeRTOS uses this pattern to mark untouched stack space */ - } - } -} - // .irom0.text+0x398 void sdk_wdt_init(void) { WDT.CTRL &= ~WDT_CTRL_ENABLE; diff --git a/core/debug_dumps.c b/core/debug_dumps.c new file mode 100644 index 0000000..6075f40 --- /dev/null +++ b/core/debug_dumps.c @@ -0,0 +1,88 @@ +/* Code for dumping status/debug output/etc, including fatal + * exception handling. + * + * Part of esp-open-rtos + * + * Partially reverse engineered from MIT licensed Espressif RTOS SDK Copyright (C) Espressif Systems. + * Additions Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#include +#include +#include +#include + +#include "debug_dumps.h" +#include "common_macros.h" +#include "xtensa_ops.h" +#include "esp/rom.h" +#include "esp/uart.h" +#include "espressif/esp_common.h" +#include "sdk_internal.h" + +void dump_excinfo(void) { + uint32_t exccause, epc1, epc2, epc3, excvaddr, depc, excsave1; + uint32_t excinfo[8]; + + RSR(exccause, exccause); + printf("Fatal exception (%d): \n", (int)exccause); + RSR(epc1, epc1); + RSR(epc2, epc2); + RSR(epc3, epc3); + RSR(excvaddr, excvaddr); + RSR(depc, depc); + RSR(excsave1, excsave1); + printf("%s=0x%08x\n", "epc1", epc1); + printf("%s=0x%08x\n", "epc2", epc2); + printf("%s=0x%08x\n", "epc3", epc3); + printf("%s=0x%08x\n", "excvaddr", excvaddr); + printf("%s=0x%08x\n", "depc", depc); + printf("%s=0x%08x\n", "excsave1", excsave1); + sdk_system_rtc_mem_read(0, excinfo, 32); // Why? + excinfo[0] = 2; + excinfo[1] = exccause; + excinfo[2] = epc1; + excinfo[3] = epc2; + excinfo[4] = epc3; + excinfo[5] = excvaddr; + excinfo[6] = depc; + excinfo[7] = excsave1; + sdk_system_rtc_mem_write(0, excinfo, 32); +} + +/* There's a lot of smart stuff we could do while dumping stack + but for now we just dump a likely looking section of stack + memory +*/ +void dump_stack(uint32_t *sp) { + printf("\nStack: SP=%p\n", sp); + for(uint32_t *p = sp; p < sp + 32; p += 4) { + if((intptr_t)p >= 0x3fffc000) { + break; /* approximate end of RAM */ + } + printf("%p: %08x %08x %08x %08x\n", p, p[0], p[1], p[2], p[3]); + if(p[0] == 0xa5a5a5a5 && p[1] == 0xa5a5a5a5 + && p[2] == 0xa5a5a5a5 && p[3] == 0xa5a5a5a5) { + break; /* FreeRTOS uses this pattern to mark untouched stack space */ + } + } +} + +void IRAM fatal_exception_handler(uint32_t *sp) { + if (!sdk_NMIIrqIsOn) { + vPortEnterCritical(); + do { + DPORT.DPORT0 &= 0xffffffe0; + } while (DPORT.DPORT0 & 0x00000001); + } + Cache_Read_Disable(); + Cache_Read_Enable(0, 0, 1); + dump_excinfo(); + if (sp) + dump_stack(sp); + uart_flush_txfifo(0); + uart_flush_txfifo(1); + sdk_system_restart_in_nmi(); + while(1) {} +} + diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 1980a0a..ba8fb25 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -69,7 +69,7 @@ DebugExceptionVector: wsr a0, excsave2 mov a2, a1 - call0 sdk_user_fatal_exception_handler + call0 fatal_exception_handler rfi 2 .org VecBase + 0x20 @@ -83,7 +83,7 @@ KernelExceptionVector: break 1, 0 mov a2, a1 - call0 sdk_user_fatal_exception_handler + call0 fatal_exception_handler rfe .org VecBase + 0x50 @@ -101,7 +101,7 @@ DoubleExceptionVector: break 1, 4 mov a2, a1 - call0 sdk_user_fatal_exception_handler + call0 fatal_exception_handler /* Reset vector at offset 0x80 is unused, as vecbase gets reset to mask ROM * vectors on chip reset. */ @@ -259,7 +259,7 @@ LoadStoreErrorHandler: l32i a4, sp, 0x10 rsr a1, excsave1 mov a2, a1 - call0 sdk_user_fatal_exception_handler + call0 fatal_exception_handler .balign 4 .LSE_assign_a1: @@ -520,7 +520,7 @@ UserExceptionHandler: .LUserFailOtherExceptionCause: break 1, 1 addi a2, a1, 0x50 /* UserExceptionHandler pushes stack down 0x50 */ - call0 sdk_user_fatal_exception_handler + call0 fatal_exception_handler /* _xt_user_exit is pushed onto the stack as part of the user exception handler, restores same set registers which were saved there and returns from exception */ diff --git a/core/include/debug_dumps.h b/core/include/debug_dumps.h new file mode 100644 index 0000000..d918043 --- /dev/null +++ b/core/include/debug_dumps.h @@ -0,0 +1,29 @@ +/* Functions for dumping status/debug output/etc, including fatal + * exception handling. + * + * Part of esp-open-rtos + * + * Copyright (C) 2015-2016 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#ifndef _DEBUG_DUMPS_H +#define _DEBUG_DUMPS_H +#include + +/* Dump stack memory starting from stack pointer address sp. */ +void dump_stack(uint32_t *sp); + +/* Called from exception_vectors.S when a fatal exception occurs. + + Probably not useful to be called in other contexts. +*/ +void fatal_exception_handler(uint32_t *sp); + +/* Dump the current exception register state. + + Probably mostly useful when called from fatal exception handler. +*/ +void dump_excinfo(void); + + +#endif