diff --git a/src/idt.zig b/src/idt.zig deleted file mode 100644 index f19dc37..0000000 --- a/src/idt.zig +++ /dev/null @@ -1,142 +0,0 @@ -const std = @import("std"); - -pub const InterruptStackFrame = extern struct { - instruction_ptr: u64, - code_segment: u64, - cpu_flags: u64, - stack_ptr: u64, - stack_segment: u64, -}; - -const HandlerFunction = *const fn (_: *InterruptStackFrame) callconv(.{ .x86_interrupt = .{} }) void; - -fn HandlerFunctionWithErrorCode(comptime Return: type) type { - if (Return != void and Return != noreturn) { - @compileError("Return should either be void or noreturn"); - } - - return *const fn (_: *InterruptStackFrame, error_code: u32) callconv(.{ .x86_interrupt = .{} }) Return; -} - -pub const InterruptDescriptorTableEntryType = enum(u8) { - division_error = 0, - debug = 1, - non_maskable_interrupt = 2, - breakpoint = 3, - overflow = 4, - bound_range_exceeded = 5, - invalid_opcode = 6, - device_not_available = 7, - double_fault = 8, - coprocessor_segment_overrun = 9, - invalid_tss = 10, - segment_not_present = 11, - stack_segment_fault = 12, - general_protection_fault = 13, - page_fault = 14, - x87_floating_point_exception = 16, - alignment_check = 17, - machine_check = 18, - simd_floating_point = 19, - virtualization = 20, - control_protection_exception = 21, - hypervisor_injection_exception = 28, - vmm_communication_exception = 29, - security_exception = 30, - - const Self = @This(); - - pub fn HandlerFunctionType(self: Self) type { - return switch (self) { - .double_fault, .machine_check => HandlerFunctionWithErrorCode(noreturn), - .invalid_tss, .segment_not_present, .stack_segment_fault, .general_protection_fault, .page_fault, .alignment_check, .control_protection_exception, .vmm_communication_exception, .security_exception => HandlerFunctionWithErrorCode(void), - else => HandlerFunction, - }; - } -}; - -pub const InterruptDescriptorTable = extern struct { - table: [Length]Entry, - - const Length = std.math.maxInt(u8) + 1; - - const Entry = packed struct { - ptr_low: u16, - options: Options, - ptr_mid: u16, - ptr_high: u32, - reserved: u32, - - pub const missing: Entry = .{ - .ptr_low = 0, - .options = .minimal, - .ptr_mid = 0, - .ptr_high = 0, - .reserved = 0, - }; - - const Options = packed struct { - code_segment: u16, - bit_set: std.bit_set.IntegerBitSet(16), - - pub const minimal: Options = .{ - .code_segment = 0, - .bit_set = .{ .mask = 0b1110_0000_0000 }, - }; - - pub fn setCodeSelector(self: *align(2) Options, segment: u16) void { - self.code_segment = segment; - } - - pub fn setPresent(self: *align(2) Options, present: bool) void { - self.bit_set.setValue(15, present); - } - }; - - fn setHandler(self: *Entry, handler_addr: u64) void { - self.ptr_low = @truncate(handler_addr); - self.ptr_mid = @truncate(handler_addr >> 16); - self.ptr_high = @truncate(handler_addr >> 32); - - self.options = .minimal; - const segment = asm volatile ( - \\ mov %%cs, %[segment] - : [segment] "=&r" (-> u16) - : - ); - self.options.setCodeSelector(segment); - self.options.setPresent(true); - - std.log.info("Setting handler {any}\n", .{ self.* }); - } - }; - - pub const empty: InterruptDescriptorTable = .{ - .table = [_]Entry{.missing} ** Length, - }; - - pub fn setEntry( - self: *InterruptDescriptorTable, - comptime entry_type: InterruptDescriptorTableEntryType, - handler: InterruptDescriptorTableEntryType.HandlerFunctionType(entry_type), - ) void { - self.table[@intFromEnum(entry_type)].setHandler(@intFromPtr(handler)); - } - - pub fn load(self: *InterruptDescriptorTable) void { - const DescriptorTablePointer = packed struct { - limit: u16, - base: u64, - }; - const idt: DescriptorTablePointer = .{ - .limit = @sizeOf(@TypeOf(self.*)) - 1, - .base = @intFromPtr(self), - }; - - asm volatile ( - \\ lidt (%[idt]) - : - : [idt] "r" (idt), - ); - } -}; diff --git a/src/main.zig b/src/main.zig index 256ff39..dd4f020 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,11 +1,7 @@ const lazy = @import("utils/Lazy.zig").lazy; const Console = @import("Console.zig"); - const MultibootInfo = @import("multiboot.zig").Info; -const InterruptDescriptorTable = @import("idt.zig").InterruptDescriptorTable; -const InterruptStackFrame = @import("idt.zig").InterruptStackFrame; - const MultibootHeader = packed struct { magic: i32, flags: i32, @@ -41,8 +37,6 @@ export fn _start() callconv(.naked) noreturn { var console = lazy(Console, .init); -var idt: InterruptDescriptorTable = .empty; - fn kmain(magic: u32, info: *const MultibootInfo) callconv(.c) void { std.debug.assert(magic == MAGIC); @@ -55,24 +49,9 @@ fn kmain(magic: u32, info: *const MultibootInfo) callconv(.c) void { std.log.info("Booted with cmdline \"{s}\"", .{info.cmdline}); } - idt.setEntry(.breakpoint, breakpointHandler); - idt.load(); - - //asm volatile ( - // \\ int3 - // : - // : - //); - hang(); } -fn breakpointHandler(stack_frame: *InterruptStackFrame) callconv(.{ .x86_interrupt = .{} }) void { - _ = stack_frame; - - std.log.err("breakpoint\n", .{}); -} - fn hang() noreturn { while (true) asm volatile ("hlt"); }