diff --git a/kernel/Makefile b/kernel/Makefile index 9dd1361..34a5ae3 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -62,6 +62,7 @@ SRCFILES += $(call GRABSRC, \ path \ rbuf \ ipc/pipe \ + drivers/ps2kb \ ) ifeq ($(ARCH),x86_64) diff --git a/kernel/drivers/ps2kb/ps2kb.c b/kernel/drivers/ps2kb/ps2kb.c new file mode 100644 index 0000000..b44f96a --- /dev/null +++ b/kernel/drivers/ps2kb/ps2kb.c @@ -0,0 +1,19 @@ +#include +#include "ps2kb.h" +#include "hal/hal.h" +#include "kprintf.h" + +void ps2kb_write(uint8_t val) { + while (io_in8(0x64) & 2); + io_out8(0x64, val); +} + +uint8_t ps2kb_read(void) { + while (!(io_in8(0x64) & 1)); + return io_in8(0x60); +} + +void ps2kb_intr(void) { + uint8_t scancode = ps2kb_read(); + kprintf("%02x\n", scancode); +} diff --git a/kernel/drivers/ps2kb/ps2kb.h b/kernel/drivers/ps2kb/ps2kb.h new file mode 100644 index 0000000..37a2724 --- /dev/null +++ b/kernel/drivers/ps2kb/ps2kb.h @@ -0,0 +1,10 @@ +#ifndef DRIVERS_PS2KB_H_ +#define DRIVERS_PS2KB_H_ + +#include + +void ps2kb_write(uint8_t val); +uint8_t ps2kb_read(void); +void ps2kb_intr(void); + +#endif // DRIVERS_PS2KB_H_ diff --git a/kernel/hal/hal.h b/kernel/hal/hal.h index 6fabf0d..f7f9535 100644 --- a/kernel/hal/hal.h +++ b/kernel/hal/hal.h @@ -18,7 +18,6 @@ size_t hal_strcspn(const char *s, const char *reject); size_t hal_strspn(const char *s, const char *accept); char *hal_strcpy(char *dest, const char *src); char *hal_strchr(const char *s, int c); -void hal_init_withmalloc(void); void hal_wait(uint32_t ms); #define HAL_PAGE_SIZE 0x1000 @@ -27,5 +26,6 @@ void hal_wait(uint32_t ms); #include "x86_64/paging.h" #include "x86_64/cpu.h" #include "x86_64/intr.h" +#include "x86_64/io.h" #endif // KERNEL_HAL_HAL_H_ diff --git a/kernel/hal/x86_64/acpi.c b/kernel/hal/x86_64/acpi.c index 0fae02e..0683f8c 100644 --- a/kernel/hal/x86_64/acpi.c +++ b/kernel/hal/x86_64/acpi.c @@ -10,7 +10,6 @@ #include "bootinfo/bootinfo.h" #include "uacpi/uacpi.h" #include "uacpi/acpi.h" -#include "apic.h" struct acpi_madt *MADT = NULL; @@ -60,7 +59,7 @@ void acpi_init(void) { } uint8_t acpi_remapirq(uint8_t irq) { - uint64_t cur = (uint64_t)&MADT->entries; + uint64_t cur = (uint64_t)(&MADT->entries); uint64_t end = cur + MADT->hdr.length; while (cur < end) { @@ -69,7 +68,8 @@ uint8_t acpi_remapirq(uint8_t irq) { if (ent->type == ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE) { struct acpi_madt_interrupt_source_override *override = (struct acpi_madt_interrupt_source_override *)ent; if (override->source == irq) { - return override->gsi; + irq = override->gsi; + break; } } diff --git a/kernel/hal/x86_64/apic.c b/kernel/hal/x86_64/apic.c deleted file mode 100644 index 58158cb..0000000 --- a/kernel/hal/x86_64/apic.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include -#include "apic.h" -#include "uacpi/tables.h" -#include "uacpi/acpi.h" -#include "kprintf.h" -#include "hal/hal.h" -#include "dlmalloc/malloc.h" -#include "bootinfo/bootinfo.h" -#include "assert.h" -#include "util/util.h" -#include "cpu.h" -#include "util/mmio.h" -#include "acpi.h" - - -typedef struct LApic { - struct LApic *next; - uint8_t id; -} LApic; - -uint8_t *IOAPIC; -uint8_t *LAPIC; -LApic *LAPICS = NULL; - -void ioapic_write(uint8_t *base, uint8_t reg, uint32_t data) { - mmiowrite32(base + IOAPIC_IOREGSEL, reg); - mmiowrite32(base + IOAPIC_IOWIN, data); -} - -uint32_t ioapic_read(uint8_t *base, uint8_t reg) { - mmiowrite32(base + IOAPIC_IOREGSEL, reg); - return mmioread32(base + IOAPIC_IOWIN); -} - -void ioapic_setentry(uint8_t *base, uint8_t idx, uint64_t data) { - ioapic_write(base, IOAPIC_IOREDTBL + idx * 2, (uint32_t) data); - ioapic_write(base, IOAPIC_IOREDTBL + idx * 2 + 1, (uint32_t) (data >> 32)); -} - -void ioapic_init(void) { - uint32_t x = ioapic_read(IOAPIC, IOAPIC_IOAPICVER); - uint32_t count = ((x >> 16) & 0xff) + 1; - LOG("hal", "IOAPIC pins = %d\n", count); - - for (uint32_t i = 0; i < count; i++) { - ioapic_setentry(IOAPIC, i, 1 << 16); - } -} - -uint32_t lapic_read(uint32_t reg) { - return mmioread32(LAPIC + reg); -} - -void lapic_write(uint32_t reg, uint32_t data) { - mmiowrite32(LAPIC + reg, data); -} - -void lapic_init(void) { - lapic_write(LAPIC_TPR, 0); - lapic_write(LAPIC_DFR, 0xffffffff); - lapic_write(LAPIC_LDR, 0x01000000); - lapic_write(LAPIC_SVR, 0x100 | 0xff); -} - -uint32_t lapic_getid(void) { - return lapic_read(LAPIC_ID) >> 24; -} - -void lapic_sendinit(uint32_t id) { - lapic_write(LAPIC_ICRHI, id << ICR_DEST_SHIFT); - lapic_write(LAPIC_ICRLO, ICR_INIT | ICR_PHYS | ICR_ASSERT | ICR_EDGE | ICR_NO_SHORTHAND); - while (lapic_read(LAPIC_ICRLO) & ICR_SEND_PENDING); -} - -void lapic_sendstartup(uint32_t id, uint32_t vec) { - lapic_write(LAPIC_ICRHI, id << ICR_DEST_SHIFT); - lapic_write(LAPIC_ICRLO, vec | ICR_STARTUP | ICR_PHYS | ICR_ASSERT | ICR_EDGE | ICR_NO_SHORTHAND); - while (lapic_read(LAPIC_ICRLO) & ICR_SEND_PENDING); -} - -void apic_init(void) { - uacpi_status r; - - uacpi_table madt; - r = uacpi_table_find_by_signature("APIC", &madt); - if (r != UACPI_STATUS_OK) { - ERR("hal", "could not find MADT\n"); - hal_hang(); - } - MADT = madt.ptr; - - LAPIC = (uint8_t *)(MADT->local_interrupt_controller_address + BOOT_INFO.hhdm_off); - - uint64_t cur = (uint64_t)&MADT->entries; - uint64_t end = cur + MADT->hdr.length; - - while (cur < end) { - struct acpi_entry_hdr *ent = (struct acpi_entry_hdr *)cur; - - if (ent->type == ACPI_MADT_ENTRY_TYPE_IOAPIC) { - struct acpi_madt_ioapic *ioapic = (struct acpi_madt_ioapic *)ent; - IOAPIC = (uint8_t *)(ioapic->address + BOOT_INFO.hhdm_off); - LOG("hal", "IOAPIC p=%p v=%p id=%d gsi=%d\n", ioapic->address, IOAPIC, ioapic->id, ioapic->gsi_base); - } else if (ent->type == ACPI_MADT_ENTRY_TYPE_LAPIC) { - struct acpi_madt_lapic *lapic = (struct acpi_madt_lapic *)ent; - - LApic *new = dlmalloc(sizeof(*new)); - ASSERT("hal", new != NULL, "out of memory\n"); - new->id = lapic->id; - LL_APPEND(LAPICS, new); - LOG("hal", "LAPIC id=%d\n", lapic->id); - } else if (ent->type == ACPI_MADT_ENTRY_TYPE_LAPIC_ADDRESS_OVERRIDE) { - struct acpi_madt_lapic_address_override *override= (struct acpi_madt_lapic_address_override *)ent; - uint8_t *prev = LAPIC; - LAPIC = (uint8_t *)(override->address + BOOT_INFO.hhdm_off); - LOG("hal", "LAPIC override %p -> %p (v)\n", prev, LAPIC); - } - - cur += ent->length; - } - - lapic_init(); - ioapic_init(); -} diff --git a/kernel/hal/x86_64/apic.h b/kernel/hal/x86_64/apic.h deleted file mode 100644 index 43b2a11..0000000 --- a/kernel/hal/x86_64/apic.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef HAL_APIC_H_ -#define HAL_APIC_H_ - -#include - -#define IOAPIC_IOREGSEL 0x00 -#define IOAPIC_IOWIN 0x10 - -#define IOAPIC_IOAPICID 0x00 -#define IOAPIC_IOAPICVER 0x01 -#define IOAPIC_IOAPICARB 0x02 -#define IOAPIC_IOREDTBL 0x10 - -#define LAPIC_ID 0x0020 -#define LAPIC_VER 0x0030 -#define LAPIC_TPR 0x0080 -#define LAPIC_APR 0x0090 -#define LAPIC_PPR 0x00A0 -#define LAPIC_EOI 0x00B0 -#define LAPIC_RRD 0x00C0 -#define LAPIC_LDR 0x00D0 -#define LAPIC_DFR 0x00E0 -#define LAPIC_SVR 0x00F0 -#define LAPIC_ISR 0x0100 -#define LAPIC_TMR 0x0180 -#define LAPIC_IRR 0x0200 -#define LAPIC_ESR 0x0280 -#define LAPIC_ICRLO 0x0300 -#define LAPIC_ICRHI 0x0310 -#define LAPIC_TIMER 0x0320 -#define LAPIC_THERMAL 0x0330 -#define LAPIC_PERF 0x0340 -#define LAPIC_LINT0 0x0350 -#define LAPIC_LINT1 0x0360 -#define LAPIC_ERROR 0x0370 -#define LAPIC_TICR 0x0380 -#define LAPIC_TCCR 0x0390 -#define LAPIC_TDCR 0x03E0 - -#define ICR_FIXED 0x00000000 -#define ICR_LOWEST 0x00000100 -#define ICR_SMI 0x00000200 -#define ICR_NMI 0x00000400 -#define ICR_INIT 0x00000500 -#define ICR_STARTUP 0x00000600 -#define ICR_PHYS 0x00000000 -#define ICR_LOGC 0x00000800 -#define ICR_IDLE 0x00000000 -#define ICR_SEND_PENDING 0x00001000 -#define ICR_DEASSERT 0x00000000 -#define ICR_ASSERT 0x00004000 -#define ICR_EDGE 0x00000000 -#define ICR_LEVEL 0x00008000 -#define ICR_NO_SHORTHAND 0x00000000 -#define ICR_SELF 0x00040000 -#define ICR_ALL_INC_SELF 0x00080000 -#define ICR_ALL_EXCL_SELF 0x000C0000 - -#define ICR_DEST_SHIFT 24 - -extern uint8_t *IOAPIC; - -void apic_init(void); -void ioapic_setentry(uint8_t *base, uint8_t idx, uint64_t data); -uint32_t ioapic_read(uint8_t *base, uint8_t reg); -void ioapic_write(uint8_t *base, uint8_t reg, uint32_t data); -void lapic_write(uint32_t reg, uint32_t data); -uint32_t lapic_read(uint32_t reg); - -#endif // HAL_APIC_H_ diff --git a/kernel/hal/x86_64/hal.c b/kernel/hal/x86_64/hal.c index 76503a0..581dff4 100644 --- a/kernel/hal/x86_64/hal.c +++ b/kernel/hal/x86_64/hal.c @@ -4,10 +4,8 @@ #include "kprintf.h" #include "serial.h" #include "gdt.h" -#include "acpi.h" #include "intr.h" #include "pic.h" -#include "apic.h" #include "pit.h" void hal_init(void) { @@ -16,6 +14,10 @@ void hal_init(void) { } LOG("hal", "serial init\n"); gdt_init(); + intr_init(); + pic_init(); + pit_init(); + hal_intr_disable(); } __attribute__((noreturn)) void hal_hang(void) { @@ -24,16 +26,6 @@ __attribute__((noreturn)) void hal_hang(void) { } } -void hal_init_withmalloc(void) { - acpi_init(); - pic_init(); - apic_init(); - intr_init(); - pit_init(); - ioapic_setentry(IOAPIC, acpi_remapirq(0x00), INTR_TIMER); - hal_intr_disable(); -} - void hal_wait(uint32_t ms) { pit_wait(ms); } diff --git a/kernel/hal/x86_64/intr.c b/kernel/hal/x86_64/intr.c index b58c51e..9f8b979 100644 --- a/kernel/hal/x86_64/intr.c +++ b/kernel/hal/x86_64/intr.c @@ -8,11 +8,11 @@ #include "kprintf.h" #include "compiler/attr.h" #include "pic.h" -#include "apic.h" #include "pit.h" #include "proc/proc.h" #include "syscall/syscall.h" #include "errors.h" +#include "drivers/ps2kb/ps2kb.h" void hal_intr_disable(void) { asm volatile("cli"); @@ -172,6 +172,13 @@ void hal_syscalldispatch(IntrStackFrame *frame) { } } +void intr_eoi(uint8_t irq) { + if (irq >= 8) { + io_out8(PIC2_CMD, PIC_EOI); + } + io_out8(PIC1_CMD, PIC_EOI); +} + void intr_handleintr(IntrStackFrame *frame) { if (frame->trapnum <= 31) { kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum); @@ -183,14 +190,17 @@ void intr_handleintr(IntrStackFrame *frame) { } hal_hang(); } else if (frame->trapnum >= 32 && frame->trapnum <= 47) { - if (frame->trapnum == INTR_TIMER) { - io_out8(PIC2_CMD, 0x20); - PIT_TICKS++; + switch (frame->trapnum) { + case INTR_IRQBASE+0: + PIT_TICKS++; + intr_eoi(frame->trapnum - INTR_IRQBASE); + proc_sched((void *)frame); + break; + case INTR_IRQBASE+1: + ps2kb_intr(); + intr_eoi(frame->trapnum - INTR_IRQBASE); + break; } - io_out8(PIC1_CMD, 0x20); - lapic_write(LAPIC_EOI, 0x00); - - proc_sched((void *)frame); } else if (frame->trapnum == 0x80) { hal_syscalldispatch(frame); } diff --git a/kernel/hal/x86_64/intr.h b/kernel/hal/x86_64/intr.h index a1179e9..232f202 100644 --- a/kernel/hal/x86_64/intr.h +++ b/kernel/hal/x86_64/intr.h @@ -2,9 +2,6 @@ #define HAL_INTR_H_ #define INTR_IRQBASE 0x20 -#define INTR_IRQTIMER 0x00 -#define INTR_TIMER 0x20 -#define INTR_SPURIOUS 0xff #include "compiler/attr.h" diff --git a/kernel/hal/x86_64/pic.c b/kernel/hal/x86_64/pic.c index 4b321a5..d89e380 100644 --- a/kernel/hal/x86_64/pic.c +++ b/kernel/hal/x86_64/pic.c @@ -11,12 +11,12 @@ void pic_init(void) { io_out8(PIC1_DATA, INTR_IRQBASE); io_out8(PIC2_DATA, INTR_IRQBASE+8); - io_out8(PIC1_DATA, 4); + io_out8(PIC1_DATA, 2); io_out8(PIC2_DATA, 2); io_out8(PIC1_DATA, ICW4_8086); io_out8(PIC2_DATA, ICW4_8086); - io_out8(PIC1_DATA, 0xff); - io_out8(PIC2_DATA, 0xff); + io_out8(PIC1_DATA, 0); + io_out8(PIC2_DATA, 0); } diff --git a/kernel/hal/x86_64/pic.h b/kernel/hal/x86_64/pic.h index dea0213..fb08aa8 100644 --- a/kernel/hal/x86_64/pic.h +++ b/kernel/hal/x86_64/pic.h @@ -6,6 +6,8 @@ #define PIC2_CMD 0x00A0 #define PIC2_DATA 0x00A1 +#define PIC_EOI 0x20 + #define ICW1_ICW4 0x01 #define ICW1_SINGLE 0x02 #define ICW1_ADI 0x04 diff --git a/kernel/kmain.c b/kernel/kmain.c index 6b9f5ef..31cccad 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -65,7 +65,6 @@ void kmain(void) { storedev_init(); baseimg_init(); vfs_init(); - hal_init_withmalloc(); proc_init(); for(;;);