Microkernel thing OS experiment (Zig ⚡)
1pub const apic = @import("apic.zig");
2pub const pic = @import("pic.zig");
3pub const pit = @import("pit.zig");
4pub const idt = @import("idt.zig");
5const std = @import("std");
6const arch = @import("../root.zig");
7
8pub inline fn enable() void {
9 asm volatile ("sti");
10}
11pub inline fn disable() void {
12 asm volatile ("cli");
13}
14
15fn print_regs(frame: *idt.InterruptFrame(u64)) void {
16 std.log.err("CR3: 0x{x:0>16}", .{frame.cr3});
17 std.log.err("RAX: 0x{x:0>16}, RBX: 0x{x:0>16}, RCX: 0x{x:0>16}, RDX: 0x{x:0>16}", .{ frame.regs.rax, frame.regs.rbx, frame.regs.rcx, frame.regs.rdx });
18 std.log.err("RSI: 0x{x:0>16}, RDI: 0x{x:0>16}, RBP: 0x{x:0>16}, RSP: 0x{x:0>16}", .{ frame.regs.rsi, frame.regs.rdi, frame.regs.rbp, frame.rsp });
19 std.log.err("R8: 0x{x:0>16}, R9: 0x{x:0>16}, R10: 0x{x:0>16}, R11: 0x{x:0>16}", .{ frame.regs.r8, frame.regs.r9, frame.regs.r10, frame.regs.r11 });
20 std.log.err("R12: 0x{x:0>16}, R13: 0x{x:0>16}, R14: 0x{x:0>16}, R15: 0x{x:0>16}", .{ frame.regs.r12, frame.regs.r13, frame.regs.r14, frame.regs.r15 });
21 std.log.err("RFL: 0x{x:0>16}, RIP: 0x{x:0>16}, CS: 0x{x:0>16}, SS: 0x{x:0>16}", .{ frame.eflags, frame.rip, frame.cs, frame.ss });
22}
23
24pub fn unhandled_interrupt(frame: *idt.InterruptFrame(u64)) callconv(.{ .x86_64_sysv = .{} }) void {
25 if (std.enums.tagName(idt.Exception, frame.int_num.exception)) |exception_name| {
26 std.log.err("Unhandled interrupt (0x{x} : {s})!!!", .{ frame.int_num.interrupt, exception_name });
27 } else {
28 std.log.err("Unhandled interrupt (0x{x})!!!", .{frame.int_num.interrupt});
29 }
30
31 print_regs(frame);
32
33 arch.interrupts.disable();
34 arch.instructions.die();
35}
36
37pub fn breakpoint(stack_frame: *idt.InterruptFrame(u64)) callconv(.{ .x86_64_sysv = .{} }) void {
38 std.log.warn("Breakpoint @ 0x{x}, returning execution...", .{stack_frame.rip});
39}
40
41pub fn double_fault(stack_frame: *idt.InterruptFrame(u64)) callconv(.{ .x86_64_sysv = .{} }) void {
42 std.log.err("Double fault @ 0x{x}, dying!!!", .{stack_frame.rip});
43 print_regs(stack_frame);
44 arch.interrupts.disable();
45 arch.instructions.die();
46}
47
48pub fn general_protection_fault(stack_frame: *idt.InterruptFrame(idt.SelectorErrorCode)) callconv(.{ .x86_64_sysv = .{} }) void {
49 std.log.warn("General Protection Fault @ 0x{x}", .{stack_frame.rip});
50
51 const target = stack_frame.error_code.parse();
52 switch (target) {
53 .interrupt => |int| {
54 if (std.enums.tagName(idt.Exception, int.exception)) |exc_name| {
55 std.log.warn("Caused by interrupt 0x{x} ({s})", .{ int.interrupt, exc_name });
56 } else {
57 std.log.warn("Caused by interrupt 0x{x}", .{int.interrupt});
58 }
59 },
60 .gdt_sel => |gdt_sel| {
61 std.log.warn("GDT selector: 0x{x}", .{gdt_sel});
62 },
63 .ldt_sel => |ldt_sel| {
64 std.log.warn("LDT selector: 0x{x}", .{ldt_sel});
65 },
66 }
67 print_regs(@ptrCast(stack_frame));
68 arch.instructions.die();
69}