diff --git a/kobold/build.zig b/kobold/build.zig index 17efaae..c325c75 100644 --- a/kobold/build.zig +++ b/kobold/build.zig @@ -75,7 +75,7 @@ pub fn build(b: *std.Build) void { targetQuery.os_tag = .freestanding; targetQuery.abi = .none; const resolvedTarget = b.resolveTargetQuery(targetQuery); - const resolvedModTarget = b.resolveTargetQuery(modTargetQuery); + //const resolvedModTarget = b.resolveTargetQuery(modTargetQuery); const optimize = b.standardOptimizeOption(.{}); const perlibMod = b.addModule("perlib", .{ @@ -129,27 +129,27 @@ pub fn build(b: *std.Build) void { halMod.addObjectFile(b.path("../lowlevel.o")); } - const personalityDir = std.fs.cwd().openDir("personalities", .{ .iterate = true }) catch @panic("Couldn't retrieve personalities!"); - var iter = personalityDir.iterate(); - while (iter.next() catch @panic("Personality Iteration Failure")) |entry| { - if (entry.kind == .directory) { - const mainZig = b.fmt("personalities/{s}/main.zig", .{entry.name}); - _ = std.fs.cwd().access(mainZig, .{}) catch continue; - const personality = b.addObject(.{ - .name = entry.name, - .root_source_file = b.path(mainZig), - .target = resolvedModTarget, - .optimize = optimize, - .code_model = .large, - .strip = true, - }); - if (getArch(board) == .riscv64) { - personality.root_module.code_model = .medium; - } - personality.root_module.addImport("perlib", perlibMod); - //b.getInstallStep().dependOn(addInstallObjectFile(b, personality, entry.name)); - } - } + //const personalityDir = std.fs.cwd().openDir("personalities", .{ .iterate = true }) catch @panic("Couldn't retrieve personalities!"); + //var iter = personalityDir.iterate(); + //while (iter.next() catch @panic("Personality Iteration Failure")) |entry| { + // if (entry.kind == .directory) { + // const mainZig = b.fmt("personalities/{s}/main.zig", .{entry.name}); + // _ = std.fs.cwd().access(mainZig, .{}) catch continue; + // const personality = b.addObject(.{ + // .name = entry.name, + // .root_source_file = b.path(mainZig), + // .target = resolvedModTarget, + // .optimize = optimize, + // .code_model = .large, + // .strip = true, + // }); + // if (getArch(board) == .riscv64) { + // personality.root_module.code_model = .medium; + // } + // personality.root_module.addImport("perlib", perlibMod); + // //b.getInstallStep().dependOn(addInstallObjectFile(b, personality, entry.name)); + // } + //} kernel.want_lto = false; kernel.root_module.omit_frame_pointer = false; diff --git a/kobold/hal/debug/debug.zig b/kobold/hal/debug/debug.zig index c475f39..7ad023f 100644 --- a/kobold/hal/debug/debug.zig +++ b/kobold/hal/debug/debug.zig @@ -96,6 +96,43 @@ pub fn backtraceCommand(cmd: []const u8, iter: *std.mem.SplitIterator(u8, .seque PrintBacktrace(@returnAddress()); } +pub fn dbCommand(cmd: []const u8, iter: *std.mem.SplitIterator(u8, .sequence)) void { + _ = cmd; + const addrO = iter.next(); + const sizeO = iter.next(); + if (addrO != null and sizeO != null) { + const range: std.bit_set.Range = .{ .start = std.fmt.parseInt(usize, addrO.?, 0) catch 0, .end = std.fmt.parseInt(usize, sizeO.?, 0) catch 0 }; + const slice = @as([*]const u8, @ptrFromInt(range.start))[0..range.end]; + var chunks = std.mem.window(u8, slice, 16, 16); + while (chunks.next()) |window| { + const address = (@intFromPtr(slice.ptr) + 0x10 * (chunks.index orelse 0) / 16) - 0x10; + std.log.debug("{x:0>[1]} ", .{ address, @sizeOf(usize) * 2 }); + for (window, 0..) |byte, index| { + std.log.debug("{X:0>2} ", .{byte}); + if (index == 7) std.log.debug(" ", .{}); + } + std.log.debug(" ", .{}); + if (window.len < 16) { + var missing_columns = (16 - window.len) * 3; + if (window.len < 8) missing_columns += 1; + for (0..missing_columns) |_| { + std.log.debug(" ", .{}); + } + } + for (window) |byte| { + if (std.ascii.isPrint(byte)) { + std.log.debug("{c}", .{byte}); + } else { + std.log.debug(".", .{}); + } + } + std.log.debug("\n", .{}); + } + } else { + std.log.debug("Usage: db \n", .{}); + } +} + pub fn sbCommand(cmd: []const u8, iter: *std.mem.SplitIterator(u8, .sequence)) void { _ = cmd; if (iter.peek() != null) { @@ -229,6 +266,7 @@ pub fn symsCommand(cmd: []const u8, iter: *std.mem.SplitIterator(u8, .sequence)) pub fn DebugInit() void { NewDebugCommand("help", "Prints this message", &helpCommand); NewDebugCommand("bt", "Prints a Stack Backtrace", &backtraceCommand); + NewDebugCommand("db", "Dump hex data (in byte sizes) within a given range", &dbCommand); NewDebugCommand("sb", "Dump hex data (in byte sizes) within a given symbol", &sbCommand); NewDebugCommand("sn", "Dump number within a given symbol", &snCommand); NewDebugCommand("si", "Disassembles the given symbol", &siCommand); diff --git a/kobold/hal/memmodel.zig b/kobold/hal/memmodel.zig index a6374e8..d089276 100644 --- a/kobold/hal/memmodel.zig +++ b/kobold/hal/memmodel.zig @@ -1,8 +1,10 @@ const std = @import("std"); const hal = @import("hal.zig"); const builtin = @import("builtin"); +const physmem = @import("root").physmem; +const pfn = @import("root").pfn; -pub const PageDirectory = *anyopaque; +pub const PageDirectory = [*]usize; pub const LayoutType = enum { Flat, @@ -74,3 +76,48 @@ pub const MemoryModel = struct { changeTable: ?fn (usize) void = null, invalPage: ?fn (usize) void = null, }; + +pub fn MapPage(root: PageDirectory, vaddr: usize, frame: HALPageFrame) usize { + var i: usize = 0; + var entries: [*]usize = root; + while (i < hal.arch.memModel.layout.layerCount()) : (i += 1) { + const index: u64 = (vaddr >> (39 - @as(u6, @intCast(i * 9)))) & 0x1ff; + var entry = hal.arch.memModel.nativeToHal.?(entries[index], i + 1 < hal.arch.memModel.layout.layerCount()); + if (i + 1 < hal.arch.memModel.layout.layerCount()) { + entries[index] = hal.arch.memModel.halToNative.?(frame); + if (hal.arch.memModel.invalPage) |inval| { + inval(vaddr); + } + if (frame.valid == 0 and entry.valid == 1) { + if (pfn.DereferencePage(@intFromPtr(entries))) { + physmem.Free(@intFromPtr(entries), 4096); + } + } else if (frame.valid == 1 and entry.valid == 0) { + pfn.ReferencePage(@intFromPtr(entries), 1, .noChange); + } + return @intFromPtr(&entries[index]); + } else { + if (entry.valid != 1) { + // Allocate a new Page Table + const page = physmem.Allocate(0x1000, 0x1000).?; + pfn.ReferencePage(@intFromPtr(page), 0, .pageTable); + pfn.SetPagePTE(@intFromPtr(page), @intFromPtr(&entries[index]) & 0x7fff_ffff_ffff); + entry.valid = 1; + entry.read = 0; // no rwx = branch page + entry.write = 0; + entry.execute = 0; + entry.user = frame.user; + entry.noCache = 0; + entry.writeComb = 0; + entry.writeThru = 0; + entry.reserved = 0; + entry.phys = @truncate((page & 0x7fff_ffff_f000) >> 12); + entries[index] = hal.arch.memModel.halToNative.?(entry); + pfn.ReferencePage(@intFromPtr(entries), 1, .noChange); + entries = @as([*]usize, @ptrFromInt(@intFromPtr(page))); + } else { + entries = @as([*]usize, @ptrFromInt((@as(usize, @intCast(entry.phys)) << 12) + 0xffff800000000000)); + } + } + } +} diff --git a/kobold/hal/x86_64/main.zig b/kobold/hal/x86_64/main.zig index 290622c..a2bd1a7 100644 --- a/kobold/hal/x86_64/main.zig +++ b/kobold/hal/x86_64/main.zig @@ -326,6 +326,7 @@ fn fthConvert(pte: usize, high: bool) hal.memmodel.HALPageFrame { // high set if frame.read = if (branch) 0 else (pte & 1); frame.write = if (branch) 0 else ((pte >> 1) & 1); frame.execute = if (branch) 0 else (((~pte) >> 63) & 1); + frame.user = (pte >> 2) & 1; frame.noCache = (pte >> 4) & 1; frame.writeThru = (pte >> 3) & 1; if (high) { diff --git a/kobold/hal/x86_64/timer.zig b/kobold/hal/x86_64/timer.zig index fe39c72..6ffa2ed 100644 --- a/kobold/hal/x86_64/timer.zig +++ b/kobold/hal/x86_64/timer.zig @@ -75,7 +75,7 @@ pub fn init() void { //apic.write(0x320, 0x10000); //const count = 0xffffffff - apic.read(0x390); ticksPerSecond = @as(u64, @intFromFloat(correctedBase * 1000)); - } else { + } else { // 65520 const freq: f64 = 105000000.0 / 88.0 / 65536.0; timer_log.info("PIT @ ~{} Hz for APIC Timer Calibration", .{freq}); var speakerControlByte = io.inb(0x61); diff --git a/kobold/kernel/pfn.zig b/kobold/kernel/pfn.zig index 3683f4e..e5aaac9 100644 --- a/kobold/kernel/pfn.zig +++ b/kobold/kernel/pfn.zig @@ -2,23 +2,95 @@ const std = @import("std"); const hal = @import("root").hal; const physmem = @import("physmem.zig"); +const Spinlock = @import("spinlock.zig").Spinlock; -var pfn: ?[]PFNEntry = null; -var pfnBaseAddr: usize = 0; +pub var pfn: ?[]PFNEntry = null; +pub var pfnBaseAddr: usize = 0; +pub var pfnSpinlock: Spinlock = .unaquired; pub const PFNEntryType = enum(u8) { gpp = 0, // General Purpose Page reserved = 1, // Memory that will never be reclaimed pageTable = 2, // Memory Reserved for a branch of a page table pageDir = 3, // Memory Reserved for the trunk of a page table + noChange = 255, // Not used on the PFN, but tells ReferencePage to not change the entry type }; pub const PFNEntry = packed struct { ref: usize, pte: u56, pfnType: PFNEntryType, + + comptime { + if (@sizeOf(@This()) != 16) { + @compileError("PFNEntry Size != 16!"); + } + } }; +pub fn GetEntry(a: usize) ?*PFNEntry { + const addr = a & 0x7fff_ffff_f000; + if (pfn.?) |p| { + if (addr >= pfnBaseAddr and addr < pfnBaseAddr + (p.len * 4096)) { + return &p[(addr - pfnBaseAddr) >> 12]; + } + } + return null; +} + +pub fn SetPagePTE(addr: usize, pte: usize) void { + const old = hal.arch.intControl(false); + pfnSpinlock.acquire(); + const entry = GetEntry(addr); + if (entry) |e| { + e.pte = @truncate(pte); + } + pfnSpinlock.release(); + _ = hal.arch.intControl(old); +} + +pub fn ReferencePage(addr: usize, ref: usize, tag: PFNEntryType) void { + const old = hal.arch.intControl(false); + pfnSpinlock.acquire(); + const entry = GetEntry(addr); + if (entry) |e| { + e.ref += ref; + if (tag != .noChange) { + e.pfnType = tag; + } + } + pfnSpinlock.release(); + _ = hal.arch.intControl(old); +} + +pub fn DerferencePage(addr: usize) bool { + const old = hal.arch.intControl(false); + pfnSpinlock.acquire(); + const entry = GetEntry(addr); + if (entry) |e| { + if (e.refs == 0) { + const oldState = e.pfnType; + e.pfnType = .gpp; + if (e.pte != 0 and oldState == .pageTable) { + const pt: usize = (e.pte & (~@as(usize, @intCast(0xFFF)))) + 0xffff8000_00000000; + @as(*usize, @ptrFromInt(entry)).* = 0; + pfnSpinlock.release(); + if (DerferencePage(pt)) { + physmem.Free(pt, 4096); + } + _ = hal.arch.intControl(old); + return true; + } + pfnSpinlock.release(); + _ = hal.arch.intControl(old); + return true; + } + } + pfnSpinlock.release(); + _ = hal.arch.intControl(old); + return false; +} + pub fn init(base: u64, entries: usize) void { hal.debug.DebugInit(); physmem.DebugInit(); diff --git a/kobold/personalities/ACPI/main.zig b/kobold/personalities/ACPI/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/AHCI/main.zig b/kobold/personalities/AHCI/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/DiskScheme/main.zig b/kobold/personalities/DiskScheme/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/FramebufferScheme/main.zig b/kobold/personalities/FramebufferScheme/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/HIDScheme/main.zig b/kobold/personalities/HIDScheme/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/KoboldFS/main.zig b/kobold/personalities/KoboldFS/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/NVMe/main.zig b/kobold/personalities/NVMe/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/NVMe/nvme.zig b/kobold/personalities/NVMe/nvme.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/PCI/legacypc.zig b/kobold/personalities/PCI/legacypc.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/PCI/main.zig b/kobold/personalities/PCI/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/PCI/pci.zig b/kobold/personalities/PCI/pci.zig deleted file mode 100644 index 9df090d..0000000 --- a/kobold/personalities/PCI/pci.zig +++ /dev/null @@ -1,22 +0,0 @@ -const PCI_VENDOR_ID: u16 = 0x00; -const PCI_DEVICE_ID: u16 = 0x02; -const PCI_COMMAND: u16 = 0x04; -const PCI_STATUS: u16 = 0x06; -const PCI_REVISION_ID: u16 = 0x08; -const PCI_SUBSYSTEM_ID: u16 = 0x2e; -const PCI_PROG_IF: u16 = 0x09; -const PCI_SUBCLASS: u16 = 0x0a; -const PCI_CLASS: u16 = 0x0b; -const PCI_CACHE_LINE_SIZE: u16 = 0x0c; -const PCI_LATENCY_TIMER: u16 = 0x0d; -const PCI_HEADER_TYPE: u16 = 0x0e; -const PCI_BIST: u16 = 0x0f; -const PCI_BAR0: u16 = 0x10; -const PCI_BAR1: u16 = 0x14; -const PCI_BAR2: u16 = 0x18; -const PCI_BAR3: u16 = 0x1c; -const PCI_BAR4: u16 = 0x20; -const PCI_BAR5: u16 = 0x24; -const PCI_INTERRUPT_LINE: u16 = 0x3c; -const PCI_INTERRUPT_PIN: u16 = 0x3d; -const PCI_SECONDARY_BUS: u16 = 0x19; diff --git a/kobold/personalities/PCI/pcie.zig b/kobold/personalities/PCI/pcie.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/PersonalityList/universal b/kobold/personalities/PersonalityList/universal deleted file mode 100644 index dfc47ea..0000000 --- a/kobold/personalities/PersonalityList/universal +++ /dev/null @@ -1,13 +0,0 @@ -PCI -ext2FS -KoboldFS -USBStack -DiskScheme -HIDScheme -UserIPCScheme -NVMe -USBHID -USBMass -UNIXFileScheme -SoundScheme -FramebufferScheme \ No newline at end of file diff --git a/kobold/personalities/PersonalityList/x86_64-pc b/kobold/personalities/PersonalityList/x86_64-pc deleted file mode 100644 index 9669bf7..0000000 --- a/kobold/personalities/PersonalityList/x86_64-pc +++ /dev/null @@ -1,6 +0,0 @@ -ACPI -i8042HID -AHCI -UHCI -xHCI -IDE \ No newline at end of file diff --git a/kobold/personalities/SoundScheme/main.zig b/kobold/personalities/SoundScheme/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/UNIXFileScheme/main.zig b/kobold/personalities/UNIXFileScheme/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/USBHID/main.zig b/kobold/personalities/USBHID/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/USBMass/main.zig b/kobold/personalities/USBMass/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/USBStack/main.zig b/kobold/personalities/USBStack/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/UserIPCScheme/main.zig b/kobold/personalities/UserIPCScheme/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/ext2FS/main.zig b/kobold/personalities/ext2FS/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/i8042HID/main.zig b/kobold/personalities/i8042HID/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/xHCI/main.zig b/kobold/personalities/xHCI/main.zig deleted file mode 100644 index e69de29..0000000 diff --git a/kobold/personalities/xHCI/xhci.zig b/kobold/personalities/xHCI/xhci.zig deleted file mode 100644 index 0f8c30b..0000000 --- a/kobold/personalities/xHCI/xhci.zig +++ /dev/null @@ -1,33 +0,0 @@ -pub const XHCICapRegs = extern struct { - caplength: u8 align(1) = undefined, - reserved: u8 align(1) = undefined, - version: u16 align(1) = undefined, - hcsparams1: u32 align(1) = undefined, - hcsparams2: u32 align(1) = undefined, - hcsparams3: u32 align(1) = undefined, - hccparams1: u32 align(1) = undefined, - dboff: u32 align(1) = undefined, - rtsoff: u32 align(1) = undefined, - hccparams2: u32 align(1) = undefined, -}; - -pub const XHCIPortRegs = extern struct { - portsc: u32 align(4) = undefined, - portpmsc: u32 align(1) = undefined, - portli: u32 align(1) = undefined, - reserved: u32 align(1) = undefined, -}; - -pub const XHCIOperationRegs = extern struct { - usbcmd: u32 align(8) = undefined, - usbsts: u32 align(1) = undefined, - page_size: u32 align(1) = undefined, - reserved1: [0x14 - 0x0C]u8 align(1) = undefined, - dnctrl: u32 align(1) = undefined, - crcr: u64 align(1) = undefined, - reserved2: [0x30 - 0x20]u8 align(1) = undefined, - dcbaap: u64 align(1) = undefined, - config: u32 align(1) = undefined, - reserved3: [964]u8 align(1) = undefined, - ports: [256]XHCIPortRegs align(4) = undefined, -};