Updating to zig master
Added cpu model Moved logging to defer done log Moved mem.init to bottom Updated again to new zig master
This commit is contained in:
parent
d17381c267
commit
1f97a5c6c8
21 changed files with 157 additions and 135 deletions
38
build.zig
38
build.zig
|
@ -3,30 +3,19 @@ const builtin = @import("builtin");
|
||||||
const Builder = std.build.Builder;
|
const Builder = std.build.Builder;
|
||||||
const LibExeObjStep = std.build.LibExeObjStep;
|
const LibExeObjStep = std.build.LibExeObjStep;
|
||||||
const Step = std.build.Step;
|
const Step = std.build.Step;
|
||||||
const Target = std.build.Target;
|
const Target = std.Target;
|
||||||
|
const CrossTarget = std.zig.CrossTarget;
|
||||||
const fs = std.fs;
|
const fs = std.fs;
|
||||||
const Mode = builtin.Mode;
|
const Mode = builtin.Mode;
|
||||||
|
|
||||||
pub fn build(b: *Builder) !void {
|
pub fn build(b: *Builder) !void {
|
||||||
const target = Target{
|
const target = CrossTarget{
|
||||||
.Cross = Target.Cross{
|
.cpu_arch = .i386,
|
||||||
.arch = .i386,
|
.os_tag = .freestanding,
|
||||||
.os = .freestanding,
|
.cpu_model = .{ .explicit = &Target.x86.cpu._i686 },
|
||||||
.abi = .gnu,
|
|
||||||
.cpu_features = Target.CpuFeatures.initFromCpu(.i386, &builtin.Target.x86.cpu._i686),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const test_target = Target{
|
const target_str = switch (target.getCpuArch()) {
|
||||||
.Cross = Target.Cross{
|
|
||||||
.arch = .i386,
|
|
||||||
.os = .linux,
|
|
||||||
.abi = .gnu,
|
|
||||||
.cpu_features = Target.CpuFeatures.initFromCpu(.i386, &builtin.Target.x86.cpu._i686),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const target_str = switch (target.getArch()) {
|
|
||||||
.i386 => "x86",
|
.i386 => "x86",
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
@ -50,7 +39,7 @@ pub fn build(b: *Builder) !void {
|
||||||
exec.addBuildOption(bool, "rt_test", rt_test);
|
exec.addBuildOption(bool, "rt_test", rt_test);
|
||||||
exec.setBuildMode(build_mode);
|
exec.setBuildMode(build_mode);
|
||||||
exec.setLinkerScriptPath("link.ld");
|
exec.setLinkerScriptPath("link.ld");
|
||||||
exec.setTheTarget(target);
|
exec.setTarget(target);
|
||||||
|
|
||||||
const output_iso = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "pluto.iso" });
|
const output_iso = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "pluto.iso" });
|
||||||
const iso_dir_path = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "iso" });
|
const iso_dir_path = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "iso" });
|
||||||
|
@ -77,14 +66,9 @@ pub fn build(b: *Builder) !void {
|
||||||
unit_tests.addBuildOption([]const u8, "mock_path", mock_path);
|
unit_tests.addBuildOption([]const u8, "mock_path", mock_path);
|
||||||
unit_tests.addBuildOption([]const u8, "arch_mock_path", arch_mock_path);
|
unit_tests.addBuildOption([]const u8, "arch_mock_path", arch_mock_path);
|
||||||
|
|
||||||
const qemu_bin = switch (test_target.getArch()) {
|
if (builtin.os.tag != .windows) unit_tests.enable_qemu = true;
|
||||||
.i386 => "qemu-i386",
|
|
||||||
else => unreachable,
|
|
||||||
};
|
|
||||||
|
|
||||||
// We need this as the build as the make() doesn't handle it properly
|
unit_tests.setTarget(.{ .cpu_arch = .i386 });
|
||||||
unit_tests.setExecCmd(&[_]?[]const u8{ qemu_bin, null });
|
|
||||||
unit_tests.setTheTarget(test_target);
|
|
||||||
|
|
||||||
test_step.dependOn(&unit_tests.step);
|
test_step.dependOn(&unit_tests.step);
|
||||||
}
|
}
|
||||||
|
@ -92,7 +76,7 @@ pub fn build(b: *Builder) !void {
|
||||||
const run_step = b.step("run", "Run with qemu");
|
const run_step = b.step("run", "Run with qemu");
|
||||||
const run_debug_step = b.step("debug-run", "Run with qemu and wait for a gdb connection");
|
const run_debug_step = b.step("debug-run", "Run with qemu and wait for a gdb connection");
|
||||||
|
|
||||||
const qemu_bin = switch (target.getArch()) {
|
const qemu_bin = switch (target.getCpuArch()) {
|
||||||
.i386 => "qemu-system-i386",
|
.i386 => "qemu-system-i386",
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
|
|
@ -425,6 +425,7 @@ pub fn setTssStack(esp0: u32) void {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init gdt\n", .{});
|
log.logInfo("Init gdt\n", .{});
|
||||||
|
defer log.logInfo("Done gdt\n", .{});
|
||||||
// Initiate TSS
|
// Initiate TSS
|
||||||
gdt_entries[TSS_INDEX] = makeEntry(@ptrToInt(&tss), @sizeOf(TtsEntry) - 1, TSS_SEGMENT, NULL_FLAGS);
|
gdt_entries[TSS_INDEX] = makeEntry(@ptrToInt(&tss), @sizeOf(TtsEntry) - 1, TSS_SEGMENT, NULL_FLAGS);
|
||||||
|
|
||||||
|
@ -437,8 +438,6 @@ pub fn init() void {
|
||||||
// Load the TSS
|
// Load the TSS
|
||||||
arch.ltr(TSS_OFFSET);
|
arch.ltr(TSS_OFFSET);
|
||||||
|
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,11 +180,11 @@ pub fn openInterruptGate(index: u8, handler: InterruptHandler) IdtError!void {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init idt\n", .{});
|
log.logInfo("Init idt\n", .{});
|
||||||
|
defer log.logInfo("Done idt\n", .{});
|
||||||
|
|
||||||
idt_ptr.base = @ptrToInt(&idt_entries);
|
idt_ptr.base = @ptrToInt(&idt_entries);
|
||||||
|
|
||||||
arch.lidt(&idt_ptr);
|
arch.lidt(&idt_ptr);
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,14 +129,13 @@ pub fn registerIrq(irq_num: u8, handler: IrqHandler) IrqError!void {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init irq\n", .{});
|
log.logInfo("Init irq\n", .{});
|
||||||
|
defer log.logInfo("Done irq\n", .{});
|
||||||
|
|
||||||
comptime var i = IRQ_OFFSET;
|
comptime var i = IRQ_OFFSET;
|
||||||
inline while (i < IRQ_OFFSET + 16) : (i += 1) {
|
inline while (i < IRQ_OFFSET + 16) : (i += 1) {
|
||||||
openIrq(i, interrupts.getInterruptStub(i));
|
openIrq(i, interrupts.getInterruptStub(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,7 @@ pub fn registerIsr(isr_num: u16, handler: IsrHandler) IsrError!void {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init isr\n", .{});
|
log.logInfo("Init isr\n", .{});
|
||||||
|
defer log.logInfo("Done isr\n", .{});
|
||||||
|
|
||||||
comptime var i = 0;
|
comptime var i = 0;
|
||||||
inline while (i < 32) : (i += 1) {
|
inline while (i < 32) : (i += 1) {
|
||||||
|
@ -243,8 +244,6 @@ pub fn init() void {
|
||||||
|
|
||||||
openIsr(syscalls.INTERRUPT, interrupts.getInterruptStub(syscalls.INTERRUPT));
|
openIsr(syscalls.INTERRUPT, interrupts.getInterruptStub(syscalls.INTERRUPT));
|
||||||
|
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -293,6 +293,8 @@ fn pageFault(state: *arch.InterruptContext) void {
|
||||||
///
|
///
|
||||||
pub fn init(mb_info: *multiboot.multiboot_info_t, mem_profile: *const MemProfile, allocator: *std.mem.Allocator) void {
|
pub fn init(mb_info: *multiboot.multiboot_info_t, mem_profile: *const MemProfile, allocator: *std.mem.Allocator) void {
|
||||||
log.logInfo("Init paging\n", .{});
|
log.logInfo("Init paging\n", .{});
|
||||||
|
defer log.logInfo("Done paging\n", .{});
|
||||||
|
|
||||||
// Calculate start and end of mapping
|
// Calculate start and end of mapping
|
||||||
const v_start = std.mem.alignBackward(@ptrToInt(mem_profile.vaddr_start), PAGE_SIZE_4KB);
|
const v_start = std.mem.alignBackward(@ptrToInt(mem_profile.vaddr_start), PAGE_SIZE_4KB);
|
||||||
const v_end = std.mem.alignForward(@ptrToInt(mem_profile.vaddr_end) + mem_profile.fixed_alloc_size, PAGE_SIZE_4KB);
|
const v_end = std.mem.alignForward(@ptrToInt(mem_profile.vaddr_end) + mem_profile.fixed_alloc_size, PAGE_SIZE_4KB);
|
||||||
|
@ -351,7 +353,6 @@ pub fn init(mb_info: *multiboot.multiboot_info_t, mem_profile: *const MemProfile
|
||||||
isr.registerIsr(isr.PAGE_FAULT, if (options.rt_test) rt_pageFault else pageFault) catch |e| {
|
isr.registerIsr(isr.PAGE_FAULT, if (options.rt_test) rt_pageFault else pageFault) catch |e| {
|
||||||
panic(@errorReturnTrace(), "Failed to register page fault ISR: {}\n", .{e});
|
panic(@errorReturnTrace(), "Failed to register page fault ISR: {}\n", .{e});
|
||||||
};
|
};
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (options.rt_test) runtimeTests(v_end);
|
if (options.rt_test) runtimeTests(v_end);
|
||||||
}
|
}
|
||||||
|
@ -410,7 +411,7 @@ test "virtToTableEntryIdx" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "mapDirEntry" {
|
test "mapDirEntry" {
|
||||||
var allocator = std.heap.direct_allocator;
|
var allocator = std.heap.page_allocator;
|
||||||
var dir: Directory = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = [_]?*Table{null} ** ENTRIES_PER_DIRECTORY };
|
var dir: Directory = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = [_]?*Table{null} ** ENTRIES_PER_DIRECTORY };
|
||||||
var phys: usize = 0 * PAGE_SIZE_4MB;
|
var phys: usize = 0 * PAGE_SIZE_4MB;
|
||||||
const phys_end: usize = phys + PAGE_SIZE_4MB;
|
const phys_end: usize = phys + PAGE_SIZE_4MB;
|
||||||
|
@ -425,7 +426,7 @@ test "mapDirEntry" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "mapDirEntry returns errors correctly" {
|
test "mapDirEntry returns errors correctly" {
|
||||||
var allocator = std.heap.direct_allocator;
|
var allocator = std.heap.page_allocator;
|
||||||
var dir = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = undefined };
|
var dir = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = undefined };
|
||||||
testing.expectError(PagingError.UnalignedVirtAddresses, mapDirEntry(&dir, 1, PAGE_SIZE_4KB + 1, 0, PAGE_SIZE_4KB, allocator));
|
testing.expectError(PagingError.UnalignedVirtAddresses, mapDirEntry(&dir, 1, PAGE_SIZE_4KB + 1, 0, PAGE_SIZE_4KB, allocator));
|
||||||
testing.expectError(PagingError.UnalignedPhysAddresses, mapDirEntry(&dir, 0, PAGE_SIZE_4KB, 1, PAGE_SIZE_4KB + 1, allocator));
|
testing.expectError(PagingError.UnalignedPhysAddresses, mapDirEntry(&dir, 0, PAGE_SIZE_4KB, 1, PAGE_SIZE_4KB + 1, allocator));
|
||||||
|
@ -435,7 +436,7 @@ test "mapDirEntry returns errors correctly" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "mapDir" {
|
test "mapDir" {
|
||||||
var allocator = std.heap.direct_allocator;
|
var allocator = std.heap.page_allocator;
|
||||||
var dir = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = [_]?*Table{null} ** ENTRIES_PER_DIRECTORY };
|
var dir = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = [_]?*Table{null} ** ENTRIES_PER_DIRECTORY };
|
||||||
const phys_start: usize = PAGE_SIZE_4MB * 2;
|
const phys_start: usize = PAGE_SIZE_4MB * 2;
|
||||||
const virt_start: usize = PAGE_SIZE_4MB * 4;
|
const virt_start: usize = PAGE_SIZE_4MB * 4;
|
||||||
|
|
|
@ -433,6 +433,7 @@ pub fn clearMask(irq_num: u8) void {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init pic\n", .{});
|
log.logInfo("Init pic\n", .{});
|
||||||
|
defer log.logInfo("Done pic\n", .{});
|
||||||
|
|
||||||
// Initiate
|
// Initiate
|
||||||
sendCommandMaster(ICW1_INITIALISATION | ICW1_EXPECT_ICW4);
|
sendCommandMaster(ICW1_INITIALISATION | ICW1_EXPECT_ICW4);
|
||||||
|
@ -467,8 +468,6 @@ pub fn init() void {
|
||||||
// Clear the IRQ for the slave
|
// Clear the IRQ for the slave
|
||||||
clearMask(IRQ_CASCADE_FOR_SLAVE);
|
clearMask(IRQ_CASCADE_FOR_SLAVE);
|
||||||
|
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -371,6 +371,8 @@ pub fn getFrequency() u32 {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init pit\n", .{});
|
log.logInfo("Init pit\n", .{});
|
||||||
|
defer log.logInfo("Done pit\n", .{});
|
||||||
|
|
||||||
// Set up counter 0 at 10000hz in a square wave mode counting in binary
|
// Set up counter 0 at 10000hz in a square wave mode counting in binary
|
||||||
const freq: u32 = 10000;
|
const freq: u32 = 10000;
|
||||||
setupCounter(CounterSelect.Counter0, freq, OCW_MODE_SQUARE_WAVE_GENERATOR | OCW_BINARY_COUNT_BINARY) catch |e| {
|
setupCounter(CounterSelect.Counter0, freq, OCW_MODE_SQUARE_WAVE_GENERATOR | OCW_BINARY_COUNT_BINARY) catch |e| {
|
||||||
|
@ -389,8 +391,6 @@ pub fn init() void {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,6 +252,7 @@ fn enableInterrupts() void {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init rtc\n", .{});
|
log.logInfo("Init rtc\n", .{});
|
||||||
|
defer log.logInfo("Done rtc\n", .{});
|
||||||
|
|
||||||
// Register the interrupt handler
|
// Register the interrupt handler
|
||||||
irq.registerIrq(pic.IRQ_REAL_TIME_CLOCK, rtcHandler) catch |err| switch (err) {
|
irq.registerIrq(pic.IRQ_REAL_TIME_CLOCK, rtcHandler) catch |err| switch (err) {
|
||||||
|
@ -276,16 +277,12 @@ pub fn init() void {
|
||||||
// Enable RTC interrupts
|
// Enable RTC interrupts
|
||||||
enableInterrupts();
|
enableInterrupts();
|
||||||
|
|
||||||
// Read status register C to clear any interrupts that may have happened during set up
|
|
||||||
//const reg_c = cmos.readStatusRegister(cmos.StatusRegister.C, false);
|
|
||||||
|
|
||||||
// Can now enable interrupts
|
// Can now enable interrupts
|
||||||
arch.enableInterrupts();
|
arch.enableInterrupts();
|
||||||
|
|
||||||
|
// Read status register C to clear any interrupts that may have happened during set up
|
||||||
const reg_c = cmos.readStatusRegister(cmos.StatusRegister.C, false);
|
const reg_c = cmos.readStatusRegister(cmos.StatusRegister.C, false);
|
||||||
|
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -238,8 +238,9 @@ inline fn syscallArg(ctx: *arch.InterruptContext, comptime arg_idx: u32) u32 {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init syscalls\n", .{});
|
log.logInfo("Init syscalls\n", .{});
|
||||||
|
defer log.logInfo("Done syscalls\n", .{});
|
||||||
|
|
||||||
isr.registerIsr(INTERRUPT, handle) catch unreachable;
|
isr.registerIsr(INTERRUPT, handle) catch unreachable;
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
if (options.rt_test) runtimeTests();
|
if (options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ pub fn Bitmap(comptime BitmapType: type) type {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "setEntry" {
|
test "setEntry" {
|
||||||
var bmp = try Bitmap(u32).init(31, std.heap.direct_allocator);
|
var bmp = try Bitmap(u32).init(31, std.heap.page_allocator);
|
||||||
testing.expectEqual(@as(u32, 31), bmp.num_free_entries);
|
testing.expectEqual(@as(u32, 31), bmp.num_free_entries);
|
||||||
|
|
||||||
try bmp.setEntry(0);
|
try bmp.setEntry(0);
|
||||||
|
@ -178,7 +178,7 @@ test "setEntry" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "clearEntry" {
|
test "clearEntry" {
|
||||||
var bmp = try Bitmap(u32).init(32, std.heap.direct_allocator);
|
var bmp = try Bitmap(u32).init(32, std.heap.page_allocator);
|
||||||
testing.expectEqual(@as(u32, 32), bmp.num_free_entries);
|
testing.expectEqual(@as(u32, 32), bmp.num_free_entries);
|
||||||
|
|
||||||
try bmp.setEntry(0);
|
try bmp.setEntry(0);
|
||||||
|
@ -204,7 +204,7 @@ test "clearEntry" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "setFirstFree multiple bitmaps" {
|
test "setFirstFree multiple bitmaps" {
|
||||||
var bmp = try Bitmap(u8).init(9, std.heap.direct_allocator);
|
var bmp = try Bitmap(u8).init(9, std.heap.page_allocator);
|
||||||
|
|
||||||
// Allocate the first entry
|
// Allocate the first entry
|
||||||
testing.expectEqual(bmp.setFirstFree() orelse unreachable, 0);
|
testing.expectEqual(bmp.setFirstFree() orelse unreachable, 0);
|
||||||
|
@ -239,7 +239,7 @@ test "setFirstFree multiple bitmaps" {
|
||||||
testing.expectEqual(bmp.bitmaps[1], 1);
|
testing.expectEqual(bmp.bitmaps[1], 1);
|
||||||
}
|
}
|
||||||
test "setFirstFree" {
|
test "setFirstFree" {
|
||||||
var bmp = try Bitmap(u32).init(32, std.heap.direct_allocator);
|
var bmp = try Bitmap(u32).init(32, std.heap.page_allocator);
|
||||||
|
|
||||||
// Allocate the first entry
|
// Allocate the first entry
|
||||||
testing.expectEqual(bmp.setFirstFree() orelse unreachable, 0);
|
testing.expectEqual(bmp.setFirstFree() orelse unreachable, 0);
|
||||||
|
@ -260,7 +260,7 @@ test "setFirstFree" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "isSet" {
|
test "isSet" {
|
||||||
var bmp = try Bitmap(u32).init(32, std.heap.direct_allocator);
|
var bmp = try Bitmap(u32).init(32, std.heap.page_allocator);
|
||||||
|
|
||||||
bmp.bitmaps[0] = 1;
|
bmp.bitmaps[0] = 1;
|
||||||
// Make sure that only the set entry is considered set
|
// Make sure that only the set entry is considered set
|
||||||
|
@ -292,7 +292,7 @@ test "isSet" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "indexToBit" {
|
test "indexToBit" {
|
||||||
var bmp = try Bitmap(u8).init(10, std.heap.direct_allocator);
|
var bmp = try Bitmap(u8).init(10, std.heap.page_allocator);
|
||||||
testing.expectEqual(bmp.indexToBit(0), 1);
|
testing.expectEqual(bmp.indexToBit(0), 1);
|
||||||
testing.expectEqual(bmp.indexToBit(1), 2);
|
testing.expectEqual(bmp.indexToBit(1), 2);
|
||||||
testing.expectEqual(bmp.indexToBit(2), 4);
|
testing.expectEqual(bmp.indexToBit(2), 4);
|
||||||
|
|
|
@ -39,8 +39,9 @@ export fn kmain(mb_info: *multiboot.multiboot_info_t, mb_magic: u32) void {
|
||||||
serial.init(serial.DEFAULT_BAUDRATE, serial.Port.COM1) catch |e| {
|
serial.init(serial.DEFAULT_BAUDRATE, serial.Port.COM1) catch |e| {
|
||||||
panic_root.panic(@errorReturnTrace(), "Failed to initialise serial: {}", .{e});
|
panic_root.panic(@errorReturnTrace(), "Failed to initialise serial: {}", .{e});
|
||||||
};
|
};
|
||||||
if (build_options.rt_test)
|
|
||||||
log.runtimeTests();
|
if (build_options.rt_test) log.runtimeTests();
|
||||||
|
|
||||||
const mem_profile = mem.init(mb_info);
|
const mem_profile = mem.init(mb_info);
|
||||||
var buffer = mem_profile.vaddr_end[0..mem_profile.fixed_alloc_size];
|
var buffer = mem_profile.vaddr_end[0..mem_profile.fixed_alloc_size];
|
||||||
var fixed_allocator = std.heap.FixedBufferAllocator.init(buffer);
|
var fixed_allocator = std.heap.FixedBufferAllocator.init(buffer);
|
||||||
|
@ -56,6 +57,7 @@ export fn kmain(mb_info: *multiboot.multiboot_info_t, mb_magic: u32) void {
|
||||||
tty.init();
|
tty.init();
|
||||||
|
|
||||||
log.logInfo("Init done\n", .{});
|
log.logInfo("Init done\n", .{});
|
||||||
|
|
||||||
tty.print("Hello Pluto from kernel :)\n", .{});
|
tty.print("Hello Pluto from kernel :)\n", .{});
|
||||||
// The panic runtime tests must run last as they never return
|
// The panic runtime tests must run last as they never return
|
||||||
if (options.rt_test) panic_root.runtimeTests();
|
if (options.rt_test) panic_root.runtimeTests();
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
const serial = @import("serial.zig");
|
const serial = @import("serial.zig");
|
||||||
const fmt = @import("std").fmt;
|
const std = @import("std");
|
||||||
|
const fmt = std.fmt;
|
||||||
|
|
||||||
|
/// The errors that can occur when logging
|
||||||
|
const LoggingError = error{};
|
||||||
|
|
||||||
|
/// The OutStream for the format function
|
||||||
|
const OutStream = std.io.OutStream(void, LoggingError, logCallback);
|
||||||
|
|
||||||
pub const Level = enum {
|
pub const Level = enum {
|
||||||
INFO,
|
INFO,
|
||||||
|
@ -8,8 +15,9 @@ pub const Level = enum {
|
||||||
ERROR,
|
ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn logCallback(context: void, str: []const u8) anyerror!void {
|
fn logCallback(context: void, str: []const u8) LoggingError!usize {
|
||||||
serial.writeBytes(str, serial.Port.COM1);
|
serial.writeBytes(str, serial.Port.COM1);
|
||||||
|
return str.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -21,7 +29,7 @@ fn logCallback(context: void, str: []const u8) anyerror!void {
|
||||||
/// IN args: var - A struct of the parameters for the format string.
|
/// IN args: var - A struct of the parameters for the format string.
|
||||||
///
|
///
|
||||||
pub fn log(comptime level: Level, comptime format: []const u8, args: var) void {
|
pub fn log(comptime level: Level, comptime format: []const u8, args: var) void {
|
||||||
fmt.format({}, anyerror, logCallback, "[" ++ @tagName(level) ++ "] " ++ format, args) catch unreachable;
|
fmt.format(OutStream{ .context = {} }, "[" ++ @tagName(level) ++ "] " ++ format, args) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
|
@ -53,36 +53,6 @@ const FIXED_ALLOC_SIZE: usize = 1024 * 1024;
|
||||||
/// release-safe. This is a workaround until that is fixed.
|
/// release-safe. This is a workaround until that is fixed.
|
||||||
var ADDR_OFFSET: usize = undefined;
|
var ADDR_OFFSET: usize = undefined;
|
||||||
|
|
||||||
///
|
|
||||||
/// Initialise the system's memory profile based on linker symbols and the multiboot info struct.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// IN mb_info: *multiboot.multiboot_info_t - The multiboot info passed by the bootloader.
|
|
||||||
///
|
|
||||||
/// Return: MemProfile
|
|
||||||
/// The memory profile constructed from the exported linker symbols and the relevant multiboot info.
|
|
||||||
///
|
|
||||||
pub fn init(mb_info: *multiboot.multiboot_info_t) MemProfile {
|
|
||||||
log.logInfo("Init mem\n", .{});
|
|
||||||
defer log.logInfo("Done\n", .{});
|
|
||||||
const mods_count = mb_info.mods_count;
|
|
||||||
ADDR_OFFSET = @ptrToInt(&KERNEL_ADDR_OFFSET);
|
|
||||||
const mmap_addr = mb_info.mmap_addr;
|
|
||||||
const num_mmap_entries = mb_info.mmap_length / @sizeOf(multiboot.multiboot_memory_map_t);
|
|
||||||
const mem_profile = MemProfile{
|
|
||||||
.vaddr_end = @ptrCast([*]u8, &KERNEL_VADDR_END),
|
|
||||||
.vaddr_start = @ptrCast([*]u8, &KERNEL_VADDR_START),
|
|
||||||
.physaddr_end = @ptrCast([*]u8, &KERNEL_PHYSADDR_END),
|
|
||||||
.physaddr_start = @ptrCast([*]u8, &KERNEL_PHYSADDR_START),
|
|
||||||
// Total memory available including the initial 1MiB that grub doesn't include
|
|
||||||
.mem_kb = mb_info.mem_upper + mb_info.mem_lower + 1024,
|
|
||||||
.fixed_alloc_size = FIXED_ALLOC_SIZE,
|
|
||||||
.boot_modules = @intToPtr([*]multiboot.multiboot_mod_list, physToVirt(mb_info.mods_addr))[0..mods_count],
|
|
||||||
.mem_map = @intToPtr([*]multiboot.multiboot_memory_map_t, mmap_addr)[0..num_mmap_entries],
|
|
||||||
};
|
|
||||||
return mem_profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Convert a virtual address to its physical counterpart by subtracting the kernel virtual offset from the virtual address.
|
/// Convert a virtual address to its physical counterpart by subtracting the kernel virtual offset from the virtual address.
|
||||||
///
|
///
|
||||||
|
@ -94,7 +64,7 @@ pub fn init(mb_info: *multiboot.multiboot_info_t) MemProfile {
|
||||||
///
|
///
|
||||||
pub inline fn virtToPhys(virt: var) @TypeOf(virt) {
|
pub inline fn virtToPhys(virt: var) @TypeOf(virt) {
|
||||||
const T = @TypeOf(virt);
|
const T = @TypeOf(virt);
|
||||||
return switch (@typeId(T)) {
|
return switch (@typeInfo(T)) {
|
||||||
.Pointer => @intToPtr(T, @ptrToInt(virt) - ADDR_OFFSET),
|
.Pointer => @intToPtr(T, @ptrToInt(virt) - ADDR_OFFSET),
|
||||||
.Int => virt - ADDR_OFFSET,
|
.Int => virt - ADDR_OFFSET,
|
||||||
else => @compileError("Only pointers and integers are supported"),
|
else => @compileError("Only pointers and integers are supported"),
|
||||||
|
@ -112,13 +82,43 @@ pub inline fn virtToPhys(virt: var) @TypeOf(virt) {
|
||||||
///
|
///
|
||||||
pub inline fn physToVirt(phys: var) @TypeOf(phys) {
|
pub inline fn physToVirt(phys: var) @TypeOf(phys) {
|
||||||
const T = @TypeOf(phys);
|
const T = @TypeOf(phys);
|
||||||
return switch (@typeId(T)) {
|
return switch (@typeInfo(T)) {
|
||||||
.Pointer => @intToPtr(T, @ptrToInt(phys) + ADDR_OFFSET),
|
.Pointer => @intToPtr(T, @ptrToInt(phys) + ADDR_OFFSET),
|
||||||
.Int => phys + ADDR_OFFSET,
|
.Int => phys + ADDR_OFFSET,
|
||||||
else => @compileError("Only pointers and integers are supported"),
|
else => @compileError("Only pointers and integers are supported"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Initialise the system's memory profile based on linker symbols and the multiboot info struct.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN mb_info: *multiboot.multiboot_info_t - The multiboot info passed by the bootloader.
|
||||||
|
///
|
||||||
|
/// Return: MemProfile
|
||||||
|
/// The memory profile constructed from the exported linker symbols and the relevant multiboot info.
|
||||||
|
///
|
||||||
|
pub fn init(mb_info: *multiboot.multiboot_info_t) MemProfile {
|
||||||
|
log.logInfo("Init mem\n", .{});
|
||||||
|
defer log.logInfo("Done mem\n", .{});
|
||||||
|
|
||||||
|
const mods_count = mb_info.mods_count;
|
||||||
|
ADDR_OFFSET = @ptrToInt(&KERNEL_ADDR_OFFSET);
|
||||||
|
const mmap_addr = mb_info.mmap_addr;
|
||||||
|
const num_mmap_entries = mb_info.mmap_length / @sizeOf(multiboot.multiboot_memory_map_t);
|
||||||
|
return .{
|
||||||
|
.vaddr_end = @ptrCast([*]u8, &KERNEL_VADDR_END),
|
||||||
|
.vaddr_start = @ptrCast([*]u8, &KERNEL_VADDR_START),
|
||||||
|
.physaddr_end = @ptrCast([*]u8, &KERNEL_PHYSADDR_END),
|
||||||
|
.physaddr_start = @ptrCast([*]u8, &KERNEL_PHYSADDR_START),
|
||||||
|
// Total memory available including the initial 1MiB that grub doesn't include
|
||||||
|
.mem_kb = mb_info.mem_upper + mb_info.mem_lower + 1024,
|
||||||
|
.fixed_alloc_size = FIXED_ALLOC_SIZE,
|
||||||
|
.boot_modules = @intToPtr([*]multiboot.multiboot_mod_list, physToVirt(mb_info.mods_addr))[0..mods_count],
|
||||||
|
.mem_map = @intToPtr([*]multiboot.multiboot_memory_map_t, mmap_addr)[0..num_mmap_entries],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
test "physToVirt" {
|
test "physToVirt" {
|
||||||
ADDR_OFFSET = 0xC0000000;
|
ADDR_OFFSET = 0xC0000000;
|
||||||
const offset: usize = ADDR_OFFSET;
|
const offset: usize = ADDR_OFFSET;
|
||||||
|
|
|
@ -77,11 +77,11 @@ const SymbolMap = struct {
|
||||||
/// The function name associated with that program address, or null if one wasn't found.
|
/// The function name associated with that program address, or null if one wasn't found.
|
||||||
///
|
///
|
||||||
pub fn search(self: *const SymbolMap, addr: usize) ?[]const u8 {
|
pub fn search(self: *const SymbolMap, addr: usize) ?[]const u8 {
|
||||||
if (self.symbols.len == 0)
|
if (self.symbols.items.len == 0)
|
||||||
return null;
|
return null;
|
||||||
// Find the first element whose address is greater than addr
|
// Find the first element whose address is greater than addr
|
||||||
var previous_name: ?[]const u8 = null;
|
var previous_name: ?[]const u8 = null;
|
||||||
for (self.symbols.toSliceConst()) |entry| {
|
for (self.symbols.items) |entry| {
|
||||||
if (entry.addr > addr)
|
if (entry.addr > addr)
|
||||||
return previous_name;
|
return previous_name;
|
||||||
previous_name = entry.func_name;
|
previous_name = entry.func_name;
|
||||||
|
@ -116,7 +116,7 @@ pub fn panic(trace: ?*builtin.StackTrace, comptime format: []const u8, args: var
|
||||||
} else {
|
} else {
|
||||||
const first_ret_addr = @returnAddress();
|
const first_ret_addr = @returnAddress();
|
||||||
var last_addr: u64 = 0;
|
var last_addr: u64 = 0;
|
||||||
var it = std.debug.StackIterator.init(first_ret_addr);
|
var it = std.debug.StackIterator.init(first_ret_addr, null);
|
||||||
while (it.next()) |ret_addr| {
|
while (it.next()) |ret_addr| {
|
||||||
if (ret_addr != last_addr) logTraceAddress(ret_addr);
|
if (ret_addr != last_addr) logTraceAddress(ret_addr);
|
||||||
last_addr = ret_addr;
|
last_addr = ret_addr;
|
||||||
|
@ -278,7 +278,8 @@ fn parseMapEntry(start: *[*]const u8, end: *const u8) !MapEntry {
|
||||||
///
|
///
|
||||||
pub fn init(mem_profile: *const mem.MemProfile, allocator: *std.mem.Allocator) !void {
|
pub fn init(mem_profile: *const mem.MemProfile, allocator: *std.mem.Allocator) !void {
|
||||||
log.logInfo("Init panic\n", .{});
|
log.logInfo("Init panic\n", .{});
|
||||||
defer log.logInfo("Done\n", .{});
|
defer log.logInfo("Done panic\n", .{});
|
||||||
|
|
||||||
// Exit if we haven't loaded all debug modules
|
// Exit if we haven't loaded all debug modules
|
||||||
if (mem_profile.boot_modules.len < 1)
|
if (mem_profile.boot_modules.len < 1)
|
||||||
return;
|
return;
|
||||||
|
@ -288,7 +289,7 @@ pub fn init(mem_profile: *const mem.MemProfile, allocator: *std.mem.Allocator) !
|
||||||
const mod_start = mem.physToVirt(module.mod_start);
|
const mod_start = mem.physToVirt(module.mod_start);
|
||||||
const mod_end = mem.physToVirt(module.mod_end) - 1;
|
const mod_end = mem.physToVirt(module.mod_end) - 1;
|
||||||
const mod_str_ptr = mem.physToVirt(@intToPtr([*:0]u8, module.cmdline));
|
const mod_str_ptr = mem.physToVirt(@intToPtr([*:0]u8, module.cmdline));
|
||||||
if (std.mem.eql(u8, std.mem.toSlice(u8, mod_str_ptr), "kernel.map")) {
|
if (std.mem.eql(u8, std.mem.span(mod_str_ptr), "kernel.map")) {
|
||||||
kmap_start = mod_start;
|
kmap_start = mod_start;
|
||||||
kmap_end = mod_end;
|
kmap_end = mod_end;
|
||||||
break;
|
break;
|
||||||
|
@ -422,7 +423,7 @@ test "parseMapEntry fails without a name" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "SymbolMap" {
|
test "SymbolMap" {
|
||||||
var allocator = std.heap.direct_allocator;
|
var allocator = std.heap.page_allocator;
|
||||||
var map = SymbolMap.init(allocator);
|
var map = SymbolMap.init(allocator);
|
||||||
try map.add("abc"[0..], 123);
|
try map.add("abc"[0..], 123);
|
||||||
try map.addEntry(MapEntry{ .func_name = "def"[0..], .addr = 456 });
|
try map.addEntry(MapEntry{ .func_name = "def"[0..], .addr = 456 });
|
||||||
|
|
|
@ -91,6 +91,8 @@ pub fn free(addr: usize) (PmmBitmap.BitmapError || PmmError)!void {
|
||||||
///
|
///
|
||||||
pub fn init(mem: *const MemProfile, allocator: *std.mem.Allocator) void {
|
pub fn init(mem: *const MemProfile, allocator: *std.mem.Allocator) void {
|
||||||
log.logInfo("Init pmm\n", .{});
|
log.logInfo("Init pmm\n", .{});
|
||||||
|
defer log.logInfo("Done pmm\n", .{});
|
||||||
|
|
||||||
bitmap = PmmBitmap.init(mem.mem_kb * 1024 / BLOCK_SIZE, allocator) catch @panic("Bitmap allocation failed");
|
bitmap = PmmBitmap.init(mem.mem_kb * 1024 / BLOCK_SIZE, allocator) catch @panic("Bitmap allocation failed");
|
||||||
|
|
||||||
// Occupy the regions of memory that the memory map describes as reserved
|
// Occupy the regions of memory that the memory map describes as reserved
|
||||||
|
@ -118,10 +120,8 @@ pub fn init(mem: *const MemProfile, allocator: *std.mem.Allocator) void {
|
||||||
else => panic(@errorReturnTrace(), "Failed setting kernel code address 0x{x} as occupied: {}", .{ addr, e }),
|
else => panic(@errorReturnTrace(), "Failed setting kernel code address 0x{x} as occupied: {}", .{ addr, e }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
if (build_options.rt_test) {
|
if (build_options.rt_test) runtimeTests(mem);
|
||||||
runtimeTests(mem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -154,7 +154,7 @@ fn runtimeTests(mem: *const MemProfile) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "alloc" {
|
test "alloc" {
|
||||||
bitmap = try Bitmap(u32).init(32, std.heap.direct_allocator);
|
bitmap = try Bitmap(u32).init(32, std.heap.page_allocator);
|
||||||
comptime var addr = 0;
|
comptime var addr = 0;
|
||||||
comptime var i = 0;
|
comptime var i = 0;
|
||||||
// Allocate all entries, making sure they succeed and return the correct addresses
|
// Allocate all entries, making sure they succeed and return the correct addresses
|
||||||
|
@ -171,7 +171,7 @@ test "alloc" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "free" {
|
test "free" {
|
||||||
bitmap = try Bitmap(u32).init(32, std.heap.direct_allocator);
|
bitmap = try Bitmap(u32).init(32, std.heap.page_allocator);
|
||||||
comptime var i = 0;
|
comptime var i = 0;
|
||||||
// Allocate and free all entries
|
// Allocate and free all entries
|
||||||
inline while (i < 32) : (i += 1) {
|
inline while (i < 32) : (i += 1) {
|
||||||
|
@ -186,7 +186,7 @@ test "free" {
|
||||||
|
|
||||||
test "setAddr and isSet" {
|
test "setAddr and isSet" {
|
||||||
const num_entries: u32 = 32;
|
const num_entries: u32 = 32;
|
||||||
bitmap = try Bitmap(u32).init(num_entries, std.heap.direct_allocator);
|
bitmap = try Bitmap(u32).init(num_entries, std.heap.page_allocator);
|
||||||
var addr: u32 = 0;
|
var addr: u32 = 0;
|
||||||
var i: u32 = 0;
|
var i: u32 = 0;
|
||||||
while (i < num_entries) : ({
|
while (i < num_entries) : ({
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const arch = @import("arch.zig").internals;
|
const arch = @import("arch.zig").internals;
|
||||||
const panic = @import("panic.zig").panic;
|
const panic = @import("panic.zig").panic;
|
||||||
const testing = @import("std").testing;
|
const testing = @import("std").testing;
|
||||||
const options = @import("build_options");
|
const build_options = @import("build_options");
|
||||||
|
|
||||||
/// The I/O port numbers associated with each serial port
|
/// The I/O port numbers associated with each serial port
|
||||||
pub const Port = enum(u16) {
|
pub const Port = enum(u16) {
|
||||||
|
@ -147,12 +147,13 @@ pub fn init(baud: u32, port: Port) SerialError!void {
|
||||||
// Send the divisor's msb
|
// Send the divisor's msb
|
||||||
arch.outb(port_int + 1, @truncate(u8, divisor >> 8));
|
arch.outb(port_int + 1, @truncate(u8, divisor >> 8));
|
||||||
// Send the properties to use
|
// Send the properties to use
|
||||||
arch.outb(port_int + LCR, lcrValue(CHAR_LEN, SINGLE_STOP_BIT, PARITY_BIT, 0) catch |e| panic(@errorReturnTrace(), "Failed to setup serial properties: {}", .{e}));
|
arch.outb(port_int + LCR, lcrValue(CHAR_LEN, SINGLE_STOP_BIT, PARITY_BIT, 0) catch |e| {
|
||||||
|
panic(@errorReturnTrace(), "Failed to setup serial properties: {}", .{e});
|
||||||
|
});
|
||||||
// Stop initialisation
|
// Stop initialisation
|
||||||
arch.outb(port_int + 1, 0);
|
arch.outb(port_int + 1, 0);
|
||||||
|
|
||||||
if (options.rt_test)
|
if (build_options.rt_test) runtimeTests();
|
||||||
runtimeTests();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "lcrValue computes the correct value" {
|
test "lcrValue computes the correct value" {
|
||||||
|
|
|
@ -11,6 +11,9 @@ const vga = if (is_test) @import(mock_path ++ "vga_mock.zig") else @import("vga.
|
||||||
const log = if (is_test) @import(mock_path ++ "log_mock.zig") else @import("log.zig");
|
const log = if (is_test) @import(mock_path ++ "log_mock.zig") else @import("log.zig");
|
||||||
const panic = if (is_test) @import(mock_path ++ "panic_mock.zig").panic else @import("panic.zig").panic;
|
const panic = if (is_test) @import(mock_path ++ "panic_mock.zig").panic else @import("panic.zig").panic;
|
||||||
|
|
||||||
|
/// The OutStream for the format function
|
||||||
|
const OutStream = std.io.OutStream(void, TtyError, printCallback);
|
||||||
|
|
||||||
/// The error set for if there is an error whiles printing.
|
/// The error set for if there is an error whiles printing.
|
||||||
const TtyError = error{
|
const TtyError = error{
|
||||||
/// If the printing tries to print outside the video buffer.
|
/// If the printing tries to print outside the video buffer.
|
||||||
|
@ -427,8 +430,9 @@ fn printLogo() void {
|
||||||
/// Errors:
|
/// Errors:
|
||||||
/// TtyError.OutOfBounds - If trying to print beyond the video buffer.
|
/// TtyError.OutOfBounds - If trying to print beyond the video buffer.
|
||||||
///
|
///
|
||||||
fn printCallback(ctx: void, str: []const u8) TtyError!void {
|
fn printCallback(ctx: void, str: []const u8) TtyError!usize {
|
||||||
try writeString(str);
|
try writeString(str);
|
||||||
|
return str.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -441,7 +445,7 @@ fn printCallback(ctx: void, str: []const u8) TtyError!void {
|
||||||
///
|
///
|
||||||
pub fn print(comptime format: []const u8, args: var) void {
|
pub fn print(comptime format: []const u8, args: var) void {
|
||||||
// Printing can't error because of the scrolling, if it does, we have a big problem
|
// Printing can't error because of the scrolling, if it does, we have a big problem
|
||||||
fmt.format({}, TtyError, printCallback, format, args) catch |e| {
|
fmt.format(OutStream{ .context = {} }, format, args) catch |e| {
|
||||||
log.logError("TTY: Error printing. Error: {}\n", .{e});
|
log.logError("TTY: Error printing. Error: {}\n", .{e});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -570,6 +574,7 @@ pub fn getVideoBufferAddress() usize {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init tty\n", .{});
|
log.logInfo("Init tty\n", .{});
|
||||||
|
defer log.logInfo("Done tty\n", .{});
|
||||||
|
|
||||||
// Video buffer in higher half
|
// Video buffer in higher half
|
||||||
if (is_test) {
|
if (is_test) {
|
||||||
|
@ -631,8 +636,6 @@ pub fn init() void {
|
||||||
displayPageNumber();
|
displayPageNumber();
|
||||||
updateCursor();
|
updateCursor();
|
||||||
|
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,6 @@ inline fn sendData(data: u8) void {
|
||||||
inline fn getData() u8 {
|
inline fn getData() u8 {
|
||||||
return arch.inb(PORT_DATA);
|
return arch.inb(PORT_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set the VGA register port to write to and sending data to that VGA register port.
|
/// Set the VGA register port to write to and sending data to that VGA register port.
|
||||||
///
|
///
|
||||||
|
@ -287,6 +286,7 @@ pub fn setCursorShape(shape: CursorShape) void {
|
||||||
///
|
///
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
log.logInfo("Init vga\n", .{});
|
log.logInfo("Init vga\n", .{});
|
||||||
|
defer log.logInfo("Done vga\n", .{});
|
||||||
|
|
||||||
// Set the maximum scan line to 0x0F
|
// Set the maximum scan line to 0x0F
|
||||||
sendPortData(REG_MAXIMUM_SCAN_LINE, CURSOR_SCANLINE_END);
|
sendPortData(REG_MAXIMUM_SCAN_LINE, CURSOR_SCANLINE_END);
|
||||||
|
@ -294,8 +294,6 @@ pub fn init() void {
|
||||||
// Set by default the underline cursor
|
// Set by default the underline cursor
|
||||||
setCursorShape(CursorShape.UNDERLINE);
|
setCursorShape(CursorShape.UNDERLINE);
|
||||||
|
|
||||||
log.logInfo("Done\n", .{});
|
|
||||||
|
|
||||||
if (build_options.rt_test) runtimeTests();
|
if (build_options.rt_test) runtimeTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,39 @@
|
||||||
def get_test_cases(TestCase):
|
def get_test_cases(TestCase):
|
||||||
return [
|
return [
|
||||||
TestCase("GDT init", [r"Init gdt", r"Done"]),
|
TestCase("GDT init", [r"Init gdt"]),
|
||||||
TestCase("GDT tests", [r"GDT: Tested loading GDT"]),
|
TestCase("GDT tests", [r"GDT: Tested loading GDT"]),
|
||||||
TestCase("IDT init", [r"Init idt", r"Done"]),
|
TestCase("GDT done", [r"Done gdt"]),
|
||||||
|
|
||||||
|
TestCase("IDT init", [r"Init idt"]),
|
||||||
TestCase("IDT tests", [r"IDT: Tested loading IDT"]),
|
TestCase("IDT tests", [r"IDT: Tested loading IDT"]),
|
||||||
TestCase("PIC init", [r"Init pic", r"Done"]),
|
TestCase("IDT done", [r"Done idt"]),
|
||||||
|
|
||||||
|
TestCase("PIC init", [r"Init pic"]),
|
||||||
TestCase("PIC tests", [r"PIC: Tested masking"]),
|
TestCase("PIC tests", [r"PIC: Tested masking"]),
|
||||||
TestCase("ISR init", [r"Init isr", r"Done"]),
|
TestCase("PIC done", [r"Done pic"]),
|
||||||
|
|
||||||
|
TestCase("ISR init", [r"Init isr"]),
|
||||||
TestCase("ISR tests", [r"ISR: Tested registered handlers", r"ISR: Tested opened IDT entries"]),
|
TestCase("ISR tests", [r"ISR: Tested registered handlers", r"ISR: Tested opened IDT entries"]),
|
||||||
TestCase("IRQ init", [r"Init irq", r"Done"]),
|
TestCase("ISR done", [r"Done isr"]),
|
||||||
|
|
||||||
|
TestCase("IRQ init", [r"Init irq"]),
|
||||||
TestCase("IRQ tests", [r"IRQ: Tested registered handlers", r"IRQ: Tested opened IDT entries"]),
|
TestCase("IRQ tests", [r"IRQ: Tested registered handlers", r"IRQ: Tested opened IDT entries"]),
|
||||||
TestCase("Paging init", [r"Init paging", r"Done"]),
|
TestCase("IRQ done", [r"Done irq"]),
|
||||||
|
|
||||||
|
TestCase("Paging init", [r"Init paging"]),
|
||||||
TestCase("Paging tests", [r"Paging: Tested accessing unmapped memory", r"Paging: Tested accessing mapped memory"]),
|
TestCase("Paging tests", [r"Paging: Tested accessing unmapped memory", r"Paging: Tested accessing mapped memory"]),
|
||||||
|
TestCase("Paging done", [r"Done paging"]),
|
||||||
|
|
||||||
TestCase("PIT init", [r"Init pit"]),
|
TestCase("PIT init", [r"Init pit"]),
|
||||||
TestCase("PIT init", [r".+"], r"\[DEBUG\] "),
|
TestCase("PIT init", [r".+"], r"\[DEBUG\] "),
|
||||||
TestCase("PIT init", [r"Done"]),
|
|
||||||
TestCase("PIT tests", [r"PIT: Tested init", r"PIT: Tested wait ticks", r"PIT: Tested wait ticks 2"]),
|
TestCase("PIT tests", [r"PIT: Tested init", r"PIT: Tested wait ticks", r"PIT: Tested wait ticks 2"]),
|
||||||
TestCase("RTC init", [r"Init rtc", r"Done"]),
|
TestCase("PIT done", [r"Done pit"]),
|
||||||
|
|
||||||
|
TestCase("RTC init", [r"Init rtc"]),
|
||||||
TestCase("RTC tests", [r"RTC: Tested init", r"RTC: Tested interrupts"]),
|
TestCase("RTC tests", [r"RTC: Tested init", r"RTC: Tested interrupts"]),
|
||||||
TestCase("Syscalls init", [r"Init syscalls", r"Done"]),
|
TestCase("RTC done", [r"Done rtc"]),
|
||||||
TestCase("Syscall tests", [r"Syscalls: Tested no args", r"Syscalls: Tested 1 arg", r"Syscalls: Tested 2 args", r"Syscalls: Tested 3 args", r"Syscalls: Tested 4 args", r"Syscalls: Tested 5 args"])
|
|
||||||
|
TestCase("Syscalls init", [r"Init syscalls"]),
|
||||||
|
TestCase("Syscalls tests", [r"Syscalls: Tested no args", r"Syscalls: Tested 1 arg", r"Syscalls: Tested 2 args", r"Syscalls: Tested 3 args", r"Syscalls: Tested 4 args", r"Syscalls: Tested 5 args"]),
|
||||||
|
TestCase("Syscalls done", [r"Done syscalls"]),
|
||||||
]
|
]
|
||||||
|
|
|
@ -31,26 +31,40 @@ def test_pass(case, exp, expected_idx, found):
|
||||||
def get_pre_archinit_cases():
|
def get_pre_archinit_cases():
|
||||||
return [
|
return [
|
||||||
TestCase("Serial tests", [r"c", r"123"], ""),
|
TestCase("Serial tests", [r"c", r"123"], ""),
|
||||||
TestCase("Log info tests", [r"Test INFO level", r"Test INFO level with args a, 1", r"Test INFO function", r"Test INFO function with args a, 1"], "\[INFO\] "),
|
|
||||||
TestCase("Log debug tests", [r"Test DEBUG level", r"Test DEBUG level with args a, 1", r"Test DEBUG function", r"Test DEBUG function with args a, 1"], "\[DEBUG\] "),
|
TestCase("Log info tests", [r"Test INFO level", r"Test INFO level with args a, 1", r"Test INFO function", r"Test INFO function with args a, 1"], r"\[INFO\] "),
|
||||||
TestCase("Log warning tests", [r"Test WARNING level", r"Test WARNING level with args a, 1", r"Test WARNING function", r"Test WARNING function with args a, 1"], "\[WARNING\] "),
|
TestCase("Log debug tests", [r"Test DEBUG level", r"Test DEBUG level with args a, 1", r"Test DEBUG function", r"Test DEBUG function with args a, 1"], r"\[DEBUG\] "),
|
||||||
TestCase("Log error tests", [r"Test ERROR level", r"Test ERROR level with args a, 1", r"Test ERROR function", r"Test ERROR function with args a, 1"], "\[ERROR\] "),
|
TestCase("Log warning tests", [r"Test WARNING level", r"Test WARNING level with args a, 1", r"Test WARNING function", r"Test WARNING function with args a, 1"], r"\[WARNING\] "),
|
||||||
TestCase("Mem init", [r"Init mem", r"Done"]),
|
TestCase("Log error tests", [r"Test ERROR level", r"Test ERROR level with args a, 1", r"Test ERROR function", r"Test ERROR function with args a, 1"], r"\[ERROR\] "),
|
||||||
TestCase("PMM init", [r"Init pmm", r"Done"]),
|
|
||||||
|
TestCase("Mem init", [r"Init mem"]),
|
||||||
|
TestCase("Mem done", [r"Done mem"]),
|
||||||
|
|
||||||
|
TestCase("PMM init", [r"Init pmm"]),
|
||||||
TestCase("PMM tests", [r"PMM: Tested allocation"]),
|
TestCase("PMM tests", [r"PMM: Tested allocation"]),
|
||||||
|
TestCase("PMM done", [r"Done pmm"]),
|
||||||
|
|
||||||
TestCase("Arch init starts", [r"Init arch \w+"])
|
TestCase("Arch init starts", [r"Init arch \w+"])
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_post_archinit_cases():
|
def get_post_archinit_cases():
|
||||||
return [
|
return [
|
||||||
TestCase("Arch init finishes", [r"Arch init done"]),
|
TestCase("Arch init finishes", [r"Arch init done"]),
|
||||||
TestCase("Panic init", [r"Init panic", r"Done"]),
|
|
||||||
TestCase("VGA init", [r"Init vga", r"Done"]),
|
TestCase("Panic init", [r"Init panic"]),
|
||||||
|
TestCase("Panic done", [r"Done panic"]),
|
||||||
|
|
||||||
|
TestCase("VGA init", [r"Init vga"]),
|
||||||
TestCase("VGA tests", [r"VGA: Tested max scan line", r"VGA: Tested cursor shape", r"VGA: Tested updating cursor"]),
|
TestCase("VGA tests", [r"VGA: Tested max scan line", r"VGA: Tested cursor shape", r"VGA: Tested updating cursor"]),
|
||||||
TestCase("TTY init", [r"Init tty", r"Done"]),
|
TestCase("VGA done", [r"Done vga"]),
|
||||||
|
|
||||||
|
TestCase("TTY init", [r"Init tty"]),
|
||||||
TestCase("TTY tests", [r"TTY: Tested globals", r"TTY: Tested printing"]),
|
TestCase("TTY tests", [r"TTY: Tested globals", r"TTY: Tested printing"]),
|
||||||
|
TestCase("TTY done", [r"Done tty"]),
|
||||||
|
|
||||||
TestCase("Init finishes", [r"Init done"]),
|
TestCase("Init finishes", [r"Init done"]),
|
||||||
TestCase("Panic tests", [r"Kernel panic: integer overflow", r"c[a-z\d]+: panic", r"c[a-z\d]+: panic.runtimeTests", r"c[a-z\d]+: kmain", r"c[a-z\d]+: start_higher_half"], "\[ERROR\] ")
|
|
||||||
|
TestCase("Panic tests", [r"Kernel panic: integer overflow", r"c[a-z\d]+: panic", r"c[a-z\d]+: panic.runtimeTests", r"c[a-z\d]+: kmain", r"c[a-z\d]+: start_higher_half"], r"\[ERROR\] ")
|
||||||
]
|
]
|
||||||
|
|
||||||
def read_messages(proc):
|
def read_messages(proc):
|
||||||
|
|
Loading…
Reference in a new issue