feat: aarch64 port - Raspberry Pi 4/400 SD boot (SDHCI, ext2 root + first-boot grow), USB hubs, PCI INTx routing, SMP, DMA fences

This commit is contained in:
daniel committed 2026-10-25 13:48:26 +01:00
1 parent 8c09ccef66
commit 808e1d66fd
66 files changed
+3690 -196

No files matched your search

+41 -9
View File
@@ -104,10 +104,11 @@ dispatch table (`ArchIrqDispatch`), panic-frame printing, and:
HHDM maps only the memory map's RAM and firmware regions, never the holes
between them (device space on ARM). MAIR: 0 Normal WB, 1 Normal NC
(`MapWC`), 2 Device-nGnRE (`MapMMIO`).
- GICv2 (`Interrupts.cpp`, from the MADT): IRQ slots map onto INTIDs --
`IRQ_TIMER` onto the generic timer's PPI, the MSI slots (24-45) onto the
SPIs of a GICv2m MSI frame (`ComposeMsi`), the IPI slots onto SGIs 0/1.
SPIs of a GICv2m MSI frame (`ComposeMsi`), the IPI slots onto SGIs 0/1,
and the platform lines (1-23) onto the SPIs `AssignPlatformLine` gives
them (see "Interrupt lines" below).
Interrupts are completed (EOI) before the handler runs, as on x86; a
level-triggered source drops its line first in an ack hook.
- Generic timer tick (`Timer.cpp`): the EL1 virtual timer at
@@ -119,13 +120,11 @@ dispatch table (`ArchIrqDispatch`), panic-frame printing, and:
instruction fetch does not snoop data writes (QEMU hides this; real
cores do not). EL0 may maintain caches itself (`SCTLR_EL1.UCI`).
Not yet written (each is marked `TODO(aarch64)`):
- Secondary CPU start-up (`Smp::BootAPs`).
- PCI INTx: the PC interrupt lines (slots 1-23) have no ARM meaning, so
`RouteLegacyIrq` refuses them. Routing a PCI pin needs its `_PRT`
entry and a GSI-based routing call; until then PCI drivers use MSI
(GICv2m) or polling.
- SMP (`Smp.cpp`): Limine wakes each secondary CPU (PSCI `CPU_ON`
underneath) on the bootloader's tables; it programs its own system
registers and the kernel translation regime (`Bringup.hpp`), its banked
GIC CPU interface and timer PPI, then idles until a reschedule SGI.
TLB maintenance is broadcast (`tlbi ...is`).
The generic kernel is compiled `-fsigned-char` for AArch64: it was written
for x86's signed plain `char`.
@@ -145,6 +144,39 @@ The kernel console is mirrored to the serial port the ACPI SPCR table names
including the log written before the port was found. On QEMU that is
`-serial stdio`.
## Interrupt lines
Drivers for PCI functions without MSI read the Interrupt Line register and
pass it to `Arch::EnableLegacyIrq`. On x86 the firmware fills that register
with the function's I/O APIC input (`Arch::PlatformLinesAreFixed()`). On
other platforms `Pci::AssignInterruptLines` (`Pci/PciAcpi.cpp`) fills it
instead: it finds each pin's global system interrupt in the root bridge's
`_PRT` (swizzling through PCI-to-PCI bridges, resolving PNP0C0F link
devices through `_CRS`), binds the GSI to a platform line with
`Hal::GsiRouting::LineForGsi` and writes the line number into the register.
Devices that ACPI describes directly (platform devices) get their line from
`LineForGsi` too.
## DMA
`Memory/Dma.hpp` serves devices whose DMA does not snoop the CPU caches
(ACPI `_CCA = 0`): pages for rings and descriptors come uncached, and
`SyncForDevice` / `SyncForCpu` clean and invalidate streaming buffers
around a transfer (`Arch::CleanDataCache` / `InvalidateDataCache`). For
coherent devices every call is the plain allocation or a no-op. The xHCI
driver uses it; it also orders its TRB writes with `Arch::DmaWriteFence`
(the cycle bit last, a control TD's Setup TRB after its Data and Status
TRBs) and its event reads with `Arch::DmaReadFence`. Those fences cost
nothing on x86 and are required on ARM, where stores to normal memory and
device registers may otherwise be observed out of order. The other PCI
drivers (AHCI, NVMe, e1000, HDA) do not have them yet: they work on QEMU,
which does not reorder, but need them before they meet real ARM hardware.
## Raspberry Pi 4 / 400
See `docs/raspberry-pi.md`: `make ARCH=aarch64 rpi4-sd`, the firmware it
expects and how the Pi's hardware is reached.
## Userspace
The programs are architecture-neutral C/C++ built by `<arch>-montauk-gcc`