cpu/esp8266: vendor files changed for RTOS SDK

This commit is contained in:
Gunar Schorcht 2019-09-05 13:13:30 +02:00
parent 464bb9f4c4
commit a6d01fc2de
9 changed files with 1040 additions and 779 deletions

View File

@ -1,4 +1,3 @@
file ../ld/esp8266.riot-os.sdk.app.ld
#set remotedebug 1 #set remotedebug 1
set remotelogfile gdb_rsp_logfile.txt set remotelogfile gdb_rsp_logfile.txt
set serial baud 115200 set serial baud 115200

View File

@ -5,60 +5,75 @@
extern "C" { extern "C" {
#endif #endif
/* /**
Enable this define if you're using the RTOS SDK. It will use a custom exception handler instead of the HAL * @brief Enable own stack for gdbstub
and do some other magic to make everything work and compile under FreeRTOS. *
*/ * Enable this to make the exception and debugging handlers switch to a
#ifndef GDBSTUB_FREERTOS * private stack. This will use GDBSTUB_STACK_SIZE of RAM, but may be useful
#define GDBSTUB_FREERTOS 1 * if you're debugging stack or stack pointer corruption problems. It's
#endif * normally disabled because not many situations need it. If for some reason
* the GDB communication stops when you run into an error in your code, try
/* * enabling this.
Enable this to make the exception and debugging handlers switch to a private stack. This will use */
up 1K of RAM, but may be useful if you're debugging stack or stack pointer corruption problems. It's
normally disabled because not many situations need it. If for some reason the GDB communication
stops when you run into an error in your code, try enabling this.
*/
#ifndef GDBSTUB_USE_OWN_STACK #ifndef GDBSTUB_USE_OWN_STACK
#define GDBSTUB_USE_OWN_STACK 0 #define GDBSTUB_USE_OWN_STACK (0)
#endif #endif
/* /**
If this is defined, gdbstub will break the program when you press Ctrl-C in gdb. it does this by * @brief Size of gdbstub stack
hooking the UART interrupt. Unfortunately, this means receiving stuff over the serial port won't *
work for your program anymore. This will fail if your program sets an UART interrupt handler after * If own stack is enale for gdbstub (\ref GDBSTUB_USE_OWN_STACK),
the gdbstub_init call. * GDBSTUB_STACK_SIZE defines the size of this stack.
*/ */
#ifndef GDBSTUB_STACK_SIZE
#define GDBSTUB_STACK_SIZE (1024)
#endif
/**
* @brief Enable Ctrl-C handling
*
* If Ctrl-C is enabled, gdbstub interrupts the program when you press the
* Ctrl-C key either in gdb or, if used, in the console window. Ctrl-C handling
* is realized by hooking the UART interrupt.
*/
#ifndef GDBSTUB_CTRLC_BREAK #ifndef GDBSTUB_CTRLC_BREAK
#define GDBSTUB_CTRLC_BREAK 1 #define GDBSTUB_CTRLC_BREAK (1)
#endif #endif
/* /**
Enabling this will redirect console output to GDB. This basically means that printf/os_printf output * @brief Redirect console output to GDB
will show up in your gdb session, which is useful if you use gdb to do stuff. It also means that if *
you use a normal terminal, you can't read the printfs anymore. * Enabling this will redirect console output to GDB. This basically means
*/ * that printf/os_printf output will show up in your gdb session, which is
* useful if you use gdb to do stuff. It also means that if you use a normal
* terminal, you can't read the printfs anymore.
*/
#ifndef GDBSTUB_REDIRECT_CONSOLE_OUTPUT #ifndef GDBSTUB_REDIRECT_CONSOLE_OUTPUT
#define GDBSTUB_REDIRECT_CONSOLE_OUTPUT 1 #define GDBSTUB_REDIRECT_CONSOLE_OUTPUT (1)
#endif #endif
/* /**
Enable this if you want the GDB stub to wait for you to attach GDB before running. It does this by * @brief Break on init
breaking in the init routine; use the gdb 'c' command (continue) to start the program. *
*/ * Enable this if you want the GDB stub to wait for you to attach GDB before
* running. It does this by breaking in the init routine; use the gdb 'c'
* command (continue) to start the program.
*/
#ifndef GDBSTUB_BREAK_ON_INIT #ifndef GDBSTUB_BREAK_ON_INIT
#define GDBSTUB_BREAK_ON_INIT 1 #define GDBSTUB_BREAK_ON_INIT (1)
#endif #endif
/* /**
Function attributes for function types. * @brief Function attributes for function types.
Gdbstub functions are placed in flash or IRAM using attributes, as defined here. The gdbinit function *
(and related) can always be in flash, because it's called in the normal code flow. The rest of the * gdbstub functions are placed in flash or IRAM using attributes, as defined
gdbstub functions can be in flash too, but only if there's no chance of them being called when the * here. The gdbinit function (and related) can always be in flash, because
flash somehow is disabled (eg during SPI operations or flash write/erase operations). If the routines * it's called in the normal code flow. The rest of the gdbstub functions can
are called when the flash is disabled (eg due to a Ctrl-C at the wrong time), the ESP8266 will most * be in flash too, but only if there's no chance of them being called when the
likely crash. * flash somehow is disabled (eg during SPI operations or flash write/erase
*/ * operations). If the routines are called when the flash is disabled (e.g.
* due to a Ctrl-C at the wrong time), the ESP8266 will most likely crash.
*/
#define ATTR_GDBINIT ICACHE_FLASH_ATTR #define ATTR_GDBINIT ICACHE_FLASH_ATTR
#ifndef ATTR_GDBFN #ifndef ATTR_GDBFN
#define ATTR_GDBFN #define ATTR_GDBFN

View File

@ -8,397 +8,398 @@
#include "gdbstub-cfg.h" #include "gdbstub-cfg.h"
#include "gdbstub-exc.h"
#include <xtensa/config/specreg.h> #include <xtensa/config/specreg.h>
#include <xtensa/config/core-isa.h> #include <xtensa/config/core-isa.h>
#include <xtensa/corebits.h> #include <xtensa/corebits.h>
#define DEBUG_PC (EPC + XCHAL_DEBUGLEVEL) #include "xtensa/xtensa_context.h"
#define DEBUG_EXCSAVE (EXCSAVE + XCHAL_DEBUGLEVEL)
#define DEBUG_PS (EPS + XCHAL_DEBUGLEVEL)
#define DEBUG_PC (EPC + XCHAL_DEBUGLEVEL)
#define DEBUG_EXCSAVE (EXCSAVE + XCHAL_DEBUGLEVEL)
#define DEBUG_PS (EPS + XCHAL_DEBUGLEVEL)
.global gdbstub_savedRegs .global gdbstub_regs
.global gdbstub_debug_exception_entry
#if GDBSTUB_USE_OWN_STACK #if GDBSTUB_USE_OWN_STACK
.global gdbstub_exceptionStack .global gdbstub_exceptionStack
#endif #endif
.text .text
.literal_position .literal_position
.text .text
.align 4 .align 4
/**
/* * @brief Debugging exception routine; it's called by the debugging vector
The savedRegs struct: */
uint32_t pc;
uint32_t ps;
uint32_t sar;
uint32_t vpri;
uint32_t a0;
uint32_t a[14]; //a2..a15
uint32_t litbase;
uint32_t sr176;
uint32_t sr208;
uint32_t a1;
uint32_t reason;
*/
/*
This is the debugging exception routine; it's called by the debugging vector
We arrive here with all regs intact except for a2. The old contents of A2 are saved
into the DEBUG_EXCSAVE special function register. EPC is the original PC.
*/
gdbstub_debug_exception_entry: gdbstub_debug_exception_entry:
/*
//Minimum no-op debug exception handler, for debug
rsr a2,DEBUG_PC
addi a2,a2,3
wsr a2,DEBUG_PC
xsr a2, DEBUG_EXCSAVE
rfi XCHAL_DEBUGLEVEL
*/
//Save all regs to structure /*
movi a2, gdbstub_savedRegs * All registers except A2 are intact when we arrive here. The original
s32i a0, a2, 0x10 * contents of A2 was save in the EXCSAVE2/DEBUG_EXCSAVE register by
s32i a1, a2, 0x58 * _DebugExceptionVector stub. EPC2/DEBUG_PC register contains the
rsr a0, DEBUG_PS * original PC and EPC2/DEBUG_PC the original PS register
s32i a0, a2, 0x04 */
rsr a0, DEBUG_EXCSAVE //was R2
s32i a0, a2, 0x14
s32i a3, a2, 0x18
s32i a4, a2, 0x1c
s32i a5, a2, 0x20
s32i a6, a2, 0x24
s32i a7, a2, 0x28
s32i a8, a2, 0x2c
s32i a9, a2, 0x30
s32i a10, a2, 0x34
s32i a11, a2, 0x38
s32i a12, a2, 0x3c
s32i a13, a2, 0x40
s32i a14, a2, 0x44
s32i a15, a2, 0x48
rsr a0, SAR
s32i a0, a2, 0x08
rsr a0, LITBASE
s32i a0, a2, 0x4C
rsr a0, 176
s32i a0, a2, 0x50
rsr a0, 208
s32i a0, a2, 0x54
rsr a0, DEBUGCAUSE
s32i a0, a2, 0x5C
rsr a4, DEBUG_PC
s32i a4, a2, 0x00
#if GDBSTUB_USE_OWN_STACK /* Save all regs to standard exception frame structure XtExcFrame */
//Move to our own stack movi a2, gdbstub_regs
movi a1, exceptionStack+255*4
s32i a0, a2, XT_STK_A0 /* save A0 (return address) before we used it */
s32i a1, a2, XT_STK_A1 /* save A1 (stack pointer) */
rsr a0, DEBUG_PC /* read original PC from EPC2 and save it */
s32i a0, a2, XT_STK_PC
rsr a0, DEBUG_PS /* read original PS from ESP2 and save it */
s32i a0, a2, XT_STK_PS
rsr a0, DEBUG_EXCSAVE /* read original A2 from EXCSAVE2 and save it */
s32i a0, a2, XT_STK_A2
s32i a3, a2, XT_STK_A3 /* save remaining A registers */
s32i a4, a2, XT_STK_A4
s32i a5, a2, XT_STK_A5
s32i a6, a2, XT_STK_A6
s32i a7, a2, XT_STK_A7
s32i a8, a2, XT_STK_A8
s32i a9, a2, XT_STK_A9
s32i a10, a2, XT_STK_A10
s32i a11, a2, XT_STK_A11
s32i a12, a2, XT_STK_A12
s32i a13, a2, XT_STK_A13
s32i a14, a2, XT_STK_A14
s32i a15, a2, XT_STK_A15
rsr a0, SAR /* read SAR and save it */
s32i a0, a2, XT_STK_SAR
#if XCHAL_HAVE_LOOPS
rsr a0, lbeg
s32i a0, a2, XT_STK_LBEG
rsr a0, lend
s32i a0, a2, XT_STK_LEND
rsr a0, lcount
s32i a0, a2, XT_STK_LCOUNT
#endif #endif
//If ICOUNT is -1, disable it by setting it to 0, otherwise we will keep triggering on the same instruction. #ifdef XT_USE_SWPRI
rsr a2, ICOUNT rsr a0, vpri
movi a3, -1 s32i a0, a2, XT_STK_VPRI
bne a2, a3, noIcountReset #endif
movi a3, 0
wsr a3, ICOUNT #ifdef XT_USE_OVLY
rsr a0, ovly
s32i a0, a2, XT_STK_OVLY
#endif
/* Save additional registers required for gdb_stub */
movi a2, gdbstub_regs + XtExcFrameSize
rsr a0, LITBASE
s32i a0, a2, XT_STK_LITBASE
rsr a0, 176
s32i a0, a2, XT_STK_SR176
rsr a0, 208
s32i a0, a2, XT_STK_SR208
rsr a0, DEBUGCAUSE
s32i a0, a2, XT_STK_REASON
#if GDBSTUB_USE_OWN_STACK
/* Move to our own stack */
movi a1, gdbstub_exceptionStack + GDBSTUB_STACK_SIZE - 4
#endif
/*
* If ICOUNT is -1, disable it by setting it to 0, otherwise we will
* keep triggering on the same instruction.
*/
rsr a2, ICOUNT
movi a3, -1
bne a2, a3, noIcountReset
movi a3, 0
wsr a3, ICOUNT
noIcountReset: noIcountReset:
rsr a2, ps
addi a2, a2, -PS_EXCM_MASK
wsr a2, ps
rsync
rsr a2, ps /* Call into the C code to do the actual handling. */
addi a2, a2, -PS_EXCM_MASK call0 gdbstub_handle_debug_exception
wsr a2, ps
rsync
//Call into the C code to do the actual handling.
call0 gdbstub_handle_debug_exception
DebugExceptionExit: DebugExceptionExit:
rsr a2, ps rsr a2, ps
addi a2, a2, PS_EXCM_MASK addi a2, a2, PS_EXCM_MASK
wsr a2, ps wsr a2, ps
rsync rsync
//Restore registers from the gdbstub_savedRegs struct /* Restore registers from the gdbstub_regs struct. */
movi a2, gdbstub_savedRegs
l32i a0, a2, 0x00
wsr a0, DEBUG_PC
// l32i a0, a2, 0x54
// wsr a0, 208
l32i a0, a2, 0x50
//wsr a0, 176 //Some versions of gcc do not understand this...
.byte 0x00, 176, 0x13 //so we hand-assemble the instruction.
l32i a0, a2, 0x4C
wsr a0, LITBASE
l32i a0, a2, 0x08
wsr a0, SAR
l32i a15, a2, 0x48
l32i a14, a2, 0x44
l32i a13, a2, 0x40
l32i a12, a2, 0x3c
l32i a11, a2, 0x38
l32i a10, a2, 0x34
l32i a9, a2, 0x30
l32i a8, a2, 0x2c
l32i a7, a2, 0x28
l32i a6, a2, 0x24
l32i a5, a2, 0x20
l32i a4, a2, 0x1c
l32i a3, a2, 0x18
l32i a0, a2, 0x14
wsr a0, DEBUG_EXCSAVE //was R2
l32i a0, a2, 0x04
wsr a0, DEBUG_PS
l32i a1, a2, 0x58
l32i a0, a2, 0x10
//Read back vector-saved a2 value, put back address of this routine. movi a2, gdbstub_regs + XtExcFrameSize
movi a2, gdbstub_debug_exception_entry
xsr a2, DEBUG_EXCSAVE
//All done. Return to where we came from. #if 0
rfi XCHAL_DEBUGLEVEL /* TODO: check whether it is really necessary to recover SR178 and SR208
* Some versions of gcc do not understand instruction 'wsr <n>' where n is
* the decimal number of the special register. A hand-assembled version of
* instruction would have to be used instead.
*
* .byte 0x00, <n>, 0x13
*
* However, writing to SR176 or SR208 leads to an IllegalInstruction
* exception
*/
l32i a0, a2, XT_STK_SR208
wsr a0, 208
#if GDBSTUB_FREERTOS l32i a0, a2, XT_STK_SR176
/* wsr a0, 176
FreeRTOS exception handling code. For some reason or another, we can't just hook the main exception vector: it
seems FreeRTOS uses that for something else too (interrupts). FreeRTOS has its own fatal exception handler, and we
hook that. Unfortunately, that one is called from a few different places (eg directly in the DoubleExceptionVector)
so the precise location of the original register values are somewhat of a mystery when we arrive here...
As a 'solution', we'll just decode the most common case of the user_fatal_exception_handler being called from
the user exception handler vector:
- excsave1 - orig a0
- a1: stack frame:
sf+16: orig a1
sf+8: ps
sf+4: epc
sf+12: orig a0
sf: magic no?
*/
.global gdbstub_handle_user_exception
.global gdbstub_user_exception_entry
.align 4
gdbstub_user_exception_entry:
//Save all regs to structure
movi a0, gdbstub_savedRegs
s32i a1, a0, 0x14 //was a2
s32i a3, a0, 0x18
s32i a4, a0, 0x1c
s32i a5, a0, 0x20
s32i a6, a0, 0x24
s32i a7, a0, 0x28
s32i a8, a0, 0x2c
s32i a9, a0, 0x30
s32i a10, a0, 0x34
s32i a11, a0, 0x38
s32i a12, a0, 0x3c
s32i a13, a0, 0x40
s32i a14, a0, 0x44
s32i a15, a0, 0x48
rsr a2, SAR
s32i a2, a0, 0x08
rsr a2, LITBASE
s32i a2, a0, 0x4C
rsr a2, 176
s32i a2, a0, 0x50
rsr a2, 208
s32i a2, a0, 0x54
rsr a2, EXCCAUSE
s32i a2, a0, 0x5C
//Get the rest of the regs from the stack struct
l32i a3, a1, 12
s32i a3, a0, 0x10
l32i a3, a1, 16
s32i a3, a0, 0x58
l32i a3, a1, 8
s32i a3, a0, 0x04
l32i a3, a1, 4
s32i a3, a0, 0x00
#if GDBSTUB_USE_OWN_STACK
movi a1, exceptionStack+255*4
#endif #endif
rsr a2, ps l32i a0, a2, XT_STK_LITBASE
addi a2, a2, -PS_EXCM_MASK wsr a0, LITBASE
wsr a2, ps
rsync
call0 gdbstub_handle_user_exception movi a2, gdbstub_regs
UserExceptionExit:
/*
Okay, from here on, it Does Not Work. There's not really any continuing from an exception in the
FreeRTOS case; there isn't any effort put in reversing the mess the exception code made yet. Maybe this
is still something we need to implement later, if there's any demand for it, or maybe we should modify
FreeRTOS to allow this in the future. (Which will then kill backwards compatibility... hmmm.)
*/
j UserExceptionExit
.global gdbstub_handle_uart_int
.global gdbstub_uart_entry
.align 4
gdbstub_uart_entry:
//On entry, the stack frame is at SP+16.
//This is a small stub to present that as the first arg to the gdbstub_handle_uart function.
movi a2, 16
add a2, a2, a1
movi a3, gdbstub_handle_uart_int
jx a3
#ifdef XT_USE_OVLY
l32i a0, a2, XT_STK_OVLY
wsr a0, ovly
#endif #endif
#ifdef XT_USE_SWPRI
l32i a0, a2, XT_STK_VPRI
wsr a0, vpri
#endif
#if XCHAL_HAVE_LOOPS
l32i a0, a2, XT_STK_LCOUNT
wsr a0, lcount
l32i a0, a2, XT_STK_LEND
wsr a0, lend
l32i a0, a2, XT_STK_LBEG
wsr a0, lbeg
#endif
l32i a0, a2, XT_STK_SAR
wsr a0, sar
l32i a15, a2, XT_STK_A15
l32i a14, a2, XT_STK_A14
l32i a13, a2, XT_STK_A13
l32i a12, a2, XT_STK_A12
l32i a11, a2, XT_STK_A11
l32i a10, a2, XT_STK_A10
l32i a9, a2, XT_STK_A9
l32i a8, a2, XT_STK_A8
l32i a7, a2, XT_STK_A7
l32i a6, a2, XT_STK_A6
l32i a5, a2, XT_STK_A5
l32i a4, a2, XT_STK_A4
l32i a3, a2, XT_STK_A3
l32i a0, a2, XT_STK_A2 /* read original A2 and save it to EXCSAVE2 */
wsr a0, DEBUG_EXCSAVE
l32i a0, a2, XT_STK_PS /* read original PS and save it to EPS2 */
wsr a0, DEBUG_PS
l32i a0, a2, XT_STK_PC /* read original PC and save it to EPS2 */
wsr a0, DEBUG_PC
l32i a1, a2, XT_STK_A1 /* restore A1 (stack pointer) */
l32i a0, a2, XT_STK_A0 /* restore A0 (return address) */
/* Read back vector-saved a2 value, put back address of this routine. */
movi a2, gdbstub_debug_exception_entry
xsr a2, DEBUG_EXCSAVE
/* All done. Return to where we came from. */
rfi XCHAL_DEBUGLEVEL
.global gdbstub_save_extra_sfrs_for_exception .global gdbstub_save_extra_sfrs_for_exception
.align 4 .align 4
//The Xtensa OS HAL does not save all the special function register things. This bit of assembly /*
//fills the gdbstub_savedRegs struct with them. * The Xtensa standard exception handlers does not save all the special
* function register things. This bit of assembly fills the gdbstub_regs struct
* with them.
*/
gdbstub_save_extra_sfrs_for_exception: gdbstub_save_extra_sfrs_for_exception:
movi a2, gdbstub_savedRegs
rsr a3, LITBASE
s32i a3, a2, 0x4C
rsr a3, 176
s32i a3, a2, 0x50
rsr a3, 208
s32i a3, a2, 0x54
rsr a3, EXCCAUSE
s32i a3, a2, 0x5C
ret
.global gdbstub_init_debug_entry /* a14-a15 are only saved by standard exception handlers for Windowed ABI */
.global _DebugExceptionVector #ifdef __XTENSA_CALL0_ABI__
.align 4 movi a2, gdbstub_regs
s32i a14, a2, XT_STK_A14
s32i a15, a2, XT_STK_A15
#endif
/* Save additional registers required for gdb_stub */
movi a2, gdbstub_regs + XtExcFrameSize
rsr a3, LITBASE
s32i a3, a2, XT_STK_LITBASE
rsr a3, 176
s32i a3, a2, XT_STK_SR176
rsr a3, 208
s32i a3, a2, XT_STK_SR208
rsr a3, EXCCAUSE
s32i a3, a2, XT_STK_REASON
ret
.global gdbstub_init_debug_entry
.global _DebugExceptionVector
.align 4
/*
* This puts the following 2 instructions into the debug exception vector:
* xsr a2, DEBUG_EXCSAVE
* jx a2
*/
gdbstub_init_debug_entry: gdbstub_init_debug_entry:
//This puts the following 2 instructions into the debug exception vector:
// xsr a2, DEBUG_EXCSAVE
// jx a2
movi a2, _DebugExceptionVector
movi a3, 0xa061d220
s32i a3, a2, 0
movi a3, 0x00000002
s32i a3, a2, 4
//Tell the just-installed debug vector where to go. movi a2, _DebugExceptionVector
movi a2, gdbstub_debug_exception_entry movi a3, 0xa061d220
wsr a2, DEBUG_EXCSAVE s32i a3, a2, 0
movi a3, 0x00000002
s32i a3, a2, 4
ret /* Tell the just-installed debug vector where to go. */
movi a2, gdbstub_debug_exception_entry
wsr a2, DEBUG_EXCSAVE
ret
//Set up ICOUNT register to step one single instruction .global gdbstub_icount_ena_single_step
.global gdbstub_icount_ena_single_step .align 4
.align 4 /*
* Set up ICOUNT register to step one single instruction
*/
gdbstub_icount_ena_single_step: gdbstub_icount_ena_single_step:
movi a3, XCHAL_DEBUGLEVEL //Only count steps in non-debug mode movi a3, XCHAL_DEBUGLEVEL /* Only count steps in non-debug mode */
movi a2, -2 movi a2, -2
wsr a3, ICOUNTLEVEL wsr a3, ICOUNTLEVEL
wsr a2, ICOUNT wsr a2, ICOUNT
isync isync
ret ret
/*
* The following routines all assume that only one breakpoint and watchpoint
* is available, which is the case for the ESP8266 Xtensa core.
*/
//These routines all assume only one breakpoint and watchpoint is available, which .global gdbstub_set_hw_breakpoint
//is the case for the ESP8266 Xtensa core. .align 4
/*
* set an hw breakpoint
.global gdbstub_set_hw_breakpoint * paramters: a2 = addr, a3 = len (unused here)
*/
gdbstub_set_hw_breakpoint: gdbstub_set_hw_breakpoint:
//a2 - addr, a3 - len (unused here)
rsr a4, IBREAKENABLE
bbsi a4, 0, return_w_error
wsr a2, IBREAKA
movi a2, 1
wsr a2, IBREAKENABLE
isync
movi a2, 1
ret
.global gdbstub_del_hw_breakpoint call0 40000080
rsr a4, IBREAKENABLE
bbsi a4, 0, return_w_error
wsr a2, IBREAKA
movi a2, 1
wsr a2, IBREAKENABLE
isync
movi a2, 1
ret
.global gdbstub_del_hw_breakpoint
.align 4
/*
* delete an hw breakpoint
* paramters: a2 = addr
*/
gdbstub_del_hw_breakpoint: gdbstub_del_hw_breakpoint:
//a2 - addr
rsr a5, IBREAKENABLE
bbci a5, 0, return_w_error
rsr a3, IBREAKA
bne a3, a2, return_w_error
movi a2,0
wsr a2, IBREAKENABLE
isync
movi a2, 1
ret
.global gdbstub_set_hw_watchpoint rsr a5, IBREAKENABLE
//a2 - addr, a3 - mask, a4 - type (1=read, 2=write, 3=access) bbci a5, 0, return_w_error
rsr a3, IBREAKA
bne a3, a2, return_w_error
movi a2,0
wsr a2, IBREAKENABLE
isync
movi a2, 1
ret
.global gdbstub_set_hw_watchpoint
.align 4
/*
* set an hw breakpoint
* paramters: a2 = addr, a3 = mask, a4 = type (1=read, 2=write, 3=access)
*/
gdbstub_set_hw_watchpoint: gdbstub_set_hw_watchpoint:
//Check if any of the masked address bits are set. If so, that is an error.
movi a5,0x0000003F
xor a5, a5, a3
bany a2, a5, return_w_error
//Check if watchpoint already is set
rsr a5, DBREAKC
movi a6, 0xC0000000
bany a6, a5, return_w_error
//Set watchpoint
wsr a2, DBREAKA
//Combine type and mask /* Check if any of the masked address bits are set. If so, that is an error. */
movi a6, 0x3F movi a5,0x0000003F
and a3, a3, a6 xor a5, a5, a3
slli a4, a4, 30 bany a2, a5, return_w_error
or a3, a3, a4
wsr a3, DBREAKC
// movi a2, 1 /* Check if watchpoint already is set */
mov a2, a3 rsr a5, DBREAKC
isync movi a6, 0xC0000000
ret bany a6, a5, return_w_error
/* Set watchpoint */
wsr a2, DBREAKA
/* Combine type and mask */
movi a6, 0x3F
and a3, a3, a6
slli a4, a4, 30
or a3, a3, a4
wsr a3, DBREAKC
mov a2, a3
isync
ret
.global gdbstub_del_hw_watchpoint .global gdbstub_del_hw_watchpoint
//a2 - addr .align 4
/*
* delete a hw breakpoint
* paramters: a2 = addr
*/
gdbstub_del_hw_watchpoint: gdbstub_del_hw_watchpoint:
//See if the address matches /* see if the address matches */
rsr a3, DBREAKA rsr a3, DBREAKA
bne a3, a2, return_w_error bne a3, a2, return_w_error
//See if the bp actually is set /* see if the bp actually is set */
rsr a3, DBREAKC rsr a3, DBREAKC
movi a2, 0xC0000000 movi a2, 0xC0000000
bnone a3, a2, return_w_error bnone a3, a2, return_w_error
//Disable bp /* Disable bp */
movi a2,0 movi a2,0
wsr a2,DBREAKC wsr a2,DBREAKC
movi a2,1 movi a2,1
isync isync
ret ret
return_w_error: return_w_error:
movi a2, 0 movi a2, 0
ret ret
//Breakpoint, with an attempt at a functional function prologue and epilogue... .global gdbstub_do_break_breakpoint_addr
.global gdbstub_do_break_breakpoint_addr .global gdbstub_do_break
.global gdbstub_do_break .align 4
.align 4 /*
* Breakpoint, with an attempt at a functional function prologue and epilogue...
*/
gdbstub_do_break: gdbstub_do_break:
addi a1, a1, -16 addi a1, a1, -16
s32i a15, a1, 12 s32i a15, a1, 12
mov a15, a1 mov a15, a1
gdbstub_do_break_breakpoint_addr: gdbstub_do_break_breakpoint_addr:
break 0,0 break 0,0
mov a1, a15 mov a1, a15
l32i a15, a1, 12 l32i a15, a1, 12
addi a1, a1, 16 addi a1, a1, 16
ret ret

View File

@ -6,7 +6,6 @@ extern "C" {
#endif #endif
void gdbstub_init_debug_entry(void); void gdbstub_init_debug_entry(void);
void gdbstub_do_break(void);
void gdbstub_icount_ena_single_step(void); void gdbstub_icount_ena_single_step(void);
void gdbstub_save_extra_sfrs_for_exception(void); void gdbstub_save_extra_sfrs_for_exception(void);
void gdbstub_uart_entry(void); void gdbstub_uart_entry(void);

View File

@ -0,0 +1,25 @@
#ifndef GDBSTUB_EXC_H
#define GDBSTUB_EXC_H
#include "xtensa/xtensa_context.h"
/**
* @brief Structure of additional registers in excpeption fram as used by GDB
*/
STRUCT_BEGIN
STRUCT_FIELD (long, 4, XT_STK_LITBASE, litbase)
STRUCT_FIELD (long, 4, XT_STK_SR176, sr176)
STRUCT_FIELD (long, 4, XT_STK_SR208, sr208)
/*
* 'reason' is abused for both the debug and the exception vector:
* if bit 7 is set, this contains an exception reason, otherwise it
* contains a debug vector bitmap.
*/
STRUCT_FIELD (long, 4, XT_STK_REASON, reason)
STRUCT_END(XtExcFrameGdb)
#ifdef __cplusplus
extern "C" {
#endif
#endif /* GDBSTUB_EXC_H */

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@ extern "C" {
#endif #endif
void gdbstub_init(void); void gdbstub_init(void);
void gdbstub_do_break(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,3 +1,3 @@
All files in this directory are part of [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos.git). They are under the copyright of their respective owners. Please note the copyright notice in these files. All files in this directory are part of [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos.git). They are under the copyright of their respective owners.
All of these files are BSD Licensed as described in the file [LICENSE](https://github.com/SuperHouse/esp-open-rtos/blob/master/LICENSE). All of these files are BSD Licensed as described in the file [LICENSE](https://github.com/SuperHouse/esp-open-rtos/blob/master/LICENSE).

View File

@ -33,7 +33,7 @@ extern "C" {
#define UNUSED __attributed((unused)) #define UNUSED __attributed((unused))
#ifndef BIT #if defined(MCU_ESP8266) && !defined(BIT)
#define BIT(X) (1<<(X)) #define BIT(X) (1<<(X))
#endif #endif