FABRIC-3.md: pci_init() DTB path item was wrong -- re-scope, don't build the ECAM version
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run

Investigated before writing code, per this document's own discipline, and
found the original item 5 text's assumption doesn't hold: it framed this
as "swap the ACPI MCFG lookup for a DTB one, same flat-ECAM access
underneath." Confirmed against three primary sources that this is wrong:

- bcm2712-rpi-5-b.dts: RP1 sits under pcie2 ("brcm,bcm2712-pcie"),
  reg = <0x10 0x00120000 0x00 0x9310> -- a ~37KB window, far too small
  for a flat 256MB ECAM region.
- pcie-brcmstb.c (the real Linux driver for this compatible string):
  brcm_pcie_map_bus() computes a standard ECAM-shaped offset but accesses
  it through an IDX_ADDR/DATA_ADDR indirect index+window pair, not a
  direct MMIO read. A real third config-access mechanism, not a bigger
  version of the DTB-lookup task.

Re-scoped item 5 (§IV.3) to record the real shape: pci.c's cfg_read32/
cfg_write32 family dispatches today via #ifdef ARCH_AMD64 vs. everything
else (flat ECAM) -- but QEMU aarch64 (flat ECAM, real ACPI MCFG) and Pi 5
aarch64 (Broadcom indirect windowing) are the same build, so this needs a
runtime dispatch change to a file all three architectures currently boot
through, not a small addition. Also flagged: pci_init()'s vmm_map_range()
for the ECAM window is amd64-only today (aarch64/riscv64 rely on UEFI's
identity map); native boot has no UEFI identity map at all, so any PCIe
work here needs its own explicit mapping regardless of access mechanism.

Also corrected §V.3 item 5's now-stale "shares the same code" cross-
reference -- the Mars's JH7110 PCIe controller needs its own primary-
source check, not an assumed-shared implementation with RP1's.

Not implemented this pass -- recording the real shape is the deliverable;
building the runtime-dispatch version is a materially larger, separate
task. Doc-only change; 3-arch boot verified per the project's standing
rule, proving only that nothing regressed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
This commit is contained in:
Robert Allan James
2026-09-04 22:47:18 -04:00
co-authored by Claude Sonnet 5
parent 7187d68082
commit 11c93773d0
9 changed files with 27614 additions and 8 deletions
+46 -7
View File
@@ -405,9 +405,43 @@ blocker for free.
devicetree excerpt that confirmed it. Verified 3-arch boot to `ok>` (compile-only — these
two functions have no caller yet; that's the entry-stub/framebuffer-driver items above,
still open).
5. **`pci_init()` DTB path**: a devicetree-based alternative for RP1 discovery, since
`boot_info->acpi_table` will be `NULL` on this path and RP1 is PCIe-attached, not directly
memory-mapped.
5. **`pci_init()` DTB path — RE-SCOPED 2026-09-04, this item's own original text was wrong.**
Investigated before writing any code (per this document's own discipline) rather than
building the originally-assumed "swap the ACPI MCFG lookup for a DTB one, same flat-ECAM
access underneath" version — that assumption does not hold, confirmed against three primary
sources, not guessed:
- `bcm2712-rpi-5-b.dts` (real board file): RP1 is attached under `pcie2`
(`pcie2: pcie@1000120000`, `compatible = "brcm,bcm2712-pcie"`) via
`rp1_target: &pcie2 { status = "okay"; };`.
- `pcie2`'s own `reg` is `<0x10 0x00120000 0x00 0x9310>` — a ~37 KB window, far too small to
be a flat 256 MB ECAM region (256 buses × 1 MB) the way `pci.c`'s existing `ecam_*`
functions assume.
- The real Linux driver for `"brcm,bcm2712-pcie"` (`drivers/pci/controller/pcie-brcmstb.c`)
confirms why: `brcm_pcie_map_bus()` computes a standard ECAM-shaped offset
(`PCIE_ECAM_OFFSET(bus, devfn, 0)`) but does **not** read/write it directly — it writes
that offset to an `IDX_ADDR` index register, then accesses the config data through a small
windowed `DATA_ADDR` region. Root-complex-local accesses (`devfn == 0` on the root bus)
skip the indirection and hit `base + PCIE_ECAM_REG(where)` directly; every downstream
device access (RP1 included) goes through the index/data window.
- This is a real **third config-access mechanism**, not a bigger version of "find the ECAM
base in the DTB instead of ACPI." `pci.c`'s `cfg_read32`/`cfg_write32` family
(`pci.c:188232`) today dispatches exactly two ways, selected by `#ifdef ARCH_AMD64` vs.
everything else (flat `ecam_*`) — and that `#ifdef` selection is itself now wrong for this
case: QEMU aarch64 (flat ECAM via ACPI MCFG, real and working) and Pi 5 aarch64
(Broadcom indirect windowing) are the **same build** (`ARCH=aarch64`), so the dispatch
must become a runtime choice, not a compile-time one — a real change to a shared file all
three architectures currently boot clean through, not a small addition.
- Secondary finding, not yet acted on: `pci_init()`'s `vmm_map_range()` call for the ECAM
window is inside `#ifdef ARCH_AMD64` only (`pci.c:306318`) — aarch64/riscv64 rely on
UEFI's own identity map instead (per this file's own header comment). Native boot has no
UEFI identity map at all, so **any** PCIe work on this path — regardless of access
mechanism — needs its own explicit `vmm_map_range()` call, not just a new config-access
branch.
- **Not implemented this pass.** The re-scoped shape (add a third, runtime-selected
Broadcom-indirect access mode to `pci.c`, plus explicit VMM mapping for the native path)
is a materially larger, higher-blast-radius change than items 14 — it touches a file all
three architectures share and boot through today. Recording the real shape here is this
pass's own deliverable; building it is future work.
6. **`config.txt` contents, decided from research**: `kernel=kernel_2712.img` (or `kernel8.img`
with `os_check=0` if the Pi-5-specific name isn't used), `arm_64bit=1`, pointing at
`bcm2712-rpi-5-b.dtb`.
@@ -515,10 +549,15 @@ it doesn't. This is a real punch-list item, not a hypothetical.
pass — unlike the Pi 5's mailbox interface (well-documented, reused across many Pi bare-
metal projects), no equivalent research done yet for JH7110's own display controller.
Flagged here rather than assumed simple.
5. **`pci_init()` DTB path**: shares the same new code §IV.3 item 5 scopes for the Pi 5's RP1
— one implementation, two consumers (M.2 here, RP1 there), assuming the underlying DTB PCI
binding shape is similar enough (ECAM-based, most likely, but not yet confirmed for JH7110
specifically).
5. **`pci_init()` DTB path — the "shares §IV.3 item 5's code" framing is now wrong, corrected
2026-09-04.** §IV.3 item 5's own investigation found the Pi 5's RP1 sits behind a
Broadcom-specific indirect config-access window (`"brcm,bcm2712-pcie"`, confirmed against
`pcie-brcmstb.c`), not flat ECAM — a SoC-specific mechanism with no reason to assume it
matches JH7110's own PCIe controller. The "one implementation, two consumers" plan this line
originally stated no longer holds; the Mars's M.2 E-Key slot needs its **own** primary-source
check of JH7110's actual PCIe controller (compatible string, `reg` window size, and whether
its Linux driver uses flat ECAM or its own indirect scheme) before any implementation
decision, same discipline §IV.3 item 5 itself just applied. Not yet done.
6. **Boot image packaging**: `vf2-imager`/`mkimage`-based FIT image (§V.1) — confirm this
tooling's actual invocation once building the first real image, not just cited from
VisionFive 2 research.