diff --git a/core/src/arch/x86_64/interrupts.zig b/core/src/arch/x86_64/interrupts.zig index 128f5c7..bb8791a 100644 --- a/core/src/arch/x86_64/interrupts.zig +++ b/core/src/arch/x86_64/interrupts.zig @@ -139,7 +139,16 @@ fn pageFault(frame: *InterruptStackFrame) void { } export fn interruptEntry(frame: *InterruptStackFrame) callconv(.C) void { - debug.print("Caught interrupt {d}\n", .{frame.isr}); + if (frame.isr >= 32 and frame.isr < 48) { + // IRQ + const irq_handler = irq_handlers[frame.error_or_irq]; + if (irq_handler) |handler| { + handler(@intCast(frame.error_or_irq), frame); + } + pic.picEOI(@intCast(frame.error_or_irq)); + return; + } + switch (frame.isr) { @intFromEnum(Exceptions.PageFault) => { pageFault(frame); @@ -149,7 +158,7 @@ export fn interruptEntry(frame: *InterruptStackFrame) callconv(.C) void { }, SYSCALL_INTERRUPT => { var args = sys.Arguments{ .arg0 = frame.rdi, .arg1 = frame.rsi, .arg2 = frame.rdx, .arg3 = frame.r10, .arg4 = frame.r8, .arg5 = frame.r9 }; - sys.invokeSyscall(frame.rax, frame, &args, @ptrFromInt(@as(usize, @intFromPtr(&frame.rax)))); + sys.invokeSyscall(frame.rax, frame, &args, @ptrCast(&frame.rax)); }, else => {}, } diff --git a/core/src/arch/x86_64/pit.zig b/core/src/arch/x86_64/pit.zig new file mode 100644 index 0000000..eacb344 --- /dev/null +++ b/core/src/arch/x86_64/pit.zig @@ -0,0 +1,28 @@ +const io = @import("ioports.zig"); +const interrupts = @import("interrupts.zig"); +const pic = @import("pic.zig"); +const thread = @import("../../thread.zig"); + +// Every timer tick is equivalent to 1 millisecond. +const TIMER_RESOLUTION = 1; + +const PIT_CHANNEL_0 = 0x40; + +const base_frequency: u64 = 1193182; + +pub fn initializePIT() void { + const divisor: u16 = @intCast(base_frequency / (TIMER_RESOLUTION * 1000)); + if (divisor < 100) { + @compileError("Timer resolution is too low"); + } + + io.outb(PIT_CHANNEL_0, @as(u8, @intCast(divisor & 0xFF))); + io.outb(0x80, 0); // short delay + io.outb(PIT_CHANNEL_0, @as(u8, @intCast((divisor & 0xFF00) >> 8))); + + _ = interrupts.registerIRQ(0, &pitTimerHandler); +} + +pub fn pitTimerHandler(_: u32, regs: *interrupts.InterruptStackFrame) void { + thread.preempt(regs); +} diff --git a/core/src/arch/x86_64/platform.zig b/core/src/arch/x86_64/platform.zig index c535282..b7aa53f 100644 --- a/core/src/arch/x86_64/platform.zig +++ b/core/src/arch/x86_64/platform.zig @@ -1,6 +1,7 @@ const gdt = @import("gdt.zig"); const idt = @import("idt.zig"); const pic = @import("pic.zig"); +const pit = @import("pit.zig"); const interrupts = @import("interrupts.zig"); pub const PAGE_SIZE = 4096; @@ -26,5 +27,5 @@ pub fn platformInit() void { pub fn platformEndInit() void { pic.remapPIC(); interrupts.syncInterrupts(); - interrupts.enableInterrupts(); + pit.initializePIT(); }