feat(gdbstub): modify GDB stub for ESP8266

This commit is contained in:
dongheng
2019-10-28 15:47:13 +08:00
committed by Dong Heng
parent 56747578d2
commit 1e69cbd242
19 changed files with 272 additions and 78 deletions

View File

@ -182,5 +182,9 @@ uint32_t esp_get_time(void);
#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE
#endif /* configIDLE_TASK_STACK_SIZE */
#ifndef configENABLE_TASK_SNAPSHOT
#define configENABLE_TASK_SNAPSHOT 1
#endif
#endif /* FREERTOS_CONFIG_H */

View File

@ -63,22 +63,25 @@ extern "C" {
*/
/* Type definitions. */
#define portCHAR char
#define portCHAR int8_t
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned char
#define portBASE_TYPE long
#define portLONG int32_t
#define portSHORT int16_t
#define portSTACK_TYPE uint8_t
#define portBASE_TYPE int
#define BaseType_t portBASE_TYPE
#define TickType_t unsigned portLONG
#define UBaseType_t unsigned portBASE_TYPE
#define StackType_t portSTACK_TYPE
typedef portSTACK_TYPE StackType_t;
typedef portBASE_TYPE BaseType_t;
typedef unsigned portBASE_TYPE UBaseType_t;
typedef unsigned portLONG portTickType;
typedef unsigned int INT32U;
#define portMAX_DELAY ( portTickType ) 0xffffffff
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
/*-----------------------------------------------------------*/
/* Architecture specifics. */
@ -131,6 +134,7 @@ void PortEnableInt_NoNest( void );
#define portEXIT_CRITICAL() vPortExitCritical()
#define xPortGetCoreID() 0
#define xTaskGetCurrentTaskHandleForCPU(_cpu) xTaskGetCurrentTaskHandle()
// no need to disable/enable lvl1 isr again in ISR
//#define portSET_INTERRUPT_MASK_FROM_ISR() PortDisableInt_NoNest()

View File

@ -30,6 +30,7 @@ NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
#include <xtensa/config/tie.h>
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include <xtensa/xtruntime-frames.h>
/*
@ -79,6 +80,52 @@ space to help manage the spilling of the register windows.
#define XT_STK_SAR 0x4C
#define XT_STK_EXCCAUSE 0x50
#define XT_STK_EXCVADDR 0x54
STRUCT_BEGIN
STRUCT_FIELD (long, 4, XT_STK_EXIT, exit) /* exit point for dispatch */
STRUCT_FIELD (long, 4, XT_STK_PC, pc) /* return PC */
STRUCT_FIELD (long, 4, XT_STK_PS, ps) /* return PS */
STRUCT_FIELD (long, 4, XT_STK_A0, a0)
STRUCT_FIELD (long, 4, XT_STK_A1, a1) /* stack pointer before interrupt */
STRUCT_FIELD (long, 4, XT_STK_A2, a2)
STRUCT_FIELD (long, 4, XT_STK_A3, a3)
STRUCT_FIELD (long, 4, XT_STK_A4, a4)
STRUCT_FIELD (long, 4, XT_STK_A5, a5)
STRUCT_FIELD (long, 4, XT_STK_A6, a6)
STRUCT_FIELD (long, 4, XT_STK_A7, a7)
STRUCT_FIELD (long, 4, XT_STK_A8, a8)
STRUCT_FIELD (long, 4, XT_STK_A9, a9)
STRUCT_FIELD (long, 4, XT_STK_A10, a10)
STRUCT_FIELD (long, 4, XT_STK_A11, a11)
STRUCT_FIELD (long, 4, XT_STK_A12, a12)
STRUCT_FIELD (long, 4, XT_STK_A13, a13)
STRUCT_FIELD (long, 4, XT_STK_A14, a14)
STRUCT_FIELD (long, 4, XT_STK_A15, a15)
STRUCT_FIELD (long, 4, XT_STK_SAR, sar)
STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
#if XCHAL_HAVE_LOOPS
STRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg)
STRUCT_FIELD (long, 4, XT_STK_LEND, lend)
STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
#endif
#ifndef __XTENSA_CALL0_ABI__
/* Temporary space for saving stuff during window spill */
STRUCT_FIELD (long, 4, XT_STK_TMP0, tmp0)
STRUCT_FIELD (long, 4, XT_STK_TMP1, tmp1)
STRUCT_FIELD (long, 4, XT_STK_TMP2, tmp2)
#endif
#ifdef XT_USE_SWPRI
/* Storage for virtual priority mask */
STRUCT_FIELD (long, 4, XT_STK_VPRI, vpri)
#endif
#ifdef XT_USE_OVLY
/* Storage for overlay state */
STRUCT_FIELD (long, 4, XT_STK_OVLY, ovly)
#endif
STRUCT_END(XtExcFrame)
#if XCHAL_HAVE_LOOPS
#define XT_STK_LBEG 0x50
#define XT_STK_LEND 0x54
@ -115,6 +162,49 @@ Windowed -
#endif
/*
-------------------------------------------------------------------------------
SOLICITED STACK FRAME FOR A THREAD
A stack frame of this structure is allocated whenever a thread enters the
RTOS kernel intentionally (and synchronously) to submit to thread scheduling.
It goes on the current thread's stack.
The solicited frame only includes registers that are required to be preserved
by the callee according to the compiler's ABI conventions, some space to save
the return address for returning to the caller, and the caller's PS register.
For Windowed ABI, this stack frame includes the caller's base save area.
Note on XT_SOL_EXIT field:
It is necessary to distinguish a solicited from an interrupt stack frame.
This field corresponds to XT_STK_EXIT in the interrupt stack frame and is
always at the same offset (0). It can be written with a code (usually 0)
to distinguish a solicted frame from an interrupt frame. An RTOS port may
opt to ignore this field if it has another way of distinguishing frames.
-------------------------------------------------------------------------------
*/
STRUCT_BEGIN
#ifdef __XTENSA_CALL0_ABI__
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
STRUCT_FIELD (long, 4, XT_SOL_NEXT, a0)
STRUCT_FIELD (long, 4, XT_SOL_A12, a1) /* should be on 16-byte alignment */
STRUCT_FIELD (long, 4, XT_SOL_A13, a2)
#else
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
STRUCT_FIELD (long, 4, XT_SOL_A0, a0) /* should be on 16-byte alignment */
STRUCT_FIELD (long, 4, XT_SOL_A1, a1)
STRUCT_FIELD (long, 4, XT_SOL_A2, a2)
STRUCT_FIELD (long, 4, XT_SOL_A3, a3)
#endif
STRUCT_END(XtSolFrame)
/*******************************************************************************
SOLICTED STACK FRAME FOR A THREAD

View File

@ -27,6 +27,7 @@
#include "esp_err.h"
#include "FreeRTOS.h"
#include "freertos/xtensa_context.h"
#define PANIC(_fmt, ...) ets_printf(_fmt, ##__VA_ARGS__)
@ -42,39 +43,14 @@
#define ESP_PANIC_PRINT
#endif
#if defined(CONFIG_ESP_PANIC_GDBSTUB)
#define ESP_PANIC_GDBSTUB
#else
#undef ESP_PANIC_GDBSTUB
#endif
#ifdef ESP_PANIC_PRINT
typedef struct panic_frame {
uint32_t exit;
uint32_t pc;
uint32_t ps;
uint32_t a0;
uint32_t a1;
uint32_t a2;
uint32_t a3;
uint32_t a4;
uint32_t a5;
uint32_t a6;
uint32_t a7;
uint32_t a8;
uint32_t a9;
uint32_t a10;
uint32_t a11;
uint32_t a12;
uint32_t a13;
uint32_t a14;
uint32_t a15;
uint32_t sar;
uint32_t exccause;
} panic_frame_t;
static void panic_frame(panic_frame_t *frame)
static inline void panic_frame(XtExcFrame *frame)
{
static const char *sdesc[] = {
"PC", "PS", "A0", "A1",
@ -161,6 +137,11 @@ void panicHandler(void *frame, int wdt)
#ifdef ESP_PANIC_REBOOT
esp_panic_reset();
#elif defined(ESP_PANIC_GDBSTUB)
extern void esp_gdbstub_panic_handler(void *frame);
PANIC("Entering gdb stub now.\r\n");
esp_gdbstub_panic_handler(frame);
#else
while (1) {
esp_task_wdt_reset();

View File

@ -78,7 +78,7 @@ uint8_t *__cpu_init_stk(uint8_t *stack_top, void (*_entry)(void *), void *param,
uint32_t *sp, *tp, *stk = (uint32_t *)stack_top;
/* Create interrupt stack frame aligned to 16 byte boundary */
sp = (uint32_t *)(((INT32U)(stk + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
sp = (uint32_t *)(((uint32_t)(stk + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
/* Clear the entire frame (do not use memset() because we don't depend on C library) */
for (tp = sp; tp <= stk; ++tp) {
@ -88,7 +88,7 @@ uint8_t *__cpu_init_stk(uint8_t *stack_top, void (*_entry)(void *), void *param,
/* Explicitly initialize certain saved registers */
SET_STKREG(XT_STK_PC, _entry); /* task entrypoint */
SET_STKREG(XT_STK_A0, _exit); /* to terminate GDB backtrace */
SET_STKREG(XT_STK_A1, (INT32U)sp + XT_STK_FRMSZ); /* physical top of stack frame */
SET_STKREG(XT_STK_A1, (uint32_t)sp + XT_STK_FRMSZ); /* physical top of stack frame */
SET_STKREG(XT_STK_A2, param); /* parameters */
SET_STKREG(XT_STK_EXIT, _xt_user_exit); /* user exception exit dispatcher */