feat: aarch64 port - fix build system obstacles, add exception handling, page tables
This commit is contained in:
1 parent
aae4db01ad
commit
8b6379fb7e
19 files changed
+1207
-77
No files matched your search
+33
-10
@@ -36,7 +36,7 @@ kernel/src/Arch/
|
||||
Platform.hpp boot-sequence hooks, platform device list, reboot
|
||||
CpuPower.hpp frequency scaling / thermal governor (may be no-ops)
|
||||
x86_64/ the complete port
|
||||
aarch64/ skeleton port
|
||||
aarch64/ the port in progress (see below)
|
||||
```
|
||||
|
||||
Other interfaces a port implements:
|
||||
@@ -85,25 +85,48 @@ are `Cpu.hpp`, `IoPort.hpp`, `PerCpu.hpp`, `Context.hpp`, `Abi.hpp` and
|
||||
- Interrupts are numbered IRQ slots (`Arch::IRQ_COUNT`); slot numbers for
|
||||
MSI-capable drivers are fixed in the drivers.
|
||||
|
||||
## The aarch64 skeleton
|
||||
## The aarch64 port
|
||||
|
||||
Real: CPU primitives (DAIF, WFI, `CNTVCT_EL0`, TLBI, TTBR0), per-CPU data via
|
||||
`TPIDR_EL1`, the context switch and EL0 entry (`Context.S`), TLS through
|
||||
`TPIDR_EL0`, the ELF/TLS/exit-stub ABI (syscall number in x8), the IRQ slot
|
||||
dispatch table (`ArchIrqDispatch`), panic-frame printing.
|
||||
dispatch table (`ArchIrqDispatch`), panic-frame printing, and:
|
||||
|
||||
- Exception vectors (`Vectors.S`, installed in `EarlyInitialize`). Every
|
||||
exception saves one 288-byte frame that is both `Arch::PanicFrame` and
|
||||
`Arch::SyscallFrame`. EL0 `svc` goes to `SyscallDispatch`; other
|
||||
synchronous exceptions go to `ArchSyncException` (`Exceptions.cpp`), which
|
||||
grows user stacks and lazy anonymous memory, kills faulting processes with
|
||||
a crash report, and panics on kernel faults.
|
||||
- Translation tables (`Paging.cpp`): 4 KiB granule, 48-bit VAs. The kernel
|
||||
half lives in its own TTBR1 table; `KernelRoot()` is the TTBR0 table of
|
||||
kernel contexts (EFI identity mappings only, so null pointers fault). The
|
||||
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`).
|
||||
|
||||
Not yet written (each is marked `TODO(aarch64)`):
|
||||
|
||||
- `Paging.cpp`: translation tables and MAIR (every method panics).
|
||||
- Exception vectors (`VBAR_EL1`): synchronous faults, `svc`, IRQs.
|
||||
- GIC driver: SPI routing, SGIs for IPIs, MSIs via ITS/GICv2m
|
||||
(`ComposeMsi` returns false, so drivers fall back to INTx/polling).
|
||||
- Generic timer tick (`Arch::Timer::InitializeBsp` returns false).
|
||||
(`ComposeMsi` returns false, so drivers fall back to INTx/polling). IRQs
|
||||
reach `ArchIrqException`, which only logs them.
|
||||
- Generic timer tick (`Arch::Timer::InitializeBsp` returns false). Boot
|
||||
currently stops in the first driver that waits on `GetMilliseconds()`
|
||||
(xHCI port power-up).
|
||||
- Secondary CPU start-up, PSCI reset and suspend.
|
||||
|
||||
Building it needs `clang` and `ld.lld` (`make kernel ARCH=aarch64`;
|
||||
`KERNEL_LD=` points at a different `ld.lld`, e.g. rustup's
|
||||
`lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld/ld.lld`).
|
||||
Building it needs `clang` and `ld.lld`; without a system `ld.lld` the
|
||||
kernel makefile uses the one rustup ships
|
||||
(`~/.rustup/toolchains/*/lib/rustlib/*/bin/gcc-ld/ld.lld`), and `KERNEL_LD=`
|
||||
overrides both. `make run ARCH=aarch64` boots a kernel-only image (userspace
|
||||
is x86_64-only so far) on QEMU `virt` with a GICv2 and Cortex-A72 cores, the
|
||||
Raspberry Pi 4/400's configuration; it needs `qemu-system-aarch64` and
|
||||
`qemu-efi-aarch64`.
|
||||
|
||||
The kernel console is mirrored to the serial port the ACPI SPCR table names
|
||||
(PL011, SBSA UART, 16550 or the BCM2835 mini UART; `Drivers/Serial/Uart.cpp`),
|
||||
including the log written before the port was found. On QEMU that is
|
||||
`-serial stdio`.
|
||||
|
||||
## Adding another architecture
|
||||
|
||||
|
||||
Reference in new issue
Block a user