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,196 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file block_words.h
|
||||
* @brief FORTH-79 Block and Buffer System Implementation
|
||||
*
|
||||
* This file implements the standard FORTH-79 block and buffer words:
|
||||
* @li BLOCK ( u -- addr ) Get block buffer address
|
||||
* @li BUFFER ( u -- addr ) Get empty buffer for block
|
||||
* @li UPDATE ( -- ) Mark current block as modified
|
||||
* @li SAVE-BUFFERS ( -- ) Save all modified blocks
|
||||
* @li EMPTY-BUFFERS ( -- ) Mark all buffers as empty
|
||||
* @li FLUSH ( -- ) Save buffers and empty them
|
||||
* @li LIST ( u -- ) List block contents
|
||||
* @li LOAD ( u -- ) Load and interpret block
|
||||
* @li SCR ( -- addr ) Variable: screen/block being listed
|
||||
* @li THRU ( u1 u2 -- ) Load blocks from u1 to u2
|
||||
* @li --> or → ( -- ) Continue to next block
|
||||
*/
|
||||
|
||||
#ifndef BLOCK_WORDS_H
|
||||
#define BLOCK_WORDS_H
|
||||
|
||||
#include "vm.h"
|
||||
|
||||
/** @name Block System Configuration
|
||||
* @{
|
||||
*/
|
||||
/** @brief Size of each block in bytes (1KB) */
|
||||
#define BLOCK_SIZE 1024
|
||||
/** @brief Maximum number of blocks (1024 blocks from 1MB memory) */
|
||||
#define MAX_BLOCKS (VM_MEMORY_SIZE / BLOCK_SIZE)
|
||||
/** @brief Number of block buffers in memory */
|
||||
#define BUFFER_COUNT 4
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Block buffer types for different storage mechanisms
|
||||
*/
|
||||
typedef enum {
|
||||
BUFFER_TYPE_MEMORY, /**< Direct memory access (current implementation) */
|
||||
BUFFER_TYPE_HARDWARE, /**< Future: Hardware register blocks */
|
||||
BUFFER_TYPE_STORAGE, /**< Future: Persistent storage blocks */
|
||||
BUFFER_TYPE_NETWORK /**< Future: Network packet buffers */
|
||||
} buffer_type_t;
|
||||
|
||||
/**
|
||||
* @brief Block buffer structure maintaining buffer state
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char data[BLOCK_SIZE]; /**< Block content buffer */
|
||||
int block_number; /**< Currently loaded block number (-1 = empty) */
|
||||
int dirty; /**< Modified flag for write-back */
|
||||
int accessed; /**< LRU counter for buffer management */
|
||||
buffer_type_t type; /**< Buffer type for storage mechanism */
|
||||
uintptr_t hw_address; /**< Future: Hardware backing address */
|
||||
} BlockBuffer;
|
||||
|
||||
/**
|
||||
* @brief Registers all block and buffer words with the virtual machine
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
*/
|
||||
void register_block_words(VM * vm);
|
||||
|
||||
/**
|
||||
* @brief Initializes the block system
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
*/
|
||||
void init_block_system(VM * vm);
|
||||
|
||||
/*
|
||||
* @brief Gets a buffer containing the specified block
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
* @param block_num Block number to retrieve
|
||||
* @return Pointer to the block buffer data
|
||||
*/
|
||||
unsigned char *get_block_buffer(VM *vm, int block_num);
|
||||
|
||||
/*
|
||||
* @brief Gets an empty buffer for the specified block
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
* @param block_num Block number to allocate
|
||||
* @return Pointer to the empty buffer data
|
||||
*/
|
||||
unsigned char *get_empty_buffer(VM *vm, int block_num);
|
||||
|
||||
/**
|
||||
* @brief Marks the current buffer as modified
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
*/
|
||||
void mark_buffer_dirty(VM * vm);
|
||||
|
||||
/*
|
||||
* @brief Saves all modified buffers to storage
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
*/
|
||||
void save_all_buffers(VM * vm);
|
||||
|
||||
/**
|
||||
* @brief Sync every dirty VM block-window slot to the C-layer block cache,
|
||||
* then flush the whole block subsystem to physical media --
|
||||
* the complete SAVE-BUFFERS implementation (unlike
|
||||
* save_all_buffers() above, which only calls blk_flush() and so
|
||||
* misses any BUFFER-modified-but-not-yet-UPDATE'd content still
|
||||
* sitting only in vm->memory's window). Cheap to call when nothing
|
||||
* is dirty -- every check inside is a small fixed-size scan, no
|
||||
* I/O happens unless something actually needs writing. Safe to
|
||||
* call from outside word dispatch (e.g. a periodic idle-tick
|
||||
* auto-flush); vm must be non-NULL.
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
*/
|
||||
void blk_vm_flush_all(VM * vm);
|
||||
|
||||
/*
|
||||
* @brief Marks all buffers as empty
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
*/
|
||||
void empty_all_buffers(VM * vm);
|
||||
|
||||
/**
|
||||
* @brief Discards vm->blk_vm_lbn[]/cbuf[]/dirty[] if the device chain has
|
||||
* changed since last validated (see this function's own doc comment in
|
||||
* block_words.c for why). Exposed (Phase 8 v3, 2026-09-23) so callers
|
||||
* outside this file that read vm->blk_vm_lbn[] directly (MOVE/CMOVE's
|
||||
* cross-device block-copy check, memory_words.c/string_words.c) go through
|
||||
* the same invalidation contract blk_vm_find() already uses internally,
|
||||
* rather than a second, divergent copy of this logic.
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
*/
|
||||
void blk_vm_check_epoch(VM *vm);
|
||||
|
||||
/**
|
||||
* @brief Does `addr` fall inside the block I/O window? Pure address
|
||||
* arithmetic against the window's fixed compile-time base/size -- no VM
|
||||
* state needed. Exposed (Phase 8 v3, 2026-09-23) for MOVE/CMOVE/CMOVE>'s
|
||||
* cross-device block-copy check.
|
||||
* @param addr VM offset to test
|
||||
* @return slot index (0..BLK_VM_SLOTS-1) if inside the window, -1 otherwise
|
||||
*/
|
||||
int blk_vm_slot_for_addr(vaddr_t addr);
|
||||
|
||||
/**
|
||||
* @brief True if addr1/addr2 are both block-window addresses currently
|
||||
* loaded from two different physical devices (Phase 8 v3, 2026-09-23) --
|
||||
* the check MOVE/CMOVE/CMOVE> call before copying to refuse a same-VM,
|
||||
* cross-device raw block copy. See this function's own doc comment in
|
||||
* block_words.c for exactly what is and isn't flagged.
|
||||
* @param vm VM performing the copy
|
||||
* @param addr1 first VM offset (source or destination, order doesn't matter)
|
||||
* @param addr2 second VM offset
|
||||
* @return 1 if this copy should be refused, 0 otherwise
|
||||
*/
|
||||
int blk_vm_is_cross_device_copy(VM *vm, vaddr_t addr1, vaddr_t addr2);
|
||||
|
||||
#endif /* BLOCK_WORDS_H */
|
||||
Reference in New Issue
Block a user