This repository has been archived by the owner on Jun 7, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- VMM - Paging for x86_64 - Updated to zig master - Now exceptions halt the OS, to avoid double faults - Because of the removal of `main_mod_path` (see ziglang/zig#18160) the file with the entry point has to be directly on the module root path. To solve this, we now have a `src/main.zig` that does a `usingnamespace` with a `switch` for the appropiate `start.zig` file. As a benefit, some generic functions like `panic` or the `root.os` abstraction layer can be here. - HAL system, mainly to abstract `cpu.zig`
- Loading branch information
Showing
9 changed files
with
297 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const cpu = @import("cpu.zig"); | ||
|
||
pub fn halt() noreturn { | ||
cpu.halt(); | ||
} | ||
|
||
pub fn debugcon(byte: u8) void { | ||
cpu.outb(0xE9, byte); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
const std = @import("std"); | ||
const vmm = @import("../../mm/vmm.zig"); | ||
const pmm = @import("../../mm/pmm.zig"); | ||
|
||
const log = std.log.scoped(.paging); | ||
|
||
/// An abstraction of the page mapping | ||
pub const PageMap = struct { | ||
root: u64 = undefined, | ||
|
||
/// Load the map | ||
pub fn load(self: PageMap) void { | ||
loadSpace(self.root); | ||
} | ||
|
||
/// Save the currently loaded map | ||
pub fn save(self: *PageMap) void { | ||
self.root = saveSpace(); | ||
} | ||
|
||
/// Map a physical page to a virtual page | ||
pub fn mapPage(self: *PageMap, flags: vmm.MapFlags, virt: u64, phys: u64, huge: bool) !void { | ||
var root: [*]u64 = @ptrFromInt(vmm.toHigherHalf(self.root)); | ||
|
||
const indices = [4]u64{ | ||
getIndex(virt, 39), getIndex(virt, 30), | ||
getIndex(virt, 21), getIndex(virt, 12), | ||
}; | ||
|
||
root = (try getNextLevel(root, indices[0], true)).?; | ||
root = (try getNextLevel(root, indices[1], true)).?; | ||
|
||
if (huge) { | ||
root[indices[2]] = createPte(flags, phys, true); | ||
} else { | ||
root = (try getNextLevel(root, indices[2], true)).?; | ||
root[indices[3]] = createPte(flags, phys, false); | ||
} | ||
} | ||
}; | ||
|
||
fn getNextLevel(level: [*]u64, index: usize, create: bool) !?[*]u64 { | ||
// If entry not present | ||
if ((level[index] & 1) == 0) { | ||
if (!create) return null; | ||
|
||
const table_ptr = @intFromPtr((try pmm.allocator.alloc(u8, 4096)).ptr); | ||
level[index] = table_ptr; | ||
level[index] |= 0b111; | ||
} | ||
|
||
return @ptrFromInt(vmm.toHigherHalf(level[index] & ~@as(u64, 0x1FF))); | ||
} | ||
|
||
fn createPte(flags: vmm.MapFlags, phys_ptr: u64, huge: bool) u64 { | ||
var result: u64 = 1; // Present | ||
|
||
const pat_bit = if (huge) @as(u64, 1) << 12 else @as(u64, 1) << 7; | ||
|
||
if (flags.write) result |= @as(u64, 1) << 1; | ||
if (!flags.execute) result |= @as(u64, 1) << 63; | ||
if (flags.user) result |= @as(u64, 1) << 2; | ||
if (huge) result |= @as(u64, 1) << 7; | ||
|
||
switch (flags.cache_type) { | ||
.uncached => { | ||
result |= @as(u64, 1) << 4; | ||
result |= @as(u64, 1) << 3; | ||
result &= ~pat_bit; | ||
}, | ||
.write_combining => { | ||
result |= pat_bit; | ||
result |= @as(u64, 1) << 4; | ||
result |= @as(u64, 1) << 3; | ||
}, | ||
.write_protect => { | ||
result |= pat_bit; | ||
result |= @as(u64, 1) << 4; | ||
result &= ~(@as(u64, 1) << 3); | ||
}, | ||
.write_back => {}, | ||
} | ||
|
||
result |= phys_ptr; | ||
return result; | ||
} | ||
|
||
inline fn getIndex(virt: u64, comptime shift: u6) u64 { | ||
return ((virt & (0x1FF << shift)) >> shift); | ||
} | ||
|
||
inline fn loadSpace(root: u64) void { | ||
asm volatile ("mov %[root], %%cr3" | ||
: | ||
: [root] "r" (root), | ||
: "memory" | ||
); | ||
} | ||
|
||
inline fn saveSpace() void { | ||
asm volatile ("mov %%cr3, %[root]" | ||
: [root] "=r" (-> u64), | ||
: | ||
: "memory" | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
const builtin = @import("builtin"); | ||
|
||
pub usingnamespace switch (builtin.cpu.arch) { | ||
.x86_64 => @import("arch/x86_64/hal.zig"), | ||
else => |other| @compileError("Unimplemented for " ++ @tagName(other)), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const std = @import("std"); | ||
const builtin = @import("builtin"); | ||
const pmm = @import("mm/pmm.zig"); | ||
const hal = @import("hal.zig"); | ||
|
||
pub const os = @import("os.zig"); | ||
|
||
const log = std.log.scoped(.core); | ||
|
||
pub const std_options = struct { | ||
pub fn logFn(comptime message_level: std.log.Level, comptime scope: @Type(.EnumLiteral), comptime format: []const u8, args: anytype) void { | ||
var log_allocator_buf: [2048]u8 = undefined; | ||
var log_fba = std.heap.FixedBufferAllocator.init(&log_allocator_buf); | ||
const log_allocator = log_fba.allocator(); | ||
|
||
const msg = std.fmt.allocPrint(log_allocator, switch (message_level) { | ||
.info => "\x1b[34m", | ||
.warn => "\x1b[33m", | ||
.err => "\x1b[31m", | ||
.debug => "\x1b[90m", | ||
} ++ "[" ++ @tagName(message_level) ++ "]\x1b[0m (" ++ @tagName(scope) ++ ") " ++ format ++ "\n", args) catch "LOG_FN_OOM"; | ||
|
||
for (msg) |char| { | ||
hal.debugcon(char); | ||
} | ||
} | ||
}; | ||
|
||
pub fn panic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn { | ||
log.err("{s}", .{msg}); | ||
|
||
hal.halt(); | ||
} | ||
|
||
pub const heap = struct { | ||
pub const page_allocator = pmm.allocator; | ||
}; | ||
|
||
pub usingnamespace switch (builtin.cpu.arch) { | ||
.x86_64 => @import("arch/x86_64/start.zig"), | ||
else => |other| @compileError("Unimplemented for " ++ @tagName(other)), | ||
}; |
Oops, something went wrong.