refactor(v3): the block subsystem's state is a chain there can be two of; blk_subsys_init takes no VM

The global state becomes struct blk_chain, reached through a current
pointer: blk_chain_default, blk_chain_new, blk_chain_select.  Nothing
that uses the one chain changes.  blk_subsys_init loses its VM argument,
which was stored and never used.  docs/v4.0.0/MESH.md 8.4.

Accepted on the v3 configuration: amd64, aarch64 and riscv64 reach the
zuse prompt, no UNKNOWN WORD, PARITY:M7.1a hash 0x08873e0f44b7cb2a on
all three, as on 2026-10-03.  logs/20261006-202918, -203036, -203230.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-06 20:33:32 -04:00
co-authored by Claude Opus 5.5
parent a7991f2757
commit 0e761cb117
8 changed files with 27485 additions and 11 deletions
+3 -1
View File
@@ -95,7 +95,9 @@
int capsule_blk_init(void *vm, uint8_t *ram_buf, size_t ram_size, uint8_t *krd_buf)
{
int rc = blk_subsys_init((VM *)vm, ram_buf, ram_size);
int rc;
(void)vm; /* the block subsystem no longer takes one */
rc = blk_subsys_init(ram_buf, ram_size);
if (rc != 0) return rc;
return blk_subsys_add_raw_device(krd_buf, KRD_MAX_BLOCKS);
}
+1 -1
View File
@@ -303,7 +303,7 @@ int sk_vm_bootstrap_parity(ParityPacket *out) {
/* Initialize block subsystem for POST — mirrors hosted main.c init order.
* Without this, all block word tests fail with vm->error=1 (blk_is_valid→0). */
blk_subsys_init(vm, sk_post_blk_ram, sizeof(sk_post_blk_ram));
blk_subsys_init(sk_post_blk_ram, sizeof(sk_post_blk_ram));
/* Run full POST (Power-On Self Test) */
console_println("POST: Running comprehensive test suite...");
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+12 -1
View File
@@ -327,7 +327,18 @@ typedef struct {
enum { BLK_FMT_FORMATTED = 0, BLK_FMT_PROVISIONAL = 1 };
/* ===== Public API ===== */
int blk_subsys_init(VM *vm, uint8_t *ram_base, size_t ram_size);
int blk_subsys_init(uint8_t *ram_base, size_t ram_size);
/* A chain is fast RAM and the devices chained after it. blk_chain_default
* is the one there has always been. blk_chain_new makes another, not yet
* initialized, or returns 0 if there is no memory. blk_chain_select makes
* every blk_* call from now on act on `c`, blk_subsys_init included, and
* returns the chain that was selected before; a null `c` selects nothing
* new. docs/v4.0.0/MESH.md 8.4. */
typedef struct blk_chain blk_chain_t;
blk_chain_t *blk_chain_default(void);
blk_chain_t *blk_chain_new(void);
blk_chain_t *blk_chain_select(blk_chain_t *c);
int blk_subsys_attach_device(struct blkio_dev *dev);
+21 -6
View File
@@ -167,8 +167,11 @@ struct blk_dev_slot {
};
/* ===== global state ===== */
static struct {
VM *vm;
/* A chain: fast RAM and the devices chained after it. There is the one
* v3 has always had (blk_chain_default) and there can be others
* (blk_chain_new); every blk_* call acts on the one selected
* (blk_chain_select). docs/v4.0.0/MESH.md 8.4. */
struct blk_chain {
uint8_t *ram_base;
size_t ram_size;
uint8_t dirty_ram[BLK_RAM_BLOCKS];
@@ -200,7 +203,20 @@ static struct {
uint32_t reloc_count;
int initialized;
} g = {0};
};
static struct blk_chain g_default;
static struct blk_chain *g_current = &g_default;
#define g (*g_current)
blk_chain_t *blk_chain_default(void) { return &g_default; }
blk_chain_t *blk_chain_new(void) { return (blk_chain_t *) calloc(1, sizeof(struct blk_chain)); }
blk_chain_t *blk_chain_select(blk_chain_t *c) {
blk_chain_t *was = g_current;
if (c) g_current = c;
return was;
}
/* Redirect lbn through the relocation table if it's been moved elsewhere.
* The single choke point every public LBN-consuming entry point below
@@ -644,11 +660,10 @@ static inline uint64_t blk_get_timestamp(void) {
/* ===== public API ===== */
int blk_subsys_init(VM *vm, uint8_t *ram_base, size_t ram_size) {
if (!vm || !ram_base || ram_size < ((size_t) BLK_RAM_BLOCKS * BLK_FORTH_SIZE))
int blk_subsys_init(uint8_t *ram_base, size_t ram_size) {
if (!ram_base || ram_size < ((size_t) BLK_RAM_BLOCKS * BLK_FORTH_SIZE))
return BLK_EINVAL;
memset(&g, 0, sizeof(g));
g.vm = vm;
g.ram_base = ram_base;
g.ram_size = ram_size;
g.ram_user = (BLK_RAM_BLOCKS > BLK_FORTH_SYS_RESERVED)
+2 -2
View File
@@ -316,9 +316,9 @@ static int init_vm_and_subsystem(VM* vm)
}
/* Initialize block subsystem */
extern int blk_subsys_init(VM* vm, uint8_t* ram_base, size_t ram_size);
extern int blk_subsys_init(uint8_t* ram_base, size_t ram_size);
static uint8_t blk_ram[BLK_RAM_BLOCKS * BLK_FORTH_SIZE];
int rc = blk_subsys_init(vm, blk_ram, sizeof(blk_ram));
int rc = blk_subsys_init(blk_ram, sizeof(blk_ram));
if (rc != 0)
{
fprintf(stderr, "Failed to initialize block subsystem (rc=%d)\n", rc);