const std = @import("std"); const isa = @import("riscv/isa.zig"); const Fdt = @import("Fdt.zig"); const Console = @import("drivers/Console.zig"); const debug = @import("debug.zig"); const mem = @import("mem.zig"); const UART_BASE: usize = 0x10000000; const MEMORY_START = @extern([*]u8, .{.name = "__memory_start"}); fn uart_put(c: u8) void { const uart: *volatile u8 = @ptrFromInt(UART_BASE); uart.* = c; } fn print(s: []const u8) void { for (s) |c| { uart_put(c); } } export fn _start() linksection(".text.init") callconv(.naked) noreturn { asm volatile ( \\li sp, 0x88000000 \\tail kmain ); } export fn kmain(hartid: u64, fdt_ptr: *const anyopaque) callconv(.c) noreturn { _ = hartid; const fdt = Fdt.parse(fdt_ptr) catch { while (true) asm volatile ("wfi"); }; const root = fdt.root().?; const console = Console.init(fdt).?; debug.init(console); debug.print("booting hydra...\n", .{}); const memory = fdt.memory().?; var reg_iter = Fdt.parseReg(memory.getProperty("reg").?.data, root.addressCells(), root.sizeCells()); const reg = reg_iter.next().?; const memory_end = reg.address + reg.size; var buddy: mem.BuddyAllocator = .{}; buddy.init(MEMORY_START[0..memory_end - @intFromPtr(MEMORY_START)]); debug.print("memory allocator initialized.\n", .{}); const allocator = buddy.allocator(); var table = isa.PageTable.init(allocator) catch { @panic("Unable to create page table.\n"); }; table.identityMap(allocator, memory_end) catch {}; table.map(allocator, @intFromPtr(console.mmio), @intFromPtr(console.mmio), .{.read = 1, .write = 1, .execute = 1}) catch {}; isa.write_satp(.{ .ppn = @as(u44, @intCast(@intFromPtr(table) >> 12)), .mode = .sv57, }); debug.print("loaded kernel page table.\n", .{}); while (true) { asm volatile ("wfi"); } }