Break out debug dump functions into their own compilation unit
This commit is contained in:
parent
cb78ecd0e2
commit
44b4ccdfba
4 changed files with 122 additions and 75 deletions
|
@ -84,8 +84,6 @@ static void IRAM set_spi0_divisor(uint32_t divisor);
|
||||||
static void zero_bss(void);
|
static void zero_bss(void);
|
||||||
static void init_networking(uint8_t *phy_info, uint8_t *mac_addr);
|
static void init_networking(uint8_t *phy_info, uint8_t *mac_addr);
|
||||||
static void init_g_ic(void);
|
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 user_start_phase2(void);
|
||||||
static void dump_flash_sector(uint32_t start_sector, uint32_t length);
|
static void dump_flash_sector(uint32_t start_sector, uint32_t length);
|
||||||
static void dump_flash_config_sectors(uint32_t start_sector);
|
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);
|
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) {
|
static void IRAM default_putc(char c) {
|
||||||
uart_putc(0, 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
|
// .irom0.text+0x398
|
||||||
void sdk_wdt_init(void) {
|
void sdk_wdt_init(void) {
|
||||||
WDT.CTRL &= ~WDT_CTRL_ENABLE;
|
WDT.CTRL &= ~WDT_CTRL_ENABLE;
|
||||||
|
|
88
core/debug_dumps.c
Normal file
88
core/debug_dumps.c
Normal file
|
@ -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 <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <task.h>
|
||||||
|
|
||||||
|
#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) {}
|
||||||
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ DebugExceptionVector:
|
||||||
|
|
||||||
wsr a0, excsave2
|
wsr a0, excsave2
|
||||||
mov a2, a1
|
mov a2, a1
|
||||||
call0 sdk_user_fatal_exception_handler
|
call0 fatal_exception_handler
|
||||||
rfi 2
|
rfi 2
|
||||||
|
|
||||||
.org VecBase + 0x20
|
.org VecBase + 0x20
|
||||||
|
@ -83,7 +83,7 @@ KernelExceptionVector:
|
||||||
|
|
||||||
break 1, 0
|
break 1, 0
|
||||||
mov a2, a1
|
mov a2, a1
|
||||||
call0 sdk_user_fatal_exception_handler
|
call0 fatal_exception_handler
|
||||||
rfe
|
rfe
|
||||||
|
|
||||||
.org VecBase + 0x50
|
.org VecBase + 0x50
|
||||||
|
@ -101,7 +101,7 @@ DoubleExceptionVector:
|
||||||
|
|
||||||
break 1, 4
|
break 1, 4
|
||||||
mov a2, a1
|
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
|
/* Reset vector at offset 0x80 is unused, as vecbase gets reset to mask ROM
|
||||||
* vectors on chip reset. */
|
* vectors on chip reset. */
|
||||||
|
@ -259,7 +259,7 @@ LoadStoreErrorHandler:
|
||||||
l32i a4, sp, 0x10
|
l32i a4, sp, 0x10
|
||||||
rsr a1, excsave1
|
rsr a1, excsave1
|
||||||
mov a2, a1
|
mov a2, a1
|
||||||
call0 sdk_user_fatal_exception_handler
|
call0 fatal_exception_handler
|
||||||
|
|
||||||
.balign 4
|
.balign 4
|
||||||
.LSE_assign_a1:
|
.LSE_assign_a1:
|
||||||
|
@ -520,7 +520,7 @@ UserExceptionHandler:
|
||||||
.LUserFailOtherExceptionCause:
|
.LUserFailOtherExceptionCause:
|
||||||
break 1, 1
|
break 1, 1
|
||||||
addi a2, a1, 0x50 /* UserExceptionHandler pushes stack down 0x50 */
|
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,
|
/* _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 */
|
restores same set registers which were saved there and returns from exception */
|
||||||
|
|
29
core/include/debug_dumps.h
Normal file
29
core/include/debug_dumps.h
Normal file
|
@ -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 <stdint.h>
|
||||||
|
|
||||||
|
/* 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
|
Loading…
Reference in a new issue