Skip to content

Walk CoreSight ROM tables within explicit limits. - #67

Merged
jon merged 3 commits into
mainfrom
work/coresight-rom
Sep 14, 2026
Merged

jon merged 3 commits into
mainfrom
work/coresight-rom

Conversation

@jon

@jon jon commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Add entry decoding and bounded traversal to coresight. Component.ROMTable recognizes class 1 and Arm class 9 ROM architecture 0x0af7, revision 0, and derives the entry count and width from that identity. ReadEntry validates one entry without accessing its child. Walk follows present entries in depth-first order and returns the visits recorded so far when inspection cannot finish.

Applications can validate their limits before opening hardware. This helper borrows an already-acquired MEM-AP and starts at its advertised entry:

func inspect(ctx context.Context, memory *dap.MemAP) error {
    limits := coresight.WalkLimits{MaxDepth: 8, MaxComponents: 256, MaxEntries: 4096}
    if err := limits.Validate(); err != nil {
        return err
    }
    base, present, err := memory.ReadDebugBase(ctx)
    if err != nil {
        return err
    }
    if !present {
        return errors.New("MEM-AP advertises no debug entry")
    }
    visits, err := coresight.Walk(ctx, memory, base, limits)
    for _, visit := range visits {
        if visit.Component != nil {
            fmt.Printf("parent=%d entry=%d base=%#x class=%#x\n",
                visit.Parent, visit.Index, visit.Component.Base, visit.Component.Class())
        }
        if visit.Err != nil {
            fmt.Printf("parent=%d entry=%d: %v\n", visit.Parent, visit.Index, visit.Err)
        }
    }
    return err
}

Limits cover the entire walk. Root depth is zero, the component bound counts root and skipped or failed visits, and the entry bound includes absent entries and terminators. Parent indexes refer to the returned slice. A non-table root is a successful single visit. Unknown component architectures are leaves; recognized ROM architectures with unsupported revisions or formats return errors. The traversal uses an explicit stack and rejects repeated tables before another identity read, covering cycles and duplicate table references.

An entry with a valid power-domain ID is recorded with ErrPowerDomain and skipped before any child access. Its accessible siblings are still inspected, but the walk returns a non-nil error. Every other failure stops the walk immediately, including a memory error which might invalidate the MEM-AP. Earlier visits remain available, and errors.Is can match the underlying cause, ErrWalkLimit, ErrRepeatedTable, or ErrPowerDomain.

The caller retains ownership. A MEM-AP borrowed from armdebug.Conn.OpenMemAP is released by closing that connection and retrying failed cleanup; a directly acquired MEM-AP must be released before its debug port. Inspection changes the MEM-AP's address and transfer state through ordinary reads but introduces no cleanup owner. It writes no target memory, requests no component power, and performs no unlocks, CTI configuration, halt, reset, or board activation. The caller supplies a safe root address; the API does not establish access to an advertised power domain.

Callers inspecting entries without following them can use the smaller operation on an identified component:

table, err := component.ROMTable()
if err != nil {
    return err
}
for i := 0; i < table.EntryCount(); i++ {
    entry, err := table.ReadEntry(ctx, memory, i)
    if err != nil {
        return err
    }
    if entry.End {
        break
    }
    if entry.Present {
        fmt.Printf("entry=%d base=%#x power-ID=%d valid=%t\n",
            i, entry.Base, entry.PowerID, entry.PowerIDValid)
    }
}

Entry decoding handles class 1 32-bit and class 9 32-bit or 64-bit layouts. It reads both words of a 64-bit entry before interpreting presence, rejects malformed encodings and address underflow or overflow, and returns no partial entry on failure. Power IDs remain scoped to the containing table. Class 1 FORMAT=0 is unsupported; all-ones entries are malformed.

The existing SWD example gains an explicit walk mode with depth 8, 256 visits, 4096 entry reads, and its existing ten-second deadline:

go run ./examples/simple/coresight-info \
  -provider cmsisdap -serial SERIAL -ap 0 -walk

-base ADDRESS can override the advertised root. The example prints available identities, parent and entry indexes, component errors, and whether the walk completed. Incomplete inspection exits unsuccessfully after printing partial results and attempting the existing bounded cleanup. Without -walk, it retains the single-component behavior. The library also works through JTAG memory; the example configures SWD only.

Why

A MEM-AP's advertised address often identifies a ROM table rather than the component an application needs. Entry decoding belongs above scalar memory, and traversal needs one place to enforce bounds, preserve failures, and skip components whose power-domain access has not been established. Separate entry reads remain useful for inspecting raw table contents without following children.

Documentation

Extend the CoreSight guide with entry layouts, traversal limits, parent links, power metadata, partial results, and bench observations. Update architecture, capabilities, composition, and example guides to expose those operations and the -walk option.

Hardware evidence

On the macOS Nostalgia bench, OSTIOLE_ROM_HIL=1 go test -tags=integration -run '^TestHILROMWalk$' -count=1 -v ./coresight opened two fresh 100 kHz sessions per path. Each used the advertised MEM-AP root, depth 8, 256 visits, 4096 entry reads, and a 120-second operation deadline.

CMSIS-DAP v2 micro:bit serial 9900360140124e4500279015000000360000000097969901, SWD AP0, completed six identities from root 0xf0000000, including the nested table at 0xe00ff000 and components at 0xe000e000, 0xe0001000, 0xe0002000, and 0xf0002000. The example also returned six visits and complete=true with that exact serial and its ten-second deadline.

FT4232H 01691/A on the externally enabled ZCU104 Arm 0x5ba00477/IR4 and Xilinx 0x14730093/IR12 JTAG chain, AP1, returned seventeen identities from root 0x80000000, then stopped on a DAP FAULT at CIDR address 0x803e0ff0. Both sessions retained the failed eighteenth visit for root entry 16. This is an incomplete walk and an observed access boundary, not an identified component or evidence that later entries are accessible. The error does not establish why that target access faulted.

Every owner reported successful close, including after the ZCU104 fault; restored state was not independently measured after close. The observed tables were class 1. Class 9 layouts and power-domain skips have ordinary test coverage; large addresses and both memory byte orders also have public MEM-AP simulation coverage, not physical validation here.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-14T03:10:37.445373Z 121ffb8 Manual request
🔒 Security Review Completed 2026-09-13T05:06:42.102296Z 82d961b PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@jon

jon commented Sep 13, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82d961b1cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

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".

Comment thread coresight/walk.go
@jon

jon commented Sep 13, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: 82d961b1cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

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".

jon added 3 commits September 13, 2026 20:02
Component identity does not describe the children behind a ROM
table. Derive entry geometry from the identified architecture and
expose bounded entry reads over borrowed scalar memory. Retain
presence and table-local power metadata without accessing children
or requesting power.

Validate format, reserved fields, and signed address arithmetic
before a caller can follow an entry. Read both words of a 64-bit
entry before decoding it, and return no partial entry after a failed
read.
Reading individual entries leaves hierarchy traversal and failure
handling with every caller. Walk present children in depth-first
order, retaining parent links and partial results while bounding
depth, visits, and entry reads across the entire walk. Use an
iterative stack and reject repeated tables before another identity
read.

Skip children whose entries name power domains and report the
incomplete result without requesting power. Stop on other failures
because a memory error can invalidate the borrowed client. Preserve
those causes and leave cleanup with the existing owner.
The example currently stops at the advertised component identity.
Add an explicit walk mode that calls the public traversal API with
fixed limits, prints partial results, and exits with a nonzero
status when inspection is incomplete. Keep cleanup with the existing
Arm debug owner.

Record the complete micro:bit hierarchy and the ZCU104 access
boundary in the opt-in hardware test and guides, including
successful owner close after the target fault and the limits of that
observation.
@jon
jon force-pushed the work/coresight-rom branch from 82d961b to 121ffb8 Compare September 14, 2026 03:04
@jon

jon commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: 121ffb8673

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

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".

@jon
jon merged commit 26e86e0 into main Sep 14, 2026
9 of 15 checks passed
@jon
jon deleted the work/coresight-rom branch September 14, 2026 03:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant