diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index eb3f170..b768ca2 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -7,10 +7,22 @@ #include #include +#include +#include + void TEMP_test_scheduler(); struct kernel_boot_data_st kernel_boot_data; +registers *kbd_handler(registers *r) +{ + while(inb(0x64) & 0x2); + uint8_t scancode = inb(0x60); + debug("Keyboard: %x\n", scancode); + irq_ack(); + return r; +} + void kmain(uint64_t multiboot_magic, void *multiboot_data) { musl_init(); debug_info("Started kernel\n"); @@ -34,6 +46,8 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) { debug_info("Boot complete\n"); + bind_interrupt(IRQ_INTERRUPT(IRQ_PS2_KBD), kbd_handler); + irq_unmask(IRQ_PS2_KBD); TEMP_test_scheduler(); diff --git a/src/kernel/cpu/apic.c b/src/kernel/cpu/apic.c index be4f839..231faac 100644 --- a/src/kernel/cpu/apic.c +++ b/src/kernel/cpu/apic.c @@ -7,8 +7,12 @@ #define APIC_MSR_ENABLE (1<<11) +#define APIC_EOI 0xB0 +#define APIC_SPURIOUS 0xF0 #define APIC_REG(r) (((uint32_t *)P2V(APIC_BASE + (r)))[0]) +#define IOREDTBL(irq) (0x10 + (irq)*2) + union iored { struct { uint8_t vector; @@ -39,15 +43,32 @@ static void ioapic_write(int reg, uint32_t value) { static uint64_t ioapic_read_redirection(int irq) { union iored retval; - retval.l = ioapic_read(0x10 + 2*irq); - retval.h = ioapic_read(0x11 + 2*irq); + retval.l = ioapic_read(IOREDTBL(irq)); + retval.h = ioapic_read(IOREDTBL(irq)+1); return retval.val; } static void ioapic_write_redirection(int irq, uint64_t val) { union iored value; value.val = val; - ioapic_write(0x10 + 2*irq, value.l); - ioapic_write(0x11 + 2*irq, value.h); + ioapic_write(IOREDTBL(irq), value.l); + ioapic_write(IOREDTBL(irq) + 1, value.h); +} + +void irq_ack() { + APIC_REG(APIC_EOI) = 0; +} + +void irq_mask(int irq) { + union iored iored; + iored.val = ioapic_read_redirection(irq_redirects[irq]); + iored.mask |= 0x1; + ioapic_write_redirection(irq_redirects[irq], iored.val); +} +void irq_unmask(int irq) { + union iored iored; + iored.val = ioapic_read_redirection(irq_redirects[irq]); + iored.mask &= ~0x1; + ioapic_write_redirection(irq_redirects[irq], iored.val); } void ioapic_init() { @@ -63,12 +84,6 @@ void ioapic_init() { iored.target = 0x0; ioapic_write_redirection(i, iored.val); } - - // TEMPORARY - // Unmask PS/2 keyboard interrupt - iored.val = ioapic_read_redirection(irq_redirects[1]); - iored.mask &= ~0x1; - ioapic_write_redirection(irq_redirects[1], iored.val); } void apic_init() { @@ -76,5 +91,5 @@ void apic_init() { vmm_set_page(kernel_P4, (uintptr_t)P2V(APIC_BASE), APIC_BASE, PAGE_PRESENT | PAGE_WRITE | PAGE_GLOBAL); // Allow LAPIC to receive interrupts - APIC_REG(0xF0) = APIC_REG(0xF0) | 0x100 | 0xFF; + APIC_REG(APIC_SPURIOUS) = APIC_REG(APIC_SPURIOUS) | 0x100 | IRQ_SPURIOUS; } \ No newline at end of file diff --git a/src/kernel/include/cpu.h b/src/kernel/include/cpu.h index d056fcd..eb93211 100644 --- a/src/kernel/include/cpu.h +++ b/src/kernel/include/cpu.h @@ -5,7 +5,12 @@ #define MAX_CPUS 16 #define MAX_IRQS 24 + #define IRQ_BASE 0x20 +#define IRQ_INTERRUPT(irq) (IRQ_BASE + (irq)) + +#define IRQ_PS2_KBD 0x1 +#define IRQ_SPURIOUS 0xFF struct cpu { uint8_t id; @@ -36,5 +41,8 @@ uint64_t write_msr(uint32_t msr, uint64_t value); void acpi_parse(void *_rsdp); // cpu/apic.c -void apic_init(); -void ioapic_init(); \ No newline at end of file +void irq_ack(); +void irq_mask(int irq); +void irq_unmask(int irq); +void ioapic_init(); +void apic_init(); \ No newline at end of file