Skip to content

Commit a9574c1

Browse files
dcpleungdanieldegrasse
authored andcommitted
xtensa: gdbstub: fix code stepping
The ICOUNTLEVEL register needs to be manipulated carefully according to where we want to stop. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
1 parent 0c627e9 commit a9574c1

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

arch/xtensa/core/gdbstub.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,52 @@ void arch_gdb_continue(void)
598598

599599
void arch_gdb_step(void)
600600
{
601+
uint32_t ps = xtensa_gdb_ctx.regs[xtensa_gdb_ctx.ps_idx].val;
602+
uint32_t intlevel = ps & PS_INTLEVEL_MASK;
603+
bool excm = (ps & PS_EXCM_MASK) != 0;
604+
uint32_t icountlevel;
605+
606+
/* Avoid counting while in this function. */
607+
set_one_sreg(ICOUNT, 0);
608+
set_one_sreg(ICOUNTLEVEL, 0);
609+
610+
/*
611+
* Note that ICOUNT only increments when current interrupt level
612+
* is less then ICOUNTLEVEL, and that ICOUNT interrupt is triggered
613+
* when it reaches zero.
614+
*/
615+
if (excm) {
616+
icountlevel = XCHAL_EXCM_LEVEL + 1;
617+
} else if (arch_curr_cpu()->nested > 1) {
618+
/*
619+
* ICOUNT, IBREAK and DBREAK all trigger interrupts.
620+
* So we need to account for nested being 1 when we
621+
* are running GDB stub. If nested is higher than one,
622+
* this means we are debugging inside ISRs.
623+
*/
624+
icountlevel = intlevel + 1;
625+
626+
/*
627+
* PS.INTLEVEL would be zero when it is level-1 interrupts.
628+
* A simple +1 does not work as ICOUNT would not stop inside
629+
* the ISR. So we need to up the ICOUNTLEVEL.
630+
*/
631+
icountlevel = MAX(icountlevel, 2);
632+
633+
/*
634+
* Make sure instructions are only counted below debug
635+
* interrupt level, or else ICOUNT would increment while
636+
* we are working in this function.
637+
*/
638+
icountlevel = MIN(icountlevel, XCHAL_DEBUGLEVEL);
639+
} else {
640+
/* Will break in non-ISR, normal code execution. */
641+
icountlevel = 1;
642+
}
643+
601644
set_one_sreg(ICOUNT, 0xFFFFFFFEU);
602-
set_one_sreg(ICOUNTLEVEL, XCHAL_DEBUGLEVEL);
645+
set_one_sreg(ICOUNTLEVEL, icountlevel);
646+
603647
__asm__ volatile("isync");
604648
}
605649

@@ -965,6 +1009,9 @@ void arch_gdb_init(void)
9651009
/* AR0: 0x0100 */
9661010
xtensa_gdb_ctx.ar_idx = idx;
9671011
break;
1012+
case 0x02E6:
1013+
/* PS: 0x02E6 */
1014+
xtensa_gdb_ctx.ps_idx = idx;
9681015
default:
9691016
break;
9701017
};

include/zephyr/arch/xtensa/gdbstub.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ struct gdb_ctx {
102102

103103
/** Index in register descriptions of AR0 register */
104104
uint8_t ar_idx;
105+
106+
/** Index in register descriptions of PS register */
107+
uint8_t ps_idx;
105108
};
106109

107110
/**

0 commit comments

Comments
 (0)