Files
LithosAnanake/v3/src/word_source/include/block_words.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

196 lines
7.1 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.
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 */