const console = @import("console"); const common = @import("root.zig"); const mm = common.mm; const std = @import("std"); const arch = @import("arch"); const spinlock = @import("spinlock"); // Types pub const HardwareDescription = union(enum) { /// Physical address of ACPI RSDP acpi_rsdp: usize, /// Virtual pointer to DTB dtb: *anyopaque, none, }; pub const InitState = struct { bootmem: mm.bootmem.BootPmm = .{}, console: ?console.Console = null, framebuffer: ?console.Framebuffer = null, hardware_description: HardwareDescription = .none, root_task_elf: []align(4096) u8 = undefined, hhdm_slide: usize = 0, kernel_paging_ctx: arch.mm.paging.Context = undefined, }; pub fn initConsole() void { const fb = common.init_data.framebuffer.?; // Create a canvas for the console to render to const canvas: [*]u8 = @ptrFromInt(common.init_data.bootmem.allocMem(fb.width * fb.height * fb.bypp) catch @panic("Couldn't allocate a canvas")); @memset(canvas[0 .. fb.width * fb.height * fb.bypp], 0); // Set the console instance common.init_data.console = console.Console.init(fb, canvas); } var stdout_lock: spinlock.Spinlock = .{}; pub fn logFn( comptime message_level: std.log.Level, comptime scope: @TypeOf(.enum_literal), comptime format: []const u8, args: anytype, ) void { if (common.init_data.console == null) return; // Use the same naming as the default logger const level, const color: u32 = switch (message_level) { .debug => .{ "D", 0x3bcf1d }, .err => .{ "E", 0xff0000 }, .info => .{ "I", 0x00bbbb }, .warn => .{ "W", 0xfee409 }, }; // Use same format as default once again const scope_text = switch (scope) { .default => "", else => "<" ++ @tagName(scope) ++ ">", }; const prefix = std.fmt.comptimePrint("{s}{s}: ", .{ level, scope_text }); { stdout_lock.lock(); defer stdout_lock.unlock(); common.init_data.console.?.setColor(color, 0); // No buffering for now var writer = console.Console.Writer.init(&common.init_data.console.?, &.{}); writer.interface.print(prefix ++ format ++ "\n", args) catch return; } } pub fn panic(msg: []const u8, first_trace_addr: ?usize) noreturn { _ = first_trace_addr; const log = std.log.scoped(.panic); log.err("PANIC: {s}", .{msg}); var it = std.debug.StackIterator.init(@returnAddress(), @frameAddress()); defer it.deinit(); while (it.next()) |addr| { if (addr == 0) break; log.err("Addr: 0x{x:0>16}", .{addr}); } arch.instructions.die(); }