- fixed dbg
- exception stacksize can be larger than 32kB - debugger entry on ctrl-c inside debugger terminal git-svn-id: http://moon:8086/svn/mips@78 a8ebac50-d88d-4704-bea3-6648445a41b3
This commit is contained in:
@@ -5,8 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
#include "../../regdef.h"
|
||||||
|
|
||||||
extern uart_if_t uart_if[];
|
extern uart_if_t uart_if[];
|
||||||
|
|
||||||
@@ -26,6 +26,8 @@ con_if_t con_if =
|
|||||||
con_if_entry, ARRAYSIZE(con_if_entry)
|
con_if_entry, ARRAYSIZE(con_if_entry)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void dbg_uart_setup();
|
||||||
|
|
||||||
void board_init(void)
|
void board_init(void)
|
||||||
{
|
{
|
||||||
uint32_t volatile *pITIM_ctrl = (uint32_t*)SYS_ITIM_CTRL;
|
uint32_t volatile *pITIM_ctrl = (uint32_t*)SYS_ITIM_CTRL;
|
||||||
@@ -33,18 +35,53 @@ void board_init(void)
|
|||||||
// Disable timers
|
// Disable timers
|
||||||
*pITIM_ctrl = 0;
|
*pITIM_ctrl = 0;
|
||||||
|
|
||||||
// Initialzie syscall support
|
// Setup syscall support
|
||||||
syscalls_init();
|
syscalls_init();
|
||||||
|
|
||||||
// Initialzie interrupt support
|
// Setup Uart ISR
|
||||||
interrupt_init();
|
dbg_uart_setup();
|
||||||
|
|
||||||
// Initalize debugger
|
// Setup debugger
|
||||||
dbg_init();
|
dbg_init();
|
||||||
|
|
||||||
|
// Setup interrupt support
|
||||||
|
interrupt_init();
|
||||||
|
|
||||||
// Do some initializations here
|
// Do some initializations here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void dbg_handler(struct xcptcontext * xcp);
|
||||||
|
void dbg_uart_isr(struct xcptcontext *xcp);
|
||||||
|
void dbg_uart_setup()
|
||||||
|
{
|
||||||
|
uart_if_t *pUart = (uart_if_t*)con_getInstanceByName("UART-1");
|
||||||
|
|
||||||
|
*pUart->pCTRL = SYS_UART_BIT_RX_INTEN;
|
||||||
|
interrupt_register(SYS_INT_UART1, dbg_uart_isr);
|
||||||
|
interrupt_enable(SYS_INT_UART1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_uart_isr(struct xcptcontext *xcp)
|
||||||
|
{
|
||||||
|
uart_if_t *pUart = (uart_if_t*)con_getInstanceByName("UART-1");
|
||||||
|
|
||||||
|
if(SYS_UART_BIT_RX_AVAIL & *pUart->pCTRL)
|
||||||
|
{
|
||||||
|
char c = *pUart->pDATA;
|
||||||
|
if (c == 3)
|
||||||
|
{
|
||||||
|
// Disable UART interrupt
|
||||||
|
// to prevent consuming uart data in ISR during single step
|
||||||
|
// Interrupts mask bits are recovered on return from exception
|
||||||
|
//interrupt_disable(SYS_INT_UART1);
|
||||||
|
//uint32_t im = 1 << SYS_INT_UART1;
|
||||||
|
//xcp->sr &= ~(SR_MASK_IM & (im << 8));
|
||||||
|
//*pUart->pCTRL &= ~SYS_UART_BIT_RX_INTEN;
|
||||||
|
dbg_handler(xcp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dbg_putchar(char c)
|
void dbg_putchar(char c)
|
||||||
{
|
{
|
||||||
writechar(4, c);
|
writechar(4, c);
|
||||||
|
|||||||
+2
-1
@@ -15,7 +15,8 @@ LEAF(_xcpt_handler)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* allocate exception stack frame (on 8-byte boundary) */
|
/* allocate exception stack frame (on 8-byte boundary) */
|
||||||
subu k1, sp, XCP_SIZE
|
li k1, XCP_SIZE
|
||||||
|
subu k1, sp, k1
|
||||||
srl k1, 3 /* shift right/left -> alligned on boundary */
|
srl k1, 3 /* shift right/left -> alligned on boundary */
|
||||||
sll k1, 3
|
sll k1, 3
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ void exit_critical()
|
|||||||
|
|
||||||
void _exit (int exitcode)
|
void _exit (int exitcode)
|
||||||
{
|
{
|
||||||
|
sputs("\n\rexit\n\r");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
while(1);
|
while(1);
|
||||||
|
|||||||
+79
-48
@@ -6,6 +6,9 @@
|
|||||||
#include "libsys.h"
|
#include "libsys.h"
|
||||||
#include "mips_dis.h"
|
#include "mips_dis.h"
|
||||||
|
|
||||||
|
extern int instr_info(unsigned iword, instr_info_t *pInfo);
|
||||||
|
extern int tdisasm(char *buffer, unsigned address, unsigned iword, unsigned char ext, unsigned *regmask, unsigned *symbol_value, unsigned *ls_register);
|
||||||
|
|
||||||
#define DBG_PRINT_REG(tag_str, reg) \
|
#define DBG_PRINT_REG(tag_str, reg) \
|
||||||
dbg_puts(tag_str); \
|
dbg_puts(tag_str); \
|
||||||
dbg_print_word(reg); \
|
dbg_print_word(reg); \
|
||||||
@@ -34,6 +37,7 @@
|
|||||||
#define BP_MGMT_RU(id) (((BP_MGMT_BASE_RU + id) << 6) | 0x0D)
|
#define BP_MGMT_RU(id) (((BP_MGMT_BASE_RU + id) << 6) | 0x0D)
|
||||||
|
|
||||||
static char g_buf[80];
|
static char g_buf[80];
|
||||||
|
static int DEBUG_PRINT = 1;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -134,6 +138,23 @@ int dbg_gets(char *buffer, size_t size)
|
|||||||
dbg_putchar(0x0A);
|
dbg_putchar(0x0A);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dbg_puts_d(const char *buffer)
|
||||||
|
{
|
||||||
|
if (DEBUG_PRINT)
|
||||||
|
{
|
||||||
|
dbg_puts(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_print_word_d(int word)
|
||||||
|
{
|
||||||
|
if (DEBUG_PRINT)
|
||||||
|
{
|
||||||
|
dbg_print_word(word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int IsBreak(uint32_t instr)
|
int IsBreak(uint32_t instr)
|
||||||
@@ -158,24 +179,25 @@ char* reg_changed(uint32_t reg1, uint32_t reg2)
|
|||||||
return chg_str;
|
return chg_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_mgmt_break(uint32_t *pAddr_break)
|
void set_mgmt_break(uint32_t *pAddr_break, int index)
|
||||||
{
|
{
|
||||||
mgmt_bp_ss[0].pAddr = NULL;
|
mgmt_bp_ss[index].pAddr = NULL;
|
||||||
mgmt_bp_ss[0].pAddr = 0;
|
mgmt_bp_ss[index].instr = 0;
|
||||||
|
|
||||||
|
dbg_puts_d("Set management break at ");dbg_print_word_d((long)pAddr_break);dbg_puts_d("\n\r");
|
||||||
// Don't overwrite user breaks
|
// Don't overwrite user breaks
|
||||||
if (IsBreak(*pAddr_break) && (BreakGetType(*pAddr_break) == BP_USER_BASE))
|
if (IsBreak(*pAddr_break) && (BreakGetType(*pAddr_break) == BP_USER_BASE))
|
||||||
{
|
{
|
||||||
// dbg_puts("Instruction at address ");dbg_print_word((long)pAddr_break);dbg_puts(" is user break\n");
|
dbg_puts_d("Instruction at address ");dbg_print_word_d((long)pAddr_break);dbg_puts_d(" is user break\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Save original instruction
|
// Save original instruction
|
||||||
mgmt_bp_ss[0].pAddr = pAddr_break;
|
mgmt_bp_ss[index].pAddr = pAddr_break;
|
||||||
mgmt_bp_ss[0].instr = *(mgmt_bp_ss[0].pAddr);
|
mgmt_bp_ss[index].instr = *(mgmt_bp_ss[index].pAddr);
|
||||||
// Replace instruction with managment breakpoint
|
// Replace instruction with managment breakpoint
|
||||||
*(mgmt_bp_ss[0].pAddr) = BP_MGMT_SS(1);
|
*(mgmt_bp_ss[index].pAddr) = BP_MGMT_SS(index+1);
|
||||||
ICACHE_invalidate_at(mgmt_bp_ss[0].pAddr);
|
ICACHE_invalidate_at(mgmt_bp_ss[index].pAddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,42 +205,49 @@ void singlestep(struct xcptcontext * xcp, uint32_t *pAddr_curr, uint32_t is_bran
|
|||||||
{
|
{
|
||||||
|
|
||||||
int junk;
|
int junk;
|
||||||
uint32_t branch_addr, reg, result, bp_type;
|
uint32_t branch_addr, reg, bp_type;
|
||||||
uint32_t *pInstr, *pAddr_prev, *pAddr_next;
|
uint32_t *pInstr, *pAddr_prev, *pAddr_next;
|
||||||
|
instr_info_t info;
|
||||||
|
int set_break_at_jump_target = 0;
|
||||||
|
|
||||||
|
dbg_puts_d("is_branch_shadow = ");dbg_print_word_d((long)is_branch_shadow);dbg_puts_d("\n\r");
|
||||||
|
|
||||||
pAddr_prev = pAddr_curr - 1;
|
pAddr_prev = pAddr_curr - 1;
|
||||||
pAddr_next = pAddr_curr + 1;
|
pAddr_next = pAddr_curr + 1;
|
||||||
|
|
||||||
set_mgmt_break(pAddr_next);
|
|
||||||
|
|
||||||
mgmt_bp_ss[1].pAddr = NULL;
|
mgmt_bp_ss[1].pAddr = NULL;
|
||||||
mgmt_bp_ss[1].pAddr = 0;
|
mgmt_bp_ss[1].instr = 0;
|
||||||
|
|
||||||
// We have two possible management breaks, if previous instruction was branch or jump
|
// We have two possible management breaks, if previous instruction was branch or jump
|
||||||
if (is_branch_shadow)
|
if (is_branch_shadow)
|
||||||
{
|
{
|
||||||
result = tdisasm(g_buf, (long)pAddr_prev, *pAddr_prev, 0, &junk, &branch_addr, ®);
|
int type = instr_info(*pAddr_prev, &info);
|
||||||
// Is jump target stored in register
|
|
||||||
if (result == 3)
|
|
||||||
{
|
|
||||||
branch_addr = xcp->regs[reg&0x1F];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't overwrite user breaks
|
tdisasm(g_buf, (unsigned int)pAddr_prev, (unsigned int)*pAddr_prev, 0, &junk, (unsigned int*)&branch_addr, (unsigned int*)®);
|
||||||
|
// Is jump target stored in register
|
||||||
|
if (type == INSTR_TYPE_JUMP || type == INSTR_TYPE_BRANCH)
|
||||||
|
{
|
||||||
|
if (info.flags & (INSTR_FLAGS_JUMP_REGISTER|INSTR_FLAGS_BRANCH_REGISTER))
|
||||||
|
{
|
||||||
|
branch_addr = xcp->regs[reg&0x1F];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't overwrite user breaks
|
||||||
if (IsBreak(branch_addr) && (BreakGetType(branch_addr) == BP_USER_BASE))
|
if (IsBreak(branch_addr) && (BreakGetType(branch_addr) == BP_USER_BASE))
|
||||||
{
|
{
|
||||||
// dbg_puts("Instruction at branch address ");dbg_print_word((long)branch_addr);dbg_puts(" is user break\n");
|
dbg_puts_d("Instruction at branch address ");dbg_print_word_d((long)branch_addr);dbg_puts_d(" is user break\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Save original instruction
|
set_break_at_jump_target = 1;
|
||||||
mgmt_bp_ss[1].pAddr = (uint32_t*)branch_addr;
|
|
||||||
mgmt_bp_ss[1].instr = *(mgmt_bp_ss[1].pAddr);
|
|
||||||
// Replace instruction with managment breakpoint
|
|
||||||
*(mgmt_bp_ss[1].pAddr) = BP_MGMT_SS(2);
|
|
||||||
ICACHE_invalidate_at(mgmt_bp_ss[1].pAddr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set_mgmt_break(pAddr_next, 0);
|
||||||
|
if (set_break_at_jump_target)
|
||||||
|
{
|
||||||
|
set_mgmt_break((uint32_t*)branch_addr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbg_handler(struct xcptcontext * xcp)
|
void dbg_handler(struct xcptcontext * xcp)
|
||||||
@@ -238,6 +267,8 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
pAddr_prev = pAddr_curr - 1;
|
pAddr_prev = pAddr_curr - 1;
|
||||||
pAddr_next = pAddr_curr + 1;
|
pAddr_next = pAddr_curr + 1;
|
||||||
|
|
||||||
|
dbg_puts_d("\n\r");dbg_puts_d(g_state_names[g_state]);dbg_puts_d("\n\r");
|
||||||
|
|
||||||
if (IsBreak(*pAddr_curr))
|
if (IsBreak(*pAddr_curr))
|
||||||
{
|
{
|
||||||
bp_type = BreakGetType(*pAddr_curr);
|
bp_type = BreakGetType(*pAddr_curr);
|
||||||
@@ -247,12 +278,12 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
case BP_MGMT_BASE_SS:
|
case BP_MGMT_BASE_SS:
|
||||||
|
|
||||||
// Restore original instructions after single-step
|
// Restore original instructions after single-step
|
||||||
// dbg_puts("1. Restore after single-step at ");dbg_print_word((long)mgmt_bp_ss[0].pAddr);dbg_puts("\n\r");
|
dbg_puts_d("1. Restore after single-step at ");dbg_print_word_d((long)mgmt_bp_ss[0].pAddr);dbg_puts_d("\n\r");
|
||||||
*(mgmt_bp_ss[0].pAddr) = mgmt_bp_ss[0].instr;
|
*(mgmt_bp_ss[0].pAddr) = mgmt_bp_ss[0].instr;
|
||||||
ICACHE_invalidate_at(mgmt_bp_ss[0].pAddr);
|
ICACHE_invalidate_at(mgmt_bp_ss[0].pAddr);
|
||||||
if (mgmt_bp_ss[1].pAddr)
|
if (mgmt_bp_ss[1].pAddr)
|
||||||
{
|
{
|
||||||
// dbg_puts("2. Restore after single-step at ");dbg_print_word((long)mgmt_bp_ss[1].pAddr);dbg_puts("\n\r");
|
dbg_puts_d("2. Restore after single-step at ");dbg_print_word_d((long)mgmt_bp_ss[1].pAddr);dbg_puts_d("\n\r");
|
||||||
*(mgmt_bp_ss[1].pAddr) = mgmt_bp_ss[1].instr;
|
*(mgmt_bp_ss[1].pAddr) = mgmt_bp_ss[1].instr;
|
||||||
ICACHE_invalidate_at(mgmt_bp_ss[1].pAddr);
|
ICACHE_invalidate_at(mgmt_bp_ss[1].pAddr);
|
||||||
}
|
}
|
||||||
@@ -262,19 +293,19 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
case BP_MGMT_BASE_RU:
|
case BP_MGMT_BASE_RU:
|
||||||
|
|
||||||
bp_index = BP_GET_ID(*pAddr_curr);
|
bp_index = BP_GET_ID(*pAddr_curr);
|
||||||
// dbg_puts("Restore user break at ");dbg_print_word((long)user_bp[bp_index].pAddr);dbg_puts("\n\r");
|
dbg_puts_d("Restore user break at ");dbg_print_word_d((long)user_bp[bp_index].pAddr);dbg_puts_d("\n\r");
|
||||||
|
|
||||||
*(user_bp[bp_index].pAddr) = BP_USER(bp_index);
|
*(user_bp[bp_index].pAddr) = BP_USER(bp_index);
|
||||||
ICACHE_invalidate_at(user_bp[bp_index].pAddr);
|
ICACHE_invalidate_at(user_bp[bp_index].pAddr);
|
||||||
|
|
||||||
*(mgmt_bp_ru[0].pAddr) = mgmt_bp_ru[0].instr;
|
*(mgmt_bp_ru[0].pAddr) = mgmt_bp_ru[0].instr;
|
||||||
ICACHE_invalidate_at(mgmt_bp_ru[0].pAddr);
|
ICACHE_invalidate_at(mgmt_bp_ru[0].pAddr);
|
||||||
// dbg_puts("1. Restore after RU at ");dbg_print_word((long)mgmt_bp_ru[0].pAddr);dbg_puts("\n\r");
|
dbg_puts_d("1. Restore after RU at ");dbg_print_word_d((long)mgmt_bp_ru[0].pAddr);dbg_puts_d("\n\r");
|
||||||
if (mgmt_bp_ru[1].pAddr)
|
if (mgmt_bp_ru[1].pAddr)
|
||||||
{
|
{
|
||||||
*(mgmt_bp_ru[1].pAddr) = mgmt_bp_ru[1].instr;
|
*(mgmt_bp_ru[1].pAddr) = mgmt_bp_ru[1].instr;
|
||||||
ICACHE_invalidate_at(mgmt_bp_ru[1].pAddr);
|
ICACHE_invalidate_at(mgmt_bp_ru[1].pAddr);
|
||||||
// dbg_puts("2. Restore after RU at ");dbg_print_word((long)mgmt_bp_ru[1].pAddr);dbg_puts("\n\r");
|
dbg_puts_d("2. Restore after RU at ");dbg_print_word_d((long)mgmt_bp_ru[1].pAddr);dbg_puts_d("\n\r");
|
||||||
}
|
}
|
||||||
if (!g_is_ss)
|
if (!g_is_ss)
|
||||||
return;
|
return;
|
||||||
@@ -285,13 +316,13 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
|
|
||||||
is_user_bp = 1;
|
is_user_bp = 1;
|
||||||
bp_index = BP_GET_ID(*pAddr_curr);
|
bp_index = BP_GET_ID(*pAddr_curr);
|
||||||
// dbg_puts("Restore instruction at ");dbg_print_word((long)user_bp[bp_index].pAddr);dbg_puts("\n\r");
|
dbg_puts_d("Restore instruction at ");dbg_print_word_d((long)user_bp[bp_index].pAddr);dbg_puts_d("\n\r");
|
||||||
*(user_bp[bp_index].pAddr) = user_bp[bp_index].instr;
|
*(user_bp[bp_index].pAddr) = user_bp[bp_index].instr;
|
||||||
ICACHE_invalidate_at(user_bp[bp_index].pAddr);
|
ICACHE_invalidate_at(user_bp[bp_index].pAddr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// dbg_puts("Found ordinary break at ");dbg_print_word((long)pAddr_curr);dbg_puts("\n\r");
|
dbg_puts_d("Found ordinary break at ");dbg_print_word_d((long)pAddr_curr);dbg_puts_d("\n\r");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -339,8 +370,8 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
DBG_PRINT_REG_CHG("22 (s6) : ", xcp->regs[22], reg_changed(xcp->regs[22], xcp_last.regs[22]));
|
DBG_PRINT_REG_CHG("22 (s6) : ", xcp->regs[22], reg_changed(xcp->regs[22], xcp_last.regs[22]));
|
||||||
DBG_PRINT_REG_CHG("23 (s7) : ", xcp->regs[23], reg_changed(xcp->regs[23], xcp_last.regs[23]));
|
DBG_PRINT_REG_CHG("23 (s7) : ", xcp->regs[23], reg_changed(xcp->regs[23], xcp_last.regs[23]));
|
||||||
dbg_puts("\n\r");
|
dbg_puts("\n\r");
|
||||||
DBG_PRINT_REG_CHG("24 (s8) : ", xcp->regs[24], reg_changed(xcp->regs[24], xcp_last.regs[24]));
|
DBG_PRINT_REG_CHG("24 (t8) : ", xcp->regs[24], reg_changed(xcp->regs[24], xcp_last.regs[24]));
|
||||||
DBG_PRINT_REG_CHG("25 (s9) : ", xcp->regs[25], reg_changed(xcp->regs[25], xcp_last.regs[25]));
|
DBG_PRINT_REG_CHG("25 (t9) : ", xcp->regs[25], reg_changed(xcp->regs[25], xcp_last.regs[25]));
|
||||||
DBG_PRINT_REG_CHG("26 (k0) : ", xcp->regs[26], reg_changed(xcp->regs[26], xcp_last.regs[26]));
|
DBG_PRINT_REG_CHG("26 (k0) : ", xcp->regs[26], reg_changed(xcp->regs[26], xcp_last.regs[26]));
|
||||||
DBG_PRINT_REG_CHG("27 (k1) : ", xcp->regs[27], reg_changed(xcp->regs[27], xcp_last.regs[27]));
|
DBG_PRINT_REG_CHG("27 (k1) : ", xcp->regs[27], reg_changed(xcp->regs[27], xcp_last.regs[27]));
|
||||||
dbg_puts("\n\r");
|
dbg_puts("\n\r");
|
||||||
@@ -349,10 +380,6 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
DBG_PRINT_REG_CHG("30 (fp) : ", xcp->regs[30], reg_changed(xcp->regs[30], xcp_last.regs[30]));
|
DBG_PRINT_REG_CHG("30 (fp) : ", xcp->regs[30], reg_changed(xcp->regs[30], xcp_last.regs[30]));
|
||||||
DBG_PRINT_REG_CHG("31 (ra) : ", xcp->regs[31], reg_changed(xcp->regs[31], xcp_last.regs[31]));
|
DBG_PRINT_REG_CHG("31 (ra) : ", xcp->regs[31], reg_changed(xcp->regs[31], xcp_last.regs[31]));
|
||||||
dbg_puts("\n\r");
|
dbg_puts("\n\r");
|
||||||
dbg_puts("\n\r");
|
|
||||||
|
|
||||||
// dbg_puts(g_state_names[g_state]);dbg_puts("\n\r");
|
|
||||||
// dbg_puts("\n\r");
|
|
||||||
|
|
||||||
pInstr = pAddr_prev;
|
pInstr = pAddr_prev;
|
||||||
// Disassemble instructions
|
// Disassemble instructions
|
||||||
@@ -398,17 +425,21 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
*(mgmt_bp_ru[0].pAddr) = BP_MGMT_RU(bp_index);
|
*(mgmt_bp_ru[0].pAddr) = BP_MGMT_RU(bp_index);
|
||||||
ICACHE_invalidate_at(mgmt_bp_ru[0].pAddr);
|
ICACHE_invalidate_at(mgmt_bp_ru[0].pAddr);
|
||||||
mgmt_bp_ru[1].pAddr = NULL;
|
mgmt_bp_ru[1].pAddr = NULL;
|
||||||
mgmt_bp_ru[1].pAddr = 0;
|
mgmt_bp_ru[1].instr = 0;
|
||||||
// dbg_puts("1. Insert RU-break at ");dbg_print_word((long)mgmt_bp_ru[0].pAddr);dbg_puts("\n\r");
|
dbg_puts_d("1. Insert RU-break at ");dbg_print_word_d((long)mgmt_bp_ru[0].pAddr);dbg_puts_d("\n\r");
|
||||||
|
|
||||||
// We have two possible management breaks, if previous instruction was branch or jump
|
// We have two possible management breaks, if previous instruction was branch or jump
|
||||||
if (is_branch_shadow)
|
if (is_branch_shadow)
|
||||||
{
|
{
|
||||||
result = tdisasm(g_buf, (long)pAddr_prev, *pAddr_prev, 0, &junk, &branch_addr, ®);
|
int type = instr_info(*pAddr_prev, &info);
|
||||||
|
tdisasm(g_buf, (long)pAddr_prev, *pAddr_prev, 0, &junk, (unsigned int*)&branch_addr, (unsigned int*)®);
|
||||||
// Is jump target stored in register
|
// Is jump target stored in register
|
||||||
if (result == 3)
|
if (type == INSTR_TYPE_JUMP || type == INSTR_TYPE_BRANCH)
|
||||||
{
|
{
|
||||||
branch_addr = xcp->regs[reg&0x1F];
|
if (info.flags & (INSTR_FLAGS_JUMP_REGISTER|INSTR_FLAGS_BRANCH_REGISTER))
|
||||||
|
{
|
||||||
|
branch_addr = xcp->regs[reg&0x1F];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Save original instruction
|
// Save original instruction
|
||||||
mgmt_bp_ru[1].pAddr = (uint32_t*)branch_addr;
|
mgmt_bp_ru[1].pAddr = (uint32_t*)branch_addr;
|
||||||
@@ -416,7 +447,7 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
// Replace instruction with managment breakpoint
|
// Replace instruction with managment breakpoint
|
||||||
*(mgmt_bp_ru[1].pAddr) = BP_MGMT_RU(bp_index);
|
*(mgmt_bp_ru[1].pAddr) = BP_MGMT_RU(bp_index);
|
||||||
ICACHE_invalidate_at(mgmt_bp_ru[1].pAddr);
|
ICACHE_invalidate_at(mgmt_bp_ru[1].pAddr);
|
||||||
// dbg_puts("2. Insert RU-break at ");dbg_print_word((long)mgmt_bp_ru[1].pAddr);dbg_puts("\n\r");
|
dbg_puts_d("2. Insert RU-break at ");dbg_print_word_d((long)mgmt_bp_ru[1].pAddr);dbg_puts_d("\n\r");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,8 +547,8 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
pInstr++;
|
pInstr++;
|
||||||
} while(1);
|
} while(1);
|
||||||
|
|
||||||
// dbg_puts("Return found at "); dbg_print_word((long)pInstr);dbg_puts("\n\r");
|
dbg_puts_d("Return found at "); dbg_print_word_d((long)pInstr);dbg_puts_d("\n\r");
|
||||||
set_mgmt_break(pInstr);
|
set_mgmt_break(pInstr, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
@@ -544,7 +575,7 @@ void dbg_handler(struct xcptcontext * xcp)
|
|||||||
if ((result == INSTR_TYPE_JUMP) && (info.flags & INSTR_FLAGS_JUMP_LINK))
|
if ((result == INSTR_TYPE_JUMP) && (info.flags & INSTR_FLAGS_JUMP_LINK))
|
||||||
{
|
{
|
||||||
singlestep(xcp, pAddr_next, 0);
|
singlestep(xcp, pAddr_next, 0);
|
||||||
// printf("Skip sub-routine\n");
|
dbg_puts_d("Skip sub-routine\n\r");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ symbol: .frame sp, 0, ra
|
|||||||
|
|
||||||
/* Exception stack size */
|
/* Exception stack size */
|
||||||
#ifndef XCP_SIZE
|
#ifndef XCP_SIZE
|
||||||
#define XCP_SIZE 32768
|
#define XCP_SIZE 65536
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* save location for registers */
|
/* save location for registers */
|
||||||
|
|||||||
Reference in New Issue
Block a user