Add x86_64 kernel bring-up with build-selected platform adapters
This commit is contained in:
1 parent
e8e4061564
commit
6a1eb5e2ac
69 files changed
+4981
-1502
No files matched your search
@@ -0,0 +1,23 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
unit arch.common.interrupts;
|
||||
interface
|
||||
function lock: PtrUInt;
|
||||
procedure unlock(flags: PtrUInt);
|
||||
implementation
|
||||
uses arch.platform.cpu;
|
||||
function lock: PtrUInt;
|
||||
begin lock := arch.platform.cpu.lock; end;
|
||||
procedure unlock(flags: PtrUInt);
|
||||
begin arch.platform.cpu.unlock(flags); end;
|
||||
end.
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Shared PC interrupt-controller programming. Call with interrupts disabled. }
|
||||
unit arch.common.legacyirq;
|
||||
interface
|
||||
const
|
||||
PIT_INPUT_HZ = 1193182;
|
||||
PIT_DIVISOR = 149;
|
||||
procedure remap(masterMask, slaveMask: uint8);
|
||||
procedure masks(masterMask, slaveMask: uint8);
|
||||
procedure timerStart;
|
||||
function realIRQ(line: uint8): boolean;
|
||||
procedure acknowledge(line: uint8);
|
||||
implementation
|
||||
uses arch.platform.cpu;
|
||||
procedure writeSlow(port: uint16; value: uint8);
|
||||
begin
|
||||
outb(port, value);
|
||||
outb($80, 0);
|
||||
end;
|
||||
procedure masks(masterMask, slaveMask: uint8);
|
||||
begin
|
||||
writeSlow($21, masterMask); writeSlow($A1, slaveMask);
|
||||
end;
|
||||
procedure remap(masterMask, slaveMask: uint8);
|
||||
begin
|
||||
writeSlow($20, $11); writeSlow($A0, $11);
|
||||
writeSlow($21, $20); writeSlow($A1, $28);
|
||||
writeSlow($21, $04); writeSlow($A1, $02);
|
||||
writeSlow($21, $01); writeSlow($A1, $01);
|
||||
masks(masterMask, slaveMask);
|
||||
end;
|
||||
procedure timerStart;
|
||||
begin
|
||||
{ Channel 0, low/high byte, mode 2, binary. }
|
||||
outb($43, $34);
|
||||
outb($40, PIT_DIVISOR and $FF);
|
||||
outb($40, PIT_DIVISOR shr 8);
|
||||
end;
|
||||
function realIRQ(line: uint8): boolean;
|
||||
begin
|
||||
realIRQ := line < 16;
|
||||
if line = 7 then begin
|
||||
outb($20, $0B);
|
||||
realIRQ := (inb($20) and $80) <> 0;
|
||||
end else if line = 15 then begin
|
||||
outb($A0, $0B);
|
||||
realIRQ := (inb($A0) and $80) <> 0;
|
||||
{ A spurious slave request still put master IRQ2 in service. }
|
||||
if not realIRQ then outb($20, $20);
|
||||
end;
|
||||
end;
|
||||
procedure acknowledge(line: uint8);
|
||||
begin
|
||||
if line >= 16 then exit;
|
||||
if line >= 8 then outb($A0, $20);
|
||||
outb($20, $20);
|
||||
end;
|
||||
end.
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Shared contract; implemented by each build-selected adapter. }
|
||||
function lock: PtrUInt;
|
||||
procedure unlock(flags: PtrUInt);
|
||||
procedure outb(port: uint16; value: uint8);
|
||||
function inb(port: uint16): uint8;
|
||||
procedure copyBytes(source, dest: PtrUInt; bytes: SizeUInt);
|
||||
procedure zero(dest: pointer; bytes: SizeUInt);
|
||||
procedure idle;
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Shared contract; implemented by each build-selected adapter. }
|
||||
procedure log(tag, message: pchar);
|
||||
procedure push_trace(name: pchar);
|
||||
procedure pop_trace;
|
||||
procedure fatal(tag, message: pchar);
|
||||
procedure testSummary(tag, passedKey, failedKey: pchar; passed, failed: uint32);
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Shared contract; implemented by each build-selected adapter. }
|
||||
function allocateHeapPage: PtrUInt;
|
||||
function allocateLarge(pages: uint32): PtrUInt;
|
||||
procedure release(address: PtrUInt; pages: uint32);
|
||||
function identityReserve(address: PtrUInt): pointer;
|
||||
function freeBacking: uint64;
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Shared contract; implemented by each build-selected adapter. }
|
||||
function prepare(stack: pointer; bytes: SizeUInt; entry: pointer): PtrUInt;
|
||||
function timerTicks: uint32;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,82 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Commands extracted from io.stdio (Kieron Morris). }
|
||||
unit arch.x86.console;
|
||||
interface
|
||||
procedure init;
|
||||
implementation
|
||||
uses io.stdio, core.version, driver.timer.rtc, arch.x86.util;
|
||||
procedure cmd_version(params: PParamList; stdin_buf, stdout_buf, stderr_buf: POutBuf);
|
||||
begin
|
||||
bufWriteStr(stdout_buf, ' Asuro Version: ');
|
||||
bufWriteStrLn(stdout_buf, core.version.VERSION);
|
||||
bufWriteStr(stdout_buf, ' Compiled on: ');
|
||||
bufWriteStr(stdout_buf, core.version.COMPILE_DATE);
|
||||
bufWriteStr(stdout_buf, ' ');
|
||||
bufWriteStrLn(stdout_buf, core.version.COMPILE_TIME);
|
||||
bufWriteStrLn(stdout_buf, ' Compiled With: ');
|
||||
bufWriteStr(stdout_buf, ' NASM - Version: ');
|
||||
bufWriteStrLn(stdout_buf, core.version.NASM_VERSION);
|
||||
bufWriteStr(stdout_buf, ' FPC - Version: ');
|
||||
bufWriteStrLn(stdout_buf, core.version.FPC_VERSION);
|
||||
bufWriteStr(stdout_buf, ' MAKE - Version: ');
|
||||
bufWriteStrLn(stdout_buf, core.version.MAKE_VERSION);
|
||||
bufWriteStr(stdout_buf, ' ');
|
||||
bufWriteInt(stdout_buf, core.version.LINE_COUNT);
|
||||
bufWriteStr(stdout_buf, ' lines, across ');
|
||||
bufWriteInt(stdout_buf, core.version.FILE_COUNT);
|
||||
bufWriteStrLn(stdout_buf, ' files.');
|
||||
bufWriteStr(stdout_buf, ' Baked Drivers: ');
|
||||
bufWriteIntLn(stdout_buf, core.version.DRIVER_COUNT);
|
||||
bufWriteStr(stdout_buf, ' Checksum: ');
|
||||
bufWriteStrLn(stdout_buf, core.version.CHECKSUM);
|
||||
end;
|
||||
|
||||
procedure cmd_time(params: PParamList; stdin_buf, stdout_buf, stderr_buf: POutBuf);
|
||||
var
|
||||
dt: TDateTime;
|
||||
begin
|
||||
dt := getDateTime;
|
||||
if dt.Day < 10 then bufWriteChar(stdout_buf, '0');
|
||||
bufWriteInt(stdout_buf, dt.Day);
|
||||
bufWriteChar(stdout_buf, '/');
|
||||
if dt.Month < 10 then bufWriteChar(stdout_buf, '0');
|
||||
bufWriteInt(stdout_buf, dt.Month);
|
||||
bufWriteChar(stdout_buf, '/');
|
||||
bufWriteInt(stdout_buf, dt.Century);
|
||||
bufWriteInt(stdout_buf, dt.Year);
|
||||
bufWriteChar(stdout_buf, ' ');
|
||||
if dt.Hours < 10 then bufWriteChar(stdout_buf, '0');
|
||||
bufWriteInt(stdout_buf, dt.Hours);
|
||||
bufWriteChar(stdout_buf, ':');
|
||||
if dt.Minutes < 10 then bufWriteChar(stdout_buf, '0');
|
||||
bufWriteInt(stdout_buf, dt.Minutes);
|
||||
bufWriteChar(stdout_buf, ':');
|
||||
if dt.Seconds < 10 then bufWriteChar(stdout_buf, '0');
|
||||
bufWriteIntLn(stdout_buf, dt.Seconds);
|
||||
bufWriteStr(stdout_buf, 'Weekday: ');
|
||||
bufWriteStrLn(stdout_buf, WeekdayToString(dt.Weekday));
|
||||
end;
|
||||
|
||||
procedure cmd_reboot(params: PParamList; stdin_buf, stdout_buf, stderr_buf: POutBuf);
|
||||
begin
|
||||
resetSystem;
|
||||
end;
|
||||
|
||||
procedure init;
|
||||
begin
|
||||
registerCommand('VERSION', @cmd_version, 'Display the running version of Asuro.');
|
||||
registerCommand('TIME', @cmd_time, 'Print the current time.');
|
||||
registerCommand('REBOOT', @cmd_reboot, 'Reboot the system.');
|
||||
end;
|
||||
end.
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright 2021 Kieron Morris
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +23,7 @@ unit arch.x86.irq;
|
||||
interface
|
||||
|
||||
uses
|
||||
boot.mgr,
|
||||
boot.mgr, arch.common.legacyirq,
|
||||
core.util, arch.x86.util, io.syslog;
|
||||
|
||||
procedure init();
|
||||
@@ -32,26 +33,7 @@ implementation
|
||||
procedure init();
|
||||
begin
|
||||
io.syslog.logln('IRQ','INIT START.');
|
||||
outb($20, $11);
|
||||
io_wait;
|
||||
outb($A0, $11);
|
||||
io_wait;
|
||||
outb($21, $20);
|
||||
io_wait;
|
||||
outb($A1, $28);
|
||||
io_wait;
|
||||
outb($21, $04);
|
||||
io_wait;
|
||||
outb($A1, $02);
|
||||
io_wait;
|
||||
outb($21, $01);
|
||||
io_wait;
|
||||
outb($A1, $01);
|
||||
io_wait;
|
||||
outb($21, $00);
|
||||
io_wait;
|
||||
outb($A1, $00);
|
||||
io_wait;
|
||||
arch.common.legacyirq.remap(0, 0);
|
||||
io.syslog.logln('IRQ','INIT END.');
|
||||
end;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Kieron Morris
|
||||
// Copyright 2021 Kieron Morris & Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -21,65 +21,22 @@ unit arch.x86.multiboot;
|
||||
|
||||
interface
|
||||
|
||||
uses boot.multiboot;
|
||||
|
||||
const
|
||||
KERNEL_STACKSIZE = $4000;
|
||||
MULTIBOOT_BOOTLOADER_MAGIC = $2BADB002;
|
||||
|
||||
type
|
||||
Pelf_section_header_table_t = ^elf_section_header_table_t;
|
||||
elf_section_header_table_t = packed record
|
||||
num: uint32;
|
||||
size: uint32;
|
||||
addr: uint32;
|
||||
shndx: uint32;
|
||||
end;
|
||||
|
||||
Pmultiboot_info_t = ^multiboot_info_t;
|
||||
multiboot_info_t = packed record
|
||||
flags: uint32;
|
||||
mem_lower: uint32;
|
||||
mem_upper: uint32;
|
||||
boot_device: uint32;
|
||||
cmdline: uint32;
|
||||
mods_count: uint32;
|
||||
mods_addr: uint32;
|
||||
elf_sec: elf_section_header_table_t;
|
||||
mmap_length: uint32;
|
||||
mmap_addr: uint32;
|
||||
drives_legnth : uint32;
|
||||
drives_addr: uint32;
|
||||
config_table : uint32;
|
||||
boot_loader_name : uint32;
|
||||
apm_table: uint32;
|
||||
vbe_control_info : uint32;
|
||||
vbe_mode_info : uint32;
|
||||
vbe_mode : uint16;
|
||||
vbe_interface_seg : uint16;
|
||||
vbe_interface_off : uint16;
|
||||
vbe_interface_len : uint16;
|
||||
framebuffer_addr : uint64;
|
||||
framebuffer_pitch : uint32;
|
||||
framebuffer_width : uint32;
|
||||
framebuffer_height: uint32;
|
||||
framebuffer_bpp : uint8;
|
||||
end;
|
||||
|
||||
Pmodule_t = ^module_t;
|
||||
module_t = packed record
|
||||
mod_start: uint32;
|
||||
mod_end: uint32;
|
||||
name: uint32;
|
||||
reserved: uint32;
|
||||
end;
|
||||
|
||||
Pmemory_map_t = ^memory_map_t;
|
||||
memory_map_t = packed record
|
||||
size: uint32;
|
||||
base_addr : uint64;
|
||||
length : uint64;
|
||||
mtype: uint32;
|
||||
end;
|
||||
|
||||
elf_section_header_table_t = boot.multiboot.elf_section_header_table_t;
|
||||
Pelf_section_header_table_t = boot.multiboot.Pelf_section_header_table_t;
|
||||
multiboot_info_t = boot.multiboot.multiboot_info_t;
|
||||
Pmultiboot_info_t = boot.multiboot.Pmultiboot_info_t;
|
||||
module_t = boot.multiboot.module_t;
|
||||
Pmodule_t = boot.multiboot.Pmodule_t;
|
||||
memory_map_t = boot.multiboot.memory_map_t;
|
||||
Pmemory_map_t = boot.multiboot.Pmemory_map_t;
|
||||
|
||||
var
|
||||
multibootinfo : Pmultiboot_info_t = nil;
|
||||
multibootmagic : uint32;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Compose shared services with the i386 boot manager and platform commands. }
|
||||
unit arch.x86.startup;
|
||||
interface
|
||||
implementation
|
||||
uses boot.mgr, memory.heap, proc.mgr, io.stdio, arch.x86.console;
|
||||
procedure consoleInit;
|
||||
begin io.stdio.init; arch.x86.console.init; end;
|
||||
initialization
|
||||
boot.mgr.registerBoot('memory.heap', @memory.heap.init, 'Heap Memory Manager', 'arch.*.memory.*');
|
||||
boot.mgr.registerBoot('io.stdio', @consoleInit, 'Standard I/O Abstraction', BOOT_MGR_BARRIER_EARLY);
|
||||
boot.mgr.registerBoot('proc.mgr', @proc.mgr.init, 'Process Manager', 'driver.storage.fs*');
|
||||
end.
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright 2021 Kieron Morris
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -22,14 +23,14 @@ unit arch.x86.isr.tmr0;
|
||||
interface
|
||||
|
||||
uses
|
||||
core.util, arch.x86.util,
|
||||
core.util, arch.x86.util, arch.common.legacyirq,
|
||||
arch.x86.isr.types,
|
||||
arch.x86.isr.mgr,
|
||||
arch.x86.idt;
|
||||
|
||||
const
|
||||
PIT_INPUT_HZ = 1193182;
|
||||
PIT_DIVISOR = 149;
|
||||
PIT_INPUT_HZ = arch.common.legacyirq.PIT_INPUT_HZ;
|
||||
PIT_DIVISOR = arch.common.legacyirq.PIT_DIVISOR;
|
||||
|
||||
procedure register();
|
||||
procedure hook(hook_method : uint32);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Build-selected x86 adapter. }
|
||||
unit arch.platform.cpu;
|
||||
interface
|
||||
{$i ../../common/platform.cpu.inc}
|
||||
implementation
|
||||
uses arch.x86.util, memory.raw;
|
||||
function lock: PtrUInt; assembler; nostackframe;
|
||||
asm pushfd; cli; pop eax end;
|
||||
procedure unlock(flags: PtrUInt);
|
||||
begin if (flags and $200) <> 0 then asm sti end; end;
|
||||
procedure idle;
|
||||
begin asm hlt end; end;
|
||||
procedure outb(port: uint16; value: uint8);
|
||||
begin arch.x86.util.outb(port, value); end;
|
||||
function inb(port: uint16): uint8;
|
||||
begin inb := arch.x86.util.inb(port); end;
|
||||
procedure copyBytes(source, dest: PtrUInt; bytes: SizeUInt);
|
||||
begin
|
||||
if bytes >= 16 then arch.x86.util.__REP_MOVSB_memcpy(source, dest, bytes)
|
||||
else memory.raw.move(pointer(source), pointer(dest), bytes);
|
||||
end;
|
||||
procedure zero(dest: pointer; bytes: SizeUInt);
|
||||
var d: pointer; b: SizeUInt;
|
||||
begin
|
||||
d := dest; b := bytes;
|
||||
if b = 0 then exit;
|
||||
asm
|
||||
push edi
|
||||
mov edi, d
|
||||
mov ecx, b
|
||||
shr ecx, 2
|
||||
xor eax, eax
|
||||
cld
|
||||
rep stosd
|
||||
mov ecx, b
|
||||
and ecx, 3
|
||||
rep stosb
|
||||
pop edi
|
||||
end;
|
||||
end;
|
||||
end.
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Build-selected x86 adapter. }
|
||||
unit arch.platform.diagnostics;
|
||||
interface
|
||||
{$i ../../common/platform.diagnostics.inc}
|
||||
implementation
|
||||
uses io.syslog, debug.tracer, core.panic;
|
||||
procedure log(tag, message: pchar);
|
||||
begin io.syslog.logln(tag, message); end;
|
||||
procedure push_trace(name: pchar);
|
||||
begin debug.tracer.push_trace(name); end;
|
||||
procedure pop_trace;
|
||||
begin debug.tracer.pop_trace; end;
|
||||
procedure fatal(tag, message: pchar);
|
||||
begin core.panic.panic(tag, message, nil); end;
|
||||
procedure testSummary(tag, passedKey, failedKey: pchar; passed, failed: uint32);
|
||||
begin
|
||||
io.syslog.log(tag, '');
|
||||
io.syslog.writeint(passed); io.syslog.writestring(' passed, ');
|
||||
io.syslog.writeint(failed); io.syslog.writestringln(' failed.');
|
||||
end;
|
||||
end.
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Mapping policy extracted from memory.heap (Kieron Morris). }
|
||||
unit arch.platform.memory;
|
||||
interface
|
||||
const MAX_HEAP_REGIONS = 256;
|
||||
{$i ../../common/platform.memory.inc}
|
||||
implementation
|
||||
uses arch.x86.memory.virtual, arch.x86.memory.physical, arch.platform.diagnostics;
|
||||
function allocateHeapPage: PtrUInt;
|
||||
var i: uint32;
|
||||
begin
|
||||
allocateHeapPage := 0;
|
||||
i := KERNEL_PAGE_NUMBER + 4;
|
||||
while i < 1024 do begin
|
||||
if arch.x86.memory.virtual.new_page(i) then begin
|
||||
allocateHeapPage := i shl 22; exit;
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
end;
|
||||
function allocateLarge(pages: uint32): PtrUInt;
|
||||
var curr_page, i: uint16; miss: boolean;
|
||||
begin
|
||||
allocateLarge := 0;
|
||||
if (pages = 0) or (pages > MAX_HEAP_REGIONS) then exit;
|
||||
curr_page := 5;
|
||||
while uint32(curr_page) + pages - 1 < KERNEL_PAGE_NUMBER do begin
|
||||
miss := false;
|
||||
for i := 0 to pages - 1 do begin
|
||||
if not page_mappable(curr_page + i) then begin
|
||||
miss := true; curr_page := curr_page + i; break;
|
||||
end;
|
||||
end;
|
||||
if not miss then begin
|
||||
i := 0;
|
||||
while i < pages do begin
|
||||
if not arch.x86.memory.virtual.new_page(curr_page + i) then begin
|
||||
while i > 0 do begin
|
||||
dec(i); arch.x86.memory.virtual.free_page(curr_page + i);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
allocateLarge := uint32(curr_page) shl 22;
|
||||
exit;
|
||||
end;
|
||||
inc(curr_page);
|
||||
end;
|
||||
end;
|
||||
procedure release(address: PtrUInt; pages: uint32);
|
||||
var i: uint32; page_num: uint16;
|
||||
begin
|
||||
if (pages = 0) or (pages > MAX_HEAP_REGIONS) then begin
|
||||
fatal('LMM', 'Invalid heap region release'); exit;
|
||||
end;
|
||||
page_num := address shr 22;
|
||||
for i := 0 to pages - 1 do arch.x86.memory.virtual.free_page(page_num + uint16(i));
|
||||
end;
|
||||
function identityReserve(address: PtrUInt): pointer;
|
||||
var block: uint16;
|
||||
begin
|
||||
block := address shr 22;
|
||||
force_alloc_block(block, 0);
|
||||
map_page(block, block);
|
||||
identityReserve := pointer(uint32(block) shl 22);
|
||||
end;
|
||||
function freeBacking: uint64;
|
||||
begin freeBacking := pmm_free_blocks; end;
|
||||
end.
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ Build-selected x86 adapter. }
|
||||
unit arch.platform.process;
|
||||
interface
|
||||
{$i ../../common/platform.process.inc}
|
||||
implementation
|
||||
uses arch.x86.proc.context, arch.x86.bda;
|
||||
function prepare(stack: pointer; bytes: SizeUInt; entry: pointer): PtrUInt;
|
||||
begin prepare := arch.x86.proc.context.prepare(stack, bytes, entry); end;
|
||||
function timerTicks: uint32;
|
||||
begin timerTicks := PUInt32(@Counters.c32)^; end;
|
||||
end.
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{ i386 initial frame, extracted from proc.mgr (Kieron Morris). }
|
||||
unit arch.x86.proc.context;
|
||||
interface
|
||||
function prepare(stack: pointer; bytes: SizeUInt; entry: pointer): PtrUInt;
|
||||
implementation
|
||||
uses memory.raw;
|
||||
function prepare(stack: pointer; bytes: SizeUInt; entry: pointer): PtrUInt;
|
||||
var top, frame: PtrUInt; i: uint32;
|
||||
begin
|
||||
prepare := 0;
|
||||
if (stack = nil) or (entry = nil) or (bytes < 64) or
|
||||
(PtrUInt(stack) > High(PtrUInt) - bytes) then exit;
|
||||
top := PtrUInt(stack) + bytes;
|
||||
frame := top - 60;
|
||||
memory.raw.fill(pointer(frame), 0, 60);
|
||||
{ GS, FS, ES, DS; PUSHAD; EIP, CS, EFLAGS. }
|
||||
for i := 0 to 3 do PUInt32(frame + i * 4)^ := $10;
|
||||
PUInt32(top - 12)^ := PtrUInt(entry);
|
||||
PUInt32(top - 8)^ := $08;
|
||||
PUInt32(top - 4)^ := $0202;
|
||||
prepare := frame;
|
||||
end;
|
||||
end.
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright 2021 Kieron Morris
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +36,7 @@ uses
|
||||
procedure init;
|
||||
|
||||
{ No idle ESP variable needed — idle is now a formal process (PID 0)
|
||||
with its SavedESP managed like any other process. }
|
||||
with its SavedStack managed like any other process. }
|
||||
|
||||
implementation
|
||||
|
||||
@@ -51,7 +52,7 @@ var
|
||||
next : PProcessContext;
|
||||
begin
|
||||
{ 1. Save ESP into the current process }
|
||||
proc.mgr.CurrentProcess^.SavedESP := saved_esp;
|
||||
proc.mgr.CurrentProcess^.SavedStack := saved_esp;
|
||||
|
||||
{ 2. Dispatch all hooks registered on interrupt 32 (timer hooks).
|
||||
This fires TMR_0_ISR.Main which in turn fires BDA tick,
|
||||
@@ -66,7 +67,7 @@ begin
|
||||
proc.mgr.CurrentProcess := next;
|
||||
|
||||
{ 5. Return the selected process ESP }
|
||||
do_context_switch_work := next^.SavedESP;
|
||||
do_context_switch_work := next^.SavedStack;
|
||||
end;
|
||||
|
||||
{ -----------------------------------------------------------------------
|
||||
|
||||
+5
-182
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,83 @@
|
||||
// Copyright 2026 Aaron Hance
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
unit arch.x86_64.boot;
|
||||
|
||||
interface
|
||||
|
||||
procedure kmain(info: pointer; magic: uint32); cdecl;
|
||||
|
||||
implementation
|
||||
|
||||
uses io.stdio, core.strings, driver.storage.fdtable, arch.x86_64.proc.sched, proc.mgr, arch.x86_64.context, arch.x86_64.irq, memory.heap, debug.early, arch.x86_64.debug, arch.x86_64.isr, boot.multiboot,
|
||||
arch.x86_64.memory.physical, arch.x86_64.memory.virtual;
|
||||
|
||||
function long_mode_active: boolean; assembler; nostackframe;
|
||||
asm
|
||||
mov ecx, $C0000080
|
||||
rdmsr
|
||||
shr eax, 10
|
||||
and eax, 1
|
||||
end;
|
||||
|
||||
procedure kmain(info: pointer; magic: uint32); cdecl; [public, alias: 'kmain'];
|
||||
var
|
||||
wide: PtrUInt;
|
||||
begin
|
||||
arch.x86_64.debug.init;
|
||||
arch.x86_64.isr.init;
|
||||
puts('ASURO x86_64: entered Pascal'#13#10);
|
||||
if (magic <> $2BADB002) or (info = nil) then begin
|
||||
puts('FAIL: Multiboot handoff'#13#10);
|
||||
bootstrap_halt;
|
||||
end;
|
||||
if (sizeof(pointer) <> 8) or (sizeof(PtrUInt) <> 8) or
|
||||
(sizeof(SizeUInt) <> 8) or (sizeof(uint32) <> 4) then begin
|
||||
puts('FAIL: native type widths'#13#10);
|
||||
bootstrap_halt;
|
||||
end;
|
||||
wide := PtrUInt($100000000) + PtrUInt(magic);
|
||||
if (wide shr 32 <> 1) or not long_mode_active then begin
|
||||
puts('FAIL: long mode or 64-bit arithmetic'#13#10);
|
||||
bootstrap_halt;
|
||||
end;
|
||||
puts('PASS: long mode, Multiboot handoff, 64-bit Pascal types'#13#10);
|
||||
arch.x86_64.isr.UnitTest;
|
||||
arch.x86_64.memory.physical.init(Pmultiboot_info_t(info));
|
||||
arch.x86_64.memory.physical.UnitTest;
|
||||
arch.x86_64.memory.virtual.init;
|
||||
arch.x86_64.memory.virtual.UnitTest;
|
||||
memory.heap.init;
|
||||
memory.heap.UnitTest;
|
||||
core.strings.UnitTest;
|
||||
io.stdio.init;
|
||||
arch.x86_64.irq.init;
|
||||
arch.x86_64.irq.UnitTest;
|
||||
arch.x86_64.context.UnitTest;
|
||||
driver.storage.fdtable.UnitTest;
|
||||
proc.mgr.init;
|
||||
arch.x86_64.proc.sched.init;
|
||||
arch.x86_64.proc.sched.UnitTest;
|
||||
{$ifdef ASURO_TEST_UD}
|
||||
arch.x86_64.isr.testFatal(6);
|
||||
{$endif}
|
||||
{$ifdef ASURO_TEST_PF}
|
||||
arch.x86_64.isr.testFatal(14);
|
||||
{$endif}
|
||||
{$ifdef ASURO_TEST_DF}
|
||||
arch.x86_64.isr.testFatal(8);
|
||||
{$endif}
|
||||
puts('ASURO x86_64: bootstrap complete; interrupts disabled'#13#10);
|
||||
bootstrap_halt;
|
||||
end;
|
||||
|
||||
end.
|
||||
Loaded 20 of 69 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user