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.
This commit is contained in:
vhaudiquet
2026-08-29 21:32:59 +02:00
parent fc4292918f
commit 10fb741163
4 changed files with 64 additions and 14 deletions
+63 -13
View File
@@ -115,9 +115,10 @@ by the time any payload runs") is false for this firmware generation.
### Key register facts established (all from device-era sources)
- OVL0 base `0x14008000`; `DISP_REG_OVL_EN = 0x0F00`, `DISP_REG_OVL0_2L_EN =
0x100C` (from 2021 `mtk_ddp.c`; the 0xF40 "L0_ADDR" register still holds
the menu's scanout address after stop — it is not reset).
- OVL0 base `0x14008000`; `DISP_REG_OVL_EN = 0x000C`, `DISP_REG_OVL0_2L_EN =
0x100C` (2021 `mtk_ddp.c` — **[REVERSED]** this log first claimed 0x0F00
for OVL_EN; see Round 2). The 0xF40 "L0_ADDR" register still holds the
menu's scanout address after stop — it is not reset.
- GPIO controller at `0x10005000`; `dout` block at +0x140, 16 bytes per
32-pin group, `set` at +4 / `rst` at +8. Backlight pins:
`DISP_PWM = 43` (group 1, bit 11 → set reg `0x10005154`),
@@ -139,12 +140,64 @@ Minimal inverse of the three teardown steps, executed before painting:
No DSI/panel re-init, no MTCMOS, no clock touching.
## Round 2 (post-revival reboot) — STILL BLACK: wrong OVL_EN offset
Observed: reboot into internal drive → pitch black after depthcharge boots
`mmcblk0p1`. No colors. p1 verified intact afterwards (first 159,744 bytes
hash to the payload; `vbutil_kernel --verify` on-device OK), so the stub ran.
### Live-environment re-checks
- `/dev/mem` LBIO read still blocked: pmOS kernel has `CONFIG_STRICT_DEVMEM`
(confirmed in `/boot/config`), `0xffed9000` sits in
`fae00000-ffdfffff : reserved` per `/proc/iomem` → `dd if=/dev/mem` gives
"Bad address". kexec remains the only live-read route; not needed — see
below.
- **Open item resolved without hardware access**: the runtime LBIO
`physical_address` is provably non-zero. Depthcharge's device-era
`mtk_display_init()` (`src/drivers/video/mtk_ddp.c`) programs
`OVL_L0_ADDR` from `lib_sysinfo.framebuffer.physical_address` (i.e. the
LBIO record) and the dev menu was visibly rendered through it;
`src/drivers/video/display.c` also gates display handling on
`physical_address != 0`. Mainline coreboot passes `fb_addr=0` for kukui
(`fb_new_framebuffer_info_from_edid(edid, 0)`), but the device-era
coreboot published a real address.
### Root cause
The stub's `display_revive()` re-enabled the overlay at the wrong register:
it wrote `OVL_EN` at `0x14008000 + 0x0F00`, but the actual offset in
depthcharge's `mtk_ddp.c` — confirmed in the 2021 revision (`497450b4`,
Jan 2021, inside the RO build window), the current tree, the merge commit
that unified mt8173/mt8183 (`74376061`, 2019), and Linux
`drivers/gpu/drm/mediatek/mtk_disp_ovl.c` — is `0x000C`.
The Round-1 "0x0F00 from device-era mtk_ddp.c" note was a misread
(0x0F00-era MT8173 offset / confusion with the 0x0F40 L0_ADDR neighborhood).
Consequence: depthcharge's stop wrote `OVL_EN=0` at `0x000C`, the stub
revived at `0x0F00` (a different, wrong register), the overlay engine stayed
disabled, and every fill landed in a buffer nothing scanned out. Painting in
the dark, again.
### Fix
`main.c::display_revive()`: `DISP_REG_OVL_EN` corrected to `0x000C`.
`OVL0_2L_EN = 0x100C` was already correct. Backlight GPIO writes were
correct (match `kukui_backlight_update`).
### Verification
payload `krane-fb-stub-payload.bin` sha256 `9e7cf29d…` (an intermediate
`41270e53…` rebuild was flashed once but built from the stale WIP tree
before the fix was synced into it — same wrong code as Round 1; caught by
disassembly before reboot), flashed to `mmcblk0p1`, `cmp` +
`vbutil_kernel --verify` OK. Awaiting reboot.
## Flash state
- `mmcblk0p1` reflashed with the revival payload:
sha256 `edb65b29191692186a6fde2058df05a1999c257e19b60cf01cf4ee63a6933237`,
sha256 `9e7cf29d3cddb83cda957a469ff5fb0dea70a2d67c9a6cc0a1f1497b19bc8756`,
verified on-device (`cmp` first 159,744 bytes + `vbutil_kernel --verify`
→ body verification succeeded).
→ body verification succeeded). (Round-1 payload was `edb65b29…`.)
- USB stick `sda1` untouched throughout (sha256 watched: `c4ee2044…`).
- eMMC backup: `~/mmcblk0p1-pmos-backup.img` (sha256 `20951a54…`).
**Copy it onto the USB stick before rebooting** so recovery never depends
@@ -163,13 +216,10 @@ of=/dev/mmcblk0p1 bs=4M conv=fsync`.
## Open items
- `physical_address` in the LBIO record is provably non-zero at runtime
(depthcharge's menu rendered through it), even though current mainline
coreboot passes `fb_addr=0` for kukui. Reading the live LBIO record from
Linux is currently blocked (pmOS kernel: `IO_STRICT_DEVMEM` → `/dev/mem`
EPERM, no `/proc/kcore`, sysfs coreboot driver exposes only tags). If the
revival fix doesn't produce colors, next step is a stub-side diagnostic
(e.g., blink backlight GPIO as a debug signal) or kexec-ing a small
reader.
- `physical_address` in the LBIO record — **resolved in Round 2**: provably
non-zero at runtime (depthcharge's device-era `mtk_display_init` programs
`OVL_L0_ADDR` from the LBIO record and the menu rendered through it; the
`/dev/mem` read attempt failed on `CONFIG_STRICT_DEVMEM` + reserved-RAM,
"Bad address", not EPERM as first assumed).
- qemu test updated to the same expectation (colors + held blue); it
exercises parser + fill logic, not the MMIO revival writes.
Binary file not shown.
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -247,7 +247,7 @@ static void fill_screen(const struct fbinfo *f, u64 val)
*/
#define DISP_OVL0_BASE 0x14008000u
#define DISP_REG_OVL_EN 0x0F00u /* 2021 mtk_ddp.c */
#define DISP_REG_OVL_EN 0x000Cu /* mtk_ddp.c, both mt8173/mt8183 */
#define DISP_REG_OVL0_2L_EN 0x100Cu /* 2021 mtk_ddp.c */
#define GPIO_BASE 0x10005000u