diff options
author | Himbeer <himbeer@disroot.org> | 2024-05-21 16:49:27 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-05-21 16:49:27 +0200 |
commit | 53d0a5c81ba0456d88013c366035f31f1dbab13e (patch) | |
tree | d529e81e2a826c234a489116b0c1cac478bcbbd9 /src | |
parent | c8216154bbbefd522b5ca974416fa4e572208e14 (diff) |
main: Don't use stack variables across paging activation boundary
Diffstat (limited to 'src')
-rw-r--r-- | src/main.zig | 114 |
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); |