aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-05-21 16:49:27 +0200
committerHimbeer <himbeer@disroot.org>2024-05-21 16:49:27 +0200
commit53d0a5c81ba0456d88013c366035f31f1dbab13e (patch)
treed529e81e2a826c234a489116b0c1cac478bcbbd9 /src
parentc8216154bbbefd522b5ca974416fa4e572208e14 (diff)
main: Don't use stack variables across paging activation boundary
Diffstat (limited to 'src')
-rw-r--r--src/main.zig114
1 files changed, 77 insertions, 37 deletions
diff --git a/src/main.zig b/src/main.zig
index 9ed197c..544e3a6 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -19,6 +19,27 @@ const Error = error{
SuspiciousFdtAddr,
};
+const HartData = packed struct(usize) {
+ hart_id: u16,
+ fdt_blob: u32,
+ reserved: u16,
+
+ pub inline fn loadSScratch() HartData {
+ return asm volatile (
+ \\ csrr %[hart_data], sscratch
+ : [hart_data] "=r" (-> HartData),
+ );
+ }
+
+ pub inline fn storeSScratch(self: HartData) void {
+ asm volatile (
+ \\ csrw sscratch, %[hart_data]
+ :
+ : [hart_data] "r" (self),
+ );
+ }
+};
+
pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn {
_ = &error_return_trace;
_ = &ret_addr;
@@ -48,7 +69,7 @@ export fn _start() callconv(.Naked) noreturn {
\\ .option pop
\\
\\ la sp, _stack_end
- \\ call %[function]
+ \\ j %[function]
:
: [function] "s" (&kmain),
);
@@ -60,30 +81,76 @@ fn kmain(hart_id: usize, fdt_blob: *fdt.RawHeader) noreturn {
fn run(hart_id: usize, fdt_blob: *fdt.RawHeader) !noreturn {
if (hart_id > ~@as(u16, 0)) return Error.HartIdOutOfRange;
+ if (@intFromPtr(fdt_blob) > std.math.maxInt(u32)) return Error.SuspiciousFdtAddr;
- const dt_header = try fdt.Header.parse(fdt_blob);
+ const hart_data = HartData{
+ .hart_id = @intCast(hart_id),
+ .fdt_blob = @intCast(@intFromPtr(fdt_blob)),
+ .reserved = 0,
+ };
+ hart_data.storeSScratch();
paging.init();
+ const dt_header = try fdt.Header.parse(fdt_blob);
+
const kmem: *paging.Table = @alignCast(@ptrCast(try paging.zeroedAlloc(1)));
try kmem.mapKernel();
try kmem.mapFdt(&dt_header);
- var chunk_allocator = try mem.ChunkAllocator(.{ .auto_merge_free = true }).init(128);
- const allocator = chunk_allocator.allocator();
+ instructions.setSatp(kmem.satp(0));
- fdt.default = try dt_header.parseTree(allocator);
+ asm volatile (
+ \\ la sp, _stack_end
+ \\ j %[function]
+ :
+ : [function] "s" (&pagedStart),
+ );
+
+ unreachable;
+}
+
+fn pagedStart() callconv(.Naked) noreturn {
+ asm volatile (
+ \\ la sp, _stack_end
+ \\ j %[function]
+ :
+ : [function] "s" (&pagedMain),
+ );
+}
+
+fn pagedMain() noreturn {
+ pagedRun() catch |err| std.debug.panic("Paged: {any}", .{err});
+}
- var console = Console.autoChoose() orelse while (true) asm volatile ("wfi");
- var w = console.writer();
+fn pagedRun() !noreturn {
+ const console = Console.autoChoose() orelse while (true) asm volatile ("wfi");
+ const w = console.writer();
try w.print("\r\n", .{});
try w.print("Console init\r\n", .{});
try w.print("\r\n", .{});
- try w.print("Hart : {d}\r\n", .{hart_id});
- try w.print("FDT address : 0x{x:0>8}\r\n", .{@intFromPtr(fdt_blob)});
+ const hart_data = HartData.loadSScratch();
+
+ try w.print("Hart : {d}\r\n", .{hart_data.hart_id});
+ try w.print("FDT address : 0x{x:0>8}\r\n", .{hart_data.fdt_blob});
+
+ try w.print("Paging : Sv39\r\n", .{});
+
+ interrupts.init();
+ interrupts.setEnabled(interrupts.Enable.all);
+ try w.print("Interrupts : All\r\n", .{});
+
+ try w.print("\r\n", .{});
+
+ var chunk_allocator = try mem.ChunkAllocator(.{ .auto_merge_free = true }).init(128);
+ const allocator = chunk_allocator.allocator();
+
+ const dt_header = try fdt.Header.parse(@ptrFromInt(hart_data.fdt_blob));
+
+ fdt.default = try dt_header.parseTree(allocator);
try w.print("\r\n", .{});
try w.print("===================== Kernel Page Table =====================\r\n", .{});
@@ -98,37 +165,10 @@ fn run(hart_id: usize, fdt_blob: *fdt.RawHeader) !noreturn {
try w.print("\r\n", .{});
try w.print("Heap: 0x{x:0>8} - 0x{x:0>8} -> identity mapped (rw-)\r\n", .{ @intFromPtr(paging.heap_start), @intFromPtr(paging.heap_end) });
try w.print("\r\n", .{});
- try w.print("FDT: 0x{x:0>8} - 0x{x:0>8} -> identity mapped (r--)\r\n", .{ @intFromPtr(fdt_blob), @intFromPtr(fdt_blob) + dt_header.total_size });
+ try w.print("FDT: 0x{x:0>8} - 0x{x:0>8} -> identity mapped (r--)\r\n", .{ hart_data.fdt_blob, hart_data.fdt_blob + dt_header.total_size });
try w.print("=============================================================\r\n", .{});
try w.print("\r\n", .{});
- interrupts.init();
- interrupts.setEnabled(interrupts.Enable.all);
- try w.print("Interrupts : All\r\n", .{});
-
- instructions.setSatp(kmem.satp(0));
- const console2 = Console.autoChoose() orelse while (true) asm volatile ("wfi");
- const w2 = console2.writer();
- try w2.print("Paging : Sv39\r\n", .{});
-
- try w2.print("\r\n", .{});
-
- //instructions.setSatp(.{
- // .ppn = 0,
- // .asid = 0,
- // .mode = .bare,
- //});
- try w2.print("SP = 0x{x:0>16}\r\n", .{instructions.stackPointer()});
- try w2.print("trans 0x{?x:0>16}\r\n", .{kmem.translate(instructions.stackPointer())});
- const fp = asm volatile (""
- : [fp] "={fp}" (-> usize),
- );
- try w2.print("FP = 0x{x:0>16}\r\n", .{fp});
- const ra = asm volatile (""
- : [ra] "={ra}" (-> usize),
- );
- try w2.print("RA = 0x{x:0>16}\r\n", .{ra});
-
try w.print("Timer : {d} Hz\r\n", .{1 / (@as(f64, process.schedule_interval_millis) / 1000)});
try plic.init(&fdt.default, allocator);