feat/kernel: Nuke ACPI and APIC
This commit is contained in:
parent
d9a5f8e3c0
commit
e4dc0d0a04
11 changed files with 1 additions and 666 deletions
|
@ -2,7 +2,7 @@
|
|||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
|
||||
QEMUFLAGS := -m 2G -serial file:com1.log -smp 4 -monitor stdio
|
||||
QEMUFLAGS := -m 2G -serial stdio -smp 4
|
||||
USER_QEMUFLAGS ?=
|
||||
IMAGE_NAME := release/emk
|
||||
|
||||
|
|
|
@ -5,10 +5,7 @@
|
|||
#include <arch/cpu.h>
|
||||
#include <util/log.h>
|
||||
#include <sys/kpanic.h>
|
||||
#include <sys/lapic.h>
|
||||
#include <arch/smp.h>
|
||||
#include <sys/lapic.h>
|
||||
#include <sys/ioapic.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct idt_entry __attribute__((aligned(16))) idt_descriptor[256] = {0};
|
||||
|
@ -64,12 +61,5 @@ int idt_register_handler(size_t vector, idt_intr_handler handler)
|
|||
return 1;
|
||||
|
||||
real_handlers[vector] = handler;
|
||||
|
||||
if (vector >= 32 && vector < 48)
|
||||
{
|
||||
size_t irq = vector - 32;
|
||||
ioapic_redirect_irq(bootstrap_lapic_id, vector, irq, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -17,11 +17,7 @@
|
|||
#include <flanterm/flanterm.h>
|
||||
#include <flanterm/backends/fb.h>
|
||||
#endif // FLANTERM_SUPPORT
|
||||
#include <sys/acpi.h>
|
||||
#include <sys/acpi/madt.h>
|
||||
#include <arch/smp.h>
|
||||
#include <sys/lapic.h>
|
||||
#include <sys/ioapic.h>
|
||||
|
||||
__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
|
||||
__attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = {
|
||||
|
@ -60,21 +56,6 @@ struct limine_mp_response *mp_response = NULL;
|
|||
struct flanterm_context *ft_ctx = NULL;
|
||||
#endif // FLANTERM_SUPPORT
|
||||
|
||||
void tick(struct register_ctx *)
|
||||
{
|
||||
log_early("tick");
|
||||
lapic_eoi();
|
||||
}
|
||||
|
||||
void timer_init()
|
||||
{
|
||||
uint16_t divisor = 11932;
|
||||
outb(0x43, 0x36);
|
||||
outb(0x40, divisor & 0xFF);
|
||||
outb(0x40, (divisor >> 8) & 0xFF);
|
||||
idt_register_handler(32, tick);
|
||||
}
|
||||
|
||||
void emk_entry(void)
|
||||
{
|
||||
__asm__ volatile("movq %%rsp, %0" : "=r"(kstack_top));
|
||||
|
@ -195,24 +176,5 @@ void emk_entry(void)
|
|||
smp_init();
|
||||
log_early("Initialized SMP");
|
||||
|
||||
/* Setup ACPI and APIC */
|
||||
rsdp_response = rsdp_request.response;
|
||||
if (!rsdp_response)
|
||||
{
|
||||
kpanic(NULL, "Failed to get RSDP request");
|
||||
}
|
||||
acpi_init();
|
||||
log_early("Initialized ACPI");
|
||||
|
||||
/* Setup MADT */
|
||||
madt_init();
|
||||
ioapic_init();
|
||||
log_early("Initialized IOAPIC");
|
||||
lapic_init();
|
||||
log_early("Initialized LAPIC");
|
||||
|
||||
/* Setup timer */
|
||||
timer_init();
|
||||
|
||||
hlt();
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||
#include <sys/acpi.h>
|
||||
#include <boot/emk.h>
|
||||
#include <lib/string.h>
|
||||
#include <util/log.h>
|
||||
#include <sys/kpanic.h>
|
||||
#include <mm/vmm.h>
|
||||
|
||||
static int acpi_uses_xsdt = 0;
|
||||
static void *acpi_rsdt_ptr = NULL;
|
||||
|
||||
void acpi_init(void)
|
||||
{
|
||||
if (!rsdp_response || !rsdp_response->address)
|
||||
{
|
||||
kpanic(NULL, "No RSDP provided");
|
||||
}
|
||||
|
||||
acpi_rsdp_t *rsdp = (acpi_rsdp_t *)vallocat(kvm_ctx, 1, VALLOC_RW, rsdp_response->address);
|
||||
|
||||
if (memcmp(rsdp->signature, "RSD PTR", 7) != 0)
|
||||
kpanic(NULL, "Invalid RSDP signature!");
|
||||
|
||||
if (rsdp->revision != 0)
|
||||
{
|
||||
acpi_uses_xsdt = 1;
|
||||
acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp;
|
||||
acpi_rsdt_ptr = (acpi_xsdt_t *)HIGHER_HALF(xsdp->xsdt_address);
|
||||
log_early("XSDT found at %p", acpi_rsdt_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
acpi_rsdt_ptr = (acpi_rsdt_t *)HIGHER_HALF(rsdp->rsdt_address);
|
||||
log_early("RSDT found at %p", acpi_rsdt_ptr);
|
||||
}
|
||||
|
||||
void *acpi_find_table(const char *name)
|
||||
{
|
||||
if (!acpi_uses_xsdt)
|
||||
{
|
||||
acpi_rsdt_t *rsdt = (acpi_rsdt_t *)acpi_rsdt_ptr;
|
||||
uint32_t entries = (rsdt->sdt.length - sizeof(rsdt->sdt)) / 4;
|
||||
for (uint32_t i = 0; i < entries; i++)
|
||||
{
|
||||
acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)HIGHER_HALF(*((uint32_t *)rsdt->table + i));
|
||||
if (!memcmp(sdt->signature, name, 4))
|
||||
return (void *)sdt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
acpi_xsdt_t *xsdt = (acpi_xsdt_t *)acpi_rsdt_ptr;
|
||||
log_early("XSDT address: %p", xsdt);
|
||||
uint32_t entries = (xsdt->sdt.length - sizeof(xsdt->sdt)) / 8;
|
||||
|
||||
for (uint32_t i = 0; i < entries; i++)
|
||||
{
|
||||
acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)HIGHER_HALF(*((uint64_t *)xsdt->table + i));
|
||||
if (!memcmp(sdt->signature, name, 4))
|
||||
{
|
||||
return (void *)sdt;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||
#ifndef EMK_ACPI_H
|
||||
#define EMK_ACPI_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
typedef struct acpi_rsdp
|
||||
{
|
||||
char signature[8];
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
uint8_t revision;
|
||||
uint32_t rsdt_address;
|
||||
} __attribute__((packed)) acpi_rsdp_t;
|
||||
|
||||
typedef struct acpi_xsdp
|
||||
{
|
||||
char signature[8];
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
uint8_t revision;
|
||||
uint32_t rsdt_address;
|
||||
uint32_t resv;
|
||||
uint32_t length;
|
||||
uint64_t xsdt_address;
|
||||
uint8_t extended_checksum;
|
||||
uint8_t reserved[3];
|
||||
} __attribute__((packed)) acpi_xsdp_t;
|
||||
|
||||
typedef struct acpi_sdt_header
|
||||
{
|
||||
char signature[4];
|
||||
uint32_t length;
|
||||
uint8_t revision;
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
char oem_table_id[8];
|
||||
uint32_t oem_revision;
|
||||
uint32_t creator_id;
|
||||
uint32_t creator_revision;
|
||||
} __attribute__((packed)) acpi_sdt_header_t;
|
||||
|
||||
typedef struct acpi_rsdt
|
||||
{
|
||||
acpi_sdt_header_t sdt;
|
||||
char table[];
|
||||
} __attribute__((packed)) acpi_rsdt_t;
|
||||
|
||||
typedef struct acpi_xsdt
|
||||
{
|
||||
acpi_sdt_header_t sdt;
|
||||
char table[];
|
||||
} __attribute__((packed)) acpi_xsdt_t;
|
||||
|
||||
void *acpi_find_table(const char *name);
|
||||
void acpi_init(void);
|
||||
|
||||
#endif /* EMK_ACPI_H */
|
|
@ -1,54 +0,0 @@
|
|||
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||
#include <sys/acpi/madt.h>
|
||||
#include <sys/acpi.h>
|
||||
#include <sys/kpanic.h>
|
||||
|
||||
acpi_madt_ioapic_t *madt_ioapic_list[256] = {0};
|
||||
acpi_madt_ioapic_src_ovr_t *madt_iso_list[256] = {0};
|
||||
|
||||
uint32_t madt_ioapic_len = 0;
|
||||
uint32_t madt_iso_len = 0;
|
||||
|
||||
uint64_t *lapic_addr = 0;
|
||||
|
||||
void madt_init()
|
||||
{
|
||||
acpi_madt_t *madt = (acpi_madt_t *)acpi_find_table("APIC");
|
||||
if (!madt)
|
||||
{
|
||||
kpanic(NULL, "Failed to find MADT table");
|
||||
}
|
||||
|
||||
if (madt->sdt.length < sizeof(acpi_madt_t))
|
||||
{
|
||||
kpanic(NULL, "MADT table is too small");
|
||||
}
|
||||
|
||||
uint64_t offset = 0;
|
||||
while (offset < madt->sdt.length - sizeof(acpi_madt_t))
|
||||
{
|
||||
acpi_madt_entry_t *entry = (acpi_madt_entry_t *)(madt->table + offset);
|
||||
|
||||
if (entry->length == 0 || offset + entry->length > madt->sdt.length - sizeof(acpi_madt_t))
|
||||
{
|
||||
kpanic(NULL, "Invalid MADT entry length or overflow");
|
||||
}
|
||||
|
||||
if (entry->type == MADT_ENTRY_IOAPIC)
|
||||
{
|
||||
if (madt_ioapic_len < 256)
|
||||
madt_ioapic_list[madt_ioapic_len++] = (acpi_madt_ioapic_t *)entry;
|
||||
}
|
||||
else if (entry->type == MADT_ENTRY_IOAPIC_SRC_OVR)
|
||||
{
|
||||
if (madt_iso_len < 256)
|
||||
madt_iso_list[madt_iso_len++] = (acpi_madt_ioapic_src_ovr_t *)entry;
|
||||
}
|
||||
else if (entry->type == MADT_ENTRY_LAPIC_ADDR_OVR)
|
||||
{
|
||||
lapic_addr = (uint64_t *)((acpi_madt_lapic_addr_ovr_t *)entry)->lapic_addr;
|
||||
}
|
||||
|
||||
offset += entry->length;
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||
#ifndef MADT_H
|
||||
#define MADT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/acpi.h>
|
||||
|
||||
#define MADT_ENTRY_LAPIC 0 /* Local APIC */
|
||||
#define MADT_ENTRY_IOAPIC 1 /* I/O APIC */
|
||||
#define MADT_ENTRY_IOAPIC_SRC_OVR 2 /* I/O APIC Interrupt Source Override */
|
||||
#define MADT_ENTRY_IOAPIC_NMI_SRC 3 /* I/O APIC Non-Maskable Interrupt Source */
|
||||
#define MADT_ENTRY_LAPIC_NMI 4 /* Local APIC Non-Maskable Interrupt */
|
||||
#define MADT_ENTRY_LAPIC_ADDR_OVR 5 /* Local APIC Address Override */
|
||||
#define MADT_ENTRY_LX2APIC 9 /* Local x2APIC */
|
||||
|
||||
typedef struct acpi_madt
|
||||
{
|
||||
acpi_sdt_header_t sdt;
|
||||
uint32_t lapic_base;
|
||||
uint32_t flags;
|
||||
char table[];
|
||||
} __attribute__((packed)) acpi_madt_t;
|
||||
|
||||
typedef struct acpi_madt_entry
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
} __attribute__((packed)) acpi_madt_entry_t;
|
||||
|
||||
/* Entry Type 0: Processor Local APIC */
|
||||
typedef struct acpi_madt_lapic
|
||||
{
|
||||
acpi_madt_entry_t header;
|
||||
uint8_t acpi_proc_id; /* ACPI Processor ID */
|
||||
uint8_t apic_id; /* APIC ID */
|
||||
uint32_t flags; /* Bit 0: Processor Enabled, Bit 1: Online Capable */
|
||||
} __attribute__((packed)) acpi_madt_lapic_t;
|
||||
|
||||
/* Entry Type 1: I/O APIC */
|
||||
typedef struct acpi_madt_ioapic
|
||||
{
|
||||
acpi_madt_entry_t header;
|
||||
uint8_t ioapic_id; /* I/O APIC's ID */
|
||||
uint8_t reserved; /* Reserved (0) */
|
||||
uint32_t ioapic_addr; /* I/O APIC Address */
|
||||
uint32_t gsi_base; /* Global System Interrupt Base */
|
||||
} __attribute__((packed)) acpi_madt_ioapic_t;
|
||||
|
||||
/* Entry Type 2: I/O APIC Interrupt Source Override */
|
||||
typedef struct acpi_madt_ioapic_src_ovr
|
||||
{
|
||||
acpi_madt_entry_t header;
|
||||
uint8_t bus_source; /* Bus Source */
|
||||
uint8_t irq_source; /* IRQ Source */
|
||||
uint32_t gsi; /* Global System Interrupt */
|
||||
uint16_t flags; /* Flags */
|
||||
} __attribute__((packed)) acpi_madt_ioapic_src_ovr_t;
|
||||
|
||||
/* Entry Type 3: I/O APIC Non-Maskable Interrupt Source */
|
||||
typedef struct acpi_madt_ioapic_nmi_src
|
||||
{
|
||||
acpi_madt_entry_t header;
|
||||
uint8_t nmi_source; /* NMI Source */
|
||||
uint8_t reserved; /* Reserved */
|
||||
uint16_t flags; /* Flags */
|
||||
uint32_t gsi; /* Global System Interrupt */
|
||||
} __attribute__((packed)) acpi_madt_ioapic_nmi_src_t;
|
||||
|
||||
/* Entry Type 4: Local APIC Non-Maskable Interrupt */
|
||||
typedef struct acpi_madt_lapic_nmi
|
||||
{
|
||||
acpi_madt_entry_t header;
|
||||
uint8_t acpi_proc_id; /* ACPI Processor ID (0xFF for all processors) */
|
||||
uint16_t flags; /* Flags */
|
||||
uint8_t lint; /* LINT# (0 or 1) */
|
||||
} __attribute__((packed)) acpi_madt_lapic_nmi_t;
|
||||
|
||||
/* Entry Type 5: Local APIC Address Override */
|
||||
typedef struct acpi_madt_lapic_addr_ovr
|
||||
{
|
||||
acpi_madt_entry_t header;
|
||||
uint16_t reserved; /* Reserved */
|
||||
uint64_t lapic_addr; /* 64-bit Physical Address of Local APIC */
|
||||
} __attribute__((packed)) acpi_madt_lapic_addr_ovr_t;
|
||||
|
||||
/* Entry Type 9: Processor Local x2APIC */
|
||||
typedef struct acpi_madt_lx2apic
|
||||
{
|
||||
acpi_madt_entry_t header;
|
||||
uint16_t reserved;
|
||||
uint32_t x2apic_id; /* Processor's Local x2APIC ID */
|
||||
uint32_t flags; /* Flags (same as Local APIC) */
|
||||
uint32_t acpi_id; /* ACPI ID */
|
||||
} __attribute__((packed)) acpi_madt_lx2apic_t;
|
||||
|
||||
extern acpi_madt_ioapic_t *madt_ioapic_list[256];
|
||||
extern acpi_madt_ioapic_src_ovr_t *madt_iso_list[256];
|
||||
extern uint32_t madt_ioapic_len;
|
||||
extern uint32_t madt_iso_len;
|
||||
extern uint64_t *lapic_addr;
|
||||
|
||||
void madt_init();
|
||||
|
||||
#endif // MADT_H
|
|
@ -1,182 +0,0 @@
|
|||
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||
#include <sys/ioapic.h>
|
||||
#include <boot/emk.h>
|
||||
#include <util/log.h>
|
||||
|
||||
void ioapic_init()
|
||||
{
|
||||
if (!madt_ioapic_list[0])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void ioapic_write(acpi_madt_ioapic_t *ioapic, uint8_t reg, uint32_t 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!ioapic)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((ioapic_read(ioapic, IOAPIC_VER) >> 16) & 0xFF) + 1;
|
||||
}
|
||||
|
||||
acpi_madt_ioapic_t *ioapic_get_gsi(uint32_t gsi)
|
||||
{
|
||||
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];
|
||||
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);
|
||||
if (!ioapic)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t redirect = vec;
|
||||
|
||||
if (flags & (1 << 1))
|
||||
{
|
||||
redirect |= (1ULL << 13);
|
||||
}
|
||||
|
||||
if (flags & (1 << 3))
|
||||
{
|
||||
redirect |= (1ULL << 15);
|
||||
}
|
||||
|
||||
if (mask)
|
||||
{
|
||||
redirect |= (1ULL << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect &= ~(1ULL << 16);
|
||||
}
|
||||
|
||||
redirect |= (uint64_t)lapic_id << 56;
|
||||
|
||||
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)
|
||||
{
|
||||
log_early("IOAPIC redirect: IRQ=%u -> Vector=0x%X (mask=%s)", irq, vec, mask ? "true" : "false");
|
||||
|
||||
for (uint32_t idx = 0; idx < madt_iso_len; idx++)
|
||||
{
|
||||
if (!madt_iso_list[idx])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
acpi_madt_ioapic_src_ovr_t *iso = madt_iso_list[idx];
|
||||
|
||||
log_early(" ISO override found: irq_source=%u, gsi=%u, flags=0x%X",
|
||||
iso->irq_source, iso->gsi, iso->flags);
|
||||
|
||||
if (iso->irq_source == irq)
|
||||
{
|
||||
log_early(" Match found. Redirecting IRQ %u (GSI %u) to vector 0x%X",
|
||||
irq, iso->gsi, vec);
|
||||
ioapic_redirect_gsi(lapic_id, vec, iso->gsi, iso->flags, mask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
log_early(" No ISO match. Redirecting IRQ %u directly to vector 0x%X", irq, vec);
|
||||
ioapic_redirect_gsi(lapic_id, vec, irq, 0, mask);
|
||||
}
|
||||
|
||||
uint32_t ioapic_get_redirect_irq(uint8_t irq)
|
||||
{
|
||||
for (uint32_t idx = 0; idx < madt_iso_len; 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;
|
||||
}
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||
#ifndef IOAPIC_H
|
||||
#define IOAPIC_H
|
||||
|
||||
// Credits: https://github.com/SILD-Project/soaplin/blob/main/kernel/src/dev/ioapic.h
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/acpi.h>
|
||||
#include <sys/acpi/madt.h>
|
||||
|
||||
#define IOAPIC_REGSEL 0x0
|
||||
#define IOAPIC_IOWIN 0x10
|
||||
|
||||
#define IOAPIC_ID 0x0
|
||||
#define IOAPIC_VER 0x01
|
||||
#define IOAPIC_ARB 0x02
|
||||
#define IOAPIC_REDTBL 0x10
|
||||
|
||||
void ioapic_write(acpi_madt_ioapic_t *ioapic, uint8_t reg, uint32_t val);
|
||||
uint32_t ioapic_read(acpi_madt_ioapic_t *ioapic, uint8_t reg);
|
||||
|
||||
void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq,
|
||||
bool mask);
|
||||
uint32_t ioapic_get_redirect_irq(uint8_t irq);
|
||||
|
||||
void ioapic_set_entry(acpi_madt_ioapic_t *ioapic, uint8_t idx, uint64_t data);
|
||||
|
||||
void ioapic_init();
|
||||
|
||||
#endif // IOAPIC_H
|
|
@ -1,66 +0,0 @@
|
|||
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||
#include <sys/lapic.h>
|
||||
#include <boot/emk.h>
|
||||
|
||||
uint64_t apic_ticks = 0;
|
||||
|
||||
void lapic_init()
|
||||
{
|
||||
lapic_write(0xf0, 0x1ff);
|
||||
}
|
||||
|
||||
void lapic_stop_timer()
|
||||
{
|
||||
lapic_write(LAPIC_TIMER_INITCNT, 0);
|
||||
lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE);
|
||||
}
|
||||
|
||||
void lapic_oneshot(uint8_t vec, uint64_t ms)
|
||||
{
|
||||
lapic_stop_timer();
|
||||
lapic_write(LAPIC_TIMER_DIV, 0);
|
||||
lapic_write(LAPIC_TIMER_LVT, vec);
|
||||
lapic_write(LAPIC_TIMER_INITCNT, apic_ticks * ms);
|
||||
}
|
||||
|
||||
void lapic_calibrate_timer()
|
||||
{
|
||||
lapic_stop_timer();
|
||||
lapic_write(LAPIC_TIMER_DIV, 0);
|
||||
lapic_write(LAPIC_TIMER_LVT, (1 << 16) | 0xff);
|
||||
lapic_write(LAPIC_TIMER_INITCNT, 0xFFFFFFFF);
|
||||
lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE);
|
||||
uint32_t ticks = 0xFFFFFFFF - lapic_read(LAPIC_TIMER_CURCNT);
|
||||
apic_ticks = ticks;
|
||||
lapic_stop_timer();
|
||||
}
|
||||
|
||||
void lapic_write(uint32_t reg, uint32_t val)
|
||||
{
|
||||
*((volatile uint32_t *)(HIGHER_HALF(0xfee00000) + reg)) = val;
|
||||
}
|
||||
|
||||
uint32_t lapic_read(uint32_t reg)
|
||||
{
|
||||
return *((volatile uint32_t *)(HIGHER_HALF(0xfee00000) + reg));
|
||||
}
|
||||
|
||||
void lapic_eoi() { lapic_write((uint8_t)0xb0, 0x0); }
|
||||
|
||||
void lapic_ipi(uint32_t id, uint8_t dat)
|
||||
{
|
||||
lapic_write(LAPIC_ICRHI, id << LAPIC_ICDESTSHIFT);
|
||||
lapic_write(LAPIC_ICRLO, dat);
|
||||
}
|
||||
|
||||
void lapic_send_all_int(uint32_t id, uint32_t vec)
|
||||
{
|
||||
lapic_ipi(id, vec | LAPIC_ICRAIS);
|
||||
}
|
||||
|
||||
void lapic_send_others_int(uint32_t id, uint32_t vec)
|
||||
{
|
||||
lapic_ipi(id, vec | LAPIC_ICRAES);
|
||||
}
|
||||
|
||||
uint32_t lapic_get_id() { return lapic_read(0x0020) >> LAPIC_ICDESTSHIFT; }
|
|
@ -1,56 +0,0 @@
|
|||
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||
#ifndef LAPIC_H
|
||||
#define LAPIC_H
|
||||
|
||||
// Credits: https://github.com/SILD-Project/soaplin/blob/main/kernel/src/dev/lapic.h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define LAPIC_PPR 0x00a0
|
||||
|
||||
#define LAPIC_ICRLO 0x0300
|
||||
#define LAPIC_ICRHI 0x0310
|
||||
|
||||
#define LAPIC_ICINI 0x0500
|
||||
#define LAPIC_ICSTR 0x0600
|
||||
|
||||
#define LAPIC_ICEDGE 0x0000
|
||||
|
||||
#define LAPIC_ICPEND 0x00001000
|
||||
#define LAPIC_ICPHYS 0x00000000
|
||||
#define LAPIC_ICASSR 0x00004000
|
||||
#define LAPIC_ICSHRTHND 0x00000000
|
||||
#define LAPIC_ICDESTSHIFT 24
|
||||
|
||||
#define LAPIC_ICRAIS 0x00080000
|
||||
#define LAPIC_ICRAES 0x000c0000
|
||||
|
||||
// Timer
|
||||
#define LAPIC_TIMER_DIV 0x3E0
|
||||
#define LAPIC_TIMER_INITCNT 0x380
|
||||
#define LAPIC_TIMER_LVT 0x320
|
||||
#define LAPIC_TIMER_DISABLE 0x10000
|
||||
#define LAPIC_TIMER_CURCNT 0x390
|
||||
#define LAPIC_TIMER_PERIODIC 0x20000
|
||||
|
||||
void lapic_init();
|
||||
|
||||
void lapic_stop_timer();
|
||||
void lapic_oneshot(uint8_t vec, uint64_t ms);
|
||||
void lapic_calibrate_timer();
|
||||
|
||||
void lapic_write(uint32_t reg, uint32_t val);
|
||||
uint32_t lapic_read(uint32_t reg);
|
||||
|
||||
void lapic_eoi();
|
||||
|
||||
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
|
Loading…
Add table
Add a link
Reference in a new issue