x86_64 do not merge #76

Open
Aaron wants to merge 9 commits from 64bit into feature/sotrage-system-overhaul
pull from: 64bit
169 changed files with 9635 additions and 4208 deletions

No files matched your search

+2
View File
@@ -1,6 +1,8 @@
/lib/*.ppu /lib/*.ppu
/lib/*.a /lib/*.a
/lib/*.o /lib/*.o
/lib/x86_64/
/bin/x86_64/
/release/*.svg /release/*.svg
/release/*.iso /release/*.iso
/bin/*.bin /bin/*.bin
+2 -2
View File
@@ -6,7 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN dpkg --add-architecture i386 RUN dpkg --add-architecture i386
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
curl dos2unix wget git make nasm binutils xorriso grub-pc-bin gcc gcc-multilib \ curl dos2unix wget git make nasm binutils xorriso grub-pc-bin gcc gcc-multilib \
python3 python3-pip python3-pil && \ python3 python3-pip python3-pil fp-compiler && \
apt-get clean my room apt-get clean my room
RUN pip3 install --no-cache-dir --break-system-packages "mkdocs>=1.6,<2" mkdocs-material RUN pip3 install --no-cache-dir --break-system-packages "mkdocs>=1.6,<2" mkdocs-material
@@ -20,6 +20,6 @@ RUN curl -sL https://sourceforge.net/projects/freepascal/files/Linux/$FPC_VERSIO
ADD https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver /usr/bin/semver ADD https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver /usr/bin/semver
RUN chmod +x /usr/bin/semver RUN chmod +x /usr/bin/semver
WORKDIR /code WORKDIR /code
RUN find . -type f -print0 | xargs -0 dos2unix # Sources are mounted at runtime; the CMD below normalizes build scripts.
ENTRYPOINT ["/bin/bash", "-c"] ENTRYPOINT ["/bin/bash", "-c"]
CMD ["find toolchain -name '*.sh' -exec dos2unix {} + 2>/dev/null; find toolchain -name '*.sh' -exec chmod +x {} +; bash toolchain/compile.sh"] CMD ["find toolchain -name '*.sh' -exec dos2unix {} + 2>/dev/null; find toolchain -name '*.sh' -exec chmod +x {} +; bash toolchain/compile.sh"]
+10 -10
View File
@@ -22,12 +22,12 @@ type
THeapPageHeader = memory.heap.THeapPageHeader; THeapPageHeader = memory.heap.THeapPageHeader;
procedure init; procedure init;
function kalloc(size : uint32) : void; function kalloc(size : SizeUInt) : void;
function klalloc(size : uint32) : void; function klalloc(size : SizeUInt) : void;
procedure klfree(address : uint32); procedure klfree(address : PtrUInt);
function kpalloc(address : uint32) : void; function kpalloc(address : PtrUInt) : void;
procedure kfree(area : void); procedure kfree(area : void);
function lmm_total_free : uint32; function lmm_total_free : SizeUInt;
function lmm_page_count : uint32; function lmm_page_count : uint32;
implementation implementation
@@ -37,22 +37,22 @@ begin
memory.heap.init; memory.heap.init;
end; end;
function kalloc(size : uint32) : void; inline; function kalloc(size : SizeUInt) : void; inline;
begin begin
kalloc := memory.heap.kalloc(size); kalloc := memory.heap.kalloc(size);
end; end;
function klalloc(size : uint32) : void; inline; function klalloc(size : SizeUInt) : void; inline;
begin begin
klalloc := memory.heap.klalloc(size); klalloc := memory.heap.klalloc(size);
end; end;
procedure klfree(address : uint32); inline; procedure klfree(address : PtrUInt); inline;
begin begin
memory.heap.klfree(address); memory.heap.klfree(address);
end; end;
function kpalloc(address : uint32) : void; inline; function kpalloc(address : PtrUInt) : void; inline;
begin begin
kpalloc := memory.heap.kpalloc(address); kpalloc := memory.heap.kpalloc(address);
end; end;
@@ -62,7 +62,7 @@ begin
memory.heap.kfree(area); memory.heap.kfree(area);
end; end;
function lmm_total_free : uint32; inline; function lmm_total_free : SizeUInt; inline;
begin begin
lmm_total_free := memory.heap.lmm_total_free; lmm_total_free := memory.heap.lmm_total_free;
end; end;
+2 -2
View File
@@ -205,7 +205,7 @@ Key constants:
- `DATA_OFFSET = $10000` — data area starts at 64 KB into each page - `DATA_OFFSET = $10000` — data area starts at 64 KB into each page
- `LARGE_ALLOC_MAGIC = $FFFFFFFE` — sentinel for klalloc'd multi-page allocations - `LARGE_ALLOC_MAGIC = $FFFFFFFE` — sentinel for klalloc'd multi-page allocations
Interrupt safety: `pushfd; cli; pop saved_flags` (stack-balanced) + `restore_if(saved_flags)` Interrupt safety: `pushfd; cli; pop saved_flags` (stack-balanced) + `arch.platform.cpu.unlock(saved_flags)`
inline procedure that only restores IF via `sti`, avoiding dangerous EFLAGS restoration inline procedure that only restores IF via `sti`, avoiding dangerous EFLAGS restoration
(IOPL, NT, VM, AC bits that caused Bad-TSS on IRET). (IOPL, NT, VM, AC bits that caused Bad-TSS on IRET).
@@ -256,7 +256,7 @@ list, fixes Search_Page, calls `free_page_at_address`). Skips Root_Page.
| Bug | Root Cause | Fix | | Bug | Root Cause | Fix |
|-----|-----------|-----| |-----|-----------|-----|
| Bad TSS exception during network processing | `pushfd`/`popfd` across separate asm blocks: FPC doesn't track ESP changes in asm, causing EFLAGS corruption (NT=1, IOPL wrong) → Bad TSS on IRET | Stack-balanced `pushfd; cli; pop local_var` + `restore_if()` that only does `sti` if IF was set | | Bad TSS exception during network processing | `pushfd`/`popfd` across separate asm blocks: FPC doesn't track ESP changes in asm, causing EFLAGS corruption (NT=1, IOPL wrong) → Bad TSS on IRET | Stack-balanced `pushfd; cli; pop local_var` + `arch.platform.cpu.unlock()` that only does `sti` if IF was set |
| GPF from SSE MOVAPS in doublebuffer flush | `SIZE_PREFIX=4`→8 gave 8-byte alignment; `MOVAPS` needs 16-byte. `klalloc` returned `page+8` (not 16-aligned) | `SIZE_PREFIX=16` (4B size + 12B pad), klalloc header expanded to 16 bytes | | GPF from SSE MOVAPS in doublebuffer flush | `SIZE_PREFIX=4`→8 gave 8-byte alignment; `MOVAPS` needs 16-byte. `klalloc` returned `page+8` (not 16-aligned) | `SIZE_PREFIX=16` (4B size + 12B pad), klalloc header expanded to 16 bytes |
| Pages never freed (historic) | `free_page` extracted wrong block index from PDE Address field | Fixed extraction to `Address SHR 10` — page freeing works for the first time | | Pages never freed (historic) | `free_page` extracted wrong block index from PDE Address field | Fixed extraction to `Address SHR 10` — page freeing works for the first time |
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -19,7 +19,7 @@ Every allocation is preceded by a 16-byte prefix: 4 bytes for the unit count, 12
Allocations larger than a single heap page's capacity are handled by `klalloc`, which maps contiguous virtual pages and stores a magic sentinel (`$FFFFFFFE`) in the header so `kfree` can identify them and call `klfree` instead of the normal bitmap path. Allocations larger than a single heap page's capacity are handled by `klalloc`, which maps contiguous virtual pages and stores a magic sentinel (`$FFFFFFFE`) in the header so `kfree` can identify them and call `klfree` instead of the normal bitmap path.
`kalloc` and `kfree` disable interrupts for the duration of their critical sections using a stack-balanced `pushfd`/`cli`/`pop` sequence and restore the interrupt flag via `restore_if` on all exit paths. `kalloc` and `kfree` disable interrupts for the duration of their critical sections using a stack-balanced `pushfd`/`cli`/`pop` sequence and restore the interrupt flag via `arch.platform.cpu.unlock` on all exit paths.
## Dependencies ## Dependencies
@@ -132,7 +132,7 @@ Returns the number of heap pages currently in the linked list.
## Notes ## Notes
The `restore_if` helper checks bit 9 (IF) of the saved EFLAGS word and issues `STI` only if interrupts were enabled on entry. It uses `STI` rather than `POPFD` to avoid restoring potentially dangerous EFLAGS bits (IOPL, NT, VM, AC) that could trigger a General Protection Fault or Bad-TSS on the next `IRET`. The `arch.platform.cpu.unlock` helper checks bit 9 (IF) of the saved EFLAGS word and issues `STI` only if interrupts were enabled on entry. It uses `STI` rather than `POPFD` to avoid restoring potentially dangerous EFLAGS bits (IOPL, NT, VM, AC) that could trigger a General Protection Fault or Bad-TSS on the next `IRET`.
When `DEBUG_LMM` is defined, `kalloc` allocates one additional unit and writes `GUARD_MAGIC` at the end of the allocation. `kfree` verifies this sentinel before freeing; a mismatch triggers a GPF with a syslog error, catching buffer overruns at free time. When `DEBUG_LMM` is defined, `kalloc` allocates one additional unit and writes `GUARD_MAGIC` at the end of the allocation. `kfree` verifies this sentinel before freeing; a mismatch triggers a GPF with a syslog error, catching buffer overruns at free time.
+3
View File
@@ -1,5 +1,8 @@
services: services:
builder: builder:
build: . build: .
environment:
ASURO_ARCH: ${ASURO_ARCH:-x86}
ASURO_BOOT_TEST: ${ASURO_BOOT_TEST:-none}
volumes: volumes:
- .:/code - .:/code
+1
View File
@@ -295,6 +295,7 @@ nav:
- Planning: - Planning:
- Architecture: planning/architecture.md - Architecture: planning/architecture.md
- x86-64 Migration: planning/x86_64.md
- USB: planning/USB.md - USB: planning/USB.md
- XHCI: planning/XHCI.md - XHCI: planning/XHCI.md
- FlatFS: planning/flatfs.md - FlatFS: planning/flatfs.md
+1 -1
View File
@@ -22,7 +22,7 @@ unit app.base64;
interface interface
uses uses
io.stdio, core.util, arch.x86.util, core.strings, debug.tracer, core.enc.base64, memory.heap; io.stdio, core.util, arch.platform.cpu, core.strings, debug.tracer, core.enc.base64, memory.heap;
procedure init(); procedure init();
+1 -1
View File
@@ -22,7 +22,7 @@ unit app.dhclient;
interface interface
uses uses
io.stdio, core.util, arch.x86.util, core.strings, debug.tracer, driver.net.proto.dhcp; io.stdio, core.util, arch.platform.cpu, core.strings, debug.tracer, driver.net.proto.dhcp;
procedure init(); procedure init();
+2 -2
View File
@@ -25,7 +25,7 @@ uses
core.strings, core.strings,
io.stdio, io.stdio,
debug.tracer, debug.tracer,
core.util, arch.x86.util, core.util, arch.platform.cpu,
driver.storage.vol.mgr; driver.storage.vol.mgr;
var var
@@ -254,7 +254,7 @@ begin
{ Allocate a zero buffer - 64 sectors at a time } { Allocate a zero buffer - 64 sectors at a time }
bufSects := 64; bufSects := 64;
buf := puint32(kalloc(bufSects * device^.sectorSize)); buf := puint32(kalloc(bufSects * device^.sectorSize));
memset(uint32(buf), 0, bufSects * device^.sectorSize); memset(PtrUInt(buf), 0, bufSects * device^.sectorSize);
print('Wiping device '); print('Wiping device ');
printint(idx); printint(idx);
+12 -11
View File
@@ -34,7 +34,7 @@ uses
driver.video, driver.video,
driver.storage.vol.mgr, driver.storage.vol.mgr,
driver.video.windows, driver.video.windows,
core.util, arch.x86.util; core.util, arch.platform.cpu;
const const
WIN_W = 740; WIN_W = 740;
@@ -129,9 +129,9 @@ begin
item := PUIText(kalloc(sizeof(TUIText)+n+m+1)); item := PUIText(kalloc(sizeof(TUIText)+n+m+1));
if item = nil then exit; if item = nil then exit;
item^.Next := TextTemps; TextTemps := item; item^.Next := TextTemps; TextTemps := item;
dest := pchar(uint32(item)+sizeof(TUIText)); dest := pchar(PtrUInt(item)+sizeof(TUIText));
if n > 0 then memcpy(uint32(a), uint32(dest), n); if n > 0 then memcpy(PtrUInt(a), PtrUInt(dest), n);
if m > 0 then memcpy(uint32(b), uint32(dest)+n, m); if m > 0 then memcpy(PtrUInt(b), PtrUInt(dest)+n, m);
dest[n+m] := #0; uiConcat := dest; dest[n+m] := #0; uiConcat := dest;
end; end;
@@ -606,7 +606,7 @@ begin
end; end;
end; end;
memset(uint32(@part), 0, sizeof(TPartition_table)); memset(PtrUInt(@part), 0, sizeof(TPartition_table));
driver.storage.vol.mbr.setup_partition(@part, lba, sectors); driver.storage.vol.mbr.setup_partition(@part, lba, sectors);
cbCtx := begin_partition_ui(1); cbCtx := begin_partition_ui(1);
if cbCtx = nil then exit; if cbCtx = nil then exit;
@@ -702,18 +702,19 @@ end;
procedure operation_done(error : TError; userdata : pointer); procedure operation_done(error : TError; userdata : pointer);
var var
ctx : PFmtUICallbackCtx; ctx : PFmtUICallbackCtx;
flags : uint32; flags : PtrUInt;
begin begin
ctx := PFmtUICallbackCtx(userdata); ctx := PFmtUICallbackCtx(userdata);
if ctx <> nil then begin if ctx <> nil then begin
asm pushfd; cli; pop flags end; flags := arch.platform.cpu.lock;
if ctx^.SessionID = ui_session_id then begin if ctx^.SessionID = ui_session_id then begin
fmt_done_error := error; fmt_done_error := error;
fmt_done_vol_idx := ctx^.VolumeIdx; fmt_done_vol_idx := ctx^.VolumeIdx;
done_kind := ctx^.Kind; done_device := ctx^.DeviceIdx; done_kind := ctx^.Kind;
done_device := ctx^.DeviceIdx;
puint32(@fmt_done_flag)^ := 1; puint32(@fmt_done_flag)^ := 1;
end; end;
if (flags and $200) <> 0 then asm sti end; arch.platform.cpu.unlock(flags);
kfree(void(ctx)); kfree(void(ctx));
end; end;
end; end;
@@ -824,7 +825,7 @@ begin
fs := driver.storage.fs.mgr.get_filesystem(selIdx); fs := driver.storage.fs.mgr.get_filesystem(selIdx);
if fs = nil then begin closeMsgBox; exit; end; if fs = nil then begin closeMsgBox; exit; end;
memset(uint32(@params), 0, sizeof(TFSFormatParams)); memset(PtrUInt(@params), 0, sizeof(TFSFormatParams));
params.Version := FS_FORMAT_PARAMS_VERSION_1; params.Version := FS_FORMAT_PARAMS_VERSION_1;
paramPtr := nil; paramPtr := nil;
@@ -874,7 +875,7 @@ begin
if fs^.validateLabelCallback(text,normalized) <> eNone then begin if fs^.validateLabelCallback(text,normalized) <> eNone then begin
set_fmt_param_error('Use up to 11 ASCII characters without punctuation such as / or :'); exit; set_fmt_param_error('Use up to 11 ASCII characters without punctuation such as / or :'); exit;
end; end;
memcpy(uint32(@normalized[0]),uint32(@params.LabelText[0]),12); memcpy(PtrUInt(@normalized[0]),PtrUInt(@params.LabelText[0]),12);
params.Flags := params.Flags or FS_FORMAT_PARAM_LABEL; paramPtr := @params; params.Flags := params.Flags or FS_FORMAT_PARAM_LABEL; paramPtr := @params;
end; end;
+9 -9
View File
@@ -32,7 +32,7 @@ uses
core.gfx.fileicons, core.gfx.fileicons,
debug.tracer, debug.tracer,
core.util, core.util,
arch.x86.util; arch.platform.cpu;
const const
WIN_W = 800; WIN_W = 800;
@@ -785,9 +785,9 @@ begin
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))); file_sizes := PSizeBuf(kalloc(sizeof(TSizeBuf)));
memset(uint32(dir_names), 0, sizeof(TNameBuf)); memset(PtrUInt(dir_names), 0, sizeof(TNameBuf));
memset(uint32(file_names), 0, sizeof(TNameBuf)); memset(PtrUInt(file_names), 0, sizeof(TNameBuf));
memset(uint32(file_sizes), 0, sizeof(TSizeBuf)); memset(PtrUInt(file_sizes), 0, sizeof(TSizeBuf));
{ Load directory from VFS — this may do disk I/O } { Load directory from VFS — this may do disk I/O }
Map := driver.storage.vfs.GetDirectoryListingFrom(state^.cur_path, '/'); Map := driver.storage.vfs.GetDirectoryListingFrom(state^.cur_path, '/');
@@ -1330,7 +1330,7 @@ begin
parent := stringCopy('/') parent := stringCopy('/')
else begin else begin
parent := pchar(kalloc(uint32(i) + 1)); parent := pchar(kalloc(uint32(i) + 1));
memcpy(uint32(cur), uint32(parent), uint32(i)); memcpy(PtrUInt(cur), PtrUInt(parent), uint32(i));
parent[i] := char(0); parent[i] := char(0);
end; end;
navigate_to(state, parent); navigate_to(state, parent);
@@ -1440,7 +1440,7 @@ begin
{ Segment name label } { Segment name label }
segBuf := pchar(kalloc(segEnd - segStart + 1)); segBuf := pchar(kalloc(segEnd - segStart + 1));
memcpy(uint32(@path[segStart]), uint32(segBuf), segEnd - segStart); memcpy(PtrUInt(@path[segStart]), uint32(segBuf), segEnd - segStart);
segBuf[segEnd - segStart] := char(0); segBuf[segEnd - segStart] := char(0);
lbl := lv_label_create(btn); lbl := lv_label_create(btn);
lv_label_set_text(lbl, segBuf); lv_label_set_text(lbl, segBuf);
@@ -1979,7 +1979,7 @@ begin
if state^.tabs[idx] <> nil then if state^.tabs[idx] <> nil then
free_tab_snapshot(state^.tabs[idx]); free_tab_snapshot(state^.tabs[idx]);
snap := PTabSnapshot(kalloc(sizeof(TTabSnapshot))); snap := PTabSnapshot(kalloc(sizeof(TTabSnapshot)));
memset(uint32(snap), 0, sizeof(TTabSnapshot)); memset(PtrUInt(snap), 0, sizeof(TTabSnapshot));
if state^.cur_path <> nil then if state^.cur_path <> nil then
snap^.cur_path := stringCopy(state^.cur_path) snap^.cur_path := stringCopy(state^.cur_path)
else else
@@ -2090,7 +2090,7 @@ begin
save_tab(state, state^.active_tab); save_tab(state, state^.active_tab);
{ Create snapshot for new tab } { Create snapshot for new tab }
snap := PTabSnapshot(kalloc(sizeof(TTabSnapshot))); snap := PTabSnapshot(kalloc(sizeof(TTabSnapshot)));
memset(uint32(snap), 0, sizeof(TTabSnapshot)); memset(PtrUInt(snap), 0, sizeof(TTabSnapshot));
snap^.cur_path := stringCopy(path); snap^.cur_path := stringCopy(path);
snap^.hist_len := 0; snap^.hist_len := 0;
snap^.hist_pos := 0; snap^.hist_pos := 0;
@@ -3053,7 +3053,7 @@ begin
{ Allocate and zero-initialise state } { Allocate and zero-initialise state }
state := PFileBrowserState(kalloc(sizeof(TFileBrowserState))); state := PFileBrowserState(kalloc(sizeof(TFileBrowserState)));
memset(uint32(state), 0, sizeof(TFileBrowserState)); memset(PtrUInt(state), 0, sizeof(TFileBrowserState));
state^.win_id := g_win_id; state^.win_id := g_win_id;
state^.cur_path := stringCopy('/'); state^.cur_path := stringCopy('/');
state^.view_mode := vmDetail; state^.view_mode := vmDetail;
+5 -5
View File
@@ -64,7 +64,7 @@ uses
core.strings.helpers, core.strings.helpers,
io.syslog, io.syslog,
debug.tracer, debug.tracer,
core.util, arch.x86.util, core.util, arch.platform.cpu,
driver.storage.vfs; driver.storage.vfs;
const const
@@ -325,9 +325,9 @@ begin
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))); file_sizes := PSizeBuf(kalloc(sizeof(TSizeBuf)));
memset(uint32(dir_names), 0, sizeof(TNameBuf)); memset(PtrUInt(dir_names), 0, sizeof(TNameBuf));
memset(uint32(file_names), 0, sizeof(TNameBuf)); memset(PtrUInt(file_names), 0, sizeof(TNameBuf));
memset(uint32(file_sizes), 0, sizeof(TSizeBuf)); memset(PtrUInt(file_sizes), 0, sizeof(TSizeBuf));
{ Sync path bar } { Sync path bar }
if p^.path_bar <> nil then if p^.path_bar <> nil then
@@ -898,7 +898,7 @@ begin
io.syslog.logln('FPCIK', 'make_picker: enter'); io.syslog.logln('FPCIK', 'make_picker: enter');
p := PPicker(kalloc(sizeof(TPicker))); p := PPicker(kalloc(sizeof(TPicker)));
memset(uint32(p), 0, sizeof(TPicker)); memset(PtrUInt(p), 0, sizeof(TPicker));
p^.cb := cb; p^.cb := cb;
p^.userdata := userdata; p^.userdata := userdata;
p^.is_save := is_save; p^.is_save := is_save;
+6 -1
View File
@@ -22,7 +22,7 @@ unit app.md5sum;
interface interface
uses uses
io.stdio, core.util, arch.x86.util, core.strings, debug.tracer, core.enc.md5; memory.heap, io.stdio, core.util, arch.platform.cpu, core.strings, debug.tracer, core.enc.md5;
procedure init(); procedure init();
@@ -36,6 +36,10 @@ var
i : uint32; i : uint32;
begin begin
if paramCount(Params) = 0 then begin
io.stdio.bufWriteStrLn(stderr_buf, 'Usage: MD5SUM <word>');
exit;
end;
md5word:= getParam(0, Params); md5word:= getParam(0, Params);
wordlen:= stringSize(md5word); wordlen:= stringSize(md5word);
MD5_Hash := MD5Buffer(puint8(md5word), wordlen); MD5_Hash := MD5Buffer(puint8(md5word), wordlen);
@@ -43,6 +47,7 @@ begin
io.stdio.bufWriteHexPair(stdout_buf, MD5_Hash^[i]); io.stdio.bufWriteHexPair(stdout_buf, MD5_Hash^[i]);
end; end;
io.stdio.bufWriteStrLn(stdout_buf, ' '); io.stdio.bufWriteStrLn(stdout_buf, ' ');
memory.heap.kfree(void(MD5_Hash));
end; end;
procedure init(); procedure init();
+20 -40
View File
@@ -22,7 +22,7 @@ unit app.meminfo;
interface interface
uses uses
io.stdio, arch.x86.multiboot, arch.x86.memory.physical, memory.heap, debug.tracer; io.stdio, arch.platform.memory, memory.heap, debug.tracer;
procedure init(); procedure init();
@@ -30,50 +30,30 @@ implementation
procedure run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf); procedure run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
var var
pmm_total, pmm_free, pmm_used : uint32; total, available: uint64;
lmm_pages, lmm_free : uint32; heapPages: uint32;
begin begin
{ Multiboot memory info } total := arch.platform.memory.totalPhysicalBytes;
io.stdio.bufWriteStrLn(stdout_buf, '--- Multiboot ---'); available := arch.platform.memory.freePhysicalBytes;
io.stdio.bufWriteStr(stdout_buf, 'Lower Memory : '); io.stdio.bufWriteStr(stdout_buf, 'Usable Physical: ');
io.stdio.bufWriteInt(stdout_buf, multibootinfo^.mem_lower); io.stdio.bufWriteInt(stdout_buf, total div 1024);
io.stdio.bufWriteStrLn(stdout_buf, ' KB'); io.stdio.bufWriteStrLn(stdout_buf, ' KiB');
io.stdio.bufWriteStr(stdout_buf, 'Upper Memory : ');
io.stdio.bufWriteInt(stdout_buf, multibootinfo^.mem_upper);
io.stdio.bufWriteStrLn(stdout_buf, ' KB');
io.stdio.bufWriteStr(stdout_buf, 'Total Memory : ');
io.stdio.bufWriteInt(stdout_buf, ((multibootinfo^.mem_upper + 1000) div 1024) + 1);
io.stdio.bufWriteStrLn(stdout_buf, ' MB');
{ PMM stats }
io.stdio.bufWriteStrLn(stdout_buf, '--- PMM (4 MB blocks) ---');
pmm_total := arch.x86.memory.physical.pmm_total_blocks;
pmm_free := arch.x86.memory.physical.pmm_free_blocks;
pmm_used := pmm_total - pmm_free;
io.stdio.bufWriteStr(stdout_buf, 'Total Blocks : ');
io.stdio.bufWriteIntLn(stdout_buf, pmm_total);
io.stdio.bufWriteStr(stdout_buf, 'Free Blocks : ');
io.stdio.bufWriteIntLn(stdout_buf, pmm_free);
io.stdio.bufWriteStr(stdout_buf, 'Used Blocks : ');
io.stdio.bufWriteIntLn(stdout_buf, pmm_used);
io.stdio.bufWriteStr(stdout_buf, 'Free Physical : '); io.stdio.bufWriteStr(stdout_buf, 'Free Physical : ');
io.stdio.bufWriteInt(stdout_buf, pmm_free * 4); io.stdio.bufWriteInt(stdout_buf, available div 1024);
io.stdio.bufWriteStrLn(stdout_buf, ' MB'); io.stdio.bufWriteStrLn(stdout_buf, ' KiB');
io.stdio.bufWriteStr(stdout_buf, 'Used Physical : ');
{ LMM heap stats } io.stdio.bufWriteInt(stdout_buf, (total - available) div 1024);
io.stdio.bufWriteStrLn(stdout_buf, '--- LMM (Heap) ---'); io.stdio.bufWriteStrLn(stdout_buf, ' KiB');
lmm_pages := memory.heap.lmm_page_count; heapPages := memory.heap.lmm_page_count;
lmm_free := memory.heap.lmm_total_free; io.stdio.bufWriteStr(stdout_buf, 'Heap Regions : ');
io.stdio.bufWriteStr(stdout_buf, 'Heap Pages : '); io.stdio.bufWriteIntLn(stdout_buf, heapPages);
io.stdio.bufWriteIntLn(stdout_buf, lmm_pages);
io.stdio.bufWriteStr(stdout_buf, 'Heap Size : '); io.stdio.bufWriteStr(stdout_buf, 'Heap Size : ');
io.stdio.bufWriteInt(stdout_buf, lmm_pages * 4); io.stdio.bufWriteInt(stdout_buf, uint64(heapPages) * PAGE_SIZE_LMM div 1024);
io.stdio.bufWriteStrLn(stdout_buf, ' MB'); io.stdio.bufWriteStrLn(stdout_buf, ' KiB');
io.stdio.bufWriteStr(stdout_buf, 'Heap Free : '); io.stdio.bufWriteStr(stdout_buf, 'Heap Free : ');
io.stdio.bufWriteInt(stdout_buf, lmm_free div 1024); io.stdio.bufWriteInt(stdout_buf, memory.heap.lmm_total_free div 1024);
io.stdio.bufWriteStrLn(stdout_buf, ' KB'); io.stdio.bufWriteStrLn(stdout_buf, ' KiB');
end; end;
procedure init(); procedure init();
begin begin
debug.tracer.push_trace('meminfo.init'); debug.tracer.push_trace('meminfo.init');
+1 -17
View File
@@ -23,10 +23,9 @@ unit app.mgr;
interface interface
uses uses
boot.mgr,
debug.tracer, io.stdio, proc.mgr, debug.tracer, io.stdio, proc.mgr,
//progs //progs
app.base64, app.md5sum, app.dhclient, app.vbeinfo, app.testcmd, app.ping, app.meminfo, app.setres, app.iotest, app.base64, app.md5sum, app.dhclient, app.testcmd, app.ping, app.meminfo, app.setres,
//drivers //drivers
driver.storage.ctl.ram, driver.mgr, driver.storage.ctl.ram, driver.mgr,
//network //network
@@ -35,8 +34,6 @@ uses
driver.storage.filedispatch, driver.storage.filedispatch,
//wasm //wasm
app.wasm.runner, app.wasm.runner,
app.divzero,
app.bsod,
app.vterminal; app.vterminal;
{ Initialize all baked-in programs } { Initialize all baked-in programs }
@@ -47,7 +44,6 @@ implementation
uses uses
core.version, core.version,
//command provider units //command provider units
arch.x86.cpu,
app.diskcmd, driver.bus.usb.core, app.diskutil, app.notepad, app.partcmd, app.volcmd, app.diskcmd, driver.bus.usb.core, app.diskutil, app.notepad, app.partcmd, app.volcmd,
app.filebrowser; app.filebrowser;
@@ -56,16 +52,10 @@ begin
debug.tracer.push_trace('app.mgr.init'); debug.tracer.push_trace('app.mgr.init');
{ Register commands from provider units } { Register commands from provider units }
io.stdio.registerCommand('CPU', @arch.x86.cpu.Terminal_Command_CPU, 'CPU Info.');
io.stdio.registerCommand('DEV', @driver.mgr.terminal_command_dev, 'Driver Management Interface.'); io.stdio.registerCommand('DEV', @driver.mgr.terminal_command_dev, 'Driver Management Interface.');
io.stdio.registerCommand('PS', @proc.mgr.terminal_command_ps, 'List running processes.'); io.stdio.registerCommand('PS', @proc.mgr.terminal_command_ps, 'List running processes.');
io.stdio.registerCommand('KILL', @proc.mgr.terminal_command_kill, 'Force-kill a process by PID.'); io.stdio.registerCommand('KILL', @proc.mgr.terminal_command_kill, 'Force-kill a process by PID.');
io.stdio.registerCommand('TERMINATE', @proc.mgr.terminal_command_terminate, 'Gracefully terminate a process by PID.'); io.stdio.registerCommand('TERMINATE', @proc.mgr.terminal_command_terminate, 'Gracefully terminate a process by PID.');
io.stdio.registerCommand('ARP', @driver.net.proto.arp.terminal_command_arp, 'Get ARP Table.');
io.stdio.registerCommand('IFCONFIG', @driver.net.proto.ipv4.terminal_command_ifconfig, 'Configure Network Settings.');
io.stdio.registerCommand('TCPCONNECT', @driver.net.proto.tcp.terminal_command_tcpconnect, 'Connect to a TCP host and send Hello World.');
io.stdio.registerCommand('TCPLISTEN', @driver.net.proto.tcp.terminal_command_tcplisten, 'Listen on a TCP port and log received data.');
io.stdio.registerCommand('TCPHTTP', @driver.net.proto.tcp.terminal_command_tcphttp, 'Send HTTP GET to a host IP (port 80 default).');
io.stdio.registerCommand('USB', @driver.bus.usb.core.terminal_command_usb, 'driver.bus.usb subsystem information.'); io.stdio.registerCommand('USB', @driver.bus.usb.core.terminal_command_usb, 'driver.bus.usb subsystem information.');
{ File dispatch — must init before apps that register handlers } { File dispatch — must init before apps that register handlers }
@@ -81,21 +71,15 @@ begin
app.md5sum.init(); app.md5sum.init();
app.base64.init(); app.base64.init();
app.dhclient.init(); app.dhclient.init();
app.vbeinfo.init();
app.testcmd.init(); app.testcmd.init();
app.ping.init(); app.ping.init();
app.meminfo.init(); app.meminfo.init();
{ WASM & remaining apps } { WASM & remaining apps }
app.wasm.runner.init(); app.wasm.runner.init();
app.setres.init(); app.setres.init();
app.divzero.init();
app.bsod.init();
app.vterminal.init; app.vterminal.init;
app.filebrowser.init(); app.filebrowser.init();
app.iotest.init();
end; end;
Initialization
boot.mgr.registerBoot('app.mgr', @init, 'Program Manager', BOOT_MGR_BARRIER_LATE);
end. end.
+14 -29
View File
@@ -11,8 +11,7 @@
- Status bar showing Line, Col, filename, and dirty flag - Status bar showing Line, Col, filename, and dirty flag
Key design notes: Key design notes:
- lv_event_t.stop_processing (bit 1 at struct byte offset 24) is set - lv_event_stop_processing prevents LVGL's default textarea handler from also
directly to prevent LVGL's default textarea key handler from also
acting on keys we have fully handled ourselves. acting on keys we have fully handled ourselves.
- Shift state is read from driver.hid.keyboard.is_shift / driver.hid.keyboard.is_ctrl. - Shift state is read from driver.hid.keyboard.is_shift / driver.hid.keyboard.is_ctrl.
- selection anchor (sel_anchor) is stored as a sint32 byte offset; - selection anchor (sel_anchor) is stored as a sint32 byte offset;
@@ -43,7 +42,7 @@ uses
io.syslog, io.syslog,
io.stdio, io.stdio,
debug.tracer, debug.tracer,
core.util, arch.x86.util, core.util, arch.platform.cpu,
driver.storage.vfs, driver.storage.vfs,
driver.video, driver.video,
driver.video.windows; driver.video.windows;
@@ -62,19 +61,6 @@ const
FILE_BUF_SIZE = 65536; { 64 KB read / write buffer } FILE_BUF_SIZE = 65536; { 64 KB read / write buffer }
{
Byte offset and bitmask for lv_event_t.stop_processing.
struct lv_event_t (32-bit ABI):
offset 0: current_target (ptr)
offset 4: original_target (ptr)
offset 8: code (uint32 — lv_event_code_t)
offset 12: user_data (ptr)
offset 16: param (ptr)
offset 20: prev (ptr)
offset 24: flags byte [bit0=deleted, bit1=stop_processing, bit2=stop_bubbling]
}
LV_EVT_STOP_OFF = 24;
LV_EVT_STOP_BIT = 2; { bit 1 = stop_processing }
type type
PNotepadState = ^TNotepadState; PNotepadState = ^TNotepadState;
@@ -130,8 +116,7 @@ procedure removeInstance(state: PNotepadState); forward;
============================================================ } ============================================================ }
procedure stopEvent(e: Plv_event); procedure stopEvent(e: Plv_event);
begin begin
puint8(uint32(e) + LV_EVT_STOP_OFF)^ := lv_event_stop_processing(e);
puint8(uint32(e) + LV_EVT_STOP_OFF)^ or LV_EVT_STOP_BIT;
end; end;
{ ============================================================ { ============================================================
@@ -157,18 +142,18 @@ begin
if to_idx < from_idx then to_idx := from_idx; if to_idx < from_idx then to_idx := from_idx;
result_len := from_idx + ins_len + (src_len - to_idx); result_len := from_idx + ins_len + (src_len - to_idx);
buf := pchar(kalloc(result_len + 1)); buf := pchar(kalloc(result_len + 1));
memset(uint32(buf), 0, result_len + 1); memset(PtrUInt(buf), 0, result_len + 1);
pos := 0; pos := 0;
if from_idx > 0 then begin if from_idx > 0 then begin
memcpy(uint32(src), uint32(buf), from_idx); memcpy(PtrUInt(src), PtrUInt(buf), from_idx);
pos := from_idx; pos := from_idx;
end; end;
if ins_len > 0 then begin if ins_len > 0 then begin
memcpy(uint32(insert), uint32(@buf[pos]), ins_len); memcpy(PtrUInt(insert), PtrUInt(@buf[pos]), ins_len);
pos := pos + ins_len; pos := pos + ins_len;
end; end;
if to_idx < src_len then if to_idx < src_len then
memcpy(uint32(@src[to_idx]), uint32(@buf[pos]), src_len - to_idx); memcpy(PtrUInt(@src[to_idx]), PtrUInt(@buf[pos]), src_len - to_idx);
buildSplicedString := buf; buildSplicedString := buf;
end; end;
@@ -198,12 +183,12 @@ begin
{ Generous output buffer: original + 4 bytes per line (worst case ~512 lines) } { Generous output buffer: original + 4 bytes per line (worst case ~512 lines) }
out_buf := pchar(kalloc(src_len + 2049)); out_buf := pchar(kalloc(src_len + 2049));
memset(uint32(out_buf), 0, src_len + 2049); memset(PtrUInt(out_buf), 0, src_len + 2049);
out_pos := 0; out_pos := 0;
{ Copy everything before the affected region verbatim } { Copy everything before the affected region verbatim }
if first_ls > 0 then begin if first_ls > 0 then begin
memcpy(uint32(src), uint32(out_buf), first_ls); memcpy(PtrUInt(src), PtrUInt(out_buf), first_ls);
out_pos := first_ls; out_pos := first_ls;
end; end;
@@ -215,7 +200,7 @@ begin
if i >= sel_end then begin if i >= sel_end then begin
{ Past the affected region: copy the remainder verbatim } { Past the affected region: copy the remainder verbatim }
if i < src_len then begin if i < src_len then begin
memcpy(uint32(@src[i]), uint32(@out_buf[out_pos]), src_len - i); memcpy(PtrUInt(@src[i]), PtrUInt(@out_buf[out_pos]), src_len - i);
out_pos := out_pos + (src_len - i); out_pos := out_pos + (src_len - i);
end; end;
break; break;
@@ -426,8 +411,8 @@ begin
len := stringSize(txt); len := stringSize(txt);
if len > FILE_BUF_SIZE - 1 then len := FILE_BUF_SIZE - 1; if len > FILE_BUF_SIZE - 1 then len := FILE_BUF_SIZE - 1;
buf := pchar(kalloc(FILE_BUF_SIZE)); buf := pchar(kalloc(FILE_BUF_SIZE));
memset(uint32(buf), 0, FILE_BUF_SIZE); memset(PtrUInt(buf), 0, FILE_BUF_SIZE);
memcpy(uint32(txt), uint32(buf), len); memcpy(PtrUInt(txt), PtrUInt(buf), len);
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omReadWrite, @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, omCreate, @fError); fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omCreate, @fError);
@@ -477,7 +462,7 @@ begin
exit; exit;
end; end;
buf := pchar(kalloc(FILE_BUF_SIZE)); buf := pchar(kalloc(FILE_BUF_SIZE));
memset(uint32(buf), 0, FILE_BUF_SIZE); memset(PtrUInt(buf), 0, FILE_BUF_SIZE);
driver.storage.vfs.ReadFile(fHandle, 0, puint8(buf), FILE_BUF_SIZE - 1); driver.storage.vfs.ReadFile(fHandle, 0, puint8(buf), FILE_BUF_SIZE - 1);
driver.storage.vfs.CloseFile(fHandle); driver.storage.vfs.CloseFile(fHandle);
if state^.currentPath <> nil then kfree(void(state^.currentPath)); if state^.currentPath <> nil then kfree(void(state^.currentPath));
@@ -943,7 +928,7 @@ begin
{ Allocate and zero-initialise state } { Allocate and zero-initialise state }
state := PNotepadState(kalloc(sizeof(TNotepadState))); state := PNotepadState(kalloc(sizeof(TNotepadState)));
memset(uint32(state), 0, sizeof(TNotepadState)); memset(PtrUInt(state), 0, sizeof(TNotepadState));
state^.win_id := wid; state^.win_id := wid;
state^.sel_anchor := -1; state^.sel_anchor := -1;
addInstance(state); addInstance(state);
+30 -12
View File
@@ -20,8 +20,8 @@ procedure init();
implementation implementation
uses uses
arch.x86.bda, driver.net.types, driver.net.proto.icmp, driver.net.util, core.strings, proc.types, driver.net.types, driver.net.proto.icmp, driver.net.util, core.strings,
proc.mgr, core.util, arch.x86.util, memory.heap; proc.mgr, core.util, arch.platform.cpu, memory.heap;
const const
PING_TIMEOUT_MS = 5000; { 5-second timeout per app.ping } PING_TIMEOUT_MS = 5000; { 5-second timeout per app.ping }
@@ -31,22 +31,34 @@ type
PPingState = ^TPingState; PPingState = ^TPingState;
TPingState = record TPingState = record
Result : TPingResult; Result : TPingResult;
ReplyTimeMS : uint64; ReplyTimeMS : uint32;
ErrorReason : TARPErrorCode; ErrorReason : TARPErrorCode;
SendTime : uint64; SendTime : uint32;
Address : puint8;
end; end;
procedure cleanup(handle: void);
var
st: PPingState;
begin
st := PPingState(handle);
if st = nil then exit;
driver.net.proto.icmp.cancelRequests(handle);
kfree(void(st^.Address));
kfree(handle);
end;
{ ---- ICMP callbacks (called from network recv context) ---- } { ---- ICMP callbacks (called from network recv context) ---- }
procedure on_reply(hdr : PICMPHeader; userData : void); procedure on_reply(hdr : PICMPHeader; userData : void);
var var
st : PPingState; st : PPingState;
t2 : uint64; t2 : uint32;
begin begin
st := PPingState(userData); st := PPingState(userData);
if st = nil then exit; if st = nil then exit;
t2 := Counters.c64; t2 := networkTicks;
st^.ReplyTimeMS := t2 - st^.SendTime; st^.ReplyTimeMS := (uint64(uint32(t2 - st^.SendTime)) * 1000) div 1024;
st^.Result := prGotReply; st^.Result := prGotReply;
end; end;
@@ -87,24 +99,31 @@ begin
{ Allocate per-invocation state so concurrent pings are safe } { Allocate per-invocation state so concurrent pings are safe }
st := PPingState(kalloc(sizeof(TPingState))); st := PPingState(kalloc(sizeof(TPingState)));
if st = nil then begin
kfree(void(ip));
exit;
end;
st^.Address := ip;
proc.mgr.bindResource(proc.mgr.CurrentProcess, rkCustom, void(st), @cleanup);
timeoutTicks := (PING_TIMEOUT_MS * 1024) div 1000; timeoutTicks := (PING_TIMEOUT_MS * 1024) div 1000;
for i := 0 to 9 do begin for i := 0 to 9 do begin
{ Send ICMP echo request } { Send ICMP echo request }
st^.Result := prWaiting; st^.Result := prWaiting;
st^.SendTime := Counters.c64; st^.SendTime := networkTicks;
driver.net.proto.icmp.sendICMPRequest(ip, i, 128, @on_reply, @on_error, void(st)); driver.net.proto.icmp.sendICMPRequest(ip, i, 128, @on_reply, @on_error, void(st));
{ Spin-yield until callback fires or timeout } { Spin-yield until callback fires or timeout }
tStart := Counters.c32; tStart := networkTicks;
while st^.Result = prWaiting do begin while st^.Result = prWaiting do begin
proc.mgr.proc_yield; proc.mgr.proc_yield;
tNow := Counters.c32; tNow := networkTicks;
if tNow >= tStart then if tNow >= tStart then
elapsed := tNow - tStart elapsed := tNow - tStart
else else
elapsed := ($FFFFFFFF - tStart) + tNow + 1; elapsed := ($FFFFFFFF - tStart) + tNow + 1;
if elapsed >= timeoutTicks then begin if elapsed >= timeoutTicks then begin
driver.net.proto.icmp.cancelRequests(void(st));
st^.Result := prGotError; st^.Result := prGotError;
st^.ErrorReason := aecTimeout; st^.ErrorReason := aecTimeout;
break; break;
@@ -132,8 +151,7 @@ begin
end; end;
{ Clean up } { Clean up }
kfree(void(st)); proc.mgr.unbindResource(proc.mgr.CurrentProcess, void(st));
kfree(void(ip));
end; end;
procedure init(); procedure init();
+6 -2
View File
@@ -14,7 +14,7 @@ unit app.setres;
interface interface
uses uses
io.stdio, driver.video.gpu, core.util, arch.x86.util, core.strings, debug.tracer, io.syslog; io.stdio, driver.video.lvgl, driver.video.gpu, core.util, arch.platform.cpu, core.strings, debug.tracer, io.syslog;
procedure init(); procedure init();
@@ -25,6 +25,7 @@ var
w, h : uint32; w, h : uint32;
wStr, hStr : pchar; wStr, hStr : pchar;
info : TGPUModeInfo; info : TGPUModeInfo;
changed: boolean;
begin begin
debug.tracer.push_trace('setres.run'); debug.tracer.push_trace('setres.run');
@@ -55,7 +56,10 @@ begin
io.stdio.bufWriteStrLn(stdout_buf, 'x32...'); io.stdio.bufWriteStrLn(stdout_buf, 'x32...');
{ Step 1: Set display mode via GPU framework (tries BGA first, then VBE) } { Step 1: Set display mode via GPU framework (tries BGA first, then VBE) }
if not driver.video.gpu.setMode(w, h, 32, info) then begin driver.video.lvgl.lvgl_lock;
changed := driver.video.gpu.setMode(w, h, 32, info);
driver.video.lvgl.lvgl_unlock;
if not changed then begin
io.stdio.bufWriteStrLn(stderr_buf, 'Error: Mode switch failed. Mode may not be supported.'); io.stdio.bufWriteStrLn(stderr_buf, 'Error: Mode switch failed. Mode may not be supported.');
debug.tracer.pop_trace; debug.tracer.pop_trace;
exit; exit;
Loaded 20 of 169 files, more files were not shown because too many files have changed in this diff. Show more