[esp32c6] mstatus doesn't change while single-stepping
Posted: Sat Jul 06, 2024 11:10 pm
I'm debugging some bare-metal code on an esp32c6 WROOM board using the latest released versions of riscv32-esp-elf-gdb (14.2_20240403) and openocd-esp32 (v0.12.0-esp32-20240318).
In, for example, an OS context switch, the assembly code must write to the mstatus register with something like:
before doing an mret into the new OS task.
What I notice is that when this instruction is executed by instruction single-stepping, the value of mstatus does not change, but if I set a breakpoint somewhere past this instruction and continue over it, the value of mstatus will change.
The simplest example I have to show this is below:
If I single-step through this sequence, the csrs has no effect, while if I continue through it, bit 3 of mstatus will be set as expected.
I'm wondering if something about the debugger is implicitly manipulating mstatus in an unexpected way.
Loading the program and continuing:
Loading the program and single stepping:
In, for example, an OS context switch, the assembly code must write to the mstatus register with something like:
Code: Select all
csrw mstatus, t0
What I notice is that when this instruction is executed by instruction single-stepping, the value of mstatus does not change, but if I set a breakpoint somewhere past this instruction and continue over it, the value of mstatus will change.
The simplest example I have to show this is below:
Code: Select all
.section .text.start, "ax", %progbits
.global start
.type start, %function
start:
csrs mstatus, 8
ebreak
I'm wondering if something about the debugger is implicitly manipulating mstatus in an unexpected way.
Loading the program and continuing:
Code: Select all
(gdb) continue
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
start () at src/start/start.S:6
6 ebreak
(gdb) p/x $mstatus
$1 = 0x88
Code: Select all
(gdb) si
6 ebreak
(gdb) p/x $mstatus
$2 = 0x0