fix(raspi): the Pi 5's native path turns the MMU and caches on before any C; bounded mailbox; framebuffer address from dma-ranges

boards/BRINGUP.md R2/R3, FABRIC-3 SXXXIX.  The entry stub cleans the cache
over the image, builds an identity map (the image's GiB Normal, the rest
Device) and enables MMU and caches at EL2 (or EL1); rpi5_mmu.c makes the
devicetree's RAM Normal and the framebuffer uncached.  Mailbox waits give
up after one second; the buffer is cleaned around the exchange; the
framebuffer address goes through dma-ranges, not a Pi 4 mask.

New rpi5-rehearsal target runs the native image on QEMU virt at EL2.  It
found three more that would each have stopped the board: the PL011 shift
(mine, c9519173; the host test asserted it), the GIC address not carried
through /soc's ranges (new fdt_reg_address(), checked against the real
Pi 5 DTB), and no timer IRQ at EL2 (HCR_EL2.IMO/FMO/AMO).

Rehearsal: POST 1052 passed, same parity hash as UEFI.  Standard acceptance
on three ISAs: POST 1052, hash 0x82f4ae7cb2e2d424.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-14 12:58:35 -04:00
co-authored by Claude Opus 5.5
parent 4da370f492
commit 0e2c60dac3
23 changed files with 36835 additions and 85 deletions
+9 -5
View File
@@ -49,8 +49,8 @@ the prompt was told a key was waiting on every poll and read `0xFF` for ever.
| # | What | Where | Effect |
|---|---|---|---|
| R1 | **Fixed 2026-10-13.** Every character the console printed was also written to a PL011 at `0x09000000`, QEMU's address, which on a Pi 5 is ordinary RAM. The console now finds its serial line from the devicetree's `/chosen/stdout-path`: on the Pi 5 that is `serial10`, the debug connector, a PL011 at `0x107d001000`. | `kernel/src/hal/console.c`, `kernel/src/hal/fdt_uart.c`; `tools/fdt_uart_test.c` reads the board's real devicetree | Checked off the board only. The first run is the board's. |
| R2 | Entry is at EL2 with the MMU off. Nothing on this path has ever run. | `boards/raspi/README.md`; `FABRIC-3.md` IV.3 | Unknown. |
| R3 | Two details of the framebuffer request are unverified: the size field of the allocate tag, and whether the address returned needs its top bits masked. The mode is fixed at 1920x1080x32. | `FABRIC-3.md` IV.3 item 3 | No picture, or a wrong one. With R1 unfixed there is then no channel at all. |
| R2 | **Fixed 2026-10-14.** Entry is at EL2 with the MMU off, where every access is Device memory: unaligned accesses and atomics fault, nothing is cached. The entry stub now cleans the cache over the image, turns the MMU and caches on before any C (identity map: the image's GiB Normal in 2 MiB blocks, the rest Device), and routes interrupts to EL2; C then makes the rest of the devicetree's RAM Normal. Rehearsing it found and fixed three more: the PL011 register shift, the GIC address (not carried through `/soc`'s `ranges`), and the EL2 timer interrupt never being taken. | `native_rpi5_entry.S`, `rpi5_mmu.c`, `fdt.c` (`fdt_reg_address`), `apic.c`; `FABRIC-3.md` XXXIX | Rehearsed on QEMU virt at EL2 (section 3.2): POST passes, same parity hash. Not yet on the board. |
| R3 | **Partly fixed 2026-10-14.** The address returned is now carried through the devicetree's `dma-ranges` (on the Pi 5 it is already physical; the old `& 0x3FFFFFFF` was the Pi 4's rule), every mailbox wait gives up after one second, the request buffer is cleaned to RAM and back around the exchange, and the framebuffer is mapped uncached. Still unverified: the size field of the allocate tag. The mode is fixed at 1920x1080x32. | `rpi5_mailbox.c`, `rpi5_mmu.c`; `FABRIC-3.md` IV.3 item 3, XXXIX | QEMU virt has no mailbox: none of this runs before the board. No picture shows as no framebuffer, not a hang. |
| R4 | USB, Ethernet and GPIO are behind the RP1 chip on PCIe, which needs a Broadcom-specific driver that is not written. | `FABRIC-3.md` IV.3 item 5 | No USB on the Pi 5 whatever is done about A1. |
| R5 | No hardware entropy source is known for the BCM2712. | `FABRIC-3.md` IV.2 | A5 stands. |
@@ -150,8 +150,12 @@ One QEMU at a time. Use a copy of the image: the kernel writes to its disk.
- [ ] **SER5:** q35 with OVMF, the image as the only disk, no `-cdrom`, no virtio disk, no
thumbdrive. This is the machine the README's "booted in QEMU" refers to.
- [ ] **MILKV:** the command in `boards/milkv/README.md` (OpenSBI, U-Boot, `bootefi`).
- [ ] **RASPI:** there is no QEMU model of the Pi 5. Nothing can be rehearsed; the first run
is on the board.
- [ ] **RASPI:** there is no QEMU model of the Pi 5, but its native path -- raw image, entry
at EL2 with the MMU off, devicetree in x0 -- is rehearsed on QEMU virt:
`make -f kernel/Makefile ARCH=aarch64 RPI5_NATIVE_BASE=0x40080000 rpi5-rehearsal`
(log under `logs/<TS>/aarch64-rpi5/`). Not rehearsed: the mailbox and framebuffer, the
Pi 5's own UART and GIC addresses (checked against its real devicetree by
`tools/fdt_uart_test.c` instead), and PCI (virt's needs ACPI, the Pi 5's is R4).
### 3.3 What to settle in the rehearsal
@@ -167,7 +171,7 @@ One QEMU at a time. Use a copy of the image: the kernel writes to its disk.
## 4. On the bench
Do one board at a time, in this order: SER5, then the Mars, then the Pi 5. The SER5's path is
the one QEMU exercises most closely, and the Pi 5's cannot be rehearsed at all.
the one QEMU exercises most closely, and the Pi 5's can be rehearsed only in part (3.2).
### 4.1 Writing the media, every board