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:
rajames
2026-10-01 15:40:09 -04:00
co-authored by Junie
parent 3c709c115b
commit a8b70e88d3
630 changed files with 2646 additions and 2036 deletions
+263
View File
@@ -0,0 +1,263 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* capsule_run.h - DoE Run Logging (M7.1)
*
* Structures for logging capsule execution runs and VM births.
* Supports provenance tracking and experiment reproducibility.
*/
#ifndef STARKERNEL_CAPSULE_RUN_H
#define STARKERNEL_CAPSULE_RUN_H
#include <stddef.h>
#include <stdint.h>
#include "starkernel/vm_uuid.h" /* VMUuid -- FABRIC-0.md item 3.8 */
#ifdef __cplusplus
extern "C" {
#endif
/*===========================================================================
* Run Log Configuration
*===========================================================================*/
/** Phase A: Fixed ring buffer size */
#define CAPSULE_MAX_RUN_RECORDS 1024
/*===========================================================================
* Result Codes
*===========================================================================*/
typedef enum {
CAPSULE_RUN_OK = 0,
CAPSULE_RUN_ERR_INVALID, /* Invalid capsule */
CAPSULE_RUN_ERR_NOT_ELIGIBLE, /* Capsule not eligible for operation */
CAPSULE_RUN_ERR_EXEC_FAIL, /* Execution failed */
CAPSULE_RUN_ERR_HASH_MISMATCH, /* Post-run hash mismatch */
CAPSULE_RUN_ERR_STILLBORN, /* VM birth failed */
CAPSULE_RUN_ERR_FLEET_FULL, /* Outer Stadium at stadium_max_vm_count() (FABRIC-0.md item 1.5/2.2) */
} CapsuleRunResult;
/*===========================================================================
* CapsuleRunRecord - DoE Execution Log Entry
*===========================================================================*/
typedef struct {
uint64_t run_id; /* Sequential run identifier */
VMUuid vm_id; /* Which VM executed this (item 3.8) */
uint32_t reserved; /* Padding */
uint64_t capsule_id; /* Which capsule was run */
uint64_t capsule_hash; /* Hash at time of execution */
uint64_t pre_dict_hash; /* Dictionary state before run */
uint64_t post_dict_hash; /* Dictionary state after run */
uint64_t started_ns; /* Monotonic start time */
uint64_t ended_ns; /* Monotonic end time */
uint32_t result_code; /* CapsuleRunResult */
uint32_t flags; /* Run flags (mode, etc.) */
} CapsuleRunRecord;
/*===========================================================================
* VM Registry Entry
*===========================================================================*/
/** Maximum length of a VM symbolic name, including null terminator */
#define VM_NAME_MAX 64
typedef enum {
VM_STATE_EMBRYO = 0, /* Allocated but not yet born */
VM_STATE_LIVE, /* Successfully born, operational */
VM_STATE_STOPPED, /* Suspended — execution state saved. Set by
* the START word after STOP cleanly unwinds
* its C stack back to START's own frame: no
* live native frame remains, safe to free. */
VM_STATE_STILLBORN, /* Birth failed */
VM_STATE_DEAD, /* Terminated */
VM_STATE_SWITCHED_OUT, /* FABRIC-3.md §XXVIII, Stage 2 (2026-09-13):
* a live saved register/stack context is
* parked on this VM's own native stack
* (SWITCH-TO switched control away mid-
* execution). Deliberately distinct from
* VM_STATE_STOPPED -- that state means "no
* live native frame," this one means the
* opposite. KILL must refuse/defer here: the
* parked frame still points into vm->memory
* and the native stack, both of which a free
* would invalidate out from under it. */
} VMState;
typedef struct {
VMUuid vm_id; /* Assigned at birth, immutable (item 3.8) */
uint32_t state; /* VMState */
uint64_t birth_capsule_id; /* Which capsule birthed this VM */
uint64_t birth_timestamp_ns; /* When VM was born */
uint64_t birth_dict_hash; /* Dictionary hash after birth */
uint32_t flags; /* VM flags */
VMUuid parent_vm_id; /* Who birthed this VM. Set once at birth,
* never rewritten. Hera's own entry is
* self-referential (parent_vm_id == vm_id
* == vm_uuid_hera(), all-zero) -- the
* sentinel a heat-fanout walk up the
* parent chain stops at. */
void *vm_ptr; /* Pointer to live VM object; NULL when dead */
char name[VM_NAME_MAX]; /* Symbolic name, e.g. "Hera", "Hermes" */
size_t stadium_patron_cell; /* FABRIC-2.md SS B, VM-COOL: this VM's own
* Stadium cell index (STADIUM_CELL_NONE,
* i.e. (size_t)-1, if never admitted or
* already reaped) -- admitted into the VM's
* own quota at birth, explicitly evicted at
* KILL. Not Hera's; she is pinned and never
* reaches this field's purpose. */
int pending_reap; /* FABRIC-3.md §XXVIII Stage 4 (2026-09-14):
* set (capsule_vm_set_pending_reap()) when
* this VM is VM_STATE_SWITCHED_OUT and its
* owning WIREBIND device has physically
* detached -- capsule_vm_kill() correctly
* refuses to free a parked context, but the
* memory still needs reclaiming once it's
* no longer coming back. Deliberately a
* plain flag, not a new VMState: `state`
* still accurately reads SWITCHED_OUT (a
* live context genuinely is parked there)
* until the Stage 3 checkpoint
* (vm_core.c) notices this flag instead of
* attempting to resume it, and calls
* capsule_vm_force_reap() there instead --
* a safe point the switcher itself
* controls, not the async detach handler. */
} VMRegistryEntry;
/*===========================================================================
* Run Log Functions
*===========================================================================*/
/**
* capsule_run_log_init - Initialize run log
*/
void capsule_run_log_init(void);
/**
* capsule_run_log_record - Log a run record
*
* @param record Record to log
* @return Run ID assigned, or 0 on failure
*/
uint64_t capsule_run_log_record(const CapsuleRunRecord *record);
/**
* capsule_run_log_get - Get a run record by ID
*
* @param run_id Run ID to retrieve
* @param out Output record
* @return 0 on success, -1 if not found
*/
int capsule_run_log_get(uint64_t run_id, CapsuleRunRecord *out);
/**
* capsule_run_log_count - Get number of logged runs
*/
uint32_t capsule_run_log_count(void);
/*===========================================================================
* Parity Logging
*===========================================================================*/
/**
* capsule_parity_log_birth - Log VM birth parity record
*
* Output format:
* PARITY:BIRTH vm_id=N capsule_id=X mode=p capsule_hash=H dict_hash=D
*/
void capsule_parity_log_birth(
VMUuid vm_id,
uint64_t capsule_id,
uint64_t capsule_hash,
uint64_t dict_hash
);
/**
* capsule_parity_log_birth_failed - Log failed birth
*
* Output format:
* PARITY:BIRTH_FAILED vm_id=N capsule_id=X error=E partial_dict_hash=H
*/
void capsule_parity_log_birth_failed(
VMUuid vm_id,
uint64_t capsule_id,
CapsuleRunResult error,
uint64_t partial_dict_hash
);
/**
* capsule_parity_log_run - Log DoE run parity record
*
* Output format:
* PARITY:RUN vm_id=N run_id=R capsule_id=X mode=e pre_dict=P post_dict=Q
*/
void capsule_parity_log_run(
VMUuid vm_id,
uint64_t run_id,
uint64_t capsule_id,
uint64_t pre_dict_hash,
uint64_t post_dict_hash
);
/**
* capsule_parity_log_mama_init - Log Mama init parity record
*
* Output format:
* PARITY:MAMA_INIT capsule_id=X mode=m capsule_hash=H dict_hash=D
*/
void capsule_parity_log_mama_init(
uint64_t capsule_id,
uint64_t capsule_hash,
uint64_t dict_hash
);
/**
* capsule_parity_log_kill - Log VM kill parity record
*
* Output format:
* PARITY:KILL vm_id=N name=X
*/
void capsule_parity_log_kill(
VMUuid vm_id,
const char *name
);
/**
* capsule_parity_set_output - Set output hooks for parity logging
*
* @param putc_fn Function to output a single character
* @param puts_fn Function to output a string
*/
void capsule_parity_set_output(
void (*putc_fn)(char),
void (*puts_fn)(const char *)
);
#ifdef __cplusplus
}
#endif
#endif /* STARKERNEL_CAPSULE_RUN_H */