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
+226
View File
@@ -0,0 +1,226 @@
/*
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.
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.
*/
/**
* timer.h - Timer and Heartbeat Interface
*
* M5 Time Model:
* - TIME-TICKS (Q64.0): Monotonic heartbeat counter, never decreases
* - TIME-TRUST (Q48.16): Continuous confidence metric [0.0, 1.0]
* - No discrete modes (NONE/REL/ABS are legacy, being phased out)
* - Trust is a measurement, never gates execution
*/
#ifndef STARKERNEL_TIMER_H
#define STARKERNEL_TIMER_H
#include <stdint.h>
#include "uefi.h"
#include "q48_16.h"
/* ============================================================================
* M5 Time Model (New)
* ============================================================================ */
/* TIME-TRUST: Continuous confidence metric in Q48.16 format */
typedef q48_16_t time_trust_t;
/* Rolling window size for timestamp variance computation */
#define TIME_WINDOW_SIZE 64
/* TIME-TRUST thresholds in Q48.16 (for diagnostics, NOT for gating) */
#define TIME_TRUST_HIGH Q48_ONE /* 1.0 = full confidence */
#define TIME_TRUST_LOW (Q48_ONE >> 2) /* 0.25 = low confidence */
/*
* Rolling window of timestamp deltas for variance computation.
* Each entry is (actual_tsc_delta - expected_tsc_delta) in TSC ticks.
*/
typedef struct time_window {
int64_t deltas[TIME_WINDOW_SIZE]; /* Signed: can be early or late */
uint32_t pos; /* Current write position */
uint32_t count; /* Number of valid samples (up to SIZE) */
} TimeWindow;
/*
* M5 Heartbeat State: Holds all time-related metrics.
* Updated every heartbeat tick by the ISR.
*/
typedef struct time_trust_state {
/* Core counters */
volatile uint64_t ticks; /* TIME-TICKS: monotonic heartbeat count --
* written directly in ISR context
* (heartbeat_tick(), all three archs) and
* read directly by mainline
* (heartbeat_ticks()); genuinely
* concurrent, unlike every other field in
* this struct (FABRIC-0.md item 4.5a/4.5b,
* 2026-08-11). */
uint64_t last_tsc; /* TSC at last heartbeat */
uint64_t expected_delta; /* Expected TSC ticks per heartbeat */
/* Rolling window for variance */
TimeWindow window;
/* Derived metrics (Q48.16) */
q48_16_t variance; /* Variance of deltas */
q48_16_t trust; /* TIME-TRUST: derived from variance */
/* Statistics */
uint64_t total_samples; /* Lifetime sample count */
} TimeTrustState;
/* ============================================================================
* Legacy M4 Interface (To Be Phased Out)
* ============================================================================ */
/*
* Timer trust levels (LEGACY - discrete modes violate M5 spec):
* - NONE: no usable time base
* - RELATIVE: monotonic-ish, not for claims
* - ABSOLUTE: invariant + calibrated
*/
typedef enum timer_trust_level {
TIMER_TRUST_NONE = 0,
TIMER_TRUST_RELATIVE = 1,
TIMER_TRUST_ABSOLUTE = 2
} timer_trust_level_t;
/*
* Timer calibration record for logging / DoE traceability.
* Keep it minimal and serial-friendly.
*/
typedef struct timer_calibration_record {
uint64_t hpet_hz; /* HPET frequency derived from period_fs (if available) */
uint64_t tsc_hz_mean; /* Locked TSC Hz (final) */
uint64_t pit_hz_mean; /* PIT-based estimate (if used) */
uint64_t cv_hpet_ppm; /* HPET window CV in ppm (bare metal convergence) */
uint64_t cv_pit_ppm; /* PIT window CV in ppm (bare metal convergence) */
uint64_t diff_ppm; /* HPET vs PIT mean diff in ppm (bare metal convergence) */
uint32_t windows_used; /* number of windows consumed to converge */
uint8_t converged; /* 1 if converged/locked, 0 otherwise */
uint8_t vm_mode; /* 1 if hypervisor policy path used */
uint8_t trust; /* timer_trust_level_t (NONE/RELATIVE/ABSOLUTE) */
uint8_t reserved[1];
} timer_calibration_record_t;
/* Legacy API (still works, wraps M5 internals) */
int timer_init(BootInfo *boot_info);
uint64_t timer_tsc_hz(void);
uint64_t timer_now_ns(void);
int timer_check_drift_now(void);
const timer_calibration_record_t *timer_calibration_record(void);
/* ============================================================================
* M5 Heartbeat API (New)
* ============================================================================ */
/*
* Initialize the heartbeat subsystem.
* Called after timer_init(), before enabling APIC timer.
*/
void heartbeat_init(uint64_t tsc_hz, uint64_t tick_hz);
/**
* Top half. Called directly from each architecture's ISR (punch-list item
* 0.8) -- one call site per architecture, unchanged from before this item.
* Does exactly three things: reads the raw counter via
* @c heartbeat_read_counter(), increments TIME-TICKS, and latches the
* sample for @c heartbeat_service() to pick up. No window math, no
* variance, no loops -- this must stay cheap enough for interrupt context.
*/
void heartbeat_tick(void);
/**
* Bottom half (punch-list item 0.8). Services one pending sample if
* @c heartbeat_tick() has latched one since the last call: computes the
* inter-tick deviation, updates the rolling window, and (architecture
* permitting -- see @c heartbeat.c) recomputes variance and TIME-TRUST.
* Never runs in interrupt context. Call from the mainline, as frequently
* as convenient -- a stale/skipped service call degrades the window's
* fidelity but affects nothing else, since TIME-TRUST is diagnostic only
* and never gates execution.
*/
void heartbeat_service(void);
/**
* Read the raw hardware counter this architecture's heartbeat is paced
* against -- the same clock @c timer_now_ns() and calibration already use
* internally (rdtsc on amd64, the `time` CSR on riscv64, CNTPCT_EL0 on
* aarch64), not a separate/different source. Implemented once per
* architecture in that architecture's timer.c; consumed only by
* @c heartbeat_tick() in the shared heartbeat.c.
*/
uint64_t heartbeat_read_counter(void);
/**
* Get current TIME-TICKS (monotonic heartbeat count).
*/
uint64_t heartbeat_ticks(void);
/**
* Get current TIME-TRUST (Q48.16 confidence metric).
*/
time_trust_t heartbeat_trust(void);
/**
* Get pointer to full heartbeat state (for diagnostics).
*/
const TimeTrustState *heartbeat_state(void);
/**
* Set the adaptive re-arm period, in nanoseconds (punch-list item 0.8,
* FABRIC-0.md §26). Called from the mainline execution path only (Loop #7's
* site in vm_runtime.c) -- never from interrupt context. Clamped to
* [1/4x, 4x] of the kernel's base period internally; a caller need not
* pre-clamp.
*/
void heartbeat_set_adaptive_period_ns(uint64_t ns);
/**
* Read the period the next hardware re-arm should use. Called from
* interrupt context by each architecture's re-arm function in place of a
* fixed constant.
*/
uint64_t heartbeat_next_period_ns(void);
#endif /* STARKERNEL_TIMER_H */