]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commit
feat: Fase 6 — LAPIC + IOAPIC drivers, replace legacy PIC 8259
authorTulio A M Mendes <[email protected]>
Tue, 10 Feb 2026 08:40:28 +0000 (05:40 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 02:20:50 +0000 (23:20 -0300)
commita57918c4c2e4a7f28324cfdb30055ad0af208110
tree22eea96fd2e7198eb484567c4b35b8549323ee74
parent316d4ef4f9624b4a55537fc299a403f84af52bff
feat: Fase 6 — LAPIC + IOAPIC drivers, replace legacy PIC 8259

New files:
- include/arch/x86/lapic.h — LAPIC register definitions and API
- include/arch/x86/ioapic.h — IOAPIC register definitions and API
- src/arch/x86/lapic.c — Local APIC driver: init, EOI, MMIO access,
  timer calibration via PIT channel 2, pic_disable()
- src/arch/x86/ioapic.c — I/O APIC driver: init, IRQ routing,
  mask/unmask per-IRQ line

Changes:
- vmm.h: Add VMM_FLAG_PWT, VMM_FLAG_PCD, VMM_FLAG_NOCACHE for MMIO
- vmm.c: Translate PWT/PCD flags to x86 PTE bits in vmm_flags_to_x86
- arch_platform.c: Init LAPIC+IOAPIC after syscall_init, route ISA
  IRQs (timer=32, kbd=33, ATA=46) through IOAPIC, disable PIC only
  after IOAPIC routes are live
- idt.c: Send EOI BEFORE handler callback (critical: schedule() in
  timer handler context-switches away; deferred EOI blocks LAPIC).
  Add IDT gate for spurious vector 255; skip EOI for spurious
  interrupts per Intel spec.
- interrupts.S: Add ISR stub for vector 255 (LAPIC spurious)
- timer.c: Use LAPIC periodic timer when available, fallback to PIT

Key design decisions:
- LAPIC MMIO mapped at 0xC0200000 (above kernel _end, below heap)
- IOAPIC MMIO mapped at 0xC0201000
- Both mapped with PCD+PWT (cache-disable) to prevent MMIO caching
- PIC disabled only AFTER IOAPIC routes configured (avoids IRQ gap)
- EOI sent before handler to prevent LAPIC starvation on context switch
- Spurious vector 255 has IDT entry but no EOI (Intel requirement)
- LAPIC timer calibrated against PIT channel 2 (~10ms measurement)

Bugs fixed during development:
- VA 0xC0100000 overlapped kernel text — moved to 0xC0200000
- pic_disable() inside lapic_init() caused IRQ gap — moved to caller
- EOI after handler blocked LAPIC when schedule() context-switched
- Missing IDT entry for vector 255 caused triple fault on spurious IRQ

Passes: make, cppcheck, QEMU smoke test (all init tests OK).
13 files changed:
include/arch/x86/acpi.h [new file with mode: 0644]
include/arch/x86/ioapic.h [new file with mode: 0644]
include/arch/x86/lapic.h [new file with mode: 0644]
include/vmm.h
src/arch/x86/acpi.c [new file with mode: 0644]
src/arch/x86/arch_platform.c
src/arch/x86/idt.c
src/arch/x86/interrupts.S
src/arch/x86/ioapic.c [new file with mode: 0644]
src/arch/x86/lapic.c [new file with mode: 0644]
src/arch/x86/vmm.c
src/hal/x86/timer.c
src/kernel/shm.c