From 28c95303e9c33029d93422f05318dda6b65d4cfd Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Tue, 18 Nov 2025 23:27:49 +0100 Subject: [PATCH] Fix PIC, add small delays when initializing --- kernel/intr/intr.c | 17 +++++++++++------ kernel/intr/pic.c | 30 ++++++++++++++++++++++++++---- kernel/intr/pic.h | 6 +++++- kernel/intr/pit.c | 6 ------ kernel/io/io.c | 4 ++++ kernel/io/io.h | 2 ++ kernel/proc/proc.c | 8 ++------ run/qemu-x86_64-hdd.sh | 2 +- 8 files changed, 51 insertions(+), 24 deletions(-) diff --git a/kernel/intr/intr.c b/kernel/intr/intr.c index 57d602a..fed3523 100644 --- a/kernel/intr/intr.c +++ b/kernel/intr/intr.c @@ -186,7 +186,6 @@ void intr_init(void) { idt_init(); intr_pic_init(); intr_pit_init(); - intr_disable(); } void intr_dumpframe(IntrStackFrame *frame) { @@ -246,12 +245,18 @@ void intr_handleintr(IntrStackFrame *frame) { cpu_hang(); } } else if (frame->trapnum >= 32 && frame->trapnum <= 47) { - intr_pic_eoi(); - IntrHandler *ih, *ihtmp; - LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) { - if ((uint64_t)ih->irq == frame->trapnum) { - ih->fn(frame); + if (frame->trapnum == INTR_IRQBASE+0) { + PIT_TICKS++; + intr_pic_eoi(frame->trapnum >= 40); + proc_sched((void *)frame); + } else { + IntrHandler *ih, *ihtmp; + LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) { + if ((uint64_t)ih->irq == frame->trapnum) { + ih->fn(frame); + } } + intr_pic_eoi(frame->trapnum >= 40); } } else if (frame->trapnum == 0x80) { intr_syscalldispatch(frame); diff --git a/kernel/intr/pic.c b/kernel/intr/pic.c index 7465df4..3d945d2 100644 --- a/kernel/intr/pic.c +++ b/kernel/intr/pic.c @@ -25,22 +25,44 @@ void intr_pic_init(void) { io_out8(PIC1_CMD, ICW1_INIT | ICW1_ICW4); + io_wait(); io_out8(PIC2_CMD, ICW1_INIT | ICW1_ICW4); + io_wait(); io_out8(PIC1_DATA, INTR_IRQBASE); + io_wait(); io_out8(PIC2_DATA, INTR_IRQBASE+8); + io_wait(); io_out8(PIC1_DATA, 2); + io_wait(); io_out8(PIC2_DATA, 2); + io_wait(); io_out8(PIC1_DATA, ICW4_8086); + io_wait(); io_out8(PIC2_DATA, ICW4_8086); + io_wait(); - io_out8(PIC1_DATA, 0); - io_out8(PIC2_DATA, 0); + intr_pic_mask(); } -void intr_pic_eoi(void) { - io_out8(PIC2_CMD, PIC_EOI); +void intr_pic_mask(void) { + io_out8(PIC1_DATA, 0xFF); + io_wait(); + io_out8(PIC2_DATA, 0xFF); + io_wait(); +} + +void intr_pic_unmask(void) { + io_out8(PIC1_DATA, 0); + io_wait(); + io_out8(PIC2_DATA, 0); + io_wait(); +} + +void intr_pic_eoi(bool pic2) { + if (pic2) + io_out8(PIC2_CMD, PIC_EOI); io_out8(PIC1_CMD, PIC_EOI); } diff --git a/kernel/intr/pic.h b/kernel/intr/pic.h index 7de9b6c..3a4c1e6 100644 --- a/kernel/intr/pic.h +++ b/kernel/intr/pic.h @@ -1,7 +1,11 @@ #ifndef INTR_PIC_H_ #define INTR_PIC_H_ +#include + void intr_pic_init(void); -void intr_pic_eoi(void); +void intr_pic_eoi(bool pic2); +void intr_pic_mask(void); +void intr_pic_unmask(void); #endif // INTR_PIC_H_ diff --git a/kernel/intr/pit.c b/kernel/intr/pit.c index de6f508..35125f5 100644 --- a/kernel/intr/pit.c +++ b/kernel/intr/pit.c @@ -31,13 +31,7 @@ void intr_pit_wait(uint32_t ms) { while (PIT_TICKS - now < ms); } -void intr_pit_intr(IntrStackFrame *frame) { - PIT_TICKS++; -} - void intr_pit_init(void) { - intr_attchhandler(&intr_pit_intr, INTR_IRQBASE+0); - uint32_t hz = 1000; uint32_t div = PIT_FREQ / hz; io_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0); diff --git a/kernel/io/io.c b/kernel/io/io.c index 57b0f38..d2aa908 100644 --- a/kernel/io/io.c +++ b/kernel/io/io.c @@ -45,3 +45,7 @@ void io_outs16(uint16_t port, const void *addr, int cnt) { : "memory", "cc" ); } + +void io_wait(void) { + io_out8(0x80, 0); +} diff --git a/kernel/io/io.h b/kernel/io/io.h index e155240..6ad98cb 100644 --- a/kernel/io/io.h +++ b/kernel/io/io.h @@ -15,4 +15,6 @@ void io_out32(uint16_t port, uint32_t value); void io_ins16(uint16_t port, void *addr, int cnt); void io_outs16(uint16_t port, const void *addr, int cnt); +void io_wait(void); + #endif // IO_IO_H_ diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 03f86a2..69d8b6b 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -253,21 +253,17 @@ void proc_killself(void) { proc_kill(proc); } -void proc_intr(IntrStackFrame *frame) { - proc_sched(frame); -} - void proc_init(void) { spinlock_init(&PROCS.spinlock); PROCS.procs = NULL; - intr_attchhandler(&proc_intr, INTR_IRQBASE+0); - Proc *init = proc_spawnuser("base", "/bin/init"); PROCS.current = init; proc_register(init); init->state = PROC_READY; + intr_pic_unmask(); + tss.rsp0 = (uint64_t)VIRT(PROCS.current->platformdata.kstack); proc_switch(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3); } diff --git a/run/qemu-x86_64-hdd.sh b/run/qemu-x86_64-hdd.sh index 8e10c5b..ea87073 100755 --- a/run/qemu-x86_64-hdd.sh +++ b/run/qemu-x86_64-hdd.sh @@ -3,7 +3,7 @@ set -x qemu-system-x86_64 \ - -cpu IvyBridge \ + -machine pc \ -m 4G \ -boot d \ -serial stdio \