diff options
| -rw-r--r-- | mirai/asm/interrupts/idt.zig | 6 | ||||
| -rw-r--r-- | mirai/asm/interrupts/stubs.zig | 52 | ||||
| -rw-r--r-- | mirai/interrupts/handlers/exceptions.zig | 82 | ||||
| -rw-r--r-- | mirai/interrupts/handlers/hardware.zig | 48 |
4 files changed, 102 insertions, 86 deletions
diff --git a/mirai/asm/interrupts/idt.zig b/mirai/asm/interrupts/idt.zig index 85147a2..78acff1 100644 --- a/mirai/asm/interrupts/idt.zig +++ b/mirai/asm/interrupts/idt.zig @@ -4,14 +4,12 @@ pub fn lidt(desc: *const anyopaque) void { asm volatile ("lidt (%[desc])" : : [desc] "r" (desc), - : .{ .memory = true } - ); + : .{ .memory = true }); } pub fn sidt(desc: *anyopaque) void { asm volatile ("sidt (%[desc])" : : [desc] "r" (desc), - : .{ .memory = true } - ); + : .{ .memory = true }); } diff --git a/mirai/asm/interrupts/stubs.zig b/mirai/asm/interrupts/stubs.zig index 65b3cd8..f569652 100644 --- a/mirai/asm/interrupts/stubs.zig +++ b/mirai/asm/interrupts/stubs.zig @@ -1,5 +1,13 @@ //! Interrupt Handler Stub Assembly +const std = @import("std"); + +pub const push_zero = "push $0\n"; + +pub fn push_vector(comptime vector: u8) []const u8 { + return comptime std.fmt.comptimePrint("push ${d}\n", .{vector}); +} + pub const push_all = \\push %%rax \\push %%rbx @@ -40,3 +48,47 @@ pub const iret_cleanup = \\add $16, %%rsp \\iretq ; + +pub const call_exception_dispatch = + \\mov %%rsp, %%rdi + \\call exception_dispatch +; + +pub const call_irq_dispatch = + \\mov %%rsp, %%rdi + \\call irq_dispatch +; + +pub fn exception_stub(comptime vector: u8, comptime has_error_code: bool) []const u8 { + return (if (!has_error_code) push_zero else "") ++ + push_vector(vector) ++ + push_all ++ + call_exception_dispatch ++ + pop_all ++ + iret_cleanup; +} + +pub fn irq_stub(comptime irq: u8) []const u8 { + return push_zero ++ + push_vector(irq + 32) ++ + push_all ++ + call_irq_dispatch ++ + pop_all ++ + iret_cleanup; +} + +pub fn make_exception_handler(comptime vector: u8, comptime has_error_code: bool) fn () callconv(.Naked) void { + return struct { + fn handler() callconv(.Naked) void { + asm volatile (exception_stub(vector, has_error_code)); + } + }.handler; +} + +pub fn make_irq_handler(comptime irq: u8) fn () callconv(.Naked) void { + return struct { + fn handler() callconv(.Naked) void { + asm volatile (irq_stub(irq)); + } + }.handler; +} diff --git a/mirai/interrupts/handlers/exceptions.zig b/mirai/interrupts/handlers/exceptions.zig index 87e63db..befabff 100644 --- a/mirai/interrupts/handlers/exceptions.zig +++ b/mirai/interrupts/handlers/exceptions.zig @@ -6,24 +6,6 @@ const asm_stubs = @import("../../asm/interrupts/stubs.zig"); const crimson = @import("../../crimson/crimson.zig"); -fn make_handler(comptime vector: u8, comptime has_error_code: bool) fn () callconv(.Naked) void { - return struct { - fn handler() callconv(.Naked) void { - if (!has_error_code) { - asm volatile ("push $0"); - } - asm volatile ("push %[v]" - : - : [v] "i" (vector), - ); - asm volatile (asm_stubs.push_all ++ - \\mov %%rsp, %%rdi - \\call exception_dispatch - ++ asm_stubs.pop_all ++ asm_stubs.iret_cleanup); - } - }.handler; -} - export fn exception_dispatch(frame: *InterruptFrame) void { const vector: u8 = @truncate(frame.vector); @@ -44,38 +26,38 @@ export fn exception_dispatch(frame: *InterruptFrame) void { } } -pub const exception_0 = make_handler(0, false); -pub const exception_1 = make_handler(1, false); -pub const exception_2 = make_handler(2, false); -pub const exception_3 = make_handler(3, false); -pub const exception_4 = make_handler(4, false); -pub const exception_5 = make_handler(5, false); -pub const exception_6 = make_handler(6, false); -pub const exception_7 = make_handler(7, false); -pub const exception_8 = make_handler(8, true); -pub const exception_9 = make_handler(9, false); -pub const exception_10 = make_handler(10, true); -pub const exception_11 = make_handler(11, true); -pub const exception_12 = make_handler(12, true); -pub const exception_13 = make_handler(13, true); -pub const exception_14 = make_handler(14, true); -pub const exception_15 = make_handler(15, false); -pub const exception_16 = make_handler(16, false); -pub const exception_17 = make_handler(17, true); -pub const exception_18 = make_handler(18, false); -pub const exception_19 = make_handler(19, false); -pub const exception_20 = make_handler(20, false); -pub const exception_21 = make_handler(21, true); -pub const exception_22 = make_handler(22, false); -pub const exception_23 = make_handler(23, false); -pub const exception_24 = make_handler(24, false); -pub const exception_25 = make_handler(25, false); -pub const exception_26 = make_handler(26, false); -pub const exception_27 = make_handler(27, false); -pub const exception_28 = make_handler(28, false); -pub const exception_29 = make_handler(29, true); -pub const exception_30 = make_handler(30, true); -pub const exception_31 = make_handler(31, false); +pub const exception_0 = asm_stubs.make_exception_handler(0, false); +pub const exception_1 = asm_stubs.make_exception_handler(1, false); +pub const exception_2 = asm_stubs.make_exception_handler(2, false); +pub const exception_3 = asm_stubs.make_exception_handler(3, false); +pub const exception_4 = asm_stubs.make_exception_handler(4, false); +pub const exception_5 = asm_stubs.make_exception_handler(5, false); +pub const exception_6 = asm_stubs.make_exception_handler(6, false); +pub const exception_7 = asm_stubs.make_exception_handler(7, false); +pub const exception_8 = asm_stubs.make_exception_handler(8, true); +pub const exception_9 = asm_stubs.make_exception_handler(9, false); +pub const exception_10 = asm_stubs.make_exception_handler(10, true); +pub const exception_11 = asm_stubs.make_exception_handler(11, true); +pub const exception_12 = asm_stubs.make_exception_handler(12, true); +pub const exception_13 = asm_stubs.make_exception_handler(13, true); +pub const exception_14 = asm_stubs.make_exception_handler(14, true); +pub const exception_15 = asm_stubs.make_exception_handler(15, false); +pub const exception_16 = asm_stubs.make_exception_handler(16, false); +pub const exception_17 = asm_stubs.make_exception_handler(17, true); +pub const exception_18 = asm_stubs.make_exception_handler(18, false); +pub const exception_19 = asm_stubs.make_exception_handler(19, false); +pub const exception_20 = asm_stubs.make_exception_handler(20, false); +pub const exception_21 = asm_stubs.make_exception_handler(21, true); +pub const exception_22 = asm_stubs.make_exception_handler(22, false); +pub const exception_23 = asm_stubs.make_exception_handler(23, false); +pub const exception_24 = asm_stubs.make_exception_handler(24, false); +pub const exception_25 = asm_stubs.make_exception_handler(25, false); +pub const exception_26 = asm_stubs.make_exception_handler(26, false); +pub const exception_27 = asm_stubs.make_exception_handler(27, false); +pub const exception_28 = asm_stubs.make_exception_handler(28, false); +pub const exception_29 = asm_stubs.make_exception_handler(29, true); +pub const exception_30 = asm_stubs.make_exception_handler(30, true); +pub const exception_31 = asm_stubs.make_exception_handler(31, false); pub const stubs = [32]*const fn () callconv(.Naked) void{ &exception_0, &exception_1, &exception_2, &exception_3, diff --git a/mirai/interrupts/handlers/hardware.zig b/mirai/interrupts/handlers/hardware.zig index 6b1d09d..b2ca579 100644 --- a/mirai/interrupts/handlers/hardware.zig +++ b/mirai/interrupts/handlers/hardware.zig @@ -14,22 +14,6 @@ pub fn unregister_handler(irq: u4) void { irq_handlers[irq] = null; } -fn make_irq_handler(comptime irq: u8) fn () callconv(.Naked) void { - return struct { - fn handler() callconv(.Naked) void { - asm volatile ("push $0"); - asm volatile ("push %[v]" - : - : [v] "i" (irq + 32), - ); - asm volatile (asm_stubs.push_all ++ - \\mov %%rsp, %%rdi - \\call irq_dispatch - ++ asm_stubs.pop_all ++ asm_stubs.iret_cleanup); - } - }.handler; -} - export fn irq_dispatch(frame: *InterruptFrame) void { const vector: u8 = @truncate(frame.vector); const irq = vector - 32; @@ -41,22 +25,22 @@ export fn irq_dispatch(frame: *InterruptFrame) void { } } -pub const irq_0 = make_irq_handler(0); -pub const irq_1 = make_irq_handler(1); -pub const irq_2 = make_irq_handler(2); -pub const irq_3 = make_irq_handler(3); -pub const irq_4 = make_irq_handler(4); -pub const irq_5 = make_irq_handler(5); -pub const irq_6 = make_irq_handler(6); -pub const irq_7 = make_irq_handler(7); -pub const irq_8 = make_irq_handler(8); -pub const irq_9 = make_irq_handler(9); -pub const irq_10 = make_irq_handler(10); -pub const irq_11 = make_irq_handler(11); -pub const irq_12 = make_irq_handler(12); -pub const irq_13 = make_irq_handler(13); -pub const irq_14 = make_irq_handler(14); -pub const irq_15 = make_irq_handler(15); +pub const irq_0 = asm_stubs.make_irq_handler(0); +pub const irq_1 = asm_stubs.make_irq_handler(1); +pub const irq_2 = asm_stubs.make_irq_handler(2); +pub const irq_3 = asm_stubs.make_irq_handler(3); +pub const irq_4 = asm_stubs.make_irq_handler(4); +pub const irq_5 = asm_stubs.make_irq_handler(5); +pub const irq_6 = asm_stubs.make_irq_handler(6); +pub const irq_7 = asm_stubs.make_irq_handler(7); +pub const irq_8 = asm_stubs.make_irq_handler(8); +pub const irq_9 = asm_stubs.make_irq_handler(9); +pub const irq_10 = asm_stubs.make_irq_handler(10); +pub const irq_11 = asm_stubs.make_irq_handler(11); +pub const irq_12 = asm_stubs.make_irq_handler(12); +pub const irq_13 = asm_stubs.make_irq_handler(13); +pub const irq_14 = asm_stubs.make_irq_handler(14); +pub const irq_15 = asm_stubs.make_irq_handler(15); pub const stubs = [16]*const fn () callconv(.Naked) void{ &irq_0, &irq_1, &irq_2, &irq_3, |
