Reorganize source tree: kernel/, v3/, v4/ split and board infrastructure
Source tree reorganization: - Move StarForth v3 engine to v3/ (src/, include/, Makefile) - Move kernel to kernel/ (src/, include/, linker/, Makefile) - Create v4/ skeleton for F18-ISA golden model (DECOMPOSITION.md, JUSTIFICATION.md) - Move FABRIC-0..4.md to docs/fabric/ - Move ONTOLOGY.md and ROADMAP.md to docs/ Board infrastructure: - Add boards/ser5/, boards/raspi/, boards/milkv/, boards/zynq7020/ - Each board has board.mk (ISA, CPU flags, boot recipe) and README.md - Root Makefile becomes thin dispatcher: boot_image, all, clean, docs take TARGET - make boot_image TARGET=SER5|RASPI|MILKV builds one GPT/MBR image per board - ZYNQ7020 target exists but stops with clear error (ARMv7 port not built yet) - scripts/mkdiskimage.sh builds disk images for all boards Docs pipeline: - docs/book/ with LaTeX master (main.tex) and Makefile - pandoc converts Markdown to LaTeX at build time - Two Lua filters: table-widths.lua (wide tables wrap), code-breaks.lua (inline code breaks) - make docs builds single PDF (754 pages, 0 missing characters) - make docs TARGET=<board> adds board appendix - build/docs/<book|board>/meta.tex stamps git commit into PDF Bug fixes: - 42 include paths that only worked by accident now use correct relative paths - clang-18 hardcode replaced with configurable CC variable (fixed aarch64 build) - Pi 5: kernel_2712.img linked at 0x80000, .bss zeroed, memory reserved - Doxyfile, .clang-tidy, README.md, Kconfig paths updated Verified: - Hosted v3 build passes 1012 tests, 0 failures - SER5 image boots in QEMU (OVMF), POST passes, K exact (65536 = Q48_ONE) - Milk-V image boots in QEMU (OpenSBI + U-Boot + bootefi), POST passes - make clean TARGET=<board> removes only that board and its ISA objects - make all builds all boards, hosted v3, and docs in one run Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* switch.S (amd64) - Cooperative VM context switch primitive.
|
||||
*
|
||||
* FABRIC-3.md §XXVIII (Stage 2, preemptive-context-switch save/restore
|
||||
* primitive, 2026-09-13). This is deliberately NOT the same mechanism as
|
||||
* isr.S's interrupt trap frame (Stage 0) -- that saves every register
|
||||
* because an interrupt is not a call site the interrupted code knows
|
||||
* about. sk_vm_switch_to() IS an ordinary function call (SWITCH-TO's C
|
||||
* handler calls it directly), so the standard System V AMD64 ABI already
|
||||
* guarantees every caller-saved register (rax, rcx, rdx, rsi, rdi, r8-r11,
|
||||
* all XMM) is the caller's own problem to preserve across the call, exactly
|
||||
* like any other call. Only the callee-saved set -- rbx, rbp, r12-r15 --
|
||||
* needs explicit handling here, because this function does not really
|
||||
* "return" in the normal sense: it swaps to a completely different stack
|
||||
* and (from the newly-resumed context's point of view) appears to return
|
||||
* from whichever earlier call to this same function originally parked it.
|
||||
* SysV has no callee-saved XMM registers at all, so there is no FP state
|
||||
* to carry here.
|
||||
*
|
||||
* void sk_vm_switch_to(uint64_t *save_sp_out, uint64_t new_sp);
|
||||
* rdi = save_sp_out, rsi = new_sp
|
||||
*
|
||||
* For a VM that has never run before, new_sp must point at a synthetic
|
||||
* frame built to this exact layout by the C glue (switch.c): six zeroed
|
||||
* quadwords (r15, r14, r13, r12, rbx, rbp -- values irrelevant, never a
|
||||
* real prior context) followed by the trampoline entry address at
|
||||
* new_sp+48, so the final `ret` below jumps there instead of into some
|
||||
* prior caller.
|
||||
*/
|
||||
|
||||
.intel_syntax noprefix
|
||||
.section .text
|
||||
|
||||
.hidden sk_vm_switch_to
|
||||
|
||||
.global sk_vm_switch_to
|
||||
sk_vm_switch_to:
|
||||
push rbp
|
||||
push rbx
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
mov [rdi], rsp /* *save_sp_out = rsp (this context's parked SP) */
|
||||
mov rsp, rsi /* rsp = new_sp (switch stacks) */
|
||||
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbx
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
/*
|
||||
* uint64_t sk_vm_switch_prime(uint64_t stack_top, void *entry);
|
||||
*
|
||||
* Builds the synthetic frame described above at the top of a fresh native
|
||||
* stack, so the first ever sk_vm_switch_to() into it lands at `entry`
|
||||
* instead of some real prior caller. Returns the resulting sp value to
|
||||
* pass as sk_vm_switch_to()'s new_sp. Kept in this file (not C) so the
|
||||
* layout can never drift from what sk_vm_switch_to() above actually
|
||||
* expects -- one set of offsets, not two copies to keep in sync.
|
||||
*/
|
||||
.hidden sk_vm_switch_prime
|
||||
|
||||
.global sk_vm_switch_prime
|
||||
sk_vm_switch_prime:
|
||||
mov rax, rdi
|
||||
sub rax, 56
|
||||
mov qword ptr [rax+0], 0 /* r15 */
|
||||
mov qword ptr [rax+8], 0 /* r14 */
|
||||
mov qword ptr [rax+16], 0 /* r13 */
|
||||
mov qword ptr [rax+24], 0 /* r12 */
|
||||
mov qword ptr [rax+32], 0 /* rbx */
|
||||
mov qword ptr [rax+40], 0 /* rbp */
|
||||
mov [rax+48], rsi /* return address = entry */
|
||||
ret
|
||||
Reference in New Issue
Block a user