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.
This commit is contained in:
+15
@@ -385,6 +385,21 @@ The OVL register READ is device-only (qemu -M virt aborts on reads to
|
||||
unassigned MMIO; qemu never takes the failure/substitution path, so the
|
||||
test is unaffected).
|
||||
|
||||
## Round 8 — hex-digit diagnostic dump
|
||||
|
||||
The bit-band dump WAS visible at the L0_ADDR scanout (proving both the
|
||||
scanout substitution and the render path), but 32 coarse squares per row
|
||||
proved unreadable from a photo, and the apparent row/column confusion
|
||||
made transcription unreliable. The dump rendering is replaced with
|
||||
**giant hex digits**: one u32 per line, 8 digits of a 3x5 cell font
|
||||
scaled x10 (30x50 px), MSB nibble first, white on depthcharge's black
|
||||
background. Readable in any panel orientation, transcribable as text.
|
||||
Same data, same markers (`0xC0DE0001` DTB stage, `0xC0DE0002|rc` LBIO
|
||||
stage, word 15 = raw OVL_L0_ADDR value).
|
||||
|
||||
Payload `10760e3c…` 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.
Binary file not shown.
@@ -313,34 +313,66 @@ static void stage0(void)
|
||||
|
||||
/* ---- failure diagnostics -------------------------------------------------
|
||||
*
|
||||
* The parse failed. Paint the failing values as bit-bands directly into
|
||||
* the live scanout buffer (read from OVL_L0_ADDR — the same buffer the
|
||||
* menu was displayed from, and the one clear_screen() blackened at
|
||||
* handoff). No parse result is needed to find it. Format: one row per
|
||||
* u32 word, 32 cells of 32x32 px, MSB first, white=1 / black=0, rows
|
||||
* every 64 px. Photograph the panel; decode offline. Word 0 is the
|
||||
* marker 0xC0DE00xx identifying the failure stage.
|
||||
* The parse failed. Paint the failing values as giant hex digits directly
|
||||
* into the live scanout buffer (read from OVL_L0_ADDR — the same buffer
|
||||
* the menu was displayed from and clear_screen() blackened at handoff).
|
||||
* No parse result is needed to find it. One word per line, 8 digits of
|
||||
* 3x5 cells scaled x10 (30x50 px), MSB nibble first, white on the black
|
||||
* background depthcharge left. Readable in any panel orientation.
|
||||
* Line 0 is the marker 0xC0DE00xx identifying the failure stage.
|
||||
*/
|
||||
|
||||
#define DIAG_FB_WIDTH 1200 /* menu geometry, 32bpp xRGB */
|
||||
#define DIAG_DIGIT_SCALE 10 /* 3x5 font -> 30x50 px */
|
||||
|
||||
static const u16 hexfont[16] = {
|
||||
0b111101101101111, /* 0 */
|
||||
0b010110010010111, /* 1 */
|
||||
0b111001111100111, /* 2 */
|
||||
0b111001011001111, /* 3 */
|
||||
0b101101111001001, /* 4 */
|
||||
0b111100111001111, /* 5 */
|
||||
0b111100111101111, /* 6 */
|
||||
0b111001001010010, /* 7 */
|
||||
0b111101111101111, /* 8 */
|
||||
0b111101111001111, /* 9 */
|
||||
0b111101111101101, /* A */
|
||||
0b100100111101111, /* b */
|
||||
0b111100100100111, /* C */
|
||||
0b001001111101111, /* d */
|
||||
0b111100111100111, /* E */
|
||||
0b111100111100100, /* F */
|
||||
};
|
||||
|
||||
static void fill_rect(u32 base, u32 x, u32 y, u32 w, u32 h, u32 c)
|
||||
{
|
||||
volatile u32 *fb = (volatile u32 *)(u64)base;
|
||||
for (u32 yy = 0; yy < h; yy++) {
|
||||
volatile u32 *row = fb + (u64)(y + yy) * DIAG_FB_WIDTH + x;
|
||||
for (u32 xx = 0; xx < w; xx++)
|
||||
row[xx] = c;
|
||||
}
|
||||
}
|
||||
|
||||
static void render_diag(u32 base, const u32 *d, int n)
|
||||
{
|
||||
volatile u32 *fb = (volatile u32 *)(u64)base;
|
||||
const u32 S = DIAG_DIGIT_SCALE;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
u32 y0 = 40 + (u32)i * 64;
|
||||
if (y0 + 32 > 1920)
|
||||
u32 y0 = 30 + (u32)i * 70;
|
||||
if (y0 + 50 > 1920)
|
||||
break;
|
||||
for (u32 b = 0; b < 32; b++) {
|
||||
u32 c = ((d[i] >> (31 - b)) & 1) ? 0x00FFFFFFu
|
||||
: 0x00000000u;
|
||||
for (u32 yy = 0; yy < 32; yy++) {
|
||||
volatile u32 *row = fb +
|
||||
(u64)(y0 + yy) * DIAG_FB_WIDTH + b * 32;
|
||||
for (u32 xx = 0; xx < 32; xx++)
|
||||
row[xx] = c;
|
||||
}
|
||||
for (u32 j = 0; j < 8; j++) {
|
||||
u32 nib = (d[i] >> (28 - 4 * j)) & 0xF;
|
||||
u16 g = hexfont[nib];
|
||||
u32 x0 = 40 + j * 4 * S;
|
||||
for (u32 gy = 0; gy < 5; gy++)
|
||||
for (u32 gx = 0; gx < 3; gx++)
|
||||
if ((g >> (14 - gy * 3 - gx)) & 1)
|
||||
fill_rect(base,
|
||||
x0 + gx * S,
|
||||
y0 + gy * S,
|
||||
S, S, 0x00FFFFFFu);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,9 +395,6 @@ static void fail_dump(u32 marker, const u32 *words, int n)
|
||||
render_diag(l0, diag, 16);
|
||||
halt();
|
||||
}
|
||||
|
||||
/* ---- main checkpoint sequence ------------------------------------------- */
|
||||
|
||||
static void checkpoint(const struct fbinfo *f, int r, int g, int b)
|
||||
{
|
||||
fill_screen(f, mkcolor(f, r, g, b));
|
||||
|
||||
Reference in New Issue
Block a user