diff options
| author | Bobby <[email protected]> | 2026-03-27 18:52:18 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-03-27 18:52:18 +0530 |
| commit | b45cfb5ede9f1a3dd7f7323bd218a4dcaaf76b76 (patch) | |
| tree | 7ea4ab655b3c37cd2a5d35d21a228b763ba413aa | |
| parent | aec48b60740d9ea7060da6d494e3cf95b1aa8e18 (diff) | |
| download | akiba-b45cfb5ede9f1a3dd7f7323bd218a4dcaaf76b76.tar.xz akiba-b45cfb5ede9f1a3dd7f7323bd218a4dcaaf76b76.zip | |
Refactor and implement interrupt handling and PIT driver
- Refactored CPU context structure for better readability.
- Enhanced corpse and exception structures with clearer formatting.
- Improved frame structure for consistency.
- Added interrupt flag operations for enabling and disabling interrupts.
- Implemented IDT (Interrupt Descriptor Table) operations including loading and setting gates.
- Created PIC (Programmable Interrupt Controller) initialization and masking functions.
- Developed PIT (Programmable Interval Timer) driver with initialization and handler functions.
- Established common interrupt handler structure and exception handling stubs.
- Added hardware IRQ handling for IRQs 0-15.
- Introduced IDT entry and gate descriptor types for better organization.
- Ensured proper handling of interrupt and exception vectors.
48 files changed, 951 insertions, 92 deletions
diff --git a/mirai.old/asm/context.zig b/mirai.old/asm/context.zig index ada6585..5876b33 100644 --- a/mirai.old/asm/context.zig +++ b/mirai.old/asm/context.zig @@ -60,7 +60,6 @@ pub fn switch_to_context(ctx: *const kata_mod.Context, page_table: u64, kernel_s : [ctx_addr] "r" (ctx_addr), [pt] "r" (page_table), [kstack] "r" (kernel_stack), - : .{ .memory = true } - ); + : .{ .memory = true }); unreachable; } diff --git a/mirai.old/asm/cpu.zig b/mirai.old/asm/cpu.zig index 86324a0..608aa6b 100644 --- a/mirai.old/asm/cpu.zig +++ b/mirai.old/asm/cpu.zig @@ -63,6 +63,5 @@ pub inline fn reload_code_segment(selector: u16) void { \\1: : : [sel] "r" (@as(u64, selector)), - : .{ .rax = true } - ); + : .{ .rax = true }); } diff --git a/mirai/asm/asm.zig b/mirai/asm/asm.zig index 1a12c31..f2bae9b 100644 --- a/mirai/asm/asm.zig +++ b/mirai/asm/asm.zig @@ -5,3 +5,4 @@ pub const io = @import("io/io.zig"); pub const gdt = @import("gdt/gdt.zig"); pub const debug = @import("debug/debug.zig"); pub const fpu = @import("fpu/fpu.zig"); +pub const interrupts = @import("interrupts/interrupts.zig"); diff --git a/mirai/asm/cpu/control.zig b/mirai/asm/cpu/control.zig index ec408c1..719c8bd 100644 --- a/mirai/asm/cpu/control.zig +++ b/mirai/asm/cpu/control.zig @@ -35,8 +35,7 @@ pub fn write_cr3(value: u64) void { asm volatile ("mov %[value], %%cr3" : : [value] "r" (value), - : .{ .memory = true } - ); + : .{ .memory = true }); } pub fn read_cr4() u64 { @@ -63,6 +62,5 @@ pub fn invalidate_page(virtual_address: u64) void { asm volatile ("invlpg (%[address])" : : [address] "r" (virtual_address), - : .{ .memory = true } - ); + : .{ .memory = true }); } diff --git a/mirai/asm/fpu/fpu.zig b/mirai/asm/fpu/fpu.zig index 4f5e5db..e6f86ec 100644 --- a/mirai/asm/fpu/fpu.zig +++ b/mirai/asm/fpu/fpu.zig @@ -4,16 +4,14 @@ pub fn fxsave(addr: u64) void { asm volatile ("fxsave (%[addr])" : : [addr] "r" (addr), - : .{ .memory = true } - ); + : .{ .memory = true }); } pub fn fxrstor(addr: u64) void { asm volatile ("fxrstor (%[addr])" : : [addr] "r" (addr), - : .{ .memory = true } - ); + : .{ .memory = true }); } pub fn fninit() void { @@ -28,14 +26,12 @@ pub fn stmxcsr(addr: *u32) void { asm volatile ("stmxcsr (%[addr])" : : [addr] "r" (addr), - : .{ .memory = true } - ); + : .{ .memory = true }); } pub fn ldmxcsr(addr: *const u32) void { asm volatile ("ldmxcsr (%[addr])" : : [addr] "r" (addr), - : .{ .memory = true } - ); + : .{ .memory = true }); } diff --git a/mirai/asm/gdt/lgdt.zig b/mirai/asm/gdt/lgdt.zig index 457a8aa..42a640b 100644 --- a/mirai/asm/gdt/lgdt.zig +++ b/mirai/asm/gdt/lgdt.zig @@ -9,8 +9,7 @@ pub fn lgdt(gdtr: *const Gdtr) void { asm volatile ("lgdt (%[gdtr])" : : [gdtr] "r" (gdtr), - : .{ .memory = true } - ); + : .{ .memory = true }); } pub fn sgdt() Gdtr { @@ -18,7 +17,6 @@ pub fn sgdt() Gdtr { asm volatile ("sgdt (%[gdtr])" : : [gdtr] "r" (&gdtr), - : .{ .memory = true } - ); + : .{ .memory = true }); return gdtr; } diff --git a/mirai/asm/gdt/segments.zig b/mirai/asm/gdt/segments.zig index ab2a26a..10d7c9e 100644 --- a/mirai/asm/gdt/segments.zig +++ b/mirai/asm/gdt/segments.zig @@ -9,8 +9,7 @@ pub fn reload_code_segment(code_selector: u16) void { \\1: : : [code_sel] "r" (@as(u64, code_selector)), - : .{ .rax = true, .memory = true } - ); + : .{ .rax = true, .memory = true }); } pub fn reload_data_segments(data_selector: u16) void { @@ -23,8 +22,7 @@ pub fn reload_data_segments(data_selector: u16) void { \\mov %%ax, %%ss : : [data_sel] "r" (data_selector), - : .{ .rax = true, .memory = true } - ); + : .{ .rax = true, .memory = true }); } pub fn load_tss(tss_selector: u16) void { diff --git a/mirai/asm/interrupts/flags.zig b/mirai/asm/interrupts/flags.zig new file mode 100644 index 0000000..2bf3fc3 --- /dev/null +++ b/mirai/asm/interrupts/flags.zig @@ -0,0 +1,23 @@ +//! Interrupt Flag Operations + +pub fn enable() void { + asm volatile ("sti"); +} + +pub fn disable() void { + asm volatile ("cli"); +} + +pub fn read_flags() u64 { + var flags: u64 = undefined; + asm volatile ( + \\pushfq + \\pop %[flags] + : [flags] "=r" (flags), + ); + return flags; +} + +pub fn are_enabled() bool { + return (read_flags() & 0x200) != 0; +} diff --git a/mirai/asm/interrupts/idt.zig b/mirai/asm/interrupts/idt.zig new file mode 100644 index 0000000..85147a2 --- /dev/null +++ b/mirai/asm/interrupts/idt.zig @@ -0,0 +1,17 @@ +//! IDT Assembly Operations + +pub fn lidt(desc: *const anyopaque) void { + asm volatile ("lidt (%[desc])" + : + : [desc] "r" (desc), + : .{ .memory = true } + ); +} + +pub fn sidt(desc: *anyopaque) void { + asm volatile ("sidt (%[desc])" + : + : [desc] "r" (desc), + : .{ .memory = true } + ); +} diff --git a/mirai/asm/interrupts/interrupts.zig b/mirai/asm/interrupts/interrupts.zig new file mode 100644 index 0000000..812ee04 --- /dev/null +++ b/mirai/asm/interrupts/interrupts.zig @@ -0,0 +1,11 @@ +//! Interrupt Assembly Operations + +pub const idt = @import("idt.zig"); +pub const flags = @import("flags.zig"); +pub const stubs = @import("stubs.zig"); + +pub const lidt = idt.lidt; +pub const sidt = idt.sidt; +pub const enable = flags.enable; +pub const disable = flags.disable; +pub const are_enabled = flags.are_enabled; diff --git a/mirai/asm/interrupts/stubs.zig b/mirai/asm/interrupts/stubs.zig new file mode 100644 index 0000000..65b3cd8 --- /dev/null +++ b/mirai/asm/interrupts/stubs.zig @@ -0,0 +1,42 @@ +//! Interrupt Handler Stub Assembly + +pub const push_all = + \\push %%rax + \\push %%rbx + \\push %%rcx + \\push %%rdx + \\push %%rsi + \\push %%rdi + \\push %%rbp + \\push %%r8 + \\push %%r9 + \\push %%r10 + \\push %%r11 + \\push %%r12 + \\push %%r13 + \\push %%r14 + \\push %%r15 +; + +pub const pop_all = + \\pop %%r15 + \\pop %%r14 + \\pop %%r13 + \\pop %%r12 + \\pop %%r11 + \\pop %%r10 + \\pop %%r9 + \\pop %%r8 + \\pop %%rbp + \\pop %%rdi + \\pop %%rsi + \\pop %%rdx + \\pop %%rcx + \\pop %%rbx + \\pop %%rax +; + +pub const iret_cleanup = + \\add $16, %%rsp + \\iretq +; diff --git a/mirai/crimson/classify/analyze.zig b/mirai/crimson/classify/analyze.zig index e4287a4..b7c9818 100644 --- a/mirai/crimson/classify/analyze.zig +++ b/mirai/crimson/classify/analyze.zig @@ -1,16 +1,29 @@ //! Analyze Error Codes pub const PageFaultError = struct { - present: bool, write: bool, user: bool, reserved_write: bool, instruction_fetch: bool, + present: bool, + write: bool, + user: bool, + reserved_write: bool, + instruction_fetch: bool, pub fn from_error_code(code: u64) PageFaultError { return PageFaultError{ - .present = (code & 1) != 0, .write = (code & 2) != 0, .user = (code & 4) != 0, - .reserved_write = (code & 8) != 0, .instruction_fetch = (code & 16) != 0, + .present = (code & 1) != 0, + .write = (code & 2) != 0, + .user = (code & 4) != 0, + .reserved_write = (code & 8) != 0, + .instruction_fetch = (code & 16) != 0, }; } - pub fn is_not_present(self: PageFaultError) bool { return !self.present; } - pub fn is_write_access(self: PageFaultError) bool { return self.write; } - pub fn is_execute_access(self: PageFaultError) bool { return self.instruction_fetch; } + pub fn is_not_present(self: PageFaultError) bool { + return !self.present; + } + pub fn is_write_access(self: PageFaultError) bool { + return self.write; + } + pub fn is_execute_access(self: PageFaultError) bool { + return self.instruction_fetch; + } pub fn description(self: PageFaultError) []const u8 { if (self.instruction_fetch) return if (self.present) "Execute on non-executable page" else "Execute on non-present page"; if (self.write) return if (self.present) "Write to read-only page" else "Write to non-present page"; @@ -19,7 +32,9 @@ pub const PageFaultError = struct { }; pub const SelectorError = struct { - external: bool, table: u2, index: u13, + external: bool, + table: u2, + index: u13, pub fn from_error_code(code: u64) SelectorError { return SelectorError{ .external = (code & 1) != 0, .table = @truncate((code >> 1) & 0x3), .index = @truncate((code >> 3) & 0x1FFF) }; } diff --git a/mirai/crimson/classify/vector.zig b/mirai/crimson/classify/vector.zig index 213b1ee..5d03a13 100644 --- a/mirai/crimson/classify/vector.zig +++ b/mirai/crimson/classify/vector.zig @@ -4,7 +4,15 @@ const constants = @import("../constants/constants.zig"); const ExceptionType = constants.ExceptionType; const vectors = constants.vectors; -pub fn classify_vector(vector_number: u8) ExceptionType { return vectors.get_exception_type(vector_number); } -pub fn get_vector_name(vector_number: u8) []const u8 { return vectors.get_name(vector_number); } -pub fn vector_has_error_code(vector_number: u8) bool { return vectors.has_error_code(vector_number); } -pub fn is_exception_vector(vector_number: u8) bool { return vector_number < 32; } +pub fn classify_vector(vector_number: u8) ExceptionType { + return vectors.get_exception_type(vector_number); +} +pub fn get_vector_name(vector_number: u8) []const u8 { + return vectors.get_name(vector_number); +} +pub fn vector_has_error_code(vector_number: u8) bool { + return vectors.has_error_code(vector_number); +} +pub fn is_exception_vector(vector_number: u8) bool { + return vector_number < 32; +} diff --git a/mirai/crimson/constants/flavors.zig b/mirai/crimson/constants/flavors.zig index 4639522..b614bd9 100644 --- a/mirai/crimson/constants/flavors.zig +++ b/mirai/crimson/constants/flavors.zig @@ -1,11 +1,29 @@ //! State Flavors pub const Flavor = enum(u8) { - none = 0, general = 1, float = 2, debug = 3, avx = 4, full = 5, - pub fn includes_general(self: Flavor) bool { return self == .general or self == .full; } - pub fn includes_float(self: Flavor) bool { return self == .float or self == .full; } - pub fn includes_debug(self: Flavor) bool { return self == .debug or self == .full; } + none = 0, + general = 1, + float = 2, + debug = 3, + avx = 4, + full = 5, + pub fn includes_general(self: Flavor) bool { + return self == .general or self == .full; + } + pub fn includes_float(self: Flavor) bool { + return self == .float or self == .full; + } + pub fn includes_debug(self: Flavor) bool { + return self == .debug or self == .full; + } pub fn name(self: Flavor) []const u8 { - return switch (self) { .none => "None", .general => "General", .float => "Float", .debug => "Debug", .avx => "AVX", .full => "Full" }; + return switch (self) { + .none => "None", + .general => "General", + .float => "Float", + .debug => "Debug", + .avx => "AVX", + .full => "Full", + }; } }; diff --git a/mirai/crimson/constants/vectors.zig b/mirai/crimson/constants/vectors.zig index 92d903b..684683f 100644 --- a/mirai/crimson/constants/vectors.zig +++ b/mirai/crimson/constants/vectors.zig @@ -27,16 +27,22 @@ pub const vectors = [_]Vector{ }; pub fn get_exception_type(vector_number: u8) ExceptionType { - for (vectors) |v| { if (v.number == vector_number) return v.exception_type; } + for (vectors) |v| { + if (v.number == vector_number) return v.exception_type; + } return .forbidden; } pub fn has_error_code(vector_number: u8) bool { - for (vectors) |v| { if (v.number == vector_number) return v.has_error_code; } + for (vectors) |v| { + if (v.number == vector_number) return v.has_error_code; + } return false; } pub fn get_name(vector_number: u8) []const u8 { - for (vectors) |v| { if (v.number == vector_number) return v.name; } + for (vectors) |v| { + if (v.number == vector_number) return v.name; + } return "Unknown"; } diff --git a/mirai/crimson/ports/array.zig b/mirai/crimson/ports/array.zig index 6157fc8..1f1d265 100644 --- a/mirai/crimson/ports/array.zig +++ b/mirai/crimson/ports/array.zig @@ -9,10 +9,24 @@ pub const exception_type_count = 10; pub const PortArray = struct { ports: [exception_type_count]Port, - pub fn init() PortArray { var a = PortArray{ .ports = undefined }; for (&a.ports) |*p| p.clear(); return a; } - pub fn get(self: *PortArray, t: ExceptionType) *Port { return &self.ports[@intFromEnum(t)]; } - pub fn get_const(self: *const PortArray, t: ExceptionType) *const Port { return &self.ports[@intFromEnum(t)]; } - pub fn set(self: *PortArray, t: ExceptionType, port: Port) void { self.ports[@intFromEnum(t)] = port; } - pub fn clear_all(self: *PortArray) void { for (&self.ports) |*p| p.clear(); } - pub fn has_port(self: *const PortArray, t: ExceptionType) bool { return self.get_const(t).is_valid(); } + pub fn init() PortArray { + var a = PortArray{ .ports = undefined }; + for (&a.ports) |*p| p.clear(); + return a; + } + pub fn get(self: *PortArray, t: ExceptionType) *Port { + return &self.ports[@intFromEnum(t)]; + } + pub fn get_const(self: *const PortArray, t: ExceptionType) *const Port { + return &self.ports[@intFromEnum(t)]; + } + pub fn set(self: *PortArray, t: ExceptionType, port: Port) void { + self.ports[@intFromEnum(t)] = port; + } + pub fn clear_all(self: *PortArray) void { + for (&self.ports) |*p| p.clear(); + } + pub fn has_port(self: *const PortArray, t: ExceptionType) bool { + return self.get_const(t).is_valid(); + } }; diff --git a/mirai/crimson/ports/port.zig b/mirai/crimson/ports/port.zig index 79d9844..3e4263a 100644 --- a/mirai/crimson/ports/port.zig +++ b/mirai/crimson/ports/port.zig @@ -11,7 +11,15 @@ pub fn create(port_id: u64, owner: PortOwner, owner_id: u64) Port { return Port{ .port_id = port_id, .behavior = .default, .flavor = .general, .owner = owner, .owner_id = owner_id, .active = true }; } -pub fn set_behavior(port: *Port, behavior: Behavior) void { port.behavior = behavior; } -pub fn set_flavor(port: *Port, flavor: Flavor) void { port.flavor = flavor; } -pub fn activate(port: *Port) void { port.active = true; } -pub fn deactivate(port: *Port) void { port.active = false; } +pub fn set_behavior(port: *Port, behavior: Behavior) void { + port.behavior = behavior; +} +pub fn set_flavor(port: *Port, flavor: Flavor) void { + port.flavor = flavor; +} +pub fn activate(port: *Port) void { + port.active = true; +} +pub fn deactivate(port: *Port) void { + port.active = false; +} diff --git a/mirai/crimson/types/context.zig b/mirai/crimson/types/context.zig index 710e25f..8df912e 100644 --- a/mirai/crimson/types/context.zig +++ b/mirai/crimson/types/context.zig @@ -1,20 +1,47 @@ //! CPU Context pub const Context = extern struct { - rax: u64 = 0, rbx: u64 = 0, rcx: u64 = 0, rdx: u64 = 0, - rsi: u64 = 0, rdi: u64 = 0, rbp: u64 = 0, rsp: u64 = 0, - r8: u64 = 0, r9: u64 = 0, r10: u64 = 0, r11: u64 = 0, - r12: u64 = 0, r13: u64 = 0, r14: u64 = 0, r15: u64 = 0, - rip: u64 = 0, rflags: u64 = 0, - cs: u16 = 0, ds: u16 = 0, es: u16 = 0, fs: u16 = 0, gs: u16 = 0, ss: u16 = 0, + rax: u64 = 0, + rbx: u64 = 0, + rcx: u64 = 0, + rdx: u64 = 0, + rsi: u64 = 0, + rdi: u64 = 0, + rbp: u64 = 0, + rsp: u64 = 0, + r8: u64 = 0, + r9: u64 = 0, + r10: u64 = 0, + r11: u64 = 0, + r12: u64 = 0, + r13: u64 = 0, + r14: u64 = 0, + r15: u64 = 0, + rip: u64 = 0, + rflags: u64 = 0, + cs: u16 = 0, + ds: u16 = 0, + es: u16 = 0, + fs: u16 = 0, + gs: u16 = 0, + ss: u16 = 0, padding: u32 = 0, - cr0: u64 = 0, cr2: u64 = 0, cr3: u64 = 0, cr4: u64 = 0, + cr0: u64 = 0, + cr2: u64 = 0, + cr3: u64 = 0, + cr4: u64 = 0, pub fn clear(self: *Context) void { self.* = Context{}; } - pub fn is_user_mode(self: *const Context) bool { return (self.cs & 0x3) == 3; } - pub fn is_kernel_mode(self: *const Context) bool { return (self.cs & 0x3) == 0; } - pub fn get_fault_address(self: *const Context) u64 { return self.cr2; } + pub fn is_user_mode(self: *const Context) bool { + return (self.cs & 0x3) == 3; + } + pub fn is_kernel_mode(self: *const Context) bool { + return (self.cs & 0x3) == 0; + } + pub fn get_fault_address(self: *const Context) u64 { + return self.cr2; + } }; diff --git a/mirai/crimson/types/corpse.zig b/mirai/crimson/types/corpse.zig index 4e3479c..4790aa8 100644 --- a/mirai/crimson/types/corpse.zig +++ b/mirai/crimson/types/corpse.zig @@ -8,11 +8,32 @@ const constants = @import("../constants/constants.zig"); const ExceptionType = constants.ExceptionType; pub const Corpse = struct { - kata_id: u64, thread_id: u64, exception_type: ExceptionType, exception_code: u64, exception_subcode: u64, - fault_address: u64, identity: Identity, context: Context, float_state: FloatState, debug_state: DebugState, - stack_snapshot: [4096]u8, stack_snapshot_size: u64, memory_snapshot: [4096]u8, - memory_snapshot_address: u64, memory_snapshot_size: u64, timestamp: u64, valid: bool, - pub fn clear(self: *Corpse) void { self.valid = false; self.stack_snapshot_size = 0; self.memory_snapshot_size = 0; } - pub fn is_valid(self: *const Corpse) bool { return self.valid; } - pub fn mark_valid(self: *Corpse) void { self.valid = true; } + kata_id: u64, + thread_id: u64, + exception_type: ExceptionType, + exception_code: u64, + exception_subcode: u64, + fault_address: u64, + identity: Identity, + context: Context, + float_state: FloatState, + debug_state: DebugState, + stack_snapshot: [4096]u8, + stack_snapshot_size: u64, + memory_snapshot: [4096]u8, + memory_snapshot_address: u64, + memory_snapshot_size: u64, + timestamp: u64, + valid: bool, + pub fn clear(self: *Corpse) void { + self.valid = false; + self.stack_snapshot_size = 0; + self.memory_snapshot_size = 0; + } + pub fn is_valid(self: *const Corpse) bool { + return self.valid; + } + pub fn mark_valid(self: *Corpse) void { + self.valid = true; + } }; diff --git a/mirai/crimson/types/exception.zig b/mirai/crimson/types/exception.zig index 47723e5..1b9d5ec 100644 --- a/mirai/crimson/types/exception.zig +++ b/mirai/crimson/types/exception.zig @@ -6,12 +6,30 @@ const Frame = @import("frame.zig").Frame; const ExceptionType = constants.ExceptionType; pub const Exception = struct { - exception_type: ExceptionType, code: u64, subcode: u64, vector: u8, address: u64, - context: *Context, frame: *Frame, kata_id: u64, thread_id: u64, recoverable: bool, + exception_type: ExceptionType, + code: u64, + subcode: u64, + vector: u8, + address: u64, + context: *Context, + frame: *Frame, + kata_id: u64, + thread_id: u64, + recoverable: bool, - pub fn is_kernel(self: *const Exception) bool { return self.kata_id == 0; } - pub fn is_user(self: *const Exception) bool { return self.kata_id != 0; } - pub fn is_page_fault(self: *const Exception) bool { return self.vector == 14; } - pub fn is_fatal(self: *const Exception) bool { return !self.recoverable; } - pub fn get_type_name(self: *const Exception) []const u8 { return self.exception_type.name(); } + pub fn is_kernel(self: *const Exception) bool { + return self.kata_id == 0; + } + pub fn is_user(self: *const Exception) bool { + return self.kata_id != 0; + } + pub fn is_page_fault(self: *const Exception) bool { + return self.vector == 14; + } + pub fn is_fatal(self: *const Exception) bool { + return !self.recoverable; + } + pub fn get_type_name(self: *const Exception) []const u8 { + return self.exception_type.name(); + } }; diff --git a/mirai/crimson/types/frame.zig b/mirai/crimson/types/frame.zig index 5960654..20f89fb 100644 --- a/mirai/crimson/types/frame.zig +++ b/mirai/crimson/types/frame.zig @@ -1,11 +1,24 @@ //! Interrupt Stack Frame pub const Frame = extern struct { - error_code: u64, rip: u64, cs: u64, rflags: u64, rsp: u64, ss: u64, - pub fn is_user_mode(self: *const Frame) bool { return (self.cs & 0x3) == 3; } - pub fn is_kernel_mode(self: *const Frame) bool { return (self.cs & 0x3) == 0; } + error_code: u64, + rip: u64, + cs: u64, + rflags: u64, + rsp: u64, + ss: u64, + pub fn is_user_mode(self: *const Frame) bool { + return (self.cs & 0x3) == 3; + } + pub fn is_kernel_mode(self: *const Frame) bool { + return (self.cs & 0x3) == 0; + } }; pub const FrameNoError = extern struct { - rip: u64, cs: u64, rflags: u64, rsp: u64, ss: u64, + rip: u64, + cs: u64, + rflags: u64, + rsp: u64, + ss: u64, }; diff --git a/mirai/crimson/types/identity.zig b/mirai/crimson/types/identity.zig index 197ca22..cc02149 100644 --- a/mirai/crimson/types/identity.zig +++ b/mirai/crimson/types/identity.zig @@ -1,8 +1,16 @@ //! Exception Identity pub const Identity = struct { - thread_id: u64, kata_id: u64, thread_port: u64, kata_port: u64, - thread_name: [32]u8, kata_name: [32]u8, - pub fn clear(self: *Identity) void { self.* = Identity{ .thread_id = 0, .kata_id = 0, .thread_port = 0, .kata_port = 0, .thread_name = [_]u8{0} ** 32, .kata_name = [_]u8{0} ** 32 }; } - pub fn is_kernel(self: *const Identity) bool { return self.kata_id == 0; } + thread_id: u64, + kata_id: u64, + thread_port: u64, + kata_port: u64, + thread_name: [32]u8, + kata_name: [32]u8, + pub fn clear(self: *Identity) void { + self.* = Identity{ .thread_id = 0, .kata_id = 0, .thread_port = 0, .kata_port = 0, .thread_name = [_]u8{0} ** 32, .kata_name = [_]u8{0} ** 32 }; + } + pub fn is_kernel(self: *const Identity) bool { + return self.kata_id == 0; + } }; diff --git a/mirai/crimson/types/port.zig b/mirai/crimson/types/port.zig index dd01851..fc47fc4 100644 --- a/mirai/crimson/types/port.zig +++ b/mirai/crimson/types/port.zig @@ -7,9 +7,18 @@ const Flavor = constants.Flavor; pub const PortOwner = enum(u8) { none = 0, thread = 1, kata = 2, host = 3 }; pub const Port = struct { - port_id: u64, behavior: Behavior, flavor: Flavor, owner: PortOwner, owner_id: u64, active: bool, - pub fn is_valid(self: *const Port) bool { return self.port_id != 0 and self.active; } - pub fn clear(self: *Port) void { self.* = Port{ .port_id = 0, .behavior = .default, .flavor = .none, .owner = .none, .owner_id = 0, .active = false }; } + port_id: u64, + behavior: Behavior, + flavor: Flavor, + owner: PortOwner, + owner_id: u64, + active: bool, + pub fn is_valid(self: *const Port) bool { + return self.port_id != 0 and self.active; + } + pub fn clear(self: *Port) void { + self.* = Port{ .port_id = 0, .behavior = .default, .flavor = .none, .owner = .none, .owner_id = 0, .active = false }; + } }; pub fn create_port(port_id: u64, owner: PortOwner, owner_id: u64) Port { diff --git a/mirai/drivers/drivers.zig b/mirai/drivers/drivers.zig index b12736b..424397a 100644 --- a/mirai/drivers/drivers.zig +++ b/mirai/drivers/drivers.zig @@ -1,3 +1,4 @@ //! Drivers pub const serial = @import("serial/serial.zig"); +pub const pit = @import("pit/pit.zig"); diff --git a/mirai/drivers/pit/constants.zig b/mirai/drivers/pit/constants.zig new file mode 100644 index 0000000..9aa8dec --- /dev/null +++ b/mirai/drivers/pit/constants.zig @@ -0,0 +1,15 @@ +//! PIT Constants + +pub const channel0_data: u16 = 0x40; +pub const channel1_data: u16 = 0x41; +pub const channel2_data: u16 = 0x42; +pub const command: u16 = 0x43; + +pub const base_frequency: u32 = 1193182; +pub const target_frequency: u32 = 1000; + +pub const mode_square_wave: u8 = 0x36; +pub const mode_rate_generator: u8 = 0x34; + +pub const irq: u4 = 0; +pub const vector: u8 = 32; diff --git a/mirai/drivers/pit/handler.zig b/mirai/drivers/pit/handler.zig new file mode 100644 index 0000000..4d3d3b0 --- /dev/null +++ b/mirai/drivers/pit/handler.zig @@ -0,0 +1,35 @@ +//! PIT IRQ Handler + +const constants = @import("constants.zig"); +const pic = @import("../../interrupts/pic/pic.zig"); +const idt = @import("../../interrupts/idt.zig"); + +var ticks: u64 = 0; +var tick_callback: ?*const fn () void = null; + +pub fn handler(_: u8) void { + ticks += 1; + + if (tick_callback) |callback| { + callback(); + } + + pic.send_eoi(constants.irq); +} + +pub fn register() void { + idt.register_irq(constants.irq, &handler); + pic.enable_irq(constants.irq); +} + +pub fn set_callback(callback: *const fn () void) void { + tick_callback = callback; +} + +pub fn clear_callback() void { + tick_callback = null; +} + +pub fn get_ticks() u64 { + return ticks; +} diff --git a/mirai/drivers/pit/init.zig b/mirai/drivers/pit/init.zig new file mode 100644 index 0000000..f31e47f --- /dev/null +++ b/mirai/drivers/pit/init.zig @@ -0,0 +1,16 @@ +//! PIT Initialization + +const constants = @import("constants.zig"); +const asm_io = @import("../../asm/io/io.zig"); + +pub fn init(frequency: u32) void { + const divisor: u16 = @truncate(constants.base_frequency / frequency); + + asm_io.outb(constants.command, constants.mode_square_wave); + asm_io.outb(constants.channel0_data, @truncate(divisor)); + asm_io.outb(constants.channel0_data, @truncate(divisor >> 8)); +} + +pub fn init_default() void { + init(constants.target_frequency); +} diff --git a/mirai/drivers/pit/pit.zig b/mirai/drivers/pit/pit.zig new file mode 100644 index 0000000..db0f12a --- /dev/null +++ b/mirai/drivers/pit/pit.zig @@ -0,0 +1,10 @@ +//! PIT - Programmable Interval Timer + +pub const constants = @import("constants.zig"); +pub const init = @import("init.zig"); +pub const handler = @import("handler.zig"); + +pub const initialize = init.init_default; +pub const register = handler.register; +pub const set_callback = handler.set_callback; +pub const get_ticks = handler.get_ticks; diff --git a/mirai/interrupts/handlers/common.zig b/mirai/interrupts/handlers/common.zig new file mode 100644 index 0000000..9c80580 --- /dev/null +++ b/mirai/interrupts/handlers/common.zig @@ -0,0 +1,30 @@ +//! Common Interrupt Entry/Exit + +pub const InterruptFrame = extern struct { + r15: u64, + r14: u64, + r13: u64, + r12: u64, + r11: u64, + r10: u64, + r9: u64, + r8: u64, + rbp: u64, + rdi: u64, + rsi: u64, + rdx: u64, + rcx: u64, + rbx: u64, + rax: u64, + vector: u64, + error_code: u64, + rip: u64, + cs: u64, + rflags: u64, + rsp: u64, + ss: u64, +}; + +comptime { + if (@sizeOf(InterruptFrame) != 22 * 8) @compileError("InterruptFrame size mismatch"); +} diff --git a/mirai/interrupts/handlers/exceptions.zig b/mirai/interrupts/handlers/exceptions.zig new file mode 100644 index 0000000..87e63db --- /dev/null +++ b/mirai/interrupts/handlers/exceptions.zig @@ -0,0 +1,89 @@ +//! Exception Handler Stubs (Vectors 0-31) + +const common = @import("common.zig"); +const InterruptFrame = common.InterruptFrame; +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); + + var exception = crimson.handlers.create_exception( + vector, + frame.error_code, + frame.rip, + frame.rsp, + ); + + const action = crimson.handlers.dispatch(&exception); + + switch (action) { + .resume_execution => {}, + .terminate => crimson.collapse(&exception), + .collapse => crimson.collapse(&exception), + else => crimson.collapse(&exception), + } +} + +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 stubs = [32]*const fn () callconv(.Naked) void{ + &exception_0, &exception_1, &exception_2, &exception_3, + &exception_4, &exception_5, &exception_6, &exception_7, + &exception_8, &exception_9, &exception_10, &exception_11, + &exception_12, &exception_13, &exception_14, &exception_15, + &exception_16, &exception_17, &exception_18, &exception_19, + &exception_20, &exception_21, &exception_22, &exception_23, + &exception_24, &exception_25, &exception_26, &exception_27, + &exception_28, &exception_29, &exception_30, &exception_31, +}; diff --git a/mirai/interrupts/handlers/handlers.zig b/mirai/interrupts/handlers/handlers.zig new file mode 100644 index 0000000..f32cc8e --- /dev/null +++ b/mirai/interrupts/handlers/handlers.zig @@ -0,0 +1,9 @@ +//! IDT Handlers + +pub const common = @import("common.zig"); +pub const exceptions = @import("exceptions.zig"); +pub const hardware = @import("hardware.zig"); + +pub const InterruptFrame = common.InterruptFrame; +pub const register_irq = hardware.register_handler; +pub const unregister_irq = hardware.unregister_handler; diff --git a/mirai/interrupts/handlers/hardware.zig b/mirai/interrupts/handlers/hardware.zig new file mode 100644 index 0000000..6b1d09d --- /dev/null +++ b/mirai/interrupts/handlers/hardware.zig @@ -0,0 +1,66 @@ +//! Hardware IRQ Stubs (Vectors 32-47) + +const common = @import("common.zig"); +const InterruptFrame = common.InterruptFrame; +const asm_stubs = @import("../../asm/interrupts/stubs.zig"); + +var irq_handlers: [16]?*const fn (u8) void = [_]?*const fn (u8) void{null} ** 16; + +pub fn register_handler(irq: u4, handler: *const fn (u8) void) void { + irq_handlers[irq] = handler; +} + +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; + + if (irq < 16) { + if (irq_handlers[irq]) |handler| { + handler(irq); + } + } +} + +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 stubs = [16]*const fn () callconv(.Naked) void{ + &irq_0, &irq_1, &irq_2, &irq_3, + &irq_4, &irq_5, &irq_6, &irq_7, + &irq_8, &irq_9, &irq_10, &irq_11, + &irq_12, &irq_13, &irq_14, &irq_15, +}; diff --git a/mirai/interrupts/idt.zig b/mirai/interrupts/idt.zig new file mode 100644 index 0000000..7cafb4f --- /dev/null +++ b/mirai/interrupts/idt.zig @@ -0,0 +1,49 @@ +//! IDT - Interrupt Descriptor Table + +const gdt = @import("../boot/gdt/gdt.zig"); +const asm_int = @import("../asm/interrupts/interrupts.zig"); + +pub const types = @import("types/types.zig"); +pub const table = @import("table/table.zig"); +pub const handlers = @import("handlers/handlers.zig"); +pub const load = @import("load/load.zig"); +pub const pic = @import("pic/pic.zig"); + +pub const Gate64 = types.Gate64; +pub const Descriptor = types.Descriptor; +pub const InterruptFrame = handlers.InterruptFrame; + +pub const set_gate = table.set_gate; +pub const set_interrupt = table.set_interrupt; +pub const set_trap = table.set_trap; +pub const register_irq = handlers.register_irq; +pub const unregister_irq = handlers.unregister_irq; + +pub fn initialize() void { + pic.remap(); + pic.mask_all(); + + const selector = gdt.selectors.kernel_code_selector; + + for (0..32) |i| { + const vector: u8 = @truncate(i); + const handler_ptr = @intFromPtr(handlers.exceptions.stubs[i]); + table.set_interrupt(vector, handler_ptr, selector); + } + + for (0..16) |i| { + const vector: u8 = @truncate(i + 32); + const handler_ptr = @intFromPtr(handlers.hardware.stubs[i]); + table.set_interrupt(vector, handler_ptr, selector); + } + + load.load(); +} + +pub fn enable() void { + asm_int.enable(); +} + +pub fn disable() void { + asm_int.disable(); +} diff --git a/mirai/interrupts/load/lidt.zig b/mirai/interrupts/load/lidt.zig new file mode 100644 index 0000000..926518d --- /dev/null +++ b/mirai/interrupts/load/lidt.zig @@ -0,0 +1,20 @@ +//! LIDT Operations + +const types = @import("../types/types.zig"); +const table = @import("../table/table.zig"); +const asm_int = @import("../../asm/interrupts/interrupts.zig"); + +pub fn lidt(desc: *const types.Descriptor) void { + asm_int.lidt(desc); +} + +pub fn load() void { + const desc = types.Descriptor.from_table(&table.entries.entries); + lidt(&desc); +} + +pub fn sidt() types.Descriptor { + var desc: types.Descriptor = undefined; + asm_int.sidt(&desc); + return desc; +} diff --git a/mirai/interrupts/load/load.zig b/mirai/interrupts/load/load.zig new file mode 100644 index 0000000..567a9f0 --- /dev/null +++ b/mirai/interrupts/load/load.zig @@ -0,0 +1,6 @@ +//! IDT Load Operations + +pub const lidt = @import("lidt.zig"); + +pub const load = lidt.load; +pub const sidt = lidt.sidt; diff --git a/mirai/interrupts/pic/eoi.zig b/mirai/interrupts/pic/eoi.zig new file mode 100644 index 0000000..810ea37 --- /dev/null +++ b/mirai/interrupts/pic/eoi.zig @@ -0,0 +1,20 @@ +//! PIC End-of-Interrupt + +const ports = @import("ports.zig"); +const asm_io = @import("../../asm/io/io.zig"); + +pub fn send(irq: u4) void { + if (irq >= 8) { + asm_io.outb(ports.pic2_command, ports.eoi); + } + asm_io.outb(ports.pic1_command, ports.eoi); +} + +pub fn send_master() void { + asm_io.outb(ports.pic1_command, ports.eoi); +} + +pub fn send_slave() void { + asm_io.outb(ports.pic2_command, ports.eoi); + asm_io.outb(ports.pic1_command, ports.eoi); +} diff --git a/mirai/interrupts/pic/init.zig b/mirai/interrupts/pic/init.zig new file mode 100644 index 0000000..2f84b8a --- /dev/null +++ b/mirai/interrupts/pic/init.zig @@ -0,0 +1,41 @@ +//! PIC Initialization + +const ports = @import("ports.zig"); +const asm_io = @import("../../asm/io/io.zig"); + +pub fn remap() void { + const mask1 = asm_io.inb(ports.pic1_data); + const mask2 = asm_io.inb(ports.pic2_data); + + asm_io.outb(ports.pic1_command, ports.icw1_init | ports.icw1_icw4); + io_wait(); + asm_io.outb(ports.pic2_command, ports.icw1_init | ports.icw1_icw4); + io_wait(); + + asm_io.outb(ports.pic1_data, ports.vector_offset_master); + io_wait(); + asm_io.outb(ports.pic2_data, ports.vector_offset_slave); + io_wait(); + + asm_io.outb(ports.pic1_data, 4); + io_wait(); + asm_io.outb(ports.pic2_data, 2); + io_wait(); + + asm_io.outb(ports.pic1_data, ports.icw4_8086); + io_wait(); + asm_io.outb(ports.pic2_data, ports.icw4_8086); + io_wait(); + + asm_io.outb(ports.pic1_data, mask1); + asm_io.outb(ports.pic2_data, mask2); +} + +pub fn disable() void { + asm_io.outb(ports.pic1_data, 0xFF); + asm_io.outb(ports.pic2_data, 0xFF); +} + +fn io_wait() void { + asm_io.outb(0x80, 0); +} diff --git a/mirai/interrupts/pic/mask.zig b/mirai/interrupts/pic/mask.zig new file mode 100644 index 0000000..3b98e28 --- /dev/null +++ b/mirai/interrupts/pic/mask.zig @@ -0,0 +1,40 @@ +//! PIC IRQ Masking + +const ports = @import("ports.zig"); +const asm_io = @import("../../asm/io/io.zig"); + +pub fn enable_irq(irq: u4) void { + if (irq < 8) { + const mask = asm_io.inb(ports.pic1_data); + asm_io.outb(ports.pic1_data, mask & ~(@as(u8, 1) << @truncate(irq))); + } else { + const mask = asm_io.inb(ports.pic2_data); + asm_io.outb(ports.pic2_data, mask & ~(@as(u8, 1) << @truncate(irq - 8))); + } +} + +pub fn disable_irq(irq: u4) void { + if (irq < 8) { + const mask = asm_io.inb(ports.pic1_data); + asm_io.outb(ports.pic1_data, mask | (@as(u8, 1) << @truncate(irq))); + } else { + const mask = asm_io.inb(ports.pic2_data); + asm_io.outb(ports.pic2_data, mask | (@as(u8, 1) << @truncate(irq - 8))); + } +} + +pub fn mask_all() void { + asm_io.outb(ports.pic1_data, 0xFF); + asm_io.outb(ports.pic2_data, 0xFF); +} + +pub fn unmask_all() void { + asm_io.outb(ports.pic1_data, 0x00); + asm_io.outb(ports.pic2_data, 0x00); +} + +pub fn get_mask() u16 { + const low = asm_io.inb(ports.pic1_data); + const high = asm_io.inb(ports.pic2_data); + return @as(u16, high) << 8 | low; +} diff --git a/mirai/interrupts/pic/pic.zig b/mirai/interrupts/pic/pic.zig new file mode 100644 index 0000000..ee34508 --- /dev/null +++ b/mirai/interrupts/pic/pic.zig @@ -0,0 +1,13 @@ +//! PIC - 8259A Programmable Interrupt Controller + +pub const ports = @import("ports.zig"); +pub const init = @import("init.zig"); +pub const mask = @import("mask.zig"); +pub const eoi = @import("eoi.zig"); + +pub const remap = init.remap; +pub const disable = init.disable; +pub const enable_irq = mask.enable_irq; +pub const disable_irq = mask.disable_irq; +pub const mask_all = mask.mask_all; +pub const send_eoi = eoi.send; diff --git a/mirai/interrupts/pic/ports.zig b/mirai/interrupts/pic/ports.zig new file mode 100644 index 0000000..aba363f --- /dev/null +++ b/mirai/interrupts/pic/ports.zig @@ -0,0 +1,15 @@ +//! PIC I/O Ports + +pub const pic1_command: u16 = 0x20; +pub const pic1_data: u16 = 0x21; +pub const pic2_command: u16 = 0xA0; +pub const pic2_data: u16 = 0xA1; + +pub const icw1_icw4: u8 = 0x01; +pub const icw1_init: u8 = 0x10; +pub const icw4_8086: u8 = 0x01; + +pub const eoi: u8 = 0x20; + +pub const vector_offset_master: u8 = 32; +pub const vector_offset_slave: u8 = 40; diff --git a/mirai/interrupts/table/entries.zig b/mirai/interrupts/table/entries.zig new file mode 100644 index 0000000..d62b1e7 --- /dev/null +++ b/mirai/interrupts/table/entries.zig @@ -0,0 +1,5 @@ +//! IDT Entries Table + +const types = @import("../types/types.zig"); + +pub var entries: [256]types.Gate64 = [_]types.Gate64{types.Gate64.empty()} ** 256; diff --git a/mirai/interrupts/table/install.zig b/mirai/interrupts/table/install.zig new file mode 100644 index 0000000..72b9bab --- /dev/null +++ b/mirai/interrupts/table/install.zig @@ -0,0 +1,27 @@ +//! IDT Gate Installation + +const types = @import("../types/types.zig"); +const entries = @import("entries.zig"); + +pub fn set_gate(vector: u8, handler: u64, selector: u16, ist: u3, dpl: types.DPL, gate_type: types.GateType) void { + entries.entries[vector] = switch (gate_type) { + .interrupt => types.Gate64.interrupt(handler, selector, ist, dpl), + .trap => types.Gate64.trap(handler, selector, ist, dpl), + }; +} + +pub fn set_interrupt(vector: u8, handler: u64, selector: u16) void { + set_gate(vector, handler, selector, 0, .ring0, .interrupt); +} + +pub fn set_trap(vector: u8, handler: u64, selector: u16) void { + set_gate(vector, handler, selector, 0, .ring0, .trap); +} + +pub fn set_interrupt_ist(vector: u8, handler: u64, selector: u16, ist: u3) void { + set_gate(vector, handler, selector, ist, .ring0, .interrupt); +} + +pub fn clear_gate(vector: u8) void { + entries.entries[vector] = types.Gate64.empty(); +} diff --git a/mirai/interrupts/table/table.zig b/mirai/interrupts/table/table.zig new file mode 100644 index 0000000..70e46bf --- /dev/null +++ b/mirai/interrupts/table/table.zig @@ -0,0 +1,10 @@ +//! IDT Table + +pub const entries = @import("entries.zig"); +pub const install = @import("install.zig"); + +pub const set_gate = install.set_gate; +pub const set_interrupt = install.set_interrupt; +pub const set_trap = install.set_trap; +pub const set_interrupt_ist = install.set_interrupt_ist; +pub const clear_gate = install.clear_gate; diff --git a/mirai/interrupts/types/descriptor.zig b/mirai/interrupts/types/descriptor.zig new file mode 100644 index 0000000..7b9865d --- /dev/null +++ b/mirai/interrupts/types/descriptor.zig @@ -0,0 +1,19 @@ +//! IDT Descriptor for LIDT + +const gate = @import("gate.zig"); + +pub const Descriptor = packed struct(u80) { + limit: u16, + base: u64, + + pub fn from_table(table: *const [256]gate.Gate64) Descriptor { + return Descriptor{ + .limit = @sizeOf([256]gate.Gate64) - 1, + .base = @intFromPtr(table), + }; + } +}; + +comptime { + if (@sizeOf(Descriptor) != 10) @compileError("Descriptor must be 10 bytes"); +} diff --git a/mirai/interrupts/types/gate.zig b/mirai/interrupts/types/gate.zig new file mode 100644 index 0000000..ff046a2 --- /dev/null +++ b/mirai/interrupts/types/gate.zig @@ -0,0 +1,67 @@ +//! IDT Gate Descriptor (64-bit) + +pub const GateType = enum(u4) { + interrupt = 0xE, + trap = 0xF, +}; + +pub const DPL = enum(u2) { + ring0 = 0, + ring1 = 1, + ring2 = 2, + ring3 = 3, +}; + +pub const Gate64 = packed struct(u128) { + offset_low: u16, + selector: u16, + ist: u3, + reserved0: u5 = 0, + gate_type: GateType, + zero: u1 = 0, + dpl: DPL, + present: bool, + offset_mid: u16, + offset_high: u32, + reserved1: u32 = 0, + + pub fn empty() Gate64 { + return @bitCast(@as(u128, 0)); + } + + pub fn interrupt(handler: u64, selector: u16, ist: u3, dpl: DPL) Gate64 { + return Gate64{ + .offset_low = @truncate(handler), + .selector = selector, + .ist = ist, + .gate_type = .interrupt, + .dpl = dpl, + .present = true, + .offset_mid = @truncate(handler >> 16), + .offset_high = @truncate(handler >> 32), + }; + } + + pub fn trap(handler: u64, selector: u16, ist: u3, dpl: DPL) Gate64 { + return Gate64{ + .offset_low = @truncate(handler), + .selector = selector, + .ist = ist, + .gate_type = .trap, + .dpl = dpl, + .present = true, + .offset_mid = @truncate(handler >> 16), + .offset_high = @truncate(handler >> 32), + }; + } + + pub fn get_offset(self: Gate64) u64 { + return @as(u64, self.offset_low) | + (@as(u64, self.offset_mid) << 16) | + (@as(u64, self.offset_high) << 32); + } +}; + +comptime { + if (@sizeOf(Gate64) != 16) @compileError("Gate64 must be 16 bytes"); +} diff --git a/mirai/interrupts/types/types.zig b/mirai/interrupts/types/types.zig new file mode 100644 index 0000000..292a2df --- /dev/null +++ b/mirai/interrupts/types/types.zig @@ -0,0 +1,9 @@ +//! IDT Types + +pub const gate = @import("gate.zig"); +pub const descriptor = @import("descriptor.zig"); + +pub const Gate64 = gate.Gate64; +pub const GateType = gate.GateType; +pub const DPL = gate.DPL; +pub const Descriptor = descriptor.Descriptor; diff --git a/mirai/pmm/bitmap/operations.zig b/mirai/pmm/bitmap/operations.zig index d793fa3..cade105 100644 --- a/mirai/pmm/bitmap/operations.zig +++ b/mirai/pmm/bitmap/operations.zig @@ -79,4 +79,4 @@ pub fn count_clear_bits(bitmap: []const u8, max_bit: u64) u64 { } } return count; -}
\ No newline at end of file +} diff --git a/shared/fs/afs/constants/magic.zig b/shared/fs/afs/constants/magic.zig index 757bcab..84f46db 100644 --- a/shared/fs/afs/constants/magic.zig +++ b/shared/fs/afs/constants/magic.zig @@ -12,7 +12,7 @@ pub const journal_signature: u32 = 0x4A4E524C; /// AFS partition type GUID: 414B4942-4146-5300-0000-000000000001 pub const partition_type_guid = [16]u8{ 0x42, 0x49, 0x4B, 0x41, - 0x46, 0x41, - 0x00, 0x53, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x46, 0x41, 0x00, 0x53, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, }; |
