1
0
Fork 0

feat/kernel: Removed broken PIT and added yet another broken PIT

This commit is contained in:
Kevin Alavik 2025-05-17 12:33:25 +02:00
parent 560417b091
commit c10028d366
Signed by: cmpsb
GPG key ID: 10D1CC0526FDC6D7
5 changed files with 102 additions and 82 deletions

View file

@ -22,7 +22,6 @@
#include <arch/smp.h> #include <arch/smp.h>
#include <sys/lapic.h> #include <sys/lapic.h>
#include <sys/ioapic.h> #include <sys/ioapic.h>
#include <sys/pit.h>
__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); __attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
__attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = { __attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = {
@ -67,6 +66,15 @@ void tick(struct register_ctx *)
lapic_eoi(); 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) void emk_entry(void)
{ {
__asm__ volatile("movq %%rsp, %0" : "=r"(kstack_top)); __asm__ volatile("movq %%rsp, %0" : "=r"(kstack_top));
@ -194,8 +202,7 @@ void emk_entry(void)
log_early("Initialized LAPIC"); log_early("Initialized LAPIC");
/* Setup timer */ /* Setup timer */
pit_init(tick); timer_init();
log_early("Initialized Timer");
/* Setup SMP */ /* Setup SMP */
if (!mp_request.response) if (!mp_request.response)

View file

@ -4,17 +4,22 @@
void ioapic_init() void ioapic_init()
{ {
acpi_madt_ioapic_t *ioapic = madt_ioapic_list[0]; if (!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)
{ {
return; 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, (32 + i));
ioapic_write(ioapic, IOAPIC_REDTBL + 2 * i + 1, 0); 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) void ioapic_write(acpi_madt_ioapic_t *ioapic, uint8_t reg, uint32_t val)
{ {
*((volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_REGSEL)) = if (!ioapic)
reg; {
*((volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_IOWIN)) = val; 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) uint32_t ioapic_read(acpi_madt_ioapic_t *ioapic, uint8_t reg)
{ {
*((volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_REGSEL)) = if (!ioapic)
reg; {
return *( return 0;
(volatile uint32_t *)(HIGHER_HALF(ioapic->ioapic_addr) + IOAPIC_IOWIN)); }
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) 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); if (!ioapic)
ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2 + 1), {
(uint32_t)(data >> 32)); 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) 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) 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++)
{ {
acpi_madt_ioapic_t *ioapic = madt_ioapic_list[i]; if (!madt_ioapic_list[i])
if (ioapic->gsi_base <= gsi && {
ioapic->gsi_base + ioapic_gsi_count(ioapic) > gsi) continue;
return ioapic;
}
return (acpi_madt_ioapic_t *)0;
} }
void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, acpi_madt_ioapic_t *ioapic = madt_ioapic_list[i];
uint16_t flags, bool mask) uint64_t gsi_count = ioapic_gsi_count(ioapic);
if (ioapic->gsi_base <= gsi && ioapic->gsi_base + gsi_count > gsi)
{
return ioapic;
}
}
return NULL;
}
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); acpi_madt_ioapic_t *ioapic = ioapic_get_gsi(gsi);
if (!ioapic)
{
return;
}
uint64_t redirect = vec; 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) if (mask)
redirect |= (1 << 16); {
redirect |= (1ULL << 16);
}
else else
redirect &= ~(1 << 16); {
redirect &= ~(1ULL << 16);
}
redirect |= (uint64_t)lapic_id << 56; redirect |= (uint64_t)lapic_id << 56;
uint32_t redir_table = (gsi - ioapic->gsi_base) * 2 + 16; uint32_t redir_table = (gsi - ioapic->gsi_base) * 2 + IOAPIC_REDTBL;
ioapic_write(ioapic, redir_table, (uint32_t)redirect); ioapic_write(ioapic, redir_table, (uint32_t)(redirect & 0xFFFFFFFF));
ioapic_write(ioapic, redir_table + 1, (uint32_t)(redirect >> 32)); ioapic_write(ioapic, redir_table + 1, (uint32_t)(redirect >> 32));
} }
void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask)
bool mask)
{ {
uint8_t idx = 0; for (uint32_t idx = 0; idx < madt_iso_len; idx++)
acpi_madt_ioapic_src_ovr_t *iso = (acpi_madt_ioapic_src_ovr_t *)0; {
if (!madt_iso_list[idx])
{
continue;
}
while (idx < madt_iso_len) acpi_madt_ioapic_src_ovr_t *iso = madt_iso_list[idx];
{
iso = madt_iso_list[idx];
if (iso->irq_source == irq) if (iso->irq_source == irq)
{ {
ioapic_redirect_gsi(lapic_id, vec, iso->gsi, iso->flags, mask); ioapic_redirect_gsi(lapic_id, vec, iso->gsi, iso->flags, mask);
return; return;
} }
idx++;
} }
ioapic_redirect_gsi(lapic_id, vec, irq, 0, mask); 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) uint32_t ioapic_get_redirect_irq(uint8_t irq)
{ {
uint8_t idx = 0; for (uint32_t idx = 0; idx < madt_iso_len; idx++)
acpi_madt_ioapic_src_ovr_t *iso;
while (idx < madt_iso_len)
{ {
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) if (iso->irq_source == irq)
{ {
return iso->gsi; return iso->gsi;
} }
idx++;
} }
return irq; return irq;

View file

@ -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_all_int(uint32_t id, uint32_t vec);
void lapic_send_others_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(); uint32_t lapic_get_id();
#endif // LAPIC_H #endif // LAPIC_H

View file

@ -1,24 +0,0 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#include <sys/pit.h>
#include <arch/io.h>
#include <sys/lapic.h>
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);
}

View file

@ -1,9 +0,0 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#ifndef PIT_H
#define PIT_H
#include <arch/idt.h>
void pit_init(void (*callback)(struct register_ctx *ctx));
#endif // PIT_H