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:
+63
-13
@@ -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.
Binary file not shown.
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user