Read and write Cortex-M0 registers while halted. - #74
Merged
Merged
Conversation
Callers could halt a Cortex-M0 but could not inspect its registers through the target owner. Add typed register reads while halted, including when the halt belongs to another debugger. Track transfers before selecting a register so cleanup cannot resume the processor or disable debug while completion is uncertain. Release waits for a pending transfer without replaying the selection; reset or loss of Debug state prevents automatic cleanup.
The acquired target can now change core registers as well as read them. Keep XPSR read-only and reject unaligned stack pointers and odd debug return addresses before sending traffic. A failed write may already have changed the register. Keep only cleanup available after data staging fails or later completion is uncertain, without replaying the selection. Writes persist after release, and writing during an inherited halt does not grant resume ownership.
Show register reads between halt and resume in the control example. The gated bench checks the known counter firmware, reads the selected register set, and writes R4 patterns plus temporary stack and PC values. It restores and verifies all registers before allowing execution again; unconfirmed restoration retains both owners without requesting resume. Two fresh CMSIS-DAP sessions at 1 MHz passed on the micro:bit. The CPU counter stopped while halted and progressed after resume and release. Both sessions restored disabled debug and closed both owners. This does not establish execution with the temporary PC or stack values, or cleanup after a physical transport failure.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Owner
Author
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Add
Target.ReadRegisterandTarget.WriteRegisterfor an acquired Cortex-M0. Reads cover R0–R12, SP, LR, PC, XPSR, MSP, and PSP; writes cover the same set except XPSR. An inherited halt permits register access without granting permission to resume it. Register writes persist after release.With a borrowed MEM-AP, this reads PC and deliberately changes R4 to 42 before resuming:
SP selects the active stack bank; MSP and PSP name the banks explicitly. Stack writes require word alignment. PC is the debug return address and requires bit zero clear; writing it does not change Thumb state. Invalid identifiers and values are rejected before memory traffic.
Why
Halting the processor was available, but inspecting or changing its registers required callers to manage debug transfers themselves. The target now manages DCRDR data, selects the core register through DCRSR, and waits for S_REGRDY with the caller's cancellation and earlier deadline, capped at five seconds.
A selector write is never replayed after uncertain completion. Pending transfers block ordinary calls, and release must settle them before resuming or disabling debug. Reset or loss of Debug state during a pending transfer prevents automatic cleanup. A failed write may have changed the register; release does not roll back intentional register changes or restore DCRDR scratch contents.
Documentation
Update the Cortex-M guide, capability table, architecture and composition guides, and control example. The example prints PC, SP, R0, and R4 while halted. The API remains Cortex-M0 only; XPSR writes, CONTROL/PRIMASK access, reset, and stepping are outside this change.
Hardware evidence
On September 26, 2026, Nostalgia (macOS) ran two fresh CMSIS-DAP micro:bit sessions through SWD at a requested 1 MHz and AP0. Probe serial
9900360140124e4500279015000000360000000097969901; Cortex-M0 CPUID0x410cc200. The test verified the vectors and instructions of the previously programmed counter image before acquiring the target.Both sessions read all 19 registers, wrote and read back two R4 patterns plus temporary SP, MSP, PSP, and PC values, then restored and verified the full register snapshot. SP and MSP aliased as expected. The counter remained stopped across ten samples 20 milliseconds apart after restoration and advanced after resume and release. DHCSR was
0x01000000before acquisition and after release in both sessions; initially disabled debug and running state were restored. Both target and Arm debug owners closed successfully.The temporary PC and stack values were never used for execution. Writes to the other general registers and LR, process-stack selection, inherited halts, and failure cleanup have behavioral coverage only. State after Arm owner close was not measured.