The header scan (Captain Bob, 2026-11-10): 788 source files -- 351 with the
SL-1.0 header, 12 with the old name (docs/working/experiments, kept by
ruling), 31 under someone else's licence (tools/kconfig, Linux's, GPL-2.0:
kept), and 394 with none. Ruled: the SPDX form; capsules (.4th, .f18) and
proofs (.thy) left for a ruling of their own (mkcapsule's 64x16 block format,
content-addressed capsules).
253 files now begin
SPDX-License-Identifier: LicenseRef-Starship-1.0
Copyright (c) 2023-2026 Robert A. James
as a /* */ block (C, headers, assembly, linker scripts) or # lines (scripts,
Makefiles, Kconfig; below a shebang or a coding line); tools/mkcapsule.c,
which had the copyright line, gets the SPDX line only.
Not touched: docs/working/ (archive and old campaign material, as the
ruling kept the experiments); v4/system/post_cases.c (generated by
v4/tools/mkpost.py, "do not edit" -- the generator has the header).
Comments only: the kernel builds on amd64, aarch64, riscv64; make -C v4
test-32: 39 programs, 0 failures; every changed script parses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2
109 lines
3.4 KiB
ArmAsm
109 lines
3.4 KiB
ArmAsm
/* SPDX-License-Identifier: LicenseRef-Starship-1.0
|
|
* Copyright (c) 2023-2026 Robert A. James
|
|
*/
|
|
/*
|
|
* switch.S (aarch64) - Cooperative VM context switch primitive.
|
|
*
|
|
* FABRIC-3.md §XXVIII (Stage 2, preemptive-context-switch save/restore
|
|
* primitive, 2026-09-13). Deliberately NOT isr.S's interrupt trap frame
|
|
* (Stage 0) -- that saves everything because an interrupt has no call
|
|
* site. sk_vm_switch_to() is an ordinary `bl`, so AAPCS64 already makes
|
|
* every caller-saved register (x0-x18, v0-v7, v16-v31) the caller's own
|
|
* problem across the call. Only the callee-saved set needs explicit
|
|
* handling: x19-x28, x29 (fp), x30 (lr), and d8-d15 (only the low 64
|
|
* bits of v8-v15 are callee-saved per AAPCS64).
|
|
*
|
|
* void sk_vm_switch_to(uint64_t *save_sp_out, uint64_t new_sp);
|
|
* x0 = save_sp_out, x1 = new_sp
|
|
*
|
|
* For a VM that has never run before, new_sp must point at a synthetic
|
|
* 160-byte frame built by the C glue (switch.c) to this exact layout,
|
|
* with x30 (lr) set to the trampoline entry address and everything else
|
|
* zeroed, so the final `ret` below (which branches to lr) jumps there.
|
|
*/
|
|
|
|
.section .text
|
|
.balign 4
|
|
|
|
.equ SW_X19, 0
|
|
.equ SW_X21, 16
|
|
.equ SW_X23, 32
|
|
.equ SW_X25, 48
|
|
.equ SW_X27, 64
|
|
.equ SW_X29, 80 /* x29 (fp), x30 (lr) */
|
|
.equ SW_D8, 96
|
|
.equ SW_D10, 112
|
|
.equ SW_D12, 128
|
|
.equ SW_D14, 144
|
|
.equ SW_SIZE, 160
|
|
|
|
/* .hidden is an ELF-only visibility directive with no COFF equivalent;
|
|
* this file is also assembled for the aarch64 loader, which clang targets
|
|
* at aarch64-pc-windows-msvc (PE/COFF) -- guard on _WIN32 (defined only by
|
|
* that target), matching isr.S's own precedent exactly. */
|
|
#ifndef _WIN32
|
|
.hidden sk_vm_switch_to
|
|
#endif
|
|
|
|
.global sk_vm_switch_to
|
|
sk_vm_switch_to:
|
|
sub sp, sp, #SW_SIZE
|
|
|
|
stp x19, x20, [sp, #SW_X19]
|
|
stp x21, x22, [sp, #SW_X21]
|
|
stp x23, x24, [sp, #SW_X23]
|
|
stp x25, x26, [sp, #SW_X25]
|
|
stp x27, x28, [sp, #SW_X27]
|
|
stp x29, x30, [sp, #SW_X29]
|
|
stp d8, d9, [sp, #SW_D8]
|
|
stp d10, d11, [sp, #SW_D10]
|
|
stp d12, d13, [sp, #SW_D12]
|
|
stp d14, d15, [sp, #SW_D14]
|
|
|
|
mov x2, sp
|
|
str x2, [x0] /* *save_sp_out = sp (this context's parked SP) */
|
|
|
|
mov sp, x1 /* sp = new_sp (switch stacks) */
|
|
|
|
ldp x19, x20, [sp, #SW_X19]
|
|
ldp x21, x22, [sp, #SW_X21]
|
|
ldp x23, x24, [sp, #SW_X23]
|
|
ldp x25, x26, [sp, #SW_X25]
|
|
ldp x27, x28, [sp, #SW_X27]
|
|
ldp x29, x30, [sp, #SW_X29]
|
|
ldp d8, d9, [sp, #SW_D8]
|
|
ldp d10, d11, [sp, #SW_D10]
|
|
ldp d12, d13, [sp, #SW_D12]
|
|
ldp d14, d15, [sp, #SW_D14]
|
|
|
|
add sp, sp, #SW_SIZE
|
|
ret
|
|
|
|
/*
|
|
* uint64_t sk_vm_switch_prime(uint64_t stack_top, void *entry);
|
|
*
|
|
* Builds the synthetic frame above at the top of a fresh native stack, so
|
|
* the first ever sk_vm_switch_to() into it lands at `entry` (x30/lr) via
|
|
* its final `ret`. Kept in this file (not C) so the layout can never
|
|
* drift from sk_vm_switch_to() above -- one set of offsets, not two.
|
|
*/
|
|
#ifndef _WIN32
|
|
.hidden sk_vm_switch_prime
|
|
#endif
|
|
|
|
.global sk_vm_switch_prime
|
|
sk_vm_switch_prime:
|
|
sub x2, x0, #SW_SIZE
|
|
stp xzr, xzr, [x2, #SW_X19]
|
|
stp xzr, xzr, [x2, #SW_X21]
|
|
stp xzr, xzr, [x2, #SW_X23]
|
|
stp xzr, xzr, [x2, #SW_X25]
|
|
stp xzr, xzr, [x2, #SW_X27]
|
|
stp xzr, x1, [x2, #SW_X29] /* x29=0, x30(lr)=entry */
|
|
stp xzr, xzr, [x2, #SW_D8]
|
|
stp xzr, xzr, [x2, #SW_D10]
|
|
stp xzr, xzr, [x2, #SW_D12]
|
|
stp xzr, xzr, [x2, #SW_D14]
|
|
mov x0, x2
|
|
ret
|