10 Commits
Author SHA1 Message Date
vhaudiquet 0688a7549b 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.
2026-08-30 00:32:36 +02:00
vhaudiquet edb21f2e94 stub: render failure dump as giant hex digits
Round 8: the Round-7 bit-band dump was visible at the L0_ADDR scanout
(both the scanout substitution and the render path work), but 32 coarse
squares per row proved unreadable from a photo. Replace the rendering
with giant hex digits: one u32 per line, 8 digits of a 3x5 font scaled
x10 (30x50 px), white on the black background depthcharge left.
Readable in any panel orientation, transcribable as text.

Same data and markers as before; word 15 still carries the raw
OVL_L0_ADDR value. Payload 10760e3c... flashed and verified.
2026-08-30 00:22:09 +02:00
vhaudiquet 0974367f8d stub: use OVL_L0_ADDR as scanout ground truth; render diag there
Round 7: the Round-6 bit-band dump (painted at DRAM address 0) never
reached the panel — device-era libpayload cbgfx_init() rejects
physical_address == 0, so the menu could only have been drawn through a
non-zero runtime framebuffer address. Round 5's address-0 theory and its
'OVL never stopped' corollary are [REVERSED].

The authoritative scanout address is OVL_L0_ADDR (0x14008F40),
programmed by mtk_display_init() for the menu and left in place by
stop(). The stub now reads it (device-only; qemu never takes these
paths):

- success: if the LBIO record pa is 0, substitute the L0_ADDR scanout
  before painting checkpoints
- failure: fail_dump renders the bit-band dump at the scanout address;
  word 15 carries the raw L0_ADDR value

Full-file rewrite to untangle accumulated edit damage. host_test and
qemu_test pass; payload cebb9b1b... flashed and verified.
2026-08-30 00:08:16 +02:00
vhaudiquet 32e4c2e5da stub: render failure diagnostics as bit-bands on the panel
Round 6: pa==0 accepted but parse still fails on device (5 blinks).
All local reproductions pass, so the remaining unknowns are the actual
runtime values. Since the scanout address is known without any parse
(DRAM address 0 — Round 5), fail_dump() now renders diagnostic words as
32 white/black bit-cells per row directly into the scanout buffer after
the 5-blink execution signal.

Marker 0xC0DE0001: find_coreboot_reg failed — dumps x0 + raw DTB header.
Marker 0xC0DE0002|rc: find_framebuffer failed — dumps LBIO addr/size,
raw table magic/header_bytes/entries, and raw words at +24..+68.

Also fix a build break: u32 array = {0} emitted memset in freestanding.

host_test and qemu_test pass; payload e619166a... flashed and verified.
2026-08-29 23:46:21 +02:00
vhaudiquet da4aaca1c2 stub: accept LBIO physical_address == 0 — it is the real record here
Round 5: the Round-4 diagnostic blinks decoded as parse_fail. Root cause
confirmed in coreboot 4.14 source (kukui mainboard.c + edid_fill_fb.c):
the LBIO framebuffer record genuinely has physical_address = 0 — the
menu renders through DRAM address 0, which the never-stopped OVL scans
out (display_init_required() is false, so depthcharge registers no
display ops and its handoff cleanup's backlight/stop calls are no-ops).

Round-2's 'menu proves pa != 0' reasoning was wrong; the original
open-item note was right. The stub's !fb->pa rejection caused every
parse failure. find_framebuffer now accepts pa == 0 and the stub paints
at address 0, the same region depthcharge's own cleanup black-fills.

host_test gained a pa==0 regression test; qemu_test unchanged. Payload
b25d9132... flashed and verified (cmp + vbutil).
2026-08-29 23:09:37 +02:00
vhaudiquet 9e50b6ad61 stub: fix GPIO dout offset (0x140 -> 0x100) — backlight never fired
Round 4: still black with no backlight at all. Stage-0 enables the
backlight as its first act and the menu proved the backlight works via
GPIO 43/176, so the writes had to be missing. Re-derived GpioRegs from
the device-era mt8183.h: dir[6]@0x000 + rsv00[160] puts dout[6] at
0x100, not the 0x140 claimed in the Round-1 notes. Old addresses set
pin 172 (I2S1_MCK) instead of 43 and hit a reserved region instead of
176.

Also fix the blink: writing 0 to a set register is a no-op; use the
rst register with the bit.

This reframes rounds 2-4: OVL revival and fills may have been working
all along — an LCD shows nothing without backlight. Both round-1
register misreads (OVL_EN 0x0F00, dout 0x140) are now [REVERSED].

Payload 55ccc1bd... flashed and verified (cmp + vbutil). host_test and
qemu_test pass.
2026-08-29 22:39:44 +02:00
vhaudiquet dca94d627c stub: stage-0 diagnostic — prove handoff before parsing
Round 3: still black with the corrected OVL_EN offset. All device-era
display_cleanup steps are now provably undone, and init_screen()
sequencing proves the menu was drawn into the LBIO physical_address
(OVL_L0_ADDR == pa), so revival + fills are correct on paper. The
unexcluded branch: the payload may never execute — internal boot of a
custom p1 image was never baseline-proven on this device.

Diagnostic payload (9d7859dc...):
- first instructions: OVL_EN=1, OVL0_2L_EN=1, backlight on (no parse)
- parse failure: 5 slow backlight blinks, spin
- parse success: red -> yellow -> green -> blue, blue held

Decision tree: colors = pipeline validated; blinks on black = parse
failed at runtime; nothing = payload never handed off.

An earlier design read OVL_L0_ADDR pre-parse; abandoned: unassigned
MMIO reads data-abort on qemu -M virt (killed the test) and would do
the same on hardware with a gated display clock. The stub now has no
MMIO reads.

host_test and qemu_test pass; flashed and verified on device.
2026-08-29 22:01:59 +02:00
vhaudiquet 10fb741163 stub: fix OVL_EN offset in display_revive (0x0F00 -> 0x000C)
Round-1 revival wrote the overlay-enable register at 0x14008000+0x0F00;
depthcharge's mtk_ddp.c (2021 revision 497450b4, current tree, merge
commit 74376061, and Linux mtk_disp_ovl.c) defines DISP_REG_OVL_EN at
0x000C. The wrong-register write left the OVL engine disabled, so all
checkpoint fills were invisible (Round 2: black screen with payload
verified intact on mmcblk0p1).

Also: resolve the open physical_address question in RESEARCH.md (LBIO
fb addr is provably non-zero at runtime — mtk_display_init programs
OVL_L0_ADDR from the LBIO record and the dev menu rendered through it),
and log the /dev/mem live-read result (STRICT_DEVMEM + reserved RAM,
'Bad address' rather than EPERM).

Rebuilt payload sha256 9e7cf29d... verified on device (cmp + vbutil
body verification). host_test and qemu_test pass.
2026-08-29 21:32:59 +02:00
vhaudiquet 6e31a5566e main: revive display pipeline at handoff (fix black screen)
Root cause of the black screen, verified against the DEVICE's
depthcharge (v0.0.22-10476, ChromeOS R93-era): display_cleanup() runs
at CleanupOnHandoff before jumping to the payload and
  1. clears the LBIO framebuffer to black,
  2. drives DISP_PWM (GPIO 43) and EN_LCD_BL (GPIO 176) low,
  3. disables the OVL engines (OVL_EN=0, OVL0_2L_EN=0).
DSI/panel/MTCMOS remain up (panel poweroff only exists in 2025+ code),
so the stub just undoes those three steps: re-enable both OVLs, set
both backlight GPIOs, then paint. The OVL_L0_ADDR register still points
at the menu framebuffer, which is the LBIO record address our parser
already extracts.
2026-08-29 20:47:29 +02:00
vhaudiquet 64e19c213a krane-fb-stub: arm64 framebuffer test payload for depthcharge
Minimal freestanding arm64 binary that depthcharge boots as a kernel:
parses depthcharge's /firmware/coreboot DTB node, walks the coreboot
table, finds LB_TAG_FRAMEBUFFER, and paints red/yellow/green/blue
checkpoints (~2s each) into the live boot-splash framebuffer.

Verified against coreboot tables header, Linux arm64 booting.rst, and
depthcharge's fit.c/boot64.c. Host parser tests pass against the live
/sys/firmware/fdt; full red->yellow->green->blue sequence verified
end-to-end under qemu-system-aarch64; packed image verifies with the
ChromeOS devkeys.
2026-08-29 19:21:28 +02:00