stub: fall back to fixed coreboot table address; DTB buffer reads zeros

Round 9, hex dump decoded:
  x0          = 0x5F800000 (= _fit_fdt_start, depthcharge's own FDT
                buffer; the kernel reserves 5f800000-5f815fff for it)
  dt[0..3]    = all zeros — no FDT magic at payload entry
  OVL_L0_ADDR = 0xFD536000 (real scanout, top-of-DRAM reserved region)

The device-era boot path flattens the fixed-up tree into
_fit_fdt_start and hands off that pointer. Why the kernel sees a valid
FDT there while the payload sees zeros is open (leading suspicion:
cache flush behavior differing with the ~30 MB pmOS kernel vs the
18 KB stub).

For the stub this is moot: the coreboot table address is a memlayout
constant on this board (0xffed9000, confirmed by the kernel's coreboot
driver, sysfs tags and /sys/firmware/fdt). find_coreboot_reg failure
now falls back to it instead of halting; the stub no longer depends on
the DTB. find_framebuffer failure still dumps the raw LBIO bytes.

Payload adbea06f... flashed and verified. host_test and qemu_test pass.
This commit is contained in:
vhaudiquet
2026-08-30 00:32:36 +02:00
parent edb21f2e94
commit 0688a7549b
4 changed files with 42 additions and 7 deletions
+29
View File
@@ -400,6 +400,35 @@ stage, word 15 = raw OVL_L0_ADDR value).
Payload `10760e3c…` flashed (cmp + vbutil OK). host_test and qemu_test
pass.
## Round 9 — dump decoded: x0's FDT buffer is empty; LBIO fallback
The hex dump worked. Transcription (`C0DE0001` = DTB stage failure):
x0 = 0x5F800000
dt[0..3] = 0, 0, 0, 0 (no FDT magic — buffer is zeros)
OVL_L0_ADDR = 0xFD536000 (real scanout, top-of-DRAM
reserved region, matches
/proc/iomem fae00000-ffdfffff)
x0 = `_fit_fdt_start` (device-era src/arch/arm/fit.c: the flattened tree
is placed in depthcharge's own `_fit_fdt_start.._fit_fdt_end` buffer and
that pointer is handed off). The kernel later reserves exactly
`5f800000-5f815fff` for its FDT (size ≈ the live fdt's 86738 bytes), so
the pointer is right — but for the payload boot the buffer content reads
as zeros. Why the kernel sees a valid FDT there while the payload sees
zeros is still OPEN (cache/flush difference vs the pmOS kernel boot is
the leading suspicion; the pmOS kernel is ~30 MB vs our 18 KB stub —
decompression footprint differs). For the stub this does not matter:
**Fallback added**: if `find_coreboot_reg` fails, use the fixed coreboot
table address `0xffed9000` (coreboot memlayout constant on this board;
confirmed by the kernel's own coreboot driver, sysfs tags, and
`/sys/firmware/fdt`). The stub no longer depends on the DTB at all.
`find_framebuffer` failure still dumps the raw LBIO bytes.
Payload `adbea06f…` flashed (cmp + vbutil OK). host_test and qemu_test
pass.
Recovery: power-cycle, boot USB (unchanged), `dd if=mmcblk0p1-pmos-backup.img
of=/dev/mmcblk0p1 bs=4M conv=fsync`.
Binary file not shown.
BIN
View File
Binary file not shown.
+13 -7
View File
@@ -401,6 +401,9 @@ static void checkpoint(const struct fbinfo *f, int r, int g, int b)
delay_ms(2000);
}
#define LBIO_FALLBACK_ADDR 0xffed9000ull /* coreboot memlayout, fixed */
#define LBIO_FALLBACK_SIZE 0x380
void cmain(u64 dtb)
{
struct fbinfo fb;
@@ -409,14 +412,17 @@ void cmain(u64 dtb)
stage0();
/*
* NOTE: on this device the FDT buffer depthcharge hands off (x0 =
* _fit_fdt_start = 0x5F800000) reads as all zeros at payload entry,
* so the DTB parse fails (RESEARCH.md Round 9). The coreboot table
* address, however, is fixed by coreboot's memlayout and confirmed
* by the running kernel (sysfs + /sys/firmware/fdt), so fall back
* to it instead of relying on the DTB.
*/
if (find_coreboot_reg((const void *)dtb, &lbio_addr, &lbio_size)) {
/* Dump the DTB header words + the x0 pointer itself. */
const volatile u32 *dt = (const volatile u32 *)dtb;
u32 w[6] = {
(u32)dtb, (u32)(dtb >> 32),
dt[0], dt[1], dt[2], dt[3],
};
fail_dump(0xC0DE0001u, w, 6);
lbio_addr = LBIO_FALLBACK_ADDR;
lbio_size = LBIO_FALLBACK_SIZE;
}
u32 l0 = read_scanout_addr();