feature: mirror all diagnostics to syslog, add VESA fallback for gfxd crashes
- syslogDump now outputs all five diagnostic sections (Fault Info, CPU Registers, Process Info, System Info, Call Stack) to serial, matching the on-screen BSOD content - panic() detects if the crash occurred in the gfxd process and falls back to rendering the BSOD directly to the VESA framebuffer via driver.video text drawing, bypassing LVGL entirely - Add DrawChar, DrawString, DrawHex, DrawInt to driver.video for 8x16 bitmap font rendering directly to the framebuffer - Export SHOULD_CRASH flag from svc.gfxd interface so test commands can trigger a deliberate gfxd crash - Add app.divzero with DIV0, PF, and CRASHGFXD test commands - Update doc/src/core/core.panic.md and doc/src/driver/video/driver.video.md
This commit is contained in:
1 parent
97b4460c48
commit
aa28d62e03
7 files changed
+444
-11
No files matched your search
@@ -0,0 +1,57 @@
|
||||
{
|
||||
Prog->Ping - ICMP Ping command.
|
||||
|
||||
Sends 10 ICMP echo requests to a host, printing round-trip time
|
||||
for each reply. Sleeps 1 second between pings. Each invocation
|
||||
uses a heap-allocated state record so multiple terminals can app.ping
|
||||
concurrently without corrupting each other.
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit app.divzero;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
io.stdio, debug.tracer;
|
||||
|
||||
procedure init();
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
arch.x86.bda, driver.net.types, driver.net.proto.icmp, driver.net.util, core.strings,
|
||||
proc.mgr, core.util, arch.x86.util, memory.heap, svc.gfxd;
|
||||
|
||||
{ ---- Command entry point (runs as a process) ---- }
|
||||
|
||||
procedure run_div0(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
begin
|
||||
asm
|
||||
XOR EAX, EAX
|
||||
DIV EAX { this will trigger a divide by zero exception (interrupt 0) }
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure run_pf(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
begin
|
||||
asm
|
||||
MOV EAX, $DEADBEEF
|
||||
MOV [EAX], EAX { this will trigger a page fault (interrupt 14) }
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure run_div0_gfxd(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
begin
|
||||
svc.gfxd.SHOULD_CRASH := true; { set flag to trigger crash in graphics service }
|
||||
end;
|
||||
|
||||
procedure init();
|
||||
begin
|
||||
debug.tracer.push_trace('divzero.init');
|
||||
io.stdio.registerCommand('DIV0', @run_div0, 'Force a divide by zero exception.');
|
||||
io.stdio.registerCommand('PF', @run_pf, 'Force a page fault.');
|
||||
io.stdio.registerCommand('CRASHGFXD', @run_div0_gfxd, 'Force a divide by zero exception in the graphics service.');
|
||||
end;
|
||||
|
||||
end.
|
||||
+3
-1
@@ -33,7 +33,8 @@ uses
|
||||
//dispatch
|
||||
driver.storage.filedispatch,
|
||||
//wasm
|
||||
app.wasm.runner;
|
||||
app.wasm.runner,
|
||||
app.divzero;
|
||||
|
||||
{ Initialize all baked-in programs }
|
||||
procedure init();
|
||||
@@ -81,6 +82,7 @@ begin
|
||||
driver.storage.filedispatch.init();
|
||||
app.wasm.runner.init();
|
||||
app.setres.init();
|
||||
app.divzero.init();
|
||||
end;
|
||||
|
||||
end.
|
||||
+240
-6
File diff suppressed because it is too large.
Load diff
@@ -22,7 +22,7 @@ unit driver.video;
|
||||
interface
|
||||
|
||||
uses
|
||||
memory.heap, debug.tracer, core.gfx.color, driver.video.types, core.ds.hashmap, core.util, arch.x86.util, core.gfx.texture, driver.video.gpu;
|
||||
memory.heap, debug.tracer, core.gfx.color, driver.video.types, core.ds.hashmap, core.util, arch.x86.util, core.gfx.texture, driver.video.gpu, core.gfx.fonts;
|
||||
|
||||
procedure init();
|
||||
procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
|
||||
@@ -46,6 +46,14 @@ function frontBufferLocation : uint32;
|
||||
|
||||
Procedure basicFDrawTexture(Buffer : PVideoBuffer; X : uint32; Y : uint32; Texture : PTexture);
|
||||
|
||||
{ Text drawing — renders 8x16 bitmap font glyphs directly to the
|
||||
framebuffer via DrawPixel. Useful for panic screens and other
|
||||
contexts where LVGL is unavailable. }
|
||||
function DrawChar(X, Y : uint32; C : char; Color : TRGB32) : uint32;
|
||||
function DrawString(X, Y : uint32; Str : pchar; Color : TRGB32) : uint32;
|
||||
function DrawHex(X, Y : uint32; Value : uint32; Color : TRGB32) : uint32;
|
||||
function DrawInt(X, Y : uint32; Value : uint32; Color : TRGB32) : uint32;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@@ -342,6 +350,81 @@ begin
|
||||
frontBufferLocation:= VideoInterface.FrontBuffer.Location;
|
||||
end;
|
||||
|
||||
{ ============================================================
|
||||
Text drawing — 8x16 bitmap font via Std_Font
|
||||
============================================================ }
|
||||
|
||||
const
|
||||
HexChars : array[0..15] of char = '0123456789ABCDEF';
|
||||
|
||||
function DrawChar(X, Y : uint32; C : char; Color : TRGB32) : uint32;
|
||||
var
|
||||
row, col : uint32;
|
||||
glyphRow : uint8;
|
||||
begin
|
||||
for row := 0 to 15 do begin
|
||||
glyphRow := Std_Font[ord(C) * 16 + row];
|
||||
for col := 0 to 7 do begin
|
||||
if (glyphRow AND ($80 SHR col)) <> 0 then
|
||||
DrawPixel(X + col, Y + row, Color);
|
||||
end;
|
||||
end;
|
||||
DrawChar := X + 8;
|
||||
end;
|
||||
|
||||
function DrawString(X, Y : uint32; Str : pchar; Color : TRGB32) : uint32;
|
||||
var
|
||||
i : uint32;
|
||||
begin
|
||||
i := 0;
|
||||
while Str[i] <> #0 do begin
|
||||
DrawChar(X, Y, Str[i], Color);
|
||||
X := X + 8;
|
||||
Inc(i);
|
||||
end;
|
||||
DrawString := X;
|
||||
end;
|
||||
|
||||
function DrawHex(X, Y : uint32; Value : uint32; Color : TRGB32) : uint32;
|
||||
var
|
||||
buf : array[0..10] of char;
|
||||
i : uint32;
|
||||
begin
|
||||
buf[0] := '0';
|
||||
buf[1] := 'x';
|
||||
for i := 0 to 7 do
|
||||
buf[2 + i] := HexChars[(Value SHR (28 - i * 4)) AND $F];
|
||||
buf[10] := #0;
|
||||
DrawHex := DrawString(X, Y, @buf[0], Color);
|
||||
end;
|
||||
|
||||
function DrawInt(X, Y : uint32; Value : uint32; Color : TRGB32) : uint32;
|
||||
var
|
||||
buf : array[0..11] of char;
|
||||
digits : array[0..9] of char;
|
||||
count : uint32;
|
||||
i : uint32;
|
||||
tmp : uint32;
|
||||
begin
|
||||
if Value = 0 then begin
|
||||
buf[0] := '0';
|
||||
buf[1] := #0;
|
||||
DrawInt := DrawString(X, Y, @buf[0], Color);
|
||||
exit;
|
||||
end;
|
||||
count := 0;
|
||||
tmp := Value;
|
||||
while tmp > 0 do begin
|
||||
digits[count] := char((tmp mod 10) + ord('0'));
|
||||
tmp := tmp div 10;
|
||||
Inc(count);
|
||||
end;
|
||||
for i := 0 to count - 1 do
|
||||
buf[i] := digits[count - 1 - i];
|
||||
buf[count] := #0;
|
||||
DrawInt := DrawString(X, Y, @buf[0], Color);
|
||||
end;
|
||||
|
||||
procedure reinit(fb_addr, width, height, pitch : uint32; bpp : uint8);
|
||||
begin
|
||||
debug.tracer.push_trace('driver.video.reinit.enter');
|
||||
|
||||
@@ -13,6 +13,10 @@ unit svc.gfxd;
|
||||
|
||||
interface
|
||||
|
||||
var
|
||||
SHOULD_CRASH : boolean; { set to true to intentionally trigger a crash for testing purposes }
|
||||
|
||||
|
||||
procedure init;
|
||||
|
||||
implementation
|
||||
@@ -56,6 +60,12 @@ begin
|
||||
lvgl_handler;
|
||||
driver.video.Flush;
|
||||
end;
|
||||
if SHOULD_CRASH then begin
|
||||
asm
|
||||
XOR EAX, EAX
|
||||
DIV EAX { this will trigger a divide by zero exception (interrupt 0) }
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Reference in new issue
Block a user