Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8c7c2983d | ||
|
|
91bc0e5ea2 | ||
|
|
2cf879c4b9 | ||
|
|
fcc9809248 | ||
|
|
63b67f5878 | ||
|
|
e55da49900 | ||
|
|
521633c9a4 | ||
|
|
0cd32a0f64 | ||
|
|
f2e5f3535a | ||
|
|
2159578bdf |
No files matched your search
+587
File diff suppressed because it is too large.
Load diff
Binary file not shown.
|
After Width: | Height: | Size: 257 KiB |
Generated
+1
@@ -0,0 +1 @@
|
|||||||
|
mnt {device}/sys /sys
|
||||||
@@ -138,7 +138,7 @@ begin
|
|||||||
|
|
||||||
{ Open for writing }
|
{ Open for writing }
|
||||||
debug.tracer.push_trace('edit.SaveFile.openRW');
|
debug.tracer.push_trace('edit.SaveFile.openRW');
|
||||||
fHandle := driver.storage.vfs.OpenFile(FilePath, omReadWrite, wmRewrite, @fError);
|
fHandle := driver.storage.vfs.OpenFile(FilePath, omReadWrite, @fError);
|
||||||
if fHandle <> 0 then begin
|
if fHandle <> 0 then begin
|
||||||
debug.tracer.push_trace('edit.SaveFile.writeFile');
|
debug.tracer.push_trace('edit.SaveFile.writeFile');
|
||||||
driver.storage.vfs.WriteFile(fHandle, 0, puint8(buf), totalLen);
|
driver.storage.vfs.WriteFile(fHandle, 0, puint8(buf), totalLen);
|
||||||
@@ -149,7 +149,7 @@ begin
|
|||||||
end else begin
|
end else begin
|
||||||
{ Try write-only for new file }
|
{ Try write-only for new file }
|
||||||
debug.tracer.push_trace('edit.SaveFile.openWO');
|
debug.tracer.push_trace('edit.SaveFile.openWO');
|
||||||
fHandle := driver.storage.vfs.OpenFile(FilePath, omWriteOnly, wmNew, @fError);
|
fHandle := driver.storage.vfs.OpenFile(FilePath, omCreate, @fError);
|
||||||
if fHandle <> 0 then begin
|
if fHandle <> 0 then begin
|
||||||
debug.tracer.push_trace('edit.SaveFile.writeFileNew');
|
debug.tracer.push_trace('edit.SaveFile.writeFileNew');
|
||||||
driver.storage.vfs.WriteFile(fHandle, 0, puint8(buf), totalLen);
|
driver.storage.vfs.WriteFile(fHandle, 0, puint8(buf), totalLen);
|
||||||
@@ -181,7 +181,7 @@ begin
|
|||||||
if FilePath = nil then exit;
|
if FilePath = nil then exit;
|
||||||
|
|
||||||
debug.tracer.push_trace('edit.LoadFile.openFile');
|
debug.tracer.push_trace('edit.LoadFile.openFile');
|
||||||
fHandle := driver.storage.vfs.OpenFile(FilePath, omReadOnly, wmRewrite, @fError);
|
fHandle := driver.storage.vfs.OpenFile(FilePath, omRead, @fError);
|
||||||
debug.tracer.push_trace('edit.LoadFile.openFile.done');
|
debug.tracer.push_trace('edit.LoadFile.openFile.done');
|
||||||
if (fHandle = 0) or (fError <> eNone) then begin
|
if (fHandle = 0) or (fError <> eNone) then begin
|
||||||
io.syslog.writestringln('New file.');
|
io.syslog.writestringln('New file.');
|
||||||
|
|||||||
@@ -77,12 +77,15 @@ type
|
|||||||
{ Flat name buffer — heap-alloc'd in do_refresh to avoid stack bloat }
|
{ Flat name buffer — heap-alloc'd in do_refresh to avoid stack bloat }
|
||||||
TNameBuf = array[0..ENTRY_MAX - 1] of pchar;
|
TNameBuf = array[0..ENTRY_MAX - 1] of pchar;
|
||||||
PNameBuf = ^TNameBuf;
|
PNameBuf = ^TNameBuf;
|
||||||
|
TSizeBuf = array[0..ENTRY_MAX - 1] of uint32;
|
||||||
|
PSizeBuf = ^TSizeBuf;
|
||||||
|
|
||||||
{ Per-call context passed to the forEach collect callback }
|
{ Per-call context passed to the forEach collect callback }
|
||||||
PFPCollectCtx = ^TFPCollectCtx;
|
PFPCollectCtx = ^TFPCollectCtx;
|
||||||
TFPCollectCtx = record
|
TFPCollectCtx = record
|
||||||
dir_names : PNameBuf;
|
dir_names : PNameBuf;
|
||||||
file_names : PNameBuf;
|
file_names : PNameBuf;
|
||||||
|
file_sizes : PSizeBuf;
|
||||||
dir_count : uint32;
|
dir_count : uint32;
|
||||||
file_count : uint32;
|
file_count : uint32;
|
||||||
filter : pchar;
|
filter : pchar;
|
||||||
@@ -350,6 +353,28 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Insertion sort on name array, swapping a parallel size array in lockstep }
|
||||||
|
procedure sortNamesWithSizes(var names: array of pchar; var sizes: array of uint32; n: uint32);
|
||||||
|
var
|
||||||
|
i, j : uint32;
|
||||||
|
tmpN : pchar;
|
||||||
|
tmpS : uint32;
|
||||||
|
begin
|
||||||
|
if n < 2 then exit;
|
||||||
|
for i := 1 to n - 1 do begin
|
||||||
|
tmpN := names[i];
|
||||||
|
tmpS := sizes[i];
|
||||||
|
j := i;
|
||||||
|
while (j > 0) and strLess(tmpN, names[j - 1]) do begin
|
||||||
|
names[j] := names[j - 1];
|
||||||
|
sizes[j] := sizes[j - 1];
|
||||||
|
j := j - 1;
|
||||||
|
end;
|
||||||
|
names[j] := tmpN;
|
||||||
|
sizes[j] := tmpS;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ ============================================================
|
{ ============================================================
|
||||||
fp_collect_cb
|
fp_collect_cb
|
||||||
core.ds.hashmap.forEach callback: classifies each VFS entry as dir or file
|
core.ds.hashmap.forEach callback: classifies each VFS entry as dir or file
|
||||||
@@ -364,7 +389,7 @@ begin
|
|||||||
obj := PVFSObject(data);
|
obj := PVFSObject(data);
|
||||||
if (ctx = nil) or (obj = nil) then exit;
|
if (ctx = nil) or (obj = nil) then exit;
|
||||||
case obj^.ObjectType of
|
case obj^.ObjectType of
|
||||||
otVDIRECTORY, otDRIVE, otDIRECTORY, otMOUNT:
|
otVDIRECTORY, otDRIVE, otDIRECTORY, otMOUNT, otSYMLINK:
|
||||||
if ctx^.dir_count < ENTRY_MAX then begin
|
if ctx^.dir_count < ENTRY_MAX then begin
|
||||||
ctx^.dir_names^[ctx^.dir_count] := key;
|
ctx^.dir_names^[ctx^.dir_count] := key;
|
||||||
ctx^.dir_count := ctx^.dir_count + 1;
|
ctx^.dir_count := ctx^.dir_count + 1;
|
||||||
@@ -373,6 +398,7 @@ begin
|
|||||||
if matchesFilter(key, ctx^.filter) then
|
if matchesFilter(key, ctx^.filter) then
|
||||||
if ctx^.file_count < ENTRY_MAX then begin
|
if ctx^.file_count < ENTRY_MAX then begin
|
||||||
ctx^.file_names^[ctx^.file_count] := key;
|
ctx^.file_names^[ctx^.file_count] := key;
|
||||||
|
ctx^.file_sizes^[ctx^.file_count] := obj^.FileSize;
|
||||||
ctx^.file_count := ctx^.file_count + 1;
|
ctx^.file_count := ctx^.file_count + 1;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@@ -390,12 +416,14 @@ var
|
|||||||
ctx : TFPCollectCtx;
|
ctx : TFPCollectCtx;
|
||||||
dir_names : PNameBuf; { heap-alloc'd to avoid blowing the core.version stack }
|
dir_names : PNameBuf; { heap-alloc'd to avoid blowing the core.version stack }
|
||||||
file_names : PNameBuf;
|
file_names : PNameBuf;
|
||||||
|
file_sizes : PSizeBuf;
|
||||||
dir_count : uint32;
|
dir_count : uint32;
|
||||||
file_count : uint32;
|
file_count : uint32;
|
||||||
i : uint32;
|
i : uint32;
|
||||||
row, name_lbl, size_lbl : Plv_obj;
|
row, name_lbl, size_lbl : Plv_obj;
|
||||||
sep : pchar;
|
sep : pchar;
|
||||||
copy : pchar;
|
copy : pchar;
|
||||||
|
szStr : pchar;
|
||||||
s1, s2, s3 : pchar;
|
s1, s2, s3 : pchar;
|
||||||
begin
|
begin
|
||||||
debug.tracer.push_trace('filepicker.do_refresh');
|
debug.tracer.push_trace('filepicker.do_refresh');
|
||||||
@@ -408,8 +436,10 @@ begin
|
|||||||
io.syslog.logln('FPCIK', 'do_refresh: kalloc name bufs');
|
io.syslog.logln('FPCIK', 'do_refresh: kalloc name bufs');
|
||||||
dir_names := PNameBuf(kalloc(sizeof(TNameBuf)));
|
dir_names := PNameBuf(kalloc(sizeof(TNameBuf)));
|
||||||
file_names := PNameBuf(kalloc(sizeof(TNameBuf)));
|
file_names := PNameBuf(kalloc(sizeof(TNameBuf)));
|
||||||
|
file_sizes := PSizeBuf(kalloc(sizeof(TSizeBuf)));
|
||||||
memset(uint32(dir_names), 0, sizeof(TNameBuf));
|
memset(uint32(dir_names), 0, sizeof(TNameBuf));
|
||||||
memset(uint32(file_names), 0, sizeof(TNameBuf));
|
memset(uint32(file_names), 0, sizeof(TNameBuf));
|
||||||
|
memset(uint32(file_sizes), 0, sizeof(TSizeBuf));
|
||||||
|
|
||||||
{ Sync path bar }
|
{ Sync path bar }
|
||||||
if p^.path_bar <> nil then
|
if p^.path_bar <> nil then
|
||||||
@@ -429,6 +459,7 @@ begin
|
|||||||
lv_label_set_text(p^.status_label, 'Could not read directory');
|
lv_label_set_text(p^.status_label, 'Could not read directory');
|
||||||
kfree(void(dir_names));
|
kfree(void(dir_names));
|
||||||
kfree(void(file_names));
|
kfree(void(file_names));
|
||||||
|
kfree(void(file_sizes));
|
||||||
debug.tracer.pop_trace;
|
debug.tracer.pop_trace;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@@ -437,6 +468,7 @@ begin
|
|||||||
driver.storage.vfs.FreeDirectoryListing(Map);
|
driver.storage.vfs.FreeDirectoryListing(Map);
|
||||||
kfree(void(dir_names));
|
kfree(void(dir_names));
|
||||||
kfree(void(file_names));
|
kfree(void(file_names));
|
||||||
|
kfree(void(file_sizes));
|
||||||
debug.tracer.pop_trace;
|
debug.tracer.pop_trace;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@@ -444,6 +476,7 @@ begin
|
|||||||
|
|
||||||
ctx.dir_names := dir_names;
|
ctx.dir_names := dir_names;
|
||||||
ctx.file_names := file_names;
|
ctx.file_names := file_names;
|
||||||
|
ctx.file_sizes := file_sizes;
|
||||||
ctx.dir_count := 0;
|
ctx.dir_count := 0;
|
||||||
ctx.file_count := 0;
|
ctx.file_count := 0;
|
||||||
ctx.filter := p^.filter;
|
ctx.filter := p^.filter;
|
||||||
@@ -455,7 +488,7 @@ begin
|
|||||||
|
|
||||||
{ --- Sort both collections alphabetically --- }
|
{ --- Sort both collections alphabetically --- }
|
||||||
if dir_count > 0 then sortNames(dir_names^, dir_count);
|
if dir_count > 0 then sortNames(dir_names^, dir_count);
|
||||||
if file_count > 0 then sortNames(file_names^, file_count);
|
if file_count > 0 then sortNamesWithSizes(file_names^, file_sizes^, file_count);
|
||||||
|
|
||||||
{ --- Build directory rows --- }
|
{ --- Build directory rows --- }
|
||||||
if dir_count > 0 then
|
if dir_count > 0 then
|
||||||
@@ -524,10 +557,11 @@ begin
|
|||||||
lv_obj_set_style_text_color(name_lbl, lv_color_make(210, 215, 230), 0);
|
lv_obj_set_style_text_color(name_lbl, lv_color_make(210, 215, 230), 0);
|
||||||
lv_obj_set_style_text_font(name_lbl, @lv_font_montserrat_14, 0);
|
lv_obj_set_style_text_font(name_lbl, @lv_font_montserrat_14, 0);
|
||||||
|
|
||||||
{ File size column: skipped here to avoid blocking disk I/O
|
{ File size column: use metadata from directory listing }
|
||||||
inside the LVGL timer callback context. }
|
|
||||||
size_lbl := lv_label_create(row);
|
size_lbl := lv_label_create(row);
|
||||||
lv_label_set_text(size_lbl, '--');
|
szStr := fmtFileSize(file_sizes^[i]);
|
||||||
|
lv_label_set_text(size_lbl, szStr);
|
||||||
|
kfree(void(szStr));
|
||||||
lv_obj_set_width(size_lbl, 70);
|
lv_obj_set_width(size_lbl, 70);
|
||||||
lv_obj_set_style_text_color(size_lbl, lv_color_make(100, 110, 130), 0);
|
lv_obj_set_style_text_color(size_lbl, lv_color_make(100, 110, 130), 0);
|
||||||
lv_obj_set_style_text_font(size_lbl, @lv_font_montserrat_14, 0);
|
lv_obj_set_style_text_font(size_lbl, @lv_font_montserrat_14, 0);
|
||||||
@@ -543,6 +577,7 @@ begin
|
|||||||
|
|
||||||
kfree(void(dir_names));
|
kfree(void(dir_names));
|
||||||
kfree(void(file_names));
|
kfree(void(file_names));
|
||||||
|
kfree(void(file_sizes));
|
||||||
|
|
||||||
{ Update status label: "X dirs, Y files" }
|
{ Update status label: "X dirs, Y files" }
|
||||||
if p^.status_label <> nil then begin
|
if p^.status_label <> nil then begin
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ begin
|
|||||||
|
|
||||||
{ ---- READ ---- }
|
{ ---- READ ---- }
|
||||||
if op[0] = '<' then begin
|
if op[0] = '<' then begin
|
||||||
fHandle := driver.storage.vfs.OpenFile(absPath, omReadOnly, wmRewrite, @fError);
|
fHandle := driver.storage.vfs.OpenFile(absPath, omRead, @fError);
|
||||||
if (fHandle = 0) or (fError <> eNone) then begin
|
if (fHandle = 0) or (fError <> eNone) then begin
|
||||||
io.syslog.writestringln('Error: cannot open file for reading.');
|
io.syslog.writestringln('Error: cannot open file for reading.');
|
||||||
kfree(void(absPath));
|
kfree(void(absPath));
|
||||||
@@ -112,10 +112,10 @@ begin
|
|||||||
contentLen := stringSize(content);
|
contentLen := stringSize(content);
|
||||||
|
|
||||||
{ Try read-write rewrite first (existing file) }
|
{ Try read-write rewrite first (existing file) }
|
||||||
fHandle := driver.storage.vfs.OpenFile(absPath, omReadWrite, wmRewrite, @fError);
|
fHandle := driver.storage.vfs.OpenFile(absPath, omReadWrite, @fError);
|
||||||
if (fHandle = 0) or (fError <> eNone) then begin
|
if (fHandle = 0) or (fError <> eNone) then begin
|
||||||
{ Try creating new file }
|
{ Try creating new file }
|
||||||
fHandle := driver.storage.vfs.OpenFile(absPath, omWriteOnly, wmNew, @fError);
|
fHandle := driver.storage.vfs.OpenFile(absPath, omCreate, @fError);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (fHandle = 0) or (fError <> eNone) then begin
|
if (fHandle = 0) or (fError <> eNone) then begin
|
||||||
|
|||||||
@@ -372,9 +372,9 @@ begin
|
|||||||
buf := pchar(kalloc(FILE_BUF_SIZE));
|
buf := pchar(kalloc(FILE_BUF_SIZE));
|
||||||
memset(uint32(buf), 0, FILE_BUF_SIZE);
|
memset(uint32(buf), 0, FILE_BUF_SIZE);
|
||||||
memcpy(uint32(txt), uint32(buf), len);
|
memcpy(uint32(txt), uint32(buf), len);
|
||||||
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omReadWrite, wmRewrite, @fError);
|
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omReadWrite, @fError);
|
||||||
if fHandle = 0 then
|
if fHandle = 0 then
|
||||||
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omWriteOnly, wmNew, @fError);
|
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omCreate, @fError);
|
||||||
if fHandle = 0 then begin
|
if fHandle = 0 then begin
|
||||||
kfree(void(buf));
|
kfree(void(buf));
|
||||||
io.syslog.logln('NOTEPAD', 'saveFile: OpenFile failed');
|
io.syslog.logln('NOTEPAD', 'saveFile: OpenFile failed');
|
||||||
@@ -413,7 +413,7 @@ var
|
|||||||
buf : pchar;
|
buf : pchar;
|
||||||
begin
|
begin
|
||||||
debug.tracer.push_trace('notepad.loadFile');
|
debug.tracer.push_trace('notepad.loadFile');
|
||||||
fHandle := driver.storage.vfs.OpenFile(path, omReadOnly, wmRewrite, @fError);
|
fHandle := driver.storage.vfs.OpenFile(path, omRead, @fError);
|
||||||
if (fHandle = 0) or (fError <> eNone) then begin
|
if (fHandle = 0) or (fError <> eNone) then begin
|
||||||
io.syslog.logln('NOTEPAD', 'loadFile: could not open file');
|
io.syslog.logln('NOTEPAD', 'loadFile: could not open file');
|
||||||
showErrorMsgbox('Open Failed', 'Could not open file for reading.');
|
showErrorMsgbox('Open Failed', 'Could not open file for reading.');
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
{ Resolve relative to per-terminal cwd }
|
{ Resolve relative to per-terminal cwd }
|
||||||
Validity := driver.storage.vfs.changeDirectoryFrom(Path, state^.cwd, NewDir);
|
Validity := driver.storage.vfs.ChangeDirectoryFrom(Path, state^.cwd, NewDir);
|
||||||
case Validity of
|
case Validity of
|
||||||
pvDirectory: begin
|
pvDirectory: begin
|
||||||
kfree(void(state^.cwd));
|
kfree(void(state^.cwd));
|
||||||
@@ -410,7 +410,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if STRLL_Size(state^.dir_stack) > 0 then begin
|
if STRLL_Size(state^.dir_stack) > 0 then begin
|
||||||
wd := STRLL_Get(state^.dir_stack, STRLL_Size(state^.dir_stack) - 1);
|
wd := STRLL_Get(state^.dir_stack, STRLL_Size(state^.dir_stack) - 1);
|
||||||
Validity := driver.storage.vfs.changeDirectoryFrom(wd, state^.cwd, NewDir);
|
Validity := driver.storage.vfs.ChangeDirectoryFrom(wd, state^.cwd, NewDir);
|
||||||
if Validity = pvDirectory then begin
|
if Validity = pvDirectory then begin
|
||||||
kfree(void(state^.cwd));
|
kfree(void(state^.cwd));
|
||||||
state^.cwd := NewDir;
|
state^.cwd := NewDir;
|
||||||
@@ -696,7 +696,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end else begin
|
end else begin
|
||||||
{ No built-in command found — try file dispatch }
|
{ No built-in command found — try file dispatch }
|
||||||
absPath := driver.storage.vfs.makeAbsolutePathFrom(params^.Param, state^.cwd);
|
absPath := driver.storage.vfs.MakeAbsolutePathFrom(params^.Param, state^.cwd);
|
||||||
if absPath <> nil then begin
|
if absPath <> nil then begin
|
||||||
if is_bg then begin
|
if is_bg then begin
|
||||||
{ Background file dispatch }
|
{ Background file dispatch }
|
||||||
|
|||||||
@@ -152,36 +152,35 @@ var
|
|||||||
fh : TFileHandle;
|
fh : TFileHandle;
|
||||||
err : TError;
|
err : TError;
|
||||||
fsize : uint32;
|
fsize : uint32;
|
||||||
errb : uint8;
|
|
||||||
bytesRead : uint32;
|
bytesRead : uint32;
|
||||||
processCtx : PProcessContext;
|
processCtx : PProcessContext;
|
||||||
begin
|
begin
|
||||||
debug.tracer.push_trace('wasmrunner.handler');
|
debug.tracer.push_trace('wasmrunner.handler');
|
||||||
wasm_file_handler := 0;
|
wasm_file_handler := 0;
|
||||||
|
|
||||||
{ 1. Get file size }
|
{ 1. Open file once — omRead pre-loads the data and gives us the size }
|
||||||
errb := 0;
|
err := eNone;
|
||||||
fsize := driver.storage.vfs.FileSize(path, @errb);
|
fh := driver.storage.vfs.OpenFile(path, omRead, @err);
|
||||||
if (fsize = 0) or (errb <> 0) then begin
|
if (fh = 0) or (err <> eNone) then begin
|
||||||
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: cannot determine file size');
|
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: cannot open file');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
fsize := driver.storage.vfs.FileSizeFromHandle(fh);
|
||||||
|
if fsize = 0 then begin
|
||||||
|
driver.storage.vfs.CloseFile(fh);
|
||||||
|
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: file is empty or cannot determine size');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ 2. Allocate buffer and read file }
|
{ 2. Allocate buffer and read file }
|
||||||
buf := puint8(kalloc(fsize));
|
buf := puint8(kalloc(fsize));
|
||||||
if buf = nil then begin
|
if buf = nil then begin
|
||||||
|
driver.storage.vfs.CloseFile(fh);
|
||||||
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: out of memory');
|
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: out of memory');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
err := eNone;
|
|
||||||
fh := driver.storage.vfs.OpenFile(path, omReadOnly, wmRewrite, @err);
|
|
||||||
if fh = 0 then begin
|
|
||||||
kfree(void(buf));
|
|
||||||
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: cannot open file');
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
bytesRead := driver.storage.vfs.ReadFile(fh, 0, buf, fsize);
|
bytesRead := driver.storage.vfs.ReadFile(fh, 0, buf, fsize);
|
||||||
driver.storage.vfs.CloseFile(fh);
|
driver.storage.vfs.CloseFile(fh);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
arch.x86.panic - x86-specific kernel panic bridge.
|
||||||
|
|
||||||
|
Reads the saved interrupt register state (IntReg, IntErr, IntSpec)
|
||||||
|
and packs it into a TRegisterSnapshot, then delegates to
|
||||||
|
core.panic.panic() for architecture-agnostic display and halt.
|
||||||
|
|
||||||
|
@author(Kieron Morris <[email protected]>)
|
||||||
|
}
|
||||||
|
unit arch.x86.panic;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
core.panic;
|
||||||
|
|
||||||
|
{ Register the x86 halt procedure with core.panic. Call after LVGL init. }
|
||||||
|
procedure init;
|
||||||
|
|
||||||
|
{ Build a register snapshot from IntReg/IntErr/IntSpec and trigger panic.
|
||||||
|
Must be called AFTER correctInterruptRegisters(). }
|
||||||
|
procedure x86_panic(fault : pchar; info : pchar);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
arch.x86.util,
|
||||||
|
arch.x86.isr.types;
|
||||||
|
|
||||||
|
{ Helper: add a register entry to the snapshot and increment count. }
|
||||||
|
procedure addEntry(var snap : TRegisterSnapshot; name : pchar; value : uint32);
|
||||||
|
begin
|
||||||
|
if snap.Count < MAX_REGISTER_ENTRIES then begin
|
||||||
|
snap.Entries[snap.Count].Name := name;
|
||||||
|
snap.Entries[snap.Count].Value := value;
|
||||||
|
Inc(snap.Count);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure x86_panic(fault : pchar; info : pchar);
|
||||||
|
var
|
||||||
|
snap : TRegisterSnapshot;
|
||||||
|
begin
|
||||||
|
snap.Count := 0;
|
||||||
|
|
||||||
|
{ Pack general-purpose registers from the saved interrupt frame }
|
||||||
|
if IntReg <> nil then begin
|
||||||
|
addEntry(snap, 'EBP', IntReg^.EBP);
|
||||||
|
addEntry(snap, 'EAX', IntReg^.EAX);
|
||||||
|
addEntry(snap, 'EBX', IntReg^.EBX);
|
||||||
|
addEntry(snap, 'ECX', IntReg^.ECX);
|
||||||
|
addEntry(snap, 'EDX', IntReg^.EDX);
|
||||||
|
addEntry(snap, 'ESI', IntReg^.ESI);
|
||||||
|
addEntry(snap, 'EDI', IntReg^.EDI);
|
||||||
|
addEntry(snap, 'DS', uint32(IntReg^.DS));
|
||||||
|
addEntry(snap, 'ES', uint32(IntReg^.ES));
|
||||||
|
addEntry(snap, 'FS', uint32(IntReg^.FS));
|
||||||
|
addEntry(snap, 'GS', uint32(IntReg^.GS));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Error code }
|
||||||
|
if IntErr <> nil then
|
||||||
|
addEntry(snap, 'ERROR', IntErr^.Error);
|
||||||
|
|
||||||
|
{ Special registers (EIP, CS, EFLAGS) }
|
||||||
|
if IntSpec <> nil then begin
|
||||||
|
addEntry(snap, 'EIP', IntSpec^.EIP);
|
||||||
|
addEntry(snap, 'CS', IntSpec^.CS);
|
||||||
|
addEntry(snap, 'EFLAGS', IntSpec^.EFLAGS);
|
||||||
|
end;
|
||||||
|
|
||||||
|
core.panic.panic(fault, info, @snap);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure init;
|
||||||
|
begin
|
||||||
|
{ Register x86 halt as the panic halt procedure }
|
||||||
|
core.panic.registerHaltProc(@arch.x86.util.halt_and_catch_fire);
|
||||||
|
|
||||||
|
{ Initialize the BSOD LVGL screen }
|
||||||
|
core.panic.init;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
@@ -28,8 +28,7 @@ unit arch.x86.util;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
arch.x86.bda,
|
arch.x86.bda;
|
||||||
debug.tracer;
|
|
||||||
|
|
||||||
function INTE : boolean;
|
function INTE : boolean;
|
||||||
procedure CLI();
|
procedure CLI();
|
||||||
@@ -48,7 +47,6 @@ procedure __SSE_128_memcpy(source : uint32; dest : uint32);
|
|||||||
|
|
||||||
procedure halt_and_catch_fire();
|
procedure halt_and_catch_fire();
|
||||||
procedure halt_and_dont_catch_fire();
|
procedure halt_and_dont_catch_fire();
|
||||||
procedure BSOD(fault : pchar; info : pchar);
|
|
||||||
procedure psleep(t : uint16);
|
procedure psleep(t : uint16);
|
||||||
procedure sleep(seconds : uint32);
|
procedure sleep(seconds : uint32);
|
||||||
|
|
||||||
@@ -78,8 +76,7 @@ uses
|
|||||||
arch.x86.cpu,
|
arch.x86.cpu,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
driver.timer.rtc,
|
driver.timer.rtc,
|
||||||
driver.io.serial,
|
driver.io.serial;
|
||||||
io.syslog;
|
|
||||||
|
|
||||||
function MsSinceSystemBoot : uint64;
|
function MsSinceSystemBoot : uint64;
|
||||||
begin
|
begin
|
||||||
@@ -415,65 +412,6 @@ begin
|
|||||||
RorDWord:= result;
|
RorDWord:= result;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BSOD(fault : pchar; info : pchar);
|
|
||||||
var
|
|
||||||
trace : pchar;
|
|
||||||
i : uint32;
|
|
||||||
z : uint32;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if not BSOD_ENABLE then exit;
|
|
||||||
io.syslog.writestringln('=== KERNEL PANIC ===');
|
|
||||||
io.syslog.writestringln('ASURO DID A WHOOPSIE! :(');
|
|
||||||
io.syslog.writestringln(' ');
|
|
||||||
io.syslog.writestringln('Asuro encountered an error and your computer is now a teapot.');
|
|
||||||
io.syslog.writestringln('Your data is almost certainly safe.');
|
|
||||||
io.syslog.writestringln(' ');
|
|
||||||
io.syslog.writestringln('Details of the fault (for those boring enough to read) are as follows: ');
|
|
||||||
io.syslog.writestringln(' ');
|
|
||||||
io.syslog.writestring('Fault ID: ');
|
|
||||||
io.syslog.writestringln(fault);
|
|
||||||
io.syslog.writestring('Fault Info: ');
|
|
||||||
io.syslog.writestringln(info);
|
|
||||||
io.syslog.writestringln(' ');
|
|
||||||
if IntReg <> nil then begin
|
|
||||||
io.syslog.writestringln('Processor Info: ');
|
|
||||||
io.syslog.writestring(' EBP: '); io.syslog.writehex(IntReg^.EBP); io.syslog.writestring(' EAX: '); io.syslog.writehex(IntReg^.EAX); io.syslog.writestring(' EBX: '); io.syslog.writehexln(IntReg^.EBX);
|
|
||||||
io.syslog.writestring(' ECX: '); io.syslog.writehex(IntReg^.ECX); io.syslog.writestring(' EDX: '); io.syslog.writehex(IntReg^.EDX); io.syslog.writestring(' ESI: '); io.syslog.writehexln(IntReg^.ESI);
|
|
||||||
io.syslog.writestring(' EDI: '); io.syslog.writehex(IntReg^.EDI); io.syslog.writestring(' DS: '); io.syslog.writehex(IntReg^.DS); io.syslog.writestring(' ES: '); io.syslog.writehexln(IntReg^.ES);
|
|
||||||
io.syslog.writestring(' FS: '); io.syslog.writehex(IntReg^.FS); io.syslog.writestring(' GS: '); io.syslog.writehex(IntReg^.GS); io.syslog.writestring(' ERROR: '); io.syslog.writehexln(IntErr^.Error);
|
|
||||||
io.syslog.writestring(' EIP: '); io.syslog.writehex(IntSpec^.EIP); io.syslog.writestring(' CS: '); io.syslog.writehex(IntSpec^.CS); io.syslog.writestring(' EFLAGS: '); io.syslog.writehexln(IntSpec^.EFLAGS);
|
|
||||||
io.syslog.writestringln(' ');
|
|
||||||
end;
|
|
||||||
debug.tracer.freeze;
|
|
||||||
io.syslog.writestring('Call Stack: ');
|
|
||||||
trace:= debug.tracer.get_last_trace;
|
|
||||||
if trace <> nil then begin
|
|
||||||
io.syslog.writestring('[-0] ');
|
|
||||||
io.syslog.writestringln(trace);
|
|
||||||
for i:=1 to debug.tracer.get_trace_count-1 do begin
|
|
||||||
trace:= debug.tracer.get_trace_N(i);
|
|
||||||
if trace <> nil then begin
|
|
||||||
io.syslog.writestring(' [');
|
|
||||||
io.syslog.writestring('-');
|
|
||||||
io.syslog.writeint(i);
|
|
||||||
io.syslog.writestring('] ');
|
|
||||||
io.syslog.writestringln(trace);
|
|
||||||
end else begin
|
|
||||||
io.syslog.writestring(' [');
|
|
||||||
io.syslog.writestring('-');
|
|
||||||
io.syslog.writeint(i);
|
|
||||||
io.syslog.writestring('] ');
|
|
||||||
io.syslog.writestringln('?????????');
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end else begin
|
|
||||||
io.syslog.writestringln('Unknown.');
|
|
||||||
end;
|
|
||||||
io.syslog.writestringln('=== END KERNEL PANIC ===');
|
|
||||||
halt_and_catch_fire();
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure resetSystem();
|
procedure resetSystem();
|
||||||
var
|
var
|
||||||
good : uint8;
|
good : uint8;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ unit arch.x86.v86;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util, io.syslog, debug.tracer, arch.x86.memory.virtual, arch.x86.gdt, arch.x86.idt, arch.x86.isr.types;
|
core.util, arch.x86.util, core.panic, io.syslog, debug.tracer, arch.x86.memory.virtual, arch.x86.gdt, arch.x86.idt, arch.x86.isr.types;
|
||||||
|
|
||||||
const
|
const
|
||||||
{ V86 EFLAGS: VM=1 ($20000), IOPL=3 ($3000), IF=0 }
|
{ V86 EFLAGS: VM=1 ($20000), IOPL=3 ($3000), IF=0 }
|
||||||
@@ -540,8 +540,7 @@ end;
|
|||||||
|
|
||||||
procedure v86_chain_gpf; cdecl;
|
procedure v86_chain_gpf; cdecl;
|
||||||
begin
|
begin
|
||||||
BSOD('arch.x86.fault.gpf', 'General Protection Fault.');
|
core.panic.panic('arch.x86.fault.gpf', 'General Protection Fault.', nil);
|
||||||
halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure v86_gpf_isr; assembler; nostackframe;
|
procedure v86_gpf_isr; assembler; nostackframe;
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ unit arch.x86.fault.ace;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util,
|
arch.x86.util,
|
||||||
io.syslog,
|
arch.x86.panic,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
@@ -33,15 +33,10 @@ procedure register();
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Main();
|
procedure Main();
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CLI;
|
CLI;
|
||||||
correctInterruptRegisters(true);
|
correctInterruptRegisters(true);
|
||||||
BSOD('AC', 'Alignment Check Exception.');
|
x86_panic('arch.x86.fault.ace', 'Alignment Check Exception.');
|
||||||
io.syslog.writestringln('Alignment Check Exception.');
|
|
||||||
arch.x86.util.halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ unit arch.x86.fault.bpe;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util,
|
arch.x86.util,
|
||||||
io.syslog,
|
arch.x86.panic,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
@@ -33,15 +33,10 @@ procedure register();
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Main();
|
procedure Main();
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CLI;
|
CLI;
|
||||||
correctInterruptRegisters(false);
|
correctInterruptRegisters(false);
|
||||||
BSOD('BE', 'Breakpoint Exception.');
|
x86_panic('arch.x86.fault.bpe', 'Breakpoint Exception.');
|
||||||
io.syslog.writestringln('Breakpoint Exception');
|
|
||||||
arch.x86.util.halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ unit arch.x86.fault.btsse;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util,
|
arch.x86.util,
|
||||||
io.syslog,
|
arch.x86.panic,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
@@ -33,15 +33,10 @@ procedure register();
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Main();
|
procedure Main();
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CLI;
|
CLI;
|
||||||
correctInterruptRegisters(true);
|
correctInterruptRegisters(true);
|
||||||
BSOD('TSS', 'Bad TSS Exception.');
|
x86_panic('arch.x86.fault.btsse', 'Bad TSS Exception.');
|
||||||
io.syslog.writestringln('Bad TSS Exception.');
|
|
||||||
arch.x86.util.halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ unit arch.x86.fault.cfe;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util,
|
arch.x86.util,
|
||||||
io.syslog,
|
arch.x86.panic,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
@@ -33,15 +33,10 @@ procedure register();
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Main();
|
procedure Main();
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CLI;
|
CLI;
|
||||||
correctInterruptRegisters(false);
|
correctInterruptRegisters(false);
|
||||||
BSOD('CF', 'Coprocessor Fault Exception.');
|
x86_panic('arch.x86.fault.cfe', 'Coprocessor Fault Exception.');
|
||||||
io.syslog.writestringln('Coprocessor Fault Exception.');
|
|
||||||
arch.x86.util.halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ unit arch.x86.fault.csoe;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util,
|
arch.x86.util,
|
||||||
io.syslog,
|
arch.x86.panic,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
@@ -33,15 +33,10 @@ procedure register();
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Main();
|
procedure Main();
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CLI;
|
CLI;
|
||||||
correctInterruptRegisters(false);
|
correctInterruptRegisters(false);
|
||||||
BSOD('CSO', 'Coprocessor Seg Overrun Exception.');
|
x86_panic('arch.x86.fault.csoe', 'Coprocessor Seg Overrun Exception.');
|
||||||
io.syslog.writestringln('Coprocessor Seg Overrun Exception.');
|
|
||||||
arch.x86.util.halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ unit arch.x86.fault.dbge;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util,
|
arch.x86.util,
|
||||||
io.syslog,
|
arch.x86.panic,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
@@ -33,15 +33,10 @@ procedure register();
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Main();
|
procedure Main();
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CLI;
|
CLI;
|
||||||
correctInterruptRegisters(false);
|
correctInterruptRegisters(false);
|
||||||
BSOD('DE', 'Debug Exception');
|
x86_panic('arch.x86.fault.dbge', 'Debug Exception.');
|
||||||
io.syslog.writestringln('Debug Exception.');
|
|
||||||
arch.x86.util.halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ unit arch.x86.fault.dbz;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util,
|
arch.x86.util,
|
||||||
io.syslog,
|
arch.x86.panic,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
@@ -33,15 +33,10 @@ procedure register();
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Main();
|
procedure Main();
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CLI;
|
CLI;
|
||||||
correctInterruptRegisters(false);
|
correctInterruptRegisters(false);
|
||||||
BSOD('arch.x86.fault.dbz', 'Divide By Zero Exception.');
|
x86_panic('arch.x86.fault.dbz', 'Divide By Zero Exception.');
|
||||||
io.syslog.writestringln('Divide by Zero Exception.');
|
|
||||||
arch.x86.util.halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ unit arch.x86.fault.dfe;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
core.util, arch.x86.util,
|
arch.x86.util,
|
||||||
io.syslog,
|
arch.x86.panic,
|
||||||
arch.x86.isr.types,
|
arch.x86.isr.types,
|
||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
@@ -33,15 +33,10 @@ procedure register();
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Main();
|
procedure Main();
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CLI;
|
CLI;
|
||||||
correctInterruptRegisters(true);
|
correctInterruptRegisters(true);
|
||||||
BSOD('DF', 'Double Fault.');
|
x86_panic('arch.x86.fault.dfe', 'Double Fault.');
|
||||||
io.syslog.writestringln('Double Fault.');
|
|
||||||
arch.x86.util.halt_and_catch_fire;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
|
|||||||
Loaded 20 of 52 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user