This commit is contained in:
2026-09-17 03:19:43 +02:00
parent 6719239036
commit 27fe15f83d
85 changed files with 945 additions and 901 deletions
+23 -18
View File
@@ -1,37 +1,40 @@
#include <zinnia/alloc.h>
#include <zinnia/assert.h>
#include <zinnia/clock.h>
#include <zinnia/mmio.h>
#include <zinnia/percpu.h>
#include <assert.h>
#include <zinnia/pmap.h>
#include <zinnia/vma.h>
#include <stdint.h>
#include <x86_64/apic.h>
#include <x86_64/asm.h>
#include <x86_64/defs.h>
static uint64_t lapic_read_reg(struct local_apic* lapic, mmio_reg32 reg) {
if (lapic->xapic_regs.base) {
if (reg.offset == APIC_REG_ICR.offset) {
static uint64_t lapic_read_reg(struct local_apic* lapic, uint32_t reg) {
if (lapic->xapic_regs) {
if (reg == APIC_REG_ICR) {
uint64_t lo, hi;
lo = mmio_load(&lapic->xapic_regs, APIC_REG_ICR);
hi = mmio_load(&lapic->xapic_regs, APIC_REG_ICR_HI);
lo = mmio_read32(lapic->xapic_regs + APIC_REG_ICR);
hi = mmio_read32(lapic->xapic_regs + APIC_REG_ICR_HI);
return (hi << 32) | lo;
} else {
return mmio_load(&lapic->xapic_regs, reg);
return mmio_read32(lapic->xapic_regs + reg);
}
} else {
return asm_rdmsr(0x800 + (reg.offset >> 4));
return asm_rdmsr(0x800 + (reg >> 4));
}
}
static void lapic_write_reg(struct local_apic* lapic, mmio_reg32 reg, uint64_t value) {
if (lapic->xapic_regs.base) {
if (reg.offset == APIC_REG_ICR.offset) {
mmio_store(&lapic->xapic_regs, APIC_REG_ICR_HI, value >> 32);
mmio_store(&lapic->xapic_regs, APIC_REG_ICR, (uint32_t)value);
static void lapic_write_reg(struct local_apic* lapic, uint32_t reg, uint64_t value) {
if (lapic->xapic_regs) {
if (reg == APIC_REG_ICR) {
mmio_write32(lapic->xapic_regs + APIC_REG_ICR_HI, value >> 32);
mmio_write32(lapic->xapic_regs + APIC_REG_ICR, (uint32_t)value);
} else {
mmio_store(&lapic->xapic_regs, reg, (uint32_t)value);
mmio_write32(lapic->xapic_regs + reg, (uint32_t)value);
}
} else {
asm_wrmsr(0x800 + (reg.offset >> 4), value);
asm_wrmsr(0x800 + (reg >> 4), value);
}
}
@@ -43,8 +46,10 @@ void lapic_init(struct local_apic* lapic) {
if (cpuid.ecx & CPUID_1C_X2APIC)
apic_msr |= 1 << 10;
else {
lapic->xapic_regs = mmio_new(apic_msr & 0xFFFF'F000, 0x1000);
assert(lapic->xapic_regs.base, "Failed to allocate virtual memory!\n");
uintptr_t vaddr = vm_alloc(0x1000);
pmap_map(&kernel_vma.pmap, vaddr, apic_msr & 0xFFFF'F000, PTE_READ | PTE_WRITE, CACHE_MMIO);
lapic->xapic_regs = (void*)vaddr;
assert(lapic->xapic_regs, "Failed to allocate virtual memory!\n");
}
asm_wrmsr(0x1B, apic_msr);
@@ -54,7 +59,7 @@ void lapic_init(struct local_apic* lapic) {
// Enable APIC bit in the SIVR.
lapic_write_reg(lapic, APIC_REG_SIVR, lapic_read_reg(lapic, APIC_REG_SIVR) | 0x100);
if (lapic->xapic_regs.base) {
if (lapic->xapic_regs) {
lapic_write_reg(lapic, APIC_REG_DFR, 0xF000'0000);
// Logical destination = LAPIC ID.
lapic_write_reg(lapic, APIC_REG_LDR, lapic_read_reg(lapic, APIC_REG_ID));