Fix IDT entries to be 32bit

This commit is contained in:
ktkk 2026-10-08 13:40:53 +00:00
parent 7dfdbe10ec
commit f8abe365e9
2 changed files with 27 additions and 44 deletions

View file

@ -1,11 +1,11 @@
const std = @import("std");
pub const InterruptStackFrame = extern struct {
instruction_ptr: u64,
code_segment: u64,
cpu_flags: u64,
stack_ptr: u64,
stack_segment: u64,
instruction_ptr: u32,
code_segment: u32,
cpu_flags: u32,
stack_ptr: u32,
stack_segment: u32,
};
const HandlerFunction = *const fn (_: *InterruptStackFrame) callconv(.{ .x86_interrupt = .{} }) void;
@ -48,7 +48,7 @@ pub const InterruptDescriptorTableEntryType = enum(u8) {
pub fn HandlerFunctionType(self: Self) type {
return switch (self) {
.double_fault, .machine_check => HandlerFunctionWithErrorCode(noreturn),
.double_fault => 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,
};
@ -62,52 +62,33 @@ pub const InterruptDescriptorTable = extern struct {
const Entry = packed struct {
ptr_low: u16,
options: Options,
ptr_mid: u16,
ptr_high: u32,
reserved: u32,
selector: u16,
reserved: u8 = 0,
attributes: std.bit_set.IntegerBitSet(8) = .initEmpty(),
ptr_high: u16,
pub const missing: Entry = .{
.ptr_low = 0,
.options = .minimal,
.ptr_mid = 0,
.selector = 0,
.attributes = .initEmpty(),
.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 {
fn setHandler(self: *Entry, handler_addr: u32) void {
self.ptr_low = @truncate(handler_addr);
self.ptr_mid = @truncate(handler_addr >> 16);
self.ptr_high = @truncate(handler_addr >> 32);
self.ptr_high = @truncate(handler_addr >> 16);
self.options = .minimal;
const segment = asm volatile (
const selector = asm volatile (
\\ mov %%cs, %[segment]
: [segment] "=&r" (-> u16)
:
);
self.options.setCodeSelector(segment);
self.options.setPresent(true);
self.selector = selector;
std.log.info("Setting handler {any}\n", .{ self.* });
self.attributes.set(1);
self.attributes.set(2);
self.attributes.set(3);
self.attributes.set(7);
}
};
@ -126,7 +107,7 @@ pub const InterruptDescriptorTable = extern struct {
pub fn load(self: *InterruptDescriptorTable) void {
const DescriptorTablePointer = packed struct {
limit: u16,
base: u64,
base: u32,
};
const idt: DescriptorTablePointer = .{
.limit = @sizeOf(@TypeOf(self.*)) - 1,
@ -136,7 +117,9 @@ pub const InterruptDescriptorTable = extern struct {
asm volatile (
\\ lidt (%[idt])
:
: [idt] "r" (idt),
: [idt] "r" (&idt),
: .{ .memory = true }
);
}
};

View file

@ -64,13 +64,13 @@ fn kmain(magic: u32, info: *const MultibootInfo) callconv(.c) void {
// :
//);
std.log.info("We did not crash!", .{});
hang();
}
fn breakpointHandler(stack_frame: *InterruptStackFrame) callconv(.{ .x86_interrupt = .{} }) void {
_ = stack_frame;
std.log.err("breakpoint\n", .{});
std.log.err("breakpoint\n{}", .{stack_frame.*});
}
fn hang() noreturn {