Skip to content

feat(kernel): implement aarch64/riscv64 context switch - #139

Merged
kernalix7 merged 1 commit into
mainfrom
feat/cross-arch-context-switch
Jul 10, 2026
Merged

feat(kernel): implement aarch64/riscv64 context switch#139
kernalix7 merged 1 commit into
mainfrom
feat/cross-arch-context-switch

Conversation

@kernalix7

Copy link
Copy Markdown
Owner

Replaces the unimplemented! stubs in aarch64/riscv64 context.rs with real naked-asm context switches, mirroring the proven x86_64 path: save ABI callee-saved regs onto the outgoing kernel stack, store the adjusted SP at old.sp (offset 0 of the non-x86 CpuContext), load new.sp, restore, ret.

  • aarch64: stp/ldp of x19-x28 + x29/x30 (96-byte frame); AAPCS64 x0/x1 arg pointers.
  • riscv64: sd/ld of ra + s0-s11 (112-byte frame); a0/a1 arg pointers.

First functional cross-arch scheduler primitive. Builds on x86_64/aarch64/riscv64 (x86 unchanged); correct-by-construction vs the x86 reference + each ABI. Runtime exercise awaits aarch64/riscv boot bring-up.

Replace the unimplemented! stubs in the aarch64 and riscv64 context.rs
with real naked-asm context switches, mirroring the proven x86_64 path:
save the ABI callee-saved registers onto the outgoing thread's kernel
stack, store the adjusted stack pointer at old.sp (byte offset 0 of the
non-x86 CpuContext), load new.sp, restore the callee-saved set from the
incoming stack, and ret into the new thread.

- aarch64: stp/ldp of x19-x28 + x29/x30 (96-byte frame), AAPCS64 x0/x1
  argument pointers.
- riscv64: sd/ld of ra + s0-s11 (112-byte frame), a0/a1 argument
  pointers.

Caller-saved registers remain the caller's responsibility per each
procedure-call standard, exactly as on x86_64. First functional
cross-arch scheduler primitive; builds on all three targets (x86_64
unchanged). Runtime exercise awaits aarch64/riscv64 boot bring-up.
@kernalix7
kernalix7 merged commit a6dc74f into main Jul 10, 2026
2 checks passed
@kernalix7
kernalix7 deleted the feat/cross-arch-context-switch branch July 10, 2026 07:42
kernalix7 added a commit that referenced this pull request Jul 13, 2026
…#142)

* feat(hal): enable the aarch64 MMU with an identity page table

Build a translation table so SCTLR_EL1.M can be set (previously deferred
because enabling the MMU without TTBR0_EL1 faulted the next fetch). With
TCR T0SZ=27 (37-bit VA) + 4 KiB granule the top level is L1 (1 GiB
blocks). _start populates a BSS-resident, 4 KiB-aligned L1 table
(__ttbr0_l1) with two identity block descriptors — entry 0 maps 0..1 GiB
Device-nGnRnE (GICD 0x0800_0000, GICR 0x080A_0000, PL011 0x0900_0000),
entry 1 maps 0x4000_0000..0x8000_0000 Normal WB/WA (RAM; kernel at
0x4008_0000) — installs TTBR0_EL1, flushes the TLB (tlbi vmalle1 + dsb
ish), and enables SCTLR_EL1.M|C|I.

Verified: 'qemu-system-aarch64 -M virt,gic-version=3' boots with the MMU
ON through heap/GICv3/timer to the halt loop, no translation faults under
'qemu -d int'. x86_64/riscv64 unaffected.

* feat(kernel): cooperative kernel-thread scheduling on aarch64

Make the aarch64 kernel actually schedule, exercising the #139
switch_context at runtime:
- New arch/aarch64/kthread.rs mirrors the x86_64 kthread pool (static
  16 KiB stacks, CpuContext + used bitmap, MAX_KTHREADS=32, DAIF-based
  with_interrupts_disabled). spawn_kthread seeds a 96-byte switch frame
  at the stack top — entry is written to [frame+8] (the x30 slot popped
  by 'ldp x29, x30, [sp], #96'), the other 11 slots zeroed, and
  CpuContext.sp = frame base — so the first switch into the thread ret's
  to entry.
- sched_glue::sched_yield_once replaces its no-op with a real
  kernel-thread-only cooperative switch (prepare_switch → null-check →
  switch_context; no TSS/CR3/syscall-mirror). read_cr3 now reads
  TTBR0_EL1.
- kernel_main runs a bring-up demo: two kernel threads print and
  yield_now(); boot yields into them.

Verified in QEMU (MMU on): boot → thread A ran → thread B ran → back on
boot thread, no faults. x86_64 unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant