Skip to content

Commit

Permalink
Page mapping and some other things
Browse files Browse the repository at this point in the history
Signed-off-by: TalonFloof <[email protected]>
  • Loading branch information
TalonFloof committed Nov 30, 2024
1 parent e0ed0ad commit 299d537
Show file tree
Hide file tree
Showing 30 changed files with 184 additions and 100 deletions.
44 changes: 22 additions & 22 deletions kobold/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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", .{
Expand Down Expand Up @@ -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;
Expand Down
38 changes: 38 additions & 0 deletions kobold/hal/debug/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 <addr> <size>\n", .{});
}
}

pub fn sbCommand(cmd: []const u8, iter: *std.mem.SplitIterator(u8, .sequence)) void {
_ = cmd;
if (iter.peek() != null) {
Expand Down Expand Up @@ -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);
Expand Down
49 changes: 48 additions & 1 deletion kobold/hal/memmodel.zig
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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));
}
}
}
}
1 change: 1 addition & 0 deletions kobold/hal/x86_64/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion kobold/hal/x86_64/timer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
76 changes: 74 additions & 2 deletions kobold/kernel/pfn.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Empty file removed kobold/personalities/ACPI/main.zig
Empty file.
Empty file removed kobold/personalities/AHCI/main.zig
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file removed kobold/personalities/NVMe/main.zig
Empty file.
Empty file removed kobold/personalities/NVMe/nvme.zig
Empty file.
Empty file.
Empty file removed kobold/personalities/PCI/main.zig
Empty file.
22 changes: 0 additions & 22 deletions kobold/personalities/PCI/pci.zig

This file was deleted.

Empty file removed kobold/personalities/PCI/pcie.zig
Empty file.
13 changes: 0 additions & 13 deletions kobold/personalities/PersonalityList/universal

This file was deleted.

6 changes: 0 additions & 6 deletions kobold/personalities/PersonalityList/x86_64-pc

This file was deleted.

Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file removed kobold/personalities/xHCI/main.zig
Empty file.
33 changes: 0 additions & 33 deletions kobold/personalities/xHCI/xhci.zig

This file was deleted.

0 comments on commit 299d537

Please sign in to comment.