Files
LithosAnanake/kernel/include/starkernel/vm/stadium_blocks.h
T
rajamesandJunie a8b70e88d3 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>
2026-10-01 15:40:09 -04:00

125 lines
5.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
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.
*/
/**
* stadium_blocks.h - Block patrons on the Stadium (FABRIC-2.md §B/§D,
* MIGRATE punch-list item)
*
* The block-specific layer on top of the generic L0 engine (stadium.h), same
* relationship stadium_words.h/.c already has: nothing in stadium.c/.h knows
* a block patron exists -- it only ever sees cell_index, VMUuid, and
* StadiumPatronHeader. This file is where "block" becomes a concrete
* meaning: an (owning quota slot, LBN) -> cell_index map, the starter-grant
* admission rule (mirrors stadium_word_dispatch()'s Option B exactly), and
* the reservoir-quantum touch/cool that feeds and drains a resident block's
* Stadium heat.
*
* Unlike words, LBN is not densely bounded (block_subsystem.c's unified LBN
* space spans RAM/RAMDRIVE/DISK/USB and can be large), so the map here is a
* fixed-capacity open-addressing hash table sized off stadium_cell_count()
* at init, not a dense per-VM array -- see stadium_blocks.c for the layout.
* A block's actual 1024 content bytes are never copied into a Stadium cell;
* they stay exactly where block_subsystem.c already keeps them. The cell
* only ever carries identity (the LBN) and heat/bookkeeping, same as a word
* patron's cell never carries the word's own dictionary entry.
*/
#ifndef STARKERNEL_VM_STADIUM_BLOCKS_H
#define STARKERNEL_VM_STADIUM_BLOCKS_H
#ifdef __STARKERNEL__
#include <stdint.h>
#include "starkernel/vm_uuid.h"
/*
* stadium_blocks_init - Allocates and zeroes the (quota slot, LBN) ->
* cell_index hash table (capacity computed from stadium_cell_count() *
* STADIUM_BLOCK_TRACK_CAP_MULT at call time, kmalloc'd). Must be called
* after stadium_boot_init() -- so stadium_cell_count() is non-zero -- and
* before any block ever dispatches; the real boot site is immediately after
* the existing stadium_words_init() call (kernel_main.c), same M7/M7.1
* ordering. Not safe to call twice -- guarded internally as a no-op if
* already initialized, same convention as stadium_words_init().
*/
void stadium_blocks_init(void);
/*
* stadium_block_dispatch - The per-touch entry point, called from
* block_word_block()/block_word_buffer()/block_word_update()
* (src/word_source/block_words.c) -- mirroring stadium_word_dispatch()'s
* call pattern and cooling/admission logic 1:1, keyed by LBN instead of
* word_id.
*
* If (vm_id, lbn) is already resident: applies the same redirected Loop #3
* cooling stadium_word_dispatch() applies (fraction of the cell's own
* current heat, scaled by elapsed_ticks since this block's own last touch --
* STADIUM_BLOCK_COOL_RATE_Q48), crediting the cooled amount back to vm_id's
* reservoir, then pulls STADIUM_BLOCK_HEAT_QUANTUM from the reservoir into
* the cell -- clamped to the reservoir's actual balance AND to the same
* Q48_ONE / 3 floor stadium_word_dispatch() enforces, so block-touch
* admission alone can never starve other reservoir consumers sharing the
* same VM.
*
* If not resident (or the table's entry is stale -- self-healing check
* against the cell's discriminator bit and identity, same pattern
* resolve_resident_cell() uses in stadium_words.c): attempts starter-grant
* admission -- pulls STADIUM_BLOCK_HEAT_QUANTUM (same floor), builds an
* unpinned MIGRATE candidate (identity = lbn, mass = 1, payload unused --
* the block's real content is never copied here), calls stadium_admit(). On
* refusal, pushes the pulled quantum back (rollback). On success, records
* the mapping. If the hash table itself is full and has no slot for this
* (vm_id, lbn) pair, this touch is silently skipped -- Stadium's own
* capacity already bounds real residency, so a table miss under load is
* graceful degradation, not an error.
*
* No-op if vm_id holds no Stadium quota, or stadium_blocks_init() has not
* run.
*
* @param vm_id Owning VM -- vm->stadium_vm_id at every call site,
* same quota-isolation reasoning stadium_word_
* dispatch() already documents (LBN numbering is
* global, not per-VM, but quota scoping still keeps
* two VMs' admissions from evicting each other).
* @param lbn Logical block number being touched.
* @param heartbeat_ticks Current vm->heartbeat.tick_count.
*/
void stadium_block_dispatch(VMUuid vm_id, uint32_t lbn, uint64_t heartbeat_ticks);
/*
* stadium_blocks_print_boot_diagnostics - Console output mirroring
* stadium_words_print_boot_diagnostics(): promotions/evictions for vm_id's
* own block-touch table, plus a conservation check
* (Σ(resident block heat) + reservoir against Q48_ONE is NOT a standalone
* invariant here -- word-execution heat and any other resident shares the
* same reservoir, so this prints the block-only resident sum as a
* diagnostic term, not a claim that it alone should equal Q48_ONE).
*
* @param vm_id The VM whose block-touch table/reservoir to read.
*/
void stadium_blocks_print_boot_diagnostics(VMUuid vm_id);
#endif /* __STARKERNEL__ */
#endif /* STARKERNEL_VM_STADIUM_BLOCKS_H */