diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml index a558f8a..55ecaf4 100644 --- a/.markdownlint-cli2.yaml +++ b/.markdownlint-cli2.yaml @@ -1,3 +1,6 @@ config: - MD013: false + MD013: + line_length: 80 + code_blocks: false + tables: false MD041: false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e96c438..3d2896a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -173,11 +173,11 @@ hardware path. Begin with the resulting behavior and scope, without an opening heading. Headings, separators, and empty blocks do not satisfy the description requirement. Existing descriptions may retain “What this does” as the first -section heading. -For every new API, show representative calls which make ordinary use concrete. -For every changed API, show representative calls before and after the change so that the -migration is visible. The examples must preserve the same ownership, cleanup, -and safety rules as ordinary code. +section heading. For every new API, show representative calls which make +ordinary use concrete. For every changed API, show representative calls +before and after the change so that the migration is visible. The examples +must preserve the same ownership, cleanup, and safety rules as ordinary +code. Leave each prose paragraph on one line in the Markdown source and let GitHub wrap it for display. Do not insert source line breaks merely to meet a column @@ -197,6 +197,10 @@ independently. ## Documentation +Wrap repository Markdown prose at 80 columns. Code blocks and tables keep +their own layout. This source-file rule does not apply to pull-request +descriptions, whose paragraphs stay on one line. + Every pull request must leave the public documentation consistent with the code. A pull request that does not change public behavior may need no documentation edit, but its author must still verify that the existing claims diff --git a/docs/architecture.md b/docs/architecture.md index 66787de..fdfb2b0 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -265,51 +265,51 @@ thirty for JTAG. No driver is reopened automatically after a poisoned exchange. `NewAPSel` constructs an AP selector whose zero value is invalid. -`APSel.Address` combines it with a -complete eight-bit register address; the resulting `APAddress` also has an -invalid zero value. `ReadAPIDR` reads and decodes the common read-only AP -identity. Raw AP access rejects invalid or unaligned addresses before traffic. -Register names and effects remain specific to the selected AP class. A write -to a MEM-AP data register can write target memory. A raw AP read or write which -completes, or whose completion is uncertain, invalidates existing `MemAP` -values. On SWD, `dap.DebugPort` retries the same physical request after a clean WAIT -until its response-count limit is reached or the operation context ends. The +`APSel.Address` combines it with a complete eight-bit register address; the +resulting `APAddress` also has an invalid zero value. `ReadAPIDR` reads and +decodes the common read-only AP identity. Raw AP access rejects invalid or +unaligned addresses before traffic. Register names and effects remain +specific to the selected AP class. A write to a MEM-AP data register can +write target memory. A raw AP read or write which completes, or whose +completion is uncertain, invalidates existing `MemAP` values. On SWD, +`dap.DebugPort` retries the same physical request after a clean WAIT until +its response-count limit is reached or the operation context ends. The one-argument constructor uses only the context; `WithMaxWaits` sets a limit, -and `SetMaxWaits` changes it while the port is idle. If either boundary ends AP -waiting, the debug port issues DAPABORT and invalidates AP-derived state. +and `SetMaxWaits` changes it while the port is idle. If either boundary ends +AP waiting, the debug port issues DAPABORT and invalidates AP-derived state. RDBUFF also settles DP writes, but a stall or FAULT at that barrier does not trigger AP-only recovery. A FAULT is not retried: the debug port captures -bank-zero CTRL/STAT, clears the sticky conditions reported there, verifies the -clear through CTRL/STAT, and returns a typed error. AP-derived state is +bank-zero CTRL/STAT, clears the sticky conditions reported there, verifies +the clear through CTRL/STAT, and returns a typed error. AP-derived state is invalidated when the failed sequence might have changed it, but not when a -complete AP-write FAULT or WDATAERR establishes that the write was abandoned. -A SELECT write remains provisional until later traffic establishes whether -its data took effect. WDATAERR -invalidates the cached selection; FAULT handling reads `0x04` only when both -possible DP banks are zero. If FAULT cleanup, WAIT cleanup, or another transfer -leaves framing unknown, `dap.DebugPort` invalidates AP-derived state and blocks -every operation except cleanup. Cleanup re-enters SWD before sending another +complete AP-write FAULT or WDATAERR establishes that the write was +abandoned. A SELECT write remains provisional until later traffic +establishes whether its data took effect. WDATAERR invalidates the cached +selection; FAULT handling reads `0x04` only when both possible DP banks are +zero. If FAULT cleanup, WAIT cleanup, or another transfer leaves framing +unknown, `dap.DebugPort` invalidates AP-derived state and blocks every +operation except cleanup. Cleanup re-enters SWD before sending another framed request and refuses to restore state if DPIDR no longer matches the connection being cleaned up. Failed setup uses the DPIDR read by that attempt; cleanup for an established connection uses its last successful DPIDR. `Connect` attempts this cleanup itself when setup fails; a cleanup -failure remains pending for `Release`. Once `Release` starts, a failure likewise -leaves only `MemAP.Release`, `DebugPort.Release`, and the cached identity -available. `dap.MemAP` reads CFG, then uses one access port for aligned 8-, -16-, and 32-bit target-memory reads and writes when CSW accepts the selected -size. It also permits 64-bit transfers when CFG.LD is set and CSW accepts -Size64, and addresses above 32 bits when CFG.LA is set. If a Size64 transfer -fails after its first DRW access might have started, ordinary debug-port -traffic remains blocked until the MEM-AP and debug port are released. MEM-AP -cleanup terminates an incomplete transfer through CSW before restoring TAR or -TARHI. Arbitrary-range reads and writes use sub-word edges and bounded word -runs. No auto-incrementing word run crosses a 1 KiB TAR boundary. If CSW does -not retain single address increment, block access writes TAR before each word. -Scalar and block memory access use the same WAIT rule. An accepted write is not -replayed; if its RDBUFF completion request returns WAIT, only that request is -retried. If selection, framing, or cleanup becomes uncertain, the existing -repair behavior applies. A FAULT returns the confirmed prefix instead of -retrying the failed request. +failure remains pending for `Release`. Once `Release` starts, a failure +likewise leaves only `MemAP.Release`, `DebugPort.Release`, and the cached +identity available. `dap.MemAP` reads CFG, then uses one access port for +aligned 8-, 16-, and 32-bit target-memory reads and writes when CSW accepts +the selected size. It also permits 64-bit transfers when CFG.LD is set and +CSW accepts Size64, and addresses above 32 bits when CFG.LA is set. If a +Size64 transfer fails after its first DRW access might have started, +ordinary debug-port traffic remains blocked until the MEM-AP and debug port +are released. MEM-AP cleanup terminates an incomplete transfer through CSW +before restoring TAR or TARHI. Arbitrary-range reads and writes use sub-word +edges and bounded word runs. No auto-incrementing word run crosses a 1 KiB +TAR boundary. If CSW does not retain single address increment, block access +writes TAR before each word. Scalar and block memory access use the same +WAIT rule. An accepted write is not replayed; if its RDBUFF completion +request returns WAIT, only that request is retried. If selection, framing, +or cleanup becomes uncertain, the existing repair behavior applies. A FAULT +returns the confirmed prefix instead of retrying the failed request. ADIv5 access-port enumeration scans all 256 APSEL values in bounded transactions. IDR zero means absent. The scan does not assume contiguous AP @@ -317,11 +317,11 @@ numbers and reads no class-specific register. See [Arm Debug Access Ports](ports/dap.md) for the ADIv5 register protocol and the awkward parts of posted and memory access. -`dap.MemAP.ReadDebugBase` reads and decodes the selected AP's advertised debug -entry, including legacy encodings and the optional upper address word. It -preserves the memory client's state on success and does not access target -memory. `coresight` reads component identification through a scalar-memory reader. It -uses DAP transfer sizes but owns no DAP or MEM-AP state. See +`dap.MemAP.ReadDebugBase` reads and decodes the selected AP's advertised +debug entry, including legacy encodings and the optional upper address word. +It preserves the memory client's state on success and does not access target +memory. `coresight` reads component identification through a scalar-memory +reader. It uses DAP transfer sizes but owns no DAP or MEM-AP state. See [CoreSight component identity](coresight.md) for its register and failure boundaries. diff --git a/docs/capabilities.md b/docs/capabilities.md index 0d07126..2c5bb30 100644 --- a/docs/capabilities.md +++ b/docs/capabilities.md @@ -82,12 +82,13 @@ SWD entry, explicit JTAG chain/TAP selection, cancellation, release ordering, and retryable cleanup. `armdebug.JTAGDP` copies a complete `jtag.Layout` and selects a zero-based, -TDO-first TAP with an IDCODE and a four- or eight-bit IR. Invalid static configuration is -rejected before discovery or activation; connection setup validates the exact -physical chain. Board-specific chain routing remains external. -`Config.CleanupTimeout` bounds each owned release attempt, defaulting to one -second for SWD and thirty seconds for JTAG. DAP's independent recovery attempts -remain separately configurable through `DAPOptions`. +TDO-first TAP with an IDCODE and a four- or eight-bit IR. Invalid static +configuration is rejected before discovery or activation; connection setup +validates the exact physical chain. Board-specific chain routing remains +external. `Config.CleanupTimeout` bounds each owned release attempt, +defaulting to one second for SWD and thirty seconds for JTAG. DAP's +independent recovery attempts remain separately configurable through +`DAPOptions`. `armdebug.Open` adds registered discovery and exact selection to that ownership path. It refuses incomplete discovery and never tries another candidate after @@ -298,9 +299,10 @@ Available examples: - `examples/simple/ap-id` reports DPIDR and one explicitly selected AP IDR. - `examples/simple/cortexm-info` reports DPIDR, AP IDR, and Cortex-M CPUID. - `examples/simple/coresight-info` reads the MEM-AP's advertised component - identity, or an explicitly supplied page, through a managed SWD connection and selected MEM-AP. -- `examples/simple/arm-info` reports the same identities through generic probe - discovery and one Arm debug owner, with explicit AP selection. + identity, or an explicitly supplied page, through a managed SWD connection + and selected MEM-AP. +- `examples/simple/arm-info` reports the same identities through generic + probe discovery and one Arm debug owner, with explicit AP selection. Available `ost` commands: diff --git a/docs/composition.md b/docs/composition.md index e7f0aa5..31ace0c 100644 --- a/docs/composition.md +++ b/docs/composition.md @@ -627,32 +627,32 @@ the specification details which are easiest to misread. Use `dap.DebugPort` when the application needs debug-port identity, power ownership, bank selection, or AP access. Call `Connect` before AP operations -and `Release` afterward. `DebugPort.Connect` also connects its underlying SWD -stream, and `DebugPort.Release` releases it after restoring DAP state; do not -connect or release that stream separately. Give the debug port exclusive, -serialized use of its `swd.Conn`; direct transfers on that connection can -invalidate cached DAP state. DP, AP, transaction, and MEM-AP operations require -an active connection. -`ReadDP` and `WriteDP` take logical ADIv5 register names and manage DPBANKSEL -without exposing a current-bank API. `NewAPSel` constructs an AP selector whose -zero value is invalid. `APSel.Address` combines it with a complete eight-bit -register address; the resulting `APAddress` also has an invalid zero value. -`ReadAPIDR` reads and decodes the common read-only AP identity. `EnumerateAPs` -scans every ADIv5 AP selector without reading class-specific registers. Raw AP -access rejects an invalid or unaligned address before traffic. Use it only when -the caller understands the selected AP class and will restore any state the -access changes. A raw MEM-AP data-register write can write target memory. This +and `Release` afterward. `DebugPort.Connect` also connects its underlying +SWD stream, and `DebugPort.Release` releases it after restoring DAP state; +do not connect or release that stream separately. Give the debug port +exclusive, serialized use of its `swd.Conn`; direct transfers on that +connection can invalidate cached DAP state. DP, AP, transaction, and MEM-AP +operations require an active connection. `ReadDP` and `WriteDP` take logical +ADIv5 register names and manage DPBANKSEL without exposing a current-bank +API. `NewAPSel` constructs an AP selector whose zero value is invalid. +`APSel.Address` combines it with a complete eight-bit register address; the +resulting `APAddress` also has an invalid zero value. `ReadAPIDR` reads and +decodes the common read-only AP identity. `EnumerateAPs` scans every ADIv5 +AP selector without reading class-specific registers. Raw AP access rejects +an invalid or unaligned address before traffic. Use it only when the caller +understands the selected AP class and will restore any state the access +changes. A raw MEM-AP data-register write can write target memory. This layer owns AP read and write completion. Construct an SWD binding with `dap.NewDebugPort(dap.SWDP(conn))`; the operation context bounds WAIT retry. Adding `dap.WithMaxWaits(1)` stops at the first clean WAIT, reporting both -`dap.ErrWait` and its underlying `swd.ErrWait`. `SetMaxWaits` changes the limit before -`Connect` or after a successful `Release`; it rejects the change while the port -is connected or cleanup is pending. The count is per physical request and does -not bound host I/O. A raw AP read or write which completes, or might have -completed, invalidates existing `MemAP` values. If the limit or context ends -after an AP WAIT, `dap.DebugPort` issues DAPABORT; existing `dap.MemAP` values -reject further reads, though `dap.MemAP.Release` still attempts to restore their -saved state. +`dap.ErrWait` and its underlying `swd.ErrWait`. `SetMaxWaits` changes the +limit before `Connect` or after a successful `Release`; it rejects the +change while the port is connected or cleanup is pending. The count is per +physical request and does not bound host I/O. A raw AP read or write which +completes, or might have completed, invalidates existing `MemAP` values. If +the limit or context ends after an AP WAIT, `dap.DebugPort` issues DAPABORT; +existing `dap.MemAP` values reject further reads, though `dap.MemAP.Release` +still attempts to restore their saved state. For an explicit JTAG composition, pass `dap.JTAGDP(chain, tapIndex)` instead. The chain supplies the complete expected layout; the index is zero-based and diff --git a/docs/coresight.md b/docs/coresight.md index e10f992..0f089ea 100644 --- a/docs/coresight.md +++ b/docs/coresight.md @@ -83,10 +83,11 @@ go run ./examples/simple/coresight-info \ -provider cmsisdap -serial SERIAL -ap 0 ``` -To inspect another known page, supply `-base ADDRESS`; this bypasses the BASE -read. The override must name an accessible, 4 KiB aligned identification page. -The example requests a 100 kHz clock and applies a ten-second operation deadline. The library also accepts memory clients reached -through JTAG; the example configures SWD only. +To inspect another known page, supply `-base ADDRESS`; this bypasses the +BASE read. The override must name an accessible, 4 KiB aligned +identification page. The example requests a 100 kHz clock and applies a +ten-second operation deadline. The library also accepts memory clients +reached through JTAG; the example configures SWD only. ## Hardware evidence