Fix/zephyr thread awareness #6
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes thread awareness support for Zephyr RTOS on RISC-V and Xtensa targets.
Xtensa Summary
The implementation reads thread register state from Zephyr's Base Save Area (BSA) structure using dynamic symbol-based offset resolution. The BSA size and register offsets vary based on Zephyr kernel configuration (FPU, loops, threadptr, etc.), so the implementation uses symbol addresses provided by GDB rather than hardcoded offsets.
Scope: This implementation only supports threads suspended via voluntary context switches (
arch_switch). Exception frames (involuntary context switches from interrupts/exceptions) are not supported.Accessing BSA Fields
Zephyr uses double indirection to locate the BSA on the thread's stack:
How OpenOCD reads registers:
thread->switch_handle(points to stack location)*switch_handleto getptr_to_bsa(points to BSA)ptr_to_bsaaddressZephyr Configuration Requirement
To enable thread awareness, Zephyr must expose the
switch_handleoffset in its thread info structure. Add the following tozephyr/kernel/thread_info.c:Note:
CONFIG_USE_SWITCHis enabled by default for Xtensa targets.Note:
CONFIG_DEBUG_THREAD_INFOmust be enabled in prj.confMemory Layout
Caller Spill Slots:
BSA_SIZE - 16, -12, -8, -4)caller_a0(BSA end - 16): Return address of calling functioncaller_a1(BSA end - 12): Stack pointer of calling functionENTRYinstructionDynamic Symbol Resolution:
The implementation uses symbol addresses provided by GDB to read BSA size and register offsets:
___xtensa_irq_bsa_t_SIZEOF- Total BSA size in bytes (configuration dependent)___xtensa_irq_bsa_t_ps_OFFSET- PS register offset within BSAGDB resolves these symbols from the ELF file and provides their addresses to OpenOCD, avoiding hardcoded offsets to maintain compatibility across different Zephyr kernel configurations (with/without FPU, loops, threadptr, etc.).
High Registers (A4-A15):
High registers are saved above the BSA on the stack when spilled during context switches. OpenOCD detects which register quads (A4-A7, A8-A11, A12-A15) were saved by checking marker values at fixed offsets relative to the BSA address. The registers are then read from their known locations and made available to GDB for debugging suspended threads.
RISC-V Summary
The implementation reads thread register state from Zephyr's
callee_savedstructure, which contains the callee-saved registers (SP, RA, S0-S11) that are preserved across context switches.Zephyr stores thread context directly in the thread structure:
To read
callee_savedfrom OpenOCD, Zephyr must expose thecallee_saved.spoffset in its thread info structure. This is typically provided by Zephyr'sthread_info.c:Note:
CONFIG_DEBUG_THREAD_INFOmust be enabled in prj.confMemory Layout:
For a suspended thread, the PC should point to where execution will resume when the thread is switched back in. In RISC-V, the Return Address (RA) register contains exactly this value. Setting
PC = RAenables proper backtrace construction in GDB.