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>
Per-slot registry (xhci_msc_slot_t/dev->msc_slots, sized off the
controller's own reported max_slots) replaces the single-device scalar
fields the driver carried since Milestones 2e-2h. Boot-time port scan no
longer stops at the first connected device; a connect/disconnect that
arrives while the Command Ring is busy is now queued and drained instead
of dropped. blkio_usb.c and repl.c's own single-device state (device
descriptor buffers, blkio_dev_t, attach bookkeeping) became per-slot
registries the same way.
Live multi-device testing (not just compiling) surfaced a second, more
severe bug outside the original plan: transfer_purpose and next_action
were also single scalars shared across the whole controller. Two devices
enumerating concurrently could have one's completion silently overwrite
the other's still-outstanding one, permanently stalling it with no error.
Fixed by moving both per-slot and, critically, reading the Transfer Event
TRB's own real Slot ID field instead of trusting external bookkeeping.
Verified live, all three architectures, mandatory clean-qemu acceptance:
existing single-device path unchanged, and two devices attached
simultaneously (amd64) both progress independently through enumeration
without corrupting or stalling each other.
Also in this pass (implemented and verified in earlier turns this
session, committed together per direct instruction):
- Headless-until-login console policy: no prompt/banner until a real
identity logs in via an attached thumbdrive (WIREBIND or Zuse, neither
special), reusing EMERGENCY_CONSOLE_ENABLED as the debug/recovery
escape hatch (now default-off).
- KILL/g_repl_active_vm dangling-pointer fix: killing the VM the console
is currently USE'd onto now detaches back to Hera first, matching the
existing EJECT/UNCLEAN precedent.
FABRIC-3.md §VII/§VIII carry full closure notes for all three.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018EjXFo7mPXjUMjfJeuUUz4
FABRIC.md -> FABRIC-0.md
FABRIC-2.md -> FABRIC-1.md
FABRIC-3.md -> FABRIC-2.md (the current/living document)
FABRIC-4.md unchanged (new #3 to follow separately)
Every cross-reference repo-wide updated to match, including doc-comment
citations inside kernel source (.c/.h) files -- done via an ordered
placeholder substitution (FABRIC-3.md->placeholder2, FABRIC-2.md->
placeholder1, FABRIC.md->placeholder0, then placeholders resolved to
final names) in a single pass per file to avoid double-shifting
already-renamed references.
One line in capsules/font.4th grew past the 64-char block-format limit
as a side effect of the longer filename; shortened it and reverified
with mkcapsule --lint (34/34 pass) before rebuilding.
Verified 3-arch boot to ok> (amd64/aarch64/riscv64, each in the
foreground) after the fix; logs and DoE CSVs from this session's
verification runs included per this repo's own audit-artifact
convention.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
Direct mirror of the existing READ(10) implementation (FABRIC-3.md §F.1),
data direction flipped: new XHCI_XFER_BOT_DATA_OUT/XHCI_NEXT_ACTION_BOT_DATA_OUT
states, xhci_bot_send_write10()/xhci_bot_write_block()/xhci_bot_write_data_out()
in xhci.c, new SCSI_CMD_WRITE10 opcode and BOT_CMD_WRITE10/BOT_TUR_CHAIN_WRITE10
enum values. usb_blk_write() in blkio_usb.c is real now, no longer the
BLKIO_ENOSUP stub. read_only flips to 0 in blkio_info() now that it's proven.
Verified live end-to-end on all three architectures with a genuine cold-reboot
round-trip (not just a same-session read): BLK-CONFIRM-FORMAT's BAM/reloc
writes and an explicit block content write both completed via clean WRITE10
cycles (CSW PASS), and the written byte read back correctly after a full
kernel rebuild + fresh boot -- amd64=65, aarch64=170, riscv64=201, each at
LBN 32734 on a disposable usbwrite-test.img attached via QEMU usb-storage.
Added Makefile.starkernel's QEMU_EXTRA (empty by default, no behavior change)
to attach the disposable test image for this validation; the drive must be
hotplugged via QMP after boot reaches ok>, not attached at QEMU launch --
attaching before xhci_bringup()'s controller reset means no fresh Port
Status Change event fires (see project_xhci_milestone_2d_polling memory).
Found and reported, not fixed, during testing: EMPTY-BUFFERS
(empty_all_buffers(), block_words.c) does not implement standard Forth-79
semantics -- it force-writes zero to every block on every attached device
instead of discarding cache assignments. This corrupted disk/artemis.img
during an earlier test run; restored from git, confirmed byte-identical.
Avoided in the final validation runs (detach/reattach used instead to force
a fresh read).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZGkimpfyh63EZyRkNbkPD
Wires a hot-plugged USB Mass Storage device into the block subsystem's
unified LBN chain. blkio_usb.c/blkio_usb.h mirror virtio_blk.c/
virtio_blk.h's established shape exactly (singleton state, blkio_vtable_t,
a blkio_usb_open_msc() "find" function playing virtio_blk_find_artemis()'s
role): read() translates a Forth block into a SCSI LBA/count pair and
calls xhci_bot_read_block() + xhci_bot_wait_for_idle(); write() returns
BLKIO_ENOSUP (no SCSI WRITE(10) exists yet, and blk_format_or_load_disk()
never writes at attach time, so read-only is sufficient -- confirmed by
reading that function first, not assumed). Refuses (-2) if the reported
SCSI block size doesn't evenly divide the 1024-byte Forth block size.
Connect-time wiring reuses the bot_msc_attach_pending/consume-in-
sk_repl_idle() shape the prior increment's temp probe already validated,
now made permanent: SET_CONFIGURATION sets the flag, sk_repl_idle()
(strictly after its own xhci_poll_events() call returns) calls
blkio_usb_open_msc() then blk_subsys_attach_device().
Verified live via hot-attach: full chain from USB connect through
'blkio_usb: MSC device ready' to 'blk: disk 'StarForth Volume' v2 LBN
26074..75184 (49111 user blocks)' -- real attachment, disk image confirmed
byte-for-byte untouched after. Chased a real debugging detour along the
way: the attach initially appeared silent (no blk: log line) -- traced to
LOG_INFO filtering at the default LOG_WARN boot level, not a functional
bug (settled via a temporary log-level bump, reverted after capture; also
found and reported, but did not fix, a pre-existing unrelated
Makefile.starkernel bug where --log-level=info via KERNEL_ARGS breaks
printf parsing). All three architectures re-verified clean. FABRIC-2.md
Section X 2h updated -- only hot-detach remains for 2h.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXjAPTEKrgY2Mrk25KoLDn