From c10028d366822486b046b4ee8db1627fbd97855e Mon Sep 17 00:00:00 2001 From: Kevin Alavik Date: Sat, 17 May 2025 12:33:25 +0200 Subject: [PATCH] feat/kernel: Removed broken PIT and added yet another broken PIT --- kernel/src/emk.c | 13 +++- kernel/src/sys/ioapic.c | 136 ++++++++++++++++++++++++++-------------- kernel/src/sys/lapic.h | 2 + kernel/src/sys/pit.c | 24 ------- kernel/src/sys/pit.h | 9 --- 5 files changed, 102 insertions(+), 82 deletions(-) delete mode 100644 kernel/src/sys/pit.c delete mode 100644 kernel/src/sys/pit.h diff --git a/kernel/src/emk.c b/kernel/src/emk.c index febdd3f..cf66cb0 100644 --- a/kernel/src/emk.c +++ b/kernel/src/emk.c @@ -22,7 +22,6 @@ #include #include #include -#include __attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); __attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = { @@ -67,6 +66,15 @@ void tick(struct register_ctx *) lapic_eoi(); } +void timer_init() +{ + uint16_t divisor = 11932; + outb(0x43, 0x36); + outb(0x40, divisor & 0xFF); + outb(0x40, (divisor >> 8) & 0xFF); + idt_register_handler(0x32, tick); +} + void emk_entry(void) { __asm__ volatile("movq %%rsp, %0" : "=r"(kstack_top)); @@ -194,8 +202,7 @@ void emk_entry(void) log_early("Initialized LAPIC"); /* Setup timer */ - pit_init(tick); - log_early("Initialized Timer"); + timer_init(); /* Setup SMP */ if (!mp_request.response) diff --git a/kernel/src/sys/ioapic.c b/kernel/src/sys/ioapic.c index 9451d0b..00272d4 100644 --- a/kernel/src/sys/ioapic.c +++ b/kernel/src/sys/ioapic.c @@ -4,17 +4,22 @@ void ioapic_init() { - acpi_madt_ioapic_t *ioapic = madt_ioapic_list[0]; - - uint32_t val = ioapic_read(ioapic, IOAPIC_VER); - uint32_t count = ((val >> 16) & 0xFF); - - if ((ioapic_read(ioapic, 0) >> 24) != ioapic->ioapic_id) + if (!madt_ioapic_list[0]) { return; } - for (uint8_t i = 0; i <= count; ++i) + acpi_madt_ioapic_t *ioapic = madt_ioapic_list[0]; + + uint32_t val = ioapic_read(ioapic, IOAPIC_VER); + uint32_t count = ((val >> 16) & 0xFF) + 1; + + if ((ioapic_read(ioapic, IOAPIC_ID) >> 24) != ioapic->ioapic_id) + { + return; + } + + for (uint32_t i = 0; i < count; ++i) { ioapic_write(ioapic, IOAPIC_REDTBL + 2 * i, (32 + i)); ioapic_write(ioapic, IOAPIC_REDTBL + 2 * i + 1, 0); @@ -23,87 +28,125 @@ void ioapic_init() void ioapic_write(acpi_madt_ioapic_t *ioapic, uint8_t reg, uint32_t val) { - *((volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_REGSEL)) = - reg; - *((volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_IOWIN)) = val; + if (!ioapic) + { + return; + } + + volatile uint32_t *regsel = (volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_REGSEL); + volatile uint32_t *iowin = (volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_IOWIN); + + *regsel = reg; + *iowin = val; } uint32_t ioapic_read(acpi_madt_ioapic_t *ioapic, uint8_t reg) { - *((volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_REGSEL)) = - reg; - return *( - (volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_IOWIN)); + if (!ioapic) + { + return 0; + } + + volatile uint32_t *regsel = (volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_REGSEL); + volatile uint32_t *iowin = (volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_IOWIN); + + *regsel = reg; + return *iowin; } void ioapic_set_entry(acpi_madt_ioapic_t *ioapic, uint8_t idx, uint64_t data) { - ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2), (uint32_t)data); - ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2 + 1), - (uint32_t)(data >> 32)); + if (!ioapic) + { + return; + } + + ioapic_write(ioapic, IOAPIC_REDTBL + idx * 2, (uint32_t)(data & 0xFFFFFFFF)); + ioapic_write(ioapic, IOAPIC_REDTBL + idx * 2 + 1, (uint32_t)(data >> 32)); } uint64_t ioapic_gsi_count(acpi_madt_ioapic_t *ioapic) { - return (ioapic_read(ioapic, 1) & 0xff0000) >> 16; + if (!ioapic) + { + return 0; + } + + return ((ioapic_read(ioapic, IOAPIC_VER) >> 16) & 0xFF) + 1; } acpi_madt_ioapic_t *ioapic_get_gsi(uint32_t gsi) { - for (uint64_t i = 0; i < madt_iso_len; i++) + for (uint32_t i = 0; i < madt_iso_len; i++) { + if (!madt_ioapic_list[i]) + { + continue; + } + acpi_madt_ioapic_t *ioapic = madt_ioapic_list[i]; - if (ioapic->gsi_base <= gsi && - ioapic->gsi_base + ioapic_gsi_count(ioapic) > gsi) + uint64_t gsi_count = ioapic_gsi_count(ioapic); + + if (ioapic->gsi_base <= gsi && ioapic->gsi_base + gsi_count > gsi) + { return ioapic; + } } - return (acpi_madt_ioapic_t *)0; + + return NULL; } -void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, - uint16_t flags, bool mask) +void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, uint16_t flags, bool mask) { acpi_madt_ioapic_t *ioapic = ioapic_get_gsi(gsi); + if (!ioapic) + { + return; + } uint64_t redirect = vec; - if ((flags & (1 << 1)) != 0) + if (flags & (1 << 1)) { - redirect |= (1 << 13); + redirect |= (1ULL << 13); } - if ((flags & (1 << 3)) != 0) + if (flags & (1 << 3)) { - redirect |= (1 << 15); + redirect |= (1ULL << 15); } if (mask) - redirect |= (1 << 16); + { + redirect |= (1ULL << 16); + } else - redirect &= ~(1 << 16); + { + redirect &= ~(1ULL << 16); + } redirect |= (uint64_t)lapic_id << 56; - uint32_t redir_table = (gsi - ioapic->gsi_base) * 2 + 16; - ioapic_write(ioapic, redir_table, (uint32_t)redirect); + uint32_t redir_table = (gsi - ioapic->gsi_base) * 2 + IOAPIC_REDTBL; + ioapic_write(ioapic, redir_table, (uint32_t)(redirect & 0xFFFFFFFF)); ioapic_write(ioapic, redir_table + 1, (uint32_t)(redirect >> 32)); } -void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, - bool mask) +void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask) { - uint8_t idx = 0; - acpi_madt_ioapic_src_ovr_t *iso = (acpi_madt_ioapic_src_ovr_t *)0; - - while (idx < madt_iso_len) + for (uint32_t idx = 0; idx < madt_iso_len; idx++) { - iso = madt_iso_list[idx]; + if (!madt_iso_list[idx]) + { + continue; + } + + acpi_madt_ioapic_src_ovr_t *iso = madt_iso_list[idx]; if (iso->irq_source == irq) { ioapic_redirect_gsi(lapic_id, vec, iso->gsi, iso->flags, mask); return; } - idx++; } ioapic_redirect_gsi(lapic_id, vec, irq, 0, mask); @@ -111,17 +154,18 @@ void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, uint32_t ioapic_get_redirect_irq(uint8_t irq) { - uint8_t idx = 0; - acpi_madt_ioapic_src_ovr_t *iso; - - while (idx < madt_iso_len) + for (uint32_t idx = 0; idx < madt_iso_len; idx++) { - iso = madt_iso_list[idx]; + if (!madt_iso_list[idx]) + { + continue; + } + + acpi_madt_ioapic_src_ovr_t *iso = madt_iso_list[idx]; if (iso->irq_source == irq) { return iso->gsi; } - idx++; } return irq; diff --git a/kernel/src/sys/lapic.h b/kernel/src/sys/lapic.h index 976e54c..e22ca20 100644 --- a/kernel/src/sys/lapic.h +++ b/kernel/src/sys/lapic.h @@ -49,6 +49,8 @@ void lapic_ipi(uint32_t id, uint8_t dat); void lapic_send_all_int(uint32_t id, uint32_t vec); void lapic_send_others_int(uint32_t id, uint32_t vec); +void lapic_init_cpu(uint32_t id); +void lapic_start_cpu(uint32_t id, uint32_t vec); uint32_t lapic_get_id(); #endif // LAPIC_H \ No newline at end of file diff --git a/kernel/src/sys/pit.c b/kernel/src/sys/pit.c deleted file mode 100644 index db3a2b8..0000000 --- a/kernel/src/sys/pit.c +++ /dev/null @@ -1,24 +0,0 @@ -/* EMK 1.0 Copyright (c) 2025 Piraterna */ -#include -#include -#include - -void (*pit_callback)(struct register_ctx *ctx) = NULL; - -void pit_handler(struct register_ctx *frame) -{ - if (pit_callback) - pit_callback(frame); - lapic_eoi(); -} - -void pit_init(void (*callback)(struct register_ctx *ctx)) -{ - if (callback) - pit_callback = callback; - outb(0x43, 0x36); - idt_register_handler(IDT_IRQ_BASE + 0, pit_handler); - uint16_t divisor = 5966; // ~200Hz - outb(0x40, divisor & 0xFF); - outb(0x40, (divisor >> 8) & 0xFF); -} \ No newline at end of file diff --git a/kernel/src/sys/pit.h b/kernel/src/sys/pit.h deleted file mode 100644 index b05d9ed..0000000 --- a/kernel/src/sys/pit.h +++ /dev/null @@ -1,9 +0,0 @@ -/* EMK 1.0 Copyright (c) 2025 Piraterna */ -#ifndef PIT_H -#define PIT_H - -#include - -void pit_init(void (*callback)(struct register_ctx *ctx)); - -#endif // PIT_H \ No newline at end of file