CPU Architectures
x86_64, AArch64, and RISC-V 64 support through the Hardware Abstraction Layer.
Architecture Comparison
Helix supports three CPU architectures. Each has a complete HAL backend in hal/src/<arch>/:
| Feature | x86_64 | AArch64 | RISC-V 64 |
|---|---|---|---|
| Target | x86_64-unknown-none | aarch64-unknown-none | riscv64gc-unknown-none-elf |
| Source files | ~60 | ~35 | ~30 |
| Estimated lines | ~25,000 | ~14,000 | ~12,000 |
| Maturity | Primary — most tested | Secondary | Experimental |
| Page table | 4-level (PML4) | 4-level (4KB granule) | Sv39/48/57 |
| Interrupt ctrl | APIC (Local + I/O) | GICv2 / GICv3 | CLINT + PLIC |
| Timer | TSC / HPET / APIC | Generic Timer | SBI Timer |
| SMP startup | INIT-SIPI-SIPI | PSCI | SBI HSM |
| Serial | COM1 (0x3F8) | PL011 UART | SBI Console |
| KASLR entropy | RDRAND / RDSEED | Timer jitter | Timer jitter |
| Firmware | ACPI / UEFI | ACPI / DeviceTree | DeviceTree / SBI |
| Boot protocols | Limine, Multiboot2, UEFI | UEFI, DeviceTree | SBI, DeviceTree |
x86_64
The x86_64 backend is the most complete and heavily tested architecture.
File Structure
Privilege Rings
Helix uses only Ring 0 and Ring 3. The transition between rings happens via syscall/sysret instructions (fast path) or int 0x80/iret (legacy path).
GDT Layout
| Index | Selector | Description |
|---|---|---|
| 0 | 0x00 | Null descriptor |
| 1 | 0x08 | Kernel code (64-bit, Ring 0) |
| 2 | 0x10 | Kernel data (Ring 0) |
| 3 | 0x18 | User code (64-bit, Ring 3) |
| 4 | 0x20 | User data (Ring 3) |
| 5 | 0x28 | TSS descriptor (16 bytes) |
IDT Vectors
| Range | Type | Description |
|---|---|---|
| 0-31 | CPU Exceptions | Division error, page fault, GPF, double fault, etc. |
| 32-47 | PIC IRQs | Legacy: keyboard, timer, serial, disk, etc. |
| 48-255 | APIC | I/O APIC IRQs, IPIs, MSI, spurious |
Key exception vectors:
| Vector | Name | Notes |
|---|---|---|
| 0 | #DE Divide Error | Integer division by zero |
| 6 | #UD Invalid Opcode | Undefined instruction |
| 8 | #DF Double Fault | Exception during exception handling — IST1 stack |
| 13 | #GP General Protection | Segment violation, privilege error |
| 14 | #PF Page Fault | Memory access violation — CR2 has faulting address |
Page Table Structure
APIC Architecture
Timer Selection Priority
- TSC — if
invariant_tscCPUID flag is present (preferred — ~1ns, per-core) - HPET — if ACPI HPET table exists (100ns, system-wide)
- APIC Timer — calibrated against PIT/HPET (per-core, configurable)
- PIT — fallback (838ns, single channel, legacy)
AArch64
The AArch64 (ARM 64-bit) backend targets modern ARM server and embedded platforms.
File Structure
Exception Levels
Helix runs at EL1. EL2 and EL3 are managed by firmware (if present).
Exception Vector Table
AArch64 has 16 exception vectors organized in a 4x4 table:
| From | Sync | IRQ | FIQ | SError |
|---|---|---|---|---|
| Current EL, SP_EL0 | 0x000 | 0x080 | 0x100 | 0x180 |
| Current EL, SP_ELx | 0x200 | 0x280 | 0x300 | 0x380 |
| Lower EL, AArch64 | 0x400 | 0x480 | 0x500 | 0x580 |
| Lower EL, AArch32 | 0x600 | 0x680 | 0x700 | 0x780 |
GIC Architecture
Interrupt Types
| Type | Range | Description |
|---|---|---|
| SGI | 0-15 | Software Generated Interrupt (IPI) |
| PPI | 16-31 | Private Peripheral Interrupt (per-core timer, PMU) |
| SPI | 32-1019 | Shared Peripheral Interrupt (external devices) |
| LPI | 8192+ | Locality-specific (GICv3 ITS, MSI) |
Page Table (4KB Granule)
AArch64 uses two page table base registers:
- TTBR0_EL1: Lower half (user space, 0x0000...)
- TTBR1_EL1: Upper half (kernel space, 0xFFFF...)
RISC-V 64
The RISC-V backend targets the open RISC-V 64-bit ISA with GC (general + compressed) extensions.
File Structure
Privilege Modes
Helix runs in S-mode and communicates with M-mode firmware via the SBI (Supervisor Binary Interface).
CSR (Control and Status Registers)
| CSR | Name | Purpose |
|---|---|---|
sstatus | Status | Interrupt enable, previous privilege |
sie | Interrupt Enable | Enable timer, external, software interrupts |
sip | Interrupt Pending | Pending interrupt bits |
stvec | Trap Vector | Trap handler address |
sscratch | Scratch | Per-hart scratch register |
sepc | Exception PC | PC at time of exception |
scause | Cause | Exception/interrupt cause code |
stval | Trap Value | Faulting address or instruction |
satp | Address Translation | Page table base + ASID + mode (Sv39/48/57) |
Page Table Modes
| Mode | Levels | Virtual Bits | Address Space |
|---|---|---|---|
| Sv39 | 3 | 39 bits | 512 GB |
| Sv48 | 4 | 48 bits | 256 TB |
| Sv57 | 5 | 57 bits | 128 PB |
Helix uses Sv39 by default (sufficient for most use cases) with Sv48 as an option for large-memory systems.
Sv39 Page Table
PLIC Architecture
SBI Interface
The Supervisor Binary Interface provides standardized firmware calls:
| Extension | EID | Functions |
|---|---|---|
| Timer | 0x54494D45 | set_timer(deadline) |
| Console | 0x4442434E | putchar(c), getchar() |
| HSM | 0x48534D | hart_start, hart_stop, hart_get_status |
| IPI | 0x735049 | send_ipi(hart_mask) |
| RFENCE | 0x52464E43 | remote_sfence_vma(hart_mask, addr, size) |
SBI calls use the ecall instruction with a7 = extension_id and a6 = function_id.
HAL Trait Unification
Despite vastly different hardware, all three architectures present the same interface to the kernel through the HAL traits.
Abstraction Boundaries
| Concept | x86_64 | AArch64 | RISC-V |
|---|---|---|---|
| Enable interrupts | sti | MSR DAIF, #0 | csrsi sstatus, SIE |
| Disable interrupts | cli | MSR DAIF, #0xF | csrci sstatus, SIE |
| Halt | hlt | wfi | wfi |
| Page table switch | Write CR3 | Write TTBR0/1_EL1 | Write satp + sfence.vma |
| TLB flush (single) | invlpg | TLBI VAE1 | sfence.vma addr |
| TLB flush (all) | Reload CR3 | TLBI VMALLE1 | sfence.vma |
| IPI | APIC write | GIC SGI | SBI send_ipi |
| Timer read | rdtsc | MRS CNTPCT_EL0 | rdtime |
Adding a New Architecture
To port Helix to a new architecture:
- Create
hal/src/<arch>/mod.rsimplementingHalImpl - Implement
CpuHal,InterruptHal,MmuHal,TimerHal - Add a linker script in
profiles/<arch>/linker.ld - Add the target triple to
rust-toolchain.toml - Create a boot entry point (
_startor equivalent) - Add
#[cfg(target_arch = "<arch>")]guards to the HAL root
The rest of the kernel (core, subsystems, modules, filesystem) requires zero changes — it programs against the HAL traits, not the concrete implementation.