From a8b70e88d31fe2824b6df16e0efde50809d31bd2 Mon Sep 17 00:00:00 2001 From: rajames Date: Thu, 1 Oct 2026 15:40:09 -0400 Subject: [PATCH] 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= adds board appendix - build/docs//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= removes only that board and its ISA objects - make all builds all boards, hosted v3, and docs in one run Co-authored-by: Junie --- .clang-tidy | 2 +- .clang-tidy-ignore | 56 +- .claude/CLAUDE.md | 40 +- Doxyfile | 17 +- Kconfig.arch | 2 +- Kconfig.heartbeat | 2 +- Kconfig.kernel | 2 +- Makefile | 1447 ++--------------- README.md | 34 +- boards/README.md | 29 + boards/milkv/README.md | 30 + boards/milkv/board.mk | 11 + boards/raspi/README.md | 20 + boards/raspi/board.mk | 18 + {boot_media/rpi5 => boards/raspi}/config.txt | 7 + boards/ser5/README.md | 14 + boards/ser5/board.mk | 10 + boards/zynq7020/README.md | 17 + boards/zynq7020/board.mk | 11 + boot_media/rpi5/README.md | 12 - capsules/BLOCK_MAP.md | 82 +- configs/README.md | 2 +- ONTOLOGY.md => docs/ONTOLOGY.md | 0 ROADMAP.md => docs/ROADMAP.md | 0 docs/book/Makefile | 112 ++ docs/book/README.md | 66 + docs/book/main.tex | 161 ++ docs/book/pandoc/code-breaks.lua | 29 + docs/book/pandoc/highlighting.latex | 3 + docs/book/pandoc/table-widths.lua | 55 + FABRIC-0.md => docs/fabric/FABRIC-0.md | 0 FABRIC-1.md => docs/fabric/FABRIC-1.md | 0 FABRIC-2.md => docs/fabric/FABRIC-2.md | 0 FABRIC-3.5.md => docs/fabric/FABRIC-3.5.md | 0 FABRIC-3.6.md => docs/fabric/FABRIC-3.6.md | 0 FABRIC-3.7.md => docs/fabric/FABRIC-3.7.md | 0 FABRIC-3.md => docs/fabric/FABRIC-3.md | 0 FABRIC-4.md => docs/fabric/FABRIC-4.md | 0 Makefile.starkernel => kernel/Makefile | 282 ++-- .../include}/starkernel/README.md | 0 {include => kernel/include}/starkernel/apic.h | 0 {include => kernel/include}/starkernel/arch.h | 0 .../include}/starkernel/artemis_sig.h | 0 .../include}/starkernel/blkio_usb.h | 0 .../include}/starkernel/boot_info_offsets.h | 0 .../include}/starkernel/capsule.h | 0 .../include}/starkernel/capsule_birth.h | 0 .../include}/starkernel/capsule_console.h | 0 .../include}/starkernel/capsule_generated.h | 0 .../include}/starkernel/capsule_loader.h | 0 .../include}/starkernel/capsule_mint.h | 0 .../include}/starkernel/capsule_run.h | 0 .../include}/starkernel/capsule_runcap.h | 0 .../include}/starkernel/capsule_sig.h | 0 .../include}/starkernel/capsule_vm_physics.h | 0 .../starkernel/capsule_vm_switch_signal.h | 0 .../include}/starkernel/capsule_wirebind.h | 0 .../include}/starkernel/capsule_zuse_boot.h | 0 .../include}/starkernel/cmdline.h | 0 .../include}/starkernel/console.h | 0 .../include}/starkernel/doe_log.h | 0 .../include}/starkernel/ed25519.h | 0 .../include}/starkernel/elf64.h | 0 .../include}/starkernel/elf_loader.h | 0 {include => kernel/include}/starkernel/fdt.h | 0 .../include}/starkernel/fe25519.h | 0 .../include}/starkernel/framebuffer.h | 0 .../starkernel/freestanding/README.md | 0 .../include}/starkernel/freestanding/assert.h | 0 .../include}/starkernel/freestanding/ctype.h | 0 .../include}/starkernel/freestanding/errno.h | 0 .../starkernel/freestanding/inttypes.h | 0 .../include}/starkernel/freestanding/math.h | 0 .../include}/starkernel/freestanding/sched.h | 0 .../include}/starkernel/freestanding/signal.h | 0 .../include}/starkernel/freestanding/stdio.h | 0 .../include}/starkernel/freestanding/stdlib.h | 0 .../include}/starkernel/freestanding/string.h | 0 .../starkernel/freestanding/sys/README.md | 0 .../starkernel/freestanding/sys/time.h | 0 .../starkernel/freestanding/sys/types.h | 0 .../include}/starkernel/freestanding/time.h | 0 .../include}/starkernel/hal/README.md | 0 .../include}/starkernel/hal/hal.h | 0 .../include}/starkernel/hal_memory.h | 0 .../include}/starkernel/homeblocks_sig.h | 0 .../include}/starkernel/i8042.h | 0 .../include}/starkernel/ioapic.h | 0 .../include}/starkernel/kernel_args.h | 0 .../include}/starkernel/kmalloc.h | 0 {include => kernel/include}/starkernel/log.h | 0 .../include}/starkernel/log_attrib.h | 0 .../include}/starkernel/log_region.h | 0 {include => kernel/include}/starkernel/pci.h | 0 {include => kernel/include}/starkernel/plic.h | 0 {include => kernel/include}/starkernel/pmm.h | 0 .../include}/starkernel/q48_16.h | 0 {include => kernel/include}/starkernel/repl.h | 0 {include => kernel/include}/starkernel/rng.h | 0 .../include}/starkernel/rpi5_dtb.h | 0 .../include}/starkernel/rpi5_mailbox.h | 0 .../include}/starkernel/rpi5_native_boot.h | 0 .../include}/starkernel/rpi5_native_entry.h | 0 .../include}/starkernel/scalar25519.h | 0 .../include}/starkernel/session.h | 0 .../include}/starkernel/sha512.h | 0 .../include}/starkernel/timer.h | 0 {include => kernel/include}/starkernel/ttf.h | 0 {include => kernel/include}/starkernel/uefi.h | 0 .../include}/starkernel/user_identity_seed.h | 0 .../include}/starkernel/virtio_blk.h | 0 .../include}/starkernel/virtio_input.h | 0 .../include}/starkernel/virtio_rng.h | 0 .../include}/starkernel/vm/README.md | 0 .../include}/starkernel/vm/arena.h | 0 .../starkernel/vm/bootstrap/README.md | 0 .../starkernel/vm/bootstrap/sk_vm_bootstrap.h | 0 .../include}/starkernel/vm/kernel_hermes.h | 0 .../include}/starkernel/vm/parity.h | 0 .../include}/starkernel/vm/stadium.h | 0 .../include}/starkernel/vm/stadium_blocks.h | 0 .../include}/starkernel/vm/stadium_words.h | 0 .../include}/starkernel/vm/switch.h | 0 .../include}/starkernel/vm_identity.h | 0 .../include}/starkernel/vm_uuid.h | 0 {include => kernel/include}/starkernel/vmm.h | 0 .../include}/starkernel/vt100.h | 0 .../include}/starkernel/x509_ed25519.h | 0 {include => kernel/include}/starkernel/xhci.h | 0 .../include}/starkernel/xhci_driver.h | 0 .../include}/starkernel/xxhash64.h | 0 .../include}/starkernel/zuse_cert_devblock.h | 0 .../include}/starkernel/zuse_eligibility.h | 0 .../starkernel/zuse_eligibility_list.h | 0 .../include}/starkernel/zuse_genesis_marker.h | 0 {linker => kernel/linker}/README.md | 0 {linker => kernel/linker}/starkernel-amd64.ld | 0 .../linker}/starkernel-kernel-aarch64.ld | 0 .../linker}/starkernel-kernel-amd64.ld | 0 .../linker}/starkernel-kernel-riscv64.ld | 0 .../linker}/starkernel-loader-aarch64-pe.ld | 0 .../linker}/starkernel-loader-aarch64.ld | 0 .../linker}/starkernel-loader-amd64-pe.ld | 0 .../linker}/starkernel-loader-amd64.ld | 0 .../linker}/starkernel-loader-riscv64.ld | 0 kernel/linker/starkernel-native-rpi5.ld | 74 + {src/starkernel => kernel/src}/README.md | 0 .../src}/arch/aarch64/README.md | 0 .../src}/arch/aarch64/apic.c | 0 .../src}/arch/aarch64/arch.c | 0 .../src}/arch/aarch64/boot.S | 0 .../src}/arch/aarch64/interrupts.c | 0 .../src}/arch/aarch64/isr.S | 0 .../src}/arch/aarch64/native_rpi5_entry.S | 38 +- .../src}/arch/aarch64/rpi5_dtb.c | 0 .../src}/arch/aarch64/rpi5_mailbox.c | 0 .../src}/arch/aarch64/rpi5_native_boot.c | 0 .../src}/arch/aarch64/switch.S | 0 .../src}/arch/aarch64/timer.c | 0 .../src}/arch/amd64/README.md | 0 .../src}/arch/amd64/apic.c | 0 .../src}/arch/amd64/arch.c | 0 .../src}/arch/amd64/boot.S | 0 .../src}/arch/amd64/i8042.c | 0 .../src}/arch/amd64/interrupts.c | 0 .../src}/arch/amd64/ioapic.c | 0 .../src}/arch/amd64/isr.S | 0 .../src}/arch/amd64/kernel_entry.S | 0 .../src}/arch/amd64/switch.S | 0 .../src}/arch/amd64/timer.c | 0 .../src}/arch/riscv64/README.md | 0 .../src}/arch/riscv64/apic.c | 0 .../src}/arch/riscv64/arch.c | 0 .../src}/arch/riscv64/boot.S | 0 .../src}/arch/riscv64/interrupts.c | 0 .../src}/arch/riscv64/isr.S | 0 .../src}/arch/riscv64/kernel_entry.S | 0 .../src}/arch/riscv64/plic.c | 0 .../src}/arch/riscv64/switch.S | 0 .../src}/arch/riscv64/timer.c | 0 {src/starkernel => kernel/src}/artemis_sig.c | 0 {src/starkernel => kernel/src}/boot/README.md | 0 {src/starkernel => kernel/src}/boot/cmdline.c | 0 .../src}/boot/elf_loader.c | 0 {src/starkernel => kernel/src}/boot/reloc.S | 0 .../src}/boot/reloc_stub.c | 0 .../src}/boot/uefi_loader.c | 0 .../src}/capsule/README.md | 0 .../src}/capsule/capsule_birth.c | 0 .../src}/capsule/capsule_console.c | 0 .../src}/capsule/capsule_find.c | 0 .../src}/capsule/capsule_loader.c | 0 .../src}/capsule/capsule_mint.c | 0 .../src}/capsule/capsule_run.c | 0 .../src}/capsule/capsule_runcap.c | 0 .../src}/capsule/capsule_sig.c | 0 .../src}/capsule/capsule_validate.c | 0 .../src}/capsule/capsule_vm_hooks.c | 0 .../src}/capsule/capsule_vm_physics.c | 0 .../src}/capsule/capsule_vm_switch_signal.c | 0 .../src}/capsule/capsule_wirebind.c | 0 .../src}/capsule/capsule_zuse_boot.c | 0 .../src}/capsule/mama_forth_words.c | 2 +- .../src}/capsule/vm_identity.c | 0 .../src}/capsule/vm_uuid.c | 0 .../src}/capsule/zuse_eligibility.c | 0 .../src}/crypto/ed25519.c | 0 .../src}/crypto/fe25519.c | 0 .../src}/crypto/scalar25519.c | 0 .../starkernel => kernel/src}/crypto/sha512.c | 0 .../src}/crypto/x509_ed25519.c | 0 {src/starkernel => kernel/src}/doe_log.c | 0 {src/starkernel => kernel/src}/hal/README.md | 0 {src/starkernel => kernel/src}/hal/console.c | 0 {src/starkernel => kernel/src}/hal/fdt.c | 0 .../starkernel => kernel/src}/hal/font_8x16.c | 0 .../src}/hal/framebuffer.c | 0 {src/starkernel => kernel/src}/hal/hal.c | 0 .../src}/hal/host_services.c | 0 {src/starkernel => kernel/src}/hal/memory.c | 0 {src/starkernel => kernel/src}/hal/ttf.c | 0 {src/starkernel => kernel/src}/hal/vt100.c | 0 {src/starkernel => kernel/src}/hash/README.md | 0 .../starkernel => kernel/src}/hash/xxhash64.c | 0 {src/starkernel => kernel/src}/heartbeat.c | 0 .../src}/homeblocks_sig.c | 0 {src/starkernel => kernel/src}/kernel_main.c | 0 {src/starkernel => kernel/src}/log_region.c | 0 {src/starkernel => kernel/src}/math/README.md | 0 {src/starkernel => kernel/src}/math/q48_16.c | 0 .../src}/memory/README.md | 0 .../src}/memory/kmalloc.c | 0 {src/starkernel => kernel/src}/memory/pmm.c | 0 {src/starkernel => kernel/src}/memory/vmm.c | 0 {src/starkernel => kernel/src}/pci/README.md | 0 {src/starkernel => kernel/src}/pci/pci.c | 0 {src/starkernel => kernel/src}/repl.c | 0 {src/starkernel => kernel/src}/rng/rng.c | 0 .../starkernel => kernel/src}/usb/blkio_usb.c | 0 {src/starkernel => kernel/src}/usb/xhci.c | 0 .../src}/virtio/README.md | 0 .../src}/virtio/virtio_blk.c | 0 .../src}/virtio/virtio_input.c | 0 .../src}/virtio/virtio_rng.c | 0 {src/starkernel => kernel/src}/vm/README.md | 0 .../src}/vm/alloc_kernel.c | 0 {src/starkernel => kernel/src}/vm/arena.c | 0 .../src}/vm/bootstrap/README.md | 0 .../src}/vm/bootstrap/sk_vm_bootstrap.c | 0 .../src}/vm/host/README.md | 0 {src/starkernel => kernel/src}/vm/host/shim.c | 0 .../src}/vm/kernel_hermes.c | 0 {src/starkernel => kernel/src}/vm/parity.c | 0 {src/starkernel => kernel/src}/vm/q48_stubs.c | 0 {src/starkernel => kernel/src}/vm/session.c | 0 {src/starkernel => kernel/src}/vm/stadium.c | 0 .../src}/vm/stadium_blocks.c | 0 .../src}/vm/stadium_words.c | 0 {src/starkernel => kernel/src}/vm/switch.c | 0 .../src}/vm/vm_bootstrap.c | 16 +- {src/starkernel => kernel/src}/vm/vm_core.c | 28 +- .../src}/vm/vm_internal.h | 4 +- .../starkernel => kernel/src}/vm/vm_runtime.c | 16 +- lfs/amd64/starforth | Bin 1544744 -> 1548840 bytes logs2/.gitkeep | 0 logs2/README.md | 7 - logs2/qemu-aarch64-20260609-192112.log | 3 - logs2/qemu-aarch64-20260611-002443.log | 3 - logs2/qemu-aarch64-20260611-024456.log | 3 - logs2/qemu-aarch64-20260611-173737.log | 3 - logs2/qemu-aarch64-20260611-174951.log | 3 - logs2/qemu-aarch64-20260611-175257.log | 3 - logs2/qemu-aarch64-20260611-190822.log | 3 - logs2/qemu-aarch64-20260611-202955.log | 3 - logs2/qemu-aarch64-20260612-132412.log | 3 - logs2/qemu-aarch64-20260612-141722.log | 3 - logs2/qemu-aarch64-20260612-160132.log | 3 - logs2/qemu-aarch64-20260614-164017.log | 3 - logs2/qemu-aarch64-20260614-164043.log | 3 - logs2/qemu-aarch64-20260614-182154.log | 3 - logs2/qemu-aarch64-20260614-190109.log | 3 - logs2/qemu-aarch64-20260614-230803.log | 3 - logs2/qemu-aarch64-20260615-003908.log | 3 - logs2/qemu-aarch64-20260615-005301.log | 3 - logs2/qemu-aarch64-20260615-020020.log | 3 - logs2/qemu-aarch64-20260615-103253.log | 3 - logs2/qemu-aarch64-20260615-103655.log | 3 - logs2/qemu-aarch64-20260615-121103.log | 3 - logs2/qemu-aarch64-20260615-123814.log | 3 - logs2/qemu-aarch64-20260615-160204.log | 3 - logs2/qemu-aarch64-20260615-183010.log | 3 - logs2/qemu-aarch64-20260615-192747.log | 3 - logs2/qemu-aarch64-20260615-194133.log | 3 - logs2/qemu-aarch64-20260615-204232.log | 3 - logs2/qemu-aarch64-20260615-223549.log | 3 - logs2/qemu-aarch64-20260615-235720.log | 3 - logs2/qemu-aarch64-20260616-000920.log | 3 - logs2/qemu-aarch64-20260616-011049.log | 3 - logs2/qemu-aarch64-20260616-112907.log | 3 - logs2/qemu-aarch64-20260616-155223.log | 3 - logs2/qemu-aarch64-20260616-175845.log | 3 - logs2/qemu-aarch64-20260620-222449.log | 3 - logs2/qemu-aarch64-20260621-004736.log | 3 - logs2/qemu-amd64-20260609-184750.log | 3 - logs2/qemu-amd64-20260609-193717.log | 3 - logs2/qemu-amd64-20260611-002301.log | 3 - logs2/qemu-amd64-20260611-012412.log | 3 - logs2/qemu-amd64-20260611-013401.log | 3 - logs2/qemu-amd64-20260611-023023.log | 3 - logs2/qemu-amd64-20260611-023818.log | 3 - logs2/qemu-amd64-20260611-172713.log | 3 - logs2/qemu-amd64-20260611-174904.log | 3 - logs2/qemu-amd64-20260611-175217.log | 3 - logs2/qemu-amd64-20260611-180750.log | 3 - logs2/qemu-amd64-20260611-192015.log | 3 - logs2/qemu-amd64-20260611-201951.log | 3 - logs2/qemu-amd64-20260611-204126.log | 3 - logs2/qemu-amd64-20260611-223613.log | 3 - logs2/qemu-amd64-20260612-110212.log | 3 - logs2/qemu-amd64-20260612-142323.log | 3 - logs2/qemu-amd64-20260612-160656.log | 3 - logs2/qemu-amd64-20260614-163853.log | 3 - logs2/qemu-amd64-20260614-182034.log | 3 - logs2/qemu-amd64-20260614-182119.log | 3 - logs2/qemu-amd64-20260614-183302.log | 3 - logs2/qemu-amd64-20260614-185942.log | 3 - logs2/qemu-amd64-20260614-190244.log | 3 - logs2/qemu-amd64-20260614-212929.log | 3 - logs2/qemu-amd64-20260614-233623.log | 3 - logs2/qemu-amd64-20260615-005725.log | 3 - logs2/qemu-amd64-20260615-020446.log | 3 - logs2/qemu-amd64-20260615-103154.log | 3 - logs2/qemu-amd64-20260615-103619.log | 3 - logs2/qemu-amd64-20260615-103843.log | 3 - logs2/qemu-amd64-20260615-124956.log | 3 - logs2/qemu-amd64-20260615-125017.log | 3 - logs2/qemu-amd64-20260615-125335.log | 3 - logs2/qemu-amd64-20260615-142839.log | 3 - logs2/qemu-amd64-20260615-161023.log | 3 - logs2/qemu-amd64-20260615-180252.log | 3 - logs2/qemu-amd64-20260615-182339.log | 3 - logs2/qemu-amd64-20260615-182946.log | 3 - logs2/qemu-amd64-20260615-183023.log | 3 - logs2/qemu-amd64-20260615-194545.log | 3 - logs2/qemu-amd64-20260615-204632.log | 3 - logs2/qemu-amd64-20260615-223531.log | 0 logs2/qemu-amd64-20260615-223607.log | 3 - logs2/qemu-amd64-20260615-230419.log | 3 - logs2/qemu-amd64-20260616-001614.log | 3 - logs2/qemu-amd64-20260616-011447.log | 3 - logs2/qemu-amd64-20260616-111913.log | 3 - logs2/qemu-amd64-20260616-154608.log | 3 - logs2/qemu-amd64-20260616-175829.log | 3 - logs2/qemu-amd64-20260620-222036.log | 3 - logs2/qemu-amd64-20260621-002830.log | 3 - logs2/qemu-amd64-20260621-004710.log | 3 - logs2/qemu-riscv64-20260609-192223.log | 3 - logs2/qemu-riscv64-20260611-002548.log | 3 - logs2/qemu-riscv64-20260611-003502.log | 3 - logs2/qemu-riscv64-20260611-003801.log | 3 - logs2/qemu-riscv64-20260611-024624.log | 3 - logs2/qemu-riscv64-20260611-173903.log | 3 - logs2/qemu-riscv64-20260611-175348.log | 3 - logs2/qemu-riscv64-20260611-191335.log | 3 - logs2/qemu-riscv64-20260611-203104.log | 3 - logs2/qemu-riscv64-20260612-135612.log | 3 - logs2/qemu-riscv64-20260612-141129.log | 3 - logs2/qemu-riscv64-20260612-174414.log | 3 - logs2/qemu-riscv64-20260614-164140.log | 3 - logs2/qemu-riscv64-20260614-165900.log | 3 - logs2/qemu-riscv64-20260614-170926.log | 3 - logs2/qemu-riscv64-20260614-171955.log | 3 - logs2/qemu-riscv64-20260614-182235.log | 3 - logs2/qemu-riscv64-20260614-190152.log | 3 - logs2/qemu-riscv64-20260614-230220.log | 3 - logs2/qemu-riscv64-20260615-004335.log | 3 - logs2/qemu-riscv64-20260615-004822.log | 3 - logs2/qemu-riscv64-20260615-031059.log | 3 - logs2/qemu-riscv64-20260615-103741.log | 3 - logs2/qemu-riscv64-20260615-122026.log | 3 - logs2/qemu-riscv64-20260615-122930.log | 3 - logs2/qemu-riscv64-20260615-174420.log | 3 - logs2/qemu-riscv64-20260615-183017.log | 3 - logs2/qemu-riscv64-20260615-193223.log | 3 - logs2/qemu-riscv64-20260615-193711.log | 3 - logs2/qemu-riscv64-20260615-214335.log | 3 - logs2/qemu-riscv64-20260615-223550.log | 3 - logs2/qemu-riscv64-20260616-000114.log | 3 - logs2/qemu-riscv64-20260616-000522.log | 3 - logs2/qemu-riscv64-20260616-021123.log | 3 - logs2/qemu-riscv64-20260616-113103.log | 3 - logs2/qemu-riscv64-20260616-155324.log | 3 - logs2/qemu-riscv64-20260616-175915.log | 3 - logs2/qemu-riscv64-20260620-231806.log | 3 - logs2/qemu-riscv64-20260621-004843.log | 3 - logs2/qemu-screenshot-20260609-105458.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260609-130717.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260609-181200.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260609-193724.log | 3 - logs2/qemu-screenshot-20260609-193724.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260609-194549.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260609-194812.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260609-222537.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260609-225958.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260609-232904.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260610-005734.png | Bin 282 -> 0 bytes logs2/qemu-screenshot-20260610-134732.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260610-145902.png | Bin 1375 -> 0 bytes logs2/qemu-screenshot-20260610-213714.png | Bin 1398 -> 0 bytes logs2/qemu-screenshot-20260611-002306.log | 3 - logs2/qemu-screenshot-20260611-004156.log | 3 - logs2/qemu-screenshot-20260611-012817.log | 3 - logs2/qemu-screenshot-20260611-023758.log | 3 - logs2/qemu-screenshot-20260611-024401.log | 3 - logs2/qemu-screenshot-20260611-173657.log | 3 - logs2/qemu-screenshot-20260611-174914.log | 3 - logs2/qemu-screenshot-20260611-175224.log | 3 - logs2/qemu-screenshot-20260611-190757.log | 3 - logs2/qemu-screenshot-20260611-202932.log | 3 - logs2/qemu-screenshot-20260612-115354.log | 3 - logs2/qemu-screenshot-20260612-160054.log | 3 - logs2/qemu-screenshot-20260612-174331.log | 3 - logs2/qemu-screenshot-20260614-163902.log | 3 - logs2/qemu-screenshot-20260614-182044.log | 0 logs2/qemu-screenshot-20260614-182127.log | 3 - mk/Kconfig.mk | 4 +- mk/README.md | 2 +- scripts/mkdiskimage.sh | 91 ++ scripts/perf-profile.sh | 2 +- scripts/perf-profile_control.sh | 2 +- scripts/remove_loop_conditionals.sh | 6 +- tools/README.md | 6 +- tools/ttftest.c | 2 +- v3/Makefile | 1340 +++++++++++++++ {include => v3/include}/README.md | 0 {include => v3/include}/arch_detect.h | 0 {include => v3/include}/blkcfg.h | 0 {include => v3/include}/blkio.h | 0 {include => v3/include}/blkio_factory.h | 0 {include => v3/include}/block_subsystem.h | 0 {include => v3/include}/cli.h | 0 {include => v3/include}/compudynamics.h | 0 .../include}/dictionary_heat_optimization.h | 0 .../include}/dictionary_management.h | 0 {include => v3/include}/doe_metrics.h | 0 {include => v3/include}/inference_engine.h | 0 {include => v3/include}/io.h | 0 {include => v3/include}/log.h | 0 {include => v3/include}/math_portable.h | 0 {include => v3/include}/memory_management.h | 0 .../include}/physics_execution_hooks.h | 0 .../include}/physics_hotwords_cache.h | 0 {include => v3/include}/physics_metadata.h | 0 .../include}/physics_pipelining_metrics.h | 0 {include => v3/include}/physics_runtime.h | 0 {include => v3/include}/platform_alloc.h | 0 {include => v3/include}/platform_io.h | 0 {include => v3/include}/platform_lock.h | 0 {include => v3/include}/platform_time.h | 0 {include => v3/include}/profiler.h | 0 {include => v3/include}/q48_16.h | 0 {include => v3/include}/repl.h | 0 .../include}/rolling_window_knobs.h | 0 .../include}/rolling_window_of_truth.h | 0 {include => v3/include}/ssm_jacquard.h | 0 {include => v3/include}/starforth_config.h | 0 {include => v3/include}/startup.h | 0 v3/include/version.h | 10 + {include => v3/include}/vm.h | 0 {include => v3/include}/vm_api.h | 0 {include => v3/include}/vm_asm_opt.h | 0 {include => v3/include}/vm_asm_opt_arm64.h | 0 {include => v3/include}/vm_asm_opt_riscv64.h | 0 {include => v3/include}/vm_debug.h | 0 {include => v3/include}/vm_host.h | 0 .../include}/vm_inner_interp_arm64.h | 0 {include => v3/include}/vm_inner_interp_asm.h | 0 .../include}/vm_inner_interp_riscv64.h | 0 {include => v3/include}/word_registry.h | 0 {src => v3/src}/README.md | 0 {src => v3/src}/blkio_factory.c | 0 {src => v3/src}/blkio_file.c | 0 {src => v3/src}/blkio_ram.c | 0 {src => v3/src}/block_subsystem.c | 0 {src => v3/src}/cli.c | 0 {src => v3/src}/compudynamics.c | 0 .../src}/dictionary_heat_optimization.c | 0 {src => v3/src}/dictionary_management.c | 0 {src => v3/src}/doe_metrics.c | 0 {src => v3/src}/heartbeat_export.c | 0 {src => v3/src}/inference_engine.c | 0 {src => v3/src}/io.c | 0 {src => v3/src}/log.c | 0 {src => v3/src}/main.c | 0 {src => v3/src}/math_portable.c | 0 {src => v3/src}/memory_management.c | 0 {src => v3/src}/physics_execution_hooks.c | 0 {src => v3/src}/physics_hotwords_cache.c | 0 {src => v3/src}/physics_metadata.c | 0 {src => v3/src}/physics_pipelining_metrics.c | 0 {src => v3/src}/physics_runtime.c | 0 {src => v3/src}/platform/README.md | 0 {src => v3/src}/platform/alloc_host.c | 0 {src => v3/src}/platform/alloc_kernel.c | 0 {src => v3/src}/platform/l4re/README.md | 0 {src => v3/src}/platform/l4re/time.c | 0 {src => v3/src}/platform/linux/README.md | 0 {src => v3/src}/platform/linux/io.c | 0 {src => v3/src}/platform/linux/time.c | 0 {src => v3/src}/platform/platform_init.c | 0 {src => v3/src}/platform/threading.c | 0 {src => v3/src}/profiler.c | 0 {src => v3/src}/repl.c | 0 {src => v3/src}/rolling_window_of_truth.c | 0 {src => v3/src}/ssm_jacquard.c | 0 {src => v3/src}/stack_management.c | 0 {src => v3/src}/test_runner/README.md | 0 {src => v3/src}/test_runner/include/README.md | 0 .../src}/test_runner/include/test_common.h | 4 +- .../src}/test_runner/include/test_contracts.h | 0 .../src}/test_runner/include/test_runner.h | 0 {src => v3/src}/test_runner/modules/README.md | 0 .../src}/test_runner/modules/acl_words_test.c | 0 .../modules/arithmetic_words_test.c | 0 .../test_runner/modules/block_words_test.c | 0 .../src}/test_runner/modules/break_me_tests.c | 0 .../test_runner/modules/control_words_test.c | 0 .../modules/defining_words_tests.c | 0 .../dictionary_manipulation_words_test.c | 0 .../modules/dictionary_words_test.c | 0 .../test_runner/modules/double_words_test.c | 0 .../test_runner/modules/format_words_test.c | 0 .../modules/inference_words_test.c | 0 .../test_runner/modules/integration_tests.c | 0 .../src}/test_runner/modules/io_words_test.c | 0 .../test_runner/modules/logical_words_test.c | 0 .../modules/mama_forth_words_test.c | 0 .../test_runner/modules/memory_words_test.c | 0 .../modules/mixed_arithmetic_words_test.c | 0 .../modules/physics_freeze_words_test.c | 0 .../src}/test_runner/modules/q48_words_test.c | 0 .../modules/return_stack_words_test.c | 0 .../test_runner/modules/stack_words_test.c | 0 .../modules/starforth_words_test.c | 0 .../src}/test_runner/modules/stress_tests.c | 0 .../test_runner/modules/string_words_test.c | 0 .../test_runner/modules/system_words_test.c | 0 .../modules/vocabulary_words_test.c | 0 {src => v3/src}/test_runner/test_common.c | 0 {src => v3/src}/test_runner/test_contracts.c | 0 {src => v3/src}/test_runner/test_runner.c | 0 {src => v3/src}/vm.c | 0 {src => v3/src}/vm_api.c | 0 {src => v3/src}/vm_bootstrap.c | 4 +- {src => v3/src}/vm_debug.c | 0 {src => v3/src}/vm_internal.h | 0 {src => v3/src}/vm_time.c | 0 {src => v3/src}/word_registry.c | 0 {src => v3/src}/word_source/README.md | 0 {src => v3/src}/word_source/acl_words.c | 0 .../src}/word_source/arithmetic_words.c | 0 {src => v3/src}/word_source/block_words.c | 0 {src => v3/src}/word_source/control_words.c | 0 {src => v3/src}/word_source/defer_words.c | 0 {src => v3/src}/word_source/defining_words.c | 0 .../dictionary_heat_diagnostic_words.c | 0 .../dictionary_manipulation_words.c | 0 .../src}/word_source/dictionary_words.c | 0 {src => v3/src}/word_source/double_words.c | 0 {src => v3/src}/word_source/editor_words.c | 0 {src => v3/src}/word_source/format_words.c | 0 .../src}/word_source/framebuffer_words.c | 0 {src => v3/src}/word_source/include/README.md | 0 .../src}/word_source/include/acl_words.h | 0 .../word_source/include/arithmetic_words.h | 0 .../src}/word_source/include/block_words.h | 0 .../src}/word_source/include/control_words.h | 0 .../src}/word_source/include/defer_words.h | 2 +- .../src}/word_source/include/defining_words.h | 0 .../dictionary_heat_diagnostic_words.h | 0 .../include/dictionary_manipulation_words.h | 0 .../word_source/include/dictionary_words.h | 0 .../src}/word_source/include/double_words.h | 0 .../src}/word_source/include/editor_words.h | 0 .../src}/word_source/include/format_words.h | 0 .../word_source/include/framebuffer_words.h | 0 .../word_source/include/inference_words.h | 0 .../src}/word_source/include/io_words.h | 0 .../src}/word_source/include/keyboard_words.h | 0 .../src}/word_source/include/log_words.h | 0 .../src}/word_source/include/logical_words.h | 0 .../word_source/include/mama_forth_words.h | 0 .../src}/word_source/include/memory_words.h | 0 .../include/mixed_arithmetic_words.h | 0 .../include/physics_benchmark_words.h | 0 .../include/physics_diagnostic_words.h | 0 .../include/physics_freeze_words.h | 0 .../physics_pipelining_diagnostic_words.h | 0 .../src}/word_source/include/q48_words.h | 0 .../word_source/include/return_stack_words.h | 0 .../src}/word_source/include/scroll_words.h | 0 .../src}/word_source/include/stack_words.h | 0 .../word_source/include/starforth_words.h | 0 .../src}/word_source/include/string_words.h | 0 .../src}/word_source/include/system_words.h | 0 .../src}/word_source/include/ttf_words.h | 0 .../word_source/include/vocabulary_words.h | 0 {src => v3/src}/word_source/inference_words.c | 0 {src => v3/src}/word_source/io_words.c | 0 {src => v3/src}/word_source/keyboard_words.c | 0 .../src}/word_source/lifecycle_words_hosted.c | 0 {src => v3/src}/word_source/log_words.c | 0 {src => v3/src}/word_source/logical_words.c | 0 {src => v3/src}/word_source/memory_words.c | 0 .../src}/word_source/mixed_arithmetic_words.c | 0 .../word_source/physics_benchmark_words.c | 0 .../word_source/physics_diagnostic_words.c | 0 .../src}/word_source/physics_freeze_words.c | 0 .../physics_pipelining_diagnostic_words.c | 6 +- {src => v3/src}/word_source/q48_16_words.c | 2 +- {src => v3/src}/word_source/q48_words.c | 0 .../src}/word_source/return_stack_words.c | 0 {src => v3/src}/word_source/scroll_words.c | 0 {src => v3/src}/word_source/stack_words.c | 0 {src => v3/src}/word_source/starforth_words.c | 0 {src => v3/src}/word_source/string_words.c | 0 {src => v3/src}/word_source/system_words.c | 0 {src => v3/src}/word_source/ttf_words.c | 0 .../src}/word_source/vocabulary_words.c | 0 v4/README.md | 9 + 630 files changed, 2646 insertions(+), 2036 deletions(-) create mode 100644 boards/README.md create mode 100644 boards/milkv/README.md create mode 100644 boards/milkv/board.mk create mode 100644 boards/raspi/README.md create mode 100644 boards/raspi/board.mk rename {boot_media/rpi5 => boards/raspi}/config.txt (91%) create mode 100644 boards/ser5/README.md create mode 100644 boards/ser5/board.mk create mode 100644 boards/zynq7020/README.md create mode 100644 boards/zynq7020/board.mk delete mode 100644 boot_media/rpi5/README.md rename ONTOLOGY.md => docs/ONTOLOGY.md (100%) rename ROADMAP.md => docs/ROADMAP.md (100%) create mode 100644 docs/book/Makefile create mode 100644 docs/book/README.md create mode 100644 docs/book/main.tex create mode 100644 docs/book/pandoc/code-breaks.lua create mode 100644 docs/book/pandoc/highlighting.latex create mode 100644 docs/book/pandoc/table-widths.lua rename FABRIC-0.md => docs/fabric/FABRIC-0.md (100%) rename FABRIC-1.md => docs/fabric/FABRIC-1.md (100%) rename FABRIC-2.md => docs/fabric/FABRIC-2.md (100%) rename FABRIC-3.5.md => docs/fabric/FABRIC-3.5.md (100%) rename FABRIC-3.6.md => docs/fabric/FABRIC-3.6.md (100%) rename FABRIC-3.7.md => docs/fabric/FABRIC-3.7.md (100%) rename FABRIC-3.md => docs/fabric/FABRIC-3.md (100%) rename FABRIC-4.md => docs/fabric/FABRIC-4.md (100%) rename Makefile.starkernel => kernel/Makefile (84%) rename {include => kernel/include}/starkernel/README.md (100%) rename {include => kernel/include}/starkernel/apic.h (100%) rename {include => kernel/include}/starkernel/arch.h (100%) rename {include => kernel/include}/starkernel/artemis_sig.h (100%) rename {include => kernel/include}/starkernel/blkio_usb.h (100%) rename {include => kernel/include}/starkernel/boot_info_offsets.h (100%) rename {include => kernel/include}/starkernel/capsule.h (100%) rename {include => kernel/include}/starkernel/capsule_birth.h (100%) rename {include => kernel/include}/starkernel/capsule_console.h (100%) rename {include => kernel/include}/starkernel/capsule_generated.h (100%) rename {include => kernel/include}/starkernel/capsule_loader.h (100%) rename {include => kernel/include}/starkernel/capsule_mint.h (100%) rename {include => kernel/include}/starkernel/capsule_run.h (100%) rename {include => kernel/include}/starkernel/capsule_runcap.h (100%) rename {include => kernel/include}/starkernel/capsule_sig.h (100%) rename {include => kernel/include}/starkernel/capsule_vm_physics.h (100%) rename {include => kernel/include}/starkernel/capsule_vm_switch_signal.h (100%) rename {include => kernel/include}/starkernel/capsule_wirebind.h (100%) rename {include => kernel/include}/starkernel/capsule_zuse_boot.h (100%) rename {include => kernel/include}/starkernel/cmdline.h (100%) rename {include => kernel/include}/starkernel/console.h (100%) rename {include => kernel/include}/starkernel/doe_log.h (100%) rename {include => kernel/include}/starkernel/ed25519.h (100%) rename {include => kernel/include}/starkernel/elf64.h (100%) rename {include => kernel/include}/starkernel/elf_loader.h (100%) rename {include => kernel/include}/starkernel/fdt.h (100%) rename {include => kernel/include}/starkernel/fe25519.h (100%) rename {include => kernel/include}/starkernel/framebuffer.h (100%) rename {include => kernel/include}/starkernel/freestanding/README.md (100%) rename {include => kernel/include}/starkernel/freestanding/assert.h (100%) rename {include => kernel/include}/starkernel/freestanding/ctype.h (100%) rename {include => kernel/include}/starkernel/freestanding/errno.h (100%) rename {include => kernel/include}/starkernel/freestanding/inttypes.h (100%) rename {include => kernel/include}/starkernel/freestanding/math.h (100%) rename {include => kernel/include}/starkernel/freestanding/sched.h (100%) rename {include => kernel/include}/starkernel/freestanding/signal.h (100%) rename {include => kernel/include}/starkernel/freestanding/stdio.h (100%) rename {include => kernel/include}/starkernel/freestanding/stdlib.h (100%) rename {include => kernel/include}/starkernel/freestanding/string.h (100%) rename {include => kernel/include}/starkernel/freestanding/sys/README.md (100%) rename {include => kernel/include}/starkernel/freestanding/sys/time.h (100%) rename {include => kernel/include}/starkernel/freestanding/sys/types.h (100%) rename {include => kernel/include}/starkernel/freestanding/time.h (100%) rename {include => kernel/include}/starkernel/hal/README.md (100%) rename {include => kernel/include}/starkernel/hal/hal.h (100%) rename {include => kernel/include}/starkernel/hal_memory.h (100%) rename {include => kernel/include}/starkernel/homeblocks_sig.h (100%) rename {include => kernel/include}/starkernel/i8042.h (100%) rename {include => kernel/include}/starkernel/ioapic.h (100%) rename {include => kernel/include}/starkernel/kernel_args.h (100%) rename {include => kernel/include}/starkernel/kmalloc.h (100%) rename {include => kernel/include}/starkernel/log.h (100%) rename {include => kernel/include}/starkernel/log_attrib.h (100%) rename {include => kernel/include}/starkernel/log_region.h (100%) rename {include => kernel/include}/starkernel/pci.h (100%) rename {include => kernel/include}/starkernel/plic.h (100%) rename {include => kernel/include}/starkernel/pmm.h (100%) rename {include => kernel/include}/starkernel/q48_16.h (100%) rename {include => kernel/include}/starkernel/repl.h (100%) rename {include => kernel/include}/starkernel/rng.h (100%) rename {include => kernel/include}/starkernel/rpi5_dtb.h (100%) rename {include => kernel/include}/starkernel/rpi5_mailbox.h (100%) rename {include => kernel/include}/starkernel/rpi5_native_boot.h (100%) rename {include => kernel/include}/starkernel/rpi5_native_entry.h (100%) rename {include => kernel/include}/starkernel/scalar25519.h (100%) rename {include => kernel/include}/starkernel/session.h (100%) rename {include => kernel/include}/starkernel/sha512.h (100%) rename {include => kernel/include}/starkernel/timer.h (100%) rename {include => kernel/include}/starkernel/ttf.h (100%) rename {include => kernel/include}/starkernel/uefi.h (100%) rename {include => kernel/include}/starkernel/user_identity_seed.h (100%) rename {include => kernel/include}/starkernel/virtio_blk.h (100%) rename {include => kernel/include}/starkernel/virtio_input.h (100%) rename {include => kernel/include}/starkernel/virtio_rng.h (100%) rename {include => kernel/include}/starkernel/vm/README.md (100%) rename {include => kernel/include}/starkernel/vm/arena.h (100%) rename {include => kernel/include}/starkernel/vm/bootstrap/README.md (100%) rename {include => kernel/include}/starkernel/vm/bootstrap/sk_vm_bootstrap.h (100%) rename {include => kernel/include}/starkernel/vm/kernel_hermes.h (100%) rename {include => kernel/include}/starkernel/vm/parity.h (100%) rename {include => kernel/include}/starkernel/vm/stadium.h (100%) rename {include => kernel/include}/starkernel/vm/stadium_blocks.h (100%) rename {include => kernel/include}/starkernel/vm/stadium_words.h (100%) rename {include => kernel/include}/starkernel/vm/switch.h (100%) rename {include => kernel/include}/starkernel/vm_identity.h (100%) rename {include => kernel/include}/starkernel/vm_uuid.h (100%) rename {include => kernel/include}/starkernel/vmm.h (100%) rename {include => kernel/include}/starkernel/vt100.h (100%) rename {include => kernel/include}/starkernel/x509_ed25519.h (100%) rename {include => kernel/include}/starkernel/xhci.h (100%) rename {include => kernel/include}/starkernel/xhci_driver.h (100%) rename {include => kernel/include}/starkernel/xxhash64.h (100%) rename {include => kernel/include}/starkernel/zuse_cert_devblock.h (100%) rename {include => kernel/include}/starkernel/zuse_eligibility.h (100%) rename {include => kernel/include}/starkernel/zuse_eligibility_list.h (100%) rename {include => kernel/include}/starkernel/zuse_genesis_marker.h (100%) rename {linker => kernel/linker}/README.md (100%) rename {linker => kernel/linker}/starkernel-amd64.ld (100%) rename {linker => kernel/linker}/starkernel-kernel-aarch64.ld (100%) rename {linker => kernel/linker}/starkernel-kernel-amd64.ld (100%) rename {linker => kernel/linker}/starkernel-kernel-riscv64.ld (100%) rename {linker => kernel/linker}/starkernel-loader-aarch64-pe.ld (100%) rename {linker => kernel/linker}/starkernel-loader-aarch64.ld (100%) rename {linker => kernel/linker}/starkernel-loader-amd64-pe.ld (100%) rename {linker => kernel/linker}/starkernel-loader-amd64.ld (100%) rename {linker => kernel/linker}/starkernel-loader-riscv64.ld (100%) create mode 100644 kernel/linker/starkernel-native-rpi5.ld rename {src/starkernel => kernel/src}/README.md (100%) rename {src/starkernel => kernel/src}/arch/aarch64/README.md (100%) rename {src/starkernel => kernel/src}/arch/aarch64/apic.c (100%) rename {src/starkernel => kernel/src}/arch/aarch64/arch.c (100%) rename {src/starkernel => kernel/src}/arch/aarch64/boot.S (100%) rename {src/starkernel => kernel/src}/arch/aarch64/interrupts.c (100%) rename {src/starkernel => kernel/src}/arch/aarch64/isr.S (100%) rename {src/starkernel => kernel/src}/arch/aarch64/native_rpi5_entry.S (68%) rename {src/starkernel => kernel/src}/arch/aarch64/rpi5_dtb.c (100%) rename {src/starkernel => kernel/src}/arch/aarch64/rpi5_mailbox.c (100%) rename {src/starkernel => kernel/src}/arch/aarch64/rpi5_native_boot.c (100%) rename {src/starkernel => kernel/src}/arch/aarch64/switch.S (100%) rename {src/starkernel => kernel/src}/arch/aarch64/timer.c (100%) rename {src/starkernel => kernel/src}/arch/amd64/README.md (100%) rename {src/starkernel => kernel/src}/arch/amd64/apic.c (100%) rename {src/starkernel => kernel/src}/arch/amd64/arch.c (100%) rename {src/starkernel => kernel/src}/arch/amd64/boot.S (100%) rename {src/starkernel => kernel/src}/arch/amd64/i8042.c (100%) rename {src/starkernel => kernel/src}/arch/amd64/interrupts.c (100%) rename {src/starkernel => kernel/src}/arch/amd64/ioapic.c (100%) rename {src/starkernel => kernel/src}/arch/amd64/isr.S (100%) rename {src/starkernel => kernel/src}/arch/amd64/kernel_entry.S (100%) rename {src/starkernel => kernel/src}/arch/amd64/switch.S (100%) rename {src/starkernel => kernel/src}/arch/amd64/timer.c (100%) rename {src/starkernel => kernel/src}/arch/riscv64/README.md (100%) rename {src/starkernel => kernel/src}/arch/riscv64/apic.c (100%) rename {src/starkernel => kernel/src}/arch/riscv64/arch.c (100%) rename {src/starkernel => kernel/src}/arch/riscv64/boot.S (100%) rename {src/starkernel => kernel/src}/arch/riscv64/interrupts.c (100%) rename {src/starkernel => kernel/src}/arch/riscv64/isr.S (100%) rename {src/starkernel => kernel/src}/arch/riscv64/kernel_entry.S (100%) rename {src/starkernel => kernel/src}/arch/riscv64/plic.c (100%) rename {src/starkernel => kernel/src}/arch/riscv64/switch.S (100%) rename {src/starkernel => kernel/src}/arch/riscv64/timer.c (100%) rename {src/starkernel => kernel/src}/artemis_sig.c (100%) rename {src/starkernel => kernel/src}/boot/README.md (100%) rename {src/starkernel => kernel/src}/boot/cmdline.c (100%) rename {src/starkernel => kernel/src}/boot/elf_loader.c (100%) rename {src/starkernel => kernel/src}/boot/reloc.S (100%) rename {src/starkernel => kernel/src}/boot/reloc_stub.c (100%) rename {src/starkernel => kernel/src}/boot/uefi_loader.c (100%) rename {src/starkernel => kernel/src}/capsule/README.md (100%) rename {src/starkernel => kernel/src}/capsule/capsule_birth.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_console.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_find.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_loader.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_mint.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_run.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_runcap.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_sig.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_validate.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_vm_hooks.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_vm_physics.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_vm_switch_signal.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_wirebind.c (100%) rename {src/starkernel => kernel/src}/capsule/capsule_zuse_boot.c (100%) rename {src/starkernel => kernel/src}/capsule/mama_forth_words.c (99%) rename {src/starkernel => kernel/src}/capsule/vm_identity.c (100%) rename {src/starkernel => kernel/src}/capsule/vm_uuid.c (100%) rename {src/starkernel => kernel/src}/capsule/zuse_eligibility.c (100%) rename {src/starkernel => kernel/src}/crypto/ed25519.c (100%) rename {src/starkernel => kernel/src}/crypto/fe25519.c (100%) rename {src/starkernel => kernel/src}/crypto/scalar25519.c (100%) rename {src/starkernel => kernel/src}/crypto/sha512.c (100%) rename {src/starkernel => kernel/src}/crypto/x509_ed25519.c (100%) rename {src/starkernel => kernel/src}/doe_log.c (100%) rename {src/starkernel => kernel/src}/hal/README.md (100%) rename {src/starkernel => kernel/src}/hal/console.c (100%) rename {src/starkernel => kernel/src}/hal/fdt.c (100%) rename {src/starkernel => kernel/src}/hal/font_8x16.c (100%) rename {src/starkernel => kernel/src}/hal/framebuffer.c (100%) rename {src/starkernel => kernel/src}/hal/hal.c (100%) rename {src/starkernel => kernel/src}/hal/host_services.c (100%) rename {src/starkernel => kernel/src}/hal/memory.c (100%) rename {src/starkernel => kernel/src}/hal/ttf.c (100%) rename {src/starkernel => kernel/src}/hal/vt100.c (100%) rename {src/starkernel => kernel/src}/hash/README.md (100%) rename {src/starkernel => kernel/src}/hash/xxhash64.c (100%) rename {src/starkernel => kernel/src}/heartbeat.c (100%) rename {src/starkernel => kernel/src}/homeblocks_sig.c (100%) rename {src/starkernel => kernel/src}/kernel_main.c (100%) rename {src/starkernel => kernel/src}/log_region.c (100%) rename {src/starkernel => kernel/src}/math/README.md (100%) rename {src/starkernel => kernel/src}/math/q48_16.c (100%) rename {src/starkernel => kernel/src}/memory/README.md (100%) rename {src/starkernel => kernel/src}/memory/kmalloc.c (100%) rename {src/starkernel => kernel/src}/memory/pmm.c (100%) rename {src/starkernel => kernel/src}/memory/vmm.c (100%) rename {src/starkernel => kernel/src}/pci/README.md (100%) rename {src/starkernel => kernel/src}/pci/pci.c (100%) rename {src/starkernel => kernel/src}/repl.c (100%) rename {src/starkernel => kernel/src}/rng/rng.c (100%) rename {src/starkernel => kernel/src}/usb/blkio_usb.c (100%) rename {src/starkernel => kernel/src}/usb/xhci.c (100%) rename {src/starkernel => kernel/src}/virtio/README.md (100%) rename {src/starkernel => kernel/src}/virtio/virtio_blk.c (100%) rename {src/starkernel => kernel/src}/virtio/virtio_input.c (100%) rename {src/starkernel => kernel/src}/virtio/virtio_rng.c (100%) rename {src/starkernel => kernel/src}/vm/README.md (100%) rename {src/starkernel => kernel/src}/vm/alloc_kernel.c (100%) rename {src/starkernel => kernel/src}/vm/arena.c (100%) rename {src/starkernel => kernel/src}/vm/bootstrap/README.md (100%) rename {src/starkernel => kernel/src}/vm/bootstrap/sk_vm_bootstrap.c (100%) rename {src/starkernel => kernel/src}/vm/host/README.md (100%) rename {src/starkernel => kernel/src}/vm/host/shim.c (100%) rename {src/starkernel => kernel/src}/vm/kernel_hermes.c (100%) rename {src/starkernel => kernel/src}/vm/parity.c (100%) rename {src/starkernel => kernel/src}/vm/q48_stubs.c (100%) rename {src/starkernel => kernel/src}/vm/session.c (100%) rename {src/starkernel => kernel/src}/vm/stadium.c (100%) rename {src/starkernel => kernel/src}/vm/stadium_blocks.c (100%) rename {src/starkernel => kernel/src}/vm/stadium_words.c (100%) rename {src/starkernel => kernel/src}/vm/switch.c (100%) rename {src/starkernel => kernel/src}/vm/vm_bootstrap.c (96%) rename {src/starkernel => kernel/src}/vm/vm_core.c (98%) rename {src/starkernel => kernel/src}/vm/vm_internal.h (97%) rename {src/starkernel => kernel/src}/vm/vm_runtime.c (98%) delete mode 100644 logs2/.gitkeep delete mode 100644 logs2/README.md delete mode 100644 logs2/qemu-aarch64-20260609-192112.log delete mode 100644 logs2/qemu-aarch64-20260611-002443.log delete mode 100644 logs2/qemu-aarch64-20260611-024456.log delete mode 100644 logs2/qemu-aarch64-20260611-173737.log delete mode 100644 logs2/qemu-aarch64-20260611-174951.log delete mode 100644 logs2/qemu-aarch64-20260611-175257.log delete mode 100644 logs2/qemu-aarch64-20260611-190822.log delete mode 100644 logs2/qemu-aarch64-20260611-202955.log delete mode 100644 logs2/qemu-aarch64-20260612-132412.log delete mode 100644 logs2/qemu-aarch64-20260612-141722.log delete mode 100644 logs2/qemu-aarch64-20260612-160132.log delete mode 100644 logs2/qemu-aarch64-20260614-164017.log delete mode 100644 logs2/qemu-aarch64-20260614-164043.log delete mode 100644 logs2/qemu-aarch64-20260614-182154.log delete mode 100644 logs2/qemu-aarch64-20260614-190109.log delete mode 100644 logs2/qemu-aarch64-20260614-230803.log delete mode 100644 logs2/qemu-aarch64-20260615-003908.log delete mode 100644 logs2/qemu-aarch64-20260615-005301.log delete mode 100644 logs2/qemu-aarch64-20260615-020020.log delete mode 100644 logs2/qemu-aarch64-20260615-103253.log delete mode 100644 logs2/qemu-aarch64-20260615-103655.log delete mode 100644 logs2/qemu-aarch64-20260615-121103.log delete mode 100644 logs2/qemu-aarch64-20260615-123814.log delete mode 100644 logs2/qemu-aarch64-20260615-160204.log delete mode 100644 logs2/qemu-aarch64-20260615-183010.log delete mode 100644 logs2/qemu-aarch64-20260615-192747.log delete mode 100644 logs2/qemu-aarch64-20260615-194133.log delete mode 100644 logs2/qemu-aarch64-20260615-204232.log delete mode 100644 logs2/qemu-aarch64-20260615-223549.log delete mode 100644 logs2/qemu-aarch64-20260615-235720.log delete mode 100644 logs2/qemu-aarch64-20260616-000920.log delete mode 100644 logs2/qemu-aarch64-20260616-011049.log delete mode 100644 logs2/qemu-aarch64-20260616-112907.log delete mode 100644 logs2/qemu-aarch64-20260616-155223.log delete mode 100644 logs2/qemu-aarch64-20260616-175845.log delete mode 100644 logs2/qemu-aarch64-20260620-222449.log delete mode 100644 logs2/qemu-aarch64-20260621-004736.log delete mode 100644 logs2/qemu-amd64-20260609-184750.log delete mode 100644 logs2/qemu-amd64-20260609-193717.log delete mode 100644 logs2/qemu-amd64-20260611-002301.log delete mode 100644 logs2/qemu-amd64-20260611-012412.log delete mode 100644 logs2/qemu-amd64-20260611-013401.log delete mode 100644 logs2/qemu-amd64-20260611-023023.log delete mode 100644 logs2/qemu-amd64-20260611-023818.log delete mode 100644 logs2/qemu-amd64-20260611-172713.log delete mode 100644 logs2/qemu-amd64-20260611-174904.log delete mode 100644 logs2/qemu-amd64-20260611-175217.log delete mode 100644 logs2/qemu-amd64-20260611-180750.log delete mode 100644 logs2/qemu-amd64-20260611-192015.log delete mode 100644 logs2/qemu-amd64-20260611-201951.log delete mode 100644 logs2/qemu-amd64-20260611-204126.log delete mode 100644 logs2/qemu-amd64-20260611-223613.log delete mode 100644 logs2/qemu-amd64-20260612-110212.log delete mode 100644 logs2/qemu-amd64-20260612-142323.log delete mode 100644 logs2/qemu-amd64-20260612-160656.log delete mode 100644 logs2/qemu-amd64-20260614-163853.log delete mode 100644 logs2/qemu-amd64-20260614-182034.log delete mode 100644 logs2/qemu-amd64-20260614-182119.log delete mode 100644 logs2/qemu-amd64-20260614-183302.log delete mode 100644 logs2/qemu-amd64-20260614-185942.log delete mode 100644 logs2/qemu-amd64-20260614-190244.log delete mode 100644 logs2/qemu-amd64-20260614-212929.log delete mode 100644 logs2/qemu-amd64-20260614-233623.log delete mode 100644 logs2/qemu-amd64-20260615-005725.log delete mode 100644 logs2/qemu-amd64-20260615-020446.log delete mode 100644 logs2/qemu-amd64-20260615-103154.log delete mode 100644 logs2/qemu-amd64-20260615-103619.log delete mode 100644 logs2/qemu-amd64-20260615-103843.log delete mode 100644 logs2/qemu-amd64-20260615-124956.log delete mode 100644 logs2/qemu-amd64-20260615-125017.log delete mode 100644 logs2/qemu-amd64-20260615-125335.log delete mode 100644 logs2/qemu-amd64-20260615-142839.log delete mode 100644 logs2/qemu-amd64-20260615-161023.log delete mode 100644 logs2/qemu-amd64-20260615-180252.log delete mode 100644 logs2/qemu-amd64-20260615-182339.log delete mode 100644 logs2/qemu-amd64-20260615-182946.log delete mode 100644 logs2/qemu-amd64-20260615-183023.log delete mode 100644 logs2/qemu-amd64-20260615-194545.log delete mode 100644 logs2/qemu-amd64-20260615-204632.log delete mode 100644 logs2/qemu-amd64-20260615-223531.log delete mode 100644 logs2/qemu-amd64-20260615-223607.log delete mode 100644 logs2/qemu-amd64-20260615-230419.log delete mode 100644 logs2/qemu-amd64-20260616-001614.log delete mode 100644 logs2/qemu-amd64-20260616-011447.log delete mode 100644 logs2/qemu-amd64-20260616-111913.log delete mode 100644 logs2/qemu-amd64-20260616-154608.log delete mode 100644 logs2/qemu-amd64-20260616-175829.log delete mode 100644 logs2/qemu-amd64-20260620-222036.log delete mode 100644 logs2/qemu-amd64-20260621-002830.log delete mode 100644 logs2/qemu-amd64-20260621-004710.log delete mode 100644 logs2/qemu-riscv64-20260609-192223.log delete mode 100644 logs2/qemu-riscv64-20260611-002548.log delete mode 100644 logs2/qemu-riscv64-20260611-003502.log delete mode 100644 logs2/qemu-riscv64-20260611-003801.log delete mode 100644 logs2/qemu-riscv64-20260611-024624.log delete mode 100644 logs2/qemu-riscv64-20260611-173903.log delete mode 100644 logs2/qemu-riscv64-20260611-175348.log delete mode 100644 logs2/qemu-riscv64-20260611-191335.log delete mode 100644 logs2/qemu-riscv64-20260611-203104.log delete mode 100644 logs2/qemu-riscv64-20260612-135612.log delete mode 100644 logs2/qemu-riscv64-20260612-141129.log delete mode 100644 logs2/qemu-riscv64-20260612-174414.log delete mode 100644 logs2/qemu-riscv64-20260614-164140.log delete mode 100644 logs2/qemu-riscv64-20260614-165900.log delete mode 100644 logs2/qemu-riscv64-20260614-170926.log delete mode 100644 logs2/qemu-riscv64-20260614-171955.log delete mode 100644 logs2/qemu-riscv64-20260614-182235.log delete mode 100644 logs2/qemu-riscv64-20260614-190152.log delete mode 100644 logs2/qemu-riscv64-20260614-230220.log delete mode 100644 logs2/qemu-riscv64-20260615-004335.log delete mode 100644 logs2/qemu-riscv64-20260615-004822.log delete mode 100644 logs2/qemu-riscv64-20260615-031059.log delete mode 100644 logs2/qemu-riscv64-20260615-103741.log delete mode 100644 logs2/qemu-riscv64-20260615-122026.log delete mode 100644 logs2/qemu-riscv64-20260615-122930.log delete mode 100644 logs2/qemu-riscv64-20260615-174420.log delete mode 100644 logs2/qemu-riscv64-20260615-183017.log delete mode 100644 logs2/qemu-riscv64-20260615-193223.log delete mode 100644 logs2/qemu-riscv64-20260615-193711.log delete mode 100644 logs2/qemu-riscv64-20260615-214335.log delete mode 100644 logs2/qemu-riscv64-20260615-223550.log delete mode 100644 logs2/qemu-riscv64-20260616-000114.log delete mode 100644 logs2/qemu-riscv64-20260616-000522.log delete mode 100644 logs2/qemu-riscv64-20260616-021123.log delete mode 100644 logs2/qemu-riscv64-20260616-113103.log delete mode 100644 logs2/qemu-riscv64-20260616-155324.log delete mode 100644 logs2/qemu-riscv64-20260616-175915.log delete mode 100644 logs2/qemu-riscv64-20260620-231806.log delete mode 100644 logs2/qemu-riscv64-20260621-004843.log delete mode 100644 logs2/qemu-screenshot-20260609-105458.png delete mode 100644 logs2/qemu-screenshot-20260609-130717.png delete mode 100644 logs2/qemu-screenshot-20260609-181200.png delete mode 100644 logs2/qemu-screenshot-20260609-193724.log delete mode 100644 logs2/qemu-screenshot-20260609-193724.png delete mode 100644 logs2/qemu-screenshot-20260609-194549.png delete mode 100644 logs2/qemu-screenshot-20260609-194812.png delete mode 100644 logs2/qemu-screenshot-20260609-222537.png delete mode 100644 logs2/qemu-screenshot-20260609-225958.png delete mode 100644 logs2/qemu-screenshot-20260609-232904.png delete mode 100644 logs2/qemu-screenshot-20260610-005734.png delete mode 100644 logs2/qemu-screenshot-20260610-134732.png delete mode 100644 logs2/qemu-screenshot-20260610-145902.png delete mode 100644 logs2/qemu-screenshot-20260610-213714.png delete mode 100644 logs2/qemu-screenshot-20260611-002306.log delete mode 100644 logs2/qemu-screenshot-20260611-004156.log delete mode 100644 logs2/qemu-screenshot-20260611-012817.log delete mode 100644 logs2/qemu-screenshot-20260611-023758.log delete mode 100644 logs2/qemu-screenshot-20260611-024401.log delete mode 100644 logs2/qemu-screenshot-20260611-173657.log delete mode 100644 logs2/qemu-screenshot-20260611-174914.log delete mode 100644 logs2/qemu-screenshot-20260611-175224.log delete mode 100644 logs2/qemu-screenshot-20260611-190757.log delete mode 100644 logs2/qemu-screenshot-20260611-202932.log delete mode 100644 logs2/qemu-screenshot-20260612-115354.log delete mode 100644 logs2/qemu-screenshot-20260612-160054.log delete mode 100644 logs2/qemu-screenshot-20260612-174331.log delete mode 100644 logs2/qemu-screenshot-20260614-163902.log delete mode 100644 logs2/qemu-screenshot-20260614-182044.log delete mode 100644 logs2/qemu-screenshot-20260614-182127.log create mode 100644 scripts/mkdiskimage.sh create mode 100644 v3/Makefile rename {include => v3/include}/README.md (100%) rename {include => v3/include}/arch_detect.h (100%) rename {include => v3/include}/blkcfg.h (100%) rename {include => v3/include}/blkio.h (100%) rename {include => v3/include}/blkio_factory.h (100%) rename {include => v3/include}/block_subsystem.h (100%) rename {include => v3/include}/cli.h (100%) rename {include => v3/include}/compudynamics.h (100%) rename {include => v3/include}/dictionary_heat_optimization.h (100%) rename {include => v3/include}/dictionary_management.h (100%) rename {include => v3/include}/doe_metrics.h (100%) rename {include => v3/include}/inference_engine.h (100%) rename {include => v3/include}/io.h (100%) rename {include => v3/include}/log.h (100%) rename {include => v3/include}/math_portable.h (100%) rename {include => v3/include}/memory_management.h (100%) rename {include => v3/include}/physics_execution_hooks.h (100%) rename {include => v3/include}/physics_hotwords_cache.h (100%) rename {include => v3/include}/physics_metadata.h (100%) rename {include => v3/include}/physics_pipelining_metrics.h (100%) rename {include => v3/include}/physics_runtime.h (100%) rename {include => v3/include}/platform_alloc.h (100%) rename {include => v3/include}/platform_io.h (100%) rename {include => v3/include}/platform_lock.h (100%) rename {include => v3/include}/platform_time.h (100%) rename {include => v3/include}/profiler.h (100%) rename {include => v3/include}/q48_16.h (100%) rename {include => v3/include}/repl.h (100%) rename {include => v3/include}/rolling_window_knobs.h (100%) rename {include => v3/include}/rolling_window_of_truth.h (100%) rename {include => v3/include}/ssm_jacquard.h (100%) rename {include => v3/include}/starforth_config.h (100%) rename {include => v3/include}/startup.h (100%) create mode 100644 v3/include/version.h rename {include => v3/include}/vm.h (100%) rename {include => v3/include}/vm_api.h (100%) rename {include => v3/include}/vm_asm_opt.h (100%) rename {include => v3/include}/vm_asm_opt_arm64.h (100%) rename {include => v3/include}/vm_asm_opt_riscv64.h (100%) rename {include => v3/include}/vm_debug.h (100%) rename {include => v3/include}/vm_host.h (100%) rename {include => v3/include}/vm_inner_interp_arm64.h (100%) rename {include => v3/include}/vm_inner_interp_asm.h (100%) rename {include => v3/include}/vm_inner_interp_riscv64.h (100%) rename {include => v3/include}/word_registry.h (100%) rename {src => v3/src}/README.md (100%) rename {src => v3/src}/blkio_factory.c (100%) rename {src => v3/src}/blkio_file.c (100%) rename {src => v3/src}/blkio_ram.c (100%) rename {src => v3/src}/block_subsystem.c (100%) rename {src => v3/src}/cli.c (100%) rename {src => v3/src}/compudynamics.c (100%) rename {src => v3/src}/dictionary_heat_optimization.c (100%) rename {src => v3/src}/dictionary_management.c (100%) rename {src => v3/src}/doe_metrics.c (100%) rename {src => v3/src}/heartbeat_export.c (100%) rename {src => v3/src}/inference_engine.c (100%) rename {src => v3/src}/io.c (100%) rename {src => v3/src}/log.c (100%) rename {src => v3/src}/main.c (100%) rename {src => v3/src}/math_portable.c (100%) rename {src => v3/src}/memory_management.c (100%) rename {src => v3/src}/physics_execution_hooks.c (100%) rename {src => v3/src}/physics_hotwords_cache.c (100%) rename {src => v3/src}/physics_metadata.c (100%) rename {src => v3/src}/physics_pipelining_metrics.c (100%) rename {src => v3/src}/physics_runtime.c (100%) rename {src => v3/src}/platform/README.md (100%) rename {src => v3/src}/platform/alloc_host.c (100%) rename {src => v3/src}/platform/alloc_kernel.c (100%) rename {src => v3/src}/platform/l4re/README.md (100%) rename {src => v3/src}/platform/l4re/time.c (100%) rename {src => v3/src}/platform/linux/README.md (100%) rename {src => v3/src}/platform/linux/io.c (100%) rename {src => v3/src}/platform/linux/time.c (100%) rename {src => v3/src}/platform/platform_init.c (100%) rename {src => v3/src}/platform/threading.c (100%) rename {src => v3/src}/profiler.c (100%) rename {src => v3/src}/repl.c (100%) rename {src => v3/src}/rolling_window_of_truth.c (100%) rename {src => v3/src}/ssm_jacquard.c (100%) rename {src => v3/src}/stack_management.c (100%) rename {src => v3/src}/test_runner/README.md (100%) rename {src => v3/src}/test_runner/include/README.md (100%) rename {src => v3/src}/test_runner/include/test_common.h (99%) rename {src => v3/src}/test_runner/include/test_contracts.h (100%) rename {src => v3/src}/test_runner/include/test_runner.h (100%) rename {src => v3/src}/test_runner/modules/README.md (100%) rename {src => v3/src}/test_runner/modules/acl_words_test.c (100%) rename {src => v3/src}/test_runner/modules/arithmetic_words_test.c (100%) rename {src => v3/src}/test_runner/modules/block_words_test.c (100%) rename {src => v3/src}/test_runner/modules/break_me_tests.c (100%) rename {src => v3/src}/test_runner/modules/control_words_test.c (100%) rename {src => v3/src}/test_runner/modules/defining_words_tests.c (100%) rename {src => v3/src}/test_runner/modules/dictionary_manipulation_words_test.c (100%) rename {src => v3/src}/test_runner/modules/dictionary_words_test.c (100%) rename {src => v3/src}/test_runner/modules/double_words_test.c (100%) rename {src => v3/src}/test_runner/modules/format_words_test.c (100%) rename {src => v3/src}/test_runner/modules/inference_words_test.c (100%) rename {src => v3/src}/test_runner/modules/integration_tests.c (100%) rename {src => v3/src}/test_runner/modules/io_words_test.c (100%) rename {src => v3/src}/test_runner/modules/logical_words_test.c (100%) rename {src => v3/src}/test_runner/modules/mama_forth_words_test.c (100%) rename {src => v3/src}/test_runner/modules/memory_words_test.c (100%) rename {src => v3/src}/test_runner/modules/mixed_arithmetic_words_test.c (100%) rename {src => v3/src}/test_runner/modules/physics_freeze_words_test.c (100%) rename {src => v3/src}/test_runner/modules/q48_words_test.c (100%) rename {src => v3/src}/test_runner/modules/return_stack_words_test.c (100%) rename {src => v3/src}/test_runner/modules/stack_words_test.c (100%) rename {src => v3/src}/test_runner/modules/starforth_words_test.c (100%) rename {src => v3/src}/test_runner/modules/stress_tests.c (100%) rename {src => v3/src}/test_runner/modules/string_words_test.c (100%) rename {src => v3/src}/test_runner/modules/system_words_test.c (100%) rename {src => v3/src}/test_runner/modules/vocabulary_words_test.c (100%) rename {src => v3/src}/test_runner/test_common.c (100%) rename {src => v3/src}/test_runner/test_contracts.c (100%) rename {src => v3/src}/test_runner/test_runner.c (100%) rename {src => v3/src}/vm.c (100%) rename {src => v3/src}/vm_api.c (100%) rename {src => v3/src}/vm_bootstrap.c (99%) rename {src => v3/src}/vm_debug.c (100%) rename {src => v3/src}/vm_internal.h (100%) rename {src => v3/src}/vm_time.c (100%) rename {src => v3/src}/word_registry.c (100%) rename {src => v3/src}/word_source/README.md (100%) rename {src => v3/src}/word_source/acl_words.c (100%) rename {src => v3/src}/word_source/arithmetic_words.c (100%) rename {src => v3/src}/word_source/block_words.c (100%) rename {src => v3/src}/word_source/control_words.c (100%) rename {src => v3/src}/word_source/defer_words.c (100%) rename {src => v3/src}/word_source/defining_words.c (100%) rename {src => v3/src}/word_source/dictionary_heat_diagnostic_words.c (100%) rename {src => v3/src}/word_source/dictionary_manipulation_words.c (100%) rename {src => v3/src}/word_source/dictionary_words.c (100%) rename {src => v3/src}/word_source/double_words.c (100%) rename {src => v3/src}/word_source/editor_words.c (100%) rename {src => v3/src}/word_source/format_words.c (100%) rename {src => v3/src}/word_source/framebuffer_words.c (100%) rename {src => v3/src}/word_source/include/README.md (100%) rename {src => v3/src}/word_source/include/acl_words.h (100%) rename {src => v3/src}/word_source/include/arithmetic_words.h (100%) rename {src => v3/src}/word_source/include/block_words.h (100%) rename {src => v3/src}/word_source/include/control_words.h (100%) rename {src => v3/src}/word_source/include/defer_words.h (89%) rename {src => v3/src}/word_source/include/defining_words.h (100%) rename {src => v3/src}/word_source/include/dictionary_heat_diagnostic_words.h (100%) rename {src => v3/src}/word_source/include/dictionary_manipulation_words.h (100%) rename {src => v3/src}/word_source/include/dictionary_words.h (100%) rename {src => v3/src}/word_source/include/double_words.h (100%) rename {src => v3/src}/word_source/include/editor_words.h (100%) rename {src => v3/src}/word_source/include/format_words.h (100%) rename {src => v3/src}/word_source/include/framebuffer_words.h (100%) rename {src => v3/src}/word_source/include/inference_words.h (100%) rename {src => v3/src}/word_source/include/io_words.h (100%) rename {src => v3/src}/word_source/include/keyboard_words.h (100%) rename {src => v3/src}/word_source/include/log_words.h (100%) rename {src => v3/src}/word_source/include/logical_words.h (100%) rename {src => v3/src}/word_source/include/mama_forth_words.h (100%) rename {src => v3/src}/word_source/include/memory_words.h (100%) rename {src => v3/src}/word_source/include/mixed_arithmetic_words.h (100%) rename {src => v3/src}/word_source/include/physics_benchmark_words.h (100%) rename {src => v3/src}/word_source/include/physics_diagnostic_words.h (100%) rename {src => v3/src}/word_source/include/physics_freeze_words.h (100%) rename {src => v3/src}/word_source/include/physics_pipelining_diagnostic_words.h (100%) rename {src => v3/src}/word_source/include/q48_words.h (100%) rename {src => v3/src}/word_source/include/return_stack_words.h (100%) rename {src => v3/src}/word_source/include/scroll_words.h (100%) rename {src => v3/src}/word_source/include/stack_words.h (100%) rename {src => v3/src}/word_source/include/starforth_words.h (100%) rename {src => v3/src}/word_source/include/string_words.h (100%) rename {src => v3/src}/word_source/include/system_words.h (100%) rename {src => v3/src}/word_source/include/ttf_words.h (100%) rename {src => v3/src}/word_source/include/vocabulary_words.h (100%) rename {src => v3/src}/word_source/inference_words.c (100%) rename {src => v3/src}/word_source/io_words.c (100%) rename {src => v3/src}/word_source/keyboard_words.c (100%) rename {src => v3/src}/word_source/lifecycle_words_hosted.c (100%) rename {src => v3/src}/word_source/log_words.c (100%) rename {src => v3/src}/word_source/logical_words.c (100%) rename {src => v3/src}/word_source/memory_words.c (100%) rename {src => v3/src}/word_source/mixed_arithmetic_words.c (100%) rename {src => v3/src}/word_source/physics_benchmark_words.c (100%) rename {src => v3/src}/word_source/physics_diagnostic_words.c (100%) rename {src => v3/src}/word_source/physics_freeze_words.c (100%) rename {src => v3/src}/word_source/physics_pipelining_diagnostic_words.c (99%) rename {src => v3/src}/word_source/q48_16_words.c (99%) rename {src => v3/src}/word_source/q48_words.c (100%) rename {src => v3/src}/word_source/return_stack_words.c (100%) rename {src => v3/src}/word_source/scroll_words.c (100%) rename {src => v3/src}/word_source/stack_words.c (100%) rename {src => v3/src}/word_source/starforth_words.c (100%) rename {src => v3/src}/word_source/string_words.c (100%) rename {src => v3/src}/word_source/system_words.c (100%) rename {src => v3/src}/word_source/ttf_words.c (100%) rename {src => v3/src}/word_source/vocabulary_words.c (100%) create mode 100644 v4/README.md diff --git a/.clang-tidy b/.clang-tidy index fc5ec979..4f74e301 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -14,7 +14,7 @@ Checks: > WarningsAsErrors: [ ] -HeaderFilterRegex: '^src/.*|^include/.*' +HeaderFilterRegex: '^v3/(src|include)/.*|^kernel/(src|include)/.*' AnalyzeTemporaryDtors: false FormatStyle: none diff --git a/.clang-tidy-ignore b/.clang-tidy-ignore index a9f4fa42..53a4a208 100644 --- a/.clang-tidy-ignore +++ b/.clang-tidy-ignore @@ -6,8 +6,8 @@ # clang-tidy will ALWAYS false-positive them. Always. # --------------------------------------------------------- -src/platform/** -src/platform/* +v3/src/platform/** +v3/src/platform/* # --------------------------------------------------------- # Skip test infrastructure @@ -15,8 +15,8 @@ src/platform/* # and stress edge conditions clang-tidy will never grok. # --------------------------------------------------------- -src/test_runner/** -src/test_runner/* +v3/src/test_runner/** +v3/src/test_runner/* # --------------------------------------------------------- # Skip word definitions generated or "mechanically patterned" @@ -24,30 +24,30 @@ src/test_runner/* # clang-tidy gives ZERO useful feedback on them. # --------------------------------------------------------- -src/word_source/string_words.c -src/word_source/block_words.c -src/word_source/arithmetic_words.c -src/word_source/mixed_arithmetic_words.c -src/word_source/return_stack_words.c -src/word_source/defining_words.c -src/word_source/stack_words.c -src/word_source/logical_words.c -src/word_source/memory_words.c -src/word_source/io_words.c -src/word_source/dictionary_words.c -src/word_source/dictionary_manipulation_words.c -src/word_source/vocabulary_words.c -src/word_source/system_words.c -src/word_source/starforth_words.c -src/word_source/editor_words.c -src/word_source/format_words.c +v3/src/word_source/string_words.c +v3/src/word_source/block_words.c +v3/src/word_source/arithmetic_words.c +v3/src/word_source/mixed_arithmetic_words.c +v3/src/word_source/return_stack_words.c +v3/src/word_source/defining_words.c +v3/src/word_source/stack_words.c +v3/src/word_source/logical_words.c +v3/src/word_source/memory_words.c +v3/src/word_source/io_words.c +v3/src/word_source/dictionary_words.c +v3/src/word_source/dictionary_manipulation_words.c +v3/src/word_source/vocabulary_words.c +v3/src/word_source/system_words.c +v3/src/word_source/starforth_words.c +v3/src/word_source/editor_words.c +v3/src/word_source/format_words.c # --------------------------------------------------------- # Skip headers belonging to the word system # Same reason: no signal, infinite false positives. # --------------------------------------------------------- -src/word_source/include/* +v3/src/word_source/include/* # --------------------------------------------------------- # Skip anything that implements performance knobs, @@ -55,15 +55,15 @@ src/word_source/include/* # These are meant to be weird, and tidy can't reason about them. # --------------------------------------------------------- -src/stack_management.c -src/profiler.c -src/vm_debug.c -src/physics_runtime.c +v3/src/stack_management.c +v3/src/profiler.c +v3/src/vm_debug.c +v3/src/physics_runtime.c # --------------------------------------------------------- # Skip integration + stress torture-tests. # These *intentionally* do UB-like bullshit. # --------------------------------------------------------- -src/test_runner/modules/*stress* -src/test_runner/modules/*integration* +v3/src/test_runner/modules/*stress* +v3/src/test_runner/modules/*integration* diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index b6348859..8981e7d3 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -224,43 +224,43 @@ changes with any new C word registration). ```bash # Build kernel for a given architecture (amd64 default) -make -f Makefile.starkernel ARCH=amd64 -make -f Makefile.starkernel ARCH=aarch64 -make -f Makefile.starkernel ARCH=riscv64 +make -f kernel/Makefile ARCH=amd64 +make -f kernel/Makefile ARCH=aarch64 +make -f kernel/Makefile ARCH=riscv64 # Run in QEMU with OVMF -make -f Makefile.starkernel qemu -make -f Makefile.starkernel ARCH=aarch64 qemu -make -f Makefile.starkernel ARCH=riscv64 qemu +make -f kernel/Makefile qemu +make -f kernel/Makefile ARCH=aarch64 qemu +make -f kernel/Makefile ARCH=riscv64 qemu # Clean -make -f Makefile.starkernel clean +make -f kernel/Makefile clean ``` Output: `build//kernel/starkernel_loader.efi` + `build//kernel/starkernel_kernel.elf`. Two independently tracked version strings flow into the generated `include/version.h`: -`VERSION` (`Makefile.starkernel` โ€” the embedded StarForth engine version, currently `3.1.0`; +`VERSION` (`kernel/Makefile` โ€” the embedded StarForth engine version, currently `3.1.0`; note this does **not** auto-sync with the standalone StarForth repo's own version) and -`LITHOS_VERSION` (`Makefile.starkernel` โ€” the kernel version, currently **`2.0.0`**; +`LITHOS_VERSION` (`kernel/Makefile` โ€” the kernel version, currently **`2.0.0`**; corrected 2026-09-19 โ€” this file said `2.0.1`, but `FABRIC-3.md` ยงI.2 rolled it back to `2.0.0` on 2026-09-04 because `2.0.1` names the SER5 hardware-track line and claims hardware progress not yet verified. The versioning policy is **semantic, not sequential** โ€” see the -roadmap table in `Makefile.starkernel` before choosing any version). +roadmap table in `kernel/Makefile` before choosing any version). ### Build configuration (Kconfig โ€” real, wired, not vestigial) Every kernel-only knob (`STARFORTH_ENABLE_VM`, `PARITY_MODE`, the shared physics/heartbeat family, etc.) is an optional Kconfig symbol defined across `Kconfig`, `Kconfig.arch`, `Kconfig.heartbeat`, `Kconfig.kernel`, `Kconfig.physics`, `Kconfig.variant` (~40 symbols -total). `Makefile.starkernel` pulls its defaults from this system via a `kconfig_bool(...)` +total). `kernel/Makefile` pulls its defaults from this system via a `kconfig_bool(...)` mechanism โ€” e.g. `STARFORTH_ENABLE_VM` defaults to **1** (confirmed at -`Makefile.starkernel:61`), meaning a plain `make -f Makefile.starkernel` already builds with +`kernel/Makefile:61`), meaning a plain `make -f kernel/Makefile` already builds with VM + capsule-birth + ACL active. A bare invocation uses the defaults it always has: ```bash -make -f Makefile.starkernel ARCH=amd64 menuconfig -make -f Makefile.starkernel ARCH=amd64 kernel_amd64_defconfig +make -f kernel/Makefile ARCH=amd64 menuconfig +make -f kernel/Makefile ARCH=amd64 kernel_amd64_defconfig ``` ### Hosted VM (vendored, for local sanity only) @@ -277,7 +277,7 @@ StarForth repo) were removed 2026-08-15 โ€” they referenced in the actual generated `include/version.h` (which only has `STARFORTH_VERSION`, `STARFORTH_ARCH`, `STARFORTH_TARGET`, `STARFORTH_TIMESTAMP`, `STARFORTH_VERSION_FULL`, `LITHOS_VERSION`, `LITHOS_VERSION_STR`), so they could never have worked. Bump versions by hand-editing the `VERSION`/ -`LITHOS_VERSION` variables in `Makefile.starkernel` instead. Report the broken targets if +`LITHOS_VERSION` variables in `kernel/Makefile` instead. Report the broken targets if asked, don't silently fix them. ### Important: Linker Configuration @@ -298,9 +298,9 @@ The vendored hosted `make` build (above) is NEVER used to validate kernel change ```bash # Run in this exact order for every kernel change: -make -f Makefile.starkernel ARCH=amd64 clean qemu -make -f Makefile.starkernel ARCH=aarch64 clean qemu -make -f Makefile.starkernel ARCH=riscv64 clean qemu +make -f kernel/Makefile ARCH=amd64 clean qemu +make -f kernel/Makefile ARCH=aarch64 clean qemu +make -f kernel/Makefile ARCH=riscv64 clean qemu ``` **QEMU rule โ€” non-negotiable:** Only ONE QEMU instance may run at a time, always in the @@ -475,7 +475,7 @@ listed in `proof/ROOT` (corrected 2026-09-19; this file said 23, and `proof/COVE said 52 all along). **Read `proof/COVERAGE.md` first**: its stated goal is not a green build but "identify precisely what cannot be proven and why โ€” the boundary between 'formally verified' and 'not, for this specific reason'." Run `isabelle build -D proof/` -directly; neither `Makefile` nor `Makefile.starkernel` in this repo defines an +directly; neither `Makefile` nor `kernel/Makefile` in this repo defines an `isabelle-build`/`isabelle-check` target (unlike the standalone StarForth repo, which has a broken one โ€” this repo simply doesn't have the target at all, so there's nothing to mistakenly invoke). @@ -495,7 +495,7 @@ status for kernel work. - **Strict ANSI C99** โ€” No GNU extensions, no C++ features - **Zero warnings target, with four explicit exceptions โ€” corrected 2026-08-18, previous - claim was wrong.** Build with `-Wall -Wextra -Werror`, but `Makefile.starkernel` carries + claim was wrong.** Build with `-Wall -Wextra -Werror`, but `kernel/Makefile` carries `-Wno-error=unused-parameter -Wno-error=shift-negative-value -Wno-error=sign-compare -Wno-error=missing-field-initializers` โ€” those four classes are enabled (still visible as warnings) but deliberately downgraded from fatal, everything else is. The previous version diff --git a/Doxyfile b/Doxyfile index 517db1c4..4d6cd19a 100644 --- a/Doxyfile +++ b/Doxyfile @@ -933,10 +933,12 @@ WARN_LOGFILE = docs/api/doxygen_warnings.log # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = include \ - src \ - src/word_source \ - src/test_runner \ +INPUT = v3/include \ + v3/src \ + v3/src/word_source \ + v3/src/test_runner \ + kernel/include \ + kernel/src \ README.md # This tag can be used to specify the character encoding of the source files @@ -2366,9 +2368,10 @@ SEARCH_INCLUDES = YES # RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = include \ - src/word_source/include \ - src/test_runner/include +INCLUDE_PATH = v3/include \ + kernel/include \ + v3/src/word_source/include \ + v3/src/test_runner/include # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the diff --git a/Kconfig.arch b/Kconfig.arch index 9cc52bee..21e5bdc0 100644 --- a/Kconfig.arch +++ b/Kconfig.arch @@ -5,7 +5,7 @@ choice default ARCH_AMD64 help Selects the value passed as ARCH= to whichever Makefile - (Makefile or Makefile.starkernel) is driven from this config. + (Makefile or kernel/Makefile) is driven from this config. Both Makefiles already accept "amd64"/"aarch64"/"riscv64" as canonical spellings (each has its own alias-normalizing logic for other spellings like x86_64/arm64/riscv), so this choice diff --git a/Kconfig.heartbeat b/Kconfig.heartbeat index eb6750ea..c0880d72 100644 --- a/Kconfig.heartbeat +++ b/Kconfig.heartbeat @@ -17,7 +17,7 @@ config HEARTBEAT_THREAD_ENABLED builds without needing a special case. This is UI/model correctness (menuconfig can't offer a choice LithosAnanke has no way to honor -- there are no pthreads in a freestanding kernel), - not the sole enforcement mechanism: Makefile.starkernel additionally + not the sole enforcement mechanism: kernel/Makefile additionally keeps its own unconditional `VM_FEATURE_OVERRIDES += -DHEARTBEAT_THREAD_ENABLED=0` post-override exactly as it was before this migration. Deliberately redundant with the `depends diff --git a/Kconfig.kernel b/Kconfig.kernel index bb8cc681..9cf88534 100644 --- a/Kconfig.kernel +++ b/Kconfig.kernel @@ -11,7 +11,7 @@ config STARFORTH_ENABLE_VM kernel that only reaches the M0-M6 hardware milestones (console, PMM, VMM, interrupts, timers, kmalloc) with no FORTH interpreter, no capsules, no "ok" REPL. Gates a large source-file selection - block in Makefile.starkernel, not just a handful of -D flags. + block in kernel/Makefile, not just a handful of -D flags. config PARITY_MODE bool "Deterministic parity harness mode (PARITY_MODE)" diff --git a/Makefile b/Makefile index d3757f86..e2d16cb5 100644 --- a/Makefile +++ b/Makefile @@ -1,1340 +1,159 @@ # ============================================================================== -# StarForth Build System - The Fastest Forth in the West! -# ============================================================================== +# LithosAnanke / StarForth -- top-level Makefile # -# Quick Start: -# make - Standard optimized build (auto ARCH, TARGET=standard) -# make TARGET=fastest - Maximum performance build -# make ARCH=arm64 TARGET=fastest - Build for arm64 (e.g., Raspberry Pi 4) -# make help - Show all available targets +# Thin dispatcher. The real build lives in: +# v3/Makefile -- hosted StarForth v3 (Linux userland VM, POST, DoE) +# kernel/Makefile -- LithosAnanke kernel (UEFI loader, kernel ELF, QEMU) +# boards// -- one directory per physical target (board.mk + boot files) +# docs/book/Makefile -- the single LaTeX book (build/docs/*.pdf) +# Every sub-make runs from this directory, so paths are always repo-relative. # +# TARGET is either a board (SER5 RASPI MILKV ZYNQ7020), a hosted v3 profile +# (standard fast fastest turbo asan ...), or empty: +# +# make [all] every board that has a kernel port, the +# hosted v3 build, and the book +# make [all] TARGET= that board's boot image + its book +# make [all] TARGET= hosted v3 build with that profile +# +# make boot_image TARGET= only the board's boot image +# make boot_images every board that has a kernel port +# make docs [TARGET=] the book; a board adds its appendix +# +# make clean all of build/ except build/cache/ +# make clean TARGET= the board's image + book and its ISA's kernel objects +# make clean TARGET= build// for every arch +# make clean-docs build/docs/ +# +# make kernel ARCH= [GOAL=g] kernel/Makefile goal (default: all) +# make boards list boards and whether they can be built +# make goes to v3/Makefile (make help-hosted) # ============================================================================== -# ============================================================================== -# CONFIGURATION -# ============================================================================== +# Board name (as typed on the command line) -> boards/ directory. +BOARD_DIR_SER5 := ser5 +BOARD_DIR_RASPI := raspi +BOARD_DIR_MILKV := milkv +BOARD_DIR_ZYNQ7020 := zynq7020 +BOARDS := SER5 RASPI MILKV ZYNQ7020 +empty := +space := $(empty) $(empty) -VERSION ?= 3.2.0 -CC = gcc +board_field = $(if $(BOARD_DIR_$(1)),$(shell sed -n 's/^$(2) *:= *//p' boards/$(BOARD_DIR_$(1))/board.mk)) +board_arch = $(call board_field,$(1),BOARD_ARCH) +# A board can be built once its ISA's kernel port exists. +board_ready = $(if $(call board_arch,$(1)),$(wildcard kernel/src/arch/$(call board_arch,$(1))/.)) -# Isabelle configuration -# NOTE: Isabelle must be installed separately and available on PATH -# See docs/DEVELOPER.md for installation instructions -ISABELLE ?= isabelle +READY_BOARDS := $(foreach b,$(BOARDS),$(if $(call board_ready,$(b)),$(b))) +UNREADY_BOARDS := $(filter-out $(READY_BOARDS),$(BOARDS)) -# Architecture / target selection -ARCH ?= $(shell uname -m) -ARCH := $(strip $(ARCH)) -TARGET ?= standard -TARGET := $(strip $(TARGET)) +TARGET := $(strip $(TARGET)) +BOARD_DIR := $(if $(TARGET),$(BOARD_DIR_$(TARGET))) -# Friendly guardrail: 32-bit builds are not supported -unsupported_32bit_arches := i386 i486 i586 i686 x86 armv6 armv7 armv7l arm -ifneq ($(filter $(ARCH),$(unsupported_32bit_arches)),) - $(error StarForth targets 64-bit platforms only. ARCH='$(ARCH)' is unsupported. Please build on amd64/arm64/raspi/riscv64.) -endif +SUBMAKE := $(MAKE) --no-print-directory -# Canonical architecture normalization (x86_64โ†’amd64, aarch64โ†’arm64, etc.) -canon_arch = $(strip $(if $(filter x86_64,$1),amd64,$(if $(filter amd64,$1),amd64,$(if $(filter aarch64 arm64,$1),arm64,$(if $(filter riscv riscv64,$1),riscv64,$1))))) -ARCH_DIR := $(call canon_arch,$(ARCH)) -# Normalize ARCH for consistent ifeq matching -ARCH := $(call canon_arch,$(ARCH)) - -# Kconfig bridge (menuconfig/xconfig/config/oldconfig/*_defconfig). See -# mk/Kconfig.mk for why KCONFIG_ARCH_DIR must be set here, before include. -# .DEFAULT_GOAL is pinned explicitly because mk/Kconfig.mk's first rule -# would otherwise silently become Make's default goal, since it's included -# before this Makefile's own `all:` target is defined below. .DEFAULT_GOAL := all -KCONFIG_ARCH_DIR := $(ARCH_DIR) -include mk/Kconfig.mk - -# Kconfig platform-mode choice (Phase 5): PLATFORM_DEFAULT/PLATFORM_MINIMAL -# in Kconfig.variant (PLATFORM_L4RE removed -- L4Re support is historical, -# see the "Platform support" section below). Must run this early -- before -# anything below that branches on MINIMAL -- since Make evaluates a Makefile -# top-to-bottom and a variable's value at the point an `ifdef` is reached is -# whatever it resolved to *so far*, not its final value. Only applies when a -# developer hasn't already set MINIMAL explicitly (command line or -# environment) -- `ifdef` in the "Platform support" section below cares -# about definedness, not value, so this can't reuse the kconfig_bool/ -# kconfig_int pattern (those always define their target variable once -# active). Checked with $(origin ...) so an explicit `make MINIMAL=1` (or -# unset) always wins over whatever .config says. -ifeq ($(KCONFIG_ACTIVE),1) -ifeq ($(origin MINIMAL),undefined) -ifeq ($(CONFIG_PLATFORM_MINIMAL),y) -MINIMAL := 1 -endif -endif -endif - -ifeq ($(ARCH),amd64) - ARCH_NAME = x86_64 - ARCH_FLAGS = -march=native - ARCH_DEFINES = -DARCH_X86_64=1 - ASM_SYNTAX = -masm=intel -else ifeq ($(ARCH),arm64) - ARCH_NAME = ARM64 - ARCH_FLAGS = -march=armv8-a+crc+simd -mtune=cortex-a72 - ARCH_DEFINES = -DARCH_ARM64=1 - ASM_SYNTAX = -else ifeq ($(ARCH),raspi) - ARCH_NAME = Raspberry Pi 4 (ARM64) - ARCH_FLAGS = -march=armv8-a+crc+simd -mtune=cortex-a72 - ARCH_DEFINES = -DARCH_ARM64=1 -DRASPBERRY_PI_BUILD=1 - ASM_SYNTAX = -else ifeq ($(ARCH),riscv64) - ARCH_NAME = RISC-V 64 (QEMU) - ARCH_FLAGS = -march=rv64gc -mabi=lp64d -mcmodel=medany - ARCH_DEFINES = -DARCH_RISCV64=1 - ASM_SYNTAX = -else ifeq ($(ARCH),riscv) - ARCH_NAME = RISC-V 64 (QEMU) - ARCH_FLAGS = -march=rv64gc -mabi=lp64d -mcmodel=medany - ARCH_DEFINES = -DARCH_RISCV64=1 - ASM_SYNTAX = -else - $(warning Unknown architecture: $(ARCH), using generic flags) - ARCH_NAME = generic - ARCH_FLAGS = - ARCH_DEFINES = - ASM_SYNTAX = -endif - -# Compiler flags -# Feature switches (default: enabled) -# Physics/SSM knob family: repointed through the Kconfig bridge (see -# mk/Kconfig.mk's kconfig_bool/kconfig_int) as of the Kconfig migration's -# Phase 3. Each call below is a drop-in replacement for a bare `?=`: when -# no build/$(ARCH)/.config exists (KCONFIG_ACTIVE unset), it's exactly -# `VAR ?= default`, identical to before; once a .config exists, the -# Kconfig-fed value takes over. `make VAR=x` on the command line always -# wins regardless of which branch fires. -# -# STRICT_PTR: VM memory bounds checking on every pointer access -# Default: 1 (enabled). Disable only for raw benchmarking comparisons. -$(eval $(call kconfig_bool,STRICT_PTR,1)) - -# ENABLE_HOTWORDS_CACHE: Physics-driven hot-words cache (1.78ร— speedup on dictionary lookups) -# Default: 1 (enabled - experiments show cache is optimal) -# Set ENABLE_HOTWORDS_CACHE=0 to disable (for research comparison only) -$(eval $(call kconfig_bool,ENABLE_HOTWORDS_CACHE,0)) - -# ENABLE_PIPELINING: Speculative execution via word transition prediction -# Default: 1 (enabled - experiments show pipelining is optimal) -# Set ENABLE_PIPELINING=0 to disable (for research comparison only) -# NOTE: As of 2025-11-19, all future experiments use both cache and pipelining enabled -$(eval $(call kconfig_bool,ENABLE_PIPELINING,0)) - -# EMERGENCY_CONSOLE_ENABLED: 1 = REPL recovers from errors and continues (interactive fallthrough) -# 0 = errors are non-recoverable; REPL exits and vm_fault_handler() is called instead -# Default: 1 (dev/recovery builds) -# Set EMERGENCY_CONSOLE_ENABLED=0 for production, embedded, or high-security builds -# where no interactive fallthrough surface should exist. -# Heartbeat family: repointed through the Kconfig bridge (Phase 4). Same -# drop-in-replacement-for-`?=` behavior as the physics/SSM family (Phase 3). -$(eval $(call kconfig_bool,EMERGENCY_CONSOLE_ENABLED,1)) - -# Heartbeat configuration -# HEARTBEAT_THREAD_ENABLED: 1 = run vm_tick() in background thread (OPTIMAL), 0 = inline (legacy) -# Default: 1 (experiments show threaded heartbeat is optimal for adaptive tuning) -# NOTE: As of 2025-11-19, all future experiments use heartbeat enabled -$(eval $(call kconfig_bool,HEARTBEAT_THREAD_ENABLED,1)) - -# HEARTBEAT_TICK_NS: Wake frequency for heartbeat thread (default 1ms) -$(eval $(call kconfig_int,HEARTBEAT_TICK_NS,10000)) - -# HEARTBEAT_CHECK_FREQUENCY / HEARTBEAT_WINDOW_TUNING_FREQUENCY / -# HEARTBEAT_SLOPE_VALIDATION_FREQUENCY: previously unwired in the hosted -# Makefile -- no `?=` and no -D forwarding existed for any of these three -# before Phase 4, so hosted builds always got starforth_config.h's bare -# defaults (256/1000/5000) with no override mechanism at all. The kernel -# Makefile has always had opt-in forwarding for them (VM_FEATURE_FLAG_VARS). -# Promoted here for parity, same treatment as Phase 3's SSM_* knobs. -$(eval $(call kconfig_int,HEARTBEAT_CHECK_FREQUENCY,256)) -$(eval $(call kconfig_int,HEARTBEAT_WINDOW_TUNING_FREQUENCY,1000)) -$(eval $(call kconfig_int,HEARTBEAT_SLOPE_VALIDATION_FREQUENCY,5000)) - -# HISTORICAL: L4Re had no pthreads, so this forced HEARTBEAT_THREAD_ENABLED -# off whenever L4RE=1 was set. L4Re support is no longer an active target; -# see "Platform support" below. -# ifeq ($(L4RE),1) -# HEARTBEAT_THREAD_ENABLED := 0 -# endif - -# Feedback Loop Toggle Switches (for systematic performance measurement) -# ============================================================================ -# These allow turning each feedback loop on/off to measure additive performance gains -# EXP_00-BASELINE: all loops OFF (plain FORTH-79) -# EXP_01: Loop #1 ON -# EXP_02: Loops #1-2 ON -# ... etc, building cumulatively to measure each loop's contribution - -# ============================================================================== -# SSM (Steady State Machine) Configuration - Data-Driven Architecture -# ============================================================================== -# Based on 2^7 DoE with 300 reps (128 configs, 38,400 runs). -# Top 5% analysis (speed + stability) reveals optimal loop combinations. -# -# Experimentally Validated Architecture: -# L1 (heat_tracking): DISABLED (harmful in 86% of top configs) -# L4 (pipelining_metrics): DISABLED (harmful in 100% of top configs) -# L7 (adaptive_heartrate): ALWAYS ON (beneficial in 71% of top configs) -# L2, L3, L5, L6: Runtime-controlled by L8 (workload-dependent) -# L8 (Jacquard): 4-bit mode selector (16 modes: C0-C15) -# -# L8 dynamically controls L2/L3/L5/L6 based on entropy, CV, and temporal metrics. -# Top 5% validated modes: C4, C7, C9, C11, C12 (see src/ssm_jacquard.c) - -# Tuning Knobs (Physics-driven Optimization System) -# ============================================================================ -# Knob #7: ROLLING_WINDOW_SIZE (Initial execution history capture) -# - Default: 4096 (conservative, ensures statistical significance at cold start) -# - Usage: make ROLLING_WINDOW_SIZE=8192 (larger for complex workloads) -# or ROLLING_WINDOW_SIZE=2048 (smaller for memory constraints) -# - System AUTOMATICALLY shrinks during execution if diminishing returns detected -# - Window starts conservative, self-tunes down if pattern diversity plateaus -# - Window becomes "warm" (representative) after N executions, then adapts -$(eval $(call kconfig_int,ROLLING_WINDOW_SIZE,4096)) - -# Knob #6: TRANSITION_WINDOW_SIZE (Pipelining context depth) -# - Default: 8 (see starforth_config.h for the exact shipped value) -# - Usage: make TRANSITION_WINDOW_SIZE=1 (or 2, 4 for shallower context) -# - Empirically tuned via binary chop: 1 vs 2 vs 4 vs 8 -$(eval $(call kconfig_int,TRANSITION_WINDOW_SIZE,8)) - -# SPECULATION_THRESHOLD_Q48 / SPECULATION_DEPTH / MIN_SAMPLES_FOR_SPECULATION / -# MISPREDICTION_COST_Q48 / MINIMUM_PREFETCH_ROI: previously hardcoded, -# non-overridable #define in physics_pipelining_metrics.h -- no Makefile -# knob or -D forwarding existed for any of these five before Phase 5. -# Promoted here for parity, same treatment as Phase 3/4's other -# previously-unwired constants. All five are Q48.16-fixed-point or plain -# counts meaningful only when ENABLE_PIPELINING is on; see Kconfig.physics -# for the exact hex/decimal defaults. MINIMUM_PREFETCH_ROI's default was -# corrected from the long-shipped 0x11999A to 0x1199A (rev y) -- the -# former was ~17.6 in Q48.16, not the documented 1.10. -$(eval $(call kconfig_int,SPECULATION_THRESHOLD_Q48,0x8000)) -$(eval $(call kconfig_int,SPECULATION_DEPTH,1)) -$(eval $(call kconfig_int,MIN_SAMPLES_FOR_SPECULATION,10)) -$(eval $(call kconfig_int,MISPREDICTION_COST_Q48,0x190000)) -$(eval $(call kconfig_int,MINIMUM_PREFETCH_ROI,0x1199A)) - -# Knobs #8-11: Adaptive Window Shrinking Control -# ============================================================================ -# These control how aggressively the rolling window learns and adapts -# (NOT the initial window size - that's ROLLING_WINDOW_SIZE above) - -# Knob #8: ADAPTIVE_SHRINK_RATE (percentage to retain when shrinking) -# - Default: 50 (shrink to 50% = discard 50% each cycle) -# - Range: 50-95 (lower = more aggressive, higher = more conservative) -# - Usage: make ADAPTIVE_SHRINK_RATE=75 (slower learning) or 90 (slow learning) -$(eval $(call kconfig_int,ADAPTIVE_SHRINK_RATE,50)) - -# Knob #9: ADAPTIVE_MIN_WINDOW_SIZE (floor to prevent over-shrinking) -# - Default: 256 (never shrink below 256 word IDs) -# - Range: 64-1024 (smaller = leaner, larger = safer) -# - Usage: make ADAPTIVE_MIN_WINDOW_SIZE=512 (conservative) or 128 (lean) -$(eval $(call kconfig_int,ADAPTIVE_MIN_WINDOW_SIZE,256)) - -# Knob #10: ADAPTIVE_CHECK_FREQUENCY (how often to measure diversity) -# - Default: 512 (check after every 512 executions) -# - Range: 32-1024 (more = faster response, less = less overhead) -# - Usage: make ADAPTIVE_CHECK_FREQUENCY=128 (responsive) or 256 (default of comparable knobs) -$(eval $(call kconfig_int,ADAPTIVE_CHECK_FREQUENCY,512)) - -# Knob #11: ADAPTIVE_GROWTH_THRESHOLD (growth rate that signals saturation) -# - Default: 5 (shrink when growth < 5%) -# - Range: 0-10 (lower = eager shrinking, higher = cautious) -# - Usage: make ADAPTIVE_GROWTH_THRESHOLD=0 (aggressive) or 1 (less conservative) -$(eval $(call kconfig_int,ADAPTIVE_GROWTH_THRESHOLD,5)) - -# Knob #11a: INITIAL_DECAY_SLOPE_Q48 (Starting decay slope for inference engine) -# - Default: 21845 (1/3 in Q48.16 format, = 0.333... starting slope) -# - Range: 13107-43691 (0.2 to 0.67 in Q48.16) -# - Usage: make INITIAL_DECAY_SLOPE_Q48=13107 (0.2) or 32768 (0.5) or 43691 (0.67) -# - DoE: OPP #3 tests 0.2, 0.33, 0.5, 0.67 to find optimal starting point for convergence -# - Note: Inference engine adapts this value at runtime; this is just the cold-start value -$(eval $(call kconfig_int,INITIAL_DECAY_SLOPE_Q48,21845)) - -# Knob #11b: DECAY_MIN_INTERVAL (Minimum time before decay applies) -# - Default: 500 (nanoseconds) -# - Range: 500-5000 (balance between decay sensitivity and overhead) -# - Usage: make DECAY_MIN_INTERVAL=1000 (slower decay) or 2000 (slower still) -# - NOTE: as of the tick-based Loop #3 decay conversion (rev t, see -# docs/working/architecture/VM-FLEET-ATTRACTOR-DESIGN-20260705.md), -# Loop #3 no longer consults this value at all -- decay is gated on -# elapsed heartbeat ticks, not elapsed nanoseconds. Kept only because -# doe_metrics.c still reports it as a metrics field; informational, -# not load-bearing. -$(eval $(call kconfig_int,DECAY_MIN_INTERVAL,500)) - -# Knob #11d: HEARTBEAT_INFERENCE_FREQUENCY (How often to run inference engine) -# - Default: 1000 (ticks between inference runs) -# - Set VERY HIGH (999999) to effectively disable inference (static mode) -# - Set LOW for frequent inference (adaptive mode) -# - DoE: OPP #3 tests 999999 (static, no Loop #6) vs 1000 (adaptive, with Loop #6) -# - Measures: Inference engine cost vs benefit in optimized performance -$(eval $(call kconfig_int,HEARTBEAT_INFERENCE_FREQUENCY,1000)) - -# Knob #12: DECAY_RATE_PER_US_Q16 (Heat decay rate in Q16 fixed-point) -# - Default: 1 (1/65536 heat units decayed per microsecond) -# - Range: 0-65536 (0 = no decay, 65536 = 1 heat/ยตs) -# - Half-life: ~6.5 seconds at default (100-heat word โ†’ 50-heat in 6.5s) -# - Usage: make DECAY_RATE_PER_US_Q16=2 (faster decay) or 0 (no decay for baseline) -# - DoE: Vary this to measure impact of heat decay on performance -$(eval $(call kconfig_int,DECAY_RATE_PER_US_Q16,1)) - -# L8 Jacquard mode selector thresholds (ssm_jacquard.h). Previously unwired -- -# no Makefile knob or -D forwarding existed for these before the Kconfig -# migration's Phase 3; ssm_jacquard.h's own #ifndef fallback was the only -# place any of these five values lived. See Kconfig.physics for the -# rationale behind modeling the four float thresholds as Kconfig `string` -# symbols (Kconfig has no native float type). -$(eval $(call kconfig_int,SSM_ENTROPY_HIGH_THRESHOLD,0.75)) -$(eval $(call kconfig_int,SSM_CV_HIGH_THRESHOLD,0.15)) -$(eval $(call kconfig_int,SSM_TEMPORAL_DECAY_THRESHOLD,0.5)) -$(eval $(call kconfig_int,SSM_TEMPORAL_DECAY_LOW_THRESHOLD,0.3)) -$(eval $(call kconfig_int,SSM_HYSTERESIS_TICKS,5)) - -# Build the CFLAGS with tuning knobs -# L8 FINAL INTEGRATION: All experimental loop flags removed. -# L1-L7 are now always-on internal physics layers. -# L8 Jacquard mode selector is the sole policy engine. -BASE_CFLAGS = -std=c99 -Wall -Werror -Iinclude -Isrc/word_source -Isrc/test_runner/include \ - -DSTRICT_PTR=$(STRICT_PTR) \ - -DENABLE_HOTWORDS_CACHE=$(ENABLE_HOTWORDS_CACHE) \ - -DENABLE_PIPELINING=$(ENABLE_PIPELINING) \ - -DROLLING_WINDOW_SIZE=$(ROLLING_WINDOW_SIZE) \ - -DTRANSITION_WINDOW_SIZE=$(TRANSITION_WINDOW_SIZE) \ - -DSPECULATION_THRESHOLD_Q48=$(SPECULATION_THRESHOLD_Q48) \ - -DSPECULATION_DEPTH=$(SPECULATION_DEPTH) \ - -DMIN_SAMPLES_FOR_SPECULATION=$(MIN_SAMPLES_FOR_SPECULATION) \ - -DMISPREDICTION_COST_Q48=$(MISPREDICTION_COST_Q48) \ - -DMINIMUM_PREFETCH_ROI=$(MINIMUM_PREFETCH_ROI) \ - -DADAPTIVE_SHRINK_RATE=$(ADAPTIVE_SHRINK_RATE) \ - -DADAPTIVE_MIN_WINDOW_SIZE=$(ADAPTIVE_MIN_WINDOW_SIZE) \ - -DADAPTIVE_CHECK_FREQUENCY=$(ADAPTIVE_CHECK_FREQUENCY) \ - -DADAPTIVE_GROWTH_THRESHOLD=$(ADAPTIVE_GROWTH_THRESHOLD) \ - -DINITIAL_DECAY_SLOPE_Q48=$(INITIAL_DECAY_SLOPE_Q48) \ - -DDECAY_RATE_PER_US_Q16=$(DECAY_RATE_PER_US_Q16) \ - -DHEARTBEAT_THREAD_ENABLED=$(HEARTBEAT_THREAD_ENABLED) \ - -DHEARTBEAT_TICK_NS=$(HEARTBEAT_TICK_NS) \ - -DHEARTBEAT_INFERENCE_FREQUENCY=$(HEARTBEAT_INFERENCE_FREQUENCY) \ - -DHEARTBEAT_CHECK_FREQUENCY=$(HEARTBEAT_CHECK_FREQUENCY) \ - -DHEARTBEAT_WINDOW_TUNING_FREQUENCY=$(HEARTBEAT_WINDOW_TUNING_FREQUENCY) \ - -DHEARTBEAT_SLOPE_VALIDATION_FREQUENCY=$(HEARTBEAT_SLOPE_VALIDATION_FREQUENCY) \ - -DEMERGENCY_CONSOLE_ENABLED=$(EMERGENCY_CONSOLE_ENABLED) \ - -DSSM_ENTROPY_HIGH_THRESHOLD=$(SSM_ENTROPY_HIGH_THRESHOLD) \ - -DSSM_CV_HIGH_THRESHOLD=$(SSM_CV_HIGH_THRESHOLD) \ - -DSSM_TEMPORAL_DECAY_THRESHOLD=$(SSM_TEMPORAL_DECAY_THRESHOLD) \ - -DSSM_TEMPORAL_DECAY_LOW_THRESHOLD=$(SSM_TEMPORAL_DECAY_LOW_THRESHOLD) \ - -DSSM_HYSTERESIS_TICKS=$(SSM_HYSTERESIS_TICKS) - -ifeq ($(HEARTBEAT_THREAD_ENABLED),1) -# HISTORICAL: this used to branch on L4RE (no pthreads there) -- -# THREAD_FLAGS := if L4RE else -pthread. L4Re support is no longer an -# active target; see "Platform support" below. -THREAD_FLAGS := -pthread -else -THREAD_FLAGS := -endif - -BASE_CFLAGS += $(THREAD_FLAGS) - -# Build profiles (TARGET values) -SUPPORTED_TARGETS := standard fast fastest turbo asan - -TARGET_DESCRIPTION_standard := Standard optimized build -TARGET_CFLAGS_standard := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O2 -flto=auto -fuse-linker-plugin -DNDEBUG \ - -DUSE_ASM_OPT=1 \ - -ffunction-sections -fdata-sections -fomit-frame-pointer \ - -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-strict-aliasing -TARGET_LDFLAGS_standard := -Wl,--gc-sections -s -flto=auto -fuse-linker-plugin -static $(THREAD_FLAGS) - -TARGET_DESCRIPTION_fast := Fast optimized build (no LTO, easier debugging) -TARGET_CFLAGS_fast := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -TARGET_LDFLAGS_fast := -s $(THREAD_FLAGS) - -TARGET_DESCRIPTION_fastest := Maximum performance build (ASM + LTO + direct threading) -TARGET_CFLAGS_fastest := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG \ - -flto=auto -fuse-linker-plugin -funroll-loops -finline-functions -fomit-frame-pointer -fno-plt -fno-semantic-interposition -TARGET_LDFLAGS_fastest := -flto=auto -fuse-linker-plugin -s -Wl,--gc-sections $(THREAD_FLAGS) - -TARGET_DESCRIPTION_turbo := Assembly-optimized build (no direct threading) -TARGET_CFLAGS_turbo := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O3 -DUSE_ASM_OPT=1 -DNDEBUG -flto -TARGET_LDFLAGS_turbo := -flto -s $(THREAD_FLAGS) - -TARGET_DESCRIPTION_asan := ASan/UBSan instrumented build for memory error detection -TARGET_CFLAGS_asan := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O1 -g \ - -fsanitize=address,undefined -fno-omit-frame-pointer -TARGET_LDFLAGS_asan := -fsanitize=address,undefined $(THREAD_FLAGS) - -define TARGET_POST_fastest - @echo "" - @echo "๐ŸŽฏ You've built the FASTEST FORTH IN THE WEST!" - @echo "" - @echo "Quick-draw benchmark:" - @time -f " โฑ๏ธ Time: %E seconds" ./$(BINARY) -c ": BENCH 1000000 0 DO 1 2 + DROP LOOP ; BENCH BYE" 2>/dev/null || true -endef - -TARGET_DESCRIPTION := $(TARGET_DESCRIPTION_$(TARGET)) -ifeq ($(strip $(TARGET_DESCRIPTION)),) - $(error Unknown TARGET '$(TARGET)'. Supported targets: $(SUPPORTED_TARGETS)) -endif - -TARGET_CFLAGS_SELECTED := $(TARGET_CFLAGS_$(TARGET)) -TARGET_LDFLAGS_SELECTED := $(TARGET_LDFLAGS_$(TARGET)) -TARGET_POST := $(or $(TARGET_POST_$(TARGET)),@:) - -CFLAGS ?= $(TARGET_CFLAGS_SELECTED) -LDFLAGS ?= $(TARGET_LDFLAGS_SELECTED) - -CFLAGS += $(EXTRA_CFLAGS) -LDFLAGS += $(EXTRA_LDFLAGS) - -USE_ASM_OPT := $(if $(findstring -DUSE_ASM_OPT=1,$(CFLAGS)),1,0) -USE_LTO := $(if $(or $(findstring -flto,$(CFLAGS)),$(findstring -flto,$(LDFLAGS))),1,0) - -# Platform support -# -# HISTORICAL: L4Re/Fiasco.OC was a supported platform target (`make L4RE=1`) -# through mid-2026. Removed as an active target; src/platform/l4re/time.c -# is retained for reference but no longer wired into any build. To restore: -# reinstate the `else ifdef L4RE` branch below and the L4RE-conditional -# logic marked HISTORICAL elsewhere in this Makefile (search "L4RE"/"L4Re"). -# -# ifdef MINIMAL -# ... -# else ifdef L4RE -# CFLAGS += -D__l4__=1 -# PLATFORM_TIME_SRC = src/platform/l4re/time.c src/platform/platform_init.c -# PLATFORM_ALLOC_SRC = src/platform/alloc_kernel.c -# else -# ... -# endif -ifdef MINIMAL -# DISABLED 2026-07-08: this was never a finished feature, not a small bug. -# src/platform/starforth_minimal.c (referenced below) does not exist -# anywhere in the repo, and only 5 of ~90 source files under src/ have any -# STARFORTH_MINIMAL awareness despite -nostdlib -ffreestanding applying to -# the entire tree. Confirmed by trying it: even a throwaway empty stub for -# the missing file lets the build report "success" while linking a binary -# with no _start entry point (this build's specific -nostdlib/-static/ -# -pthread/-flto flag combination doesn't actually exclude libc, so most -# calls silently resolve anyway -- the illusion of success is the trap). -# Reviving this needs an actual freestanding platform layer written from -# scratch, not a quick fix -- failing loudly here instead of letting -# anyone hit a confusing compile error or, worse, a binary that "builds" -# but can't run. See .claude/CLAUDE.md's punch list for status. -$(error MINIMAL=1 build is disabled: incomplete freestanding platform layer, not currently supported. See the comment immediately above this line for why) -CFLAGS += -DSTARFORTH_MINIMAL=1 -nostdlib -ffreestanding -LDFLAGS += -nostdlib -PLATFORM_SRC = src/platform/starforth_minimal.c -PLATFORM_ALLOC_SRC = src/platform/alloc_kernel.c -else -PLATFORM_TIME_SRC = src/platform/linux/time.c src/platform/linux/io.c src/platform/platform_init.c -PLATFORM_ALLOC_SRC = src/platform/alloc_host.c -endif - -PLATFORM_COMMON_SRC = src/platform/threading.c $(PLATFORM_ALLOC_SRC) - -# Source and object files -SRC = $(wildcard src/*.c src/word_source/*.c src/test_runner/*.c src/test_runner/modules/*.c) $(PLATFORM_SRC) $(PLATFORM_TIME_SRC) $(PLATFORM_COMMON_SRC) -BUILD_ROOT ?= build -build_dir = $(BUILD_ROOT)/$(call canon_arch,$(or $2,$(ARCH)))/$1 -binary_path = $(call build_dir,$1,$2)/starforth -BUILD_DIR = $(call build_dir,$(TARGET),$(ARCH)) -BINARY = $(call binary_path,$(TARGET),$(ARCH)) -OBJ = $(patsubst src/%.c,$(BUILD_DIR)/%.o,$(SRC)) -ASM_FILES = $(patsubst src/%.c,$(BUILD_DIR)/%.s,$(SRC)) - -# Profiler support for test targets -PROFILE_LEVEL := $(strip $(PROFILE)) -ifeq ($(PROFILE_LEVEL),) -PROFILE_ARGS := -else -PROFILE_ARGS := --profile $(PROFILE_LEVEL) -PROFILE_REPORT ?= 1 -ifneq ($(strip $(PROFILE_REPORT)),0) -PROFILE_ARGS += --profile-report -endif -endif - -# Installation directories -PREFIX ?= . -BINDIR = $(PREFIX)/bin -MANDIR = $(PREFIX)/share/man/man1 -INFODIR = $(PREFIX)/share/info -DOCDIR = $(PREFIX)/share/doc/starforth -CONFDIR = $(PREFIX)/etc/starforth - -# ============================================================================== -# PHONY TARGETS -# ============================================================================== - -.PHONY: all banner help clean clean-obj clean-docs starkernel mkcapsule capsule-gen capsule-manifest -.PHONY: fastest fast turbo -.PHONY: rpi4 rpi4-cross rpi4-fastest riscv64-clang -.PHONY: minimal debug profile performance -.PHONY: test bench benchmark -.PHONY: asm sbom -.PHONY: docs api-docs docs-latex docs-isabelle isabelle-build isabelle-check info math-companion math-companion-clean -.PHONY: refinement-status refinement-init refinement-phase1 verify-defect refinement-annotate-check refinement-report -.PHONY: install uninstall package deb rpm -.PHONY: quality compile_commands clang_tidy cppcheck gcc_analyzer -.PHONY: FORCE version-info build-manifest - -# ============================================================================== -# MAIN TARGETS -# ============================================================================== - -all: banner $(BINARY) - @echo "" - @echo "โœ“ Build complete: $(BINARY)" - @echo " Architecture: $(ARCH_NAME)" - @echo " Profile: $(TARGET_DESCRIPTION) ($(TARGET))" - @echo " Output directory: $(BUILD_DIR)" - @echo " Optimizations: $(if $(findstring USE_ASM_OPT,$(CFLAGS)),Enabled,Disabled)" - @echo " Direct Threading: $(if $(findstring USE_DIRECT_THREADING,$(CFLAGS)),Enabled,Disabled)" - @mkdir -p lfs/$(ARCH_DIR) - @cp $(BINARY) lfs/$(ARCH_DIR)/starforth - @echo " LFS copy: lfs/$(ARCH_DIR)/starforth" - $(TARGET_POST) - -banner: - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo " โšก Building the Fastest Forth in the West! โšก" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo " Target Architecture: $(ARCH_NAME) ($(ARCH_DIR))" - @echo " Build Profile: $(TARGET_DESCRIPTION) ($(TARGET))" - @echo "" - -# ============================================================================== -# OPTIMIZATION BUILDS - The Fastest in the West -# ============================================================================== - -# Maximum performance - no compromises -fastest: - @echo "๐Ÿ† Building FASTEST configuration..." - @echo " - Architecture: $(ARCH_NAME)" - @echo " - Assembly optimizations: ENABLED" - @echo " - Direct threading: ENABLED" - @echo "" - @$(MAKE) TARGET=fastest all - -# Fast without LTO (easier debugging) -fast: - @echo "โšก Building FAST configuration (no LTO for debugging)..." - @$(MAKE) TARGET=fast all - -# Assembly optimizations only (no direct threading) -turbo: - @echo "๐Ÿš€ Building TURBO configuration (ASM only)..." - @$(MAKE) TARGET=turbo all - -# ============================================================================== -# PLATFORM-SPECIFIC BUILDS -# ============================================================================== - -# Raspberry Pi 4 - native build -rpi4: - @echo "๐Ÿฅง Building for Raspberry Pi 4 (native)..." - @$(MAKE) ARCH=raspi TARGET=fastest CFLAGS="$(BASE_CFLAGS) -march=armv8-a+crc+simd -mtune=cortex-a72 -DARCH_ARM64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto" LDFLAGS="-flto -s" all - @echo "โœ“ Raspberry Pi build ready: $(call binary_path,fastest,raspi)" - -# Raspberry Pi 4 - cross-compile from x86_64 -rpi4-cross: - @echo "๐Ÿฅง Cross-compiling for Raspberry Pi 4..." - @$(MAKE) ARCH=raspi TARGET=fastest CC=aarch64-linux-gnu-gcc \ - CFLAGS="$(BASE_CFLAGS) -march=armv8-a+crc+simd -mtune=cortex-a72 -DARCH_ARM64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto -static" \ - LDFLAGS="-flto -s -static" \ - all - @echo "โœ“ Cross-compiled binary ready: $(call binary_path,fastest,raspi)" - @echo " Copy to RPi4: scp $(call binary_path,fastest,raspi) pi@raspberrypi.local:~/" - -# Raspberry Pi 4 - maximum optimization -rpi4-fastest: - @echo "๐Ÿฅงโšก Building FASTEST for Raspberry Pi 4..." - @$(MAKE) ARCH=raspi TARGET=fastest CC=aarch64-linux-gnu-gcc \ - CFLAGS="$(BASE_CFLAGS) -march=armv8-a+crc+simd+crypto -mtune=cortex-a72 -DARCH_ARM64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto -funroll-loops -finline-functions" \ - LDFLAGS="-flto -s -static" \ - all - @echo "โœ“ Raspberry Pi FASTEST build ready: $(call binary_path,fastest,raspi)" - -# RISC-V 64 - cross-compile via clang (GCC fails to build this tree under -# -std=c99: a nanosleep visibility failure, not yet root-caused โ€” see -# docs/lithosananke/hosted-acceptance-test/README.md and -# docs/working/archive/session-logs/2026-07-24-punch-list.md item #3). -# CFLAGS deliberately does NOT reuse $(BASE_CFLAGS): BASE_CFLAGS hardcodes -# -std=c99, and clang needs -std=c11 -pthread here. This mirrors the exact -# recipe verified in the hosted-acceptance-test doc, kept in sync with it. -riscv64-clang: - @echo "๐Ÿฆ€ Cross-compiling for RISC-V 64 (clang)..." - @$(MAKE) ARCH=riscv64 TARGET=fastest \ - CC="clang-18 --target=riscv64-linux-gnu --sysroot=/usr/riscv64-linux-gnu" \ - CFLAGS="-std=c11 -pthread -Wall -Werror -Iinclude -Isrc/word_source -Isrc/test_runner/include -DSTRICT_PTR=1 -march=rv64gc -mabi=lp64d -mcmodel=medany -DARCH_RISCV64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto -static" \ - LDFLAGS="-flto -s -static -fuse-ld=lld" \ - all - @echo "โœ“ Cross-compiled binary ready: $(call binary_path,fastest,riscv64)" - @echo " Run: qemu-riscv64 $(call binary_path,fastest,riscv64)" - -# Minimal/embedded build -minimal: - $(MAKE) MINIMAL=1 - -# HISTORICAL: L4Re support removed as an active target (see "Platform -# support" above). This target cross-compiled a minimal build with the -# L4Re toolchain (l4-gcc) for smoke-testing without real L4Re headers. -# fake-l4re: -# $(MAKE) MINIMAL=1 CC=l4-gcc CFLAGS="$(BASE_CFLAGS) -DL4RE_TARGET=1" - -# ============================================================================== -# DEBUG & DEVELOPMENT BUILDS -# ============================================================================== - -# Debug build with symbols -debug: banner - @echo "๐Ÿ› Building DEBUG configuration..." - $(MAKE) CFLAGS="$(BASE_CFLAGS) -O0 -g -DDEBUG" LDFLAGS="" $(BINARY) - -# Build with profiler support -profile: - $(MAKE) CFLAGS="$(BASE_CFLAGS) -g -O1" $(BINARY) - -# Performance build (legacy alias - redirects to 'fastest') -performance: fastest - -# ============================================================================== -# BUILD RULES -# ============================================================================== - -# Generate version header from Makefile VERSION, ARCH, TARGET, and timestamp -include/version.h: FORCE - @mkdir -p include - @echo "Generating version header..." - @BUILD_TS=$$(date -Iseconds 2>/dev/null || echo "unknown"); \ - printf '#ifndef STARFORTH_VERSION_H\n#define STARFORTH_VERSION_H\n\n' > $@; \ - printf '#define STARFORTH_VERSION "%s"\n' "$(VERSION)" >> $@; \ - printf '#define STARFORTH_ARCH "%s"\n' "$(ARCH_NAME)" >> $@; \ - printf '#define STARFORTH_TARGET "%s"\n' "$(TARGET)" >> $@; \ - printf '#define STARFORTH_TIMESTAMP "%s"\n' "$$BUILD_TS" >> $@; \ - printf '#define STARFORTH_VERSION_FULL "StarForth v%s %s %s %s"\n\n' "$(VERSION)" "$(ARCH_NAME)" "$(TARGET)" "$$BUILD_TS" >> $@; \ - printf '#endif /* STARFORTH_VERSION_H */\n' >> $@ - -# Ensure version.h exists and is up-to-date before compilation -FORCE: - -# ============================================================================== -# CAPSULE SUBSYSTEM -# ============================================================================== - -CAPSULES_DIR ?= capsules -MKCAPSULE_SRC = tools/mkcapsule.c -MKCAPSULE_BIN = $(BUILD_DIR)/tools/mkcapsule -CAPSULE_GENERATED = $(BUILD_DIR)/capsule_generated.c -CAPSULE_GENERATED_OBJ = $(BUILD_DIR)/capsule_generated.o -CAPSULE_MANIFEST = $(CAPSULES_DIR)/MANIFEST_AUTO.md - -# Build the mkcapsule host tool -$(MKCAPSULE_BIN): $(MKCAPSULE_SRC) - @mkdir -p $(dir $@) - @echo " HOSTCC $<" - @$(CC) -O2 -Wall -o $@ $< - -# Run mkcapsule to generate the capsule directory C source -$(CAPSULE_GENERATED): $(MKCAPSULE_BIN) $(CAPSULES_DIR) - @mkdir -p $(dir $@) - @echo " MKCAP $(CAPSULES_DIR) -> $@" - @$(MKCAPSULE_BIN) $(CAPSULES_DIR) $@ - -# Compile the generated capsule directory -$(CAPSULE_GENERATED_OBJ): $(CAPSULE_GENERATED) | include/version.h - @mkdir -p $(dir $@) - @echo " CC $<" - @$(CC) $(CFLAGS) -c $< -o $@ - -.PHONY: mkcapsule capsule-gen capsule-manifest -mkcapsule: $(MKCAPSULE_BIN) -capsule-manifest: $(MKCAPSULE_BIN) - @echo " MANIFEST $(CAPSULES_DIR) -> $(CAPSULE_MANIFEST)" - @$(MKCAPSULE_BIN) --manifest $(CAPSULES_DIR) $(CAPSULE_MANIFEST) -capsule-gen: $(CAPSULE_GENERATED) capsule-manifest - -# starkernel: full capsule-aware build -# 1. Build mkcapsule tool -# 2. Generate capsule_generated.c from capsules/ -# 3. Compile StarForth with __STARKERNEL__ and capsule_generated.o linked in -starkernel: $(MKCAPSULE_BIN) $(CAPSULE_GENERATED_OBJ) - @$(MAKE) $(BINARY) \ - EXTRA_CFLAGS="-D__STARKERNEL__=1 -Iinclude" \ - EXTRA_OBJ="$(CAPSULE_GENERATED_OBJ)" - -# ============================================================================== -# Main executable -$(BINARY): $(OBJ) $(EXTRA_OBJ) - @echo "๐Ÿ”— Linking $(BINARY)..." - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) - -# Pattern rule for all C files (consolidates 5 repetitive rules) -# Order-only dependency: version.h must exist before compilation, but changes don't trigger rebuild -$(BUILD_DIR)/%.o: src/%.c | include/version.h - @mkdir -p $(dir $@) - @echo " CC $<" - @$(CC) $(CFLAGS) -c $< -o $@ -ifdef ASM - @$(CC) $(CFLAGS) -S $(ASM_SYNTAX) $< -o $(patsubst %.o,%.s,$@) -endif - -# Files that include version.h - rebuild when timestamp changes -$(BUILD_DIR)/main.o: include/version.h -$(BUILD_DIR)/cli.o: include/version.h -$(BUILD_DIR)/word_source/starforth_words.o: include/version.h - -# ============================================================================== -# TESTING & BENCHMARKING -# ============================================================================== - -# Quick benchmark -bench: $(BINARY) - @echo "" - @echo "๐Ÿ‡ Running quick-draw benchmark..." - @echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" - @echo "Test: 1 million stack operations" - @time -f "Time: %E seconds" ./$(BINARY) -c ": BENCH 1000000 0 DO 1 2 + DROP LOOP ; BENCH BYE" 2>/dev/null || echo "Benchmark complete" - @echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" - -# Full benchmark suite -benchmark: $(BINARY) - @echo "" - @echo "๐ŸŽฏ Full Benchmark Suite - Fastest Forth in the West" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo "" - @echo "๐Ÿ“Š Stack Operations (1M iterations):" - @time -f " โฑ๏ธ %E seconds" ./$(BINARY) -c ": BENCH-STACK 1000000 0 DO 1 2 3 DROP DROP DROP LOOP ; BENCH-STACK BYE" 2>/dev/null || true - @echo "" - @echo "๐Ÿ“Š Arithmetic Operations (1M iterations):" - @time -f " โฑ๏ธ %E seconds" ./$(BINARY) -c ": BENCH-MATH 1000000 0 DO 10 20 + 5 * 100 / DROP LOOP ; BENCH-MATH BYE" 2>/dev/null || true - @echo "" - @echo "๐Ÿ“Š Logic Operations (1M iterations):" - @time -f " โฑ๏ธ %E seconds" ./$(BINARY) -c ": BENCH-LOGIC 1000000 0 DO 255 DUP AND DUP OR XOR DROP LOOP ; BENCH-LOGIC BYE" 2>/dev/null || true - @echo "" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - -# ============================================================================== -# ASSEMBLY OUTPUT & ANALYSIS -# ============================================================================== - -# Generate assembly files for inspection -asm: banner - @echo "๐Ÿ“ Generating assembly output..." - @echo " Cleaning to force rebuild..." - @$(MAKE) clean-obj > /dev/null 2>&1 - $(MAKE) ASM=1 CFLAGS="$(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1" LDFLAGS="" $(BINARY) - @echo "โœ“ Assembly files generated in $(BUILD_DIR)/" - @echo " Files generated: $$(find $(BUILD_DIR) -name '*.s' | wc -l)" - @echo " Example: less $(BUILD_DIR)/stack_management.s" - -# Generate Software Bill of Materials (SBOM) in SPDX format -sbom: - @echo "๐Ÿ“‹ Generating SBOM (Software Bill of Materials)..." - @if ! which syft >/dev/null 2>&1; then \ - echo "Error: syft not found. Install from https://github.com/anchore/syft"; \ - exit 1; \ - fi - @syft dir:. -o spdx-json=sbom.spdx.json -o spdx=sbom.spdx \ - --source-name LithosAnanke \ - --source-version $(VERSION) \ - --exclude './build/**' --exclude './tools/**' --exclude './.git/**' - @echo "โœ… SBOM generated:" - @echo " SPDX JSON: sbom.spdx.json" - @echo " SPDX: sbom.spdx" - @echo " Version: $(VERSION)" - -# ============================================================================== -# DOCUMENTATION -# ============================================================================== - -# Generate API documentation (Doxygen XML โ†’ AsciiDoc) -api-docs: - @echo "๐Ÿ“š Generating API documentation from Doxygen..." - @if [ ! -f scripts/generate-doxygen-appendix.sh ]; then \ - echo "Error: scripts/generate-doxygen-appendix.sh not found"; \ - exit 1; \ - fi - @./scripts/generate-doxygen-appendix.sh - @echo "โœ… API documentation generated: docs/src/appendix/" - -# ---------------------------------------------------------------------------- -# Math companion to the SSRN paper. -# Builds docs/SSRN_companion/Math_Companion_SSRN.pdf from the LaTeX source. -# Requires: pdflatex (texlive-latex-base, texlive-latex-extra, texlive-science). -# ---------------------------------------------------------------------------- -math-companion: - @echo "Building SSRN math companion (docs/SSRN_companion/Math_Companion_SSRN.pdf)..." - @if ! command -v pdflatex >/dev/null 2>&1; then \ - echo "Error: pdflatex not found."; \ - echo " Install with: apt-get install texlive-latex-base texlive-latex-extra texlive-science"; \ - exit 1; \ - fi - @cd docs/SSRN_companion && \ - pdflatex -interaction=nonstopmode -halt-on-error Math_Companion_SSRN.tex >/dev/null && \ - pdflatex -interaction=nonstopmode -halt-on-error Math_Companion_SSRN.tex >/dev/null && \ - pdflatex -interaction=nonstopmode -halt-on-error Math_Companion_SSRN.tex >/dev/null - @echo "Built: docs/SSRN_companion/Math_Companion_SSRN.pdf" - @cd docs/SSRN_companion && ls -lh Math_Companion_SSRN.pdf | awk '{print " Size:", $$5, " Pages: see pdfinfo"}' - -math-companion-clean: - @rm -f docs/SSRN_companion/Math_Companion_SSRN.{aux,log,out,toc,lof,lot,nav,snm,vrb} - @rm -f docs/SSRN_companion/Math_Companion_SSRN.pdf - @echo "Cleaned math companion build artifacts." - -# Convert all AsciiDoc to LaTeX -docs-latex: - @echo "๐Ÿ“„ Converting AsciiDoc to LaTeX..." - @if [ ! -f scripts/asciidoc-to-latex.sh ]; then \ - echo "Error: scripts/asciidoc-to-latex.sh not found"; \ - exit 1; \ - fi - @./scripts/asciidoc-to-latex.sh - @echo "โœ… LaTeX files generated: docs/latex/" - -# Build and verify Isabelle theories -isabelle-build: - @echo "๐Ÿ”ฌ Building Isabelle formal verification theories..." - @if ! command -v $(ISABELLE) >/dev/null 2>&1; then \ - echo "Error: Isabelle not found: $(ISABELLE)"; \ - echo " Install Isabelle or set ISABELLE variable"; \ - exit 1; \ - fi - @echo " Using: $$(command -v $(ISABELLE))" - @echo " Building StarForth_Formal session (VM + Physics)..." - @cd docs/src/internal/formal && $(ISABELLE) build -v -d . StarForth_Formal - @echo "โœ… Isabelle theories verified successfully" - -# Quick check of Isabelle theories (faster than full build) -isabelle-check: - @echo "๐Ÿ”ฌ Quick-checking Isabelle theories..." - @if ! command -v $(ISABELLE) >/dev/null 2>&1; then \ - echo "Error: Isabelle not found: $(ISABELLE)"; \ - exit 1; \ - fi - @cd docs/src/internal/formal && \ - for thy in *.thy; do \ - echo " Checking $$thy..."; \ - $(ISABELLE) process -T "$$thy" 2>&1 | head -5; \ - done - @echo "โœ… Quick check complete" - -# Generate comprehensive Isabelle documentation (for auditing & CI/CD) -# This generates documentation and verification reports regardless of proof status -# Suitable for Jenkinsfile pipelines - shows complete state including errors -docs-isabelle: - @echo "๐Ÿ“š Generating comprehensive Isabelle documentation (audit mode)..." - @mkdir -p docs/src/isabelle - @echo "" - @echo "Step 1: Attempting to verify Isabelle theories..." - @echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" - @cd docs/src/internal/formal && \ - if $(ISABELLE) build -v -d . StarForth_Formal > "$(CURDIR)/docs/src/isabelle/build.log" 2>&1; then \ - echo "โœ… All theories verified successfully"; \ - else \ - echo "โš ๏ธ Some theories have incomplete proofs (see build.log for details)"; \ - fi - @echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" - @echo "" - @echo "Step 2: Generating documentation from theory source..." - @if [ ! -f scripts/isabelle-to-adoc.sh ]; then \ - echo "โš ๏ธ Warning: scripts/isabelle-to-adoc.sh not found"; \ - echo " Creating default script..."; \ - mkdir -p scripts; \ - echo '#!/bin/bash' > scripts/isabelle-to-adoc.sh; \ - echo 'echo "Generating Isabelle theory reports to AsciiDoc..."' >> scripts/isabelle-to-adoc.sh; \ - echo 'cd docs/src/internal/formal' >> scripts/isabelle-to-adoc.sh; \ - echo 'for thy in *.thy; do' >> scripts/isabelle-to-adoc.sh; \ - echo ' base=$$(basename "$$thy" .thy)' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "= $$base Theory" > "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "Formal verification theory for StarForth VM." >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "== Theory Source" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "[source,isabelle]" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "----" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' cat "$$thy" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo ' echo "----" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ - echo 'done' >> scripts/isabelle-to-adoc.sh; \ - chmod +x scripts/isabelle-to-adoc.sh; \ - fi - @bash scripts/isabelle-to-adoc.sh - @echo "" - @echo "Step 3: Creating audit summary..." - @echo "โœ… Comprehensive Isabelle documentation generated: docs/src/isabelle/" - @echo "" - @echo "๐Ÿ“‚ Documentation includes:" - @echo " โ€ข index.adoc - Master index of all theories" - @echo " โ€ข VERIFICATION_REPORT.adoc - Audit report" - @echo " โ€ข .adoc - Individual theory documentation with source" - @echo " โ€ข build.log - Isabelle build output (verification status)" - -# ============================================================================== -# REFINEMENT VERIFICATION (C โŠ‘ Isabelle) -# ============================================================================== - -# Refinement status dashboard -refinement-status: - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo " StarForth C โŠ‘ Isabelle Refinement Status" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo "" - @if [ ! -f docs/REFINEMENT_CAPA.adoc ]; then \ - echo "โš ๏ธ No REFINEMENT_CAPA.adoc found. Initialize with: make refinement-init"; \ - echo ""; \ - echo "Refinement infrastructure status: UNINITIALIZED"; \ - else \ - echo "๐Ÿ“‹ Defect Summary:"; \ - echo ""; \ - echo -n " Total Defects: "; grep -c "^== DEFECT-" docs/REFINEMENT_CAPA.adoc || echo "0"; \ - echo -n " OPEN: "; grep "| OPEN" docs/REFINEMENT_CAPA.adoc | wc -l; \ - echo -n " IN-PROGRESS: "; grep "| IN-PROGRESS" docs/REFINEMENT_CAPA.adoc | wc -l; \ - echo -n " CLOSED: "; grep "| CLOSED" docs/REFINEMENT_CAPA.adoc | wc -l; \ - fi - @echo "" - @echo "๐Ÿ† Phase Status:" - @echo " Phase 1: vm.c core .............. NOT STARTED" - @echo " Phase 2: Root utilities ......... NOT STARTED" - @echo " Phase 3: Test harness .......... NOT STARTED" - @echo " Phase 4: Primitive dictionary .. NOT STARTED" - @echo " Phase 5: VM expansion .......... NOT STARTED" - @echo "" - @echo "๐Ÿ“‚ Documentation:" - @echo " โ€ข docs/REFINEMENT_CAPA.adoc - Defect tracking" - @echo " โ€ข docs/REFINEMENT_ANNOTATIONS.adoc - Code annotation guide" - @echo "" - @echo "Next steps: make refinement-phase1 (to start Phase 1 proofs)" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - -# Initialize refinement tracking -refinement-init: - @echo "Initializing refinement tracking..." - @if [ -f docs/REFINEMENT_CAPA.adoc ]; then \ - echo "โœ… docs/REFINEMENT_CAPA.adoc already exists"; \ - else \ - echo "๐Ÿ“‹ Creating REFINEMENT_CAPA.adoc"; \ - fi - @if [ -f docs/REFINEMENT_ANNOTATIONS.adoc ]; then \ - echo "โœ… docs/REFINEMENT_ANNOTATIONS.adoc already exists"; \ - else \ - echo "๐Ÿ“‹ Creating REFINEMENT_ANNOTATIONS.adoc"; \ - fi - @echo "โœ… Refinement infrastructure ready" - @echo "" - @echo "Next: Review docs/REFINEMENT_ANNOTATIONS.adoc" - @echo " Then: make refinement-phase1" - -# Phase 1: VM Core refinement -refinement-phase1: - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo " โš™๏ธ PHASE 1: VM Core Refinement (C โŠ‘ Isabelle)" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo "" - @echo "Building refinement proofs for:" - @echo " โ€ข stack_push / stack_pop (DEFECT-001, DEFECT-002)" - @echo " โ€ข execute_call / execute_return (DEFECT-002)" - @echo " โ€ข instruction_dispatch (DEFECT-003)" - @echo "" - @echo "Proof target: StarForth_Refinement (Isabelle theory)" - @if ! command -v $(ISABELLE) >/dev/null 2>&1; then \ - echo "Error: Isabelle not found. Install or set ISABELLE variable"; \ - exit 1; \ - fi - @echo "" - @echo "Step 1: Creating StarForth_Refinement.thy if needed..." - @if [ ! -f docs/src/internal/formal/StarForth_Refinement.thy ]; then \ - echo "Creating template..."; \ - mkdir -p docs/src/internal/formal; \ - touch docs/src/internal/formal/StarForth_Refinement.thy; \ - echo "TODO: Add refinement proofs here" > docs/src/internal/formal/StarForth_Refinement.thy; \ - fi - @echo "" - @echo "Step 2: Attempting to build refinement proofs..." - @echo "(This will fail until proofs are written)" - @cd docs/src/internal/formal && \ - $(ISABELLE) build -v -d . StarForth_Formal 2>&1 | tail -20 - @echo "" - @echo "๐Ÿ“‹ Next steps:" - @echo " 1. Review open defects: grep 'OPEN' docs/REFINEMENT_CAPA.adoc" - @echo " 2. Start working on DEFECT-001 (stack_push)" - @echo " 3. Add refinement proofs to StarForth_Refinement.thy" - @echo " 4. Run: make verify-defect DEFECT=001" - -# Verify specific defect resolution -verify-defect: - @if [ -z "$(DEFECT)" ]; then \ - echo "Usage: make verify-defect DEFECT=001"; \ - echo ""; \ - echo "Available defects:"; \ - grep "== DEFECT-" docs/REFINEMENT_CAPA.adoc | sed 's/== / /'; \ - exit 1; \ - fi - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo " ๐Ÿ” Verifying Resolution: $(DEFECT)" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo "" - @if ! grep -q "== DEFECT-$(DEFECT):" docs/REFINEMENT_CAPA.adoc; then \ - echo "โŒ DEFECT-$(DEFECT) not found in REFINEMENT_CAPA.adoc"; \ - exit 1; \ - fi - @echo "Defect Details:" - @grep -A 30 "== DEFECT-$(DEFECT):" docs/REFINEMENT_CAPA.adoc | head -35 - @echo "" - @echo "Next: Implement corrective action, then run this again" - -# Check code annotation coverage -refinement-annotate-check: - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo " ๐Ÿ“ Checking Code Annotation Coverage" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo "" - @echo "Phase 1 target functions:" - @echo "" - @for func in stack_push stack_pop execute_instruction execute_call execute_return; do \ - if grep -q "REFINEMENT.*$$func\|void $$func" src/vm.c; then \ - if grep -q "REFINEMENT:" src/vm.c | grep -q "$$func"; then \ - echo " โœ… $$func - ANNOTATED"; \ - else \ - echo " โŒ $$func - MISSING ANNOTATION"; \ - fi; \ - else \ - echo " โš ๏ธ $$func - NOT FOUND"; \ - fi; \ +.PHONY: all boot_image boot_images docs clean clean-docs kernel boards help help-hosted + +# ------------------------------------------------------------------------------ +# all +# ------------------------------------------------------------------------------ +ifeq ($(TARGET),) +all: + @for b in $(READY_BOARDS); do \ + $(SUBMAKE) boot_image TARGET=$$b || exit 1; \ done + @$(SUBMAKE) -f v3/Makefile all + @$(SUBMAKE) docs @echo "" - @echo "Guide: docs/REFINEMENT_ANNOTATIONS.adoc" + @echo "Built:" + @for b in $(READY_BOARDS); do \ + d=$$(echo $$b | tr A-Z a-z); ls build/boards/$$d/*.img | sed 's/^/ /'; \ + done + @echo " build/docs/LithosAnanke.pdf" + @$(foreach b,$(UNREADY_BOARDS),echo "Skipped $(b): needs kernel/src/arch/$(call board_arch,$(b)), which does not exist yet";) +else ifneq ($(BOARD_DIR),) +all: + @$(SUBMAKE) boot_image TARGET=$(TARGET) + @$(SUBMAKE) docs TARGET=$(TARGET) +else +all: + @$(SUBMAKE) -f v3/Makefile all TARGET=$(TARGET) +endif -# Generate refinement report -refinement-report: - @echo "๐Ÿ”„ Generating refinement status report..." - @mkdir -p docs/reports - @echo "# StarForth Refinement Status" > docs/reports/refinement-status.md - @echo "" >> docs/reports/refinement-status.md - @echo "Generated: $$(date)" >> docs/reports/refinement-status.md - @echo "" >> docs/reports/refinement-status.md - @echo "## Summary" >> docs/reports/refinement-status.md - @echo "" >> docs/reports/refinement-status.md - @grep -c "== DEFECT-" docs/REFINEMENT_CAPA.adoc | xargs -I {} echo "Total Defects: {}" >> docs/reports/refinement-status.md - @echo "" >> docs/reports/refinement-status.md - @echo "See docs/REFINEMENT_CAPA.adoc for details" >> docs/reports/refinement-status.md - @echo "โœ… Report: docs/reports/refinement-status.md" - -# Generate GNU info documentation -docs/starforth.info: - @if [ ! -f docs/starforth.texi ]; then \ - echo "โš ๏ธ Skipping info docs: docs/starforth.texi not present"; \ - touch docs/starforth.info; \ - else \ - echo "๐Ÿ“– Building GNU info documentation..."; \ - if ! command -v makeinfo >/dev/null 2>&1; then \ - echo "Warning: makeinfo not found. Install with: sudo apt-get install texinfo"; \ - touch docs/starforth.info; \ - else \ - makeinfo docs/starforth.texi -o docs/starforth.info && \ - echo "โœ… Info documentation: docs/starforth.info"; \ - fi; \ +# ------------------------------------------------------------------------------ +# boot images +# ------------------------------------------------------------------------------ +boot_image: + @if [ -z "$(BOARD_DIR)" ]; then \ + echo "Usage: make boot_image TARGET=<$(subst $(space),|,$(BOARDS))>"; \ + [ -z "$(TARGET)" ] || echo "Unknown board TARGET='$(TARGET)'"; \ + exit 1; \ fi + @if [ -z "$(call board_ready,$(TARGET))" ]; then \ + echo "Error: $(TARGET) needs the $(call board_arch,$(TARGET)) kernel port (kernel/src/arch/$(call board_arch,$(TARGET))), which does not exist yet."; \ + echo " $(call board_field,$(TARGET),BOARD_DESC)"; \ + exit 1; \ + fi + @$(SUBMAKE) -f kernel/Makefile \ + BOARD=$(BOARD_DIR) ARCH=$(call board_arch,$(TARGET)) TARGET=kernel boot_image -# Generate all documentation -docs: api-docs docs-isabelle - @echo "โœ… All documentation generated!" - @echo "" - @echo "๐Ÿ“‚ Documentation locations:" - @echo " โ€ข API docs: docs/src/appendix/" - @echo " โ€ข Isabelle docs: docs/src/isabelle/" - @echo " โ€ข LaTeX: docs/latex/" +boot_images: + @for b in $(READY_BOARDS); do \ + $(SUBMAKE) boot_image TARGET=$$b || exit 1; \ + done + @$(foreach b,$(UNREADY_BOARDS),echo "Skipped $(b): needs kernel/src/arch/$(call board_arch,$(b)), which does not exist yet";) + +# ------------------------------------------------------------------------------ +# docs +# ------------------------------------------------------------------------------ +docs: + @if [ -n "$(TARGET)" ] && [ -z "$(BOARD_DIR)" ]; then \ + echo "Error: make docs takes TARGET=<$(subst $(space),|,$(BOARDS))> or no TARGET; '$(TARGET)' is not a board."; \ + exit 1; \ + fi + @$(SUBMAKE) -f docs/book/Makefile BOARD=$(BOARD_DIR) BOARD_NAME=$(TARGET) -# Clean generated documentation clean-docs: - @echo "๐Ÿ—‘๏ธ Cleaning generated documentation..." - @rm -rf docs/src/appendix/ docs/latex/ docs/src/isabelle/ - @echo "โœ… Documentation cleaned" - -# ============================================================================== -# INSTALLATION -# ============================================================================== - -install: $(BINARY) - @echo "๐Ÿ“ฆ Installing StarForth to $(PREFIX)..." - @install -d $(BINDIR) - @install -m 755 $(BINARY) $(BINDIR)/starforth - @echo " โœ“ Binary installed: $(BINDIR)/starforth" - @if [ -f capsules/init.4th ]; then \ - install -d $(CONFDIR); \ - install -m 644 capsules/init.4th $(CONFDIR)/init.4th; \ - echo " โœ“ Config installed: $(CONFDIR)/init.4th"; \ - fi - @if [ -f man/starforth.1 ]; then \ - install -d $(MANDIR); \ - install -m 644 man/starforth.1 $(MANDIR)/starforth.1; \ - echo " โœ“ Man page installed: $(MANDIR)/starforth.1"; \ - fi - @if [ -f docs/starforth.info ]; then \ - install -d $(INFODIR); \ - install -m 644 docs/starforth.info $(INFODIR)/starforth.info; \ - install-info --info-dir=$(INFODIR) $(INFODIR)/starforth.info 2>/dev/null || true; \ - echo " โœ“ Info docs installed: $(INFODIR)/starforth.info"; \ - fi - @install -d $(DOCDIR) - @if [ -f README.md ]; then install -m 644 README.md $(DOCDIR)/; fi - @if [ -f QUICKSTART.md ]; then install -m 644 QUICKSTART.md $(DOCDIR)/; fi - @if ls docs/*.md >/dev/null 2>&1; then install -m 644 docs/*.md $(DOCDIR)/ 2>/dev/null || true; fi - @echo " โœ“ Documentation installed: $(DOCDIR)/" - @echo "โœ… Installation complete!" - -uninstall: - @echo "๐Ÿ—‘๏ธ Uninstalling StarForth from $(PREFIX)..." - @rm -f $(BINDIR)/starforth - @rm -f $(MANDIR)/starforth.1 - @install-info --delete --info-dir=$(INFODIR) $(INFODIR)/starforth.info 2>/dev/null || true - @rm -f $(INFODIR)/starforth.info - @rm -rf $(DOCDIR) - @rm -rf $(CONFDIR) - @echo "โœ… Uninstall complete!" - -# ============================================================================== -# PACKAGING -# ============================================================================== - -# Build Debian package -deb: $(BINARY) - @echo "๐Ÿ“ฆ Building Debian package..." - @if ! command -v fpm >/dev/null 2>&1; then \ - echo "Error: fpm not found. Install with: gem install fpm"; \ - echo " or: sudo apt-get install ruby-dev && gem install fpm"; \ - exit 1; \ - fi - @mkdir -p package/deb - @fpm -s dir -t deb \ - -n starforth \ - -v $(VERSION) \ - -a native \ - --description "StarForth - The Fastest Forth in the West" \ - --url "https://github.com/yourusername/starforth" \ - --maintainer "StarForth Team" \ - --license "MIT" \ - --category "devel" \ - --package package/deb/ \ - --deb-compression xz \ - $(BINARY)=/usr/bin/starforth \ - capsules/init.4th=/etc/starforth/init.4th \ - README.md=/usr/share/doc/starforth/README.md - @echo "โœ… Debian package created: package/deb/starforth_$(VERSION)_*.deb" - -# Build RPM package -rpm: $(BINARY) - @echo "๐Ÿ“ฆ Building RPM package..." - @if ! command -v fpm >/dev/null 2>&1; then \ - echo "Error: fpm not found. Install with: gem install fpm"; \ - exit 1; \ - fi - @mkdir -p package/rpm - @fpm -s dir -t rpm \ - -n starforth \ - -v $(VERSION) \ - -a native \ - --description "StarForth - The Fastest Forth in the West" \ - --url "https://github.com/yourusername/starforth" \ - --maintainer "StarForth Team" \ - --license "MIT" \ - --category "Development/Languages" \ - --package package/rpm/ \ - $(BINARY)=/usr/bin/starforth \ - capsules/init.4th=/etc/starforth/init.4th \ - README.md=/usr/share/doc/starforth/README.md - @echo "โœ… RPM package created: package/rpm/starforth-$(VERSION)-*.rpm" - -# Build all packages -package: deb rpm - @echo "" - @echo "โœ… All packages built successfully!" - @echo " Debian: package/deb/" - @echo " RPM: package/rpm/" - -# ============================================================================== -# VERSIONING & BUILD MANIFEST (Workflow/Governance Integration) -# ============================================================================== - -# Parse version from include/version.h -GET_VERSION = $(shell grep "define STARFORTH_VERSION" include/version.h | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | head -1) - -.PHONY: version-info -version-info: - @echo "Current Version: $(GET_VERSION)" - @grep "STARFORTH_VERSION" include/version.h | grep define - -.PHONY: build-manifest -build-manifest: $(BINARY) - @echo "๐Ÿ“‹ Generating BUILD_MANIFEST.json..." - @mkdir -p builds/manifest - @VERSION=$$(grep "STARFORTH_VERSION_STRING" include/version.h | grep -o '"[^"]*"' | tr -d '"'); \ - GIT_HASH=$$(git rev-parse --short HEAD 2>/dev/null || echo "0000000"); \ - GIT_BRANCH=$$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown"); \ - BUILD_TIME=$$(date -Iseconds); \ - BINARY_PATH="$(BINARY)"; \ - if [ -f "$$BINARY_PATH" ]; then \ - BINARY_SHA256=$$(sha256sum "$$BINARY_PATH" | awk '{print $$1}'); \ - else \ - BINARY_SHA256="not-built"; \ - fi; \ - cat > builds/manifest/BUILD_MANIFEST.json << EOF; \ -{ \ - "version": "$$VERSION", \ - "timestamp": "$$BUILD_TIME", \ - "git": { \ - "commit_hash": "$$GIT_HASH", \ - "branch": "$$GIT_BRANCH", \ - "tag": "v$$VERSION" \ - }, \ - "build": { \ - "timestamp": "$$BUILD_TIME", \ - "compiler": "$$(gcc --version | head -1)", \ - "compiler_flags": "$(CFLAGS) $(ARCH_FLAGS)", \ - "target_architecture": "$(ARCH_NAME)", \ - "use_asm_opt": $(USE_ASM_OPT), \ - "use_lto": $(USE_LTO) \ - }, \ - "testing": { \ - "total_tests": 936, \ - "passed_tests": 0, \ - "failed_tests": 0, \ - "code_coverage_percent": 0, \ - "smoke_test_result": "N/A" \ - }, \ - "binary": { \ - "path": "$$BINARY_PATH", \ - "sha256": "$$BINARY_SHA256" \ - }, \ - "signatures": { \ - "builder": "jenkins-agent", \ - "approval_timestamp": "$(shell date -Iseconds)" \ - } \ -} \ -EOF - @echo "โœ“ BUILD_MANIFEST created: builds/manifest/BUILD_MANIFEST.json" - @cat builds/manifest/BUILD_MANIFEST.json | head -20 - -# ============================================================================== -# CLEANUP -# ============================================================================== + rm -rf build/docs +# ------------------------------------------------------------------------------ +# clean +# ------------------------------------------------------------------------------ +ifeq ($(TARGET),) clean: - @echo "๐Ÿงน Cleaning build artifacts..." - @rm -rfv build/* - @rm -f src/*.gcda src/word_source/*.gcda src/*.gcno src/word_source/*.gcno - @echo "โœ“ Clean complete" + @if [ -d build ]; then find build -mindepth 1 -maxdepth 1 ! -name cache -exec rm -rf {} +; fi + rm -f v3/include/version.h + rm -f v3/src/*.gcda v3/src/*.gcno v3/src/word_source/*.gcda v3/src/word_source/*.gcno + @echo "Cleaned build/ (kept build/cache/)" +else ifneq ($(BOARD_DIR),) +clean: + rm -rf build/boards/$(BOARD_DIR) build/$(call board_arch,$(TARGET))/kernel build/docs/$(BOARD_DIR) \ + build/docs/LithosAnanke-$(BOARD_DIR).pdf +else +clean: + rm -rf build/*/$(TARGET) +endif -clean-obj: - @echo "๐Ÿงน Cleaning object files..." - @find build -name "*.o" -type f -delete 2>/dev/null || true - @echo "โœ“ Object files cleaned" +# ------------------------------------------------------------------------------ +# misc +# ------------------------------------------------------------------------------ +GOAL ?= all +kernel: + @$(SUBMAKE) -f kernel/Makefile TARGET=kernel $(GOAL) -# ============================================================================== -# HELP -# ============================================================================== +boards: + @$(foreach b,$(BOARDS),printf ' %-9s %-8s %s\n' "$(b)" \ + "$(if $(call board_ready,$(b)),ready,no port)" "$(call board_field,$(b),BOARD_DESC)";) help: - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo " โšก StarForth Build System - Fastest in the West! โšก" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" - @echo "" - @echo "๐Ÿ› ๏ธ Variables:" - @echo " ARCH= (default: $(ARCH); canonical directory: $(ARCH_DIR))" - @echo " TARGET= (standard | fast | fastest | turbo)" - @echo "" - @echo "๐Ÿ† OPTIMIZATION BUILDS:" - @echo " fastest - Maximum performance (ASM + direct threading + LTO)" - @echo " fast - Fast without LTO (easier debugging)" - @echo " turbo - Assembly optimizations only" - @echo "" - @echo "๐Ÿฅง PLATFORM-SPECIFIC BUILDS:" - @echo " rpi4 - Native build on Raspberry Pi 4" - @echo " rpi4-cross - Cross-compile from x86_64" - @echo " rpi4-fastest - Maximum optimization for RPi4" - @echo " riscv64-clang - Cross-compile for RISC-V 64 via clang (GCC fails here)" - @echo " minimal - Minimal/embedded build" - @echo "" - @echo "๐Ÿ”ง DEBUG & DEVELOPMENT:" - @echo " all - Standard optimized build (default)" - @echo " debug - Debug build with symbols (-g -O0)" - @echo " profile - Build with profiling support" - @echo " performance - Legacy performance build (use 'fastest')" - @echo "" - @echo "๐Ÿงช TESTING & BENCHMARKING:" - @echo " test - Run full test suite" - @echo " bench - Quick benchmark" - @echo " benchmark - Full benchmark suite" - @echo "" - @echo "๐Ÿ“ ANALYSIS & DOCUMENTATION:" - @echo " asm - Generate assembly output" - @echo " sbom - Generate SBOM (Software Bill of Materials, SPDX)" - @echo " docs - Generate all documentation" - @echo " api-docs - Generate API docs (Doxygen โ†’ AsciiDoc)" - @echo " docs-latex - Convert AsciiDoc to LaTeX" - @echo " docs-isabelle - Generate Isabelle documentation for auditing (includes build log)" - @echo " isabelle-build - Build and verify Isabelle formal theories (strict verification)" - @echo " isabelle-check - Quick-check Isabelle theories" - @echo " info - Build GNU info documentation" - @echo "" - @echo "๐Ÿ”ฌ REFINEMENT VERIFICATION (C โŠ‘ Isabelle):" - @echo " refinement-init - Initialize refinement tracking (CAPA + annotations)" - @echo " refinement-status - Show refinement defect summary and phase status" - @echo " refinement-phase1 - Build Phase 1 refinement proofs (vm.c core)" - @echo " verify-defect - Verify specific defect (Usage: make verify-defect DEFECT=001)" - @echo " refinement-annotate-check - Check code annotation coverage" - @echo " refinement-report - Generate refinement status report" - @echo "" - @echo "๐Ÿ“ฆ INSTALLATION & PACKAGING:" - @echo " install - Install to PREFIX (default: .)" - @echo " uninstall - Uninstall from PREFIX" - @echo " deb - Build Debian package" - @echo " rpm - Build RPM package" - @echo " package - Build all packages" - @echo "" - @echo "๐Ÿงน CLEANUP:" - @echo " clean - Remove all build artifacts" - @echo " clean-obj - Remove object files only" - @echo " clean-docs - Remove generated documentation" - @echo "" - @echo "โš™๏ธ CONFIGURATION VARIABLES:" - @echo " CC - Compiler (default: gcc)" - @echo " CFLAGS - Compiler flags (override defaults)" - @echo " LDFLAGS - Linker flags (override defaults)" - @echo " PREFIX - Install prefix (default: .)" - @echo " MINIMAL=1 - Minimal build mode (DISABLED -- incomplete, errors out)" - @echo " ASM=1 - Generate assembly files during build" - @echo "" - @echo "๐Ÿ“‹ EXAMPLES:" - @echo " make fastest # Fastest build for current platform" - @echo " make rpi4-cross # Cross-compile for Raspberry Pi 4" - @echo " make riscv64-clang # Cross-compile for RISC-V 64 (clang)" - @echo " make asm # Generate assembly for inspection" - @echo " make debug # Debug build" - @echo " make PREFIX=/usr/local install # Install system-wide" - @echo "" - @echo "๐ŸŒŸ CURRENT PLATFORM: $(ARCH_NAME)" - @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @sed -n '/^# TARGET is/,/^# =====/p' Makefile | sed '$$d; s/^# \{0,1\}//' -quality: compile_commands clang_tidy cppcheck gcc_analyzer +help-hosted: + @$(SUBMAKE) -f v3/Makefile help -compile_commands: - bear --output build/compile_commands.json -- make -j$(nproc) - -clang_tidy: - clang-tidy -p build $(shell find src -name '*.c' -o -name '*.h') | tee build/clang-tidy.txt - -cppcheck: - cppcheck --enable=all --inconclusive --std=c99 src 2> build/cppcheck.txt || true - -gcc_analyzer: - $(MAKE) clean - CFLAGS="$(CFLAGS) -fanalyzer -Wall -Wextra" $(MAKE) all 2>&1 | tee build/gcc-analyzer.txt +# Everything else is the hosted v3 build, unchanged. (The empty Makefile +# rule stops the match-anything rule from trying to remake this file.) +Makefile: ; +%: + @$(SUBMAKE) -f v3/Makefile $@ diff --git a/README.md b/README.md index f3d8355e..6fa97f8c 100644 --- a/README.md +++ b/README.md @@ -48,19 +48,39 @@ POST at boot: **parity hash verified across amd64/aarch64/riscv64 ยท Mama capsul ## Quick Start ```bash +# One boot image per physical target (output: build/boards//) +make boot_image TARGET=SER5 # Beelink SER5 -- GPT/ESP, BOOTX64.EFI +make boot_image TARGET=RASPI # Raspberry Pi 5 -- FAT, config.txt + kernel_2712.img + DTB +make boot_image TARGET=MILKV # Milk-V Mars -- GPT/ESP, BOOTRISCV64.EFI (U-Boot bootefi) +make boot_image TARGET=ZYNQ7020 # Zynq-7020 -- ARMv7 port in progress +make boards # list boards + +# The same TARGET drives all, docs and clean (make help) +make # every board with a kernel port + hosted v3 + the book +make TARGET=RASPI # one board's image + build/docs/LithosAnanke-raspi.pdf +make docs # build/docs/LithosAnanke.pdf (LaTeX master: docs/book/main.tex) +make clean TARGET=RASPI # that board's outputs and build/aarch64/kernel +make clean # all of build/ except build/cache/ + # Build kernel (requires cross-compilation toolchain, or native gcc) -make -f Makefile.starkernel ARCH=amd64 +make -f kernel/Makefile ARCH=amd64 # Run in QEMU with OVMF -make -f Makefile.starkernel qemu +make -f kernel/Makefile qemu # Other architectures -make -f Makefile.starkernel ARCH=aarch64 qemu -make -f Makefile.starkernel ARCH=riscv64 qemu +make -f kernel/Makefile ARCH=aarch64 qemu +make -f kernel/Makefile ARCH=riscv64 qemu ``` Artifacts: `build/amd64/kernel/starkernel_loader.efi` ยท `build/amd64/kernel/starkernel_kernel.elf` +Tree: `kernel/` (LithosAnanke: `Makefile`, `src/`, `include/starkernel/`, `linker/`), +`v3/` (StarForth v3 engine and hosted build: `Makefile`, `src/`, `include/`), +`v4/` (StarForth v4, see `docs/v4.0.0/`), `boards//` (`board.mk` + boot files). +Every makefile runs from the repo root; the root `Makefile` forwards any other goal to +`v3/Makefile` (hosted build). + For the hosted VM by itself (Linux, no cross-compiler needed, no bare-metal tooling): see the separate **StarForth** repository โ€” LithosAnanke used to be a branch inside that repo, now it's its own project with its own `master`. @@ -69,12 +89,12 @@ now it's its own project with its own `master`. Every kernel-only knob (`STARFORTH_ENABLE_VM`, `PARITY_MODE`, the shared physics/heartbeat family, etc.) is an optional Kconfig symbol โ€” a plain -`make -f Makefile.starkernel` uses the same defaults it always has unless +`make -f kernel/Makefile` uses the same defaults it always has unless you opt in: ```bash -make -f Makefile.starkernel ARCH=amd64 menuconfig -make -f Makefile.starkernel ARCH=amd64 kernel_amd64_defconfig +make -f kernel/Makefile ARCH=amd64 menuconfig +make -f kernel/Makefile ARCH=amd64 kernel_amd64_defconfig ``` --- diff --git a/boards/README.md b/boards/README.md new file mode 100644 index 00000000..3816786f --- /dev/null +++ b/boards/README.md @@ -0,0 +1,29 @@ +# boards/ + +One directory per physical target. `make boot_image TARGET=` (repo root) maps the +name to a directory here, reads its `board.mk`, and builds the single file that goes on +that board's boot medium into `build/boards//`. + +| TARGET | Directory | ISA | Boot path | Image | +|---|---|---|---|---| +| `SER5` | `ser5/` | amd64 | UEFI firmware, removable-media path | GPT + FAT32 ESP: `EFI/BOOT/BOOTX64.EFI` | +| `RASPI` | `raspi/` | aarch64 | Pi 5 EEPROM firmware, native | MBR + FAT32: `config.txt`, `kernel_2712.img`, `bcm2712-rpi-5-b.dtb` | +| `MILKV` | `milkv/` | riscv64 | SPI-flash U-Boot + OpenSBI, `bootefi` | GPT + FAT32 ESP: `EFI/BOOT/BOOTRISCV64.EFI` | +| `ZYNQ7020` | `zynq7020/` | armv7 | BootROM, `BOOT.BIN`, U-Boot | not yet: needs `kernel/src/arch/armv7` | + +`board.mk` sets: + +- `BOARD_DESC`: one-line description (`make boards`) +- `BOARD_ARCH`: kernel ISA (`kernel/src/arch/`) +- `BOARD_BOOT`: image recipe in `kernel/Makefile` (`uefi-esp`, `rpi-native`, ...) +- `BOARD_IMAGE`: output file name + +Disk images are assembled by `scripts/mkdiskimage.sh`, which needs no root access and no loop +devices. `KERNEL_ARGS="..."` is written as `starforth.cfg` (UEFI boards) or `cmdline.txt` +(Pi 5, where the firmware copies it into `/chosen/bootargs`). `BOOT_IMAGE_SIZE_MIB` sets the +image size; the default is 128. + +Hardware status: none of these images has been booted on real silicon from this build. The +SER5 image has been booted in QEMU (q35 + OVMF, from its own disk) through POST. The Pi 5 +native path (`raspi/README.md`) and the JH7110 peripherals have still only been checked by +compiling. diff --git a/boards/milkv/README.md b/boards/milkv/README.md new file mode 100644 index 00000000..63a9c99a --- /dev/null +++ b/boards/milkv/README.md @@ -0,0 +1,30 @@ +# Milk-V Mars boot media + +`make boot_image TARGET=MILKV` builds `build/boards/milkv/lithos-milkv.img`: a GPT disk with one +FAT32 EFI System Partition. Write it to an SD card with `dd`. The partition holds: + +- `EFI/BOOT/BOOTRISCV64.EFI`: the riscv64 monolithic loader, the same one QEMU boots. +- `startup.nsh`: for a UEFI shell, if one is used. +- `starforth.cfg`: only present when `KERNEL_ARGS="..."` is given. + +The board's own SPI-flash U-Boot, with OpenSBI underneath, finds the loader through its standard +`bootefi` scan of the removable-media path. U-Boot passes its devicetree to the loader through the +EFI configuration table. + +Status: booted in QEMU through the same chain the board uses: OpenSBI, then U-Boot +`qemu-riscv64_smode`, then `bootefi` from this image's ESP, then the loader and the kernel. POST +passed, Stadium conservation was exact (resident 43691 + reservoir 21845 = 65536 = `Q48_ONE`), and +Hestia and Artemis came up. Not yet booted on the Mars itself. The JH7110 peripherals +(framebuffer, RNG) have only been checked by compiling. + +To repeat the QEMU boot (`qemu-system-riscv64` is in Ubuntu 26.04's `qemu-system-riscv` package; +OpenSBI and U-Boot come from `opensbi` and `u-boot-qemu`). Use a copy, because the kernel writes +to its disk: + +``` +cp build/boards/milkv/lithos-milkv.img /tmp/mv.img +qemu-system-riscv64 -machine virt -cpu rv64 -m 2048 -nographic \ + -bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_dynamic.bin \ + -kernel /usr/lib/u-boot/qemu-riscv64_smode/u-boot.bin \ + -drive if=none,format=raw,file=/tmp/mv.img,id=d0 -device virtio-blk-device,drive=d0 +``` diff --git a/boards/milkv/board.mk b/boards/milkv/board.mk new file mode 100644 index 00000000..64ed1490 --- /dev/null +++ b/boards/milkv/board.mk @@ -0,0 +1,11 @@ +# boards/milkv/board.mk -- Milk-V Mars (StarFive JH7110, SiFive U74, RV64GC). +# +# The board's own SPI-flash U-Boot (OpenSBI underneath) runs the EFI +# application through its standard distro/bootefi scan: the SD card is a GPT +# disk with one FAT32 EFI System Partition holding EFI/BOOT/BOOTRISCV64.EFI, +# the same riscv64 monolithic loader QEMU boots. U-Boot passes its own +# devicetree through the EFI configuration table. +BOARD_DESC := Milk-V Mars (StarFive JH7110, RV64GC, U-Boot bootefi) +BOARD_ARCH := riscv64 +BOARD_BOOT := uefi-esp +BOARD_IMAGE := lithos-milkv.img diff --git a/boards/raspi/README.md b/boards/raspi/README.md new file mode 100644 index 00000000..d3e3e2d6 --- /dev/null +++ b/boards/raspi/README.md @@ -0,0 +1,20 @@ +# Raspberry Pi 5 native boot media + +`make boot_image TARGET=RASPI` builds `build/boards/raspi/lithos-raspi.img`: an MBR disk +with one FAT32 (LBA) partition. Write it to an SD card with `dd`. The partition holds: + +- `config.txt`: checked in here (FABRIC-3.md ยงIV.3 item 6). It pins `kernel_address=0x80000` + because Pi 5 firmware loads `kernel_2712.img` at 0x200000 by default. +- `kernel_2712.img`: the aarch64 kernel objects relinked at 0x80000 by + `kernel/linker/starkernel-native-rpi5.ld`, entered at `rpi5_native_start` + (`kernel/src/arch/aarch64/native_rpi5_entry.S`, which zeroes `.bss` first), and flattened + with `objcopy -O binary`. +- `bcm2712-rpi-5-b.dtb`: the Raspberry Pi firmware's own stock DTB. It is not built by this + project; it is fetched once from the firmware release pinned in `board.mk` + (`RPI_FIRMWARE_TAG`) into `build/cache/`. To use a local copy, pass `RPI5_DTB=/path/to/dtb`. +- `cmdline.txt`: only present when `KERNEL_ARGS="..."` is given. The firmware copies it into + `/chosen/bootargs`, which `rpi5_native_boot()` parses. + +Not yet verified on hardware. The native path still assumes everything `kernel_main()` +needs after a UEFI handoff. The firmware enters at EL2 with the MMU off, which is not what +UEFI hands over, and that difference has not been exercised. diff --git a/boards/raspi/board.mk b/boards/raspi/board.mk new file mode 100644 index 00000000..9555bbf9 --- /dev/null +++ b/boards/raspi/board.mk @@ -0,0 +1,18 @@ +# boards/raspi/board.mk -- Raspberry Pi 5 (BCM2712, Cortex-A76, aarch64). +# +# Native firmware boot, no UEFI (FABRIC-3.md ยงIV): the Pi 5 bootloader +# lives in EEPROM and reads config.txt, kernel_2712.img and the board DTB +# from the first FAT partition of the SD card. kernel_2712.img is the +# aarch64 kernel relinked at 0x80000 (kernel/linker/starkernel-native-rpi5.ld) +# and flattened to a raw binary. +# +# The DTB is the Raspberry Pi firmware's own stock file, not built here. It +# is fetched once from the pinned firmware release below into build/cache/ +# unless RPI5_DTB points at a local copy. +BOARD_DESC := Raspberry Pi 5 (BCM2712, Cortex-A76, native firmware boot) +BOARD_ARCH := aarch64 +BOARD_BOOT := rpi-native +BOARD_IMAGE := lithos-raspi.img +RPI_FIRMWARE_TAG ?= 1.20260915 +RPI5_DTB_URL ?= https://raw.githubusercontent.com/raspberrypi/firmware/$(RPI_FIRMWARE_TAG)/boot/bcm2712-rpi-5-b.dtb +RPI5_DTB ?= build/cache/raspi-$(RPI_FIRMWARE_TAG)/bcm2712-rpi-5-b.dtb diff --git a/boot_media/rpi5/config.txt b/boards/raspi/config.txt similarity index 91% rename from boot_media/rpi5/config.txt rename to boards/raspi/config.txt index 3f084b85..546b7491 100644 --- a/boot_media/rpi5/config.txt +++ b/boards/raspi/config.txt @@ -12,6 +12,13 @@ # firmware picks up. kernel=kernel_2712.img +# Pin the load address to the one the image is linked at +# (kernel/linker/starkernel-native-rpi5.ld). Pi 5 firmware's own default +# for kernel_2712.img is 0x200000, not the classic 0x80000 -- leaving it +# implicit would load a 0x80000-linked flat image 1.5 MiB away from where +# every absolute address in it points. +kernel_address=0x80000 + # Disable the firmware's Linux-compatible-image sanity check. Without # this, official docs describe it as checking for "a compatible Device # Tree file before attempting to boot" and warn that "older non-compatible diff --git a/boards/ser5/README.md b/boards/ser5/README.md new file mode 100644 index 00000000..af4eee17 --- /dev/null +++ b/boards/ser5/README.md @@ -0,0 +1,14 @@ +# Beelink SER5 boot media + +`make boot_image TARGET=SER5` builds `build/boards/ser5/lithos-ser5.img`: a GPT disk with one +FAT32 EFI System Partition. Write it to a USB stick with `dd`. The partition holds: + +- `EFI/BOOT/BOOTX64.EFI`: the amd64 monolithic loader, with the whole kernel embedded. Firmware + finds it through the UEFI removable-media path, so no boot entry has to be created. +- `startup.nsh`: runs the loader if the firmware drops into the UEFI shell. +- `starforth.cfg`: only present when `KERNEL_ARGS="..."` is given. + +Nothing in the image is SER5-specific. It follows the generic UEFI/ACPI path in FABRIC-3.md ยงIII. + +Status: booted in QEMU (q35 + OVMF, from this image as its own disk) through POST, with Stadium +conservation exact (sum 65536 = `Q48_ONE`). Not yet booted on the SER5 itself. diff --git a/boards/ser5/board.mk b/boards/ser5/board.mk new file mode 100644 index 00000000..33df360f --- /dev/null +++ b/boards/ser5/board.mk @@ -0,0 +1,10 @@ +# boards/ser5/board.mk -- Beelink SER5 (AMD Ryzen, x86-64, UEFI/ACPI). +# +# Generic standards-compliant UEFI path (FABRIC-3.md ยงIII): nothing in the +# image is SER5-specific. The monolithic loader embeds the whole kernel, so +# the image is a GPT disk with one FAT32 EFI System Partition holding +# EFI/BOOT/BOOTX64.EFI. Write it to a USB stick with dd. +BOARD_DESC := Beelink SER5 (AMD Ryzen, x86-64, UEFI) +BOARD_ARCH := amd64 +BOARD_BOOT := uefi-esp +BOARD_IMAGE := lithos-ser5.img diff --git a/boards/zynq7020/README.md b/boards/zynq7020/README.md new file mode 100644 index 00000000..b28cad8d --- /dev/null +++ b/boards/zynq7020/README.md @@ -0,0 +1,17 @@ +# Xilinx Zynq-7020 boot media + +The Zynq-7020's processing system is a dual Cortex-A9: ARMv7-A, 32-bit. It is the host for the +StarForth v4 mesh (`docs/v4.0.0/JUSTIFICATION.md` ยง5, ยง8). + +Boot chain: BootROM, then `BOOT.BIN` (U-Boot SPL with the board's `ps7_init` DDR and clock setup), +then U-Boot, then LithosAnanke. Everything is read from the SD card's FAT partition. + +Status: no image yet. `make boot_image TARGET=ZYNQ7020` stops with an error, because there is no +ARMv7 kernel port (`kernel/src/arch/armv7`: entry code, MMU, GIC, private timer). A trial +compile for Cortex-A9 built 147 of the 151 kernel and engine sources. The four that failed use +`__int128` or have no ARMv7 branch: `kernel/src/crypto/fe25519.c`, +`kernel/src/crypto/scalar25519.c`, `kernel/src/hal/hal.c` and +`v3/src/word_source/mixed_arithmetic_words.c`. + +`BOOT.BIN` depends on the exact board (Zybo Z7-20, PYNQ-Z2, Arty Z7-20, ZedBoard, ...), because +`ps7_init` holds that board's DDR timing. The board has not been chosen yet. diff --git a/boards/zynq7020/board.mk b/boards/zynq7020/board.mk new file mode 100644 index 00000000..9fbd1ab5 --- /dev/null +++ b/boards/zynq7020/board.mk @@ -0,0 +1,11 @@ +# boards/zynq7020/board.mk -- Xilinx Zynq-7020 (dual Cortex-A9, ARMv7-A, 32-bit). +# +# Boot chain: BootROM -> BOOT.BIN (U-Boot SPL with the board's ps7_init DDR/ +# clock setup) -> U-Boot -> LithosAnanke, all from the SD card's FAT +# partition. Needs the ARMv7 kernel port (kernel/src/arch/armv7), which is +# in progress: until it exists, boot_image stops with an explicit error +# rather than producing an image that cannot run. +BOARD_DESC := Xilinx Zynq-7020 (Cortex-A9, ARMv7-A, BOOT.BIN) -- ARMv7 port in progress +BOARD_ARCH := armv7 +BOARD_BOOT := zynq-bootbin +BOARD_IMAGE := lithos-zynq7020.img diff --git a/boot_media/rpi5/README.md b/boot_media/rpi5/README.md deleted file mode 100644 index a1f7cd4e..00000000 --- a/boot_media/rpi5/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Raspberry Pi 5 native boot media - -What goes on the SD card for the native (non-UEFI) boot path (FABRIC-3.md ยงIV): - -- `config.txt` โ€” checked in here, done (ยงIV.3 item 6). -- `bcm2712-rpi-5-b.dtb` โ€” Raspberry Pi firmware's own stock DTB; not built by this - project, copied from the firmware release the card is otherwise built from. -- `kernel_2712.img` โ€” **does not exist yet.** `config.txt` names it, but no build target - in `Makefile.starkernel` currently emits a raw image by this name at load address - 0x80000 โ€” item 1 (entry stub) explicitly scoped a separate-image build target as future - work, not part of that item. Building this file is the remaining prerequisite before - item 7 (assembling the card) is possible. diff --git a/capsules/BLOCK_MAP.md b/capsules/BLOCK_MAP.md index 57fdf053..d2477242 100644 --- a/capsules/BLOCK_MAP.md +++ b/capsules/BLOCK_MAP.md @@ -1,5 +1,5 @@ # Capsule Block Manifest โ€” Auto-generated - + @@ -8,42 +8,44 @@ | Capsule | Blocks claimed | xxHash64 | Signed | |---------|----------------|----------|--------| -| `ACL.4th` | 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4015 | `0xf8890c05c0d8f921` | yes | -| `acl-std79.4th` | 4023, 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048 | `0x773bf9209df191d1` | yes | -| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852, 4853, 4854, 4856, 4857, 4858, 4860 | `0xe6fba9ae56e1c916` | yes | -| `block-acl.4th` | 4019, 4020 | `0xf6cc2a59e3a6734e` | yes | -| `doe-campaign.4th` | 4060, 4061, 4062, 4063, 4064, 4065 | `0x26fb485e5c9dc6ff` | yes | -| `doe.4th` | 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107 | `0xf154616d248e861f` | yes | -| `fabric.4th` | 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, 4909, 4910, 4911, 4912, 4913, 4914, 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, 4923, 4924, 5000, 5001, 5002 | `0x9d9489cbeca4099b` | yes | -| `font.4th` | 4925, 4926, 4927, 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, 4939, 4940, 4941, 4942, 4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, 4984, 4985 | `0x3f305911500c78f6` | yes | -| `hestia:init.4th` | 4986, 4987, 4988 | `0x64e111990fbc45ff` | yes | -| `init-l8-diverse.4th` | 4820, 4821, 4822 | `0xaa293201a6c91838` | yes | -| `init-l8-omni.4th` | 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079 | `0x5979e314d6452045` | yes | -| `init-l8-stable.4th` | 4806 | `0xdc3830f189063a9a` | yes | -| `init-l8-temporal.4th` | 4830, 4831 | `0x51abd4c138246651` | yes | -| `init-l8-transition.4th` | 4840, 4841, 4842 | `0xbcc1a81976f0a4c9` | yes | -| `init-l8-volatile.4th` | 4810, 4811, 4812, 4813 | `0x98caabbbd92abac4` | yes | -| `init.4th` | 2049, 2050, 2057 | `0xea038ba684c53443` | yes | -| `lib.4th` | 4050 | `0x4b216635c359ef73` | yes | -| `multiuser-doe.4th` | 5044, 5045, 5046, 5047, 5048, 5049, 5050, 5051, 5052, 5053, 5054, 5055 | `0x22140588ee7c39e6` | yes | -| `sdk.4th` | 5109, 5110, 5111, 5112, 5113, 5114, 5115 | `0x008fdbbb62c94a3a` | yes | -| `turtle.4th` | 5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108 | `0x4d470418ca543365` | yes | -| `user-font-demo.4th` | 4200, 4201, 4202 | `0xce1fd7d1b581a56d` | yes | -| `workload-0.4th` | 2200, 2201 | `0x93f86f60aeba8feb` | yes | -| `workload-1-lite.4th` | 5058, 5059 | `0x44a7a7e3176dcc8d` | yes | -| `workload-1.4th` | 4406, 4415, 4425, 4435 | `0x63e251adb0a03613` | yes | -| `workload-2.4th` | 4506, 4515, 4525, 4535, 4545 | `0xf113b3d0bcccae47` | yes | -| `workload-3.4th` | 4606, 4615, 4625, 4635, 4645, 4655, 4665 | `0x62b7a71576ad1041` | yes | -| `workload-4.4th` | 2130, 2131, 2132 | `0x099619264e650b1c` | yes | -| `workload-5-lite.4th` | 5056, 5057 | `0xea0303f38824f254` | yes | -| `workload-5.4th` | *(none โ€” raw code capsule)* | `0x526964c7c9506a11` | yes | -| `workload-6.4th` | 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095 | `0x06fc0ce1e369ef5a` | yes | -| `workload-7.4th` | 2150 | `0x02862291387eb7ac` | yes | -| `workload-8.4th` | 2160 | `0x56b7f2f0efa000df` | yes | -| `workload-9.4th` | 4706, 4715, 4725, 4735, 4745 | `0x3f2bec73142aa424` | yes | -| `workload-calib1.4th` | 5043 | `0x3b9f2d17b554fabc` | yes | -| `zuse-eligibility.4th` | 4021, 4022 | `0x7b28f4776a32e0b7` | yes | -| `zuse.4th` | 4016, 4017, 4018 | `0x490ded9be257a90b` | yes | +| `ACL.4th` | 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4015 | `0xf8890c05c0d8f921` | n/a | +| `acl-std79.4th` | 4023, 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048 | `0x773bf9209df191d1` | n/a | +| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852, 4853, 4854, 4856, 4857, 4858, 4860 | `0xe6fba9ae56e1c916` | n/a | +| `block-acl.4th` | 4019, 4020 | `0xf6cc2a59e3a6734e` | n/a | +| `doe-campaign.4th` | 4060, 4061, 4062, 4063, 4064, 4065 | `0x26fb485e5c9dc6ff` | n/a | +| `doe.4th` | 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107 | `0xf154616d248e861f` | n/a | +| `fabric.4th` | 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, 4909, 4910, 4911, 4912, 4913, 4914, 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, 4923, 4924, 5000, 5001, 5002 | `0x9d9489cbeca4099b` | n/a | +| `font.4th` | 4925, 4926, 4927, 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, 4939, 4940, 4941, 4942, 4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, 4984, 4985 | `0x3f305911500c78f6` | n/a | +| `hestia:init.4th` | 4986, 4987, 4988 | `0x64e111990fbc45ff` | n/a | +| `init-l8-diverse.4th` | 4820, 4821, 4822 | `0xaa293201a6c91838` | n/a | +| `init-l8-omni.4th` | 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079 | `0x5979e314d6452045` | n/a | +| `init-l8-stable.4th` | 4806 | `0xdc3830f189063a9a` | n/a | +| `init-l8-temporal.4th` | 4830, 4831 | `0x51abd4c138246651` | n/a | +| `init-l8-transition.4th` | 4840, 4841, 4842 | `0xbcc1a81976f0a4c9` | n/a | +| `init-l8-volatile.4th` | 4810, 4811, 4812, 4813 | `0x98caabbbd92abac4` | n/a | +| `init.4th` | 2049, 2050, 2057 | `0xea038ba684c53443` | n/a | +| `lib.4th` | 4050 | `0x4b216635c359ef73` | n/a | +| `multiuser-doe.4th` | 5044, 5045, 5046, 5047, 5048, 5049, 5050, 5051, 5052, 5053, 5054, 5055 | `0x22140588ee7c39e6` | n/a | +| `sdk.4th` | 5109, 5110, 5111, 5112, 5113, 5114, 5115 | `0x008fdbbb62c94a3a` | n/a | +| `turtle.4th` | 5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108 | `0x4d470418ca543365` | n/a | +| `user-font-demo.4th` | 4200, 4201, 4202 | `0xce1fd7d1b581a56d` | n/a | +| `workload-0.4th` | 2200, 2201 | `0x93f86f60aeba8feb` | n/a | +| `workload-1-lite.4th` | 5058, 5059 | `0x44a7a7e3176dcc8d` | n/a | +| `workload-1.4th` | 4406, 4415, 4425, 4435 | `0x63e251adb0a03613` | n/a | +| `workload-2.4th` | 4506, 4515, 4525, 4535, 4545 | `0xf113b3d0bcccae47` | n/a | +| `workload-3.4th` | 4606, 4615, 4625, 4635, 4645, 4655, 4665 | `0x62b7a71576ad1041` | n/a | +| `workload-4.4th` | 2130, 2131, 2132 | `0x099619264e650b1c` | n/a | +| `workload-5-lite.4th` | 5056, 5057 | `0xea0303f38824f254` | n/a | +| `workload-5.4th` | *(none โ€” raw code capsule)* | `0x526964c7c9506a11` | n/a | +| `workload-6.4th` | 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095 | `0x06fc0ce1e369ef5a` | n/a | +| `workload-7.4th` | 2150 | `0x02862291387eb7ac` | n/a | +| `workload-8.4th` | 2160 | `0x56b7f2f0efa000df` | n/a | +| `workload-9.4th` | 4706, 4715, 4725, 4735, 4745 | `0x3f2bec73142aa424` | n/a | +| `workload-calib1.4th` | 5043 | `0x3b9f2d17b554fabc` | n/a | +| `zuse-eligibility.4th` | 4021, 4022 | `0x7b28f4776a32e0b7` | n/a | +| `zuse.4th` | 4016, 4017, 4018 | `0xa14d5a7a88791cf6` | n/a | + +*Signed column is `n/a`: this manifest run had no `--sign-key`. Re-run with `--sign-key ` to check signing status (does not modify or require rebuilding capsule_generated.c).* ## Block Map (sorted by LBN) @@ -109,9 +111,9 @@ | 4007 | `ACL.4th` | `0xf8890c05c0d8f921` | ok | | 4008 | `ACL.4th` | `0xf8890c05c0d8f921` | ok | | 4015 | `ACL.4th` | `0xf8890c05c0d8f921` | ok | -| 4016 | `zuse.4th` | `0x490ded9be257a90b` | ok | -| 4017 | `zuse.4th` | `0x490ded9be257a90b` | ok | -| 4018 | `zuse.4th` | `0x490ded9be257a90b` | ok | +| 4016 | `zuse.4th` | `0xa14d5a7a88791cf6` | ok | +| 4017 | `zuse.4th` | `0xa14d5a7a88791cf6` | ok | +| 4018 | `zuse.4th` | `0xa14d5a7a88791cf6` | ok | | 4019 | `block-acl.4th` | `0xf6cc2a59e3a6734e` | ok | | 4020 | `block-acl.4th` | `0xf6cc2a59e3a6734e` | ok | | 4021 | `zuse-eligibility.4th` | `0x7b28f4776a32e0b7` | ok | diff --git a/configs/README.md b/configs/README.md index dfe48f80..1cc77e37 100644 --- a/configs/README.md +++ b/configs/README.md @@ -1,7 +1,7 @@ # configs/ Example Kconfig `defconfig` files โ€” starting points for `make -f -Makefile.starkernel ARCH= defconfig` (kernel) or the equivalent +kernel/Makefile ARCH= defconfig` (kernel) or the equivalent hosted target, matching the current committed default build behavior for each profile. Loaded via `tools/kconfig/conf`. diff --git a/ONTOLOGY.md b/docs/ONTOLOGY.md similarity index 100% rename from ONTOLOGY.md rename to docs/ONTOLOGY.md diff --git a/ROADMAP.md b/docs/ROADMAP.md similarity index 100% rename from ROADMAP.md rename to docs/ROADMAP.md diff --git a/docs/book/Makefile b/docs/book/Makefile new file mode 100644 index 00000000..43481d7c --- /dev/null +++ b/docs/book/Makefile @@ -0,0 +1,112 @@ +# docs/book/Makefile -- the single LithosAnanke book, built from LaTeX. +# +# Run from the repo root (the root Makefile does this): +# make docs -> build/docs/LithosAnanke.pdf +# make docs TARGET= -> build/docs/LithosAnanke-.pdf +# (same book + that board's appendix) +# +# docs/book/main.tex is the master. Markdown sources are converted by pandoc +# into LaTeX fragments under build/docs/gen/ and \input from main.tex; the +# Markdown stays the source of truth until a chapter is rewritten in LaTeX. +# Figures and tables that present data read the CSV directly at LaTeX time +# (pgfplots / pgfplotstable) and cite it with \datasource{path}; see +# docs/book/README.md. + +BOOK_DIR := docs/book +OUT := build/docs +GEN := $(OUT)/gen + +BOARD ?= +BOARD_NAME ?= +VARIANT := $(if $(BOARD),$(BOARD),book) +VAR_DIR := $(OUT)/$(VARIANT) +PDF := $(OUT)/LithosAnanke$(if $(BOARD),-$(BOARD)).pdf + +PANDOC ?= pandoc +LATEXMK ?= latexmk +PANDOC_FILTERS := $(BOOK_DIR)/pandoc/table-widths.lua $(BOOK_DIR)/pandoc/code-breaks.lua +PANDOC_FLAGS := -f gfm -t latex --top-level-division=chapter --wrap=preserve \ + $(foreach f,$(PANDOC_FILTERS),--lua-filter=$(f)) + +# fragment name : Markdown source. The order of \input lines is main.tex's. +CHAPTERS := \ + ontology:docs/ONTOLOGY.md \ + roadmap:docs/ROADMAP.md \ + boards:boards/README.md \ + justification:docs/v4.0.0/JUSTIFICATION.md \ + decomposition:docs/v4.0.0/DECOMPOSITION.md \ + fabric-0:docs/fabric/FABRIC-0.md \ + fabric-1:docs/fabric/FABRIC-1.md \ + fabric-2:docs/fabric/FABRIC-2.md \ + fabric-3:docs/fabric/FABRIC-3.md \ + fabric-3-5:docs/fabric/FABRIC-3.5.md \ + fabric-3-6:docs/fabric/FABRIC-3.6.md \ + fabric-3-7:docs/fabric/FABRIC-3.7.md \ + fabric-4:docs/fabric/FABRIC-4.md + +ifneq ($(BOARD),) +ifeq ($(wildcard boards/$(BOARD)/README.md),) + $(error boards/$(BOARD)/README.md is missing: it is the board's appendix) +endif +CHAPTERS += board-$(BOARD):boards/$(BOARD)/README.md +endif + +chapter_name = $(word 1,$(subst :, ,$(1))) +chapter_src = $(word 2,$(subst :, ,$(1))) +FRAGMENTS := $(foreach c,$(CHAPTERS),$(GEN)/$(call chapter_name,$(c)).tex) + +.PHONY: all tools FORCE +all: $(PDF) + +tools: + @missing=""; \ + for t in $(PANDOC) $(LATEXMK) xelatex; do command -v $$t >/dev/null 2>&1 || missing="$$missing $$t"; done; \ + if [ -n "$$missing" ]; then \ + echo "Error: make docs needs:$$missing"; \ + echo " sudo apt-get install -y pandoc latexmk texlive-xetex texlive-latex-extra texlive-pictures texlive-fonts-recommended fonts-dejavu fonts-dejavu-extra"; \ + echo " (or a user-local TinyTeX + pandoc in ~/.local; see docs/book/README.md)"; \ + exit 1; \ + fi + +# --id-prefix keeps heading labels unique across documents that reuse +# section names ("Summary", "Open questions", ...). +define chapter_rule +$(GEN)/$(call chapter_name,$(1)).tex: $(call chapter_src,$(1)) $(PANDOC_FILTERS) | tools + @mkdir -p $(GEN) + @echo " PANDOC $$< -> $$@" + @$(PANDOC) $(PANDOC_FLAGS) --id-prefix=$(call chapter_name,$(1))- $$< -o $$@ +endef +$(foreach c,$(CHAPTERS),$(eval $(call chapter_rule,$(c)))) + +# Pandoc's syntax-highlighting macros, taken from the installed pandoc so the +# fragments and their macros always come from the same version. +$(GEN)/pandoc-highlighting.tex: $(BOOK_DIR)/pandoc/highlighting.latex | tools + @mkdir -p $(GEN) + @printf '```c\nx\n```\n' | $(PANDOC) -f gfm -t latex -s --template=$< -o $@ + +# Per-build facts the book prints: the commit every \datasource refers to, +# and which board appendix (if any) is included. +$(VAR_DIR)/meta.tex: FORCE + @mkdir -p $(VAR_DIR) + @{ \ + c=$$(git rev-parse --short=12 HEAD 2>/dev/null || echo unknown); \ + git diff --quiet HEAD -- 2>/dev/null || c="$$c (+ uncommitted changes)"; \ + printf '\\newcommand{\\bookcommit}{%s}\n' "$$c"; \ + printf '\\newcommand{\\bookdate}{%s}\n' "$$(date -u +%Y-%m-%d)"; \ + printf '\\def\\bookboard{%s}\n' "$(BOARD_NAME)"; \ + $(if $(BOARD),printf '\\newcommand{\\bookboardappendix}{board-%s}\n' "$(BOARD)";) \ + } > $@.tmp + @cmp -s $@.tmp $@ && rm -f $@.tmp || mv $@.tmp $@ + +FORCE: + +TEXINPUTS_BOOK := $(abspath $(VAR_DIR)):$(abspath $(GEN)):$(abspath $(BOOK_DIR)): + +$(PDF): $(BOOK_DIR)/main.tex $(FRAGMENTS) $(GEN)/pandoc-highlighting.tex $(VAR_DIR)/meta.tex | tools + @echo " LATEXMK $(BOOK_DIR)/main.tex -> $@" + @TEXINPUTS=$(TEXINPUTS_BOOK) $(LATEXMK) -xelatex -interaction=nonstopmode -halt-on-error \ + -file-line-error -outdir=$(VAR_DIR) $(BOOK_DIR)/main.tex > $(VAR_DIR)/latexmk.log 2>&1 || { \ + grep -A4 -E '^(.*:[0-9]+:|!)' $(VAR_DIR)/main.log | head -40; \ + echo "Error: LaTeX failed; full log: $(VAR_DIR)/main.log"; exit 1; } + @cp $(VAR_DIR)/main.pdf $@ + @echo " PDF $@" diff --git a/docs/book/README.md b/docs/book/README.md new file mode 100644 index 00000000..eedb4db7 --- /dev/null +++ b/docs/book/README.md @@ -0,0 +1,66 @@ +# docs/book/ + +`make docs` builds one PDF, `build/docs/LithosAnanke.pdf`, from `main.tex` with xelatex. +`make docs TARGET=` builds `build/docs/LithosAnanke-.pdf`: the same book with +`boards//README.md` added as an appendix. + +Tools: `sudo apt-get install -y pandoc latexmk texlive-xetex texlive-latex-extra texlive-pictures texlive-fonts-recommended fonts-dejavu fonts-dejavu-extra` + +Without root, a user-local TeX Live works too (this is how the book was first built): +TinyTeX (`curl -sL https://yihui.org/tinytex/install-bin-unix.sh | sh`) plus +`tlmgr install latexmk xetex fontspec pgf pgfplots booktabs multirow fancyvrb fvextra lineno upquote ulem enumitem newunicodechar bookmark hyperref geometry xcolor graphics tools etoolbox fancyhdr truncate amsfonts`, +and the pandoc release tarball unpacked into `~/.local`. + +The installed DejaVu decides italics: `fonts-dejavu-core` alone has no serif italic, so +`main.tex` falls back to a slanted upright face; `fonts-dejavu-extra` gives real italics. + +## How it fits together + +- `main.tex` is the master file. It sets the parts and the chapter order. +- Chapters that are still Markdown are listed in `Makefile` (`CHAPTERS`, as `name:source.md`). + At build time pandoc converts each one into `build/docs/gen/.tex`, and `main.tex` + includes it with `\input{}`. The Markdown stays the source until the chapter is + rewritten in LaTeX. At that point the `.tex` moves into this directory and the `CHAPTERS` + entry is removed. +- `pandoc/highlighting.latex` extracts the code-highlighting macros from the installed pandoc, + so the macros and the fragments always come from the same pandoc version. +- Two Lua filters run on every chapter. `pandoc/table-widths.lua` gives wide tables + proportional wrapping columns, because pandoc's gfm reader leaves column widths unset. + `pandoc/code-breaks.lua` lets long inline identifiers and paths break after `_ / . - :`. + Code blocks wrap through fvextra (`breaklines`). +- `build/docs//meta.tex` is written on every build. It records the commit (and + whether there were uncommitted changes), the date, and the board. + +## Rule for data + +Any figure or table that shows measured numbers is generated from the CSV when the book is +built. Numbers are never typed in by hand: + +```latex +\begin{tikzpicture} + \begin{axis}[xlabel=run, ylabel=K] + \addplot table[col sep=comma, x=run, y=K]{experiments//results.csv}; + \end{axis} +\end{tikzpicture} +\datasource{experiments//results.csv} +``` + +Use `\pgfplotstabletypeset[col sep=comma]{...}` for tables. `\datasource` prints the CSV path +and the commit, so a reader can find the exact file the figure was drawn from. CSV paths are +repo-relative, because xelatex runs from the repo root. + +## Older pipelines to fold in or retire + +These still exist and still have their own targets. Each one needs a decision during the +curation pass: move it into this book, or retire it. + +| Source | Current target | Produces | +|---|---|---| +| `docs/formal/vol1-vm-physics`, `vol2-kernel`, `vol3-research` | `make -C docs/formal vols` | three volume PDFs | +| `docs/formal/dev-guide`, `user-guide`, `cookbook` | `make -C docs/formal books` | three practitioner PDFs | +| `docs/formal/experiments`, `proofs`, `ssrn`, `patent` | `make -C docs/formal standalone` | four standalone PDFs | +| Doxygen (`Doxyfile`) | `make -C docs/formal doxygen` | API reference PDF | +| `scripts/generate-doxygen-appendix.sh` | `make -f v3/Makefile api-docs` | AsciiDoc API appendix | +| `docs/src/internal/formal/*.thy` | `make -f v3/Makefile docs-isabelle` | Isabelle report | +| `scripts/asciidoc-to-latex.sh` | `make -f v3/Makefile docs-latex` | `docs/latex/` | +| `docs/SSRN_companion/Math_Companion_SSRN.tex` | `make -f v3/Makefile math-companion` | SSRN math companion | diff --git a/docs/book/main.tex b/docs/book/main.tex new file mode 100644 index 00000000..5435e9dc --- /dev/null +++ b/docs/book/main.tex @@ -0,0 +1,161 @@ +% docs/book/main.tex -- master file of the single LithosAnanke book. +% +% Built by `make docs [TARGET=]` (docs/book/Makefile) with xelatex. +% Fragments named below (ontology, fabric-0, ...) are generated by pandoc +% from the Markdown listed in docs/book/Makefile's CHAPTERS into +% build/docs/gen/; meta.tex is generated per build. Neither is committed. +\documentclass[11pt,openany]{book} + +\usepackage{amsmath,amssymb} +\usepackage{fontspec} +% fonts-dejavu-core has no serif/sans italics (fonts-dejavu-extra does); when a +% shape is missing, slant the upright one rather than silently drop emphasis. +\setmainfont{DejaVu Serif}[AutoFakeSlant=0.2] +\setsansfont{DejaVu Sans}[AutoFakeSlant=0.2] +\setmonofont{DejaVu Sans Mono}[Scale=0.85] +\newfontfamily\symbolfont{DejaVu Sans} + +\usepackage[letterpaper,margin=1in]{geometry} +\usepackage{xcolor} +\usepackage{graphicx} +\usepackage{longtable,booktabs,array,calc,multirow} +\usepackage{fancyvrb} +\usepackage[normalem]{ulem} +\usepackage{enumitem} +\usepackage{newunicodechar} +\usepackage{pgfplots} +\usepackage{pgfplotstable} +\pgfplotsset{compat=1.18} +\usepackage[hidelinks]{hyperref} +\usepackage{bookmark} + +% --- what pandoc's LaTeX fragments expect (normally from its own template) +\providecommand{\tightlist}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} +\providecommand{\pandocbounded}[1]{#1} +\providecommand{\st}[1]{\sout{#1}} +\newcounter{none} % pandoc: {\def\LTcaptype{none} ...} marks unnumbered tables +\usepackage{etoolbox} +\makeatletter +\def\fnum@table{\tablename~\thetable} +\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} +\makeatother +\usepackage{fvextra} +\input{pandoc-highlighting} +% Code and diagrams are wider than the page in places: wrap, never overflow. +\RecustomVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\},breaklines,breakanywhere,fontsize=\small} +\RecustomVerbatimEnvironment{verbatim}{Verbatim}{breaklines,breakanywhere,fontsize=\small} +\setlistdepth{9} +\renewlist{itemize}{itemize}{9} +\setlist[itemize]{label=\textbullet} +\renewlist{enumerate}{enumerate}{9} +\setlist[enumerate]{label=\arabic*.} +% Running heads: chapter on the left page, section on the right, both cut to +% the page width (several design-record titles are a full sentence long). +\usepackage{fancyhdr} +\usepackage[fit]{truncate} +\pagestyle{fancy} +\fancyhf{} +\renewcommand{\chaptermark}[1]{\markboth{#1}{}} +\renewcommand{\sectionmark}[1]{\markright{#1}} +\fancyhead[LE]{\small\truncate{\dimexpr\headwidth-3em}{\leftmark}} +\fancyhead[RO]{\small\truncate{\dimexpr\headwidth-3em}{\rightmark}} +\fancyhead[RE,LO]{\small\thepage} +\renewcommand{\headrulewidth}{0.4pt} +\setlength{\headheight}{14pt} +\fancypagestyle{plain}{\fancyhf{}\fancyfoot[C]{\small\thepage}\renewcommand{\headrulewidth}{0pt}} +\setlength{\emergencystretch}{3em} +\setlength{\parindent}{0pt} +\setlength{\parskip}{0.5em} + +% --- glyphs DejaVu Serif lacks: the status marks used across the docs +\newunicodechar{โœ…}{{\symbolfont โœ”}} +\newunicodechar{โœ“}{{\symbolfont โœ“}} +\newunicodechar{โŒ}{{\symbolfont โœ˜}} +\newunicodechar{โœ—}{{\symbolfont โœ—}} +\newunicodechar{โฌœ}{{\symbolfont โ˜}} +\newunicodechar{โญ}{{\symbolfont โ˜…}} +\newunicodechar{๐Ÿ”ถ}{{\symbolfont โ—†}} +\newunicodechar{โš }{{\symbolfont โš }} +\newunicodechar{๐Ÿ“‹}{} +\newunicodechar{๐Ÿ›}{[bug]} +\newunicodechar{๐ŸŽฏ}{[goal]} +\newunicodechar{๐ŸŸก}{{\symbolfont โ—}} +\newunicodechar{๐Ÿ“}{{\symbolfont โ–ธ}} +\newunicodechar{๐Ÿ”“}{[unlocked]} +\newunicodechar{โ“}{?} +\newunicodechar{โŸบ}{\ensuremath{\Longleftrightarrow}} +\newunicodechar{โ‹ฏ}{\ensuremath{\cdots}} +\newunicodechar{^^^^fe0f}{} + +% --- the documents number their own sections (ยงIII.1, D-3, ...) +\setcounter{secnumdepth}{0} +\setcounter{tocdepth}{1} + +\input{meta} + +% \datasource{path/to/data.csv}: cite the data behind a figure or table. +% Every figure or table of measured numbers reads its CSV at build time +% (\addplot table / \pgfplotstabletypeset) and is followed by this line, so +% the reader can find the exact file at the exact commit. +\newcommand{\datasource}[1]{% + \par{\small Data: \texttt{\detokenize{#1}} at commit \texttt{\bookcommit}.}\par} + +\title{LithosAnanke and StarForth} +\author{} +\date{Built \bookdate{} from commit \texttt{\bookcommit}% + \ifx\bookboard\empty\else\\Board appendix: \bookboard\fi} + +\begin{document} +\frontmatter +\maketitle +\tableofcontents + +\chapter{About this book} +This book is generated from the repository by \texttt{make docs}. Each +chapter below is still maintained as the Markdown file named in the table and +converted at build time; a chapter moves into LaTeX source when it is +rewritten. Part~III is the design record: those documents are archival and +are reproduced as written, including their struck-through corrections. + +\begin{longtable}{@{}ll@{}} +\toprule +Chapter & Source \\ +\midrule +\endhead +Ontology & \texttt{docs/ONTOLOGY.md} \\ +Roadmap & \texttt{docs/ROADMAP.md} \\ +Boot targets & \texttt{boards/README.md} \\ +v4 justification & \texttt{docs/v4.0.0/JUSTIFICATION.md} \\ +v4 decomposition & \texttt{docs/v4.0.0/DECOMPOSITION.md} \\ +FABRIC-0 \dots{} FABRIC-4 & \texttt{docs/fabric/FABRIC-*.md} \\ +Board appendix (\texttt{TARGET=}) & \texttt{boards//README.md} \\ +\bottomrule +\end{longtable} + +\mainmatter + +\part{The system} +\input{ontology} +\input{roadmap} +\input{boards} + +\part{StarForth v4} +\input{justification} +\input{decomposition} + +\part{Design record (FABRIC series)} +\input{fabric-0} +\input{fabric-1} +\input{fabric-2} +\input{fabric-3} +\input{fabric-3-5} +\input{fabric-3-6} +\input{fabric-3-7} +\input{fabric-4} + +\ifdefined\bookboardappendix +\appendix +\input{\bookboardappendix} +\fi + +\end{document} diff --git a/docs/book/pandoc/code-breaks.lua b/docs/book/pandoc/code-breaks.lua new file mode 100644 index 00000000..ec8bc5f5 --- /dev/null +++ b/docs/book/pandoc/code-breaks.lua @@ -0,0 +1,29 @@ +-- docs/book/pandoc/code-breaks.lua +-- +-- Inline code in the design record is full of long identifiers and paths +-- (g_wirebind_attached_username, kernel/src/arch/riscv64/...), which LaTeX +-- cannot break, so they run into the margin. Emit inline code as \texttt +-- ourselves, escaped the same way pandoc does, with a break opportunity +-- after each separator character. + +local BREAK_AFTER = { ["_"] = true, ["/"] = true, ["."] = true, ["-"] = true, + [":"] = true, [","] = true, ["("] = true, ["="] = true } + +local ESCAPE = { + ["\\"] = "\\textbackslash{}", ["{"] = "\\{", ["}"] = "\\}", + ["$"] = "\\$", ["&"] = "\\&", ["#"] = "\\#", ["%"] = "\\%", ["_"] = "\\_", + ["^"] = "\\textasciicircum{}", ["~"] = "\\textasciitilde{}", + ["'"] = "\\textquotesingle{}", ["`"] = "\\textasciigrave{}", + [" "] = "\\ ", +} + +function Code(el) + if not FORMAT:match("latex") then return nil end + local out = {} + for _, cp in utf8.codes(el.text) do + local ch = utf8.char(cp) + out[#out + 1] = ESCAPE[ch] or ch + if BREAK_AFTER[ch] then out[#out + 1] = "\\allowbreak{}" end + end + return pandoc.RawInline("latex", "\\texttt{" .. table.concat(out) .. "}") +end diff --git a/docs/book/pandoc/highlighting.latex b/docs/book/pandoc/highlighting.latex new file mode 100644 index 00000000..c8427f53 --- /dev/null +++ b/docs/book/pandoc/highlighting.latex @@ -0,0 +1,3 @@ +$if(highlighting-macros)$ +$highlighting-macros$ +$endif$ diff --git a/docs/book/pandoc/table-widths.lua b/docs/book/pandoc/table-widths.lua new file mode 100644 index 00000000..4f74a020 --- /dev/null +++ b/docs/book/pandoc/table-widths.lua @@ -0,0 +1,55 @@ +-- docs/book/pandoc/table-widths.lua +-- +-- pandoc's gfm reader leaves every column width unset, so the LaTeX writer +-- emits `l` columns and a table with long cells runs off the page. For any +-- table wider than WIDE characters, give each column a width proportional +-- to its longest cell (clamped to [MIN_COL, MAX_COL] characters); the +-- writer then emits wrapping p{} columns that together fill \linewidth. + +local WIDE = 72 +local MIN_COL = 6 +local MAX_COL = 60 + +local stringify = pandoc.utils.stringify + +local function measure(rows, widths) + for _, row in ipairs(rows) do + local col = 1 + for _, cell in ipairs(row.cells) do + local span = cell.col_span or 1 + local len = utf8.len(stringify(cell.contents)) or #stringify(cell.contents) + local per = len / span + for c = col, col + span - 1 do + if per > (widths[c] or 0) then widths[c] = per end + end + col = col + span + end + end +end + +function Table(tbl) + local n = #tbl.colspecs + local widths = {} + for i = 1, n do widths[i] = 0 end + + measure(tbl.head.rows, widths) + for _, body in ipairs(tbl.bodies) do + measure(body.head, widths) + measure(body.body, widths) + end + measure(tbl.foot.rows, widths) + + local total = 0 + for i = 1, n do total = total + widths[i] end + if total <= WIDE then return nil end + + local sum = 0 + for i = 1, n do + widths[i] = math.max(MIN_COL, math.min(MAX_COL, widths[i])) + sum = sum + widths[i] + end + for i = 1, n do + tbl.colspecs[i] = { tbl.colspecs[i][1], widths[i] / sum } + end + return tbl +end diff --git a/FABRIC-0.md b/docs/fabric/FABRIC-0.md similarity index 100% rename from FABRIC-0.md rename to docs/fabric/FABRIC-0.md diff --git a/FABRIC-1.md b/docs/fabric/FABRIC-1.md similarity index 100% rename from FABRIC-1.md rename to docs/fabric/FABRIC-1.md diff --git a/FABRIC-2.md b/docs/fabric/FABRIC-2.md similarity index 100% rename from FABRIC-2.md rename to docs/fabric/FABRIC-2.md diff --git a/FABRIC-3.5.md b/docs/fabric/FABRIC-3.5.md similarity index 100% rename from FABRIC-3.5.md rename to docs/fabric/FABRIC-3.5.md diff --git a/FABRIC-3.6.md b/docs/fabric/FABRIC-3.6.md similarity index 100% rename from FABRIC-3.6.md rename to docs/fabric/FABRIC-3.6.md diff --git a/FABRIC-3.7.md b/docs/fabric/FABRIC-3.7.md similarity index 100% rename from FABRIC-3.7.md rename to docs/fabric/FABRIC-3.7.md diff --git a/FABRIC-3.md b/docs/fabric/FABRIC-3.md similarity index 100% rename from FABRIC-3.md rename to docs/fabric/FABRIC-3.md diff --git a/FABRIC-4.md b/docs/fabric/FABRIC-4.md similarity index 100% rename from FABRIC-4.md rename to docs/fabric/FABRIC-4.md diff --git a/Makefile.starkernel b/kernel/Makefile similarity index 84% rename from Makefile.starkernel rename to kernel/Makefile index ccb035d1..2ea15960 100644 --- a/Makefile.starkernel +++ b/kernel/Makefile @@ -1,13 +1,13 @@ # ============================================================================== -# Makefile.starkernel โ€” StarKernel UEFI Build System +# kernel/Makefile โ€” StarKernel UEFI Build System # Multi-architecture: amd64 (x86_64), aarch64 (ARM64), riscv64 (RISC-V 64) # # Quick start: -# make -f Makefile.starkernel โ€” build for host arch -# make -f Makefile.starkernel ARCH=amd64 qemu โ€” build + boot (x86_64) -# make -f Makefile.starkernel ARCH=aarch64 qemu โ€” build + boot (aarch64) -# make -f Makefile.starkernel ARCH=riscv64 qemu โ€” build + boot (riscv64) -# make -f Makefile.starkernel help โ€” show all targets +# make -f kernel/Makefile โ€” build for host arch +# make -f kernel/Makefile ARCH=amd64 qemu โ€” build + boot (x86_64) +# make -f kernel/Makefile ARCH=aarch64 qemu โ€” build + boot (aarch64) +# make -f kernel/Makefile ARCH=riscv64 qemu โ€” build + boot (riscv64) +# make -f kernel/Makefile help โ€” show all targets # ============================================================================== # ============================================================================== @@ -64,7 +64,7 @@ $(eval $(call kconfig_bool,STARFORTH_ENABLE_VM,1)) MONOLITHIC ?= 1 # Parallel build โ€” use all available cores when not cleaning -# (adding -j when 'clean' is also a goal causes a race on include/version.h) +# (adding -j when 'clean' is also a goal causes a race on v3/include/version.h) NPROC := $(shell nproc 2>/dev/null || echo 4) ifeq ($(filter clean,$(MAKECMDGOALS)),) MAKEFLAGS += -j$(NPROC) @@ -106,9 +106,9 @@ KERNEL_OBJ_DIR := $(OBJ_DIR)/kernel LOADER_EFI := $(BUILD_DIR)/starkernel_loader.efi KERNEL_ELF := $(BUILD_DIR)/starkernel_kernel.elf -KERNEL_SRC := src/starkernel -KERNEL_INC := include/starkernel -STARFORTH_CONFIG_HEADER := include/starforth_config.h +KERNEL_SRC := kernel/src +KERNEL_INC := kernel/include/starkernel +STARFORTH_CONFIG_HEADER := v3/include/starforth_config.h QEMU_LOG_DIR := logs QEMU_ISO := $(BUILD_DIR)/starkernel.iso @@ -129,17 +129,17 @@ ARTDISK ?= disk/artemis.img # headroom above the current 9-device identity roster (Zuse + 8 minted identities) # rather than matching it exactly, per Bob's standing ruling against hardcoding a bound # to today's scale (FABRIC-3.md ยงVII.4). Override if a future test needs more, e.g. -# `make -f Makefile.starkernel qemu XHCI_PORTS=32`. +# `make -f kernel/Makefile qemu XHCI_PORTS=32`. XHCI_PORTS ?= 16 # ZUSEDISK -- Zuse's own minted USB thumbdrive, attached by default so a # plain `make qemu` lands already authenticated into the Zuse identity # (Captain Bob, 2026-08-28). Attached at QEMU launch time via -drive/ # -device on the qemu-xhci controller each arch's qemu target already -# creates; xhci_bringup()'s initial port scan (src/starkernel/usb/xhci.c) +# creates; xhci_bringup()'s initial port scan (kernel/src/usb/xhci.c) # is what makes an already-connected-at-launch device visible at all -- # xhci_poll_events() alone is purely hotplug-event-driven and would never # see a device present before controller reset. Override to "" (empty) to -# boot without Zuse attached, e.g. `make -f Makefile.starkernel qemu ZUSEDISK=`. +# boot without Zuse attached, e.g. `make -f kernel/Makefile qemu ZUSEDISK=`. ZUSEDISK ?= disk/thumbdrives/zuse-thumb-ident.img # Precomputed (not inlined as $(if ...,...)) because the drive/device specs # below are comma-heavy and GNU make's $(if) function splits its own @@ -153,10 +153,10 @@ else ZUSEDISK_QEMU_ARGS := endif MKCAPSULE_SRC = tools/mkcapsule.c tools/pkcs8_ed25519.c \ - src/starkernel/crypto/ed25519.c \ - src/starkernel/crypto/fe25519.c \ - src/starkernel/crypto/scalar25519.c \ - src/starkernel/crypto/sha512.c + kernel/src/crypto/ed25519.c \ + kernel/src/crypto/fe25519.c \ + kernel/src/crypto/scalar25519.c \ + kernel/src/crypto/sha512.c MKCAPSULE_BIN = $(BUILD_DIR)/tools/mkcapsule # Milestone 6 (Phase 8): the snakeoil intermediate's private key, generated # offline outside this repo entirely (see FABRIC-2.md's Phase 8 ยงMilestone 6 @@ -169,6 +169,28 @@ CAPSULE_GENERATED = $(BUILD_DIR)/capsule_generated.c CAPSULE_GENERATED_OBJ = $(BUILD_DIR)/capsule_generated.o CAPSULE_GENERATED_KOBJ = $(KERNEL_OBJ_DIR)/capsule_generated.o +# ============================================================================== +# BOARD (boot_image) +# ============================================================================== +# BOARD names a directory under boards/ (ser5, raspi, milkv, ...). Its +# board.mk sets BOARD_ARCH, BOARD_BOOT (how the firmware finds us) and +# BOARD_IMAGE (the single file written to the boot medium). The root +# Makefile's `make boot_image TARGET=` maps NAME to BOARD and passes +# ARCH=$(BOARD_ARCH); the kernel objects themselves are the ordinary +# build/$(ARCH)/kernel ones, shared with `make qemu`. +BOARD ?= +ifneq ($(strip $(BOARD)),) +ifeq ($(wildcard boards/$(BOARD)/board.mk),) + $(error Unknown BOARD='$(BOARD)': no boards/$(BOARD)/board.mk) +endif +include boards/$(BOARD)/board.mk +ifneq ($(BOARD_ARCH),$(ARCH)) + $(error BOARD=$(BOARD) is ARCH=$(BOARD_ARCH), but ARCH=$(ARCH) was requested) +endif +BOARD_OUT := build/boards/$(BOARD) +endif +BOOT_IMAGE_SIZE_MIB ?= 128 + # ============================================================================== # TOOLCHAIN # ============================================================================== @@ -195,8 +217,8 @@ ifeq ($(ARCH),amd64) # correctly. These flags come after COMMON_CFLAGS on the command line so # they win for amd64 only; riscv64/aarch64 keep -fPIC. ARCH_CFLAGS := -m64 -march=x86-64 -mno-red-zone -DARCH_AMD64 -fno-pic -fno-pie - LOADER_LINKER_SCRIPT := linker/starkernel-loader-amd64.ld - KERNEL_LINKER_SCRIPT := linker/starkernel-kernel-amd64.ld + LOADER_LINKER_SCRIPT := kernel/linker/starkernel-loader-amd64.ld + KERNEL_LINKER_SCRIPT := kernel/linker/starkernel-kernel-amd64.ld else ifeq ($(ARCH),aarch64) ifneq ($(shell which aarch64-linux-gnu-gcc 2>/dev/null),) @@ -211,14 +233,16 @@ else ifeq ($(ARCH),aarch64) $(error No ARM64 toolchain found. Install aarch64-linux-gnu-gcc or aarch64-none-elf-gcc) endif # aarch64 loader uses clang + lld-link (COFF target โ€” GCC cannot produce aarch64 PE) - LOADER_CC := clang-18 - # Debian/Ubuntu package only installs the versioned lld-link-18 on PATH by - # default (unversioned lld-link lives under /usr/lib/llvm-18/bin, which + # Any clang with the aarch64 COFF backend works; the version is not + # pinned (Ubuntu 26.04 ships clang-21, older hosts clang-18). + LOADER_CC := $(shell which clang 2>/dev/null || ls /usr/bin/clang-[0-9]* 2>/dev/null | sort -V | tail -1 || echo clang) + # Debian/Ubuntu package only installs the versioned lld-link-NN on PATH by + # default (unversioned lld-link lives under /usr/lib/llvm-NN/bin, which # isn't on PATH unless explicitly prepended) โ€” detect whichever resolves. - LOADER_LD := $(shell which lld-link 2>/dev/null || which lld-link-18 2>/dev/null || echo lld-link) + LOADER_LD := $(shell which lld-link 2>/dev/null || ls /usr/bin/lld-link-[0-9]* /usr/lib/llvm-*/bin/lld-link 2>/dev/null | sort -V | tail -1 || echo lld-link) ARCH_CFLAGS := -march=armv8-a -mcpu=cortex-a72 -DARCH_AARCH64 -mno-outline-atomics - LOADER_LINKER_SCRIPT := linker/starkernel-loader-aarch64.ld - KERNEL_LINKER_SCRIPT := linker/starkernel-kernel-aarch64.ld + LOADER_LINKER_SCRIPT := kernel/linker/starkernel-loader-aarch64.ld + KERNEL_LINKER_SCRIPT := kernel/linker/starkernel-kernel-aarch64.ld else ifeq ($(ARCH),riscv64) ifneq ($(shell which riscv64-unknown-elf-gcc 2>/dev/null),) @@ -233,8 +257,8 @@ else ifeq ($(ARCH),riscv64) $(error No RISC-V toolchain found. Install riscv64-unknown-elf-gcc or riscv64-linux-gnu-gcc) endif ARCH_CFLAGS := -march=rv64gc -mabi=lp64d -DARCH_RISCV64 - LOADER_LINKER_SCRIPT := linker/starkernel-loader-riscv64.ld - KERNEL_LINKER_SCRIPT := linker/starkernel-kernel-riscv64.ld + LOADER_LINKER_SCRIPT := kernel/linker/starkernel-loader-riscv64.ld + KERNEL_LINKER_SCRIPT := kernel/linker/starkernel-kernel-riscv64.ld endif # Default loader toolchain = kernel toolchain (overridden for aarch64 above) @@ -260,13 +284,13 @@ COMMON_CFLAGS := \ -ffreestanding -nostdlib -fno-builtin \ -fPIC -fvisibility=hidden -fno-stack-protector -fshort-wchar \ $(ARCH_CFLAGS) \ - -I$(KERNEL_INC) -Iinclude -Isrc \ + -I$(KERNEL_INC) -Iv3/include -Ikernel/include -Iv3/src \ -include $(STARFORTH_CONFIG_HEADER) \ -DPARITY_MODE=$(PARITY_MODE) VMCORE_CFLAGS_COMMON := \ $(filter-out -I$(KERNEL_INC),$(COMMON_CFLAGS)) \ - -Iinclude -I. -Isrc/word_source -Isrc/test_runner/include \ + -Iv3/include -Ikernel/include -I. -Iv3/src/word_source -Iv3/src/test_runner/include \ -Wno-error=unused-parameter -Wno-error=shift-negative-value \ -Wno-error=sign-compare -Wno-error=missing-field-initializers @@ -281,8 +305,8 @@ LOADER_BASE_CFLAGS := \ -mno-stack-arg-probe \ -march=armv8-a \ -DARCH_AARCH64 \ - -I$(KERNEL_INC) -Iinclude -Isrc \ - -Iinclude/starkernel/freestanding \ + -I$(KERNEL_INC) -Iv3/include -Ikernel/include -Iv3/src \ + -Ikernel/include/starkernel/freestanding \ -include $(STARFORTH_CONFIG_HEADER) \ -DPARITY_MODE=$(PARITY_MODE) \ -DPLATFORM_TIME_NO_INLINE @@ -308,7 +332,7 @@ ifeq ($(ARCH),aarch64) else ifeq ($(ARCH),riscv64) LOADER_LDFLAGS_PE := # ELFโ†’objcopy pipeline in link rule else - LOADER_LINKER_SCRIPT_PE := linker/starkernel-loader-amd64-pe.ld + LOADER_LINKER_SCRIPT_PE := kernel/linker/starkernel-loader-amd64-pe.ld LOADER_LDFLAGS_PE := \ -T $(LOADER_LINKER_SCRIPT_PE) -m i386pep -nostdlib \ --enable-reloc-section --image-base 0 --subsystem 10 -e efi_main @@ -429,7 +453,7 @@ LOADER_CFLAGS += $(VM_FEATURE_OVERRIDES) endif # SK_CMD โ€” optional startup FORTH script injected before the interactive REPL. -# Usage: make -f Makefile.starkernel qemu SK_CMD="TIME-TICKS . BYE" +# Usage: make -f kernel/Makefile qemu SK_CMD="TIME-TICKS . BYE" ifdef SK_CMD KERNEL_CFLAGS += -DSK_STARTUP_FORTH='"$(SK_CMD)"' LOADER_CFLAGS += -DSK_STARTUP_FORTH='"$(SK_CMD)"' @@ -439,7 +463,7 @@ endif # The loader reads this file from the EFI partition and parses it at boot. # Supported flags: --doe --log-level= # --stack=[MG] --heap=[MG] -# Usage: make -f Makefile.starkernel qemu KERNEL_ARGS="--doe --log-level=info" +# Usage: make -f kernel/Makefile qemu KERNEL_ARGS="--doe --log-level=info" KERNEL_ARGS ?= # ============================================================================== @@ -534,19 +558,19 @@ KERNEL_ASM := $(wildcard $(KERNEL_SRC)/arch/$(ARCH)/*.S) ifeq ($(STARFORTH_ENABLE_VM),1) VM_ALL_SRCS := \ - $(wildcard src/*.c) \ - $(wildcard src/word_source/*.c) \ - $(wildcard src/test_runner/*.c) \ - $(wildcard src/test_runner/modules/*.c) + $(wildcard v3/src/*.c) \ + $(wildcard v3/src/word_source/*.c) \ + $(wildcard v3/src/test_runner/*.c) \ + $(wildcard v3/src/test_runner/modules/*.c) VM_EXCLUDE := \ - src/main.c src/cli.c src/repl.c \ - src/platform/% \ - src/blkio_factory.c src/blkio_file.c \ - src/log.c src/doe_metrics.c \ - src/vm.c src/vm_core.c src/vm_bootstrap.c src/vm_runtime.c src/vm_time.c \ - src/word_source/q48_16_words.c \ - src/test_runner/modules/break_me_tests.c + v3/src/main.c v3/src/cli.c v3/src/repl.c \ + v3/src/platform/% \ + v3/src/blkio_factory.c v3/src/blkio_file.c \ + v3/src/log.c v3/src/doe_metrics.c \ + v3/src/vm.c v3/src/vm_core.c v3/src/vm_bootstrap.c v3/src/vm_runtime.c v3/src/vm_time.c \ + v3/src/word_source/q48_16_words.c \ + v3/src/test_runner/modules/break_me_tests.c VM_CORE_SRCS := $(filter-out $(VM_EXCLUDE),$(VM_ALL_SRCS)) @@ -569,8 +593,8 @@ LOADER_EXTRA_SRCS := \ KERNEL_EXTRA_SRCS := $(LOADER_EXTRA_SRCS) -LOADER_VM_OBJS := $(patsubst src/%.c,$(LOADER_OBJ_DIR)/vmcore/%.o,$(VM_CORE_SRCS)) -KERNEL_VM_OBJS := $(patsubst src/%.c,$(KERNEL_OBJ_DIR)/vmcore/%.o,$(VM_CORE_SRCS)) +LOADER_VM_OBJS := $(patsubst v3/src/%.c,$(LOADER_OBJ_DIR)/vmcore/%.o,$(VM_CORE_SRCS)) +KERNEL_VM_OBJS := $(patsubst v3/src/%.c,$(KERNEL_OBJ_DIR)/vmcore/%.o,$(VM_CORE_SRCS)) endif LOADER_SRCS := $(LOADER_SRCS_BASE) $(LOADER_EXTRA_SRCS) @@ -603,7 +627,7 @@ KERNEL_OBJS := \ # MAIN TARGETS # ============================================================================== -all: include/version.h $(CAPSULE_GENERATED_OBJ) $(CAPSULE_GENERATED_KOBJ) $(LOADER_EFI) $(KERNEL_ELF) +all: v3/include/version.h $(CAPSULE_GENERATED_OBJ) $(CAPSULE_GENERATED_KOBJ) $(LOADER_EFI) $(KERNEL_ELF) @echo "StarKernel built successfully for $(ARCH)" @echo " Loader: $(LOADER_EFI)" @echo " Kernel: $(KERNEL_ELF)" @@ -611,13 +635,13 @@ all: include/version.h $(CAPSULE_GENERATED_OBJ) $(CAPSULE_GENERATED_KOBJ) $(LOAD kernel: all kernel-all: - @$(MAKE) -f Makefile.starkernel ARCH=amd64 TARGET=$(TARGET) - @$(MAKE) -f Makefile.starkernel ARCH=aarch64 TARGET=$(TARGET) - @$(MAKE) -f Makefile.starkernel ARCH=riscv64 TARGET=$(TARGET) + @$(MAKE) -f kernel/Makefile ARCH=amd64 TARGET=$(TARGET) + @$(MAKE) -f kernel/Makefile ARCH=aarch64 TARGET=$(TARGET) + @$(MAKE) -f kernel/Makefile ARCH=riscv64 TARGET=$(TARGET) clean: rm -rf build/$(ARCH)/$(TARGET) - rm -f include/version.h + rm -f v3/include/version.h clean-kernel: @echo "Cleaning all StarKernel build artifacts..." @@ -636,8 +660,8 @@ FORCE: # here after a hosted `make` run silently reuses that stale/wrong-flavored file # and fails with "LITHOS_VERSION_STR undeclared" deep in kernel_main.c, instead # of regenerating its own correct version. -include/version.h: FORCE - @mkdir -p include +v3/include/version.h: FORCE + @mkdir -p v3/include @BUILD_TS=$$(date -Iseconds 2>/dev/null || echo "unknown"); \ printf '#ifndef STARFORTH_VERSION_H\n#define STARFORTH_VERSION_H\n\n' > $@; \ printf '#define STARFORTH_VERSION "%s"\n' "$(VERSION)" >> $@; \ @@ -653,7 +677,7 @@ include/version.h: FORCE $(MKCAPSULE_BIN): $(MKCAPSULE_SRC) @mkdir -p $(dir $@) @echo "HOSTCC $(MKCAPSULE_SRC)" - @cc -std=c99 -Wall -Wextra -O2 -Iinclude -Itools -o $@ $(MKCAPSULE_SRC) + @cc -std=c99 -Wall -Wextra -O2 -Iv3/include -Ikernel/include -Itools -o $@ $(MKCAPSULE_SRC) # Generate capsule_generated.c from capsules/ CAPSULE_SRCS := $(shell find $(CAPSULES_DIR) -type f ! -name '.*' 2>/dev/null) @@ -695,12 +719,12 @@ $(LOADER_OBJ_DIR)/%.o: $(KERNEL_SRC)/%.c | $(LOADER_OBJ_DIR) @$(LOADER_CC) $(LOADER_CFLAGS) -c $< -o $@ # Compile loader VM core sources -$(LOADER_OBJ_DIR)/vmcore/%.o: src/%.c include/version.h | $(LOADER_OBJ_DIR) +$(LOADER_OBJ_DIR)/vmcore/%.o: v3/src/%.c v3/include/version.h | $(LOADER_OBJ_DIR) @mkdir -p $(dir $@) @echo "CC (loader) $<" ifeq ($(ARCH),aarch64) @$(LOADER_CC) $(LOADER_CFLAGS) \ - -Iinclude -I. -Isrc/test_runner/include \ + -Iv3/include -Ikernel/include -I. -Iv3/src/test_runner/include \ -Wno-error=unused-parameter -Wno-error=shift-negative-value \ -Wno-error=sign-compare -Wno-error=missing-field-initializers \ -Wno-unused-function \ @@ -722,10 +746,10 @@ $(KERNEL_OBJ_DIR)/%.o: $(KERNEL_SRC)/%.c | $(KERNEL_OBJ_DIR) @$(CC) $(KERNEL_CFLAGS) -c $< -o $@ # Compile kernel VM core sources -$(KERNEL_OBJ_DIR)/vmcore/%.o: src/%.c include/version.h | $(KERNEL_OBJ_DIR) +$(KERNEL_OBJ_DIR)/vmcore/%.o: v3/src/%.c v3/include/version.h | $(KERNEL_OBJ_DIR) @mkdir -p $(dir $@) @echo "CC (kernel) $<" - @$(CC) $(VMCORE_CFLAGS_COMMON) $(filter-out -I$(KERNEL_INC),$(KERNEL_CFLAGS)) -Isrc/starkernel/vm -c $< -o $@ + @$(CC) $(VMCORE_CFLAGS_COMMON) $(filter-out -I$(KERNEL_INC),$(KERNEL_CFLAGS)) -Ikernel/src/vm -c $< -o $@ # Compile kernel assembly sources $(KERNEL_OBJ_DIR)/%.o: $(KERNEL_SRC)/%.S | $(KERNEL_OBJ_DIR) @@ -802,7 +826,7 @@ OVMF_CODE := /usr/share/OVMF/OVMF_CODE_4M.fd OVMF_VARS_RO := /usr/share/OVMF/OVMF_VARS_4M.fd # QEMU_DISPLAY โ€” window backend for the framebuffer console (gtk/sdl/none/...). -# Usage: make -f Makefile.starkernel qemu QEMU_DISPLAY=none # headless/CI +# Usage: make -f kernel/Makefile qemu QEMU_DISPLAY=none # headless/CI QEMU_DISPLAY ?= gtk # QEMU_EXTRA โ€” extra raw qemu-system-* args appended verbatim to every arch's @@ -1072,38 +1096,98 @@ else ifeq ($(ARCH),riscv64) # fallback boot path EFI/BOOT/BOOT.EFI. Storage on real hardware is the # USB BOT/xHCI path (already live), not virtio. thumbdrive: all - @mkdir -p $(BUILD_DIR) - @if ! which sgdisk >/dev/null 2>&1; then echo "Error: sgdisk not found. Install gdisk (apt-get install gdisk)."; exit 1; fi - @if ! which mkfs.fat >/dev/null 2>&1; then echo "Error: mkfs.fat not found. Install dosfstools (apt-get install dosfstools)."; exit 1; fi - @case "$(ARCH)" in \ - amd64) BOOTNAME="BOOTX64.EFI" ;; \ - aarch64) BOOTNAME="BOOTAA64.EFI" ;; \ - riscv64) BOOTNAME="BOOTRISCV64.EFI" ;; \ - *) echo "Error: no thumbdrive EFI boot name for ARCH=$(ARCH)"; exit 1 ;; \ - esac; \ - # Geometry: 128 MiB disk (262144 sectors), GPT partition 1 spans sectors \ - # 2048..262110 (the GPT last-usable sector for this disk size), i.e. \ - # 260063 sectors. The FAT32 ESP image MUST match the partition size \ - # exactly; a larger ESP overruns the disk (GPT grows corrupt) or \ - # spills past the partition end, both of which made earlier builds \ - # unbootable on hardware. \ - DISK=$(BUILD_DIR)/starkernel-thumbdrive.img; \ - ESP_SECTORS=260063; \ - rm -f $$DISK $(BUILD_DIR)/thumbdrive-esp.img; \ - dd if=/dev/zero of=$(BUILD_DIR)/thumbdrive-esp.img bs=512 count=$$ESP_SECTORS 2>/dev/null; \ - mkfs.fat -F 32 -n "STARKERNEL" $(BUILD_DIR)/thumbdrive-esp.img >/dev/null 2>&1; \ - mmd -i $(BUILD_DIR)/thumbdrive-esp.img ::/EFI; \ - mmd -i $(BUILD_DIR)/thumbdrive-esp.img ::/EFI/BOOT; \ - mcopy -i $(BUILD_DIR)/thumbdrive-esp.img $(LOADER_EFI) ::/EFI/BOOT/$$BOOTNAME; \ - printf 'FS0:\\EFI\\BOOT\\%s\r\n' "$$BOOTNAME" > $(BUILD_DIR)/thumbdrive-startup.nsh; \ - mcopy -i $(BUILD_DIR)/thumbdrive-esp.img $(BUILD_DIR)/thumbdrive-startup.nsh ::/startup.nsh; \ - dd if=/dev/zero of=$$DISK bs=1M count=128 2>/dev/null; \ - sgdisk -n 1:2048:0 -t 1:ef00 -c 1:"EFI System" $$DISK >/dev/null 2>&1; \ - dd if=$(BUILD_DIR)/thumbdrive-esp.img of=$$DISK bs=512 seek=2048 conv=notrunc 2>/dev/null; \ - rm -f $(BUILD_DIR)/thumbdrive-esp.img $(BUILD_DIR)/thumbdrive-startup.nsh; \ - echo "Thumbdrive image: $$DISK"; \ - echo "Write to a USB stick with: dd if=$$DISK of=/dev/sdX bs=4M status=progress" + @printf 'FS0:\\EFI\\BOOT\\%s\r\n' "$(EFI_BOOTNAME)" > $(BUILD_DIR)/thumbdrive-startup.nsh + @bash scripts/mkdiskimage.sh --out $(BUILD_DIR)/starkernel-thumbdrive.img --table gpt \ + --size-mib 128 --label STARKERNEL \ + $(LOADER_EFI):/EFI/BOOT/$(EFI_BOOTNAME) \ + $(BUILD_DIR)/thumbdrive-startup.nsh:/startup.nsh + @rm -f $(BUILD_DIR)/thumbdrive-startup.nsh + @echo "Write to a USB stick with: dd if=$(BUILD_DIR)/starkernel-thumbdrive.img of=/dev/sdX bs=4M status=progress" +# ============================================================================== +# BOOT IMAGES (one per board) +# ============================================================================== +# boot_image -- the single file written to a board's boot medium. Driven by +# BOARD (boards//board.mk); normally invoked from the repo root as +# make boot_image TARGET=SER5|RASPI|MILKV|ZYNQ7020 +# Output: build/boards//$(BOARD_IMAGE). +# +# BOARD_BOOT selects the recipe: +# uefi-esp -- GPT disk, one FAT32 EFI System Partition holding the +# monolithic loader as EFI/BOOT/BOOT.EFI (+ startup.nsh +# for the UEFI shell, + starforth.cfg when KERNEL_ARGS is set). +# Real UEFI firmware (SER5) and U-Boot's bootefi (Milk-V) both +# boot it through the removable-media fallback path. +# rpi-native -- MBR disk, one FAT32 (LBA) partition holding config.txt, +# kernel_2712.img (kernel relinked at 0x80000 and flattened) +# and the stock BCM2712 DTB (+ cmdline.txt, which firmware +# copies into /chosen/bootargs, when KERNEL_ARGS is set). +ifeq ($(ARCH),amd64) +EFI_BOOTNAME := BOOTX64.EFI +else ifeq ($(ARCH),aarch64) +EFI_BOOTNAME := BOOTAA64.EFI +else ifeq ($(ARCH),riscv64) +EFI_BOOTNAME := BOOTRISCV64.EFI +endif + +RPI5_NATIVE_LINKER_SCRIPT := kernel/linker/starkernel-native-rpi5.ld +RPI5_NATIVE_ELF := $(BUILD_DIR)/starkernel_rpi5.elf +RPI5_NATIVE_IMG := $(BUILD_DIR)/kernel_2712.img + +$(RPI5_NATIVE_ELF): $(KERNEL_OBJS) $(RPI5_NATIVE_LINKER_SCRIPT) | $(BUILD_DIR) + @echo "LD (rpi5 native) $@" + @$(LD) -T $(RPI5_NATIVE_LINKER_SCRIPT) -nostdlib --build-id=none \ + -e rpi5_native_start $(KERNEL_OBJS) -o $@ + +$(RPI5_NATIVE_IMG): $(RPI5_NATIVE_ELF) + @echo "OBJCOPY (raw) $@" + @$(OBJCOPY) -O binary $< $@ + +.PHONY: boot_image +ifeq ($(strip $(BOARD)),) +boot_image: + @echo "boot_image needs a board. From the repo root:" + @echo " make boot_image TARGET=SER5|RASPI|MILKV|ZYNQ7020" + @exit 1 +else ifeq ($(BOARD_BOOT),uefi-esp) +boot_image: all + @mkdir -p $(BOARD_OUT) + @printf 'FS0:\\EFI\\BOOT\\%s\r\n' "$(EFI_BOOTNAME)" > $(BOARD_OUT)/startup.nsh + @rm -f $(BOARD_OUT)/starforth.cfg + $(if $(KERNEL_ARGS),@printf '%s\n' '$(KERNEL_ARGS)' > $(BOARD_OUT)/starforth.cfg) + @bash scripts/mkdiskimage.sh --out $(BOARD_OUT)/$(BOARD_IMAGE) --table gpt \ + --size-mib $(BOOT_IMAGE_SIZE_MIB) --label LITHOS \ + $(LOADER_EFI):/EFI/BOOT/$(EFI_BOOTNAME) \ + $(BOARD_OUT)/startup.nsh:/startup.nsh \ + $(if $(KERNEL_ARGS),$(BOARD_OUT)/starforth.cfg:/starforth.cfg) + @echo "$(BOARD_DESC)" + @echo "Write with: dd if=$(BOARD_OUT)/$(BOARD_IMAGE) of=/dev/sdX bs=4M conv=fsync status=progress" +else ifeq ($(BOARD_BOOT),rpi-native) +$(RPI5_DTB): + @mkdir -p $(dir $@) + @echo " FETCH $(RPI5_DTB_URL)" + @curl -fsSL -o $@.tmp $(RPI5_DTB_URL) || { rm -f $@.tmp; \ + echo "Error: could not fetch the Pi 5 DTB. Copy bcm2712-rpi-5-b.dtb from a Raspberry Pi"; \ + echo "firmware release and pass RPI5_DTB=/path/to/bcm2712-rpi-5-b.dtb"; exit 1; } + @mv $@.tmp $@ + +boot_image: v3/include/version.h $(RPI5_NATIVE_IMG) $(RPI5_DTB) + @mkdir -p $(BOARD_OUT) + @rm -f $(BOARD_OUT)/cmdline.txt + $(if $(KERNEL_ARGS),@printf '%s\n' '$(KERNEL_ARGS)' > $(BOARD_OUT)/cmdline.txt) + @bash scripts/mkdiskimage.sh --out $(BOARD_OUT)/$(BOARD_IMAGE) --table mbr \ + --size-mib $(BOOT_IMAGE_SIZE_MIB) --label LITHOS \ + boards/$(BOARD)/config.txt:/config.txt \ + $(RPI5_NATIVE_IMG):/kernel_2712.img \ + $(RPI5_DTB):/bcm2712-rpi-5-b.dtb \ + $(if $(KERNEL_ARGS),$(BOARD_OUT)/cmdline.txt:/cmdline.txt) + @echo "$(BOARD_DESC)" + @echo "Write with: dd if=$(BOARD_OUT)/$(BOARD_IMAGE) of=/dev/mmcblkX bs=4M conv=fsync status=progress" +else +boot_image: + @echo "Error: BOARD=$(BOARD) has BOARD_BOOT='$(BOARD_BOOT)', which has no boot_image recipe" + @exit 1 +endif # iso-usb โ€” build a PURE UEFI isohybrid ISO for the Iso Image Writer workflow # (GNOME Disks "Restore Disk Image...", or dd). Writes a single .iso to a USB @@ -1150,7 +1234,7 @@ iso-usb: all # yourself with Ctrl-A X or by closing the window). # amd64/aarch64: serial โ†’ stdio (bidirectional, you can type into the REPL); # riscv64: uses proper GPT (esp dir not supported) -qemu-esp: include/version.h $(LOADER_EFI) $(KERNEL_ELF) +qemu-esp: v3/include/version.h $(LOADER_EFI) $(KERNEL_ELF) ifeq ($(ARCH),amd64) @rm -rf $(BUILD_DIR)/esp @mkdir -p $(BUILD_DIR)/esp/EFI/BOOT @@ -1206,7 +1290,7 @@ else ifeq ($(ARCH),riscv64) endif # qemu-gdb โ€” launch QEMU with GDB stub on port 1234 -qemu-gdb: include/version.h $(LOADER_EFI) $(KERNEL_ELF) +qemu-gdb: v3/include/version.h $(LOADER_EFI) $(KERNEL_ELF) ifeq ($(ARCH),amd64) @mkdir -p $(BUILD_DIR)/esp/EFI/BOOT @cp $(LOADER_EFI) $(BUILD_DIR)/esp/EFI/BOOT/BOOTX64.EFI @@ -1259,7 +1343,7 @@ help: @echo "StarKernel Build System" @echo "=======================" @echo "" - @echo "Usage: make -f Makefile.starkernel [ARCH=] [TARGET=] " + @echo "Usage: make -f kernel/Makefile [ARCH=] [TARGET=] " @echo "" @echo "Architectures (aliases accepted):" @echo " ARCH=amd64 / x86_64 โ€” x86-64 (default on x86 host)" @@ -1289,8 +1373,8 @@ help: @echo " help โ€” show this message" @echo "" @echo "Examples:" - @echo " make -f Makefile.starkernel ARCH=amd64 qemu" - @echo " make -f Makefile.starkernel ARCH=aarch64 clean qemu" - @echo " make -f Makefile.starkernel ARCH=riscv64 clean qemu" - @echo " make -f Makefile.starkernel ARCH=x86_64 qemu # alias works" - @echo " make -f Makefile.starkernel kernel-all" + @echo " make -f kernel/Makefile ARCH=amd64 qemu" + @echo " make -f kernel/Makefile ARCH=aarch64 clean qemu" + @echo " make -f kernel/Makefile ARCH=riscv64 clean qemu" + @echo " make -f kernel/Makefile ARCH=x86_64 qemu # alias works" + @echo " make -f kernel/Makefile kernel-all" diff --git a/include/starkernel/README.md b/kernel/include/starkernel/README.md similarity index 100% rename from include/starkernel/README.md rename to kernel/include/starkernel/README.md diff --git a/include/starkernel/apic.h b/kernel/include/starkernel/apic.h similarity index 100% rename from include/starkernel/apic.h rename to kernel/include/starkernel/apic.h diff --git a/include/starkernel/arch.h b/kernel/include/starkernel/arch.h similarity index 100% rename from include/starkernel/arch.h rename to kernel/include/starkernel/arch.h diff --git a/include/starkernel/artemis_sig.h b/kernel/include/starkernel/artemis_sig.h similarity index 100% rename from include/starkernel/artemis_sig.h rename to kernel/include/starkernel/artemis_sig.h diff --git a/include/starkernel/blkio_usb.h b/kernel/include/starkernel/blkio_usb.h similarity index 100% rename from include/starkernel/blkio_usb.h rename to kernel/include/starkernel/blkio_usb.h diff --git a/include/starkernel/boot_info_offsets.h b/kernel/include/starkernel/boot_info_offsets.h similarity index 100% rename from include/starkernel/boot_info_offsets.h rename to kernel/include/starkernel/boot_info_offsets.h diff --git a/include/starkernel/capsule.h b/kernel/include/starkernel/capsule.h similarity index 100% rename from include/starkernel/capsule.h rename to kernel/include/starkernel/capsule.h diff --git a/include/starkernel/capsule_birth.h b/kernel/include/starkernel/capsule_birth.h similarity index 100% rename from include/starkernel/capsule_birth.h rename to kernel/include/starkernel/capsule_birth.h diff --git a/include/starkernel/capsule_console.h b/kernel/include/starkernel/capsule_console.h similarity index 100% rename from include/starkernel/capsule_console.h rename to kernel/include/starkernel/capsule_console.h diff --git a/include/starkernel/capsule_generated.h b/kernel/include/starkernel/capsule_generated.h similarity index 100% rename from include/starkernel/capsule_generated.h rename to kernel/include/starkernel/capsule_generated.h diff --git a/include/starkernel/capsule_loader.h b/kernel/include/starkernel/capsule_loader.h similarity index 100% rename from include/starkernel/capsule_loader.h rename to kernel/include/starkernel/capsule_loader.h diff --git a/include/starkernel/capsule_mint.h b/kernel/include/starkernel/capsule_mint.h similarity index 100% rename from include/starkernel/capsule_mint.h rename to kernel/include/starkernel/capsule_mint.h diff --git a/include/starkernel/capsule_run.h b/kernel/include/starkernel/capsule_run.h similarity index 100% rename from include/starkernel/capsule_run.h rename to kernel/include/starkernel/capsule_run.h diff --git a/include/starkernel/capsule_runcap.h b/kernel/include/starkernel/capsule_runcap.h similarity index 100% rename from include/starkernel/capsule_runcap.h rename to kernel/include/starkernel/capsule_runcap.h diff --git a/include/starkernel/capsule_sig.h b/kernel/include/starkernel/capsule_sig.h similarity index 100% rename from include/starkernel/capsule_sig.h rename to kernel/include/starkernel/capsule_sig.h diff --git a/include/starkernel/capsule_vm_physics.h b/kernel/include/starkernel/capsule_vm_physics.h similarity index 100% rename from include/starkernel/capsule_vm_physics.h rename to kernel/include/starkernel/capsule_vm_physics.h diff --git a/include/starkernel/capsule_vm_switch_signal.h b/kernel/include/starkernel/capsule_vm_switch_signal.h similarity index 100% rename from include/starkernel/capsule_vm_switch_signal.h rename to kernel/include/starkernel/capsule_vm_switch_signal.h diff --git a/include/starkernel/capsule_wirebind.h b/kernel/include/starkernel/capsule_wirebind.h similarity index 100% rename from include/starkernel/capsule_wirebind.h rename to kernel/include/starkernel/capsule_wirebind.h diff --git a/include/starkernel/capsule_zuse_boot.h b/kernel/include/starkernel/capsule_zuse_boot.h similarity index 100% rename from include/starkernel/capsule_zuse_boot.h rename to kernel/include/starkernel/capsule_zuse_boot.h diff --git a/include/starkernel/cmdline.h b/kernel/include/starkernel/cmdline.h similarity index 100% rename from include/starkernel/cmdline.h rename to kernel/include/starkernel/cmdline.h diff --git a/include/starkernel/console.h b/kernel/include/starkernel/console.h similarity index 100% rename from include/starkernel/console.h rename to kernel/include/starkernel/console.h diff --git a/include/starkernel/doe_log.h b/kernel/include/starkernel/doe_log.h similarity index 100% rename from include/starkernel/doe_log.h rename to kernel/include/starkernel/doe_log.h diff --git a/include/starkernel/ed25519.h b/kernel/include/starkernel/ed25519.h similarity index 100% rename from include/starkernel/ed25519.h rename to kernel/include/starkernel/ed25519.h diff --git a/include/starkernel/elf64.h b/kernel/include/starkernel/elf64.h similarity index 100% rename from include/starkernel/elf64.h rename to kernel/include/starkernel/elf64.h diff --git a/include/starkernel/elf_loader.h b/kernel/include/starkernel/elf_loader.h similarity index 100% rename from include/starkernel/elf_loader.h rename to kernel/include/starkernel/elf_loader.h diff --git a/include/starkernel/fdt.h b/kernel/include/starkernel/fdt.h similarity index 100% rename from include/starkernel/fdt.h rename to kernel/include/starkernel/fdt.h diff --git a/include/starkernel/fe25519.h b/kernel/include/starkernel/fe25519.h similarity index 100% rename from include/starkernel/fe25519.h rename to kernel/include/starkernel/fe25519.h diff --git a/include/starkernel/framebuffer.h b/kernel/include/starkernel/framebuffer.h similarity index 100% rename from include/starkernel/framebuffer.h rename to kernel/include/starkernel/framebuffer.h diff --git a/include/starkernel/freestanding/README.md b/kernel/include/starkernel/freestanding/README.md similarity index 100% rename from include/starkernel/freestanding/README.md rename to kernel/include/starkernel/freestanding/README.md diff --git a/include/starkernel/freestanding/assert.h b/kernel/include/starkernel/freestanding/assert.h similarity index 100% rename from include/starkernel/freestanding/assert.h rename to kernel/include/starkernel/freestanding/assert.h diff --git a/include/starkernel/freestanding/ctype.h b/kernel/include/starkernel/freestanding/ctype.h similarity index 100% rename from include/starkernel/freestanding/ctype.h rename to kernel/include/starkernel/freestanding/ctype.h diff --git a/include/starkernel/freestanding/errno.h b/kernel/include/starkernel/freestanding/errno.h similarity index 100% rename from include/starkernel/freestanding/errno.h rename to kernel/include/starkernel/freestanding/errno.h diff --git a/include/starkernel/freestanding/inttypes.h b/kernel/include/starkernel/freestanding/inttypes.h similarity index 100% rename from include/starkernel/freestanding/inttypes.h rename to kernel/include/starkernel/freestanding/inttypes.h diff --git a/include/starkernel/freestanding/math.h b/kernel/include/starkernel/freestanding/math.h similarity index 100% rename from include/starkernel/freestanding/math.h rename to kernel/include/starkernel/freestanding/math.h diff --git a/include/starkernel/freestanding/sched.h b/kernel/include/starkernel/freestanding/sched.h similarity index 100% rename from include/starkernel/freestanding/sched.h rename to kernel/include/starkernel/freestanding/sched.h diff --git a/include/starkernel/freestanding/signal.h b/kernel/include/starkernel/freestanding/signal.h similarity index 100% rename from include/starkernel/freestanding/signal.h rename to kernel/include/starkernel/freestanding/signal.h diff --git a/include/starkernel/freestanding/stdio.h b/kernel/include/starkernel/freestanding/stdio.h similarity index 100% rename from include/starkernel/freestanding/stdio.h rename to kernel/include/starkernel/freestanding/stdio.h diff --git a/include/starkernel/freestanding/stdlib.h b/kernel/include/starkernel/freestanding/stdlib.h similarity index 100% rename from include/starkernel/freestanding/stdlib.h rename to kernel/include/starkernel/freestanding/stdlib.h diff --git a/include/starkernel/freestanding/string.h b/kernel/include/starkernel/freestanding/string.h similarity index 100% rename from include/starkernel/freestanding/string.h rename to kernel/include/starkernel/freestanding/string.h diff --git a/include/starkernel/freestanding/sys/README.md b/kernel/include/starkernel/freestanding/sys/README.md similarity index 100% rename from include/starkernel/freestanding/sys/README.md rename to kernel/include/starkernel/freestanding/sys/README.md diff --git a/include/starkernel/freestanding/sys/time.h b/kernel/include/starkernel/freestanding/sys/time.h similarity index 100% rename from include/starkernel/freestanding/sys/time.h rename to kernel/include/starkernel/freestanding/sys/time.h diff --git a/include/starkernel/freestanding/sys/types.h b/kernel/include/starkernel/freestanding/sys/types.h similarity index 100% rename from include/starkernel/freestanding/sys/types.h rename to kernel/include/starkernel/freestanding/sys/types.h diff --git a/include/starkernel/freestanding/time.h b/kernel/include/starkernel/freestanding/time.h similarity index 100% rename from include/starkernel/freestanding/time.h rename to kernel/include/starkernel/freestanding/time.h diff --git a/include/starkernel/hal/README.md b/kernel/include/starkernel/hal/README.md similarity index 100% rename from include/starkernel/hal/README.md rename to kernel/include/starkernel/hal/README.md diff --git a/include/starkernel/hal/hal.h b/kernel/include/starkernel/hal/hal.h similarity index 100% rename from include/starkernel/hal/hal.h rename to kernel/include/starkernel/hal/hal.h diff --git a/include/starkernel/hal_memory.h b/kernel/include/starkernel/hal_memory.h similarity index 100% rename from include/starkernel/hal_memory.h rename to kernel/include/starkernel/hal_memory.h diff --git a/include/starkernel/homeblocks_sig.h b/kernel/include/starkernel/homeblocks_sig.h similarity index 100% rename from include/starkernel/homeblocks_sig.h rename to kernel/include/starkernel/homeblocks_sig.h diff --git a/include/starkernel/i8042.h b/kernel/include/starkernel/i8042.h similarity index 100% rename from include/starkernel/i8042.h rename to kernel/include/starkernel/i8042.h diff --git a/include/starkernel/ioapic.h b/kernel/include/starkernel/ioapic.h similarity index 100% rename from include/starkernel/ioapic.h rename to kernel/include/starkernel/ioapic.h diff --git a/include/starkernel/kernel_args.h b/kernel/include/starkernel/kernel_args.h similarity index 100% rename from include/starkernel/kernel_args.h rename to kernel/include/starkernel/kernel_args.h diff --git a/include/starkernel/kmalloc.h b/kernel/include/starkernel/kmalloc.h similarity index 100% rename from include/starkernel/kmalloc.h rename to kernel/include/starkernel/kmalloc.h diff --git a/include/starkernel/log.h b/kernel/include/starkernel/log.h similarity index 100% rename from include/starkernel/log.h rename to kernel/include/starkernel/log.h diff --git a/include/starkernel/log_attrib.h b/kernel/include/starkernel/log_attrib.h similarity index 100% rename from include/starkernel/log_attrib.h rename to kernel/include/starkernel/log_attrib.h diff --git a/include/starkernel/log_region.h b/kernel/include/starkernel/log_region.h similarity index 100% rename from include/starkernel/log_region.h rename to kernel/include/starkernel/log_region.h diff --git a/include/starkernel/pci.h b/kernel/include/starkernel/pci.h similarity index 100% rename from include/starkernel/pci.h rename to kernel/include/starkernel/pci.h diff --git a/include/starkernel/plic.h b/kernel/include/starkernel/plic.h similarity index 100% rename from include/starkernel/plic.h rename to kernel/include/starkernel/plic.h diff --git a/include/starkernel/pmm.h b/kernel/include/starkernel/pmm.h similarity index 100% rename from include/starkernel/pmm.h rename to kernel/include/starkernel/pmm.h diff --git a/include/starkernel/q48_16.h b/kernel/include/starkernel/q48_16.h similarity index 100% rename from include/starkernel/q48_16.h rename to kernel/include/starkernel/q48_16.h diff --git a/include/starkernel/repl.h b/kernel/include/starkernel/repl.h similarity index 100% rename from include/starkernel/repl.h rename to kernel/include/starkernel/repl.h diff --git a/include/starkernel/rng.h b/kernel/include/starkernel/rng.h similarity index 100% rename from include/starkernel/rng.h rename to kernel/include/starkernel/rng.h diff --git a/include/starkernel/rpi5_dtb.h b/kernel/include/starkernel/rpi5_dtb.h similarity index 100% rename from include/starkernel/rpi5_dtb.h rename to kernel/include/starkernel/rpi5_dtb.h diff --git a/include/starkernel/rpi5_mailbox.h b/kernel/include/starkernel/rpi5_mailbox.h similarity index 100% rename from include/starkernel/rpi5_mailbox.h rename to kernel/include/starkernel/rpi5_mailbox.h diff --git a/include/starkernel/rpi5_native_boot.h b/kernel/include/starkernel/rpi5_native_boot.h similarity index 100% rename from include/starkernel/rpi5_native_boot.h rename to kernel/include/starkernel/rpi5_native_boot.h diff --git a/include/starkernel/rpi5_native_entry.h b/kernel/include/starkernel/rpi5_native_entry.h similarity index 100% rename from include/starkernel/rpi5_native_entry.h rename to kernel/include/starkernel/rpi5_native_entry.h diff --git a/include/starkernel/scalar25519.h b/kernel/include/starkernel/scalar25519.h similarity index 100% rename from include/starkernel/scalar25519.h rename to kernel/include/starkernel/scalar25519.h diff --git a/include/starkernel/session.h b/kernel/include/starkernel/session.h similarity index 100% rename from include/starkernel/session.h rename to kernel/include/starkernel/session.h diff --git a/include/starkernel/sha512.h b/kernel/include/starkernel/sha512.h similarity index 100% rename from include/starkernel/sha512.h rename to kernel/include/starkernel/sha512.h diff --git a/include/starkernel/timer.h b/kernel/include/starkernel/timer.h similarity index 100% rename from include/starkernel/timer.h rename to kernel/include/starkernel/timer.h diff --git a/include/starkernel/ttf.h b/kernel/include/starkernel/ttf.h similarity index 100% rename from include/starkernel/ttf.h rename to kernel/include/starkernel/ttf.h diff --git a/include/starkernel/uefi.h b/kernel/include/starkernel/uefi.h similarity index 100% rename from include/starkernel/uefi.h rename to kernel/include/starkernel/uefi.h diff --git a/include/starkernel/user_identity_seed.h b/kernel/include/starkernel/user_identity_seed.h similarity index 100% rename from include/starkernel/user_identity_seed.h rename to kernel/include/starkernel/user_identity_seed.h diff --git a/include/starkernel/virtio_blk.h b/kernel/include/starkernel/virtio_blk.h similarity index 100% rename from include/starkernel/virtio_blk.h rename to kernel/include/starkernel/virtio_blk.h diff --git a/include/starkernel/virtio_input.h b/kernel/include/starkernel/virtio_input.h similarity index 100% rename from include/starkernel/virtio_input.h rename to kernel/include/starkernel/virtio_input.h diff --git a/include/starkernel/virtio_rng.h b/kernel/include/starkernel/virtio_rng.h similarity index 100% rename from include/starkernel/virtio_rng.h rename to kernel/include/starkernel/virtio_rng.h diff --git a/include/starkernel/vm/README.md b/kernel/include/starkernel/vm/README.md similarity index 100% rename from include/starkernel/vm/README.md rename to kernel/include/starkernel/vm/README.md diff --git a/include/starkernel/vm/arena.h b/kernel/include/starkernel/vm/arena.h similarity index 100% rename from include/starkernel/vm/arena.h rename to kernel/include/starkernel/vm/arena.h diff --git a/include/starkernel/vm/bootstrap/README.md b/kernel/include/starkernel/vm/bootstrap/README.md similarity index 100% rename from include/starkernel/vm/bootstrap/README.md rename to kernel/include/starkernel/vm/bootstrap/README.md diff --git a/include/starkernel/vm/bootstrap/sk_vm_bootstrap.h b/kernel/include/starkernel/vm/bootstrap/sk_vm_bootstrap.h similarity index 100% rename from include/starkernel/vm/bootstrap/sk_vm_bootstrap.h rename to kernel/include/starkernel/vm/bootstrap/sk_vm_bootstrap.h diff --git a/include/starkernel/vm/kernel_hermes.h b/kernel/include/starkernel/vm/kernel_hermes.h similarity index 100% rename from include/starkernel/vm/kernel_hermes.h rename to kernel/include/starkernel/vm/kernel_hermes.h diff --git a/include/starkernel/vm/parity.h b/kernel/include/starkernel/vm/parity.h similarity index 100% rename from include/starkernel/vm/parity.h rename to kernel/include/starkernel/vm/parity.h diff --git a/include/starkernel/vm/stadium.h b/kernel/include/starkernel/vm/stadium.h similarity index 100% rename from include/starkernel/vm/stadium.h rename to kernel/include/starkernel/vm/stadium.h diff --git a/include/starkernel/vm/stadium_blocks.h b/kernel/include/starkernel/vm/stadium_blocks.h similarity index 100% rename from include/starkernel/vm/stadium_blocks.h rename to kernel/include/starkernel/vm/stadium_blocks.h diff --git a/include/starkernel/vm/stadium_words.h b/kernel/include/starkernel/vm/stadium_words.h similarity index 100% rename from include/starkernel/vm/stadium_words.h rename to kernel/include/starkernel/vm/stadium_words.h diff --git a/include/starkernel/vm/switch.h b/kernel/include/starkernel/vm/switch.h similarity index 100% rename from include/starkernel/vm/switch.h rename to kernel/include/starkernel/vm/switch.h diff --git a/include/starkernel/vm_identity.h b/kernel/include/starkernel/vm_identity.h similarity index 100% rename from include/starkernel/vm_identity.h rename to kernel/include/starkernel/vm_identity.h diff --git a/include/starkernel/vm_uuid.h b/kernel/include/starkernel/vm_uuid.h similarity index 100% rename from include/starkernel/vm_uuid.h rename to kernel/include/starkernel/vm_uuid.h diff --git a/include/starkernel/vmm.h b/kernel/include/starkernel/vmm.h similarity index 100% rename from include/starkernel/vmm.h rename to kernel/include/starkernel/vmm.h diff --git a/include/starkernel/vt100.h b/kernel/include/starkernel/vt100.h similarity index 100% rename from include/starkernel/vt100.h rename to kernel/include/starkernel/vt100.h diff --git a/include/starkernel/x509_ed25519.h b/kernel/include/starkernel/x509_ed25519.h similarity index 100% rename from include/starkernel/x509_ed25519.h rename to kernel/include/starkernel/x509_ed25519.h diff --git a/include/starkernel/xhci.h b/kernel/include/starkernel/xhci.h similarity index 100% rename from include/starkernel/xhci.h rename to kernel/include/starkernel/xhci.h diff --git a/include/starkernel/xhci_driver.h b/kernel/include/starkernel/xhci_driver.h similarity index 100% rename from include/starkernel/xhci_driver.h rename to kernel/include/starkernel/xhci_driver.h diff --git a/include/starkernel/xxhash64.h b/kernel/include/starkernel/xxhash64.h similarity index 100% rename from include/starkernel/xxhash64.h rename to kernel/include/starkernel/xxhash64.h diff --git a/include/starkernel/zuse_cert_devblock.h b/kernel/include/starkernel/zuse_cert_devblock.h similarity index 100% rename from include/starkernel/zuse_cert_devblock.h rename to kernel/include/starkernel/zuse_cert_devblock.h diff --git a/include/starkernel/zuse_eligibility.h b/kernel/include/starkernel/zuse_eligibility.h similarity index 100% rename from include/starkernel/zuse_eligibility.h rename to kernel/include/starkernel/zuse_eligibility.h diff --git a/include/starkernel/zuse_eligibility_list.h b/kernel/include/starkernel/zuse_eligibility_list.h similarity index 100% rename from include/starkernel/zuse_eligibility_list.h rename to kernel/include/starkernel/zuse_eligibility_list.h diff --git a/include/starkernel/zuse_genesis_marker.h b/kernel/include/starkernel/zuse_genesis_marker.h similarity index 100% rename from include/starkernel/zuse_genesis_marker.h rename to kernel/include/starkernel/zuse_genesis_marker.h diff --git a/linker/README.md b/kernel/linker/README.md similarity index 100% rename from linker/README.md rename to kernel/linker/README.md diff --git a/linker/starkernel-amd64.ld b/kernel/linker/starkernel-amd64.ld similarity index 100% rename from linker/starkernel-amd64.ld rename to kernel/linker/starkernel-amd64.ld diff --git a/linker/starkernel-kernel-aarch64.ld b/kernel/linker/starkernel-kernel-aarch64.ld similarity index 100% rename from linker/starkernel-kernel-aarch64.ld rename to kernel/linker/starkernel-kernel-aarch64.ld diff --git a/linker/starkernel-kernel-amd64.ld b/kernel/linker/starkernel-kernel-amd64.ld similarity index 100% rename from linker/starkernel-kernel-amd64.ld rename to kernel/linker/starkernel-kernel-amd64.ld diff --git a/linker/starkernel-kernel-riscv64.ld b/kernel/linker/starkernel-kernel-riscv64.ld similarity index 100% rename from linker/starkernel-kernel-riscv64.ld rename to kernel/linker/starkernel-kernel-riscv64.ld diff --git a/linker/starkernel-loader-aarch64-pe.ld b/kernel/linker/starkernel-loader-aarch64-pe.ld similarity index 100% rename from linker/starkernel-loader-aarch64-pe.ld rename to kernel/linker/starkernel-loader-aarch64-pe.ld diff --git a/linker/starkernel-loader-aarch64.ld b/kernel/linker/starkernel-loader-aarch64.ld similarity index 100% rename from linker/starkernel-loader-aarch64.ld rename to kernel/linker/starkernel-loader-aarch64.ld diff --git a/linker/starkernel-loader-amd64-pe.ld b/kernel/linker/starkernel-loader-amd64-pe.ld similarity index 100% rename from linker/starkernel-loader-amd64-pe.ld rename to kernel/linker/starkernel-loader-amd64-pe.ld diff --git a/linker/starkernel-loader-amd64.ld b/kernel/linker/starkernel-loader-amd64.ld similarity index 100% rename from linker/starkernel-loader-amd64.ld rename to kernel/linker/starkernel-loader-amd64.ld diff --git a/linker/starkernel-loader-riscv64.ld b/kernel/linker/starkernel-loader-riscv64.ld similarity index 100% rename from linker/starkernel-loader-riscv64.ld rename to kernel/linker/starkernel-loader-riscv64.ld diff --git a/kernel/linker/starkernel-native-rpi5.ld b/kernel/linker/starkernel-native-rpi5.ld new file mode 100644 index 00000000..7a9c6b9e --- /dev/null +++ b/kernel/linker/starkernel-native-rpi5.ld @@ -0,0 +1,74 @@ +/* Linker script for the Raspberry Pi 5 native (non-UEFI) kernel image. + * + * Linked from the same objects as the aarch64 kernel ELF, entered at + * rpi5_native_start (arch/aarch64/native_rpi5_entry.S, section + * .text.entry -- placed first so it sits at the load address), then + * flattened with `objcopy -O binary` into kernel_2712.img. + * + * Load address 0x80000 must match boards/raspi/config.txt's + * kernel_address=0x80000: Pi 5 firmware's own default for + * kernel_2712.img is 0x200000, so the address is pinned on both sides + * rather than left to the firmware default. + * + * __kernel_start/__kernel_end span the whole image including .bss so + * pmm_init() reserves every page the image occupies (aarch64 boot.S's + * zero-length substitutes are only correct for the UEFI loader path, + * where UEFI owns the image pages). __bss_start/__bss_end are 16-byte + * aligned for the entry stub's zeroing loop: firmware does not clear + * memory past the end of the file it loads. + */ + +OUTPUT_FORMAT("elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(rpi5_native_start) + +SECTIONS +{ + . = 0x80000; + + __kernel_start = .; + + .text : { + __text_start = .; + KEEP(*(.text.entry)) + *(.text .text.*) + __text_end = .; + } + + .rodata : ALIGN(4K) { + __rodata_start = .; + *(.rodata .rodata.*) + __rodata_end = .; + } + + .data : ALIGN(4K) { + __data_start = .; + *(.data .data.*) + *(.got .got.*) + __data_end = .; + } + + .rela.dyn : ALIGN(8) { + *(.rela .rela.*) + } + + .bss (NOLOAD) : ALIGN(4K) { + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(16); + __bss_end = .; + } + + . = ALIGN(4K); + __kernel_end = .; + + /DISCARD/ : { + *(.comment) + *(.note*) + *(.eh_frame) + *(.dynamic) + *(.dynsym) + *(.interp) + } +} diff --git a/src/starkernel/README.md b/kernel/src/README.md similarity index 100% rename from src/starkernel/README.md rename to kernel/src/README.md diff --git a/src/starkernel/arch/aarch64/README.md b/kernel/src/arch/aarch64/README.md similarity index 100% rename from src/starkernel/arch/aarch64/README.md rename to kernel/src/arch/aarch64/README.md diff --git a/src/starkernel/arch/aarch64/apic.c b/kernel/src/arch/aarch64/apic.c similarity index 100% rename from src/starkernel/arch/aarch64/apic.c rename to kernel/src/arch/aarch64/apic.c diff --git a/src/starkernel/arch/aarch64/arch.c b/kernel/src/arch/aarch64/arch.c similarity index 100% rename from src/starkernel/arch/aarch64/arch.c rename to kernel/src/arch/aarch64/arch.c diff --git a/src/starkernel/arch/aarch64/boot.S b/kernel/src/arch/aarch64/boot.S similarity index 100% rename from src/starkernel/arch/aarch64/boot.S rename to kernel/src/arch/aarch64/boot.S diff --git a/src/starkernel/arch/aarch64/interrupts.c b/kernel/src/arch/aarch64/interrupts.c similarity index 100% rename from src/starkernel/arch/aarch64/interrupts.c rename to kernel/src/arch/aarch64/interrupts.c diff --git a/src/starkernel/arch/aarch64/isr.S b/kernel/src/arch/aarch64/isr.S similarity index 100% rename from src/starkernel/arch/aarch64/isr.S rename to kernel/src/arch/aarch64/isr.S diff --git a/src/starkernel/arch/aarch64/native_rpi5_entry.S b/kernel/src/arch/aarch64/native_rpi5_entry.S similarity index 68% rename from src/starkernel/arch/aarch64/native_rpi5_entry.S rename to kernel/src/arch/aarch64/native_rpi5_entry.S index 728c443e..7260ce9a 100644 --- a/src/starkernel/arch/aarch64/native_rpi5_entry.S +++ b/kernel/src/arch/aarch64/native_rpi5_entry.S @@ -26,16 +26,19 @@ * exists only so this file's own control flow has somewhere defined to * go if that contract is ever violated. * - * Build-system note: `Makefile.starkernel`'s `KERNEL_ASM` wildcards every - * `*.S` file in this directory into the monolithic kernel ELF build (not - * the PE/COFF loader build -- that list is explicit, boot.S/isr.S only, - * see the Makefile), so this file *does* compile and link into the - * existing ARCH=aarch64 QEMU/UEFI acceptance build. Nothing there ever - * branches to `rpi5_native_start` -- it is dead code in that build by - * design, exactly like `rpi5_dtb.c`/`rpi5_mailbox.c` before it. A real, - * separately-linked Pi 5 native boot image (its own linker script placing - * this code at 0x80000) does not exist yet -- that is a build-system task, - * not scoped into this item. + * Build-system note: `kernel/Makefile`'s `KERNEL_ASM` wildcards every + * `*.S` file in this directory into the kernel ELF build (not the PE/COFF + * loader build -- that list is explicit, boot.S/isr.S/switch.S only), so + * this file links into the ARCH=aarch64 QEMU/UEFI kernel ELF as dead + * code, and is the entry point of the separately-linked Pi 5 native + * image (`make boot_image TARGET=RASPI`): + * `kernel/linker/starkernel-native-rpi5.ld` places `.text.entry` first + * at 0x80000 and the image is flattened to `kernel_2712.img`. + * + * Pi 5 firmware loads only the file's bytes; `.bss` (NOLOAD) is whatever + * was in RAM. It is zeroed here, before anything in it -- including + * `g_rpi5_dtb_ptr` and this stub's own stack -- is used. x0 (the DTB + * pointer) is preserved across the loop; only x4-x6 are touched. */ .section .bss @@ -51,7 +54,7 @@ g_rpi5_native_stack: * BSS stacks */ g_rpi5_native_stack_top: - .section .text + .section .text.entry, "ax" .global rpi5_native_start rpi5_native_start: /* Mask x0 to its documented 32-bit DTB-pointer range (ยงIV.1: the @@ -60,6 +63,19 @@ rpi5_native_start: mov x1, #0xffffffff and x0, x0, x1 + /* Zero .bss: [__bss_start, __bss_end), both 16-byte aligned by the + * native linker script. */ + adrp x4, __bss_start + add x4, x4, :lo12:__bss_start + adrp x5, __bss_end + add x5, x5, :lo12:__bss_end +.Lbss_zero: + cmp x4, x5 + b.hs .Lbss_done + stp xzr, xzr, [x4], #16 + b .Lbss_zero +.Lbss_done: + adrp x2, g_rpi5_dtb_ptr add x2, x2, :lo12:g_rpi5_dtb_ptr str x0, [x2] diff --git a/src/starkernel/arch/aarch64/rpi5_dtb.c b/kernel/src/arch/aarch64/rpi5_dtb.c similarity index 100% rename from src/starkernel/arch/aarch64/rpi5_dtb.c rename to kernel/src/arch/aarch64/rpi5_dtb.c diff --git a/src/starkernel/arch/aarch64/rpi5_mailbox.c b/kernel/src/arch/aarch64/rpi5_mailbox.c similarity index 100% rename from src/starkernel/arch/aarch64/rpi5_mailbox.c rename to kernel/src/arch/aarch64/rpi5_mailbox.c diff --git a/src/starkernel/arch/aarch64/rpi5_native_boot.c b/kernel/src/arch/aarch64/rpi5_native_boot.c similarity index 100% rename from src/starkernel/arch/aarch64/rpi5_native_boot.c rename to kernel/src/arch/aarch64/rpi5_native_boot.c diff --git a/src/starkernel/arch/aarch64/switch.S b/kernel/src/arch/aarch64/switch.S similarity index 100% rename from src/starkernel/arch/aarch64/switch.S rename to kernel/src/arch/aarch64/switch.S diff --git a/src/starkernel/arch/aarch64/timer.c b/kernel/src/arch/aarch64/timer.c similarity index 100% rename from src/starkernel/arch/aarch64/timer.c rename to kernel/src/arch/aarch64/timer.c diff --git a/src/starkernel/arch/amd64/README.md b/kernel/src/arch/amd64/README.md similarity index 100% rename from src/starkernel/arch/amd64/README.md rename to kernel/src/arch/amd64/README.md diff --git a/src/starkernel/arch/amd64/apic.c b/kernel/src/arch/amd64/apic.c similarity index 100% rename from src/starkernel/arch/amd64/apic.c rename to kernel/src/arch/amd64/apic.c diff --git a/src/starkernel/arch/amd64/arch.c b/kernel/src/arch/amd64/arch.c similarity index 100% rename from src/starkernel/arch/amd64/arch.c rename to kernel/src/arch/amd64/arch.c diff --git a/src/starkernel/arch/amd64/boot.S b/kernel/src/arch/amd64/boot.S similarity index 100% rename from src/starkernel/arch/amd64/boot.S rename to kernel/src/arch/amd64/boot.S diff --git a/src/starkernel/arch/amd64/i8042.c b/kernel/src/arch/amd64/i8042.c similarity index 100% rename from src/starkernel/arch/amd64/i8042.c rename to kernel/src/arch/amd64/i8042.c diff --git a/src/starkernel/arch/amd64/interrupts.c b/kernel/src/arch/amd64/interrupts.c similarity index 100% rename from src/starkernel/arch/amd64/interrupts.c rename to kernel/src/arch/amd64/interrupts.c diff --git a/src/starkernel/arch/amd64/ioapic.c b/kernel/src/arch/amd64/ioapic.c similarity index 100% rename from src/starkernel/arch/amd64/ioapic.c rename to kernel/src/arch/amd64/ioapic.c diff --git a/src/starkernel/arch/amd64/isr.S b/kernel/src/arch/amd64/isr.S similarity index 100% rename from src/starkernel/arch/amd64/isr.S rename to kernel/src/arch/amd64/isr.S diff --git a/src/starkernel/arch/amd64/kernel_entry.S b/kernel/src/arch/amd64/kernel_entry.S similarity index 100% rename from src/starkernel/arch/amd64/kernel_entry.S rename to kernel/src/arch/amd64/kernel_entry.S diff --git a/src/starkernel/arch/amd64/switch.S b/kernel/src/arch/amd64/switch.S similarity index 100% rename from src/starkernel/arch/amd64/switch.S rename to kernel/src/arch/amd64/switch.S diff --git a/src/starkernel/arch/amd64/timer.c b/kernel/src/arch/amd64/timer.c similarity index 100% rename from src/starkernel/arch/amd64/timer.c rename to kernel/src/arch/amd64/timer.c diff --git a/src/starkernel/arch/riscv64/README.md b/kernel/src/arch/riscv64/README.md similarity index 100% rename from src/starkernel/arch/riscv64/README.md rename to kernel/src/arch/riscv64/README.md diff --git a/src/starkernel/arch/riscv64/apic.c b/kernel/src/arch/riscv64/apic.c similarity index 100% rename from src/starkernel/arch/riscv64/apic.c rename to kernel/src/arch/riscv64/apic.c diff --git a/src/starkernel/arch/riscv64/arch.c b/kernel/src/arch/riscv64/arch.c similarity index 100% rename from src/starkernel/arch/riscv64/arch.c rename to kernel/src/arch/riscv64/arch.c diff --git a/src/starkernel/arch/riscv64/boot.S b/kernel/src/arch/riscv64/boot.S similarity index 100% rename from src/starkernel/arch/riscv64/boot.S rename to kernel/src/arch/riscv64/boot.S diff --git a/src/starkernel/arch/riscv64/interrupts.c b/kernel/src/arch/riscv64/interrupts.c similarity index 100% rename from src/starkernel/arch/riscv64/interrupts.c rename to kernel/src/arch/riscv64/interrupts.c diff --git a/src/starkernel/arch/riscv64/isr.S b/kernel/src/arch/riscv64/isr.S similarity index 100% rename from src/starkernel/arch/riscv64/isr.S rename to kernel/src/arch/riscv64/isr.S diff --git a/src/starkernel/arch/riscv64/kernel_entry.S b/kernel/src/arch/riscv64/kernel_entry.S similarity index 100% rename from src/starkernel/arch/riscv64/kernel_entry.S rename to kernel/src/arch/riscv64/kernel_entry.S diff --git a/src/starkernel/arch/riscv64/plic.c b/kernel/src/arch/riscv64/plic.c similarity index 100% rename from src/starkernel/arch/riscv64/plic.c rename to kernel/src/arch/riscv64/plic.c diff --git a/src/starkernel/arch/riscv64/switch.S b/kernel/src/arch/riscv64/switch.S similarity index 100% rename from src/starkernel/arch/riscv64/switch.S rename to kernel/src/arch/riscv64/switch.S diff --git a/src/starkernel/arch/riscv64/timer.c b/kernel/src/arch/riscv64/timer.c similarity index 100% rename from src/starkernel/arch/riscv64/timer.c rename to kernel/src/arch/riscv64/timer.c diff --git a/src/starkernel/artemis_sig.c b/kernel/src/artemis_sig.c similarity index 100% rename from src/starkernel/artemis_sig.c rename to kernel/src/artemis_sig.c diff --git a/src/starkernel/boot/README.md b/kernel/src/boot/README.md similarity index 100% rename from src/starkernel/boot/README.md rename to kernel/src/boot/README.md diff --git a/src/starkernel/boot/cmdline.c b/kernel/src/boot/cmdline.c similarity index 100% rename from src/starkernel/boot/cmdline.c rename to kernel/src/boot/cmdline.c diff --git a/src/starkernel/boot/elf_loader.c b/kernel/src/boot/elf_loader.c similarity index 100% rename from src/starkernel/boot/elf_loader.c rename to kernel/src/boot/elf_loader.c diff --git a/src/starkernel/boot/reloc.S b/kernel/src/boot/reloc.S similarity index 100% rename from src/starkernel/boot/reloc.S rename to kernel/src/boot/reloc.S diff --git a/src/starkernel/boot/reloc_stub.c b/kernel/src/boot/reloc_stub.c similarity index 100% rename from src/starkernel/boot/reloc_stub.c rename to kernel/src/boot/reloc_stub.c diff --git a/src/starkernel/boot/uefi_loader.c b/kernel/src/boot/uefi_loader.c similarity index 100% rename from src/starkernel/boot/uefi_loader.c rename to kernel/src/boot/uefi_loader.c diff --git a/src/starkernel/capsule/README.md b/kernel/src/capsule/README.md similarity index 100% rename from src/starkernel/capsule/README.md rename to kernel/src/capsule/README.md diff --git a/src/starkernel/capsule/capsule_birth.c b/kernel/src/capsule/capsule_birth.c similarity index 100% rename from src/starkernel/capsule/capsule_birth.c rename to kernel/src/capsule/capsule_birth.c diff --git a/src/starkernel/capsule/capsule_console.c b/kernel/src/capsule/capsule_console.c similarity index 100% rename from src/starkernel/capsule/capsule_console.c rename to kernel/src/capsule/capsule_console.c diff --git a/src/starkernel/capsule/capsule_find.c b/kernel/src/capsule/capsule_find.c similarity index 100% rename from src/starkernel/capsule/capsule_find.c rename to kernel/src/capsule/capsule_find.c diff --git a/src/starkernel/capsule/capsule_loader.c b/kernel/src/capsule/capsule_loader.c similarity index 100% rename from src/starkernel/capsule/capsule_loader.c rename to kernel/src/capsule/capsule_loader.c diff --git a/src/starkernel/capsule/capsule_mint.c b/kernel/src/capsule/capsule_mint.c similarity index 100% rename from src/starkernel/capsule/capsule_mint.c rename to kernel/src/capsule/capsule_mint.c diff --git a/src/starkernel/capsule/capsule_run.c b/kernel/src/capsule/capsule_run.c similarity index 100% rename from src/starkernel/capsule/capsule_run.c rename to kernel/src/capsule/capsule_run.c diff --git a/src/starkernel/capsule/capsule_runcap.c b/kernel/src/capsule/capsule_runcap.c similarity index 100% rename from src/starkernel/capsule/capsule_runcap.c rename to kernel/src/capsule/capsule_runcap.c diff --git a/src/starkernel/capsule/capsule_sig.c b/kernel/src/capsule/capsule_sig.c similarity index 100% rename from src/starkernel/capsule/capsule_sig.c rename to kernel/src/capsule/capsule_sig.c diff --git a/src/starkernel/capsule/capsule_validate.c b/kernel/src/capsule/capsule_validate.c similarity index 100% rename from src/starkernel/capsule/capsule_validate.c rename to kernel/src/capsule/capsule_validate.c diff --git a/src/starkernel/capsule/capsule_vm_hooks.c b/kernel/src/capsule/capsule_vm_hooks.c similarity index 100% rename from src/starkernel/capsule/capsule_vm_hooks.c rename to kernel/src/capsule/capsule_vm_hooks.c diff --git a/src/starkernel/capsule/capsule_vm_physics.c b/kernel/src/capsule/capsule_vm_physics.c similarity index 100% rename from src/starkernel/capsule/capsule_vm_physics.c rename to kernel/src/capsule/capsule_vm_physics.c diff --git a/src/starkernel/capsule/capsule_vm_switch_signal.c b/kernel/src/capsule/capsule_vm_switch_signal.c similarity index 100% rename from src/starkernel/capsule/capsule_vm_switch_signal.c rename to kernel/src/capsule/capsule_vm_switch_signal.c diff --git a/src/starkernel/capsule/capsule_wirebind.c b/kernel/src/capsule/capsule_wirebind.c similarity index 100% rename from src/starkernel/capsule/capsule_wirebind.c rename to kernel/src/capsule/capsule_wirebind.c diff --git a/src/starkernel/capsule/capsule_zuse_boot.c b/kernel/src/capsule/capsule_zuse_boot.c similarity index 100% rename from src/starkernel/capsule/capsule_zuse_boot.c rename to kernel/src/capsule/capsule_zuse_boot.c diff --git a/src/starkernel/capsule/mama_forth_words.c b/kernel/src/capsule/mama_forth_words.c similarity index 99% rename from src/starkernel/capsule/mama_forth_words.c rename to kernel/src/capsule/mama_forth_words.c index 900885f8..404cf5f2 100644 --- a/src/starkernel/capsule/mama_forth_words.c +++ b/kernel/src/capsule/mama_forth_words.c @@ -54,7 +54,7 @@ #include "starkernel/capsule_run.h" #include "starkernel/capsule_loader.h" #include "starkernel/capsule_vm_physics.h" -#include "starkernel/vm/vm_internal.h" +#include "../vm/vm_internal.h" #include "starkernel/vm/stadium.h" /* item 4.2 -- STADIUM-* words */ #include "starkernel/capsule_vm_switch_signal.h" /* FABRIC-3.md ยงXXVIII Stage 3 follow-on -- SWITCH-MARK-WORK */ #include "starkernel/vm/stadium_words.h" /* item 4.2 -- stadium_words_resident_heat() */ diff --git a/src/starkernel/capsule/vm_identity.c b/kernel/src/capsule/vm_identity.c similarity index 100% rename from src/starkernel/capsule/vm_identity.c rename to kernel/src/capsule/vm_identity.c diff --git a/src/starkernel/capsule/vm_uuid.c b/kernel/src/capsule/vm_uuid.c similarity index 100% rename from src/starkernel/capsule/vm_uuid.c rename to kernel/src/capsule/vm_uuid.c diff --git a/src/starkernel/capsule/zuse_eligibility.c b/kernel/src/capsule/zuse_eligibility.c similarity index 100% rename from src/starkernel/capsule/zuse_eligibility.c rename to kernel/src/capsule/zuse_eligibility.c diff --git a/src/starkernel/crypto/ed25519.c b/kernel/src/crypto/ed25519.c similarity index 100% rename from src/starkernel/crypto/ed25519.c rename to kernel/src/crypto/ed25519.c diff --git a/src/starkernel/crypto/fe25519.c b/kernel/src/crypto/fe25519.c similarity index 100% rename from src/starkernel/crypto/fe25519.c rename to kernel/src/crypto/fe25519.c diff --git a/src/starkernel/crypto/scalar25519.c b/kernel/src/crypto/scalar25519.c similarity index 100% rename from src/starkernel/crypto/scalar25519.c rename to kernel/src/crypto/scalar25519.c diff --git a/src/starkernel/crypto/sha512.c b/kernel/src/crypto/sha512.c similarity index 100% rename from src/starkernel/crypto/sha512.c rename to kernel/src/crypto/sha512.c diff --git a/src/starkernel/crypto/x509_ed25519.c b/kernel/src/crypto/x509_ed25519.c similarity index 100% rename from src/starkernel/crypto/x509_ed25519.c rename to kernel/src/crypto/x509_ed25519.c diff --git a/src/starkernel/doe_log.c b/kernel/src/doe_log.c similarity index 100% rename from src/starkernel/doe_log.c rename to kernel/src/doe_log.c diff --git a/src/starkernel/hal/README.md b/kernel/src/hal/README.md similarity index 100% rename from src/starkernel/hal/README.md rename to kernel/src/hal/README.md diff --git a/src/starkernel/hal/console.c b/kernel/src/hal/console.c similarity index 100% rename from src/starkernel/hal/console.c rename to kernel/src/hal/console.c diff --git a/src/starkernel/hal/fdt.c b/kernel/src/hal/fdt.c similarity index 100% rename from src/starkernel/hal/fdt.c rename to kernel/src/hal/fdt.c diff --git a/src/starkernel/hal/font_8x16.c b/kernel/src/hal/font_8x16.c similarity index 100% rename from src/starkernel/hal/font_8x16.c rename to kernel/src/hal/font_8x16.c diff --git a/src/starkernel/hal/framebuffer.c b/kernel/src/hal/framebuffer.c similarity index 100% rename from src/starkernel/hal/framebuffer.c rename to kernel/src/hal/framebuffer.c diff --git a/src/starkernel/hal/hal.c b/kernel/src/hal/hal.c similarity index 100% rename from src/starkernel/hal/hal.c rename to kernel/src/hal/hal.c diff --git a/src/starkernel/hal/host_services.c b/kernel/src/hal/host_services.c similarity index 100% rename from src/starkernel/hal/host_services.c rename to kernel/src/hal/host_services.c diff --git a/src/starkernel/hal/memory.c b/kernel/src/hal/memory.c similarity index 100% rename from src/starkernel/hal/memory.c rename to kernel/src/hal/memory.c diff --git a/src/starkernel/hal/ttf.c b/kernel/src/hal/ttf.c similarity index 100% rename from src/starkernel/hal/ttf.c rename to kernel/src/hal/ttf.c diff --git a/src/starkernel/hal/vt100.c b/kernel/src/hal/vt100.c similarity index 100% rename from src/starkernel/hal/vt100.c rename to kernel/src/hal/vt100.c diff --git a/src/starkernel/hash/README.md b/kernel/src/hash/README.md similarity index 100% rename from src/starkernel/hash/README.md rename to kernel/src/hash/README.md diff --git a/src/starkernel/hash/xxhash64.c b/kernel/src/hash/xxhash64.c similarity index 100% rename from src/starkernel/hash/xxhash64.c rename to kernel/src/hash/xxhash64.c diff --git a/src/starkernel/heartbeat.c b/kernel/src/heartbeat.c similarity index 100% rename from src/starkernel/heartbeat.c rename to kernel/src/heartbeat.c diff --git a/src/starkernel/homeblocks_sig.c b/kernel/src/homeblocks_sig.c similarity index 100% rename from src/starkernel/homeblocks_sig.c rename to kernel/src/homeblocks_sig.c diff --git a/src/starkernel/kernel_main.c b/kernel/src/kernel_main.c similarity index 100% rename from src/starkernel/kernel_main.c rename to kernel/src/kernel_main.c diff --git a/src/starkernel/log_region.c b/kernel/src/log_region.c similarity index 100% rename from src/starkernel/log_region.c rename to kernel/src/log_region.c diff --git a/src/starkernel/math/README.md b/kernel/src/math/README.md similarity index 100% rename from src/starkernel/math/README.md rename to kernel/src/math/README.md diff --git a/src/starkernel/math/q48_16.c b/kernel/src/math/q48_16.c similarity index 100% rename from src/starkernel/math/q48_16.c rename to kernel/src/math/q48_16.c diff --git a/src/starkernel/memory/README.md b/kernel/src/memory/README.md similarity index 100% rename from src/starkernel/memory/README.md rename to kernel/src/memory/README.md diff --git a/src/starkernel/memory/kmalloc.c b/kernel/src/memory/kmalloc.c similarity index 100% rename from src/starkernel/memory/kmalloc.c rename to kernel/src/memory/kmalloc.c diff --git a/src/starkernel/memory/pmm.c b/kernel/src/memory/pmm.c similarity index 100% rename from src/starkernel/memory/pmm.c rename to kernel/src/memory/pmm.c diff --git a/src/starkernel/memory/vmm.c b/kernel/src/memory/vmm.c similarity index 100% rename from src/starkernel/memory/vmm.c rename to kernel/src/memory/vmm.c diff --git a/src/starkernel/pci/README.md b/kernel/src/pci/README.md similarity index 100% rename from src/starkernel/pci/README.md rename to kernel/src/pci/README.md diff --git a/src/starkernel/pci/pci.c b/kernel/src/pci/pci.c similarity index 100% rename from src/starkernel/pci/pci.c rename to kernel/src/pci/pci.c diff --git a/src/starkernel/repl.c b/kernel/src/repl.c similarity index 100% rename from src/starkernel/repl.c rename to kernel/src/repl.c diff --git a/src/starkernel/rng/rng.c b/kernel/src/rng/rng.c similarity index 100% rename from src/starkernel/rng/rng.c rename to kernel/src/rng/rng.c diff --git a/src/starkernel/usb/blkio_usb.c b/kernel/src/usb/blkio_usb.c similarity index 100% rename from src/starkernel/usb/blkio_usb.c rename to kernel/src/usb/blkio_usb.c diff --git a/src/starkernel/usb/xhci.c b/kernel/src/usb/xhci.c similarity index 100% rename from src/starkernel/usb/xhci.c rename to kernel/src/usb/xhci.c diff --git a/src/starkernel/virtio/README.md b/kernel/src/virtio/README.md similarity index 100% rename from src/starkernel/virtio/README.md rename to kernel/src/virtio/README.md diff --git a/src/starkernel/virtio/virtio_blk.c b/kernel/src/virtio/virtio_blk.c similarity index 100% rename from src/starkernel/virtio/virtio_blk.c rename to kernel/src/virtio/virtio_blk.c diff --git a/src/starkernel/virtio/virtio_input.c b/kernel/src/virtio/virtio_input.c similarity index 100% rename from src/starkernel/virtio/virtio_input.c rename to kernel/src/virtio/virtio_input.c diff --git a/src/starkernel/virtio/virtio_rng.c b/kernel/src/virtio/virtio_rng.c similarity index 100% rename from src/starkernel/virtio/virtio_rng.c rename to kernel/src/virtio/virtio_rng.c diff --git a/src/starkernel/vm/README.md b/kernel/src/vm/README.md similarity index 100% rename from src/starkernel/vm/README.md rename to kernel/src/vm/README.md diff --git a/src/starkernel/vm/alloc_kernel.c b/kernel/src/vm/alloc_kernel.c similarity index 100% rename from src/starkernel/vm/alloc_kernel.c rename to kernel/src/vm/alloc_kernel.c diff --git a/src/starkernel/vm/arena.c b/kernel/src/vm/arena.c similarity index 100% rename from src/starkernel/vm/arena.c rename to kernel/src/vm/arena.c diff --git a/src/starkernel/vm/bootstrap/README.md b/kernel/src/vm/bootstrap/README.md similarity index 100% rename from src/starkernel/vm/bootstrap/README.md rename to kernel/src/vm/bootstrap/README.md diff --git a/src/starkernel/vm/bootstrap/sk_vm_bootstrap.c b/kernel/src/vm/bootstrap/sk_vm_bootstrap.c similarity index 100% rename from src/starkernel/vm/bootstrap/sk_vm_bootstrap.c rename to kernel/src/vm/bootstrap/sk_vm_bootstrap.c diff --git a/src/starkernel/vm/host/README.md b/kernel/src/vm/host/README.md similarity index 100% rename from src/starkernel/vm/host/README.md rename to kernel/src/vm/host/README.md diff --git a/src/starkernel/vm/host/shim.c b/kernel/src/vm/host/shim.c similarity index 100% rename from src/starkernel/vm/host/shim.c rename to kernel/src/vm/host/shim.c diff --git a/src/starkernel/vm/kernel_hermes.c b/kernel/src/vm/kernel_hermes.c similarity index 100% rename from src/starkernel/vm/kernel_hermes.c rename to kernel/src/vm/kernel_hermes.c diff --git a/src/starkernel/vm/parity.c b/kernel/src/vm/parity.c similarity index 100% rename from src/starkernel/vm/parity.c rename to kernel/src/vm/parity.c diff --git a/src/starkernel/vm/q48_stubs.c b/kernel/src/vm/q48_stubs.c similarity index 100% rename from src/starkernel/vm/q48_stubs.c rename to kernel/src/vm/q48_stubs.c diff --git a/src/starkernel/vm/session.c b/kernel/src/vm/session.c similarity index 100% rename from src/starkernel/vm/session.c rename to kernel/src/vm/session.c diff --git a/src/starkernel/vm/stadium.c b/kernel/src/vm/stadium.c similarity index 100% rename from src/starkernel/vm/stadium.c rename to kernel/src/vm/stadium.c diff --git a/src/starkernel/vm/stadium_blocks.c b/kernel/src/vm/stadium_blocks.c similarity index 100% rename from src/starkernel/vm/stadium_blocks.c rename to kernel/src/vm/stadium_blocks.c diff --git a/src/starkernel/vm/stadium_words.c b/kernel/src/vm/stadium_words.c similarity index 100% rename from src/starkernel/vm/stadium_words.c rename to kernel/src/vm/stadium_words.c diff --git a/src/starkernel/vm/switch.c b/kernel/src/vm/switch.c similarity index 100% rename from src/starkernel/vm/switch.c rename to kernel/src/vm/switch.c diff --git a/src/starkernel/vm/vm_bootstrap.c b/kernel/src/vm/vm_bootstrap.c similarity index 96% rename from src/starkernel/vm/vm_bootstrap.c rename to kernel/src/vm/vm_bootstrap.c index 961bd192..2c2f0ec5 100644 --- a/src/starkernel/vm/vm_bootstrap.c +++ b/kernel/src/vm/vm_bootstrap.c @@ -44,14 +44,14 @@ * vm_bootstrap.c - VM initialization and bootstrap logic */ -#include "../include/vm.h" -#include "../include/log.h" -#include "../include/word_registry.h" -#include "../include/vm_debug.h" -#include "../include/physics_hotwords_cache.h" -#include "../include/rolling_window_of_truth.h" -#include "../include/dictionary_heat_optimization.h" -#include "../include/ssm_jacquard.h" +#include "../../../v3/include/vm.h" +#include "../../../v3/include/log.h" +#include "../../../v3/include/word_registry.h" +#include "../../../v3/include/vm_debug.h" +#include "../../../v3/include/physics_hotwords_cache.h" +#include "../../../v3/include/rolling_window_of_truth.h" +#include "../../../v3/include/dictionary_heat_optimization.h" +#include "../../../v3/include/ssm_jacquard.h" #include "word_source/include/vocabulary_words.h" #include "vm_internal.h" #ifdef __STARKERNEL__ diff --git a/src/starkernel/vm/vm_core.c b/kernel/src/vm/vm_core.c similarity index 98% rename from src/starkernel/vm/vm_core.c rename to kernel/src/vm/vm_core.c index 238c2a75..c8debd2c 100644 --- a/src/starkernel/vm/vm_core.c +++ b/kernel/src/vm/vm_core.c @@ -40,20 +40,20 @@ */ -#include "../include/vm.h" -#include "../include/inference_engine.h" -#include "../include/log.h" -#include "../include/word_registry.h" -#include "../include/vm_debug.h" -#include "../include/profiler.h" -#include "../include/platform_time.h" -#include "../include/physics_metadata.h" -#include "../include/physics_hotwords_cache.h" -#include "../include/physics_pipelining_metrics.h" -#include "../include/rolling_window_of_truth.h" -#include "../include/dictionary_heat_optimization.h" -#include "../include/ssm_jacquard.h" -#include "../include/vm_host.h" +#include "../../../v3/include/vm.h" +#include "../../../v3/include/inference_engine.h" +#include "../../../v3/include/log.h" +#include "../../../v3/include/word_registry.h" +#include "../../../v3/include/vm_debug.h" +#include "../../../v3/include/profiler.h" +#include "../../../v3/include/platform_time.h" +#include "../../../v3/include/physics_metadata.h" +#include "../../../v3/include/physics_hotwords_cache.h" +#include "../../../v3/include/physics_pipelining_metrics.h" +#include "../../../v3/include/rolling_window_of_truth.h" +#include "../../../v3/include/dictionary_heat_optimization.h" +#include "../../../v3/include/ssm_jacquard.h" +#include "../../../v3/include/vm_host.h" #ifdef __STARKERNEL__ #include "starkernel/vm/arena.h" #include "starkernel/log_attrib.h" /* vm_log_attributed_vm() */ diff --git a/src/starkernel/vm/vm_internal.h b/kernel/src/vm/vm_internal.h similarity index 97% rename from src/starkernel/vm/vm_internal.h rename to kernel/src/vm/vm_internal.h index 29dd1bf8..24504bdf 100644 --- a/src/starkernel/vm/vm_internal.h +++ b/kernel/src/vm/vm_internal.h @@ -43,8 +43,8 @@ #ifndef VM_INTERNAL_H #define VM_INTERNAL_H -#include "../include/vm.h" -#include "../include/vm_host.h" +#include "../../../v3/include/vm.h" +#include "../../../v3/include/vm_host.h" #ifndef PARITY_MODE #define PARITY_MODE 0 diff --git a/src/starkernel/vm/vm_runtime.c b/kernel/src/vm/vm_runtime.c similarity index 98% rename from src/starkernel/vm/vm_runtime.c rename to kernel/src/vm/vm_runtime.c index 04a8d11b..a6cb8b7a 100644 --- a/src/starkernel/vm/vm_runtime.c +++ b/kernel/src/vm/vm_runtime.c @@ -40,15 +40,15 @@ */ -#include "../include/vm.h" -#include "../include/log.h" -#include "../include/rolling_window_of_truth.h" -#include "../include/dictionary_heat_optimization.h" -#include "../include/inference_engine.h" -#include "../include/physics_metadata.h" -#include "../include/physics_hotwords_cache.h" +#include "../../../v3/include/vm.h" +#include "../../../v3/include/log.h" +#include "../../../v3/include/rolling_window_of_truth.h" +#include "../../../v3/include/dictionary_heat_optimization.h" +#include "../../../v3/include/inference_engine.h" +#include "../../../v3/include/physics_metadata.h" +#include "../../../v3/include/physics_hotwords_cache.h" #include "starkernel/doe_log.h" -#include "../include/ssm_jacquard.h" +#include "../../../v3/include/ssm_jacquard.h" #include "vm_internal.h" #include "starkernel/capsule_vm_physics.h" #include "starkernel/timer.h" diff --git a/lfs/amd64/starforth b/lfs/amd64/starforth index 979d248ba6e7af25351e7d4378e0eefa8a81807b..4ca07ddefeed6885955f7cb8ca98be7ab9b2d4db 100755 GIT binary patch delta 205513 zcmaf+2YgJ~7x?GCWJsjU2$MvKBqT%$fRxtp6Ekh}Il_yK*Rv2b< z)~MKj7V)dn@>3OoA7^$LfO1tpD-?*|m*<@Lx&7BMT>+3pzVYJnNT+r`{Z6!St16fK z!JNy!#Nd_w3YF7ewdFAVm0VmZC8rS=ud_mQR*25NlGl@RUjJ)dzE6Vx+fdK{(l$$> zM(?R)M7#b2V_I!o{&C#!={0)4aB^Y!-)W6LqlYS0`m9*)*42DGU~CNMXY=tp&!Ra$ zmXBu&JDJFhDtiW7sm zg0!CmD%IJ!SmGJ^xHcCvNXp04YGDD!=I3M3(c$@c=3}q}`Kt!x6C}MvL-G0e9Z}-W z`FQ+Cbf|Sc9?3F*{|xzfz*FRrz*+u3s-UXyw06D(FUMmEs^;UZMTA1~@jIfMF=#e&0zWaVT%B>4P$UHI(;~PXSfb`zEZcG3JF>*0kY}S5Zxj zc^W%6)n>t|zgiCPE=j7&5#BY*=K4CRqV~9eFzkGo&0x`wU!zs+@`Q7Z+F*&8^>1yJ z@<)4_dWX8HT~r6yET+tfmCtxrE&4{CKeFS8iExFi;$>@Ig_q5b;nH%FS4ru4WgsQV zP^RbfSQ*OU+{&_tuRp+0-x^UXJyofhi6z6{8%!fzV$6GknB&t6CM#s}S*28EXI1WT zI5stO&dpM)=nCX_A$JIv4wM$J*Jc-jM&isT7LA*dmMym|7DaxA;Fclj z5ZjXeCo6&7tHSQteC_48U%AQHbZ&B3C0?c|gfCWb=v7IcRs1GdEe|Zwh5RWWDp8Yc zl|PrL;(xrh%3yk^EVJ1lwh_4f1s>Q^Gc_rbU_k>0cJ|b$4zRUNSf=s>MruI!8Dcg8 zT>)ebgp>YhAW79|<e_G?YkF?d)q;a;br}51 zR*py2m50kc14FCCfI~+;dF&YU`9IqQ%5VLfD8M&EEiZ_(J5{;;lL31?rEpyh)`3wN#PTg^el(Y!%+ z?b=M+qJJ)FWzV1z(m#Xbib2s`pMp>Jt~0`=090kfiOvxC#Hr9Z&AOv-yq~oogJs`K zs72*jGH}-Bb79m4b0fdzb-gf5Ka-``PnC}cRdk|=)!ITYo`-3qhWEwaG zr_877FpMbECo|7ew}7`0P2yf#l~h}m=wryrEd=e9otv)z!wgz$^Bf`;4)#&)(ZWSj zSmF0dom@y}-oa95tH%wNN!bW8SZ+|ZM8R8L&`1I&$i2!|^6luOiZVgOb#dU`elhaw zaVj9MDO*1hgdn+EQ2Rsji&Ftr?q9q3Kz2iuIvx%n&f%bF$^umv2P5^sNSShVy*lKJ zd#Ne%@N&J3<%_7;MH?&ZoevPCxc6YnqI;m$s;ogQFc$r{7kM>OuQ9JAeV05`9?^9N zRtBOO4rn!^eGX_YqJ|E(CL_xE zp=Hce1|uuxP|D66Mf~XkeRjhp82l{y$boEliEt|bE#x>f#r#)?q;5n1jM;RQOPkCpFj&gVF6MxrLHA2gwqY90Cc%U$@#pl!T%`G0}MkNq>~g zL5Zq+UNenFNg_%fJ2+R3Ni2FNP!7w)Ioj3`0s=!!xeJoYtnOvxi6W}Ok4YU3|0)eO zLcGlpAxw}8(?JO}i=a+%aOI|rtEhQe-C5_na2-TRE-V2c%?Ss|Ixf*)V-j=3LHJSn zZBRq`%@O-i`wx2#yI5aV#zF$K$KNPhV7CP7a{xhjJEK7poE`btDf7se3hGp*Y>wy; zKQLQQKBPE94s71O541BAT6Dd@(vcf+nY@B`5q7<)c%s*}P{Xkf-+t#M^+QQZyN8hd zb(A=vq`iYA6D3wP&#$Y4WGzb0poBL=-9@=F}U6l02H0mCCLq;G< znmHM{ciAMbsTD*~RZQgSkm%VL9tCfdlyi_=K*?8$TcZxvcBAATO3FB-S-~a7h+`-U za}cFsqD?62L96wl6aJyhfPuY;O_TDZDeh{35qs5Byz$; zl~8iTL1O*Pqu>P+WnY4m3a(mB5zbss-&@I>a92jKZmM6>CJ)U<)Szu1GEP9Y0dlaf z+6Evh=AhOAkXg5xu=whaIq23y-FFVCJfiCk8G9r0iOb8x36XKTgWAh_+~qdy^3-l2 zGC$5kCjcqB(y-hL<7*ZDOSlTM``!aukM;2zn~kqkpW7u$W8h)OO%}H9Hze<4KPpYi zZ*SxSRb8bTE#wnb%eoEvz?aS0>Vg6Cm#W1o1=d#Cv}~?wbrROqW_3CT%1VF8zfyn- zE+bMCzVQ`Ola_L1SfF=(xO%fpN>Y-Wu!DW;PQmiFTzz>=SOwBV{ynU;p>`~IDwdwV z)`b%6gi8&GX#7_VU&Ic`!A0yu&;i^*;5GtpN8IYG>|U*Sqi`YJbektitp!7QO!8qZ zBy4vH?K$y;2^9d96xuJjc7hL}CpYDR)k+x`fU_obQ(G;*l1UxMTrx-e(aZ<%H5hpP zz-iuMmA^hfaG%`~p zO`nxQ_5`kWs(c8Cu$w-E^ONihM(DdhSv|R)kW|(}P$jlQ*{SKUR$`&Hp11NC*MPAx z44Q?q4YZZ-r9e^?iUOvlKeM-=h)ku)C*HkQ#Q3O`W}}=`)_=aDJ+_I!?InXfW(ZQ6 zT5D8FUzWQ?zoxZ(w|Wt&-Be9Lst{;>gAJwWoZhT(WCw!81`Vn=e-81cy?3p&!V3SR~QhWkME(c*pv~V z5No;zd<__}cd#2Ej4?M*WF2f;uy`mjpl2|>0yCPXa+R9JJffiGfJZ?3k^fG;LRAS|^nug8iFNWEaz5>0J*nV7t>l?U2SlQq?~%!G5kk z<#}eB{JCZzNs~*~Dp9TrY%wHO?7+60*yYf!G^HgsQ|LfIm9{FS=2lPGe(2dnj;rNc z>>-Luci4Xivfv6VU6oDpoLZfttJMZgm+BCFxSoFpXY4;*_Lx4xBL6ZVvv=xwP4qdF z?i@Sm=xoxRgaexv_9O}(RsUOUTZP(nh({+DiT4RL;JSB5CwWA;-Vewq>ydB6)Gdy~ z^@LeBl&M&n5a@w}JIRN_D;OVns!TRRALl&=a<;zh4l6qBLRcPZR1gM?ADoZOci!UB z&+@SR=b=B#_vA}|z<$maq%6aub|B7A<~uKx@7yKdxpTgARlf5A`OZDWIc)x*0~!Xv zk?9Y&eXFyTkXQ2NdgUdC6h(?)Xf;+Mv8t@tJ%-vI)7gtwL0|bIIV^{L$IqjQ5~Y%$6A8#Kag*<2qbUi zZ!L;@u;v5PLrsHCJ@SDZ)H0&LgIX%3sZsu=WgvMfn_8YBZ{#km8jySP;#OtI?QQ#7 z`I5E}f7TuP8q78LjWUBNA;<;tH)X>VejRr4nN4WC*#;AgI_-m;K^6oT5@DIy(Lr#< z3lrVpqp*2n%1Qo663Zz*?c{Q8$`)@63-HX`yUH&&)hdmD64UF@4(5oQlJYNY{Mx)e z3f3D5>(%nC!;Y}t0#^dux;smyg#NIuNm!0T zPiI(j>wh(GEQV_p`N`8!K|BS8Z(hV&&_qH^Qp>5%9a z97^Nl4eg7QTXJ^$QXXTSVWspT#@0AM**jK#-9Ch?%pNNTbO_QF2FEOWgLVyvAl8Eu zDCDP`a+eMzy4?gj7mvf5x;d;_^R01`B6{gyyiceG7aoyt1Wh0uer&A+k|LUNi7!aX zqQsv|T#l+knFQ|g+?3CBi0B@Fhu;slcj8A6Q%+r0t8#N#vvPpD7(9Uw1n_YimV9vU zw6AAZUx)dq>1 z!9r`6O-~oT`d;gSaWO;gmz+()?jWQ zV^)U2XRz;7!S;T6~D?~;@ZQ&)Vk+%Unb5>h&Aip!j$`CLD2Mz{Gw-&=j&Q|3xao_ z<-qtNcVeQLwfs%xL^u>R5Xoll-`Tiv%HAzt!^eie&&!IaOJ9gV|mxyK>F#f$QjeoI}T zMaPW%s-~ht#VL16>hS$nr4N$BS>uh<(?RXX$1%`OQ!_zFx+fnV-jWQIi;U<< zzR80|>>~r@kdZOu7kT8!4dfr$e-!oW;;f1~Iz5n$Y}Q|3q}lZe7RA<{aHQn!mM@G7 zB=6;Sqrymkxm-dI@<>ii2y}%s?26jfS>Bvbl600&CWN@bum|}?e5wb3QAf0eH6Mp*%XV8TlksXmWKwbF z%pupp_y7XS@QNno0l>N?Aw$SOlkyDCOy{G_dwIqNqv_y}5}FHzpBY&Y@`E3DhwL6R z)BfN#w0A0t)yo0*P=1&a{GlXl!ZXe1$qZTdoRkaO)G*>X2Z8Cc zVAA5A3je~=YOIzmt2!hZeN_pq>b7zp1v6|x*ef!fHn~GCFvh|F3tJ)8&F(=lQx4-D zqm&>m^gA|yy4bQ}!|xABSchhgWf&6vBkq(xAXhPpG-;b)YwpuxnCjwS`LU|Fv~d0{+z32WXc)5qxW zGn!;~KBB6h0RsO<8X-eg`qVCvsdYTh`KLWP$j}vX;z6Eq8D@^7KU%j*-w9S;u%=!I z#;n@!wsy9teNZ@?wF5kG5Va4I*{sdrP_%@9XjJaWzuGO%Eao%)))CC6?K^X zgx1*$g)&VH@?|#-qG3$3B(pU?zvzQDuY7*#q{wJ-eOCNzfITVmzXmck3j-x`e;63PdE3mSP*UmLQ{kd; zVFzr@K$9CtPwb!!Ch-5hz1a*ld3kQx-jGU0Tvd~bS9UCv^SDtCYXH1N`*-vuWi z3D_1oW2aQ1EEWF6!*rLO9G?i?mQ@wsDhKTXLT-(eJgJYwD`NDKiX; zg@nX9T)t(VRv~MFP`m>Z?SI%^Ddg5n*)nT%g}Qe2$p2O^VOI~3LoK62GUf~G={b(p zq4{XL!LEy*GI^$Ts{F5IN7)ZDKRI&SUZ)uDo~syU9nA&8@rS&2_SYa~9#>s;i>X5U z<@M6r{|}Z-hJ~&1MOzL zdBtXPoX4TSBW`X>T#!Y`Lb(>53jgk*E6EkP`=Zv;*=zEqMZP3Q&R$flAw2bL>Tx&* zRz+;WnF1>e=&{ol*MgrG#|%y$gV~{}@glxd@#x3T)cyHSi*$p@qxoXF?&2o!*xA&@ z&7H~@)XHZU4iTiwpWkYv$M1Psf? zCw%8gcm0hwzk1&f%{4h98_tMk+EzF*Bu89>Gnl|vu`{!}{f=5Hwv`OyX+k6Y0~s(eX4wxXugUcq3mtI}keL=pJ9^PQ`MNd^!yJ%DU zAZ>2ePt!XT$`yoS^i#h53)9ddm^1BzJIL=|+}2@b1R=q){QFcgQ}$kEfa9L4Lg3nc z#;W#i7sZsMWS5s8ue#tF;tZ1(lp30~@+d?;wt5PgAvaso2>zYDW>xLM-mvZPMcY)X zkq?Gt9{E(oqZbg3oEdgJ>y8tgtGn>?tiW@co#$PTg&k+Cg||F#?X}V~bu4k=9lkKh z8qCR6`OX$hpI*?Az^Gqao!s}2GExhjZ2F_5G`*<&#~;BYTR!ziY1cC_4Svz8j~3nb z@sA>sH07l1v3|BRx3Ii?ePh>CD7;Zv&Rw4__4;?4<*&9<;Uk{Rv8=4S61bq>?5W-M za-)mn6r|B^`?C2@iA>nG=5MW3{%`i+v?g^>NwzvQSpG=^uawtYk!pY*P{ET#%J63L z?d{$HzAf2iDb#s(vTB)%Kf!Ge_ zzLT{>T|!sF7P@c#<@=_}!-t%1Li!CJonTGs4APKpTsP!bq`Q$GL`pUyU4_)WJJ%h) z(TLcBcpBofLU|0*vq<~Ftj4nIg|tEsZsNdTq|K4S)i`r_v!HsUL*qF8O;CTNV>`li z3@e?$u88M#;>vdgee-~qc|&JT&j@-8X;~jmI}4hPv~?P%PczW9tw{HvuD{S-%BfKo z?aP(j1x`if(`e!oJUPtDJPhf&xm@>=pk0t2L<<)LZG`mKd0aPB&`_j1`*GT958CxH zB2JPyUMVm^x~D&SzrFEzZRd*Si|j|g{}tx70h2Gd z#A%t=oEnvdh*w)hT9{(1vma6yAgucN80HGr=Pc? zZV1v|_|8Jc-=h6_AuiDxItQ#V2BPv;SSUazc!)Gr&__r&x8b@Y1wD&&Tw6|i3c3er zBX|)K>@E>>HByiE_%QDbfoCJW0vMEg3`Zx%B3;>m)76)d_C`9mBd5`#%&|yQJ8^0h zv?kIVJ+HS<|Dc5cPK`QiO^)mDMO+A#-_+uCx}a~_R)anxpP*q}kz|4j+K@ z7}61SIPE3q-$?(h%V}Fdml+WUM{s;}7@C-dR8ybRKd&Mkj`R~!A7P>^((18X*ICeL zq^Dr>0Akrf6r(cI50RYq18QWw%NKEALyk8JWeI8XMw}{wK4rTp7F}XAr%Qf8*DfPn z(U{Zef@UH;-h|TxLDwUF)09!8zL&uB5&Ok(<(7g@MoOD;+Cb0&Nbe%8ENEM#xjL?U zWed7i4`~M+eO!cYS)>PyICjhy-9wA`crk8b;@@cEGb}x!%uXda-2+d3v#32ldI~9d ziS#tmY(K6$6D}s0?k=R~N^#m$jO4%P*o@4u+hE>aNAySKS*Uyjsrnq!(MVej;ks7^ zjYk>-yDU)8=JTlA3~3*vO)emN=X!dq%t?sVqTUWGu%y zLOBKLa-^lspoyVK|CqpaqxvE3jCAWnPOAvo5b2jmocak`32Cqq_p#oKa(E+t0r%Iz z^2Z+R~DV&}X^diz*D>+RYg1Y;WHf4(_i++pHUB@UqO#2G) z9D(PdayMAfg7QQ`Cn9b9fzv^P_D5RfBd47NZH@FAT4*e29i;76b6qO>fiVd2a@gyF z>`Dq{Poy7YuIwi0N4N%pGPild>H9udx_d~?ur~n~?g@GlX<{;`kta}hC(=- zryt@`w5COy_j6Cw)gm2;f-vWqlEGkejTT4*NvO#CFn(@ zeqA_iCFp*ne;|zzbRE(_d>Fi{p!1McJkKl`^+5tpM0|u}{f2rNiT+6EeB{0TTMwkI zkru1QAH$htL|O-_jP$0^4MO@1>1jbdkv26}=O)&g(Zol7MXSp~8el7u8cW(c|)sq~uDwSulfI%_4Tiv+a*W#jLA4A?Y*$Ds0XRGuhk zFGeBT@O|9HsVMCuq>V65J#?m>prJ@RzTnw55!6Rmda)NQ!Th@jN8UKmeLu0cVc>;R zTvC1Rf~CEW^yGZr?Agnk%$ZY27v^yKx*O6Aq-T$D`sZ|{D;b3}<5;#9-N=hvYTPvy z#mPe44aM8Dxp<8**$+*A|CiH+g0@1s>jbAJLBo-HMQ}P%&@#gQmw$Nn7jbiA0DISt zd8NigapQQR&Vs%;hdyUxqAe&56)`y{q<^Bc+GUjGgvI4ZYo6rv zV^`62rwda((UdRT!iTZ*URN|VP)MUtItaIG;>9LKb2M4>5>F$;Yu>CtdXdHh)4bo! zrAvfGA54>$W#o94z(gdvwuk%vx(1gf2 z=7O$7`Wfxk0a}##YDV0?IajXORUUD&sL@ZP>4`!EPQu;9m0S#?kTeiIy^hmvf{<1e zQYVzwtH}*pgw#VwAMWO*99oM@=ZfvV7iYL-qmqr{;p@5hoLF3*L$UHFN?)(w(s80m zY!gy5O53mF(%wS4KuCw6wBuSXZ6>5+gtQfx8g(E4;^JyT+(n4PFmbcrxb(g7x~`BG zLFv=YT>3>c20tNvw~Lo})8AZrQ%G&6F_u?QnzWHgjrzkvd{>Bfqxd{lX&15ka)?PS zx_Vf53q_iZNWHP5rwU4u#v>gi=oF;Iu^Q~##Kyr4Lk%~=Y)@hXZYIjxLP&#Ax_>(_ zQCVTKijWpW>6X1*>M5j!h18nCU9a|@OFwqPj`IfI(1QXQCqCo2hj(xU3vsQ1pYxhhe~}D%L1F`G&Xd zOe;>Qpy^1Dzvem4X^-_Y6KRnroIVt~2}r-;7U#KHs2hj$F>YpdZ7;6P42ZX4bejsp z)sTKU$epMuXi22HwVZ|sS^((^q&|YaJkEoA4X<-u1ig;55d{lIi~d79^zAU>eSdJn zZv@?h^aIjdK^Gy7!WMN;(5Xl#AiXQ-uZ%)XuV#^k-%4e9#20L5z8UppgjY>4aSq3N zdkLx{Ex&^)>npTDSBoPZh4g)Eq|Qk9A+=}!oZr#V72L@!ToO)QMcT%Q_+Nn!B3{aS zt^T+$ya8!r-qZC|(1l1hqXk)5NJ5GOnLbs}K}f3);7&{swEZ!gk&OdA#_^Dk6SzJq z*HU-H?i9=qd-YL5;U z+7RbKBE_YH%wLbVSs?O9QK41r(UBZw4~m@NX4;;jC~78Btw7PDr|=M9VH8CRQ3{Hl zF_D&up#9YqvVkZY*#|88V6reFYRN^qT6h~&FQ_k;XDd=aK_#RWyYo`&1bxcyf$7wE zXS1N7myhBQXhfVLnpY+&cZuUB?zY9|wI1oJTpprJg3d>}?*XUB1)YpEdlI*BK+pk5 zvqHG;ZbsQ7sBICumFIZ7P_BoxG1AR~mPI<}G}m1(s1|9=6i$B^^fT`J$*8+Z&<99c z;EZHkF7Ro@(-F@VbQjVrq$z^_j`R!CF@nxQs{g>97$oRuq_(O&5^;jYBkl45*M{u` zZiX1131_X)AZQJw&yYq5S_ zKS4u~u0-k~s29>3u3Y!K7^J`A$Z^D-)8~RdLb^hOd(*cCK8v`RmMdQn6h}H;GSZ`h zu14K`NVf|*8|eq6zY97RX;@)ycfO##8HH=(T*Olajz#4KUR-&&pf!;;D8gx+paDpC zBW)pQA*6kZa@`0)-)8al(*wqGh-Ijt#@mQ}8gT3{@G+!ec#pTJpnoH+8^v|Cf-Xba z0dM?z2s#aE6;8% z(^Y~_Mq021rz->x>nZSQRQ7qnmE#26g>(widV>Cr^dF>Qg3dy!N4sSO9gTF( zEpE3sqwX-!#&fK{yF^}atEx0TP|m&;ETsj@&u{rk3j<}B+kU=d;2VYeoncXMfW1`! zPhiET!}C?W0_BL?GbI1pa`x>dQr!T#Pfo?c!|_S3$`boL;xP4`9C<}f9e1bYHroMT zFrWa7Q>v~4-=bg^W8f_X1N^U)%_H#aG<%-fMe$-R0Mf?r$E(>t%J;|e z@H^2`?VIw>J7uI%rQ{oTLZxF-a-qAGrFu=|I(Pk~v?#gD-D=Y4DA{s1P#P8`Z@F94 zqq$n8M8~oPus)Q^=kAt}RHfwScfD&VegMt?uyQpH%ZxQ8cZMV7JkkN|_$VB+S6bnD za9(^cv2>wa_g*Fs=Z=Dkvq^Fn$3y-L#1h4R&V!M;z}V}I>~ zeEIiXwbn!5SaZ;iSSai6my?dom+Rjzq04E&uc~gE;HpZ`xApXq3%3ou-;796)#N=7 zG9-OddDO%8Qid%1KWYMxV)lR3&Dclw{PA&-IgQ|JSIHj}Sp9metFM8VllUXT@Z6*h zUJ(Y^AM${!x>@1yqiK8$-dt<6&>M(u3zWhBjS>TxF__J1k?f5W1%&HZ0nHJcpEVm%D3e?!MQ@WL)1sOWSIVe9}Ae5EQ4duR%WBsG5aw8Vtv8KDAU(X@SISu7A zkBbL@3?2%O2Vs|aqFDG$DSKbb+M%KBsw7Djqh+&F#k=9$|J9fsC7)G_8Kc>o0FnG7 z*X*tA(Bjb=c*l&r?U!tGOV9!F1(Iwl0HG)VM+Qx_0xk#5hwS0`dy7s5&>oGlQTz?R z1_pRy7M?4GM)_QM{gu755%yl`(gd1K@?jTKPPZP`uZ<=C8oS(Nv{oK#y-!l*?oUb; zwLsnD1+l@jFWv^PDri&X*-wU(S+ecPL6R&V%q<7UPjYKUy`3!{KVz>MPJuQ8wFzwx zI-F`Hd)3IMbcN4m#+tSbhr3v@rd3Js6K(oy20ybY7PH*z=}0MSwtVU7R_`WY%xZxA z(hRobbVv^^?r)2{>{&p~r{I$5Ab+ZOBfEZwch;hzcsBI`_LH1h)ex@Uzz$97p$=|zcvV>59-pqu^m zfgUlIelMeXSdEh)0G}h|!!P1>z2W^3ZH(!#!SWZrGVwy`XOzQVP9xLh%$M~^FWL6e zr_fO|1OmpX$`(1`RdZ?OOnJzwUr4-s=~WArlJF_f_l>nlniQDld2jh)%vN1a`qYY0`Ru2n z@WSQ8Po3f4`kzaYM7hW3`ec&4>~kH7R+F!OZYTAwCWn4$PA1CZzEqRsFnQybI>mOd z;o>kGPfXt&d|Vwi@9P(7Z&mr**R!OGeEQoSH+MCAJ2o*=nNUTRzjt=83?E%cgQ^ej zUQ0!%G$tY2{B2eu{aJ+;BBZ)hry6ZQNSw5x8eKt1sI<5mJxz$e)UXXp#haoo3O^5~(B=u1s%9BtZIQ7PU#FrF0>bwsImpqy?dLlM~1* zgwmT%q?}YWl&YOcbE%%0wq?KDE729s#2}d~QL8hFlCD>zmDHf;Rf%>`ld;nL>hz47 z^pu8Fq*V)$X41?GbYcOJAFM#v6o7QJ0)0_{43S#Tpm7Bu-;fz}Q$f;DDmsI{hTm-u zlKqM2_z-;fpS>1$s}H;*QqHY1Lu?1@FLv%NcS-F;tGbX0l_r;Cy4F3te|k*?Up8pT zW%jocXm5JOg>0{MxGYa`z1M%Fn9pVQ6dAo}hAX5fgegA5@Zj(&4CZk?7=6VzAFjkx zsGseXT61bG{$D8qeoFD7CmrJkDHaBCuj=&tk39NwncXX&p0txY*;(Ow8J?nZoWmpT z=+g!+vFq20qqRK9p0a+ZpU{KpN5VkDU&we}+R^_`J*bZ-*dD~Gby4^Kv0eKo{W0C? z2T$_CbzC6##n_F$&=6m3BYtXkpi?*Mqa`-CF#%kuRacvhMvawxH2mDIRjzAB)564s zcrEt-@nVj_($z)r=t6sWkzid*J2zNLN-#h|W4O?nF7+a%E2==mT8DLQX9ypE*(iIu z{q-9d6ONY>@@bu^;ziyWjpJbe%(Twvlvlo=5)`&4=noqIVbI4eZ}Q*r{eB|DvOnYo zGfeUNe?ed%URef{`xPjIcv-=!>O_YYCC`l^kXz{u9a&qV2-D`u$N_hYkIgi z$t*w2C$F`^OC>JKl~!zKha-5OJ7H3^W@kh8K3Ojxy0HZDlYVbSPnIB2Q9h8Yo84Ah zNW$MUBBR7UdnAzTA1{FYc$I3gHCP}(xeSSw z&d<)6SccRmQrn?)ZxCtc9bvKA;JXYk&l=1L;92rf7p1% z+lO9lLMlrIc2bw7q?+V4nAU4bW=iih^jK5UMrwDImN1Yml0id98%TTU_apSAfy^p5 zzbOA$-tcIAhjPs}c&q`wYabtN`mmp^Uf`O-U1{J+jWIB>9XU+@j3K3^xf*&ZhSZbp z7ol#=NT8JFK`S>SyCroIYHbD+-TST7w>gQF-u9Q}f>if*E(B49HM)ks*v>8yvX!K) zjMFWMk0gz8rH@;Ys>QYf5Yf?!wram?rz&)%pi_?p(Nw{lI4i!Uj>fMG^(8UTJrATpDQ2h2CR%xc|86DaX zm@QMh`PY3yVU2vG0KBo*mb8*`C3>MPX;^f+Dw4JO&+t;uY%_$C4f-_7g;bOh$J4tN zNW~(F5eDAu-vo$epPET)3?j7(XRt{kuUA{g(0c938t=ibOb=#e2+3A>F-i;T>~c=@ zLwgd~Y(7jatbxK?wiAN_@H+wNyT1d2+3{#f5c|9Ycym;qoOco zmWB47+IcRX<`T1z9J5P=J5Yv=m{d4-#;yPo86@lzT^{i1MEe)IjKElJISj`JOBMa+ z8$VQ(9-w0V3hl<>ZMY8(@`wvGtTP!>c$1ok{9)L87WCn^?{sr#Qo?wz3mbsgXD1)# zC4zg9is?N6=nT$O(Olz9o`%8FBU9-QD!JawKfX_3upLs$9CB9~!gJyKbvx@C%=*=( zy;YW`ck0EBE)LY-;HrNS$S-nT4io|x;Ht6J zLHeQ#xlWSliLPX@JH00Qs&$fa{io@c?xa{$yD!j@pf}XVue{Z>tH3uQ z;7Yj?yxx92ERzLo{Amabyu3aSE`trpU$hCn(Qp<`XrUe?yzsf|d`O{W3EA{SUoyw{%||x26%B$~ISl6E`*8_DKFY06bVNTGgC`!P2m6tglJx`a*B>sa zN_?Vnf3nlp>BIk~Dyr=JNPGPPsb(Fe42atWfMc(~yDy_2o9c?p^ zv?9xBRzFgT9vDa>q<9zleIVIb`rm)C9l}EZKXv!I9Gny7K~)F4tu3Ohkx4}wcM zlZxsGlYsJ74nyN(Bel{)1%IN4?^szYu)&(Wnm!Vw{6Z{JMJEp?J+-}$BY^q{v7Uzk zi3_$R68d#U`56!^~r-jAcP~_u*u78JaT`7Ep_h(jvo1P{C9f zxM2}Z>klSA<*TqaXt8<#i|T<@fv6skV)cBblZTOEuJREElw)7$`(b3PS6_Y#!xik< zHG~nRe;SP(Omyxq_S>!ceW5FdlTy`G4w|o^2c^M4<7_(yQITi!g2bA)7yq~bmS@Qy z7eiz58%19YCq*;^N;{NfLLeqIVqY?!VSR* z?!5Lh-86y>b?wVrfwK4$4IW8)xcB0xY^<&NiOwEL!ae(~Kv&rAbodB*X(Xwj83HRA zYzYv`B!B8TiUbxOQc9GMrA~r=%ZuH-%3gc1djJ!`gtmggj07nL6NGuoJGPvMF!YD! zgQI#Nh|_4V6;d&px?WO_zIPdhzFSH; z_@3^EzHcn);CuReyYH>`*nOV_EWhvZAmzTtgYbWR-we$JeUAe1|M|bo-Wbv) zx{f`;*f&3Qx=%~c^{s;)T!(vqywiP!Zu6t1Xo^$gSduDT^`!;Ik}X+_|f-=%aCDW!-nF=)|Of@C&a)rQqpM zIQ=mY*u%No*TJWgKJ?&tQnjp?kI3H8C(C4J@7lu^?IG0?SfW4#H@t)@grSYr9!&h) zTWzX-POGhV8A|3rbz%U;XVMBgKB*eyc%256s?67EI zy?p8!eKm;`E1F?%f$Sp~+}reLwA5s>&@i@$NFH1MRWp-&RY>&iDR^@bsy8oG;7k)R zVZ98Sxj#`0uYBd;Q~Gr>S>`h~BVSO8fGvAa4zL9(AG@FBVo*FlJ%3QPfEEwRmfZgg zO0k6)l)HT}DE>tpf>O;3gA!_QvHum6XHPIFGYboUegq}+2?k}C_J4w+d-7jF>9^y* zg0gWNZz=bz^yU=OQd<<1*r>@$)yrFEtfgXdXjscUMlqTR1#cw+(aG)IEjl@m}khXDQbF54#no{Ov(+roaaG z01sL=mGr9=Wn$|IxRJoWt(I%xn_$Yn9{-#2iaX6nCH;%^#Xf?+vODWTx=1wPmn!av% z#Zkr-qCPWV&2^$1jh+EJGTk@RUuKX{=aBnQxqN6k1COC%^Z#~_X3Zd_J>xcsCIHKk zQ}^hr86?0n#euE3NBvE(ZB@pBRk=s!n25hyE&D^Q>U(szi3GZ?{fpPqjl1-|iFDMg z*(hwYyOX2uQo~FV>G>-_*nVMq#pUmQr!@z|_;?2XP^ob1&W|<+7reL#xC2ri*E@IU z?U|&4|Dg96*Qb}DhS{fo;1yn2bq?o&dfb_oGn3{+x)u~R|Ev3jLN-z1&nF&>Hf?jk z=hqk7+r4$pPmPaX*ER|gK^&+fQZ`0WpQrs&+Er8qY@3!1)O3H6^kA;kFalIYONi+LAi!$WKFU9zl;Fj~e z0;1vLh3=XZR#Lb*Tw)Bk65iT{eKy=04Q^QUXPt%R2DhkjHmOnU&7TY?(k;j+OS7{z zxCr-^^(EHRle0;&@GCcgr}GZ@!^U|`vKK^FC@hTVNsu4wIe%~oOd9DoX{kA|+4prB zZ8(S2XuPm3I)0kzF~=W4Z!{fIhMp7c<`OrcyA9U^++zboir>QA>m(d@x=H_;L&j9< z4S=^$$Y$~l@Gd!D=idN-TbMV}_!~4XjTCoX#(@%XgHB0()rw#PmSz#aCnhU7aRV@>rWxDVhC zG55Gax6X%)^Lms@3rLjlc&t5)(0lnH>jM`J_N8R3c^jV+%CJjHh~;EMpGyXKor9w<3X}7hNgwLHhy)cqAH!=W?nie}wj85di%XU1#6=`bnj_QA zi(nt9R1AH&i1UadM*L=@DuGu-ki9+g}# zh>R`*_udchs0oiX{TdX&o`Z-E3V}Mab$~yhq5f+JUAmM+Io*MciJYaRjjrTJ_$vgk zA;tP2e!@X zFy5|(jUJ3F+sN4UmR?>C_tC$;qosc%)1>(y==$GC4Uf~X<};Yx*=NHKEup!;kz&%W zleEAJxHnT9hI!@(_~UDxdXm;#LE4mR&0c|z2jw z(8+%67oI25o`7gu^wVBKV_>%n*q;wR2KQyv#rMpH$)AK<79enEzwES zQmC?)__SEv4d4(J9WfRcpzYHu{59uUxZ;1|Hh0lBJnufx0;IrF+(q zFJ06hfkHlK;2AR>f6V7ZGF|-#>0ABnQxBCD_FHU6-gM7o>Vr|e>(A;D$#B0T1Jo3! z6k2y3nJ?XPrRUZ`an2^v=j%v~1~cd8)o*?N*KZ=|d7VmW_!S;SHS1(J-jCl%W}m;` z`wb|Jx z%*2AhV50X=7qWPP0CUncHNCWfJd~#Prh7NS&RvUTlx!j+J!9Yl&XB&>EJ%N9Af2)a zN*BmZRu0VAxQWyuQiqAux*2Zw#>COYEu?nKuHqpxYXNBA;vs+^H~OH0eI9zKc1J?R zv&dQRLaR*6{vnU$E4ONP6NmO>eAz-SIcvWj(TUqg?AAkEe|l#JDdT$_=pGH2;`fWe z%}S}@*_#AfVkdd&m33Ih2WNi62kz+v_M?6oq-+%vaL(YS$+Nz2gCTdK75=8gNWecC zyOa#ZmW`q#Gf1PFQ=Y3{wt^-N(=dD$b2>cj4JS{KeMT0_m|1;lWlfbK>vR|S75RS8xwGl}et&#l{>YvC?B_ZAInO!QR~?(u zE%GN*%EdQpcs})+`69*^wv~-EmfaWVqIWUY`VO3EYgFf3OkU#FcibW`Zhd!NTK@oA zQd&W{4B^rFbcK8x7_p9WBq1h$Dikz70R{M?guzS-4xF_sNU8C`1)R85o^Gkft@7ul zp!;;)Dj%IKZosWa5fv}!iuo1Uy1m(St+Fl?1I6OPTdIY)AV1x;{4>J3-6~~C{O&wi zzx?)uApX9{$CH2bvy|R8>oM@A50n2H$ehA1sm7)H8*-jC-yev!(X?#~fwlO3qcZ1i+z2&hY>4{PL( zM;a^{oz~&Ad%>#Y7zeFosRnKX(K-;(`mM%gq-`-^AGTG7Wp1e+Pja&iWxjEP^#QDK zA1{4a3a1ZKgt5jq__qh7Djgn-LuZ$zT_tSwRUdk;TD}4ghr;C%bNM*9ys&*1^WCc9WEuV=3LOG5yg8fMknD zsxN+y?t!14NxH;eA^5jhPFAJeSU&WSRI}nHqZ4Ky5c)%qa$_vtcu0zk+U3TQJw|w- zw4)S>p_`}eJAhFy=EK(-4e#7s8^L1^OBI{lY(vSQfa!2YQrf5zPF!;pjfN_ymYbfC zF+A%qVn!!l;|~u@L8c9(F{-ikyqH^9DKJ|X8HixOgCr?0j0Ry#ct4Wf|{VC0@8|l;Xo<=gvh*+S_ySH z9GH0@*}W((?tV6k>a;QQ;f!{<1wC)%6x^+qO9nrC4Uc5rn9)7=de3_~1vhG)B1^$O z+96mSL+k{9;bun#=AK8S_NJ0oT|R3EeD0f`+0kfA4domNmA4*n0$$evN16j2z<4*H z)&cD127EHo&OXu&cw?kTGmY&OMk#9hN3B(SH|SmtqVCbzbkDNLVr3`T0sr2OdF@E9 zJ1QCaY;Y^~{Xmv14-Gb2Di!CFAJ2kmx*Jn7A`o-xgc;8Asf3Yn*<$Iz30C|^@-;`L z%EQ}&-MC7aVSH7DNens^^w&2=ATL~vHT1l>;_~D{V1>8xrn}T^0kE%to&Xe*?8Vpi z=?H7pW0If5_D|#Wa-?!>(>+}vA?^ICOPJA>aUR1;=i(H zV%(OLq0RMIh7IF?JO>4pLdlXur8a8<)%Mp^NJ581M~ZVcX}ut4b!y8JT2RHcNVSbVSpmSajzs3 z&=C`xH;XrZB>fxqs+}M`Hq)K-wE#Luzn#f@J_f0zl5YIio%Cv3cc}|L=F^`@c@gmf zYO~HD(lmI+VMN&v$oULD@~O1Le@2qKkgL;q&1X_k)K_Td#DweIG!pZlAS6TYZ`D<4 zafQF~{j~SX15Bab^}s}B#4nmA~ zDu4b$I$8ZtElA1oJwOjk;&chLUEPk_5L)Jjv#X@=+y6-A{mT%i)6K7@@{%v5z10sz zsOT@4|p zB_2Xfg1a1}V6knS=q{(~2XYon>IW3hk<)p9-Ku&Vn&~da?ATjeoF^`n7G%U3outH1gi9y;Q6FG*GxQzs=|sR`#aN`6@zI4jwL9%bU4m)gJY~$?6XZ zm#mVbtgj^2NNU?Ph@|M$P`Csx7{RB@Y?4fqg> z$6VL0XBLp|dT_dGt3Rv4M%U#h{aJ8@GQf{mN-8S2sd(3mv(l^vYiQxMO0$|F-}m~! zNko2rk;|gRz4(;UEHv4LPD` z-Pw~Tmtjc}RRM4?_U-wBUZ_1&$DXjbp8QZ5_H*0JH$_;|#P~h|Ti^j=3%vc%e05PL z-E0@t!5nZ3nG#GJ+TD7PyW%i7r5(E(AQ9?gd+;M=SvBunwe1T0d+A z>dr2W+&*}mQ7q|}d<&wip6@Xu&g#OW^{hugB#4rRDkGLASv+ovX-`ru{*|6pWUtHe zy?PcE+GByQ27$=b1bTOSUo3WVPhw~x+8hy~ys0erD#uoo@dc%;kb2tMcjZ5oW1)VP ziCS&aluBLs-EwRti*Ik8Q=Uag>`Gg8=j2KS_SWO?cGzR@yi&qP=cY}tF*4gM?3ZRCdyUX39+pM zsaqSON*n9Krvb0jhW-zQl*QM5XnA3tpd>-P+VO9yu!HPPG9O-*#Z>d_4x7zmRRdMx zp&+(zPw5`Ry|mrNY=?GM{eS|eMCCHNxuEu6F>lgf1 zHD+T0CVsLy+g9%7B5G^Uzbbz_f8ANc7l)!<%UQ&?hO&>?Vl96b%HlnfFoL5LsyQCj zO7iE!!dL`*?7{2RU z0g5u{Y0H_(--ff0%1=9C<(DG-m7XfaZ2$ztf|7n{K*A0w3=SLX5D{#A02_Az zL6j(m-DmL8wb`5+H3$Tt}E5Fwx6-g-t;0S0-8F{kM4NGO1(S;+Z-K?yLPP+~+n9TlI?T>$AEY z9{M`jk)jH=-VovHy0Z+gOFHpNEO3Pux5fu@&${7*Uh!r1*>%5*wQ285{o1mRAD_{H z1(|O9IOQZ$9C68)bpHO9x~yRF?e&pf^9ydl5LI7U^iK)QFb%^mIc-+1{sVgSfhC+` zlpKIW2pZtZSSM+cC25q=(iwq5ID5X1*x(TpXdb#~fcIB2?Kq&`et@c=jB%k#j&n)| zSFqC2g$i(?a_-!D)j3?LZ%0y3X9#kjfh_T=bCjb0hp%dgtbR40pKHjzmf@cZ7@ARx4_Hg zxCkM}cU}TE->BoG7!kBb%1_UQ+sk6nrs z;Kd)CpC@z+@{m#jF9KMFY!r}QH{9gGgY`+&n|h~o3swMc%+eV;17c6567-ZWYl7iN zU^?H{gjFyGtI|&CGH_>{Ca2)vIv4CR1c%62;Tq)-zJV!HdfQQB#DFc{(kV{a@Pzxs zu;8$jX|N4Tt%LA{7|Eg7O-%nMymJgI@3Y7uMQQqkr^K+ZdbNoOJ6Q|yAs|>%SnC4T zXK9?bb(GzHH!=4g^AjT<`Qc_P#(yw2Fe!9HUE69@oqINCZT$Opr#`BAsEFZECU)Zko3lDB zz8lYK&c?8R&ht0TSpgdo!f(a`p3{YUwP2$weS8ihGUt2&pDtnfbngPzy#^Y`@3yU(k{;koC&wM85Ym2iQW zqmC>M=M&;tOLk7-pSEHPDwMqeTGrM6ZHYg`5J^d zQK1L2*}?ZkkpufAjCW`S?6iMf*l*rBu>N7ZZfn+qCnPcxix|su6WJS9cMQ+|h&^G= zM_YHcVV+W8eXO2{L5zA-)gCbtZVMd6FB{otKG4WQqz-)YQdWgWR+W599>o`_GmEge zJCD^f-4s2+ry|ZA+ot7`(qGdj@uvIkqepT?c5=*#se!Jstz);rk+;b)=cg24@uLY= zVUo>f#nh0FG@v|Qs6muWc=0w#H*nn640=(wjJyI=O!dvWM6?w9YAAtGQ6apH$ zsle7)=*YR-y@?{Z=;Kw?E9^HA{cSg9#qnIDIG$bo z>1BA6Yaq;54Kb8b=?a95Bh}6e>)u&~=?yQFw((8Q+vy?V*I*KH1aU!>ikm83&)-3Z z2%je)xPa)hGwoQ{CZG4TmpqF1srtKUqdN7n!%&TU0HW)vD4ZzG0asq$hG5H{r{Van|m}EgjjQ9)p2^ zF`spF>F5BES^{$1piNZ5sHZN%Fo0}5(dt1!Z8x~@bspb|)n;*B_=HX@)Te%Tbb^>+ z6f0@h`I=6wrRnfaQ5%EkiQ@T_KYH7|`Jpsdr$3b9u=zkGnTwLl_x95QCP0xNt6YX< zf-9&~J9O|U?~CxNM#bSxPkazLR7X{!K&?+f(^cT~vs88FG%+1P-MOw-m#{i2&c70* zy*DL zm*a02MkW9jd6gG-W)c3L2Z}^+t@#fWdu6{55AA{;?eJATunX%K{j)PO7ocK^OuXU* zr2v#{*+^ASM1^D-PIlsdcVSaZkA4*yJkmjmdU`_z&F<{V$`b-~P=icL%Gw=DmvAfd zk!8lLgK=)KWXm2RQ7AW&=}C{A5|S-~P%){p;~eTt&^L}?mK9CF38q>uCZ!87v@Z^D zxC5MX6xCY$dcftpx)+ya z4e!^D1)2^4K?Hm8gsz?r>-LEbd>`l>yYpF55GiDb<45lE-oEqfyfana)*tfD1~1Zv z4M|E{=0m4Llp%Jh0GpaP;FP#LSP~lvX~Ie*E)NaL-1ka-H#0Jgq#YJ(Rjp+l0@Re1 zBvQmd(8x3k>+P_(uvR7(SB1qFhN`K}#}nGebfM)WN~xOMQ!7dRzb0DrD-%k)QeCM#djdBqz;t23d)0N&}7Wo6GuxxOJliT z4;E@-LTl+CUL%XqP-fB-%=Zc%+Nl#zUR;Fb`8{9e6r8G+xsVKohw_GqR9^m&G~bOh zYn@0WcvjjIxg0#iYf*V;`#X$RJ(P8kAL+qbv5L*PwkMXaCpYJjJ+U74r-A?6lTBdS z#yp}I>&SLD;xl`(k*28~UG5loUU(?DgA0@lQ0|4E4|57G)yh;v3VUm-4iaV$a-FX9>|M& zv*13<6j#ctgNd>+*#+_^kXU^#=g^8K;_X?I{<)A&-D@7WoOsnWSI_e4eOUd_Uj_&V zyl^;JV9`8esh&l=Px@JYrVk6RJW-`Q{~tzf6)QN+7)M+Zf}* z+~)(%DdoUIqk>_^+8$xyAk}5!OFrb+O-4-T(sMjfw?z%ZwuBna8$YnW?bd1Q#D1*0 z#C96_=lxk<7J1tGv_CUQ^4{Vi9x;#^*oeD)&_FD^Udty9zR`j1YZ$c1Ffd;%GBia< zgk6EMjcBtB8{A^wR;i#xZr=Mu1(m&v8D6$p`=-N2#87Fst5lUQd*g%JNti#?Aykwe*98qq{XAZI2pdzwxQQ%R z4j)Hqp$Ju_vca3U?`W1$bzC;=aIXKVL8$RP<9oz+M>5aF^X;Qq zgnm;oh9_But6Smwtk|-M{Zm3(@Q0&W#p<76!G?Bk-nWntL`64FJ;pVh%0z&Z5PdEw znSFS~7*;K=^g;NOkhw|?EUmPU`CFHH2F15smPbA8XMKw3H?`Z?k6(0}EBv_gGB@SL z`yy@`!{WV6g6x4}+`zAlVJUu+crRW^i&)3k^Il`wM^POHFm;e*h_`z^F>69GF5Fad zii*@RaBBxf`KhRgpB;-rI4y)LV_9(Do!FWuhi`jUR19OqbY>kkWpOO5Q>sSu#8?~` zOxJ4FsY|ztCF2-QzWXtpgLe#?_8%U@iC53zY`nvVj$;Yz*E;;WajZ_+2XU|tf?;bs z9JumbQL(yH5xfgq8KuXwS{1Ihpk)%JDNuA{>xO=`r=#uLj&~i;+Um}uF6AYJj-yhi z)c=-m8;|Kh`mg-bcr5#6{>$HtXCZ+{AJE7$Pb4Em3uQ0WtFD@^Y;Wxz9pwNjSKjh16Iivt zGNhR{EsK#zxBJKzt+C#lz;sf%Jna8d{fiPSdkI)bXs+m2^HP&oYZmu4?=XqA@zXW8 z>oWhQ+<475PGZ&k%f||@>_9^bZ(MJ~f1Siay!`|e6?e{Sj`Km)K8km+MrS8j#-V%| zi6P5ixJcy-pB9@(=VxhOibA`+(5`||3|#6tI2HYCJ{q!G7kpJzEPAd-7}47^O}Y6B zjrK9z3^h|M|3YM~dm_oHxq{XM7CClAcf8_fC$p+P)0^4Tqh!9~Zzi)!elr{pnBMOd zuQr8M4|f{iIG`oko)GAR{TIO?wq{Dd;^U{VwlTRec9{v51390I0!421OfbJuzI&oMO!z4Dw1%p?d)re_zv#D zL4qb3#VjRJiBF++RNwO~wJ3(sctnF2wC2U zjQcyLk9;+EmNp>Se9jp0%2=Fdl+GjO)2uC1#OF_AaSgq|XU}dMH3;sZ;jXnO*jKWN zUBM^MtgolBfs+5SQ-Ht}HCU+pQ|rhX>~E>fxqOvS34V+&!+GmsU$OKCLCYO@&42K~ zt!QZHz4yrac)?uuk#_?JAo(v|-^2>NtL4}!df0e)8k=GrGoO`{ zy#6_A2Or~$GFhj{?;Y=>QEQ!RyB{QRpo8QiYspX8PZHlWvqV|mtP;~%PcC3(C6;~I zdTSv&E3s<_`SwLDik&%VEm*`l$!y<#-e3uuzCQb{A1`6UB=*NX>#a}O5Q*Kl^480M zS!m_vW$Xo;z1M2`jCGRO7kh9<7UQ(HyLrpcvG!bc4NCZpk*@nPKfVuB%ig5MPtVq1bdn(g3DRvZXQ>Mit4N&Z7sg@+La>^dUaL zjwcozNby!rMnz{QnZ-KrDloK1>$b2Hex&*x`(PP9*Q?mKD^z+wc;)@t)AyPtvY44^9tqzCNqH$D`^rWz?v-H^wG!`Evvp&x@ z(Ltu-j+*Jy=Vzx*rFiLRWBOYG=?+Ne_=U|&8;g%8#~e@1rIFh)_Y+!JzrK!gvZ|E5 z+-KwB{11xvgLQVyH^9J#1YBn8JmFRNE#iGlZh+|G!uccIj(|b*A%}nwE&;CPY1&$F zqqjBw&pXZFafLP(%UxO_G!XW}a%#Jb)sZHf7YTQc*C+`8|5BP76#l=KmXi|Km63wD z^$*F{be#4P@cA#b{NRgH|3Bp?BHI}AL^p3I$_us~fZu6UO3`C^B)n z&-0A2R6cYI(qIBzq&O>4w-;A}+lx(q0`*E<=uz5;LUUN`F{sX^8wcF7n?hU7v?XaS zX)h&lNB&cOK3`+U)BxsxlpoyCfD1~UQ*hvq`eEFxdzH-MV)@DDjiuvidBo5r6+J8xye_y&$}d z{!HvC?m1jktVE^B;-+OvVb7> zULGWGJV4UTPI7=qs#jh4f||e_Qtt~1h+rv41X-~Qh}eto+RB=1zrxRa{$eW&jR-x1 zz6fzGi^sz)dlM@dV~){Yt-%Ly5j}%jLgR6rooy6)76um7G!1c60)G)frvO2+Ry>hH2-=oS9pd)CDy zgN>{kJI-5!b~OPzcChbu`^<+a)!cUDpy2u`yS++F&>AxyN>gn~Xu8n{&{)tL${f}e zA6MGVqKSWKX#322y37Gs_3Min1Vth3Sw-Q7@%EHx>4LvtesCM>)pTU^`(pDk^jS-a zC`sZf5?T{)xq}9m>U0dBzM-L2mf?oQq3(vVgm?UbRSdg)QcX&8Dt`_~3u5QS3`$Ve z53GEZeQ{XIj!E>?&0j*Q@R3^P5SOh~;zxgAjeS ztWLlZr=<9d<17i$0m?=0y#pI=Ux53ozA87aqr)vqbe%Xtfq)PqoD7-MvFU?@`=nsF z1B(&+c!IabTu8U~JWyF~s4j$hsIm-mgEu8OZU-q=>S&NK>c*%t3w;nV3#1UN2Nl*l zCgj0kr~)><_1X?5Nnt~e2WXO|bD~0vxudcyl~zX#ZGlj$&68o)_dl^p(!lDu0h;}F zkiUW&6|_$gj#43X%D#n-r6|$+C{0sJs4G*dSn7$XJH|$~@2#8wEK@WORLX${YR=(Z zRg=nR>|%|)_rCK{rx&Ta`OmvpL!XWgK%?DaC8iv2+03`3wZv}bBY6iNbFgRgpgqhO zyx=;@HXnAU_)A>&^h#-VRrT@+W5yu=wIbpLA6ZdCFY%MVuu81vbN=8L zR>dy^;v6%4?`^#70oKm+a=1`o{l2KUFk6f@k}O}Gz{&v$SVjv)mM_k$uSu4@xA9Av z1*mN}YNNZoS%&6&$u-J&NU~8~Rql?Z_FL2d=dxSR7e1PJbi*`#q@%O^_XDhCt0v%y z&R0LSiG>=(xFh$IE#K4FKf$t*?r6=^mOWvB3jomV-BkgIJZ({)3Ql|9X%$ zZgFIoD#`dCNzquR?xso#dM>7C;gDo^YO(hB;}CZFJKpvX8{-u@Se3D^0Y7wzRjjaj zp-^qXLsi|7sOx>lA0J{Py(SJ)so&SUQ*hJrO4EagY~l#}V;RAvOv=pQMVtQ$;0Q2|_jH z@kG}gbTF#u6OoAEhUgw$nI>+20QMkwC`-$I&5cJ`U9U|0`yWv}?Fg$;y{;kDHKlJcEiCX-%;FLPbz{ zUylzu${KXq2rNYA%y;w8$48-W(q{N4MiA@fXQ-)OrV?)ev6|?1MEMaY?UrR_stIpe z?*q%gO-i~DI}%>`OWx`jI5C)JS>j#L8Idw{6 zKI|v*z4;@NksC6crXC?vH;Mc?B>4Hp!>k!=QI`kjumG=5>@tH_@fJC(yVpBJhLDaU zEBWdiR<-3jNTTLTR^$Lh1B*ZqBTe4ZYPj@~3&MMQM8$EwRhm zbcVOhWi`Ae+28MRJ~Nj!_o`)oUsH!?=d!-0kN*~O+oU@Z^W+eO7OqFLv<ZBdT4)dOYbrQPweka5Al1)S)wVA?1V3WIfd-74->be35w1? z9#>y-d<}WMooWS9Q75xa_41xVVdcNrEmuq7rh~9@?K<>c%c--Wy(&p<(DtjOxwNsa zF5VYwXC6!f`DBp0%9KN8J-f=~E1)taS2y2FRr!@F$Lv&DpHxP!qg+k&IuCzQa(+C? z<4&+%UZwh|?*}4yd_IfeH%_q9fpv%o7v0WvSY7o1L@dyrsn z8yKSI%GEgz&a_{^ISX3>d@x-MjU9;6{2Xz<$3T({nH#Puu6U9K1bV<|C^k6R|JV=q z>#H5?gHEyvUM=jLH*2b#znoFJ1g!enp?%#cXfI{w{JMs!{ohlpY>lQc7*e}AIg9pz^EKA?(XZl$ z970CTQG1JzkGn&k!eF?8dW%8F`I6Ht!|SX)eXYZIr8BHzN9DdStL{vPSy!zPe(_63 z?{STZ3T;!#-hJ%mfuD$S3n*bmS=9^;UvrqnRf@y&CF z+SZ^=uxOj(x5c;VUap*F$)>6B9PEGdr;lcgEMdC~iw7tYq|?QXnpe{O$=QKeOV z^&I*Y3@biS- ze8+jLA8%G&@Rbl}B!bo;5Tzh*({CH}s@U`&hFmqpxTD8q(9guMgBX^*{I7zKRf8_4 zxY3)5K8@%NPyb85LY2SCL2sgwd~agtL=0Wu{FkAknt~Ju1JOqieK66_LofVcihKVd zQk>vU|K=yqKlvQ=1OEOGy-Dwfq#}<4+!^wTA)6Rd|A$Ktsr2`zx}|s((Jv+Xo&WWa zAqgI`FFz^cK~k(83u;?9$^#BqV@-8EEOrpI7X>^Mv6Dxz9SRGpvw#|lG5(5td064e-@stqd9G(z432!hJbNnT4wB}^jHI3i6i z{Et9=gqo~j?gmsOdjI8CzhBw!5<5PHKfJ=Klr6ms?Xx8n-=BL)-?P1?#8u)|uCj6w z%fL%p2tBFW5Y2_5Kg?9lFD)w0h+UTAuVK1RvCE|4^{z8LpK_JejC}_lL2GHRQKo?q zr*~;7YKI-J3{heJ)cP3O3aHWnFpKtdH-6P#GGM2L{2p!ik1!KA;^x0bMCofLr zKV8FacWNq+zQzK^9cWEH(e{Io_)eYhE2yh40yhdeVZrIxT3SER`~2>se!7>ouCRuo z981P}6b^8SMKJerU>F0n2%C_R9%as_l)@IIeeO7D{wGD%{6~t=+&N6ud=f0G=Fhq~ zHP=x!r{4UJ<~nxGaEO}tzb7Ftg}SFpc;t09+|+pr6q-tkAhNL(&w7h=ytY(pqNB5V%Oj{y~g6F^wFG})}9@RU^!XzwhZ z`x~oO`4|DRl^P%t1t$mZs_)8Xaqk-}n|1z;pSi(mRb0`@fFNpc>;sU%hPVk171Jzy%S~2W z9}EZ(eXc7q<)nqWI*mY*%of-2SVkgc+GHx<`S)H1WD5u;J zX1~1(Nh+j3ccz7V_7(U{km%)yqxl{RL`Tt2w3a zSRiZ~b;%)h;H5HZTC1vZ0b=VVm)K7};VTPR^~UMMLz`vhB2{{)PwaI;6da*2 z79bSq)VEksNU06yj(f|W6|lzo_NrVDH@UYnRp<6`n!6)Yb;Ek%rjj&peQBO{+i7mx zD2KVzGWnJ}Fn2c~lC|mq(kiS`MlR%h^?fG z-Fm?#_7hz1iz*mIWlJQr69&6fdoN=ZNv*w?{M9^r1sWK2dxS%5x%u4l9>k_W5fE?B zyTo3}P_5nRl)ElN$epp;A$Q_xe}4WJtX0KEImP0Ri+v=P6hUlTH?cJ`M4t5@O+4;- z_GF$t&rGBc-Ks|U9UvrRPdX_~gx9y>m;3Ie7^ZVo`=sHHM13=l&-fGCBUSB-&bbmb zVxCA;kf?~lSy8GE&k>G96%XgP{$}OvY04hvkoq#6hu??PMbLvZ{dU$Rb#FQ!b)U5e z^Z~IlIUPph>mK;+=rRYSTeI)8NQu=u%O5{rAwjbf44CO=ERCavl3L`k03=z;jnODi zO*~RznN{vkc@!27G6^qKFj8aO9$wHH19;T$a63q#>B(S+i8W08wZfwG!-ohHwWnPs z7R=?bHWpUpOQ+Z!bA?!CBh|pR5PNH*y=Jdf<;FSXPMgcO*jS{#qAIu7DVN-abNOF3 z7G9-~Q?5ppyRtILC38QmT!u$cnO4Ov#TvKT=pLWLd;JA-=RgtCvH7G+Z2BD4Tra2C zPIH90;XA0Rkl3m_u=-Qr6nlH1Lu|P@+_Mm3Z$J^m{*&(#dttUJc0bih;oNnY^Pz}U z2yuwjg`i^FAQmLxj&h0}F`Mrru}xI5iEd&;RI!c6IK@7hCB%Bt`X#;+i4N4iG_o4w zglVeWPX{>6&7H-2{|&jDpa}{$op70(HcM@X>O19jvdg_srIox;{HMKYH&*4|?(dLW zZWi}^2)XZ|iQJIql6zq$Z~qXxV{>@gLj=n|Xv(b*S(p^ee}9NDuLbtkY##dvr*B*E zfsYXI_ai_2h*gww`1MDufBhPF5#LBFjH^*k6Ehzo!ud#3(xYD+>Z>^f>*&}kB1-U4 zTEsmnFKh8pk6BIjQ$N1!F%BuW;d>vmx>b!QvC^Jc6^GqSiQ;${{m|{hkgK@xfbu1m zpRmSk=NjJp3Bt}kTf_T3VbK*#hu~X$EEWrwG2YfAxe7VHv5s?^9fw(mR!BK1KZa^NPIiDO<&QRkVKcj9I0C zs#Mt3Nd=8MZ0Dw8A#PboDWH<_&3-Zj0gy%u7uHy;!jvWZdD;s$s>#<>pxszQ!75e* zC}>hC@qgid^s_biAJ#-_l1wGcjeYlIclIy#{qM@>?&C{evPOaXx}zXa5y#=VY;u+5 zE3#2}6vc19WOak%{Oov))OJSMkKK)NFez(!-B+x9_bv_qsAhpm+_Cb)*Ul;~P8tTV zNR`F+=QNsF%$X!MWtGBu*l~{eGbLS&N*Bl5nUn_n%U3MQGz7#+S>r-gY6`4f3I>E{ zU}t(h7Nmp3#KyN7$ke@UP)q=Y4c{Yg!xT4TH%dWK@kt)R($Ue zRkPzZ*+ON$r_)%q~E)K5A zI2Npwo5(%i;QEslPNs(wFzwU#giPVRrB1|UfoSDGWH}MP2t=dgeX zX;RDrAv+Kgx?%-MHF=W2+^LWCOYJ@UH(w}qB&C-`*F+^|kS+&kz{id?j!GtgmDKYA{{|>Ix z^i#S8#{Klm9Q!>Uf^jRoBN{_YFVx5ld|{(Jc-8@9`<~x<%WC)!lW`W;{AYYOn#GKi z{dt9dSxqU(8uu@5ePVG{_@N@)yHK?XFD_y`+0N^H*L!AUgM+L^@6ndBPS;lqkjF80 zdBtftDDYAoY|QGuFuHgjw&FDL`>_=RfZ@g-E=zJO`*#{|CCQ;BUsk~a!_#woyd+ny z{QL^C<>-;WJk3G3@iXI&&g^@GVA?ZR_-0A2XR_d}gl-9rnP~QvB+usSHkh^F04iS1 zz8mrLXDWr}pwEd@{{{Z*He|$h#?!~Ft#lQ@po;Y0w>+yf?jD5b~5sX9}3gWV6 z?Glm@w3z<;E~5V?{X#tEw%dnci_o1B`}S9Zrh-}PA>=Y4S0m)UC(4k06`fWdAqhc; z>A&wm`mg^5|Itxzga}P)ct-4x_~A3R+DmOVet4!-6h=`JvobtTV~u8C?Z?0%8;yC| zvA^3ori05pC8MJJ#*grbxHZEq>otdtJ!}9CL^o5i|wx1afN(gDS1!Lf$M;J zrlKrjGb(li9*VV!Gkzl@w&)BW<|RKig`L6Dz9p=cc=$FJ4{aSh%x}zZ&F?KiP4GLt z0Mb0u@5t4zF>gHsB+-1b)XDVw0LNLhf1WmI;?wU$OL2jvuHZvW3Eukm0GaoMqa{qg z<8PESVgBh0%bN{(09y=C@xRoiQrd&34dZa^CENTgtb)8aB*Cmd0gSiy5dNp%87u`O z7xv?~c~2+=dFxNoZ+#B_$D6NO^xN^nVi+t;Hk2bX?~s`ZmPkEbO6k`UUSEL!8Tb85 z8H{Im3m>^$i}L^=;IGv2`1HFAD{F`=4ly0xL6?B=)?df}_*Xd^RD%Q*0=(%GpP2PW z@xyEgIL$xvk?Wck6IeQL&a4B&UY*}kLO1^$@;&2VFy1vO!!u&%oHA&t&+WG_6eg)< z|7((PEex^gNY-+^cxzV^$k#&u^=ABknOPb9EXB+G8>NM5N}V@rXE+faDL(0UH5w0% zN2#Epr+I5%IownLJ?Xw>@gIL4me}t2WqzM=zr44h4}NCEUOGwD$RT}&+8-4NB`R_F8Y1qn_B~)hp&!>2iuiU`@bMWD?N2dCCIgQ8p$*YYrcp@&C z^Q04K_S#N^t=S;T2h_G29iv4*Hy?WMVCU=+y=rIS)qLdDh4ccc+DeTs^BO^YH|O&( zom`a-%I6>H$K2>4Ao?u4K^E|5~XERKy5??nS&zezi&%Rjy<6l|#Nm-1WGyW}^ zS}F}D>Oafl!DZy3qe2iNWbu8D$e)+F5*3|FppQ%YGcCm{-PZ@d(_nXk`4S2yQfKa; zmJ0X_Fi|;$x|0d!$Q9rop&N3-to;hVjCqOc;NN0Ax6pHh?uzfMTwYj4-e@`t#(m@o zL>A8=8q^MejAp|)dRX=hBA_L!m%zogQE`I=&ag^64vtd!`qEqG%VhYFe&JFaqa|@2 zN?k3yTIQrBn|4$ zpBo@oXI?pcV}Kkfo#qz;IDVmSN!&CRA zjQV)uC|{wMJ9-+I$*5O($N1lRITp7f)+#4QNf&wFa&lwoOTN6E+(;VAPnMG#nCdO1 zNKMsD>|gwZ;j((SOW2;HlmP8sdRQ{mga_?Vf%$mA?ycg1BS=IUv<(lX<4VZO(!W;d z`mFcrn5!9J7HtTEZY=t#_)muk@Y&Qakf(fhdD+X<2f*jLx!Q7gMqk7)-{iHvny})> z#pg1@z6S7Idf0o!&OCqL^4$pCjU(w{J^&WKLX41E{{}zJ+QUF2v$dD-%!r+j{}Ot~ z2t1)hgIlWbfL%TZ=8$&7>v|n3fO-jH^t(7F{GS><* z+7gRFWY(4k5DW7QL2C@tplHm+Va%gIl<0%$!iBf6&VzngwB!E=$)(;7k_$cPr$yU^ zXw2GUmy z2h)H3z{6@)pDQr41!kte%s4Endj07FlPWM%1!gk-AdkE<< zCw^}6eQ=ncswhtj8wvnru766j$m5hidU&K%ha=bjhE)f%)|kyl1j;oUyhG3oHSYe| zXm~qe!|$aw9NfXW`K|E+`aYm9{1IOxLT+gxMfrmt4wTCUG+u-NWW-DtAEvQnvNcd8wU@|NbeZGS0@B4PSx&rFIq|o~cz{ zYQ6F5pX!r-7M%zB_c?fte|40ae)P3x>1j5QH7~X8g%AQ#4`AqefDa6k!$LFwqf|Xk zFrQERvnb>Ct+X@fG`#?gHy<_o`W~=u4w5^|0sF0#@O|{(cQ5_d@3yK5za%gh1m>K; zoUw|8H#jXYCk5t&z#PYarNBnbc}IlTn2$PI@p!zw)atE#dWc+)z2D2XgvhPCuiE<` zR8TiZ7XNJBM#2ReF(6VmfN$#1?f#5xcffX>{*GposU*!OSwu4-~EQ{EmL zw&dbJ`51%8$DqRia62IJX|Kbl&&5skU%v6yv>WP^o-F0JC@uh4ugjz>bTVFRr~Lw3 z=7HG!o^pgCN77)qC+Amb0ffE zXdy^pkzG<6cmTYzmoKg^2UhSRIb#4zKO5tc{$dY5R9y~X7xwUi>gWW%-OY=u%jIf* ziqH-iaK!fKYoXbMckzvvjMqN8PjH1AnKNcLZyqZ5sNWPjz^Hp;gZ(LD*_e@s8(B@S zHL3p~A_5JWC01+^=VZtlr5Ibv%1Ixd6Dr5Vt^LSdxv}mHT(dI4*#VBDIE)N$sW~68pzh4iaL)KQU%CCmWwGu0BCl-Cq zkJS0x$CmYe>aOVOf~?qEmtl8POa?PzzaNZwnJ)7r9G#3yzOU)#_JH+Vm*NjZ4gKhf8=2R64wAfo5W|F zVTdR*O3#cjS9F=UjkwrG*VHJO71xkM%Ju6Tpiv&o1n*e=1Na`^&?-B4qndKFsHsCl zQHaAM4i;jqd-~uW=ejdzenu?R$WKI<2zjW5}lE$^Ng!@>RYq zV*)LdY4%5gKy>-yh7L>~-@f9P!{yX!WvAjeBCaVg(}$bBd4-cU<|D|o?O1_~&TenM zt!&_9BjnSe!wWqiC_y7uC-7uoQ*HTx$}%Cii|u^bH> zPM_d|>c}nFM}zsgI&u?}&tO#H*OEy`3s~5TrNd7BasC#hPY1!h^8+MJ;a%}wfOn(0 z{WWDrSvoi0{#xOZ1=`a95`T?-Fs!)n7pxyIL-gYQ2vzHStdBv|OFWc(1g7Elmn1fl z#GW28g7=J+8+-QvD0Ligzb5cik#Yl8VGutXDF^j`GZ3_kp$;Fja~}T#T>-&&<8*G} zCkwQf@#1EJ6(+1g7^K65M_8r;%X>VO3)H}7#cm*W12@){8yLSEYS5%qj?Na52TycA z>6Ze4>ub;gV323QONKTL|0UE|pUNmLDW3BYHs2k1H>T z*$vh(z!GqH<0dbthxYJ6e_mWqu2A+2$}h$aa5<8bjTdD(uN5WNXAArD0a0?GX`CRq zgIWrLfkaRr*CN?20AP={iA@3&1B!h{b7Hn~8Q5eDb&Qt8?85CII6DM%f@TM32ycsq zUgznRSV`bhRXK|VO{z%e0{cV$Dj870EJq#bZ2a{!_Vwct#a(w0P-(lbeVfKmTTY<-B>PQfoVLT ziTn#D5a*l7(LopA6}Pi^yu!Jm>Y}wujI3kQ8Ef5UatT>F zYc;fx+c7qK7M~XTd?&lOn8?;o;;A3WAFbxGE8Th}%rZ+a4&92i}PTf!|^%0O49RWs^I}jo6Bj{JTzA z$Xh(zx~Q}Kl?Q7)%v!Sth6eh_E+I`EZ({>$^dW0O^k00zK8(I0G){=eY15EnS zn$uqnm!xghhXdr6GMm(g*Bv7FVqf&NE*v7yD;fAK4lT|!jNG9=a;s=@_E=zs*I^zy zMy}&^I$2e7I+^zwBd?d%@poh79_+7nyxUkg*Xwy(75%)ewfZ>uw!}h`xOM^vel}YB zPmrfc6(gEK!C+OvuuVe27rQZDiRXV$ls_}g#irf<`qYc!>bs2s{ryg$zd*Z;A~ulF zJJHz!{iTXN{S(mBRdgJo(T5UxmWp1n1L$5rD|fAQ1&VKFqUlM^B5o&CX%@{#3LBCL zQ|9wu~0HFb7m{a01=IznSA zM9Ocd=pZt1pNdX55&n>hKcM1kkn~k5eh8u0sOZ%yx+k&ERMD*oeM40~S4CGM)BCFE zP(p82xd*D~&cxju=)-ZS8xdFezmw&PCZ!1xV*LwNR#yqHWI&Eam6K0sG1AF0c&O;P zWMsi!;exG%?yFky=X&9S&cuCGMOz5{UbW)5iY`y+jX={e{gi@OA!ZoSVdO(btX1hk zwnNKoRZJqGFRM1DspyYLOn-iUiaeb?Y|WFVqE277E|@Ccmpm`hIMQ(8B2P_~pOrBr z_=?ZEtkmtTjN@3o!xQ+&)8xI<1#8rFxr`*8=dEYR@zOb-IYVw-@iuk}F$i6DPUmD| zSd=K$ivK!8{!BW{M}3S|cRBy`V|j?@SutSkf7bfuW4Q#Yei}7-D7Kw_FSj6-_mYQV zXk3{9834ef(9_mxv*pDSn!W9F@_F& zK9jsg%Cq)NlcQy6q1Bv$bt35#>;C!jR>^bzyJE2=$>V>J0<3ADU{O)Zux?!_e^x@8 zZH@g@epO1E$_=aJuF@24UL~KDCi8Az%Cqn||E1hbn#9AtlK10r`zv`{sq=KO1NSiW zw66GCe#WE)eBoNSrWrrER<2s1nZ3)Wn}abJ-gLPv9{M>~xU>%a(nVfjo!n9?;JwzN zce>5<*U5zyW6(X`TZ^s~hZx;@-;fx7W7kCxk0Wc-QxW>AQ%7OUu}?| zNMrcojd=T=pWG-fl76>#-y{b}(kMP=GZ;VN%Qnl^r3}7jvpmFiK4u8fvxHH#=JC*P z;LA)t;afS7o4%2QK(+cCIo&q{RJCRbs_N;y_P25?CVs z*Ou6mn042v%ixk1P*?O>&j?Qo;nu8YFw0@Y<|=};+@iVF!$IB^9J!xx61FN zS$y&LvPBxgD{Pbdprf8jkD2`JHn}zm=i6;^e+i_$euV!A^2HP9` zyj{SlarwA3jbGd$Uy%Cq^iNBaxBl{zT%`oQd-9uAUL{T7Df{FvrSVqX&+<(VX|(n4 zgYsHQ8fjg8SpHX%hFcdNkzX@dke(yYkcL>_=E##g8uvwK+?o2rEW^e+qLLoKL-~H7 zsC;z@-AP5ySJ4Xyz1X@wU%tSkJ$&kEd91XX-#U$=63@RpBX^c|@xRZ=E$|RNYjsvG zkm7jgIoXQRa`PMtbvGV%UhXUX#M93s^)2}i=jHmq-99hZDCdpA8GYtDvgNyCOJk*R z64Tg1TJp*lP#Bu=?ib|hu`N)r^HFF-gr!m3OkH9cO+_%s+8>HEVDN-UWP!){^W6*_ zF-nn+;bOhm-d*{g3-U`?u_+{p??2sn=gX)K-T3Cqa%-szw_V0C zq_egEukw$Q)RFsKm6u5!t!u7gY{1g1@b%Z_^{in{t~W2)fumOdU0KjuaWyJpj`Bv_VF>UsaiU2uW#3)WcQk z>MC_CQP<(p9eIkBz*Fv^zOUdd@5+JF8s6uw+}!W;van#3r=?_aR%D;neA8VyOj^xP z-j&-*t*rWca)g8oZuzIYMEZ=M{ZmemYVor7 z6*(VqI=2*g9Nt8=6X@AC+Vw9Q6F*C5mAKopCb8+ zB>C{u#qwmyXGIH-Nm9g$?H=W&8Y}WV+DkR9ddUNKRfX~z%wwX2Zxm2#f@F1*!mL`^ zBTDkGp{59*pTk&1|5GSW^zf+enbi<6ANneD_#_XH*5&YqCZikX>bvlh{_?czvv|IT zM`YscvY1Av5p4d&)NK~+7(x7h==$z}sE)30?mBlUvM!)YM-WBDhM=pWu8N8-im~?= zOY9{o7)umzL0va%Nz|h;vBtziQDcm27b|v&y?4#74Q$xu`^~*;d7k(A_K%%A=bUM0 zX3oruhbyUiViyQLSQsmK1aIXEK22_jFD$$!FGNGHVYAnh*?B3HK|EQ<;^BaM zP>vilRi2cSRBW=z6#c{zj^~)%Sv?>5EgDejW^s`S7U-vo(FAw4)Ned&ef#4cgeWZD z#A2_-465S6BCF0oDYC{Zt4Vz@Jl0}ZR=%>-bSvDKuFDcy4wH4;bc9Ja`i-ZF9;~4> zn6`PaD$+P|c(6K=AQit{<=-kNz%LXUf5R`X+>)zXsIe!DOB##}=&~APj$SSeeDfSv z(#=u~?$fErlZ7>L z0YsV!%ql0sk9=eaBOd1f{0Y+`vs@Km$?2yIQH@YV{=$!}Vs9W|I`#Hqdf#bkem+F> za2jQKv8s^Ne|fPo7$?tov6CLD7!YCTF_qR8XNJ(Jf{9jziH1z!*(A>s6c&B2sq?*A zM?E~)K~ERVG}aq{j)^WkfQEP@!U6Q1H>=Yn%f$u#3Vf-|6vsZ6iM-{?GhOIh`CHf5 z{Yjq|!De|lpprA+RV?VpEMJKc+c@Pb3e~bQm4z=?*1N)5^=0vetG=dWolLC&L@5_y znx1FTAT28$ky+F2zC&4wLnR82$|J)$e4)U;>Ole=%TpjGsvG6NILQgV3}}c1+Z_VXLk2M)k`feX}()Pd%~Fk zSyH?Yi26n_gWo8npErWy^G(~5Xh7Mc==TWL0Fx|71j~@Vwht-8zLzviNADxqG;H=^ zST0S!lw~{oda7M8^g|acHiE{KW0BFrMeFG=X2h1TQ}94j_^cHwEbEdk^9>j;rkA#= z2^t;kEXRgOJt#Vg)vGd0<-N(;eUL&4%L@^~4ZsVVNa?99Kla;q-R&5;Ye?bUlrCsS z#aQKKL)Ct|5zhy&~)4*Y&@6 zBoCoc6MRBe^ z_}O_it9%s{LKwNYbOK)S%awNwr0hy8pt=h%O8*X zug)6Fl97@Otbu1T@{bYpZV#GmU}fv|sOgqk9YS#nKK7dBY&a6e^GsI`<_kZ*K|z8- zy%Iu9UekNfBLfTW2k0RLP_*pn##Hn?^w0Kyri5WA3`4hS29H{vnyxQF4^n{U>aaD^De{SDYo(L+UGc1+I~H+e6Ig#N;-)9C*-{&O zP-EuM)V|^6wza8fBX~s}+5^NiUMLYt-4<7fXbl1_w(EdyqoTVB^mD3{$i709ixXK# z&8qeEJdst>%vn!mnqfScOIw<;vKpUTbhR0al-`rnoK?|;-=di2><72;Yy}&lGt$XvtDkFxzq4wOOay|6(q4*^=vE-xMWmZC_n(FYdAxXa3f_roJs$c@Km_x!zx-*)3Ql*qCo? z!KOB7E?TTjwamyE1Pw-kN%yC=Bfz@MRK#~5yDi$gy}{_#YWcgYR@l=Aj$B9N`P)ao8L!)=@ekr;(M4VOru_2Xf z&(g4%{G~nHDwU<)9auRmJu*9>)tYH%2Ns02{P_;dC~YJEj_ibghO00?GlbW-tx^)P z?5$64IhvvIn}^CS$rNw%G8W(_LE0#DAKbDhkbnwcR3P||!B)Zv^b&@Jld^c9E7FvbFS{=!5MRt=dVq11QVB%Gg zdBV2NF#^bBtMcu%snt<=68+GPRq^{4Q3t`m!Z}AR`@?VPpKh$4Z*8`A&^ue`|D`Br!#@84muaq>v%d!xeOz_E&*7srcVj{6;vAFVx^^BKCS} z>=#sY1ra<(MGq38v1uw|AF86qiqJkPIzfc~LCyan6@5aWA0K^Rq!^DA>*N_|z%WqJ zWI2a8HjM@QMrmXiZHP8M4PG>)w8%r2JeT-4Sth+ieGDHhD2`mx~R zBgGh)QrRkR9!cfZH0=0>#~k$)*nOvCkij+6H81KDJa zw23YbW<7g!OaNJPm04AxM@BwN+fdvqJ5gPOu*Zz*iWM{~)u=pG8onJ-Z2=9?eggf6 zioOTsE~41~9io7-+YmMg)B3kV*l0K-hq8>I?F~Wvy^zN?L&{o(_$w=j%aP|WF>AFO zhp}jBNV5hYgAJx2d%s2@%eR1R?Y8$tFj011N0Ua<;eyPyr+iK&J1EGefhu78fBpdN*)vm=q2v)qOUE|qc zLoR;t$rM;=Wm{RNPWQ(_W=%tkN7?1Db>OuO_g8lJ8qTx4p_O zl2-TGFk!gxmaa@>fr0M;cBv>n!v?)0?YGR}jX);zZcOpCcs2NoZ<#R-5Y#?0+D1h9 zUmwPMFZB=Q5CwT)D(2`d$B*K39GOphyq#{U-30K1{L{ zWn!0Y#Ub_32CIz+Q=m*_?bIoxRgUXKH7BviN=PrOFtr#aQH|0Ii=4SL-+WMEtC?yD z9cF5&T)FWZN}t3cB<$KwVj*yLOk!c>UyCBl#*|L$V~401ruLonA~l=w&hK7IqE+Wl zMu%o4DS9%im4qO$h}=^knqu^x0+XaS1JpAaPdA=iB)KUD4H*dO$W)v4yiJJsi5TZ? z2CW*g4vqtdfG4v$`n%(bW9mK}qW!%i=U2RSZbQ233k87RmLT9d&N;Cqz8LN)hN$$JW$BCVuZQ&{6Nzj{G~h_n96g#{+7wK@j) zB+Eg^nB}4^8CfblnS%LGA%&T-T7OQh%}gJFK%JBToe{R^@1?LOD>6)cP7}>+eEf5? z6srmLPB$R_5^yXgcMKj!*6)4>c=SsX)DiCR)V%JXvK6^UdpG#(^=~@bgHf5HYwECw@M;;V z^X(EvK)zcIbTt*-Q$>3%2l|SNzADg072QBZmlWuoDtebdH&oH#D!RTvFHzA;f!1%W zsN&sJd@GT7I%Qi}?HZ3DMmA0r_7ojAtA-B;7AwLbCKAG74^EOI(@VsC$u?sJ1a|~1 zp@12ztLEZx8a)HUJt9C`fAi4K&AdmlCM3u2nd~J@Qw%_)=0ov_neT4BNGDmkX|g7K zX^PJqQ(R1k_2mW01Dr+k5oe!Fmh&Gidd$Xu5TTSBom?*}4_~7rP^GP3AP&o2x1Yodlz1uI)5HMj4zGEYfbLdU*i72rJoj+O1W1jQ{t(?b#B#rJJ| zi&bNitwXs2lWn4pCjB{yr%SGCTm@-ByKQP%Q8SWEJqg& ztCpv;Bv{DxcZzaXMY;RoYjio3`{ol$nZ@QwO~`9DJ0H^+3pdq>F)26aIy#igw5NZP z)k83T1_*Rn&%}Uh)u%Ql-#N@5`umD=SR*)t=deoJ1k6ERNt4f@V2=`L=^R$pBtWk* z{XedTn*l$PUVRruK}QTgROi%hU1l>uV$ly2B<6dPDSnU6>?InQRo^m!ihqxB8hZ)f zvnnDT?46~=qY0HrpmEt}#p1O*tE%J~?^x%6I3L4KJ5Xl`f z{=i~9?kL>6*N{?v0RI}&@*hyM4e9U?td0J*ABy@&OxCRWweTccT`59#YS_SOnart#jGL`V9oD{1ud3@_|TbstIxp1B69i4E||y6iCFx zf7S_<8qyE{Zs4*ZtO1Rhhx{06$vh|qjdW%n8i0}B&%@f{Ce@qIYPYOk6ULY#Z?eZt zKR4x)S?5S$SZ38X2LPG%fdl^PveZX~^%aHxvs?>{Do`)HPdnzbN&z>}HeydY=fW~9 z_K>1mMGelbPw(fmKrCni2tvF*)lr?U#A;$&b|$eJJz8RaXzOiN2%PGzbmq-pqBFOj z^BytXU*~vzN0|nN{0w1oSfyL7(v22$l|h$e{XP)9aUNDnV5+CIkipj}YyqpHzmAN@ zpGygk%~9-~z#{GS>(pxj`vQBy*$bFex@M1G$i_%e5oG_!R%3&=>mn8&a0NAJ#!j)= zkEj_1^9%G+S=XCpEn?lUJ#=powT%^H^F`@)RQzt1qlx)SRjVT_9{#hEm33EPFe`HoAO1uoTZL!dru;V*<5!m1CsNcC2+>5WeKxwW$O*F+=~Hes4nmR$L( zgV^PL0x&vin4(jVhoj;^#EMKW&L@@GC+@+YxdLrA-S~YaD)u`wlmfYwng|(c#g|e7 zuM3p?J4-Ah;up`cJV9;}V-F$aL#QZ>On{=#Z$C#Heuo<2I2HVkDf)3r`-3$KoPka; z89f}s;odH5G7b|*Ub2Wzj1(^8eyY+%AMKR2h0_K2Q&Lt%qlbX1hTsU`w7u?lPq z2MOe%E_1aaaaygy)@Xug@-PTDcpanDt6AGp2&3kGF}{?%hn=PPH7ub=UQ01%^jwf^ z>9`cOt*acnN5j}qUI#i@xURwozBJj|bAkDw#*}r)A`{@aj8#~XnvJdCar?sNT}GFA z7v?3n?o@sTl5P~)7drHIXO-4*~}!Br#9IvvD6WflNP3WhHCg4oqz&lpQhil zp$$Gl53?b0P7zU7Eim#;v32QHT}DO`?A0+$z#S0+g<1p1JQ)~M*0a2yi^S~@J6 zf~}^vm?dJ>9evg*4rrzu_m-uT>sa5wOazWnC(MJJD{ZF+w?1Gxf zcr{oHBI|=1$vI!kb+h8v`L8ddlg+npp!fm4!lWJ5*;)d=rJm~lt4F8(U(>9 zG7-81&_V{nCR?YR4Oi^4ebSAKPSBG-v5q@H-8Qh0z$plRRJkYDP*DxOQpCQLY#XqV zbbwxNV3Cy%pe-rKY2TXSy;A-LD;yaJw@D56byFo*St3~nCH}>ZNc+imBio~?+mz01 zWUH`GF!^s*RYOfE`)|z3_tLSyS^e5bXX{OMDmgbniK0Xku*G|f!WNrAS4R6p&8Mp9 zZWEEhLu#~%*`z)8A9{UYt8wp&>{l=7FYET&8#L@Nf}4MGqq7ych~P3eU-dAf1o0eZHT zb@ACDB;r0@RyOF;jj;!)$2Q34HuT#z);DGxGCiP#lIgki)E1J89C{Cj9_X{}2(e^L zH}(vmI@{5u0-zV_g-qJFBd?ZQ_e*0nOujoElZA%4;!s!G9hIB>H#ZP6+h%-Sic)s6YB0H2u@mZz zQgm@AD+}lSPUvE`QpH^?HgJm&>#2FW0!4B*eg7S(D2se%3ys>vu1K4ybq=dk!w);c zX%IiVP;YLIm3Jkv?;Hd{(Rj0;8|739>T0~9Su7Kjl}I3 znsXX(bgjkMz^HV)QM_%Rk5I1puA zgoD-)1AQwgWlS4@6faWyV@w#HtvrS{xLVK#gw2IyIs@$1*=m67XeGemuMi-LJdUI1 z|3OWUvjvgAqmfuUVyJzS1O-E)*?1NZDYbr5{DIN6(e%3fMemQZ0kMFZaMy@co+Z9M zu2D1KOLZohb9|gnF{r84iWcEpiRPVPF{rKmCor9>NA7u$FLkL~9#kfM=}I13sQc|R zj^D!sQ{nhu73uyz;P`LkeG(jRT7e8F!SRgp!DfA3199B^38Ma+A*yGN!Vv^LEYMsN7y^JQD!#>0x z_P@_TZos7b(s|^5DHXrKHq|jlpdqhTCGe#%g_8@qfs^f9D+0Q|K!XpWX11&7c!91- zuP$IZy@Vn!vQ%lYeZfU`RSNzIB{1K5nQZyFi|9a>EM*tWDi8RHW?yEv%PsPAYu^gX zc=LmC=n;E<^b=EmZ{=JWW;F+~*VStgEx5uQ9t(v`(Z`3-^s6j1O7%sApo3*&35tg} zU3X_<>n>A8hKA6gtJs-<50j+L15CORIXZv&#zN9xW7X3D-dYMRPg%sF4u1XPaNY99`Si7`Kh;s|His>&!nK!BhchsEp6g z#u>40_Hlu`i9X-A*q9!+3DT#28B3l+aNQfoN zofO#-e+%1>W}`(w;Jp{PP0UZ1yS$59cnECqK~(7`3kxf(ffgXAg+P1!kGKpX0=Y^N znpvxM#0%j6 z5u2MEpOfD$W^l#6t_5HRW~X=w&9k~uZ`JmFPW^9TCI6h3-D2~@5Dh}_O8Os^qn}ZS z+n{_#b8dt3nL@e5^gk%4Jf)_0K>3t1?y&hKpDL8Pk)Yh~lRD6<|LF-;y35`{16lE3 zl<2W2(XfdBD$x*tKQEDA3c|}B9@FT5*?dj&F!FM+?w)sil}>ysltwsMv}TVlEp)KD zdMm(qNZMH*^`&Ukt=g;kPD%kTYmhpvh zRX}}G+84?#3u-{EZPU*J7}y1S;OG+f2xA4Swi=M4jt*MofP7l#WO^yzzTe4$HMkJ& z`hB)eDs7+r0P{;J)ZXI}wmI>H;=z1OK0>J|A0jV=LJF|!8)7#Uu=$b{Oh+HH+ES36 zJwcO@?%D@EWtT%ChZB8dGf%03#|lqS??5@o{;!WbQt}*A!);7rq5OU{_4bn!rP214 zesYW~b)z!@awe>-y9LVMN}fYis>ws?S`es)+M|NyL9*1&J~Lb%>kbvMTtQyUdy3ef zsj=^=ApatHc1Jivq5P;jY=~ro)ZM-^TD~Sj`IZ#}`i`H`H?A(vl|0+K(rHiEVv$aJ zdsLh}QpR91ueLmbw-WTFMEn61QAaL-qS`lJE-5A3qvGY(cz4mBYLr{+q$t{-ET>6z z?1`=9T@n^Ga%*@E_N>M>Q0X_RZq)G^cAqhzuk?KG2m0lp@7w2H#gS17tG(5)s+~W48HTU6x1B6| z7WebRv}S;Aq#;;!jgc`l%p(7(NlUSZ&ye?*(bO48cUQ}0H6;g9@ilU9KaIB%psJVZ z8vMNJ+ck2w=C8K)%Gq)UN%M1md&XM%L_o2l$;D~yMNfYkd_WG-EJ#-48Ix>ZeL&tL zV^43yQMrRArWx%!DyPHZKk=B{UK3plR`GIE%`F36KPK0cv=n+=Hfk0%q3*}!TCi*W z{_xxWS-nYvoelK|07$a8uZ6M@|R`eUkeSDvLChkrp8(Jzx++=QstBKml}}U zPReD`!2dicM@SlL4g0B6@>d$^9mSuO8$gvd?yS5?dP_0q2`-;M3UyGDIvpalSnDMy?$68j}HV!W2ObFUn@= z745w!@5erq<&r#BdNKd9+*wntGT@ zd=`1L;^^D1@P$v?ZUxo6Dp!Uu|MIF_5su}m+`KkOtonvZXhR#tF$TeLq=X5D*;sr+ zbsdSx#nWeiu61H6lq=tQM()?-vS|Rt7NQq|s*!Hq0pueGAdK@)I4{nd7AOb)T@#H- z4u>DK1^08U+NnU}ZF^7izqsn?9U8r`{fZA!b_Lsud*^cH-XIZ!uVZFioMp4>JBx@d zdlkjeDZq7`+%gk#bXiOBjeFpp1|u+b#zIV%vtnz+($V3_s`47@myQmhYZ3;L$arbQ zB7Qze$?%L7%G*w446$;Mr`N-(`X?oNgGEG-^Zdb8sOELql!g$W zqFLhdIf5NxqG${TvEw~%4{)9Q_fi7O^+htxMKb!|@rnI}J{T9?26?${QJ)ht#sM6g zgZdUzHmGp)NdUm{gCjObkmdIHEGnvi8D*{G#%A>#&IVxXI~1q^6v)p|XlDmUfuhL1(GCq=X-=^s-+y%PY7{8WIWh5wBB z0>+{}hp$95s?KO9iv$!GCOoDYH|0ni)5yLlhhpeId{gccDscS{xiXu8tr}fc5thw5 zyWZ_FHMk}BDp7!}_S24rlPixapg(TO!F~d!WWP1Okijnt= zjdik6fY!v>J;d-lUnHfy2Pap4hJW z#o;OHw}B@rNNJ=#ZN)@`)rvkv&@ z<-`^x#h(>#B$vr`m|+5Dm9w05;~u1rlf3TB3pLrl)5`mD4aq?l?#typ5DJYUz(MX0 zr#qP6{$V%n#qdJ9wrcuN0-p?vM!}MA*Uh* z;EDj?`Umuq693ZW2XYg{6Y&tj|6fXYD2GP;=<6nqV4X)?^<#9I)6ovFtUFRp?dEMu z)1-%TkWNJ9C!&HGH@+#Msz*uM{17AKb#FTJ5YqdCH@$f%CznX`MxW2a?lxBB@jI#G zBRN9T*_*z3Bu7bi>E}msVC6d>WQMH2E6STy2aOC;x(Eo9HF0_dUULMN6NM}g3FTjWrH9J^rNryj$%YTFAM)EzSYfhOV>O@1twjTNNdfHc`^6NYig)~thS zBo}WA8D-wF5neoRTMQiuQU7$4PCk~)r2%QOTu8PkflwK10Z6teVI8k~;#Q7&@(O@( z1_hf-z)w{JU7u;7VfHy)97 z{tZRFy0vE5?5;MBq@dS0{+<&0;XSSKu#ggC!|p%<*Jb(kQIz|JQsFB6$3Uw2RL;W& zp!`f;27BJ$p2_vRuR$olQ~;Y)o3GKMXL1-2-p?_4x<;nw@?h)_Zg?&?3b-mtt=J}MOy>H>-BQo$HjNW0 zO}|JbUPEe3qiV0^(!CG|hV3BKAo5m8^{HEZaz{iWHoFW}@L|zDxqu`@h0PE>pdUvw zej`8@`K@s9x(b}8mZ)aJhslgZu6cp}cr7=?QQ3R1<>(Ru4r6mfY0(eAKxN*@6%kZ~~=SlZgt`!*X>9+MdQFN$<-+RI_PKV>j zqn>YNLtUTOuz7u9vUQOh;rPb2w>h9_28v|cIH`rLW<5u9SYKg!a!yQ7beY{%E?ziC zN8ie!X*v-eXMYRDA-c{b#N?{gdQ-ni+mrg8PPXd*Mks9N&x8YcX@!G!hGJ_|@Yzbl zH%IZmG*y<{0+eJqC-xpKiR)1%g8&fr20gKX7uF9RlV#G<R$1qcIqOP4$Qa%ct_#qQpK7IarmO|gl6|m#n^u6376bR7<(duqb z5v{He&xVT9TD9J1>5upFH%W-BF#V2zA05Y}M90Lqm$>y5&y`V5`lRRymF#ypu<@D)V3KnqUnC2RvEWXv=2R(%9ir12UX^N6vS zLe(kioN9QqzrC` z)I5r1{EIXt7z!pM8PrJ$;aAIc|63)h%W#|lN}wmd&HoM@6|5X2~MJFc7 z_Gp>6*J#!}rOEC*)LVXygZ~G_oiBkh{p!xY!{NOe9{dZ<{3mv^2M?4q8PDlwPu^A2 z;4!`QS@GQ7x;Xcf zG#&G)pEs|dsgsXmpZr_th}~1mJ4k62A&mS}ZG4Za=;p3;zBkd2={xO7gdXksu$a zl6&GCLbuAlNNqUfl;R6D3+_^PJs*Sx`93{=24{;ukB1`lsXuQM82%~f2z(>xoZASB zn^FUKX(^m01n`Ei2j3dN12xhvIu*oou-!a2n2*GcF$>{;iAx+dhw|2NJi>SbIL*Tl zJ@h?c9Qwq*^sqFq3MV9-N5H8c&a1;29?nz4`#@mecYlpC_s^9V0{}7Lc0bD@uC}DM zoR=bf1n-1>*kKWT9h}fIyt8qO6>Y#aDbJC2?-gc5n?)ok^}(z34+y)85Rr+iHx11{ zAQs=F^=0@1P2L4+5y{88kGg=u1~@4^IAENy3uk zb_F!M*3_pWAE;T0H`^=nL>RC6MDuVs)rE75+Ni#-qxqm3*KQShzE8>y2Rbc33j$R9#oIsBp#!FF+5rmbBt!j@FI=7C(WwPf7WnMsus(K zY3dxIpJI7wZQv14xBgA75s2&kVakn#a9Bm5alE>p?CIuA{xGQ6^cQ4L>J`U>0=TGh z$H*>dtBYL=R|PpUj)!UJFlEQ_G9jH0BlIB*2!-<9-^6H?*W3hYBpq+^8!FPD~wRE>uFPi*TsIM zwFch+Q}YHjxqtcduZj}PX%&&?TBY6IbIq#UfG|a$$L>U--27LXP?Jx^j72i=U!m__ zW#HvCJ98<|!23yUsb(!mm|y7IS{w&eJn3yM9_RZSw`RoW=`xEeS<>gfvNx;^IUyBM zuR8o!`Mrmmvp>bg^2XFMo>z$aa<9r+=VQ?0u%vQd7&2{g!NKurdx_$~@ul=2o>%vM zhZsKNxaWJST9*g=BVrVNNt@3Z4xBBHm)7L&QTQD>ZO=!3`!D^R-@Ac8=xS}K0F~D~ z65h|)F1-KA_Wetg&@Q&OQ$t^A{U2;UyxSg8kHd^GkA~KVi2RXO*9ZH5rd~#{|M>rh z{nvr`!2Sw9(~m~5{}`2N0QNUg*}r%v6*K_*P1KVoc3DLXR5pXxxJon7}K>^x6(K;5OmAyPzY)nVT)* z%!0O)uz6S`W?wc#7f_&~b%*2FNh1?@71*Ht1jow@AQ7eaVLF+>6Z{WsQ~k?u2v5kz zP=wyLjiMX#ib$><9QQ6Dar8Vy8IAe)!1G%LeUW1;&d!OOFEP}$!}B9e$*&1-+kC7G z+x87O?gDkTvQN1zqP`Bu34hQ7XeAK z?wl^{PlS57D5akXwnHf$9XWy)2Px)}oXEe4fzSCZI(YZk9C2f2LNB~dVbj)yHOJQJ zDtkjWE9^~s>fz>?LaP(`6j(}CYsTwIb7)92jEnneQ8S(d-<@VW7QTSyynY}q)=iF& zDn2{T4f3y*WkAFj_hd`dn^`opIj`=s7rC=E^AREg3zffS)9U8DD-@iviPy&^GmTAr zVKHCkMORH2a~e>&B)-ExADszz#;VO==X#|XOv|SiNxT}=SLIt^uC(?qYTbhCH4E%C zpat(-s>PvFNtO$^wJh247!tzoPf>3N z9MBJg$wqHMYHsM35}PZt+ti>Hua$huTT!Fl-?2-We>=x2!c`mm;PcXz%2rC3UEtxi z^_4nH)vZ@*p$8mC>Lpy&;)5#8e znsmqBts`Vz`4|kCx~vjnI&IUscSikgWJ>pm{!NLw!yVM`ELz+N6!q$y4H(db-%h8#q!FgeZ6`AG8a8u zi%>J}xOa1gf|nRxHvxSAUwp`yDCtWcB3-7hzU1w2lh)=hd7SPW4D{A4p{oMP$};ro zOP&>Uyd{dcRJFmX{*zM7sy`#8`9yvAm$=XCWgoOR%oh#)F!jFlBThl`@j(ld5UQQ3 z`rNiq2~~I=%qc_O{dptzK|dmfH@{K){`@)yu9{!*Z#7dF(1x%08VpLk2k;RdD@8#K z86k9L0B?+4)xd!~6!x=*fqXDVyd?v9h~}^Pw0$72kaiMGyMWOX`yL6_9p%6q{mI_f1VOSWyIr1JDl@Yq}Uw+oQ;(cUHhUbXeX+PMW~7GJB9d`fE0N-FVJID zw4|aZ33NKpA2TpUWMJ)Y$iQ-(i}?udA;1K1Zq`dwl|StE2Jy;%L0Eg6#U$D_RZI_} z(u4UtX*q2i%$wClNw-eM?g|S3_YX?mbLS%OA-k0PloRMQ6+K@?ZxHCW6g!01#w~V( zhhQ{WjsvCKEM264p}ben1ki~=2t7l+8G1JA}a^72BN3p zRP$m*vg@+C!7H*jQ~=C5I6|4#2B1Q@=P+g1Pe9$NSI{BS$tP&s2n^DLsb~c6r8zj0 zdXMBaVW~HFBp>BFLE{2YqPYD83T%bI533 zC2%KRHcqx>4MO%E7Y`K`b?t3AP$-uiL~BQLn?^g0jAOX5(qU!pG%Ua+0bCm#Fd-SJ zWPcr+yORB*bLf{bsGk1x&lq0by?>lrartFQdOwC&!oGZT3Pk%J3k^@!Dxp|AAcUlyJ)Is(Tj0dMQx_2@qDc2`%L{8AniJ(y*qrQd$~s9@tG`)R*X1$(DZATMfM} z7Du}^zH~JWed{|)N#_GWdpVtlNml#obnYu@+$NEB3japm1>zKsNvD{^H05t`KF$#} zgBDIfku7v&3jem6MaVeYOJFd-LtlAN%o{3hLtm_<%7$lnGz=MEJrR9zvpvr3ha@cwFRR}8jKb_S?3kWwPVF*QVj8X`f2xJ+%o=l-PyX=+Jm7(3ug z)brkCSvmYe0(WN)cznt zj<4j?pYwP`sDP_W0d*GoVMo)dwItBPdAwe6L1DqEU%6jC)tJvCeE=vh%RUK$>(;Q? zeEMoWSo?@h&*x=JG>LQbNNs|1qXp)wgBp=cyaLV+RwW*!X+4Nc#2c5r=i`Px=Y0y# zqFd#vk7ChJ4z!9-EYM9khDlelHOli5WfNb4mwVbSzzF`3Ml9e)>^HAjz{_aT!s)~U z9tH371-w#_RuBH|Q73EN1}GdK4@cZrvk)WB{aBoQiA7(;7I3n4_H6WEF*RCJn$|5u zOB+pLKO%+uR986vQs*CeRS$$gCMw;h?|$UX)4G;K0zaq;{Muhh;P@}7poE!9Q?4t} zOI7qV72R+p(2*)SM4%U|=s_ylAwm~Z(Qo~L{#ivQsp#JY`Zlin5W4B7I%>BFQ@?xk z%_45_y@LlS9~@USj_aZ6_q<0t7D4anq_c~7n_#CX>(^p9hdwviy5K`$ON3IRpP*hF zNo#)ML8U>KWZo|&nfIXyzZ+ApRs2nzxsuWvjoWV1t)F=Fx*A{P%f;2!eU(CwfaADl zefv=*DdZb;?75DwoQ0bbYm&6 zp|2&jnuWCxTGwTGuupQP7DX?^%x5U|SjIy=RN#nOl)enhfg!Yg8O8_$U0lY4!wg~z zbMZU%2*ih8DvoH|jM)bAUCt|f2@=J;8nWh%3_Rr%c-jZBi)ATIaRW3~z~%cVW<$)4$vC*Nuun?ZIj51g72Z&_UFZ_g5)1I)Bzml+&s`neBw%CXMCRPU5Xw@o= zThr;Q{eYWi_83{((u>JW5%Ofi%m0c{Ru7z;o%}HBdAEK%KMs z6YPn$Sc?jsLg{NEGUD3OinTl@{B0Xl(VZ)p7&obIeyK^RI(D_m+P;f*%$H!|oLTgE zEfkL5Q`kBl9`wDK2brv6x;VxnfU_5hCI*tRZK&fqNS_RvxDHJv!+vBPUn*6J7Gr+a zYBZK)t1+~^*kOb{M@w|?&FC3e-KUPRgHPaY)sR8)e9Yg~ll;C)xI@a=>< z@B;qgdpyd5@it@eWV-Pe)`4ZI@GmU6%2LuszSe+vpsCxUOgzP?m1R;CR#$Q0)42lB zj~3ISZMIO_=07c{%HOhG7K6@Q}!%FwC5dC#(C zRHGxT(>u97ojWk_CtHk-;fK?t47K0H4Q)RW7DlLH9Dnu$q1E^Ve!+#Tv+CB-))&}3 za9x@7HBQta=P7U;eMdv2xULd0?ueiZn|Nqtgcaj^8${I;nfMNV@e_8+Vs{AFccy|x zFo+smmLlwY7}Q8MJCE{00nOLnS>&^k_U(3FLV{xF$Yvhm)2BHSv`%qTdaV9a9qIx%kQ08`S2+YDvPFZi- z48P;lB$_}xK#m^t&vst5aWEMstGEgUVq_AtUH3u^C#ckkUg1X-2H!o_4+*6w;zIa zMX&&Wnzb9LnQ1$MMK}46)E+kYEVXxdS3wj_%w0jV03f0}iEBgFrD02fEy@wn9 zrg+2tw9$Sa2=|m~P*n76M7t446VQP2_wYc2jM#CPPXGobug;Rt5FUcK$v2`>F(WuP zRkSR*x*jdXW^^i0Iap8i_ww-S$KbWd-9^w%onW9T?%)!}vL3NH>2-y@9)kR>(C7rs z_ta=F4~nxI%fn}pz40&fs-@B!Vl-8rDa@7K0aU7Hs9|8KIOYAQL8a*IUOp^#uMfmk z)f70Hhf=sD?8y$yq4pcW4zsc9RE$(O?=rR|M?SwgkAzq6w2#>b1$!Gr<6H%4>KbV= zw;AuN8jfVmz*-eTNuTynnW_2onLqg>^zx_ALzC@;4~VUgRGOa4!_y|9BN&yoWH?wy z=?KT+I7Z-Zdx)3c?m$$!G(mZ_6m&`o`bldQJzb!usG9yr?dEJK zda_O1O;Ee^MrM_|sN@)sYe4Q2yf*pHR*FB!>uHA7r?Ch5Q_YEbH1rT3=&u9M_uwTx z^Wg}*`BoKYMJ)0?9XSqh;|JV3^I^?L9Oqwa7cp?Hwe+*YLr)v6)hj@+NWcS@uMU zM+Gwui)ZFOCRzk~XEP`d%u)Xqk8```tc&lAsPo0?-ccSB3{VkFb)7mu(H3ITOz7j;_t@$`?>jlJS%&Iul? z@ra{+C!peo`|t!08tNf<`J%{KLXD|I>-LRxS-&fJT!+Fa_47ulANHw!<^kip41F@V zUk7))2v$XP5mBKYoO^-Di0bpfyHWABLxQ97kO9v)`XvvW0q$}1Dvx&;8R_&78YjiI_R=`AOq&8 zi2z=6{-Ht>Ayt&-5vfGA3s)=xF(6|C>m7%pigHJ}^Eg_H)Y4?6233r+CrAqA+wh{= z+rX2deU0E^;Bh9vYucR9sf!^tu1zyjd^0I^U`Esl5wxi2jWbeEPnJXlrq<5DjrM>; z?l`>wM<#3NvUb9o5jEul;xX){foO@gLA6ftQW`mql27rlU^T`x=V}lj#`f(K<5Eo- zQ5AtVpWjGF26yFpP4TV$Qb7__N&xi(zQ1bUG{0-JP8Em>rc%G zJ*LZe|L=c9_ss_iHeDY2|BJ3IqBEZ15x%oJyj8DA5r^cbhefQR5odUnh;`6+ShZ|@ zEJig9m#f$KxV5k)OPJOi#M{Ry?`Z28URD1t7O%lsHL%2cx6rJpOqz2rPwH8j+MVOs!5Z|BNe@hx)B=;G<4eSK6cEh4&%C9e^ALeGsnvOY zIiQBJK^vH4O)2MLvQG36+D2!I8umsP_-R>sW7l8foh7LX4ZqIY<4uL#*D>{cP5cHn z2rHB22A^KzWvrNar(8&~hL%gR))qUO6)TBYVX!`ZGTLM-Yg%GIdlbLZYe0E!Y%Pw2!#Oy)?L~ zWc(f865CVz@9;+wj=*jFmlyb!6WX{PV#=9p`%-dvmZQHNyhh2g0{pi!6Scs^FW1pN z(*DN5OKO4_W7mJ{6?K&RIY1c%m%(xH22}Ar|JoN?D5X8Qti@or_4|F^CwMtF;6DUg z=C1@>3CH1Oq;d~<8q`$3Jb=RZ5uJR130FA1e}FBuht%&O)WZ+S_E6C`{h|6!Kg2fZ z0}6h`TWTM~io3WbZ^s3g)Y0H#9sXnz5(6Lb%48ujgM z%000DSX0m*5ti*?*PV9%$Jl~{j-=aDelYT`XgGzstU|FWwN|~P_#f&rTPUm4e8+@9 zYWj@#3JrLLRpv%fV9&YOFt zbVhD-AyAF~%JuzXqO!1DKrQBD`4G zsO*E9*Ra16MHfP6a+`V-^3EFPJNmnjM{3TzqYH)n3)4zF*fT_E!EA=#iYx5NhU0h` zE9O@6fZYJ$>K~^hny^hfR*tSQ5qP9Liw3gnVaI}_P3yFvour7(hQyhg6kcHsjW{(y842*2)G&RW=TD& zXbYaAttVS6;6RW4CN+Es9YIOz`jXezBMCIDy{)XN9!b`3JVdYjr6m3Fl85-JsM{aF z<4V%mmzY}JpqN*X3SUslEB=MY7vhb(z4xpC(0h=-{rW3jO@n!v?k!J+$$r*b-Y-}u zI$`T6l(T6%<4+e%6EJ`c7ns-^9h>x zx3uUzI+1pM5!XvecK;%50ZFF66WnV{`U|4roy0kBYaA>(Aop-Xk{8(|_x8}y+>qQ$ z!g(&a&xOtS42^rA7*D~@i?Bb!=9aLau*zu-g|5FCz9uSPO}L{6CJ0Mj$~7%Y|&nR^**84rXnluKUF zlZh*>TiJ#&G(>Evd58{eXnK}5F!%D3J6&MzRpGeH?$hy()NI*3(Blk>1^cfJv|e_v zo|cRSskm^%(T}SFG*oRcO#v6eH`xUqrGlHgzy=q%j|y(=0+)7yad=I%;Z`oNy9=D4 zf}6R(1@fyjMQGPl;jLZp3$mJ(3M$y-0`GBwgH>=l7kIS`EUq{}nxa4=<8xhL*P6Y( z3p~jM7A+Rkbw9udxZrmcxb_7s9JVH^G%ZC?n=!K<79Qb|Z z;<1v)(uuO$UHy7eiE4lp7?fm7i)0`=ry%Kc^MYBzy*WwUX3@Vt~# z3Y|c^3RzY~SBK;Hx1@qDxB;{)hfGEL3N&s8*1O|=&FA)!{_Z{+Y%-+>x+e!!zY20! zW;5?AiJgfCxry!sx^Kq$%f&(Nqk|t@{uF7WdkR%6I1W6IQYqN|=Pm|;cV*e)RPe7W z0N)B0Es&o60`1E35EcCm97i=3{o)ePE}pkk(Zd8LqWdNHpndy4#eN=UA81;yg!RWy_Bqwv1B(UyAf`R8=zq&o@GnaMKa}>= zaG#ZSAEVxf>=&I-(B7bO?0xn|6h0K2#anBug>RsSwusQbsOWbSfL0Eq*bLz+`mjJ} zspy#^au;WptC6pR;}`(+?tAVTuifl|N<X&0l}B^92^_15hpt7TZ7({V!yi5&^gY(F zzU1$|5!!TLYvWxU3q{;7;8<7bW9v&z9mFC#_49F3O?!`rE5T@MQ?+%2u?rll{Z+kO zg7n4S{mfD@*j`kb%?87;=ZNTmUay(dQgGke0k|z2B{muOgJ-};=^L6$!9wp+zxxP8s-tCa@svI;n~IND3=g|zK+ zfZH+~vckYe-G%sP$Bj2y&y!IP#l$qPiT}vo zFvq}m!?C7d>k4lt0Xq&~8^lu%7rThyNgNI%*w!FUarpQJz?C`dM6j(UZRGG+f=h7t zSzUA5-$gT><57ga+hs&PCL6(RCF{cBQgE!7INXh3+sk>wjHLJe1EF&Xw(K5GbCt|I z2TWWx#AZrD!E)Y9{#X~mY_HtA92Yx>!ew%?9SFC*kk4Ff9Kk*Gqy1nT&HZ*Ja9fG% z*zrU|ya>noqrPbnM(7^HGJxAkyzw*xU+_D^J8jc_FhLX2&ZqyAfQC~IhW)>RVeJ+p z*V_oT)t5jHpCx!Qhc6Ips}O6Z7@@bru@2zyaDu;9Ck{ta=tRKQE1OYcYvef2Bqm$Q zC3B`rC&3iLWuy{pEB81Kx1uN4kmLE^GQT=f}?XBuR!DK>q|JvaW@KHkq6&Ju`S7f!CPY{`P`zY8}iU$24VIEmAEv_+ma?3u}8-C`_Zt2$OFLZ_3n3QY0qL z(UYX&C7RGO#D&=GS+sR(RjNSgCfjtj3Hxr6SG;W$s0I^%Rr z%48{1JeI=VPnK?q)*B{s2?$(zdWmo_IsQAT1bly&h;(q4#jCezQJsdt+GNb#bN+CMPnWA@iFlb*r$1 z_)z#=4`RV0yPlh&cR!P4Sbi)5zHAZ@Lm+=1JCJRiDWwSwSmZ3JDsE8zewI{Ms1FS@ zsagfm0|^+!6Y%+aBLT$+AbjwQe-B`cWjv_nTB3sMGq2f_w_AOhV@H0XPb-$0v&z`p zkt)FR7}jjIR2zmBr_Gjv9bY-wHL--iu;Ekdn^bmWHu9ay-prPQ0!Q_wJS3nV-M9Ls zzN6L81js9n6p&Y8cp>Ah`?7{iswuknWm!xLGCx6czzU2snCVRN4|vJN*K^udsa9NO zz7Q*1x2_#RRrbkYyC_<^vMwAldk$j#m4(fb+@P}7aE??CS5yv}BgL5SqIE#p=YcG5 zjuc*G@P7jSJeYl%BMrsv14HLZf%VtIkTk|%&z$TUW!AiDhgX?n3WjInZ0GxpEDksE z4pPJ~r=YflH()x|TefR#sd*n4bfgrqo(V&(%Q5Zj&2GLT$ji1AH@0%Mb?^SkDDgB6PpEEs*@g zLp|7~1=2_;a<}?Ps*lyx1wTo?!Ya1=C#e+9%-#G+njmf|&iXEtJfN$UwGb2i@7dOc zQcpa2{w#ICg6Hs`QJ6K@(x0XB-Vgtinqz@RYP!QW)AVai_WWmQme5ZhzerjwrY(mF zqZA)#Pj~tFE1Ki}o9->_3}fi9YKb~q-s(YnGMQ0-8H`?FJVFg1e}A6R!Y<;=SFTss z%>Y-W72k-f;{|av@cYVmoHJ(H;_aB9cah6WF9}W*_1~PoaL(1=rZCS3j2L77&G-Xn zT>LHLO;6^yR4P&9TYoze0B!ug1(f9izAXDD@pdIy=l@GU9V#R9zXY5&%w$9@`&K{~ zAGQ$!(!TXi_k;kl9rd+T$kq;uukp8xc^+V-UGlGt?TFD5Rq-C)aE|xL4rsX5Zlq|| zjMBzC_9TCp&pBGK@07hAR~5?NpLU9hIQt#ibmO~DBuhaL=rqN{WoHZ zpok6F_$?4<1Jb_*s@j0?Z-F{CVD>ja?C@9{@_Gs7;$I0)v;i^S1R37O2JHNI2$r*4 zY9DkPWt^XHlquHD>B&;JYHZE~W9iRQH!;@Iybe@{Uf*U#S4hQWV#s!Ra9a;qfyOL) z)Mbe)rFWw97}jW&iviN;>mbG3A z^xu|*Pl-ndbmr8p9YC$3_kv2X96)ULsHxVqP%m09T`5uypGllFm`^MgQ>k)n*9K{B zi!Ut@et$9)^|0=ZF4ml06?!F(G~L5J;K30%4V{et)P`fT>rXW0<4pyiVE1bDPIR}|0-4`td~E_*)6J5bCr6y7bVl;xEDehkY^Egz ze7I}2Wf_~LYPG^U@?6v z%ieF6N(YohvV*W?iPm)UUFJR7m)T8z!gFM5C#dl*yUViZEmBk5MLBJYRH+91ti>lm zT$V9Si7HDT`^jS}Jn~H+%J2jsqtGV7L%|uW=p!MY%go*?t#J*Au~-2!1isG+_3?~gj7Kcq6GT&1y)?#mQ zY>!B)#kx6-ori84%88i)P+!DYG>MJeCixfr*xYOvyTWN_FIqK|-%=v>^-< z${_$g!TEM!{RhC*LK17HOI;jGBlY<_dy7i5J-Rf{<##8$!y;KDbhRBxx^L~;lJ(y% zxhn_a`N(BY3pRDTbR6o29d<}j&ZS6yJ}a5haS=EAp(Hl?v9&uScd@}6c4UWCPuy3B zIp#`Foqhk|OkHJgHt}Uec1jsIzCB~7RJLd{8hP(_gDAr+&&x!1e5W*|NK^9OO5QYZ zI@N?V*(Ld@KG>SeZYWz!{=RI)E~!cpc+jEUl$XZq=;*`t?UJs+kipNpr7qsycsY0* zwV+BSzQ934R5EPo{3xRWP-Fs9p7}_IQdGpzzEm_bi906| zr+F^If`9fCQpJPjAF2*o>A~{gsP4`D_ez^E1i!FX>geZ%m~fRja`x0ZGMlSYSoMA)Tx{M||1#G_MIUwcyY4Y+~_i|I7||4~Ll zvRw{&=#TeF=Y^tfXy#TSzn)BOHQRK9P_@X3>QjQ%KO|Yjgv~7cuyja7J$rLl@)3J(qURDU zEMM9p7Ano|*6OH^jR!795v=BPAL3ca>1ij}qN{i%IJ$QAs#I00<@0ygBRvafrzO58(%R-pF)ktj;(QoN&K3)yc4>?`E2k0A|Ua|o6Sx$QpPd=yL zbq2kY(;v%#UJn}9$5z5gA8v+P)cs2!(EQi7UrdKU52<@6AeQ<>Al$Um6V-xFPu z)BQyCx6XT|_$nXG`cvFf=vpW56iJkTb-vrKgi|CP@ zu0wJMa#|<<9-N-l5p)|)&n5qOPERGe4yUJd1zm~LY2+Vh&}os*74YE2fp!EG;q-Sz zJ8-%M(eLgUudpf6k2qbO=$o9bO!PTUyAgea(t!;$2_E9 z4yP{>Fp1L_h)(8-=obOH1E;g7=_GQx(-P1zoNi8ZA`e>`dlUsRoL)q7s&e{manK>0 zE*3ycG7mhGm_BmgEHORf^oPT&@-3`ebSlhJZlP@sFU;26Lfc$WnA&D@ax2`HhNTTF z{J*dAs2}9CzipJEQ+k0^5Q<%jppE&*yY$ zqIYt-6eVaqr!BKUFX6OEJdD#f+km!k`VMu|X`H@7^bk&8rYhAtgg?|HLG3x6OH55U zJ%Y`4!-9*;xpr(r0R}>)n9l>Li~OQIM#E7}U$F5HFcI@(7amA2TRbOE)2nB2vU7ZC zGFEM$Q|5XMFd+uB1{q$~lfHa1gV89KyNi%lF1#>_AsVW%=O{dmy~A4I>1WLQk>urO zNZd_$e6@>C84EE$g}z|cGuG^p6b8#1>5s6|SCTD$B$boFi-GT7PuaOg(g@tX+w`$i zL48^t6YhODlhYh__8v=~<=}w?xl!!xu0tb(X7j6!wO>;)!Yl@cqa3fGy7^ez@AafS zM%6VbE16NAcz{-_C!TP`uH+N8;R%L@k6Hc`sgL@&JZw_Zw0GxYR^zGU7XXi`3EB6t z`a86ZN+l6@`e{P;r?`E09TJ4sah6m&YmOHi^Az*!$87ym$)n6^7bj&6^D8NP(c}S1hQ}DWiht{hXTtp@;QM>Wjv0%zYHfBm8SmA#rMS8-p3g)RX z+1AXP4%zh=IgKqrb5bbvg?q6n&!kd5!~nCX;7Abe!ERUPO#v$pDUPw0QEt{Jp6t{! z$=lfzFAXzG_yxuZR}+Mf*4>^=crG=;BqZ@UW6O$#>{OI>c!h--S62A7Of1_*O=h8160r)p2jZ6VY|*iRvJhhSJvsZv>)3(es84Vm}<^@ zBmFEi)2qLg4hxua2=Ar(PU5{4ELN7+2qJqW%TaJDnB{{-%RDmMIqj)btJ)u_P0&JG zKVp(1$BS`~Sdt=FGS7h87@Eb2hitkc4-eafN2fi`t~oV}WPYjYG>*S1mmlHXz-fZ9s>Uc3Pvm^~#bqC|roUxPoaNcVOZ~31+}$DVAnG%I zhEdoc)8PZC>p`a9xpNT?G@sLn!M1A>or`lLR1_nB!m-sa+i@d=os$WbauRq8?#BwS zw2}_L|KX4ShQ9;x4~vI(;J*Uk62rTs-UxY72iTwPa(k~_YLNk};ozpvls?hvqp$+m zjV8&xUa&SEauAG4Wq8QJxQTA9hny(vXP-UfZpwaY}ct`gyFWmt3++ z9<^l=%V;=e^%4)T&zmwjj_xtGn6BU%{lrx`O)T1}XR(=@KaS>(H|6HBrCxI9G5~0T zkHv|k4Hm~Cc(k|-!vE;)U+_ZUq+GM)p0E60H}J7P7lO#sk)H4Oup&NksJQ1ItL-Cudi;ww0Vn&DCeWp! zNSnBarTEC@p+vvTN3PXuH~O5d)=yuIwFPvMu})3)TU;2tb6SdD-d^-O1+C-wZcbP} z7!A+CUY7b>vP}a(TIz4lHgyB>aKTp#68WZfyICb)xm-thLw{BnS`p@F$ac2N$6fHL z;bHba$jmKAxkG<~b01b-^& zyVgN$m#-Y;hJdM^knuE|`0aVHn_4+)rpawU%C;%RX|@K25PT#FStxy={R9 z{V1*u+gRPQa%nf>F{~w-`h$G9i{4vKl;1Wssw_%k8=F;D4ryTs%1f#6HA+iW>%~RJ zSJO-o*0a&OhQqTXh6gXuo;Qcd2V{dr$R^2&JekTYYb;n@2kQut= z&K2b)*v{NuQEnv`KByO|BzF>oRr-KP*;~X3#GESfb$4MnYVRw2gz-w3Kz9TwZKXkn z0qST~<)ec5bT?~SU9KzqrcbXf#|Xmj`h^q1UEB1OrgBSr7y&xkT<+lbq7Y18;Ffzt`06>U z&_W&s>v0=e$d!XE$S4-FX;qwF`zm^^nNdyQjh9?d%6RHSPwd%H*+&m+DVqh+w1ibl zlB)_k^ub9oF7@7`-)kkO3c@D6LmT;^;Oe!|Y?p7G5kyPHTB9%GJ+g&WZYTG3UGNiO ziHPtYEOraq)=q9yEDRWN&vDwO6~YJd`bOs4Uf%E2ZUH{OUp*Z+>CfBCeMHw=bImY% zkS|2<{997w(yC96VjRx-J#+{X3lbSj}b|0$sftJu(< zD7_8_7V{rWUd7(@l*3B60i*IboYfMzFNw~HIYO4?aRmQorPVCrP`HIj7L+kR#n)(3S#v$1 zEjv}#+)nt+$_1J?3T^ajf#!h%J~B;$&9#MAY;v&q6D*!gDrctaHjb1tw-=Ih{}6MI z03(u{Le0bNVbQ8wgxLc+Pz@r?(S;in#y4P~44tQ($Ud*xtO%sPDcc)io(20>NfpdJ zg^T*m3g!#}hiYn7GWW$D!igTRZa zagol!N7aU7t^eZv7wf6#AC2iL<|_r>SM|RtoBd3}1Kq2pc@kNwUKM2?Cs_6Jwai{3 zOz9-lF<(TI%S4-(2*MrxSY5N9Al%j;)idui3H$VQaY!c$^kO4qTiC0+#hd$zV#UI2 zT7ZKqo7cqL3v2p9Q#16O4(M8<8CMA67P4k|SK)fa=4R{wpJd4`%nOAROloN!3uCjB zTAICFGsE$zD1om9_L6WdC+5a5`kBf0v_$L~>}E@IiNFlnl*3TPP#vJrY;-FW-S6th^S(7Cgx%Ifeq5xV_5lCW=|Cm{Vb+_V_B)$n4xB6u@F?YCL7|;IYV%V-)%1n>^sq53|bKl?oH9GXeG)WLyVg3ei)we5Z^Y zFww{OZhE*eoT`K2lrb%{4V_NH-^yOKGDnmERWRg%ac^C0_f4lL1vya_Ua*?2Q4lZK z$kyf%uTY4!IKF{{^RPMbFpz?Suy5ZW{^`N`!Pe%c0&ZG&Zfoub^A%&-n%&^cYillv zq5qDy=KjU;ex79}`@%eqBZe0U)jyL}YiF*ECO5F1xohc>RAvRVJ7x*>85K^NOKx!T z>-id)&Gz1u!Ctj9*OI{)pA))eq+Y$f8DF&nY(odL4=(*X)xkUf=1A*wG*89I;&ex| z7gXP#bTm)I2l?-08;u~GeJN<$SaSG0(zqy03L?71Q>>`Sn zO>E;REs$*+V2-bzFsl%*sO}Wqxnn`oDs&@!x{;@x$nc3qOA7^VjRX>%jeX_MhH>J3 z=&XDuvYG?UvBCnDHPCz=cAa|+GM|-tg=1zjvp1_X*xWW254Z%>7Y#Rs?)ik}C{)f* zJ;V7upPs$LNj=L224nC>O>!cfzwi0{jIg$QKJWKrHwK$sgr4m6U~>ft!7VOJd$F(~ z=HL=|_2H@(6*C9C*8A3xvvhHo z`L-g?$YA%!m|KZ8GFa^lv!_@xgLTL-mlofTVPi7PzHS%B$aZnvwHa|anp*42pRrE6 z&cx?>39AwV zA_sCe3MWoomzh_HwL9y3mzhs_i8+aE+J3W}I3$s+*>8?3HvDxV3J{vk-N*^AS)l{w zCE|=|ea!(gh7=8&=ob%~&$@_%sxp`vs31mFw} zFRb(}VV{3PV%9O{B>Mp%>SUNb?3;t=m|-p@hTdSO%P79?>J6-{{7+H7zAmxc40DkE zQ4ses5Zlb_df&22CwsBdRdy^`xhl50!d8}3f^jRsSvbyO+F|`mZKa)?*nOSezKyb~ z3`Xy!G$kVK-gpdSx;y0Z%SE_p15-r%FgrT6db%CluQP2tAN}Te-#5=YzIopG&GV{n zo)@>P^WO;Oe#0>Bo9FCrp2xIfuhWz=P^a=rS7L>Zde3w`iM^(=oH5Gx;+v`L(-@_G z%_9zWx$V$gFgkcP3716YL|OB3>g_Bvhpe5r4*M|T>BV_YaGu}cSl6@B8A>?rw^)~< zJi&!nKV>SzJhq1vg2p;$jRuH=?ur}w1}2f9iQz3 zJeHTxyqA5Vx#e}A*fWd-&m*+TfIn`ERGtdS6{4D6JYQ!;)HHqEr`>_4p;qI(zh)AC@aG+?F8bA9>6npz$UW;8+87(@G`SUZ}vzuTe5QtD8__ zw##77b~h4u4UV_Ph4fP!mASIpG>Bizhk><{ zjBwF#tiQ4`xk{rnn3BxxYm5#eueLPM8*r?RzDJ>1>L2;%_8T7*@l4`A$7QYK+#8A8 z3*6Qf{V_xNPmo6l(v^a^@Cbh7K}J)Mg8sBOaY1jiQ}M&;Y}RkD;;x>6ohu7ewM->X zu&H~Mjjr*p@n$>N3%DaS1=i-T(+bJk#;kRoa?OD?G1;*_VP@AtFHwintLZKGDek7a z-^U>r(9Z7-3n#SIFa;(1brH3#4Qp(}<`YKCT@cW~hK1K>>klgj(t_*IGS>}jw-_$x zHqUlNc;~{Dxq&sXVZU*#3SllbEZBza;8+d9X!Vw47PesrfaQ|DEaI8m{FHGxKg5wKA`HuH!Q*y(01UQ%v0-gBI{0N#I>)W^EK6jyWXF=1az>ZT1_ z&avl&eJ!bjb#;%U${;~p3=R(eD;)*C>mi6?Of* zazzw}++aH|Dq&*18~VeGik~3*UT1|bD^cQ~*I2@302{BdQJ0kfapE<$^s>@OtaXh& zyR5t}CWIMt1N(?PTEUI73SsQ+6{V!-Ks3amyodvlI6&d#U?umHUjC|r)w3`*<(g6w zbF+2V6kk03PETR%$u*@EoTAr_r}Ed8Qofq>ijsLwXKrBo|7I23Pi=6=C$EZ$xR)V+v2V|T;~k|0oPaw@ldA3~O?J5}c;=3l zGctDyj&*U2(f9v#0(!2>qzK-Tx zQ$pZex~F)-lJ=W>$`))NthujPiJ_9DikT5UeVVp-#Pp^ zz!1@wL>ywt50q+!UsAE+nbzv7ykzSipn1H|i#}Aox5s92`V*xKj+OlRLr%IrB`v`0NR4L{D^FBoMnn(1zuMyF%4v1(48~0SHP#D3nDPX)m zZ{H{E@KdF1(Z|Lca+)j{MI3eWG5h>fDJ}b>fS~34m<2skYP*BUIxrFO#)HdR8J8kG zgr$+Fj*r=xXG%<3!#qSA%)ed3e2i#kwnwy0s~XvlCAbxb+i>_(JHX{R97J$`4p-xF z9XQsa999T!$YBo-`w{%23d;W{=<-FdnCD6*SQ`4_xl*R^Bg*3uBabfC9L7UtnCZM2jCAcP){DR*)NpFaBjU&>Xvx`DMjtAW6r~_ zN~!9P1wyjoh~;_!kZr z=CB*VI)?)Z{+`26J&e!+1kcfDy+-HNy5&E@SGgH*J{)WF2t)W;f^EVla(E`e6*;_= zV4LvoIJ}r(=LqKUPPtrd`*xJ=T^{+c5{C4>aIC)N4e4_UzQ^G<99~bbP@aXpS0;+p z-Pw-!ihs4nGA!L;zK5x5{o3fhb4;Q;989;d1q09g=45*_0`u>)iD)g?TupYZQGFh{ zGS|P9s^X1WEb%YpJF%@R+x?f4Al@&bYaf&!1g!Rr`-mR*@ze^SDW&2cf=k;!}06cC90LsRzMC#61Y_-y>7{3;aI zJAGD)39xxM=!=pKtBW7LD4~KjD@gUi{|0IsL7nxp>Mq33+M)K7p>PIC)#6#Gptcgf zFUqn6wY!kc3Ix>`jv}g!g6l$EU@RI2)>*B{R$OBTbbi+9798%I`o?q`mN6Yteh2Wb z5gRS4<8U{a$zJU#$ohBoYN8Vg1sxImMt3a*#QRD8kCQ< z3?y{|-_NXkakZQf#X1yMy+qf~Y(#POwa}jpbXFtbEO%CS;L4LOE^1PZa4PSp-|kU` zsf>#taE9q^K?a@au(&iP5NDinT-Fh8ToiJwprv6$A}akUd*-5!X?x@^#7$Sp(?(!= zEjy>N*+vC+xd0$GXVeDVhmE&$&d>vOxng*xZoq9Un+!ERN6-1F^JZG_%!!<1pi${n zQ3~DJF;}&6!)k_C@@@+N>T%FB;kXt^-s*L8B>12oay-xE&!1 zYI3h%Kd^=+RG+4y6i}uu=gM)G!7y#rygX8z>I9+l4UB}+g^W>Kkc5c5nCzV4RQ^qd zeE4GAl!wN2$(I6Lrc{9~!AT3ju}y6J=44uTeI<{CAZ1J@xgKRe!MpjK5H( zzNT*tY?#B={pdU+kx@(BQO&Y*lBoh(uxOrRx_5z@s;O9CXTMcbCseI{!2xM_3}D(t zv;?P^Q*oA|GSxS_(0irwH3KSE4@jg_%rj)T=mmXpbv4dDK>ANg+ZX$q(!b99ozi*E z`o}2sqaao~rvFu2%@fe&?uZuP!JDIJDQ9X-08aXq@fIMf;C)kA;b(h%bq&};@`dSpL@7E{As`CU7A4@%SyHQz%99A@M ztlGQJ>yDn_1s_a(??9bL)Oa{n>~1$v_uO$#zvx0Y&#FDxutXO4V_MgKbZ9M~mPyO|2D9@Fy- zgX=*Cb4XINvDq{^Np*FFr?t{UsL;V?1LjG_tqu+uEH_E*>oghxERLJThQi*xY4ccC zv6UJm_S>mI&tCg@`FVj&yBRG=EQ%>Z8rO1tW zt#0b9))%Y1u(!)?z;iohgOS@OKC;m~4GSCwG{#l4%lKMj^$ zAa@?4w|U=MdetjB>lu3(=a=w}x^u@sKdkg~lL(P?M z)00cP+xo{IY70S3n9rK^Qft*)Mo~D8-Nx(ouL~)KSeLSS|4c6v&(d=AqB!#yMKeC9 z@fY#mu-b%l^Y6_g3-fEcGd^OwMTP@|dd$9?s+BHRVHD?yHNAMC0 zt!71%(arat%Oa9h=ORmu6l66riole8lO-jqq2kh4Y~LnWH~kc)DeOeDTEDbq5r%L$ zzt+HMTL|^8^XVDNVHono35VbT0}++_sQtY>e<@_wsJp|41WS)YRiTmRH1<7BsPI~Z zC2V&ewVCsEw42O(&uA8%Y|OPx{?}QlzUsjel^dGu3bN28;KtSZ6KD>LGuVC&*{8nh zF~_UMTP(XAFTeUCcJ4d12d-X)z}X@JFcNzT6y9m3c`A!<-* zX4Gc2UV6c&v}I*_fuSmYaKF&HBM3c`+?E0oB4(Y;VbY2MFrzJM8lG% zHFY+-l%ke)>l11RT$%UR7u-?lG?pezIEI?rhdHOJePy6A*-=~iuyLtsbN7^*D8|aX zdUjf1w9bNSXq_-}kczsV%v^`6-GgZ~l5cvCQ3n0!aAhmhh@Xr>%7N4*%MdNrQUe@6 zC$l9()dbI)H6XPJpGh{DZ%9pmWA)$kmR5#cnC~z(fiyA)3{$6zA7<$G!`147_+>h) z{R6(E)0sR1g>=+wSjng3UeF?d+BO=fqE=gE5LXbkwp-Z{FSrj~RN z$4_DxGS#Xcqr#A_->3v&wsNwOt>$p7re%82STswwacIZge~X2_w`FS}eHZXC$}!#8 z%?6B98&|lMK{K`(ejnDrH2BQO(jSde&zbCN zhMQPs9s7!6p>XzYk~+B+L!Wt=zqC!`jC7pqjdVI)exW~#q^jySoDcpxe z`DQ;o&+MZgo~l+73O7&Y3{Bt`FrI=}+nj$VKt^YVrg$017-t6c3>Q4b{ zuq=xPNv|WZE$>>R2J-$63nwJp1RbHS3)Bd)ofn(AKs_f~JLr9XQs+B}C4SJQU(jE= zEcr)B+h$xyVlu0>R1J0n1kt78Yjsa%sY}tVo=ajdj&N5TRGf`krg|#7uya81Y;Vba zS*G49aij%*J_xtqGAw@(xVHtHzg(>&Mwig9EmyCJLN|TqDit>icF`ZNRvjJ0UmV%T zb!r>&NMXIzdbO|Q{s?oJ+@V<1NBqM&8gKYZEhM8QuB=hZDlO6Zk>JF7OwrZFLJRh* zu0AQTDVlq)gImxQrA$0qqxFs3)z+ezSeq$3)v99Q+Iq}Rb-n1m1A2(LU3nxit&B*9 z_CnjoC8&GU>uLL60uDz9jx;1B8SvBYfP?!QwQLE&T{s-Z;gvlAs~jFna6jrUb0VEM z9Mlc)qdsrHSclddnt9kH5j@P9O zgwD=WUEG<0VlxBTE5*_CB>W2t%TwLbdJ#OG2Y%kd$k~vt2>e^Jk@AKF@8R$n4%Z~v z>p2`q@I(%8=J4w-fTwcUOzg4=Vr2!}@!{J8hqFTGgIK6Qw= zsw&&D4-Gm?f4fhO6YY1sb>Q9DxVLQhL3LWI&i`~{0d%nqERvU}7TwbH&%$l z6$pOZ-GDn0Z0pAEH!(uX1plUYKBQI?#FQ6o-eENrX0D3ltG&fp&)E<8>SOuvGY7jX zp?S~P_eU_*oA^whc?8Q*a{N>BZuOLHKdMeFcI*iT_I=Pl8LCWILUW(6mdDh|V(=6F z&M^oV>gXj;sGkL4gzo*DYPA>H116n87q$4IKI)7*SCrq}CV9_pvy$i41}=mD>0<(Y zc^~6ah5c||^%PI|>$A_RFhn^lTEBluZ6>;W_YZR;W2*VZ8eN_xTvdZZ0HMA)!`G^m zr;aYpDdt98cF7n^)`_EEzSO6&WuvtTfC;AcN8VCh>_zngn{gKm|r$1Ib1-a`n^8M}@Tk=HhYu{Qm z=|!HZvLHGiWggGeMPl;D@U-+FVuEvdtn3VYj@(y z;g~SMQe~quEF##}lL#EHg}Iv58fm~|2wu%w#4Wr4)U=-oKFZ;41lxML0~{U@4&kdg zTyO8c8q`vbr%-SU$Ned|tvzOOcps&$ABRl@+xnqiHW;%{YXXPwVFviMoi*g}6N1A4 zQ*+Fv)iQL3dx_81Dfn`}exXzXT+AYZZQYr`;n$Q0Yb9O+1lyYHEgz!<+E6SFjhwtqM zZ0qJ5a(J^Hl>mqH0oVB269;nKpCWexe(j=lPDSHmvY4dU`c#o~4JEDu7V}yiWWUD2 z#J0ayYvEAX+t+HieRT(u9`r`NAliT2Z|jy0?`KuttJ7Ks|I;n?^e~EQ+6M@V4>wA3 zH^H`UsR4%v6CBFng#_EWrLr83CAe_7?)#UTC5S6_vlSoIbR2;T{HV?lr|n|9KdSAN z$XyP!J#6Z@i}`(0=P4U^8qbcacCtgC)NnC*CwucreWbL@<^J7r^+%sET=T2C18w>! zKK69(fsd-7d$}PdJ7GI*JG<}L8ma9N1Vw);XpSN@Lq6GSE)L?vEzDWgQpA~C*+f}; z;X+&7_$E;QQsj}nF$4J|vT0_`TfDxWZ7^#AV*Yw|!L0qM%v{HlFln8>U(vh-anD-) zrmA&wuy3ap((4z|o(V3I|AI{wAR6hjOpSLln1X@!J< zH_MQj2)gDxX8}4itQ}^NIUy>THGn8XOO~}n!mPN`DF%&SI^Lw258@jP93KqHQTVv zNvSD6O)nX!4Hw;8O+X~JPK`nD6p@^LFWOm0>+6HH8bX>l9=NS*sAo0sg-4Ny;7`!} z&T+hr(fQXV@6X|ZuMu43@IivH$w|d&;&5>|)<++W(8~z6b$a*i8^V{6@RJ-KH;#HW zTd$YT@gca3!@3SQ4!ITlY#a-B>`Y>8ZF>=C^M4Dr@mx$Df^BVk42MUNlw=P35o{Yp zbmOp@5)nr*dNq-7TidV4@%2Zj1bFb}@IiuYgG>{LgI*!>M;~|z z5N!J@+`DI#Kxq* zV>vvWvi}{2{Ry`9n>{&fBrx89+c=sCw++=AaNLzr7|Mg+8w=Rhry)j z!b>bxz^v*GngnMbh!YN4aYi7aqE^|xAPpgXdB|`cvJi!wrZ1?d$!N6fWM!=+J5Wj6 zWy?|4Rf8+U3tYNBw5nE3RCXh>UQSnV-5%RfUGo&@jAnmS*Xk4-hOQAt|IBY< z24VLQb>;>Otf4IxyNqJL)zG4qlcOkHn4{y5x_eD6L&O%}f?5dg4LP;6Qm)a+aBOzc zoH&aVyYH5LY)+-a){ZCG^IDp(Xc@(d*GA;0MzbchwU*cxTvA)BCvF?5TWf2nref7M z{5S47zq0}LH8*kAaF$(P^AQf|tLkf|WZ|%WB0+0yFRty!0-9-l9z*+4ntWo=Jy?cd zDQZ9lQ?eyUKNA2U=^}#89UWmMp)A z)?8Sjd-T*Uipqm#y!r$;WgmNM6R?h&m8_i>eqpWqXf^T0n%M_|ieF#(jkwO)di8!< ze|sG4S~);tqWjut>*dK4OTrLlpY3N<%gO!hJ%p zqi})vEsoY?)@!I1S2Q`qE_UBvVqCUePPBlf%4C)|RC9HMcf6%OjByu_&vrN!ZK)$i zoEh)ZFPS|Vs+Gqwq0cbQ8&1?P%?(bgVOnXSw?1MR>L+$P=MC3zJ#J67>IZ!Eda}De zXj8oAR6|+=cv?;Kd4nYfz0gl=>Iki6nONfZ+P};-I8I)|>ngwQ4Hh;GI~I0lK6alMB;!s4!wbZ$H$r?JSN>5<-lF0~al(D)DT}B+UhCrOPI16{@&QzwlBY6 zGp2luIbc;Ni`=ADtQL|;FY<=kXk+H@#@7dT5 zimb*1SQm3vg=-Vep{~QggKYSie{d6K-hbonHoU8W7f(q=TyZFruNi)^m^p9N>WVd{ zvo>3`(&DsUY}8h5RpFqf|KeH1Ds4ll59`djZqvL9x5avgwJ+aDZ`YYw;McV#`Oz^^ z$gfRwkM6X~nU~^>kM14}oasAQh5+pM5mN=CYulJg{)@>SK)z{5pshG}fj!?eJ&?(| z7V9yo2i6mfRaRJSx{km4c{j5Tp&ZAS}EzR5#EFKBi zEjWVh)IZBI$L-o&pR#yymV_ftSwSc+>@t2n!})8{F*3ih?9g`Y2bkQfy+iv2&aE9< zd#DuF%GJW8(~8}A(~tl*Bv)%(`jle4`0*~@0U>l-URo7YICD#A&b{KB-KGHcXRhWP z>K|ffT`~^Wi2i|nC+m*>hC^Q}eHiu=TMSGy9hQFjQ+=g<((*dUzkh&%CADl@a1~zE z;xmiky~kx=#o4L6e+u+u0z17&^RMFj?-H1oV5BE&7-~M<5?DYtnIjB}N(W=poRk2( zqPNz;2`prY4*o#n8#num*z-DoW++mr;4_-diw!%0B`)0EO0qh0E(XV1(}*hS?q;KOk60fq#r`$=$ASt*H|E%n!liNP zWqG)@6wZOdWxMp(%h}bLFzQG_rZJF@I-f0)O60b^)Xh1DQ{Z`&fv}v&2Mu{mqtN;7 zj0_eb{25QwaSm4@cqPmFO{>^e3$d${8hl`?#Z;kah#fxih3hzNdsFb!bKAmrzR4B- zNSocm)BH@@FkGyTx3>hTD0s7zZtkQB2p_HeZP>?gGb{SLRy|E6@tsN4m#Wbw#qMaq z`_L`b+`X2s9oUrs!hw4f;f?8W5Bu#X1J3QsQ z7II^?D@TTRF!_N==Ltr+gdt5(eGj8XrXTwqpBVp*ie2=ZOf)|`ncMV+9><*x3fTop zEfH}B=79bf#-^S|6)Mc`oW@{x7;`y;kJ3;!=#18;=z3H~(l^^ipF~U4!S(v(Gg`b* zI~9j+smokLug>Dqke;hu7;H99O~)CYrefq-qpDNpV!VR*9G6WfkzP}wRWes)J(!M_GWz*V54QUIt&l9@Lb@8Zr!l=J-ZM-$ru`? z>1mfVPocOe1b4_nGyM+!uHb-oH&ckd_Of=>-cbM}HzLyq*B#Hkt`($tpGV2Sz%-T2 zpejbmEP-R46=$@alIX;8AMt`~&f&fU59RQUa|rFh=fxE{Jc8iX9L^&c3lt>WnZp!^ zwJP9PPNpKoX$@)zn2U7mblzBjc$g)dC}Q!68XhG)L%GL(J))B<7aq3xfjor~Do zKebex5-EL4Ym3@B>XsH*wF;Irb9eGY9F^VqcUSA_5%oLbzQN<}hn*fs`#{~MOFia( zPpb~qnwIypWDEg!-$SFD&z{`FjCmf5zOQ`;XYGCDd>;Gbz7`|+Gf%4)9W)ocz@&+9 zzfhaKx7XE>>{xLSvQxR(XIrm=o}t+wmSxpKgt=^!6`!WL?4ngG8M++%5%>;LDC_E? z=r(d3HzR277XFH8y8;QEN4pkk9ag$PtLE7rjlj@+^e+yO>v0;rU%N0itU&WNU-rbp zcTQ-Nvh1e<4CLLy*s%hwy0a}@)*Eczy*2`j=*Zk2Xr261X}@C7BI>$Lk5G4F@tJ*i zf*SeP`L4qpecl7Du^`nA0c$s3_UNG&3Cn?{9%;3TJ}GA>I%T~?^MN@(i(|qQeb6J! zSOqVA=o77uV4kkP@Vp**)Sd19f5d$Yd`wr@_sq#fM9!Hwh=_<0L_`n~geJs2NQp`{ zB?#hLC5TH26Zg2sb)}@5suCJRt43AZwAD6Mtx(leLqoL6=WjIYZMyci%XqM`BA1ixreS_Wx{W@UVE91Y>H`G0 zp>a$h=JkHb{j*UAcGIY3vCD`i`@cZ@d8xzWL2Fa>yy}CvduVg9%V2pM`l#tz-;`C> zI&9lUe-*oY-*hwP%k_zl`c7qqzSxAk6^zRqZkEd&?*2)aN?f|)6smgnv4HxMmfXiy z$YgRX#WXaDx|X`M5i(oSxKfv{ag&f)^P&YGSgDKeIHJ9T$!M<^)Qj0?*r!BZ4K0zO z=|QHx-Z>ljO;g2tRdFJVhp6Ji*nqUy#4&%)cE-w57n~h(ow}Eyw_K;mWiH#ajf@Y= zTrFD z5oh*}(_(VHzTB1ZO0Gl5BO0a^8!-^E9)=w}AJHtW*hcG2q!r_|eW^+-zAES+(kp`a zcBeiZFA%+E4xVbLL!cylpv30~1UA^kVzV`3JVms3o zz;~wa-t&vu4RBTSw2H1iz%vy@jG`t^;u?G>=q)F)367Th$Vv3A7osMGm*DQxJtxua zIegZQ+jo2^zOwFvwOF-jz5+jb&Z0h+zgS>-=i6le(-){$U9n9t44isNZJdpua-bmJHG#HNDqxWrf> zieEYz8ovoeFIDkPJCkB2TB>lCZ0gt*cv50{E|8>(AG0`875~iQ=4$Nms(3$(JE>xR z&T^`SD(<6-%ULW#to~n~S~V7z8a!CfoQb`HDHBKgL2pidQzjn0QDbI>Dh_5dBUEud zi}h+MajN(_#|~1(AG6q;$Ns8#9g7=5tgeOYnvdW;?nZv@;swKJX*Jmyq%~z{WM9N+ z;%dsyUKX1T`l;esEPkjniC3`LoSk~AIGM%2sNy&lo9pC`#$^007N3S#T?NykCSt2* z4@-D_E)@9n)JHgIV!7p@2~A<&>-13*ae=mgI(vvinvC5Iiv!g1ALY+tYz(c}0~U7@ zd58x5`?YaXacYw#yK1zKsNYO+?hY+HU}`E3*A^LXHx)Z*8;*9?m`=CqSADwG_&D-! zCXUd?8IzicIELwE`oK$k4yUCQdx>N5-dtpJaiSLcddKx*Pkg)Qz8)hp*0{KZ_`25b zxf_BeZmqU3Y$aX@SU&>G{v`!`U2wC*$}}63+3CMIzg-%ZQO}m*;5J`hM~=?p#>q-~ z3+5zMd5Eg~6^`X?DaHujR~p4u;v^ip^MDe3#8KLtblyiCBXlgG4sFD}{afH)6yfU) zPFTHb-*2Z`#;=JcVSB6UJ&c-F{Dr6re!W`hazC@3rqefto}ch)8lStv;ENvh%@@e% z#A0J3U(rX~;>0Zh)33PeSUcVz+YMIB!q#^wrmfhlt_~jqLiL~j#kjn!h(}>B(FcBF zOR%5)#Bn(6t9v_yM$(vesH2hedpk_yBT4iZapo6I^GE1K+Tt%h&|alA?ZtrbciUBO zZ1X8Uj`+}QnZwmX?bH);9zl#}7>)j(&!4b%$lDH9eag=@2+b$te0_+N_F^O4I5g@Y z28JWL_0d5mMpeM*^A@A8n2o*(7)CRefK?kET4S`^A==!*Wb~a5VrT6!)SU)L}o`Yomh>2hgp(P<~^KQUH5FNWLW;HN$> zh;{98%4@_((G%xCO&clptJ7pwG=^0ZbxHcIV*0Gk9WeeV{1~ydo%S)^i50tOtH^u2 z7!S5>JjPHJ<%}1@blFEyR@{TH<+CZ?Hd5mWVtA9Q*c!4tg&AiwRmMjrP#)|eO%R)F z7gFj3afe_$VeB|jTqS7Vp${ejeusXXB$n52;fy^2-KvK!>I>`F-=V9M#nw*mU@lqT z==5Bp^AwCqX%6~LLPo?|{J$&ojWRkmRqTcbT(_o*J!CK5`Ta$=s>F1M@N41Px2elC zSa{oHA#OHJm?mzO<6%Izas*%R@b}Y=q2UjVj?=}r1)Pa_Xol!0;9TcpGjR#jPB-3| zg~r9MdFrrK-nzGF(l3ad7MA@X=~6j^*EHJ@?VId18M|w5{fg8TilOck{*P@r|^m3&a6@lz|$j`6}x; z*?Vcx0@1_$mbUt#`sTf+(tT2hOf93#1>zm;HhO)b*h9O`cxj=C15LM5lSSwOTWI(q zaZ8;oB?`8c22%4yV&k2QMGxRj7mEi4M`z<#i^bDg!QR=pa*4QJi^top2Js`UfESs* zOAu8*D7-F(Q4$H;gFooS(E|%a{IDdt>wa$~e5V=35c`LNktUf-qz= ziLG|HB}5NAfm7`Z>u#skJH(FK!Svz|u~ZnbnuhGejnQM5_{dHexPl_~i%pCHdqgbRdl~iV;&}%&Sd{^|>3gZ)KOs4p!uyC$%z+v%at&$FF5H++`A5VAcb7SM3E-z&c-pfn z6>qDfk8&={X4BN8uy=VjB_9=E#B;-IN5!ckJ|0{c*n-y`p+9V=5n1AiW*ypL8M&%; z6GU4P+C>dDRzt%&kk2vkN8zpM^!S+ASUcC)=snR%5DoZKknV)(5Y|ht8vTx=4(s;C z9}r+QEuJQPAa<*3rv_u3*J_0=(~Rwn;xesxZz9KaX^aa|-&g3Plj56V9~HtU zOdHWFH048ao$&4iy8of*J3n53Arc%)mygek_fPsGWB`>xTjxwgt|><<1B8NR;ZS>*o6?x`;%Fh&gHD|n(*(!i6rC&H78VVou%E@o zH2Q+LK=2zvmoA7cgs+EE`32EWcy1WAyeQ5Wz8HF7_eD{w?Pg5-0XIj&fe12Q!XWx| zh*7yDeytVC1{rfMi^H_SJK@wMPdp%04W!TW#6-a>oXz{XmkvY+{PZe!z!=P$dQ%4! zuMMQ6pKZXK}nRcHqt{qM!H*I^fW9p6f#Yo^I@R1=F~8KP~=6?2f-yfAEXg zTKkUimtQb&@Q2GaSH<8aALrqE-BRt;XS$jO@7eh<@*?G36%RCNW+k4eik(@!!tYLBW@E35!NScDot_q&C9g<~uq`Uc$!aJBA|^*ZhM;Qs275 zQ8)UuuH@yu+09-vWTMLo^ND_g@F_@~==Yi%J*X>{3q=i$_nf5GJXoi`53|5}=AZ42M{&iVv~ae5X=h z6`$wWH{4CJ*R$AsD^gO|WITXle*rNzfUv_wb6uq^hP*#&GSN%b`*;}iTvan4ve;}! zuZqWVD#eXWsqA90IgeUZtZ?j$s(3Mr&3U}xWXeQ3i{FP>&4k3?N7-C}E)#)sD4Wri z`qB@Eg}>M2>DM}@Xk&&VT9%tB(U)0lwwkSqm$G<^D(=BzbDrK(#c#5Bjw)`-VsnX> ztKw`HkAPUslkqoMdReQLDYT(<(5bu_ON`dB6X{+3QLCF+FyZUckw3k&UH3czI-7W62BOzAL8p-K7}3wd2|Z z@Koc7CV`Ck@6;@1S<5&+D|WoirbzrvB1+?KR^Pe`%UldyW2VFTIAf$M_B? zc|N_>LE0hwe3ODZN(&J@)=}~l#ym8h?$WxnZ#_L_Aj|J@y#y5kd0b1=v`lGuP?{R^f{0;t7;4S;V6$M{#P?y}F zT%hkj{+4Ek zNzH|?uhZ5rX`rz5I{gwR4M(*0y^)c#%$m}?-qJ4kUHeGxU~T(It+n6KFoXiXG1)a0 zsHN$_Wut4qYBjeSnKrl@U1a|-_^S)L;~RRt585!5TJ@EN;g7QkeWkh2@_39K)p`u;;?11Uz@o3YYd_-TLAnDI6yO?-?Yyd467ub!&fJ zzdx~ue~nLEAGAV=n}@$ihi=+Jxq}dU3posyZa8f;O}5SJ(BFmjjXEIol!Iaq0k%Hv zbt`U0${e>3K)Mj5+}ldeia#So+0Oexz%SZ$!ZMN((Oa6A{juN&*|GWZzF zH!S#3!B-BACi!WczH-p1tgg!JRQ5Q|Br8{0vC95Z+3za*Rb@Y`><5*7r?RhA_F0@{ zGV_rd{2-1}7faonA@o-}b!!Qoly8_4Bpg{JIO$epyiWHPOKtGT#Vt{~z@1>yuItN4IK5D)}vux}v$qFOgn#BJ>uVrg?xaFOfps5bEFQm%sL!w$pki zRYoQh-I_zjwo9c(+PcyKe&!;+zn=ygkkn3^WsrQqQVo(P4$l3+ARPvqn1l|$o!(87 zyj{lmY5F9E=#iDL@!nYy)V5Puk`xBkZ5amrHafCQ>I7D>48vm^)me@)w2c-lm&(v7 zX0Cwwtwdl>TR5AcE#IcES4gA%{PrRz>sMv-W;OoZyHWh|Ej!IEK9`>#==5H3C$jg7 zs`|P$QClctrR3u>x;h`;TWIM@X_YpG>{m%X^&n8|@0AqlvI;) z(isn}E zT}$7smzvkJ0IS|#OXcfv{aH(H8>AL0&V6ULzQ{ZqjuvC2YWSvzFf4 zAcYBU?xNo|NJF&A2Rd$)w8HS$jh!}01x`Z8E!2Rdq1vTJyikZ`-G$A@*{M=|UEVNw zOA4^p&N4RGFLlrgon5K#0cjZyO8WAEl-}W0uBR@?E}{S%Lr-<{!|~bQ@tKkMZnr6@ zNr+DhJqaB73wV{bWk^#E9Qw-PIhA!$Sx1$%Rar}wHB(t*mDN{SJ(W4AOzCPeR;jZ4 zD!Z$)KUH>}*{z0{DpS;hDi$4-PT=z2>5$YGZ1f@2VHa~{uj>5@tvMtuK(UoW=(TtY z7;?Q!X=jVVYttwy6Y-}~y~C2eo(T^`;nJp3*TYgP;G+*qp1MG^_j>#Cq>xUKy*Sml z`Y_g{+5qD_M{&{7#!=&A724)~(_mJ_(p;n3fvC#8eTiIQI}T_T=+;5w9gwaek|=4 zJoV7Q>%zW=co7yl9>Ky5L45xjxaMQ$NI5_lh)A&~~SV`O=_z-GN2( z&xr2EbNPJf=}N|5rJ41*0ITGm(k>KGfJ>>yk6tT~f|wsIkU~YJEpDyvxbwUDFaAW8 zfbbeXx9d`WA@?#Zy^e-_LI~UJOyAy+x(E?JlJFaBKBjiR!RBKc^_%p*w#q2o zl-#rp9<|kEXy-k^OK(fz#V+5PN7U_ishReX@x|Yz#&$Rg^3_5ZD>rU0#Ple<*VDM+ zw$xFJ6E;u(B`wyrH3r|2oN%g?vG+acHn+Kdk<`?&b+J;Y=;`?)X+#6~O%prb)w`AS zG1eW6ThseRl8+Mv=mV32jn|7Loqhcld_lie2h&POWWs}6y;>Nx53m|U5|w4r6i#A% zrDUhYK~<9;N{NEDrSV3U^rfKH8#5FMH;B!RQCi&@`zHIcuzPhJ_xZdz)6le~dQgv- z0IH0g9CcTSCdW| z&POgh2pvp&fh@*n(>bY&s`!Ju5U-=R>*}sF8Hca4pW4dT%#B@s)tO@F;r)_AqMgpV zC~cDQFK1mF?ew#-a4K3=8!VaB`u+tqp;@WYf9=^@H+aI`D89{V<^u^^s%oCB_KRn! zqV8+lT3}jjiLbHdPSs$gXfn77$72;9qeK^7XmnrfPM%6o_ebAW#S34Acr*+lomMQK ztBO~u;ub6pQN<1{o}-EG112^ova9*k+ZkLviWLng z1(XiT0%e18K?R^9P$Vc86c0)Q1%SdpdQdKgZNd6~Qp(2KnBE*tGV71xIO|FbrpOu_ zBUv_)pO%0H`=4dNpyu*v89-B+T-c5KN`25(P#LHRXe_Aw`hCR@d>puiD$QZ$n&0j# z%p01yGk6Fn5abK;0*y7`=NObM^r6|$JR8LPl9`_cuL6~T3PIOEj)-67SgP!?p{od6 zNLQ!E&)A=4x(Gg%e=M{eehaOJpUD#bPdO*ZncLP|@H8gLx`K#~6K1^9LqBKIw-f2K0j<^ z|DOM$31jHnI=eb{^E-E>gFRin@UTcjA%}DuOi1KmojVmA(lw%rL%M((DC}K8(eGMA z>F?_Bf(Rm?cvsh_M$&j z?dsZ5=+ut1EnFKI@9AAfxEbH*=GsP}ux_p~#xvbrf44V&-P5&BtTA_w>pq=vL16!W1P%XEP_#JeI z!}u8(yb0QiF!N{8nrF%}GulQ{2)LBAm`^JkF^UB71uZSgvP()4?-UG@4u?kmBdNRS2; z3t9+D1r_{$UpdfXVgtJa*;ug{G#g75{pM07Y)h#UyRB47+EJ>c0`SDVv=mY2&OBL4-p?9iO2{;Yi zk4u%vPhl^+REhr_HqRjLm(V{_YEasV50ofSy2}IQmh%JUMM>rCw@@x*|2t&(-!lAk zyOAgeQ+1&Y=2CO%ETy&P-_?Df%tGx<1pS5@c?oHe(hU%N?Nm2sraC(0LF1IKr&U_@8F31Md#n0l6!v5#lDI05)VW0rpUs z2kHbG0m_HsdhqwmM$RG32ADHhj96ogXF$I-s0oN|q=7Gk9nQ=}P!6ag$fDD+UeE*O zG=PVoA`lz=13VwpmpP1B(@VgT>KX4naCNgYe30`%2|1%utFLPO?|xb1XZd)9Z<%!^ z_;&*P^_v=7xd|%Y2E|bPKv{qY)-?Ai7|Ri%mYyZfXe<28qX!DpbAQyPlTX2( z`vU_%^Qi*NL{@kh{2Xo$qt>+jDHzL>pMfV@;hRyQeTIh^%zxLW(@()zC+ivb7gq6& z@ZWmyKzU$8S8c);x#7Yy1Uszowea_X;a~67CcCF#tW$2IXNlL@O1};K@BWSU=Nwzp zn>JyKY}+&Nm#pw1@UN_Vp!|KeHl;lUW1W;rw7;z~hnJPs;Pc=gh7#H8O?e8&I-{R~ zueZVt@INSdplA*E@nc1|7_c`G?*qd_ZK$hF*dq5c z;b?ygVBua?5oGx1Vw@UmXo^kPA|L$>e3%v97yh4M_ctbk#RI;=%5M^y!wa5)zhZ@t zgP+5!YfX$>hb{gQX53%_EPS9q1=;Fn?8%Z40n!WQ{Ml+5C{=J%}d8}QEuEw3SiDd1fLSPK=mXW-6O_!DH5!>nsf zj9Z5-{*qew%o?RXtOQr!PeAo2+0ay*utgs83_Q{b?*~8joZJn!8kZ?dh9+goZqPW7 zG9?X^0?eA0G%ZuQgKj|fGiax0nUaI>|Bwt%HSn8_@pllOV#Wr5Gl^bhiX+IBfo3ZI z1pE(V>c2y5W2dK~OmRV^*`QG%2LFd8`uE}+{^wO#o#20xc}Fho6i=gYyM9l>tEgw0 z!sOnoOqmfk!w)?fBc zO-aV0bk;J9pA*~fQm)iPO?~}iP2%Q^8I4So)r$N&!m|6N*OHejvKhONU-^II}73GrFqk^uvIIKtD6j4&(rwo0_I z*>A1S{^Lu_l{27ApqrplkUeU*6(|VQ4-^GT0Br{y2VF9h8M>|nX#`fj;WkXf!| z9Vu6mvdWdn_sSLh@p5c3mn+#uB%bnNxf1&kBBn#>QwTo;_Bj;30RAQLuV5$#vTq>! z7P50l?0Y0|9)@#a@FEQT0OOwkzYpC~_#Xf(L%0IrN`xOG{0QO42tPqsL0D6vXbeJy z5@uJSB-vLeu_Z{PF8t0FN@TqXYs0ifR3UW|v4+wgq%ksAyC1~NEHA4%N~sk#Gs^O5N|9pJ`UmG}Pry zT&e6rc&imQ+sbdzW4;%77wBt1P6o39YlZ*HKMe-%SQ*D@+)6>0N+mC}Qh6t=Qb_`_ zpQ$nY#$J`mQIG}eZ{?q00h#AR@F}Q!?;2%m`G4gPMcmd_aeqhRzlG9LrT$*uuy`~D zC~|hC5-~8A}GGgHD117N`^r?uqXgT1bO1h(2|dmlzs; z`AA9oLM3}EKVzk5YGfR~X%1hq!p~UwEq4A5Zm3TDUq#xEL{5GENFik6-=z)zGLGTd z1|4%$nZ z_-TGi2D%|W>zfis+6MM;gr^yqY*vo4N;J*vx7KHWz;$#;P&_CFlm*HK6@grDKn{uo z#e-5nS)kk-kMIrwJg&b%0Tc;}2c>|rK)IkIkn2szL9w6|P&TLtr2idpKuMqgP?$L! z3my+*JOz{v$^vDBazO>4B9P_}w7=^gFa!z!g@GbL@t`D73MdPd3n~J+{s}!$Bq$z~ z0?GpAf{H+{g)nM%>1J8BSzch)(Ljgw^q_!d_z43=f?`4Opd?TVD80~lv7y`(595U@ zCHE0h`Ts+PrzY&-@c$}PXd^CpbJW5bBzj7!QtmWR6A!IlrJSgGq{Qi}l*RB{*U$*7 z@RYi$?3iPfQY2O>S3oJS!*Lsf4@CUW!Jl)gZNp^GV6JwpeU)NR&~PwZ)u>A8>Z&TU z5yn~hZ(v`8_JihurXV54$C!B__-^MaC8ti6(hhQ#*@6Fo4D6Pxls93!p{7c?S&8Y^ zOa_bR{}VTua`Gv1`TsftKOoIdwT9XW8y=&*8&)Z!QC-#<>Sq;RjOu0CmuRx~!0*+o zQry5ft_%9kRru$ChM_-L+pzWj^5l`S%76&NK|MgMz(!cW{+7ThK{r6(f)*no#%G)P z0Pv&eRQc$*>1cbF9fw{Q6kxu#N-?5@`sga90yGtr3gYmOf8VVp0|znyE(9f;6;{4n zh3BPrO*CVS>W_)3Qu=}XLEA@HDJwxUm_wJzA9`mX%LG!1pdsy-JZ^sZyqc zu7aXxR4IW-+rU5nw}~_TDH4#7aBu!bGH7sol`;*K4BC(5T^@l>FQ_sox`kCr2xvb9 zakHzGCUY=!a4gIw&~Zd;Hn&Q76Vy4ON;wab=T#|-Koy_`ckliW3GM$hBb@7T$l(!W zhA+8!TQP*Tp$CJ4K^!i*bGH_y1CIuUo8^{kHS>(G5ibXs26qDIa53T+H|HNSB|+c| zayKh*M0%^4+?+mbCXe?^s&h~AVXR*rSN^Ig|35Pg7{1M7a(evY98^t3E)DjQy@gg6 zXeRTNi?r2C4irLuq^}Tm%lNTK!5Q!-=g#_|<3G|9FWEy#y-Xg>WgkJ4M}3;h9Rz(o z&1o+85$;^06V2tW!uDV39^*G}l9yiYU>8+UM8ouQTf4l6MYLEiw{DtJRb!o#XvNm? zYJO@}5q$&&L#~wq7X#-DY4U9_d%T5PXoK;4!ll6QV!z2X#4pY#)Py}QQg8}Rwc`YF zD2pZ-cyC7gORlShzM^CA6?S8tU1(ejxxQWO<06{dLT+tW2+!^oa(lbNCq?uvBUwrj z-G@h5s38w;*{4UOU9sX-Z752_(T66-8HmBlzAVS*(5fB&jG;*YKGlvEdCOixvK{U6 z=Js%;PrOlgmz?Mx^EhYnYALtZzl!fHHf`!s$0-H>+6Y2qE`g?Au~Lpw*grZ&x_z=6 zEo&(^7Lu>hu9mWQ&wWy{f&+0(j_dFo`an7`&JsJu3V>w-lQ91%CvJ1jbciaRKnO0v_F${94O_9aau1R_dFD9A^e(DZngcV399qCGgZi zw63-6XSg%8cAPViRRFV&!+w0_SECtLtQ-cjIL7g@ZA}L7z7`OiaeRwiQvkdHTEODC zzFGmVh%8n@(VXZ<)Y%99!s$gCeJ+zG{somB#ya6(;;CTHS5Gr9qIY+SK|Khsn@*53y_cv7(vT#e#C z+VG!dec(7?U!xgn?(qFK+ikKRxY1#QW4{%3?C94vawoTxsl`f1b0)ZU^*9wNa~k>h z%6@|DEA#^M;yhaFiw>LgD(&^f;Qu3!{@`%NOmc234;FsNqmgYfk+{d>&oSnVaBU@H z7)Hg@rnV?_&}{moEo?c>q1$cI%cka$m!ItI7(2IES*@k9U&@VXjGx@p<77fjS7uw> z-8Q&rG+7C>)lc^EXq$Ieo#9*@F^tt&Z#$YXeI8x(gW(%Lkz+e#E^h((wUc`YH-DnZ z2s=bC!oPOtGjFuc-gdHE&*a2nC5RJ%<8GTHVqOBqCknD-EFV~b6{ZJP1k7a#m2nyi zmym})c#wg5GEXtk1b-Crrhzv3W7dpFq7xiWT241u?!ST@+XLUXf;zNE*mWhXZZEf> zx$WipLgFe81UeM1E>=cT?_gx~Vtb6khU@4aE61)QxdZsQb=0+k?Bf=Mzr$MkEmzVE z4se(Lr6Lsh)yOT#pSr!sDbHLBdJ*8N^EG}`!6^HY-(Cv=$Nbk>oxT}nTuD#b$RIj7!3j5WdQW{(V zW}-Zt$xM9yBx@(V*9n>OB)Z%Qi5*X+C!NrI?z_n^5d6;DG%^tOHteI-f$~Tp`2t-F zL^}Nr&=bbb9Hb7N5%1i)G_o@;j{6SNrp~aJeuUm*-03J?=?uM$$mR(F9s_j7s=xMTJg7$O4QOO%_C(gj_z=u48jqN_RK z~z{O%^D&neLZ-D6dDtEo`dZzgR*Onx#V!9!3 z(LWR`n6peykKY`~qJE(7yCJQVAE=}o3K;bxc?Bb_?LSh_U{pY>pJ`?=@WP*I7vsTK z=u|LfsVqhKN22F1wK4mq7*4>3S?Re0y9w-7E6g8QSbnkcofQ@atO^)k zjo5KnqJUKZ+laN@xbAWbx7e#SEw6_{3KU|l($4NEP|j64)g7(vd#zaM1sOYT?Lz28 zU88&5Q7GRV#%+g4V%>b5V zqn89M6PTrPSZ_P944b$a!1e*NEOS}!G_Z8lo&iC%V7UO(Yz*E6mI@4)N0Z~o6~MLw zb24LGFc&QFQh=dVG#X(V&yIsd$CuFqRoni&0K8YMOkg=2+X({}bI-q6L1UO4U!bD^ zI^DWkeOX~a0B8pA$a^#=1mp7b-?Tpj-O|5^E;G+8BF9kK&rx4oteiJp8{KJWD37%g zTpHK{9H*Gr96$Gq6$~$v8DV+g&_w*Z-DIB z7*B&Yfwg4-jxkR?e#&sr0~k9_C_t~#gaBL5fH07&CXUy@Tx}7MWkEKaWlPPq7LHo` zN|n!mya@7_O?M_jU$e##lLjZa0SW;)Ysj*AWGo$62rx@2`Ko;!Sa^9cebiI#;uv3n zg_J-uvoLSzdSNvm`LLK;_LAHCxIQXY`fx|F%=i(!1X_U;`OyL`&}5nt<)|y|$-?Sm zV=uXZgU^?D6&I?1L2f{?%Vm4V(@;uxrO$iGKFumzOB7rssvYN}3UW>T62+jd`#i!h z5W;2Z5r)AUC)3z4OtYsO(CRSR&qLFwq`Jb{2#@|VXaV;|be8q>jj1FI&7at2N?Us<*-f=GSJY6hr~p8TEm6^}XnAjRpP1Hkg1M6q-R_O_eSOHe4;BtFKIGF! z_8YbQ^SerS#IYavMy+crH`okhBDPJ5difd7so=(l8w@h;z8lPP>l*-$w-0!98#>en z>7}-zv&=Kv&~2nAq_rcrzH*=;)xSjH_G8C9x;4g`4K@Q<3NY*TP6C!@qqiLx+nZvt zrrOH@R%#RXG%!v35(N{ts>%uH0(1e0BhpNcv75l0RK;qn0$4*Uj60l*4~7mfF0`gM zSI|h)4Ij&VA#2s1I`or0+fQrgqr ze&{SN9q6lmXnfDkRL0yThXC%D_A+5P3F!tr3*)E~8+)16L1K{)vw z-A349Lr94-lpeRlYOK=$xq*<`lLiccUO|7FGXT9Sd;skl0R7-`be6-pu~aeu3CBz% zw}J9d;oKyeJP_;Utf{njAmk^f(pl#EX;d;$?%9MY&n2%xuo*s&Mh!w*XXeq;LC90`d^$8p9_;78xTMxh zY>#p23#^kV72Mf?y90|_OkRUwr!bN21=5DWvXfup(wgDOExHei$-ugrBXf(L1a^EW zeKHuCI-W$=2BRQRD@v5kW}N_V&-PeMtRU|p7(!{QXyg!N)M+&>8iLA7O{PObkm1v7 z=`wJSinS%x_s?vCE5fA%ey}!=zyiW|U5PTE1!l)XC<5{n;PWgXIOB1^D}euDgC_#d z#c=?(_;%nK8~%xB0#DjlqBv?bmfHa}fin;+-1N_c^MMxt=S)}}>Pb@yyl@jejF3A7 z=579Gybvt&!ct00kN1qY2+JJ#P0Jo#9Ol52�?z~1wQa30P_^ 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 N61JGVE@+yV{{w&tNJ0Pr delta 203924 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 diff --git a/logs2/.gitkeep b/logs2/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/logs2/README.md b/logs2/README.md deleted file mode 100644 index 8af4e21f..00000000 --- a/logs2/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# logs2/ - -A second, flatter archive of QEMU serial captures and screenshots (159 -loose files: `qemu-amd64-*.log`, `qemu-aarch64-*.log`, -`qemu-riscv64-*.log`, `qemu-screenshot-*`), predating or running parallel -to the timestamped-subdirectory convention used in `logs/`. Historical โ€” -no per-file index; browse by timestamp in the filename. diff --git a/logs2/qemu-aarch64-20260609-192112.log b/logs2/qemu-aarch64-20260609-192112.log deleted file mode 100644 index 2f7c953a..00000000 --- a/logs2/qemu-aarch64-20260609-192112.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:83592610388794eaebdb48599b9b5029fc05031283d56ee3842f86a4c9ddefa6 -size 445259 diff --git a/logs2/qemu-aarch64-20260611-002443.log b/logs2/qemu-aarch64-20260611-002443.log deleted file mode 100644 index 63e80052..00000000 --- a/logs2/qemu-aarch64-20260611-002443.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3bfe27c8e32cd3e1af32ebc053f858ba75eca8c160b960aec6a2ca7e5425f2a6 -size 453599 diff --git a/logs2/qemu-aarch64-20260611-024456.log b/logs2/qemu-aarch64-20260611-024456.log deleted file mode 100644 index 0e82fb19..00000000 --- a/logs2/qemu-aarch64-20260611-024456.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2dc5080cfa9bfa8451cc868393e2db67d7c8660a5b7c923575e4b493229d2b8a -size 5286367 diff --git a/logs2/qemu-aarch64-20260611-173737.log b/logs2/qemu-aarch64-20260611-173737.log deleted file mode 100644 index d75f8f63..00000000 --- a/logs2/qemu-aarch64-20260611-173737.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cd881909023f366709be8dbc472f2242b036e3b525e36f444f2bd46b3c81eb7c -size 2860321 diff --git a/logs2/qemu-aarch64-20260611-174951.log b/logs2/qemu-aarch64-20260611-174951.log deleted file mode 100644 index db0d847f..00000000 --- a/logs2/qemu-aarch64-20260611-174951.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2600af8c22e63034d608813b31c8e26dfb591126f41f5024668b5ca53a5f815c -size 444849 diff --git a/logs2/qemu-aarch64-20260611-175257.log b/logs2/qemu-aarch64-20260611-175257.log deleted file mode 100644 index 69556556..00000000 --- a/logs2/qemu-aarch64-20260611-175257.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:548df876d4fd35678a1635f035134aabd50bfc4f94834c7f1954b32ca43ebd6a -size 444396 diff --git a/logs2/qemu-aarch64-20260611-190822.log b/logs2/qemu-aarch64-20260611-190822.log deleted file mode 100644 index db0f610d..00000000 --- a/logs2/qemu-aarch64-20260611-190822.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1e3a8fe80891d91d4969965414f9ac788d7a39bf85374f62f9c385f6f88e01d1 -size 24550579 diff --git a/logs2/qemu-aarch64-20260611-202955.log b/logs2/qemu-aarch64-20260611-202955.log deleted file mode 100644 index 56e2d5c1..00000000 --- a/logs2/qemu-aarch64-20260611-202955.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ec3b597aef2c9c692b9825ef822d77b61bad209aae74e9d4a730c5c012c392e -size 2860331 diff --git a/logs2/qemu-aarch64-20260612-132412.log b/logs2/qemu-aarch64-20260612-132412.log deleted file mode 100644 index 369178ef..00000000 --- a/logs2/qemu-aarch64-20260612-132412.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b7bcfd56a593b7dc7e94f1ee546ab482c2b7a0d6b0ef6031b52e2ab7591bdb9b -size 24547039 diff --git a/logs2/qemu-aarch64-20260612-141722.log b/logs2/qemu-aarch64-20260612-141722.log deleted file mode 100644 index dbebd8ea..00000000 --- a/logs2/qemu-aarch64-20260612-141722.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b049b883a58d66c646e20df02e5d931477901339ddf27c2d0d00ec73f62a0b48 -size 24571257 diff --git a/logs2/qemu-aarch64-20260612-160132.log b/logs2/qemu-aarch64-20260612-160132.log deleted file mode 100644 index 9d0e760c..00000000 --- a/logs2/qemu-aarch64-20260612-160132.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9c1543e8f781c0ffda150e68a473b436ef0611ae8ec0c3c57e838d82fbda99c5 -size 24557311 diff --git a/logs2/qemu-aarch64-20260614-164017.log b/logs2/qemu-aarch64-20260614-164017.log deleted file mode 100644 index c613be51..00000000 --- a/logs2/qemu-aarch64-20260614-164017.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9f0a5be56112b6e6ccdc6760c3e0cfff35a1575f76dbd8481b0943b38a1e3e5 -size 445798 diff --git a/logs2/qemu-aarch64-20260614-164043.log b/logs2/qemu-aarch64-20260614-164043.log deleted file mode 100644 index 7155bc6c..00000000 --- a/logs2/qemu-aarch64-20260614-164043.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:59c913bd5cafa83a930be572322946d54250f3e627ed3c7bb98479f0fbc073f7 -size 445830 diff --git a/logs2/qemu-aarch64-20260614-182154.log b/logs2/qemu-aarch64-20260614-182154.log deleted file mode 100644 index 5b14e80b..00000000 --- a/logs2/qemu-aarch64-20260614-182154.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:74fd6eab5924ba58deb1530223267a70316d651420709eeedbeae1ba5c09a780 -size 445940 diff --git a/logs2/qemu-aarch64-20260614-190109.log b/logs2/qemu-aarch64-20260614-190109.log deleted file mode 100644 index c3579842..00000000 --- a/logs2/qemu-aarch64-20260614-190109.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ec60bcb52390ce385697baa07c4188630be60227d606edf5f5df3281071443e1 -size 446081 diff --git a/logs2/qemu-aarch64-20260614-230803.log b/logs2/qemu-aarch64-20260614-230803.log deleted file mode 100644 index c02c03fd..00000000 --- a/logs2/qemu-aarch64-20260614-230803.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e785237ae55ff3327eb7f68aa262abada47614704f06be316c069d0b1a71da6b -size 24762825 diff --git a/logs2/qemu-aarch64-20260615-003908.log b/logs2/qemu-aarch64-20260615-003908.log deleted file mode 100644 index 0b81ce4f..00000000 --- a/logs2/qemu-aarch64-20260615-003908.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b00954cc3f39dcc4cdd8133baaa20f71e9b4a708138b41f2243a79e0c83759b4 -size 24791976 diff --git a/logs2/qemu-aarch64-20260615-005301.log b/logs2/qemu-aarch64-20260615-005301.log deleted file mode 100644 index 7c0dfa2b..00000000 --- a/logs2/qemu-aarch64-20260615-005301.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6fef1dd6edd20ac9f32396e449be401579be2165840d5a17df8763a880de1f78 -size 24810271 diff --git a/logs2/qemu-aarch64-20260615-020020.log b/logs2/qemu-aarch64-20260615-020020.log deleted file mode 100644 index 2f385fe3..00000000 --- a/logs2/qemu-aarch64-20260615-020020.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6809d86a1b7eae40c2c8ad42c10854e3e22ac96ccb2f8b50cc7d07da3d196ea1 -size 24798283 diff --git a/logs2/qemu-aarch64-20260615-103253.log b/logs2/qemu-aarch64-20260615-103253.log deleted file mode 100644 index b47ff0cb..00000000 --- a/logs2/qemu-aarch64-20260615-103253.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c79dd37830259c5988c36de5fc6d3cb0be96efe405b8bfb215685558aa69acd8 -size 446176 diff --git a/logs2/qemu-aarch64-20260615-103655.log b/logs2/qemu-aarch64-20260615-103655.log deleted file mode 100644 index 70cfd266..00000000 --- a/logs2/qemu-aarch64-20260615-103655.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8d752ffb4307e3b822788f64f55ce959a72de251ab0a8a35870ee32b47ce5402 -size 446096 diff --git a/logs2/qemu-aarch64-20260615-121103.log b/logs2/qemu-aarch64-20260615-121103.log deleted file mode 100644 index 7d342f68..00000000 --- a/logs2/qemu-aarch64-20260615-121103.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9398bee6c2494a07c23d1250814427236cbfe72881cf79387f1360b5105d2f97 -size 39524558 diff --git a/logs2/qemu-aarch64-20260615-123814.log b/logs2/qemu-aarch64-20260615-123814.log deleted file mode 100644 index 551b18a5..00000000 --- a/logs2/qemu-aarch64-20260615-123814.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b69188e7704e3f2dda83ae30f72220aa3b6edb6940c26e5d9f901263bfa3e859 -size 40407590 diff --git a/logs2/qemu-aarch64-20260615-160204.log b/logs2/qemu-aarch64-20260615-160204.log deleted file mode 100644 index 7a3317e0..00000000 --- a/logs2/qemu-aarch64-20260615-160204.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8702707f3ff9558294139bbeeee25e1a1993c2cafdecaa81b8c621611af5e0aa -size 40382353 diff --git a/logs2/qemu-aarch64-20260615-183010.log b/logs2/qemu-aarch64-20260615-183010.log deleted file mode 100644 index 311e1b25..00000000 --- a/logs2/qemu-aarch64-20260615-183010.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af8042f75f58308aeefcaaeac464b0b571b27b6ba559923fd2df35693e76e37a -size 445915 diff --git a/logs2/qemu-aarch64-20260615-192747.log b/logs2/qemu-aarch64-20260615-192747.log deleted file mode 100644 index 45d7e8dc..00000000 --- a/logs2/qemu-aarch64-20260615-192747.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a62df6904fff8e5a31790475d2121d91cf09ae1483122a9b237dde6ad6f0d8e9 -size 25720612 diff --git a/logs2/qemu-aarch64-20260615-194133.log b/logs2/qemu-aarch64-20260615-194133.log deleted file mode 100644 index e0d37b7a..00000000 --- a/logs2/qemu-aarch64-20260615-194133.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c9e78c199ae0dc052016a86c4478e7194d7ed2a26a400de58e37812fc300c7ca -size 25728577 diff --git a/logs2/qemu-aarch64-20260615-204232.log b/logs2/qemu-aarch64-20260615-204232.log deleted file mode 100644 index d81bd935..00000000 --- a/logs2/qemu-aarch64-20260615-204232.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a97c07ff0ad676c5d59b9b724ea6f3be785fec5167f06950be5107a2b47391bf -size 25730370 diff --git a/logs2/qemu-aarch64-20260615-223549.log b/logs2/qemu-aarch64-20260615-223549.log deleted file mode 100644 index 86841a74..00000000 --- a/logs2/qemu-aarch64-20260615-223549.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f10800135a26e0131326a9831d55315ad39ef194d912e4ce046d1519f9dd7fcb -size 446759 diff --git a/logs2/qemu-aarch64-20260615-235720.log b/logs2/qemu-aarch64-20260615-235720.log deleted file mode 100644 index 1109cfa0..00000000 --- a/logs2/qemu-aarch64-20260615-235720.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4df71446c9efe65f799d14f42672542570cd5f305e2b212fde2693e0347e1509 -size 24826180 diff --git a/logs2/qemu-aarch64-20260616-000920.log b/logs2/qemu-aarch64-20260616-000920.log deleted file mode 100644 index 4ea3f40b..00000000 --- a/logs2/qemu-aarch64-20260616-000920.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3e93a8ca1550f57abc3f7622bef06944de1c10fece7671a58a64d6086f86885b -size 24826961 diff --git a/logs2/qemu-aarch64-20260616-011049.log b/logs2/qemu-aarch64-20260616-011049.log deleted file mode 100644 index d96286e9..00000000 --- a/logs2/qemu-aarch64-20260616-011049.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:27a0cf152b499f395d50627028ea0e7d4d1a8a79a14794d46952c0eed7bcbd52 -size 24818835 diff --git a/logs2/qemu-aarch64-20260616-112907.log b/logs2/qemu-aarch64-20260616-112907.log deleted file mode 100644 index de788d20..00000000 --- a/logs2/qemu-aarch64-20260616-112907.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba61d2da7c79df29001522ad883f89013c4ee6fd2456f6aadacb44be1b95c022 -size 2861725 diff --git a/logs2/qemu-aarch64-20260616-155223.log b/logs2/qemu-aarch64-20260616-155223.log deleted file mode 100644 index e93447d2..00000000 --- a/logs2/qemu-aarch64-20260616-155223.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c3e133f3d8863c737ed9a9122c5dec2d5b0550795fa364646801c60d44e5588d -size 2861637 diff --git a/logs2/qemu-aarch64-20260616-175845.log b/logs2/qemu-aarch64-20260616-175845.log deleted file mode 100644 index 29bd15a6..00000000 --- a/logs2/qemu-aarch64-20260616-175845.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3fade9151f59cbd3268d1ce00f2e82dfb8e593b42000f95a5ce854a92d954f4f -size 446777 diff --git a/logs2/qemu-aarch64-20260620-222449.log b/logs2/qemu-aarch64-20260620-222449.log deleted file mode 100644 index f0931a54..00000000 --- a/logs2/qemu-aarch64-20260620-222449.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:33a2129c7b81183f63e83709fedfabb6918611e3c6af7cc5315da0ab8af952e0 -size 446938 diff --git a/logs2/qemu-aarch64-20260621-004736.log b/logs2/qemu-aarch64-20260621-004736.log deleted file mode 100644 index 8417c1d8..00000000 --- a/logs2/qemu-aarch64-20260621-004736.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3cb60e03b9837f6f4301668c98abf9ec5b6c87d953531e4bdd3a92913d892599 -size 455373 diff --git a/logs2/qemu-amd64-20260609-184750.log b/logs2/qemu-amd64-20260609-184750.log deleted file mode 100644 index 395e0868..00000000 --- a/logs2/qemu-amd64-20260609-184750.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:de8b3b76a479fdd3b80d8e678b3ffeacfbee6bceba39458889c7a59ef83d496d -size 124750043 diff --git a/logs2/qemu-amd64-20260609-193717.log b/logs2/qemu-amd64-20260609-193717.log deleted file mode 100644 index 49eac741..00000000 --- a/logs2/qemu-amd64-20260609-193717.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:264da04e9961b71db4ec4f41a6142b7a91dbe652c5a77b363a4b5ba42c9444f4 -size 452546 diff --git a/logs2/qemu-amd64-20260611-002301.log b/logs2/qemu-amd64-20260611-002301.log deleted file mode 100644 index fcf1c42a..00000000 --- a/logs2/qemu-amd64-20260611-002301.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:700b82c28e7871cc91e2dcaff02bfc8f9067671293e4d56c20e7eefa18fb0c15 -size 459031 diff --git a/logs2/qemu-amd64-20260611-012412.log b/logs2/qemu-amd64-20260611-012412.log deleted file mode 100644 index 2dd16200..00000000 --- a/logs2/qemu-amd64-20260611-012412.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7a0aacf2887944ca026af06807220dc950c8d451bbd1c3a3d315e6a062e29558 -size 25304213 diff --git a/logs2/qemu-amd64-20260611-013401.log b/logs2/qemu-amd64-20260611-013401.log deleted file mode 100644 index a54d891d..00000000 --- a/logs2/qemu-amd64-20260611-013401.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cc7c9205fb2fcba2a3d4b7816189e092234c6becf5061962fe8e1ce777dd1da9 -size 51847478 diff --git a/logs2/qemu-amd64-20260611-023023.log b/logs2/qemu-amd64-20260611-023023.log deleted file mode 100644 index dfe07389..00000000 --- a/logs2/qemu-amd64-20260611-023023.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:36ad81e9c25263496226870600ec7045a634709bfe34d559fa19c2bfa79af1f9 -size 1229048 diff --git a/logs2/qemu-amd64-20260611-023818.log b/logs2/qemu-amd64-20260611-023818.log deleted file mode 100644 index e33dfe25..00000000 --- a/logs2/qemu-amd64-20260611-023818.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c6c8f18746be9320b887e647aa718665b93cdabc7a83cbcd1e4f5652e36ea51c -size 5437912 diff --git a/logs2/qemu-amd64-20260611-172713.log b/logs2/qemu-amd64-20260611-172713.log deleted file mode 100644 index 657bfaa9..00000000 --- a/logs2/qemu-amd64-20260611-172713.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bb922c9a54f2652ce1a583e77094458e60c65b6df3b30ef478f3ea371be1835a -size 2986532 diff --git a/logs2/qemu-amd64-20260611-174904.log b/logs2/qemu-amd64-20260611-174904.log deleted file mode 100644 index 8eb20203..00000000 --- a/logs2/qemu-amd64-20260611-174904.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea16d957689e30ecff83b93f8596d1b87e784fd735971db3ef84ce7f14eb0b4c -size 452793 diff --git a/logs2/qemu-amd64-20260611-175217.log b/logs2/qemu-amd64-20260611-175217.log deleted file mode 100644 index 4836f432..00000000 --- a/logs2/qemu-amd64-20260611-175217.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6cbf185529b069e76b4a803facc6d7f8c7ed86426d0687d893253434186d76a -size 452229 diff --git a/logs2/qemu-amd64-20260611-180750.log b/logs2/qemu-amd64-20260611-180750.log deleted file mode 100644 index 6ad85163..00000000 --- a/logs2/qemu-amd64-20260611-180750.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:026efae6d5ee2af7ff980b45aae7a7b01ac8ef65aee9da7e5c4c44cd904e48d9 -size 16809778 diff --git a/logs2/qemu-amd64-20260611-192015.log b/logs2/qemu-amd64-20260611-192015.log deleted file mode 100644 index 70ce7925..00000000 --- a/logs2/qemu-amd64-20260611-192015.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b4ca1094d0b8b819711a348159ea1a222192972985780b432f3ab235c8008cd2 -size 15873920 diff --git a/logs2/qemu-amd64-20260611-201951.log b/logs2/qemu-amd64-20260611-201951.log deleted file mode 100644 index 28de5f03..00000000 --- a/logs2/qemu-amd64-20260611-201951.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8b9481705be52280fa8bd2462de213c82813f0898e04944b51856ed6d7f1fc20 -size 2990826 diff --git a/logs2/qemu-amd64-20260611-204126.log b/logs2/qemu-amd64-20260611-204126.log deleted file mode 100644 index bf608125..00000000 --- a/logs2/qemu-amd64-20260611-204126.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:600a1199e2c4d87ff564082bdcbbb2a2e34a54c6d1bfc4e2656ae42dfb3937c6 -size 16994750 diff --git a/logs2/qemu-amd64-20260611-223613.log b/logs2/qemu-amd64-20260611-223613.log deleted file mode 100644 index 47e14582..00000000 --- a/logs2/qemu-amd64-20260611-223613.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:53fd8da927e76fbc0c15b0596bab99a09f7e301e5f057428020c3a11dad67972 -size 24296628 diff --git a/logs2/qemu-amd64-20260612-110212.log b/logs2/qemu-amd64-20260612-110212.log deleted file mode 100644 index 4594ee43..00000000 --- a/logs2/qemu-amd64-20260612-110212.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:58d2f47e95d24705ddef7fea8c8ea34b522141e60b0a4c029d88d5a982654247 -size 26655843 diff --git a/logs2/qemu-amd64-20260612-142323.log b/logs2/qemu-amd64-20260612-142323.log deleted file mode 100644 index 6db15b98..00000000 --- a/logs2/qemu-amd64-20260612-142323.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:76a6a7af9c49d54a4ff812ff4cbd0d61ccd3d9444d093d4e23474669b9002082 -size 26814590 diff --git a/logs2/qemu-amd64-20260612-160656.log b/logs2/qemu-amd64-20260612-160656.log deleted file mode 100644 index d4c37437..00000000 --- a/logs2/qemu-amd64-20260612-160656.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:11f3c49d85895d547add1cd1a465479103b82d46bee48784e0f11ea7126fb167 -size 26787619 diff --git a/logs2/qemu-amd64-20260614-163853.log b/logs2/qemu-amd64-20260614-163853.log deleted file mode 100644 index a2f3714a..00000000 --- a/logs2/qemu-amd64-20260614-163853.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:79768405c5684fdbe3a37a0a20d10455f9a71689b2de19747bfc2a4e2f96ecdc -size 452449 diff --git a/logs2/qemu-amd64-20260614-182034.log b/logs2/qemu-amd64-20260614-182034.log deleted file mode 100644 index f7033f5d..00000000 --- a/logs2/qemu-amd64-20260614-182034.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:91ab796a2962f55f083225ec016df2d993a157f4c7ffdff0297e8fdca96f44dc -size 454035 diff --git a/logs2/qemu-amd64-20260614-182119.log b/logs2/qemu-amd64-20260614-182119.log deleted file mode 100644 index 1601438f..00000000 --- a/logs2/qemu-amd64-20260614-182119.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d575a3d5e65e08e83dd9ffafe823afbe6461397944c87fe550d0894639428e24 -size 454035 diff --git a/logs2/qemu-amd64-20260614-183302.log b/logs2/qemu-amd64-20260614-183302.log deleted file mode 100644 index f0638900..00000000 --- a/logs2/qemu-amd64-20260614-183302.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:28b0858d6ff05c8c7e3f43bac46abc1c999e89d341ab81cc54a8995be8731b5b -size 454084 diff --git a/logs2/qemu-amd64-20260614-185942.log b/logs2/qemu-amd64-20260614-185942.log deleted file mode 100644 index 9d69ae2e..00000000 --- a/logs2/qemu-amd64-20260614-185942.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f528c79f5107275bd0e1a4e4d7dfbea814e12d52ad1c664e596bde47f99df11 -size 454111 diff --git a/logs2/qemu-amd64-20260614-190244.log b/logs2/qemu-amd64-20260614-190244.log deleted file mode 100644 index ee25f576..00000000 --- a/logs2/qemu-amd64-20260614-190244.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d703df3557bdd25026e54230a3d91e47849001f78331b09754e00eecd8b132c8 -size 454093 diff --git a/logs2/qemu-amd64-20260614-212929.log b/logs2/qemu-amd64-20260614-212929.log deleted file mode 100644 index 83deedb1..00000000 --- a/logs2/qemu-amd64-20260614-212929.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d3d625ea9b5712bb569182f6e69be834d944ddc4c337d160a948131c8be94ba8 -size 26750601 diff --git a/logs2/qemu-amd64-20260614-233623.log b/logs2/qemu-amd64-20260614-233623.log deleted file mode 100644 index 727f18bf..00000000 --- a/logs2/qemu-amd64-20260614-233623.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c64cef6aa7612c046f55596d4303cd93f52def9b229c1978db686eb3ac0c68a6 -size 26653964 diff --git a/logs2/qemu-amd64-20260615-005725.log b/logs2/qemu-amd64-20260615-005725.log deleted file mode 100644 index dfe9b396..00000000 --- a/logs2/qemu-amd64-20260615-005725.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:535c12b23a1d1f555475283784ee3a80442379752c946ebe391e8e179aa18a6b -size 26678736 diff --git a/logs2/qemu-amd64-20260615-020446.log b/logs2/qemu-amd64-20260615-020446.log deleted file mode 100644 index b99dbe33..00000000 --- a/logs2/qemu-amd64-20260615-020446.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:951797fcd00093a2ff1f9aaff10cacbb0697d83ad33bdd4052aa59b716b2d8f7 -size 26669147 diff --git a/logs2/qemu-amd64-20260615-103154.log b/logs2/qemu-amd64-20260615-103154.log deleted file mode 100644 index 8bce7da7..00000000 --- a/logs2/qemu-amd64-20260615-103154.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:36244198d4ea8df9153d36bf317aa460b9891a1a8f23a112c04e3a96596cc419 -size 454240 diff --git a/logs2/qemu-amd64-20260615-103619.log b/logs2/qemu-amd64-20260615-103619.log deleted file mode 100644 index 34078166..00000000 --- a/logs2/qemu-amd64-20260615-103619.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c0b7c167eed3efb9c6eddd434dbf34f42599c62c2229af469ad6c1841b293f7 -size 453990 diff --git a/logs2/qemu-amd64-20260615-103843.log b/logs2/qemu-amd64-20260615-103843.log deleted file mode 100644 index cfe6e37f..00000000 --- a/logs2/qemu-amd64-20260615-103843.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:391f8438be7e7d8db94a27aa2206c508310ec96c6d8c445f218ea8bcae2cf026 -size 26759728 diff --git a/logs2/qemu-amd64-20260615-124956.log b/logs2/qemu-amd64-20260615-124956.log deleted file mode 100644 index 9dcdaa58..00000000 --- a/logs2/qemu-amd64-20260615-124956.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e5d57b7581a046460ad6f7916b572f88e908f9f255a9736f7ef64243ceea8d8b -size 1310694 diff --git a/logs2/qemu-amd64-20260615-125017.log b/logs2/qemu-amd64-20260615-125017.log deleted file mode 100644 index b4176e99..00000000 --- a/logs2/qemu-amd64-20260615-125017.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:862d1ae1c84781c78ccd637761c22065a9277d104b3e48a1de18dc648f29b2e8 -size 1220938 diff --git a/logs2/qemu-amd64-20260615-125335.log b/logs2/qemu-amd64-20260615-125335.log deleted file mode 100644 index 1f089ad3..00000000 --- a/logs2/qemu-amd64-20260615-125335.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6206230729075784373806c4e194ae45c46af6dbef4807f1603b40c91d7fd962 -size 26459082 diff --git a/logs2/qemu-amd64-20260615-142839.log b/logs2/qemu-amd64-20260615-142839.log deleted file mode 100644 index 6fa32cc6..00000000 --- a/logs2/qemu-amd64-20260615-142839.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7cdd0225e3eb4516a7cba323664b95aff5f00bb070d207e3e4dc3cffa1fd441b -size 26804029 diff --git a/logs2/qemu-amd64-20260615-161023.log b/logs2/qemu-amd64-20260615-161023.log deleted file mode 100644 index 492cc9bd..00000000 --- a/logs2/qemu-amd64-20260615-161023.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0cd6e72e44a976d342e13c7b20c84a9a25386a29e2ede68facdf1facc5d45b8c -size 26781098 diff --git a/logs2/qemu-amd64-20260615-180252.log b/logs2/qemu-amd64-20260615-180252.log deleted file mode 100644 index 293121b9..00000000 --- a/logs2/qemu-amd64-20260615-180252.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3f60516570b2de42393232c7129e0db94bd02985109b9cff0315c34a5ab8c1f0 -size 1155561 diff --git a/logs2/qemu-amd64-20260615-182339.log b/logs2/qemu-amd64-20260615-182339.log deleted file mode 100644 index e8bde4e7..00000000 --- a/logs2/qemu-amd64-20260615-182339.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:04957e8778b0b4160143b83865d21cfc79e0a8d9b97095fb040b1a93a18e68e5 -size 2977576 diff --git a/logs2/qemu-amd64-20260615-182946.log b/logs2/qemu-amd64-20260615-182946.log deleted file mode 100644 index 0e0ee3c8..00000000 --- a/logs2/qemu-amd64-20260615-182946.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:39b1c2e88bba99a54b4473eeb1c24281cadea9376a03f575f76386d541bf1dba -size 138597 diff --git a/logs2/qemu-amd64-20260615-183023.log b/logs2/qemu-amd64-20260615-183023.log deleted file mode 100644 index a2ad21ec..00000000 --- a/logs2/qemu-amd64-20260615-183023.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:28de2fff2c4e0103afa17e382b11c09587de7634766887f9bd2fb1cbbc1f24b2 -size 26627477 diff --git a/logs2/qemu-amd64-20260615-194545.log b/logs2/qemu-amd64-20260615-194545.log deleted file mode 100644 index 710af523..00000000 --- a/logs2/qemu-amd64-20260615-194545.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0ae003125d32ae45ace427117fc72799ca3265e38e22a4bb87c500aba471bddc -size 26619977 diff --git a/logs2/qemu-amd64-20260615-204632.log b/logs2/qemu-amd64-20260615-204632.log deleted file mode 100644 index d23880c1..00000000 --- a/logs2/qemu-amd64-20260615-204632.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a2315ce9165ed63d041be4f69fbfad30ed01bddc156ef34ee8ffac498a21291b -size 26624536 diff --git a/logs2/qemu-amd64-20260615-223531.log b/logs2/qemu-amd64-20260615-223531.log deleted file mode 100644 index e69de29b..00000000 diff --git a/logs2/qemu-amd64-20260615-223607.log b/logs2/qemu-amd64-20260615-223607.log deleted file mode 100644 index 35ff0116..00000000 --- a/logs2/qemu-amd64-20260615-223607.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:74ce1bcfe28e9f9a7dc2b4f2059822b646d668eb87ed8a603eff66c08c888c69 -size 6149285 diff --git a/logs2/qemu-amd64-20260615-230419.log b/logs2/qemu-amd64-20260615-230419.log deleted file mode 100644 index d3e06b9b..00000000 --- a/logs2/qemu-amd64-20260615-230419.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:975395f039c9cf72a8e4345f52eb4ad1b460f12ac9e590aa18a4b28c86f2a1d3 -size 26585196 diff --git a/logs2/qemu-amd64-20260616-001614.log b/logs2/qemu-amd64-20260616-001614.log deleted file mode 100644 index d85fec71..00000000 --- a/logs2/qemu-amd64-20260616-001614.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdca033d07fb2060c65d6b5fee3d6f0d561be8851a23aa269f574915a599b73a -size 26589065 diff --git a/logs2/qemu-amd64-20260616-011447.log b/logs2/qemu-amd64-20260616-011447.log deleted file mode 100644 index fa1b717f..00000000 --- a/logs2/qemu-amd64-20260616-011447.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8663beb8f2d885ff9230f7a33acd87bec353bc8ab9aae0d6cf9024eec4aba54f -size 26594760 diff --git a/logs2/qemu-amd64-20260616-111913.log b/logs2/qemu-amd64-20260616-111913.log deleted file mode 100644 index a2bb3131..00000000 --- a/logs2/qemu-amd64-20260616-111913.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:54e64439fc6838e884e5963c225eaf596e1ef297e4b1e915e0aac0e569269de7 -size 2989365 diff --git a/logs2/qemu-amd64-20260616-154608.log b/logs2/qemu-amd64-20260616-154608.log deleted file mode 100644 index 95c95fa6..00000000 --- a/logs2/qemu-amd64-20260616-154608.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a925f3e693496963a135dd0a26bff73f96b9d52748b7789e1163291ba3d20f61 -size 2979714 diff --git a/logs2/qemu-amd64-20260616-175829.log b/logs2/qemu-amd64-20260616-175829.log deleted file mode 100644 index 6045e214..00000000 --- a/logs2/qemu-amd64-20260616-175829.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:748ec87f38fe3ee754e56f64c2d35d1a1fa52fe9c7363a260431765117c60fc8 -size 454128 diff --git a/logs2/qemu-amd64-20260620-222036.log b/logs2/qemu-amd64-20260620-222036.log deleted file mode 100644 index 7d0d760e..00000000 --- a/logs2/qemu-amd64-20260620-222036.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f2d88a222232a42b27d41bef5852ac44351f2a076625b495a2b6c747edda11e7 -size 454888 diff --git a/logs2/qemu-amd64-20260621-002830.log b/logs2/qemu-amd64-20260621-002830.log deleted file mode 100644 index 4cd23e23..00000000 --- a/logs2/qemu-amd64-20260621-002830.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b48635e970f3d19331d075386cd793bbc2069cd073ed962d272970cb1fd290c6 -size 463427 diff --git a/logs2/qemu-amd64-20260621-004710.log b/logs2/qemu-amd64-20260621-004710.log deleted file mode 100644 index f385ef3d..00000000 --- a/logs2/qemu-amd64-20260621-004710.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:60a9c348ace7155d195ad47acabbbfc314fc20b2a353435423f7f0bedc79cd87 -size 463389 diff --git a/logs2/qemu-riscv64-20260609-192223.log b/logs2/qemu-riscv64-20260609-192223.log deleted file mode 100644 index f3f5113a..00000000 --- a/logs2/qemu-riscv64-20260609-192223.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:13265fd92a595a4ecf253c4bb6461d5ae284b31c6565e6d9053d85f38a110082 -size 454533 diff --git a/logs2/qemu-riscv64-20260611-002548.log b/logs2/qemu-riscv64-20260611-002548.log deleted file mode 100644 index 81ed5b7e..00000000 --- a/logs2/qemu-riscv64-20260611-002548.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c3a24074ce39f43c81052c2ce1cddf0794d8ceec07b3195cd96acad9b6d5a7d7 -size 3656 diff --git a/logs2/qemu-riscv64-20260611-003502.log b/logs2/qemu-riscv64-20260611-003502.log deleted file mode 100644 index 5c4fa2a2..00000000 --- a/logs2/qemu-riscv64-20260611-003502.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1982b748e57fe8c302c83fe804e55e6437e505e748405e5c7d32cb7b710b4c3e -size 3656 diff --git a/logs2/qemu-riscv64-20260611-003801.log b/logs2/qemu-riscv64-20260611-003801.log deleted file mode 100644 index 276d9df0..00000000 --- a/logs2/qemu-riscv64-20260611-003801.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5d39b719c48058e3d903bc92d121ac446772f177d05bdbf3a9bfa519e30da119 -size 461796 diff --git a/logs2/qemu-riscv64-20260611-024624.log b/logs2/qemu-riscv64-20260611-024624.log deleted file mode 100644 index e1099f32..00000000 --- a/logs2/qemu-riscv64-20260611-024624.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3a8ad9c1bb22efb837c9a7b9646832a688cca6710177155f3ee7a8f4c96699ea -size 5246437 diff --git a/logs2/qemu-riscv64-20260611-173903.log b/logs2/qemu-riscv64-20260611-173903.log deleted file mode 100644 index 19d4411f..00000000 --- a/logs2/qemu-riscv64-20260611-173903.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6e3bbd31797d0b4ad4f22622f4c15c9b2e4f2a0b68841b540a775d0ac1d6ea8d -size 2869662 diff --git a/logs2/qemu-riscv64-20260611-175348.log b/logs2/qemu-riscv64-20260611-175348.log deleted file mode 100644 index 472e8a1a..00000000 --- a/logs2/qemu-riscv64-20260611-175348.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b6379b501b237f23888354d49f01775a6361162af5c6cc3252a721ac4a1db1c4 -size 453754 diff --git a/logs2/qemu-riscv64-20260611-191335.log b/logs2/qemu-riscv64-20260611-191335.log deleted file mode 100644 index be5a74fb..00000000 --- a/logs2/qemu-riscv64-20260611-191335.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:424044bf92ab72748724fe3432e7cf09720cf64834dc0c9d4502b9daf0b18fd5 -size 24461243 diff --git a/logs2/qemu-riscv64-20260611-203104.log b/logs2/qemu-riscv64-20260611-203104.log deleted file mode 100644 index f39af689..00000000 --- a/logs2/qemu-riscv64-20260611-203104.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bdc8f152b9c1216ebfc5aaa3bddeefe53462485de887ba2bbc0109554905e0af -size 2869665 diff --git a/logs2/qemu-riscv64-20260612-135612.log b/logs2/qemu-riscv64-20260612-135612.log deleted file mode 100644 index 12487e24..00000000 --- a/logs2/qemu-riscv64-20260612-135612.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6ba3e43f91ef13cbafe6d288930d2e7a9d1a065421403f6b12ed50ec9fbf489 -size 24461719 diff --git a/logs2/qemu-riscv64-20260612-141129.log b/logs2/qemu-riscv64-20260612-141129.log deleted file mode 100644 index 06ced14b..00000000 --- a/logs2/qemu-riscv64-20260612-141129.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fedc2623db6780b04521c478657f700f7eb6d5d2d46d86d718f602bbc8ba98d9 -size 24487550 diff --git a/logs2/qemu-riscv64-20260612-174414.log b/logs2/qemu-riscv64-20260612-174414.log deleted file mode 100644 index be3f2930..00000000 --- a/logs2/qemu-riscv64-20260612-174414.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:672ec58e1c3395a7c2ecd3324ff3772699b6423737576e37ce9fa651b6cb10cc -size 24470192 diff --git a/logs2/qemu-riscv64-20260614-164140.log b/logs2/qemu-riscv64-20260614-164140.log deleted file mode 100644 index 1f4d81c6..00000000 --- a/logs2/qemu-riscv64-20260614-164140.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:68de4275e8a5d79d049870690cb6ae80872a619176a724ff26189d27e2e43951 -size 3478 diff --git a/logs2/qemu-riscv64-20260614-165900.log b/logs2/qemu-riscv64-20260614-165900.log deleted file mode 100644 index ea6c6cf0..00000000 --- a/logs2/qemu-riscv64-20260614-165900.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8e09f737f70ee5d08d85c4548cef334215b30c31d1b51938913eaa1737414a70 -size 3484 diff --git a/logs2/qemu-riscv64-20260614-170926.log b/logs2/qemu-riscv64-20260614-170926.log deleted file mode 100644 index c5aca9dd..00000000 --- a/logs2/qemu-riscv64-20260614-170926.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7bda12cfc05493e20f42ebba91e207d0ae1ae8190035f352617ebd59ac127f3f -size 4746 diff --git a/logs2/qemu-riscv64-20260614-171955.log b/logs2/qemu-riscv64-20260614-171955.log deleted file mode 100644 index 8de4f3ef..00000000 --- a/logs2/qemu-riscv64-20260614-171955.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a16185d8e5cdcb302637af85b6c8a66d73cbd7c8f983aba88cb73981957d02a0 -size 454514 diff --git a/logs2/qemu-riscv64-20260614-182235.log b/logs2/qemu-riscv64-20260614-182235.log deleted file mode 100644 index fa8d972a..00000000 --- a/logs2/qemu-riscv64-20260614-182235.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e545d0827cff65a7f125590a27583a163f248b484b0a333d3015cdd826db0b5f -size 455326 diff --git a/logs2/qemu-riscv64-20260614-190152.log b/logs2/qemu-riscv64-20260614-190152.log deleted file mode 100644 index 1cfdb783..00000000 --- a/logs2/qemu-riscv64-20260614-190152.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94f39f57529b464ae62455f9df5d204b2fcb2a4b0f72efbd5b77d3d05681c064 -size 455396 diff --git a/logs2/qemu-riscv64-20260614-230220.log b/logs2/qemu-riscv64-20260614-230220.log deleted file mode 100644 index 308170f4..00000000 --- a/logs2/qemu-riscv64-20260614-230220.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a9252d099af5aae9ba861e96f4e28b52ed6acf1b36714883f5dc4b721084a3d4 -size 24721249 diff --git a/logs2/qemu-riscv64-20260615-004335.log b/logs2/qemu-riscv64-20260615-004335.log deleted file mode 100644 index 01f0508d..00000000 --- a/logs2/qemu-riscv64-20260615-004335.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3e266bf0ab69591c30071e90b59eb4f2394e7c75c54897a2ac78e4b1a78610cc -size 24715944 diff --git a/logs2/qemu-riscv64-20260615-004822.log b/logs2/qemu-riscv64-20260615-004822.log deleted file mode 100644 index 0ad56fcc..00000000 --- a/logs2/qemu-riscv64-20260615-004822.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:afa30fafd39d23078b484fd0a876e706307800c7e894a8e466595a1d58f856bd -size 24742087 diff --git a/logs2/qemu-riscv64-20260615-031059.log b/logs2/qemu-riscv64-20260615-031059.log deleted file mode 100644 index 209a8aaa..00000000 --- a/logs2/qemu-riscv64-20260615-031059.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b54e988ed8fff287a1ea4f2f6390a8ddf9bf1f08c7cb4a2f690d13a3039fc66b -size 24726338 diff --git a/logs2/qemu-riscv64-20260615-103741.log b/logs2/qemu-riscv64-20260615-103741.log deleted file mode 100644 index c199af61..00000000 --- a/logs2/qemu-riscv64-20260615-103741.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:889f022a9a9b4f835d8b1cb3b9a31aaf63982f43e871b569fec347a61ceea121 -size 455449 diff --git a/logs2/qemu-riscv64-20260615-122026.log b/logs2/qemu-riscv64-20260615-122026.log deleted file mode 100644 index 23990740..00000000 --- a/logs2/qemu-riscv64-20260615-122026.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba68fb8c137c5db04ee89d8355a18dbccaf6cc533fc65f558ad339194aa2c69d -size 40469576 diff --git a/logs2/qemu-riscv64-20260615-122930.log b/logs2/qemu-riscv64-20260615-122930.log deleted file mode 100644 index d21ea928..00000000 --- a/logs2/qemu-riscv64-20260615-122930.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8cdaafbdc7baae96e6cc5e6f8f0522ee4dbef2a02692c6c3fc88bf276290bbf1 -size 40707313 diff --git a/logs2/qemu-riscv64-20260615-174420.log b/logs2/qemu-riscv64-20260615-174420.log deleted file mode 100644 index 3e92765a..00000000 --- a/logs2/qemu-riscv64-20260615-174420.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d8de0e7cfbdbe9f1b764778019095962bdb83961c18da79ec77c4bd12fce9f67 -size 40970797 diff --git a/logs2/qemu-riscv64-20260615-183017.log b/logs2/qemu-riscv64-20260615-183017.log deleted file mode 100644 index 35eadadf..00000000 --- a/logs2/qemu-riscv64-20260615-183017.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f7093abe9e9ebca406ca4ee0f13ab0c44c1aab6dd362162422c450c934866dd3 -size 454565 diff --git a/logs2/qemu-riscv64-20260615-193223.log b/logs2/qemu-riscv64-20260615-193223.log deleted file mode 100644 index 58e23cf5..00000000 --- a/logs2/qemu-riscv64-20260615-193223.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ab2d39c04e76e34ad66606adfb5cba94edad5f4268fe221f4186e02e90cf4b9 -size 25739252 diff --git a/logs2/qemu-riscv64-20260615-193711.log b/logs2/qemu-riscv64-20260615-193711.log deleted file mode 100644 index 8b2add39..00000000 --- a/logs2/qemu-riscv64-20260615-193711.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9a92d3d9d1dea81945339edfde95ea96fafd671adee5aff4fdcc5780956dc694 -size 25753142 diff --git a/logs2/qemu-riscv64-20260615-214335.log b/logs2/qemu-riscv64-20260615-214335.log deleted file mode 100644 index 544abeca..00000000 --- a/logs2/qemu-riscv64-20260615-214335.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f3fb8b4c9e3cd3d4c93c9a8edd5ff127f8c493bdc399f8daa90df213e62af36e -size 25766622 diff --git a/logs2/qemu-riscv64-20260615-223550.log b/logs2/qemu-riscv64-20260615-223550.log deleted file mode 100644 index 4273f514..00000000 --- a/logs2/qemu-riscv64-20260615-223550.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f12ca988cc5b7df213b9bc36d1ced1a3b972f26b6a6e5cb8c09ac585494a6727 -size 456148 diff --git a/logs2/qemu-riscv64-20260616-000114.log b/logs2/qemu-riscv64-20260616-000114.log deleted file mode 100644 index c8514038..00000000 --- a/logs2/qemu-riscv64-20260616-000114.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:583e5a555c3c47d551b5c310cd0efe7156b8510d40c6144da379a60f7b42adf0 -size 24732863 diff --git a/logs2/qemu-riscv64-20260616-000522.log b/logs2/qemu-riscv64-20260616-000522.log deleted file mode 100644 index 56e055d7..00000000 --- a/logs2/qemu-riscv64-20260616-000522.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:20003eacea2508d339b62eb1283943212bc1053424e2ccaea9cb6c7fde94bd9c -size 24740552 diff --git a/logs2/qemu-riscv64-20260616-021123.log b/logs2/qemu-riscv64-20260616-021123.log deleted file mode 100644 index 49c2f30f..00000000 --- a/logs2/qemu-riscv64-20260616-021123.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:22833409d3f85b78bfdd04dabff0178009ebdefea664c021c91940035fa5fe6f -size 24738045 diff --git a/logs2/qemu-riscv64-20260616-113103.log b/logs2/qemu-riscv64-20260616-113103.log deleted file mode 100644 index 0acf79db..00000000 --- a/logs2/qemu-riscv64-20260616-113103.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d8afb3224c857e35b36a733406c5582f0725b274d767e5c0755cd4a2d15e0a3c -size 2871138 diff --git a/logs2/qemu-riscv64-20260616-155324.log b/logs2/qemu-riscv64-20260616-155324.log deleted file mode 100644 index 35f42dad..00000000 --- a/logs2/qemu-riscv64-20260616-155324.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ea73709d6cb5d9dd2c6917832a0f584a71a97aae402706a1d2ca542c3a3cc13 -size 2870243 diff --git a/logs2/qemu-riscv64-20260616-175915.log b/logs2/qemu-riscv64-20260616-175915.log deleted file mode 100644 index 57df4bc8..00000000 --- a/logs2/qemu-riscv64-20260616-175915.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d9b5fcaf0a7fc241170023df5cf64052b569eb43848b262d3fe3446925b6728 -size 456125 diff --git a/logs2/qemu-riscv64-20260620-231806.log b/logs2/qemu-riscv64-20260620-231806.log deleted file mode 100644 index e56f120b..00000000 --- a/logs2/qemu-riscv64-20260620-231806.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a5d8473c973399578f544e0570190d1ecf4b168a71ed9825338f071059d02334 -size 456336 diff --git a/logs2/qemu-riscv64-20260621-004843.log b/logs2/qemu-riscv64-20260621-004843.log deleted file mode 100644 index 57c4b485..00000000 --- a/logs2/qemu-riscv64-20260621-004843.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8094140433a197527fe5c462cb5d386f04d3acef87a1e690d8faf93b433ec45b -size 464944 diff --git a/logs2/qemu-screenshot-20260609-105458.png b/logs2/qemu-screenshot-20260609-105458.png deleted file mode 100644 index 47ebf0990c526825f7eb6df013bbd7d910b247af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmds1{a4a=6#jsjrdda6x>=LjPS(=YR$}7IwnPmL-=eZqK+RL;n&!kIsF0D?P&~C1 zH%vR(3ma-_k%+I!CQUPsM@110d?{a0K`l_ekYg`@#qJOHx%WQjJm=hVpL4HAgazAJ zIa&b#Y_LZ$Q2>~mO0%7CQwE5DYxySFnRqk`2LRO>00t8Py=lal0f6iQz#ItxbQu5+ zY2~6wUlRdO2o1&nvxCg^Yo^X31B(l^nA^C?+S*NY2*CnigA9xL22UAT7{lGLi%CF7DSbmZkHiZ>Qg_%YiUw3+Mfz>NM8F+yo} zjxp^VtFxhP5N^`cIgyGq+Tpp<<CJS)JXdLCCT^krymMjAsj~_XfBPXTBE0#rMCvuJgGn8^8VGp72&~s``>vAJ#yR`<;sGlXnN^qJ zyO@(OJ1C}11u3GBr(CY09;CK5T)-_32JF`y!3v%_#>*wr%vbkL+30dKJn0m{Z=3S! z%-Tp|6LP;M^V30b(-~x0l#eW9yYeZUjNeNCd2W~KY^G>?e)!z<=vcVpo`BnaxylQu z_!?r{yH8LDxM`{Mi+QoJHHP^gAXr?Fv+Jyi<1cZ3F%-utJdy<{HDzZw@8O??$GcQ( zbnUDYj1Bqf_%|j!n%x^bVsieXx3tHvJ+i3KbHy;Iv zyKhUPI*_Q=X}9()w}6zEO&T8byC>eAYQGC!?Eurx#nTJr7a0PA`7oc|09))W;n;Zm zmT!w0yI((G>7j4sZSM?Ex!O3itrw&~75O25*Czt#W&FC!>D-rv!&2F0IYkJj`2 z5lb@l1cJ5hvqrofVvNC9A45N{bjZ15ziK^VSbuLKkGniVhiX#$%>Vf-|LOdXKof7U Xcvt;~lqZaS{`Xqgz%Weh5mMe?D9%DL diff --git a/logs2/qemu-screenshot-20260609-130717.png b/logs2/qemu-screenshot-20260609-130717.png deleted file mode 100644 index 88526cc4ae56f6c25514ff605fc165b9b6f3cf44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmds1{a4a=6#jsjsgXx*x>*C;PS(`Q*2Kh@ZHXEhzD22NfSRYwHO+}bP$5IDsdQ=? zZkTqm7dF(=Lh;>Xlct%+qoRlgzLYPhpcW`!$g!8dqWi;r?!C`B&pG$p=iIAdA%O@B z2MYiI0(TS}0f4EoG;xF*GqCl$l5YgZgrgC70BBACFj)ZTj3eeO02DU>=E(qHN&&D> zEo%z*HWKjo;6N-eImAl4V(iS)ad>~T`OW4Cq`B*6?*ITcNpaY33DnWWar_M~X8Y!_ zkNm1x@g+r1EKUU6Jh?8kIgi@SG~=&5h5RlJH68TFS~3`D-%?{FrqN#>92EfBL|v$W~!; zmO0}Tt3}W^3C-2DNOG}SGctc`r7f1$%$2lWd!g$nVB3}Ix|+YX?(aRzB(@%atpb>ROk6v-hC` zIzvSu4}gk@!L1wzabeG`fx)isi&>?zEpK*;c*s}bX@gs#QqPBDUEP@|@CL0=R?Z54 zL%y<|xD7+b`7`JCb$n$(g10;tOFSmDFo^?K4FL}rvGCP?=RAtaFmLxxG-yGl6xODD zFJ;Hi4T-4J0rIHh$(Jf=hiGjL=kZHJe*4r%aDt}}aWb(alc26V5fVXT<4S=U(o{+hm&04=uzF5(}3##^Se%KMMMl! zOnDA($vDV$gBPu{b`R_9$To`md?`zSO*1cA|OfNS?Z-g{hx&nAnitEn) z`_^QdJ(*^idUMZ8D@blNSM#7h+zAJ0cDvwJ_At$S9HU5ffhi!Gj_}zHu%*5d4#MsC zd~59Z{kp*|Zn`$!j;_$;yvE_}eIOYs&(ChH^JrYw*}*ig*8;Cb8jVOg+(G=pyJn^A zS_U;st)U@%5`A?YQ^C4Pbc2fSGwf4S-agJ+EllZ5fz@AYubSiS%}?CXlek2mI2S#| z-9{%-Yh--(3{hB4pAc-cat1V=fy_!n7JWz)wSO_@w7eY+Z>dx9XO!~Q_`8?oP}8Uv z^d2D@MrEmF-Fp1qe&y*C4kE&&P!+39^q4>`-!16;&lYAVu+P3@w`Mu2-*{&vkGnj=1glf}P5=EX|Lc4}ppMg< Xy{&pp&J{*I`)4hje+ahb2s!s}t1UrE diff --git a/logs2/qemu-screenshot-20260609-181200.png b/logs2/qemu-screenshot-20260609-181200.png deleted file mode 100644 index 46748d8b174189838e6ae4eae14a3f22a95680ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmeAS@N?(olHy`uVBq!ia0y~yU#6&t6Jtngdo zqD>48EH^z}978H@y}j!@X||OJTY#wZ+LolLJ)5~g-KK>7+#!@@#aFiX&#v2+%TJqa z^ql_Jm7_$^&+9|TR=wLHUUAz}wJYn_ysh)jjCyQ0eafSW)?Tx&*|=xCuX{F0X;-Fi z=DhEvpElor%6^T>M=;uoSx42iYkT|8{5sIyCpP2PvEBB97tf|Q#P82&Rp+;F!}nfaizi0&UVpM$yHWch`#=B7zy8j5U%|jIKj;e2bgARr zr>9-Ma_m%L&5YX|&twj-kh>RHbcN^l49n$rj-9HMXLx4z;Pv7cJ66iw6Mi_CQ7+N7 z;ic{Y6RvosJsXZ+Gk^G<@tV}^55F1A8RNR|>1nl=zW@75?CaqxTnVM!8%u27)h4~X zdbr|=+x>{(?8e1a##Q^aXZgOn>a6?0$#d%#sl?mIua%u!63+X*_QQ&6PvUGv9<;vr zc`JFhyzYlG*{g?lN6F6!vc6d&{a{O9X$XJ)%vXxQXaj=%2QAW{-?{5ArS3e}w(dce zS>oFG{a+-_3}+YQ*XK6H#H{`Eru;W!>{&IPm#?SW9bOhceR}qM1@pD%>$b~ZJeqSz z@Ig>?!|~D+Onb@cWxo!|M*>_(G+@*CmD zZ*ncKowYp>*xO_J`Olm4zuK94@^xe`E)`6u5>Ke&E|{YJX)iU3U%Rc(SUcb9Iu!eQ`h-wNqt{@JZNuZx^# z$o@UAt#$dCW?Z4adxjX+*KI69j{cB#X&}d7QKArlm`e8=o#}KPQU!^kbA@8zctlYzeVW1jgGy)-;8O`ruVC#zrO!DX;Jh2-@9&E|Nh5&?Yex; z``f4f_-b5y9UCfjIONfe_c7m7%^%8tT-1IDk~A2c&jeJQwalyc{B!@L-}?VecETTT zzJDa#{ond${9LcU(JtIRRtM*c*DetI!F}t`|F1yFVD0r*-XHQWvVzMMs5!%k`jGgC Y{mYuC2~9g94uZVp>FVdQ&MBb@0In56=Kufz diff --git a/logs2/qemu-screenshot-20260609-193724.log b/logs2/qemu-screenshot-20260609-193724.log deleted file mode 100644 index 58987244..00000000 --- a/logs2/qemu-screenshot-20260609-193724.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c9c87048a095a22f62092b734a48c0b27e41946f433f023132b6bae3dbda3ac8 -size 452582 diff --git a/logs2/qemu-screenshot-20260609-193724.png b/logs2/qemu-screenshot-20260609-193724.png deleted file mode 100644 index c0fa46396b3c351fd3b44b9d1e20b66c040ca8a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmeAS@N?(olHy`uVBq!ia0y~yU#6&t6ps?w?r zOI#QjSZ;c{IEGZ*dVAM*(rhacwg6G*wJk|gdp2{0x=jiDxkD(+imz<%pIx^tm!CG< z=sEqbD@Tc-pVxHi$k6^SFvyQ53$>m#zgdH#}F1`OaI-vV-%(M!AIE58rOQn)Yd5 zOx5n$*Y@_G`E{VZPi)4oW4rAIFP=?rh~J;l$Uk+5 z+`?}ay(v6ioEW)$tIluVhVQ+;7Eg@kz5ZmicBA%1_J97DfBl{BzJh^ae$W-3=~BnL zPfxpi<=Cmhni;n_p2-|uA$KpZ=nBv88J5fM96MDh&+yFb!Ry5@cC3`UC;V_OqgD=#xBC&n*^P^hD)mit0ljqhgQi->ZUn@JeB%Jqq?S~cDp2XRTJZOFK z^H%b1dEF0XvR4o9j*_1dWPP(l`oWgI(h&aonXeRq(FO$j4_c%@zjN1LO5J&`ZQX+` zv&6OW`@cw<8O|=qug`6YiCO#SP5E!e*t2RnFJDi$JG?A@`tt;s7S{8BR)zqqry`|XLM_|3h^%Y>BQnw`42%(Tzo_v_Nv zTaQKb{jQjE>PPR#>Un=7{|7Yu?nsei?E7u=ef7l027C0ko8I=YI=}Oq*^MUu>Tq>AQC7w{lT`)!c(_V(`y__Fb{61nDqF*JZ z$h1bB@!PA!`kvdl4O`<_Z>;Xy&iL;9)akqitJ(xz?k?SQg~Q<2z7^8P{IgqkUKcsf zko|jJTkYOW<~u+B5@Y=K^oM(AI4~i`TO5efv|0CQPJdZN&4+JQa;H=6ejRx1{p*q0 z_V?Ac*KOC$+kdy^b9erse8z44``5f&q0yEqeLD4B^}~$F$FupW<15zPUfuURZpXap zhg<*eoqqY-A@_#Ge`~6*ev8n18y$OpzZuh>P48Dfe|`UR(xT@3zjxiT{{4^l+I9Jw z_qR{|@zuEaIyO}5aLA(_?_<8Fnm?5PxTyUQBxx`>p9!cqYnfN?`RD#gzxDr{?1Vqw zeE&$e`@i+i__uU#PagZtK>|6hTU!P@Jsyg%e$WCfQiP;-V6^&#;O Y`=LjPTIVbt%-`4ZHXBg-lEhrK+RL;nwNLPkaMysw#>iM__RfA>g{kNrC1_!F}{DV?_AmLep(`9<) za&}PSnJHiPoyl8Xfxn8q11>1DXK#Pjl!!|#(~#HdWHTmW_zBBsw2||E|MY=TAwq6+ zo-t=1qp_fE5tyoK>_~+w^~mDgwYC^)Ge_Kd^QE>Uk7Zq~?P~tovcLB{gV=uI%Fd$t zO0sfYOAs_XYqME_-F5893;gL=#Aw=5s_2K*x6ot=LH4ZSNMp?W+#>Jb+78nZb0_``CX@_JUp5q zBENvQWE|$W!V5N-`-ipGBrEwto`lKAq%1d0qj;f=oiVTMGdUq6O6Z&?jL=kqqr7q$ z>k7N)t77#?m^KQDxh&O<^Yjqii5-W510=q2T~}L#jD(PcPG7UZqr-I{W3In>}LJ&x{cRHH_6LgJSYQ%jdT#l1cqVTA>5>$;^rZ63TJ*?CX@ zLrW6XhD0?_x#O_b3X)n)Rb1!~H~b;0^*(r|4NSclOD~XKV(r2t=pcOIUAX`dOxr8KWhNLm!Xti&+qA2o$RmRC!0CG zh*gPl5|O{@wLvTm)JJ2?PoSTd+hpCderGKNwSel$7%~1NuSs diff --git a/logs2/qemu-screenshot-20260609-194812.png b/logs2/qemu-screenshot-20260609-194812.png deleted file mode 100644 index 0397151d78ec06a73aa8452c0ff913804a3e6a97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmds1{a4a=6#jsjrCCR5xLFh1PTJCn*2Kh@ZHXEhzC~qefSRYwHO+}5P$46=sdQ>8 zZkTp5iw(83P<%Jpq-o~ys3@X=Z~1}>YC-aa9DDgIxk_$A$D?(sk2DI6Z|aZH*Q9tkO({0Pff}N4znmCIs*7{E!mM1( z2#P;5>BB9UxaAr6tJEvtf;!{%?avzH3Gt;m>dF(vw1pIY%q9|R=DOQ2rGG?>P@0`* z%{WErtQi|bn>95KlzfeLc)n<*HHzNEleXM^p>NOTAdB^#O<&ve^_*vs+b&$)R`|4% zs$SKTMD=y8c1y6Lz3th7Klz^;NnW@t`62rBL!m1~VCnJ+ho`ZjOQ%TQ+m+X6 z*G6KSQ2R8gpAL$f&Y+6JJ!L67lutQS;x^_l^SexEGez68!{=v4$3pC#eeZZ@C@*57 ztH^C{KEWL1B_%R1Wky9+85VwoU}t-rT<26=AMpb+mzz-L=w8*EQIG2T^ScfkWq2e@ zLVXTzPCdv&!}HeIyNC2himkFjAY%)0NsEnB7(pm&ThvRZG+xNC8an3zBQ=%~XfK^d zJHzh!XgJ+6ww+35rMT?IdwhWD!i~Yf0gBkLYN#zlML?*NOWw>Y9^c^C@7qeQNz7x7 zdw=GC92^&4K07MNU3{KQev%*i!1nV+Oqc9|8wU-ks48J+1P7v(biK=8W|SIFuZOar zoO2E^4&ju>3r?Rl`EBJ{z8w=(@A7 z!iGY(qtLCA3Y=G3KtjuA4Ilc$jd*~L+y$?+gK6iZnR)U{EFsB!Siq@=E%g?1t87gG9vkKJLwCr>Xnk4 zskAhWmhR9U=c8|*4AM_v>eUSIA@AzawlVf4z$!PUF$T2}`xhh6D%vpc=32F2Mx|Jdxpz$gHI8^f z@2#ans5G^_%Rt!Er#gGWUQC=2siSmp?&GNCd)XcTSp)dK2&MISe9y!i6n_OjTF>-B zEX&jrh}?D0HS(Q6VY>UBfH diff --git a/logs2/qemu-screenshot-20260609-222537.png b/logs2/qemu-screenshot-20260609-222537.png deleted file mode 100644 index fd5705ac3e137d03442ab93b8eea59b64681f60c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmds1{a4a=6#jsjrkO`=xU@-aCv9nIYhvKbw!{<--=eZKK+RL;n&!k2sF0D?R5~>c zH%wdh!iHK}B)*$$(lqmUR1{Icm+}P>)Pm#-Ikxpz?EY|{d+&43bIv{YIrnO0c(9F? zlNA8K1{Z>j2Eg1@nr(xdGH?jIl4pW#i6PN=0BEiNFj)ZTO(W(k02D6(=E(qHN&#?8 zD{GAMGZFBFuwX1O+s8`3V(Kh1aQGmL`SlwRTReY7C#nEgC&gjEAy7wDWB40f%;xox z9|cyk5=sgmTOB!Ad~{W4e-^VTv&GOTLqF(7)#5nDAj=H9@K6mwut!D+B|c4Zzrd(c z<%A`lmY_6Iar5?S;NQpN%NhcQ$=x*Vl8JNoqTD(YEAC z6-B+GCkpGIwmL4tZtiN&5B>4rv61wJ^WyL0k3SH2KzOFE2)}>&i*n^Mrn=U>&*FVV zzus68%mbhzdSD~RNnFrwH$J%<}bC5zl2jDt%xhREmBu+Szph30|WV%F0>c zZ!Y5w6SrV4@j=YF-R)mmk>Jgb#1fwg9ZcfH)j+@pMl2ZLv+FWNZJbBE6%AOCDFw9| zev8=&bAux4^g(&d;gpM&w0*SJ`m^}O!NA>`131AGr+ArIlKJxPF&kaBh9{XO`fpZT zo?RVDY(nnVWPUOzYC3@|jrNshI4hp8DFj=_&-2?&XER0Hv;C)MM#mzY+yZa;=P1si z;;Tt*Z?>TJa??^7=W^rXstpT2K(LcNt{!trPJrk>iNi^$*ydB+n^TYM`}5llJ4JLX zQ%rddZ_eDy^@10!vUUvV5oCMCJ-(DBz^17hr&0V!rfu9y*DP+tuo^mrh7lXf@YI)X zqn%N=12pVzDa%nQwU(dv=05UdxN{P)aDXH_*x_r zx^l_|#)kZK{OeO*&7Sq%vJgyfgBCTM8hs}+sUBPV z?%9!Pj%1p3TCv-53rK0%py5G(coRHni0$wyN0@d#o>3?}#}p9FhxzP!*kW%9$HwdT zJUi^zy}AKQFMTV|xicc=a>LN(UXTKn=ViCl`7|u)5isqmcfnVWnT$x<-%kA8uV%UI zS|&A1qouiYCk5!+r^57;sCqTsf5^Y4ylsrNQjpq_3VV93t!j?9GcU=xJ86+Vapw3G zcN3jNt&#EBGeluIeL}F-!s*v`1T!m*S@c0|%pO(jNqHLz-dv~V&nV?933o2Zp~ewk z=)H|(2$`jpbs6wG`;;e-IEe_8LUo)j$!7w&bSJ;#KWl)%7m?H+^mh!LLH<|x!?oN1 zhb5_c(xG6@ca?N2)EJAkK7@Hz;h23J@y>e0u=dtO9(I3-3DczZng9D&KIr_9Kof7U XcvJO?oGXlZ_Rm_lpm1!>0dnr&w}wLL diff --git a/logs2/qemu-screenshot-20260609-225958.png b/logs2/qemu-screenshot-20260609-225958.png deleted file mode 100644 index 81a4b0d40777fde5e371e1f4532fc4519222a9c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmds1`&ZI;82*5nsaeO%WV0rfJG7j=wbj6 z$t6u;-Ub356BK{}Mu(Xxd4|p;6^rvXS=?%h0HzD-eMbSs=_soXC>I!;CTC1)}>RHu`s>8DN{@YS5g9BA~{y`}|knlXt`5L`? zIWs8!{ERRA?(}W1z+c4P0hg7TZ|;276pxE9)sWYo%3hm@;U_I4(MB%&{8I(D2)Yei@;P>XHP0rsYe&@t+ho_n>pgvTQ9X8xh&gaZFlog%YnX23}XA`>pP2{ zRg;zLT7sbAc^hH{cF(CJH}J>fXU9^Ou8O{oK3Bzefp82>A@0cRm!*m|bWNS}fXRoD zL9M9#k!g(k@M?P zy;m|~7KVkC+2gW^Qwi70sfVd;4Oeh0!+r-;$FTfocF|IiIPKM=vlf~R6<0h<@Uf9+ z&u@&yHX{$H(mov)HlIfphkHp6 zAtJwkx1=57xWNlHnEOVwwj?Wg1y91{W0IGfW>LIQ#?Gi$4(XhbQ6+TI6Gmt%!BJj0 zj(3MW@Kv#TB}{}uVlKPt&UxZWcV@?6-~fqlT-VhXAtNBzOGy9*XF_tl3aEV zR9KRz2olvi`L5$yD@bTHRdJ!;-SMte+r98=1WdgcO)ropGWZ1JQ68%Sw$fk3ws89` z#}YG9Q9rcJP20xZ)g6+M-8f>?4-%l#oQ&3bkH%H4ElmCTeZbAL1|t%WbP&Gqu3am+ zl}1Tdsj2q8alYD)nIP>nszFKf8S$wtZJ%JS=O=X~!Jgl0uU_Ep&xzaB8@EE6x_oYi zvx7#Y)Jl1*If9^+HpSm;We=*m0vP4`blR{w;^1=R1z9@^-cqmR%_(H-F%NIZpr$b| z=!1oL1evas_ULf?2NV}h+X?a00%epY&SMI>`Y^ZaUuyurm!XtC&+q71o$Sxx$D3Kc z)~gcbv~~Wb*9P%^pgs~~eiGeThRAqe``&y^xB1RMo^pPS4pJoz82|HE{?qv%fht;O X^0xXlDN7L1`S)5_|6ok*F;doF0g*z) diff --git a/logs2/qemu-screenshot-20260609-232904.png b/logs2/qemu-screenshot-20260609-232904.png deleted file mode 100644 index 8a1a841f42aa9a1f9e225e9c95a32ef66d74b929..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmeAS@N?(olHy`uVBq!ia0y~yU#6&t6xEMLdJ zI}HpBEH^z}978H@y}j!@X||OJTY#wZ+LolLJ)5~g-KK>7+#!@@#aFiX&#v2+%TJqa z^ql_Jm7_$^&+9|TR=wLHUUAz}wJYn_ysh)jjCyQ0eafSW)?Tx&*|=xCuX{F0X;-Fi z=DhEvpElor%6^T>M=;uoSx42iYkT|8{5sIyCpP2PvEBB97tf|Q#P82&Rp+;F!}nfaizi0&UVpM$yHWch`#=B7zy8j5U%|jIKj;e2bgARr zr>9-Ma_m%L&5YX|&twj-kh>RHbcN^l49n$rj-9HMXLx4z;Pv7cJ66iw6Mi_CQ7+N7 z;ic{Y6RvosJsXZ+Gk^G<@tV}^55F1A8RNR|>1nl=zW@75?CaqxTnVM!8%u27)h4~X zdbr|=+x>{(?8e1a##Q^aXZgOn>a6?0$#d%#sl?mIua%u!63+X*_QQ&6PvUGv9<;vr zc`JFhyzYlG*{g?lN6F6!vc6d&{a{O9X$XJ)%vXxQXaj=%2QAW{-?{5ArS3e}w(dce zS>oFG{a+-_3}+YQ*XK6H#H{`Eru;W!>{&IPm#?SW9bOhceR}qM1@pD%>$b~ZJeqSz z@Ig>?!|~D+Onb@cWxo!|M*>_(G+@*CmD zZ*ncKowYp>*xO_J`Olm4zuK94@^xe`E)`6u5>Ke&E|{YJX)iU3U%Rc(SUcb9Iu!eQ`h-wNqt{@JZNuZx^# z$o@UAt#$dCW?Z4adxjX+*KI69j{cB#X&}d7QKArlm`e8=o#}KPQU!^kbA@8zctlYzeVW1jgGy)-;8O`ruVC#zrO!DX;Jh2-@9&E|Nh5&?Yex; z``f4f_-b5y9UCfjIONfe_c7m7%^%8tT-1IDk~A2c&jeJQwalyc{B!@L-}?VecETTT zzJDa#{ond${9LcU(JtIRRtM*c*DetI!F}t`|F1yFVD0r*-XHQWvVzMMs5!%k`jGgC Y{mYuC2~9g94uZVp>FVdQ&MBb@0K9oag#Z8m diff --git a/logs2/qemu-screenshot-20260610-005734.png b/logs2/qemu-screenshot-20260610-005734.png deleted file mode 100644 index e9be55f6efdcfe8481542768ebf5fb29f2e7d9db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 282 zcmeAS@N?(olHy`uVBq!ia0y~yUa@a2CEqi4B`cIb_Lo1C76=D-CYOJbhi+U$Jp9Sn4ca zm39*-G{w`!F{I+w+k=K6D-JFA>YvM=zW~S_Fwk(F;k!Nq=LjPS(7)CMI6i5;HWsMQN#kn#asF&50vWAtSA+bZQxH zn0B%Y8)~Vcc)zeo)70ZpQA7hTrGg4-LGpzhyZjY`Zf zrA^^JMgkrm9EbrXhnVTtjh$Hr78hWq*ldn)bFNbyi3MPj1dI6wPZ?jD#NFngcWw^* z$iIpiUtCyce(Knr)9V7O3+U~ct@091GzlePT&#Q9Y-2SX78JAq9C9l@WUYm*GCoH4UCeHf;GKR*5)^d|1 z#+*Zp7D3x2*s89vCl#qRV~V@0Z86klj=1&aOI=4k%cexv-TbxXU|$l0*na-Xj^gK) zWYwCEAZVy>vt5SWb?nFw`texgc>3Zc(f4s@p75O^979`#J3RYknQ|3fRpT^h_91jg zXDAQk0#F_?yp3%qD(JmCG~C^DDXT=f<;`v(*Zx&_`tUZW#OujKch6-cc!QEFE9M2i z+P|`%x(Bn53t%j`bbMt_gtt5si9M&ZFtHs+4FOLWq2QIP<2AC%ps;x-95yGB3u-ca zmb2p*Mue2vW3s4|DOW0}hp2507jVlX{x0gHSpIXnIH^dS+5a#Sq0Lrv#j^z8o$_n* z>*EQ{NEdbHrz67Vv&fPNZ%M{3`EwQ-zk~j>Vz2RR#%S+6oHREv8EUuR|DJD-`~oVj zirD`46VyRYS}OfwZcI#-e(?tg7Tf3Gyr5+J2_F;L?3D67o>c=m4amVizU{JA-pWF>#ZlQ8+1w56t56fcaiBc|UWixWDgg3fut2u-CpO8@?e z?(qA5YF4j=X{(f2$S!$sp1IMT*zp)RK;j$M^tHvvCj-w^p_S;W$TY#= z_!IZzki_JQ`3YXZ(u;IrT~WegtIwBEJ(9;BEO$srR`R=}SP-SO=Y7!%t;}#{Ba8uE zKW7hPK|WgEtr_0Le zEHRUhYKOPD>)N=xx_2BvxaKJZ4Q(TK#u9fU7@s#i;I zW>T`$8mfJ7qMxo~CRjI(YEaR9M}4cy+9#Q71*u)Bu=<>*88Afv*NMH|sXxh_S=%Gy!zmRc2WPAOZ9e{fX>HH~{i z9}wbEWR^RK}jN6XK@@su*pe=M-|~L4Mc2)&Tx5!zg`T-_fyp*`Fa#H*)=~ zS0t)w>w*pMb>h7sLo~+X1iG`_Hv7KKdy8@X#ycZ<(&;HWSe-g(`p;kaPv?IG>NvgG X+sfCZTtQUl-)mt5LNL`wNx6RkKEp!< diff --git a/logs2/qemu-screenshot-20260610-145902.png b/logs2/qemu-screenshot-20260610-145902.png deleted file mode 100644 index 94f3cf5de83868e78f49636c2fa73db794c70d47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmds1{a4a=6#jsjrJ+Y{x@nWzPS(=O*2KVJfSRYwIn9Y9P$46&sdQ>8 zZkTqm7dF(=B=Oy3lct%+qoRlkzU2!ls0GRwa_r@==>Bk@d+&43bIv{YIrnBrkUzrQ z!5jd9z#Yei0bpt@O?JYK8QA*X$Tq^x*yCY%0BFttFj)ZTj3eeO02DU>=E(qHiUF`s zE@=q$G7|8ZKz}SSIm}AAVeHIOad=*L~CY8=Plw$czk@Rma_6pK5Zs}pRkU^n7HotOYIvL*(yvf zFlU^jvfO8d%G_%Nv#*JS{2q- zP*kfrqOk6Hi~SO;XkS}Sz)#1{45uty7XJ_(@mSyr;hEZe{E?|IOO-2_%4(Nhv-iP$ zIzyR14}h|;{%srwac);pUw=pE<@93NmNz>@Jg2eHl>Ti{G5YaHN9PqJc!N?X%V&kZ zIgQzl--S6v`!VPCw|!+!f;T-COFYK4Fo^?K4FL}rF?a01zUvf~VczbYsNbAS$*oTH zTFQu-8xT>aj>*GMCR{D29j3L^UBWL7`0iI9#R+O1qGe)9+Uo~r5ZVkiPclXH-mbVl zyFMJ-h}^GE`*c9mcotb4<|$2eRMfI51S`fb^Sg{^Ge+x+BNt{yMuQ#p_}=x-R9r$u zSCU%aeu6s0O-^DYW<^C+>KA^5VCTA>UFVb>AJHQchm%mY)1$H{vkuw&=XdSaim*tg znDP?dly->g2G3h(?H<(Gk!=(Y`BIhuo4nXCh2n=Wt)gB#r*ngcRM2@ejMz|ur@r1Z z(h+*kN6qe%vh0;o3;AVt?$d(|7fuWo4v>WUReen%G8{slUh-yKL4SkWcwi&GCN_;V z?E9JbaZp@*`RoWkckyKk=~;g4Bb(0`QJvC9?rb+mNl^+q!r2hDq;oBQnO0q6^>^P>UUV|FS3XWZ{om@ynOS-+=Li6+7SM>`$x*T|3lIxD% zht_18J(*^aT(D=Q86-4sRr8=f+zAJ1cDvve_At$SG$T)z$P^GwhxqI|*iug+2jTX6 zwl#M2VNL%QH(d+Qu_HL)di~(`9*_W)W@j|lc+@ZJ>|mPdHUFDuj7B6KX(N8&Rkc!b zD~+12*3g`~;(T;%lYzPkRGo_MJ?LFk+B(Ww%}r`gf<3?0S~17ln;qxa6}LnmzZfye zwWO1%RWd$%hA1qhj|(=MIenUTe`dKMoj#xmKd=~iPTq=wH`S>4GfMet%>8R}sA1R> zdXJC{BGXl}PCb5aukzd}2N7XHsEX3Yd5j~M@8`7tXAR){DumjN{+@x;%l`^`vXSLu zyDU{r*ye6{u9NNt7$UJ2ConI{>@)7!tyv7~H{Kb^lP*s%f$F4Q(|`ZU|2iKKsH62} XZ!4zBS;Fua|Ez`c3&K_%C1?E&YJ5UI diff --git a/logs2/qemu-screenshot-20260610-213714.png b/logs2/qemu-screenshot-20260610-213714.png deleted file mode 100644 index f4694fbc674dc14a42b2affd0f14d41e3af84579..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1398 zcmds1{a4a=6#j%b(`c(%VOiPPS$2G3%;Q3QZ7qzP!`Eho<_p!dgp-OIr5JXoq#`#{ zv1r*+i<48yRMbR~N|sdA5nqr592gafnhGMK`*!*-c7M3{KF_`9`QhGsE-NYmzuIY& z698a!*gjkg0QOL7w+#k);Jl~k0u;6#*%w0q;EX!}3?={z5XE>0K+g97d`Jc$paKA7 z#?AKVAgBN%h2wF+&X<{01R;m)FhZ!qhcBGgZ{JjUNd}3*r^0Z%_tSnn+lPdzO!J@;GgH1&>#{evCB?!11KB=NsjOA!#-r`T)W9eU-_9oyedj`cXLD6iAm zI$M;en&WKc{L3*#x<&l+je#J1+NmUJ*ji{?I`#9d5 zpRyg5K4R_YL>f``ljmh1oNgj^@=NZ#E;G@_DbnfT#)$N$SB*h=sHCAG=3}fX&=`|= zuX*5jj>`<1V3?DAS-pa>D^8B!Y?54-miNhfdZW?LDRAo5lz$mJjF#Iv-bRxTHKL7O zHWLD#Q$&OK*Hu}(`JC@*9v7H9XaoTWA=0)fgmaUl13As@pr{C7!g3kf%|nB8->vqP!3T|0bedUdR~O~3E3h{ z>l;`(V#8}6M^$b;E9obTiCqQneaR%usA_2#-iD2brf)r0|C@99>|A(dN}o(BZI1k% zJCNEi;niM2z`_zvtm5zD*wZFRm=w6njAMBH+=k?@H8r&gW-~5hqCs?UELMK(spZ^4>DhfZTiNh=xk&E)7+zNXhn}tEbEV4*D-SDF>a>rkRUPriX_w3 z9J{g0r$F{lZCGBX3Hjzao}tCaY-Al4F*(rs%r(PkEvr<#pruH+}ehiWg{ItOGcdhS~N zMTt3!E}Er;(@Icv!ezJouxB_MR83xPPswkNtH>ivBlsz(k@C|Pd4bMTc6|IXbIKmPJOO$kgCv*TZ*|E1v7;C4as>{>5Z$G zNC#V>COUdEDm~#n-+W%*DEvS(o;S216Rll&ffRH;96Kx%q*96{HA($*#^$w}GI~;Q z(()}o=Piq>!G4v(>~%1yYg%~HYsT*{T*Ikfk0WAP+D@uMFv2|hguB(r?(=0JeD;h6 z>sxK^(}HXCjwR=XU!J5kJazM4%KfMgC|lqZZK%jTw|scEkf@1Fn^_+GRIKYTcz3Hq hkt;t-{NKDtI`6>C)-ltB@K0Y8goQ@n>VHZ;_aEopTUY=9 diff --git a/logs2/qemu-screenshot-20260611-002306.log b/logs2/qemu-screenshot-20260611-002306.log deleted file mode 100644 index aff53f54..00000000 --- a/logs2/qemu-screenshot-20260611-002306.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:199e9f695072ae75c77b893a73b6a7382fe94782bc78e1f32bdb67b9e97400ae -size 459201 diff --git a/logs2/qemu-screenshot-20260611-004156.log b/logs2/qemu-screenshot-20260611-004156.log deleted file mode 100644 index 7affce54..00000000 --- a/logs2/qemu-screenshot-20260611-004156.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba128e200b7f3d691f1eeae1a924f37522f7ee162041716f383eef2b4d57af30 -size 459018 diff --git a/logs2/qemu-screenshot-20260611-012817.log b/logs2/qemu-screenshot-20260611-012817.log deleted file mode 100644 index 2347d6e7..00000000 --- a/logs2/qemu-screenshot-20260611-012817.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0712969ca14c5963b7499d5afa4252578f1fe78131f1a17fe405122c88895b08 -size 25304214 diff --git a/logs2/qemu-screenshot-20260611-023758.log b/logs2/qemu-screenshot-20260611-023758.log deleted file mode 100644 index 42970cdc..00000000 --- a/logs2/qemu-screenshot-20260611-023758.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7714a174fbb9793b69d1898fa5ac98ef9bcb6d48ec38cdea3c3a90e00f6f1565 -size 604233 diff --git a/logs2/qemu-screenshot-20260611-024401.log b/logs2/qemu-screenshot-20260611-024401.log deleted file mode 100644 index 7209e51f..00000000 --- a/logs2/qemu-screenshot-20260611-024401.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bebab938202d4aa165b10f57995cadf09381f0fccf7ec076fb9f3feb4f42d76a -size 2866250 diff --git a/logs2/qemu-screenshot-20260611-173657.log b/logs2/qemu-screenshot-20260611-173657.log deleted file mode 100644 index c60e60bd..00000000 --- a/logs2/qemu-screenshot-20260611-173657.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1c06d0476ea2356dce906c9d5fb6fb92bdd63d40449bef71fc56e4cf2e38c67c -size 452560 diff --git a/logs2/qemu-screenshot-20260611-174914.log b/logs2/qemu-screenshot-20260611-174914.log deleted file mode 100644 index 68fb3be5..00000000 --- a/logs2/qemu-screenshot-20260611-174914.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fa5498124fe32dfafdebf6357953bf0c984302be801c3de8a5892a5716212ac8 -size 452631 diff --git a/logs2/qemu-screenshot-20260611-175224.log b/logs2/qemu-screenshot-20260611-175224.log deleted file mode 100644 index 6ae2e0a1..00000000 --- a/logs2/qemu-screenshot-20260611-175224.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cee76955a92b5cb596c9b151127800e39a3e27014566c564c35938f4edee0abb -size 452264 diff --git a/logs2/qemu-screenshot-20260611-190757.log b/logs2/qemu-screenshot-20260611-190757.log deleted file mode 100644 index 8676f52f..00000000 --- a/logs2/qemu-screenshot-20260611-190757.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ccd417963fa0ba7df6837e024585f7cde5fd9d9590731566415396b40bab786a -size 452625 diff --git a/logs2/qemu-screenshot-20260611-202932.log b/logs2/qemu-screenshot-20260611-202932.log deleted file mode 100644 index 4318c6eb..00000000 --- a/logs2/qemu-screenshot-20260611-202932.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:39778c1b2c0305f5cca9a5721f32e6acfc62cc1061a045b211231e4ca984a81f -size 452591 diff --git a/logs2/qemu-screenshot-20260612-115354.log b/logs2/qemu-screenshot-20260612-115354.log deleted file mode 100644 index d2677734..00000000 --- a/logs2/qemu-screenshot-20260612-115354.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:70965feaf792b1c68be9ad045ab3927fb19761a6fb094cdd17b08fa737287e51 -size 450345 diff --git a/logs2/qemu-screenshot-20260612-160054.log b/logs2/qemu-screenshot-20260612-160054.log deleted file mode 100644 index 8ee35b46..00000000 --- a/logs2/qemu-screenshot-20260612-160054.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ab2fb5c928eccdaf8ffe880b56cc58e1d48b5c8cc1432ee86acf3c1716a226d0 -size 452714 diff --git a/logs2/qemu-screenshot-20260612-174331.log b/logs2/qemu-screenshot-20260612-174331.log deleted file mode 100644 index 93393887..00000000 --- a/logs2/qemu-screenshot-20260612-174331.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfb85553d48568163408c013ad76dfe3d6b2ef633517a3bbcd0dc1366f0d5c78 -size 452712 diff --git a/logs2/qemu-screenshot-20260614-163902.log b/logs2/qemu-screenshot-20260614-163902.log deleted file mode 100644 index 7968ffa0..00000000 --- a/logs2/qemu-screenshot-20260614-163902.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9cfedb98dd49805599db38c2d8f7d974399c2adc4f18719d2514148369ad8d9c -size 452394 diff --git a/logs2/qemu-screenshot-20260614-182044.log b/logs2/qemu-screenshot-20260614-182044.log deleted file mode 100644 index e69de29b..00000000 diff --git a/logs2/qemu-screenshot-20260614-182127.log b/logs2/qemu-screenshot-20260614-182127.log deleted file mode 100644 index 89d3a041..00000000 --- a/logs2/qemu-screenshot-20260614-182127.log +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1105c2be14434743bc2ab87c17e362523c02be36ea29beaa2d66d49bcce1d076 -size 453849 diff --git a/mk/Kconfig.mk b/mk/Kconfig.mk index 4d2bfc08..a5575e78 100644 --- a/mk/Kconfig.mk +++ b/mk/Kconfig.mk @@ -1,5 +1,5 @@ # ============================================================================== -# mk/Kconfig.mk โ€” shared Kconfig bridge for Makefile and Makefile.starkernel +# mk/Kconfig.mk โ€” shared Kconfig bridge for Makefile and kernel/Makefile # ============================================================================== # # Included by both build systems, after each has finished resolving its own @@ -101,7 +101,7 @@ savedefconfig: $(KCONFIG_CONF) # dispatching any -jN jobs" behavior fully serializes "regenerate config" # before "compile anything" -- for free, with no hand-maintained # prerequisite list. Deliberately not the include/version.h-style -# order-only pattern (Makefile.starkernel:49-53/656-658), which needed its +# order-only pattern (kernel/Makefile:49-53/656-658), which needed its # own special-cased -j/clean workaround once already. # # Guarded on the config file already existing: until a developer opts in via diff --git a/mk/README.md b/mk/README.md index 98155bfe..74fd285f 100644 --- a/mk/README.md +++ b/mk/README.md @@ -1,7 +1,7 @@ # mk/ - `Kconfig.mk` โ€” shared Kconfig bridge included by both `Makefile` and - `Makefile.starkernel`. Each Makefile canonicalizes its own `ARCH` and + `kernel/Makefile`. Each Makefile canonicalizes its own `ARCH` and sets `KCONFIG_ARCH_DIR` before including this file, since the hosted and kernel builds map `aarch64` to different object-directory names. Config lives per-architecture under `build/$(KCONFIG_ARCH_DIR)/` rather diff --git a/scripts/mkdiskimage.sh b/scripts/mkdiskimage.sh new file mode 100644 index 00000000..f0bb89c7 --- /dev/null +++ b/scripts/mkdiskimage.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# mkdiskimage.sh -- build a single-partition FAT32 boot disk image. +# +# Used by `make boot_image TARGET=` (kernel/Makefile). One script for +# every board so the geometry rules live in one place: +# - partition 1 starts at 1 MiB (sector 2048) and runs to the last usable +# sector; the FAT32 filesystem is sized to the partition exactly (a +# larger filesystem overruns the partition -- the bug that made early +# SER5 thumbdrive images unbootable, see kernel/Makefile `thumbdrive`); +# - GPT tables reserve 33 sectors at the end of the disk for the backup +# header, MBR tables do not. +# +# Usage: +# mkdiskimage.sh --out IMG --table gpt|mbr --size-mib N --label LABEL \ +# SRC:DEST [SRC:DEST ...] +# +# --table gpt -> partition type "EFI System" (UEFI firmware, U-Boot bootefi) +# --table mbr -> partition type 0x0c FAT32 (LBA) (Raspberry Pi firmware) +# DEST is an absolute path inside the FAT filesystem; parent directories are +# created as needed. +# +# Needs only sfdisk (util-linux), mkfs.fat (dosfstools) and mtools -- no +# root, no loop devices. +set -euo pipefail + +OUT="" TABLE="" SIZE_MIB="" LABEL="" +while [ $# -gt 0 ]; do + case "$1" in + --out) OUT="$2"; shift 2 ;; + --table) TABLE="$2"; shift 2 ;; + --size-mib) SIZE_MIB="$2"; shift 2 ;; + --label) LABEL="$2"; shift 2 ;; + --) shift; break ;; + -*) echo "mkdiskimage.sh: unknown option $1" >&2; exit 2 ;; + *) break ;; + esac +done + +[ -n "$OUT" ] && [ -n "$TABLE" ] && [ -n "$SIZE_MIB" ] && [ -n "$LABEL" ] || { + echo "mkdiskimage.sh: --out, --table, --size-mib and --label are required" >&2; exit 2; } +[ $# -gt 0 ] || { echo "mkdiskimage.sh: no SRC:DEST files given" >&2; exit 2; } + +for tool in sfdisk mkfs.fat mmd mcopy; do + command -v "$tool" >/dev/null 2>&1 || PATH="$PATH:/usr/sbin:/sbin" + command -v "$tool" >/dev/null 2>&1 || { + echo "mkdiskimage.sh: $tool not found (install util-linux, dosfstools, mtools)" >&2; exit 1; } +done + +TOTAL_SECTORS=$(( SIZE_MIB * 2048 )) +START=2048 +case "$TABLE" in + gpt) LAST=$(( TOTAL_SECTORS - 34 )); PTYPE="C12A7328-F81F-11D2-BA4B-00A0C93EC93B" ;; + mbr) LAST=$(( TOTAL_SECTORS - 1 )); PTYPE="c" ;; + *) echo "mkdiskimage.sh: --table must be gpt or mbr" >&2; exit 2 ;; +esac +PART_SECTORS=$(( LAST - START + 1 )) + +ESP="$OUT.part1" +rm -f "$OUT" "$ESP" +mkdir -p "$(dirname "$OUT")" + +truncate -s $(( TOTAL_SECTORS * 512 )) "$OUT" +if [ "$TABLE" = gpt ]; then + printf 'label: gpt\nstart=%d, size=%d, type=%s, name="EFI System"\n' \ + "$START" "$PART_SECTORS" "$PTYPE" | sfdisk --quiet "$OUT" +else + printf 'label: dos\nstart=%d, size=%d, type=%s, bootable\n' \ + "$START" "$PART_SECTORS" "$PTYPE" | sfdisk --quiet "$OUT" +fi + +truncate -s $(( PART_SECTORS * 512 )) "$ESP" +mkfs.fat -F 32 -n "$LABEL" "$ESP" >/dev/null + +for spec in "$@"; do + src="${spec%%:*}" + dest="${spec#*:}" + [ -f "$src" ] || { echo "mkdiskimage.sh: missing input $src" >&2; rm -f "$OUT" "$ESP"; exit 1; } + dir="$(dirname "$dest")" + path="" + IFS=/ read -r -a parts <<< "${dir#/}" + for p in "${parts[@]}"; do + [ -n "$p" ] || continue + path="$path/$p" + mmd -D s -i "$ESP" "::$path" 2>/dev/null || true + done + mcopy -o -i "$ESP" "$src" "::$dest" +done + +dd if="$ESP" of="$OUT" bs=512 seek="$START" conv=notrunc status=none +rm -f "$ESP" +echo " IMAGE $OUT ($TABLE, ${SIZE_MIB} MiB, FAT32 '$LABEL')" diff --git a/scripts/perf-profile.sh b/scripts/perf-profile.sh index 4953aee7..c38c489d 100755 --- a/scripts/perf-profile.sh +++ b/scripts/perf-profile.sh @@ -50,7 +50,7 @@ ARGS=(--log-error --run-tests) # We need to run specific control word tests echo "[CLEAN]"; make clean echo "[BUILD performance w/ symbols for profiling]" -make CFLAGS="-std=c99 -O3 -g -fno-omit-frame-pointer -DSTARFORTH_PERFORMANCE -DNDEBUG -march=native -Wall -Werror -Iinclude -Isrc/word_source -Isrc/test_runner/include -DSTRICT_PTR=1" LDFLAGS="" +make -f v3/Makefile CFLAGS="-std=c99 -O3 -g -fno-omit-frame-pointer -DSTARFORTH_PERFORMANCE -DNDEBUG -march=native -Wall -Werror -Iv3/include -Ikernel/include -Iv3/src/word_source -Iv3/src/test_runner/include -DSTRICT_PTR=1" LDFLAGS="" [[ -x "$EXE" ]] || { echo "ERROR: $EXE missing/not executable"; exit 2; } diff --git a/scripts/perf-profile_control.sh b/scripts/perf-profile_control.sh index bc685855..7d6874e5 100755 --- a/scripts/perf-profile_control.sh +++ b/scripts/perf-profile_control.sh @@ -48,7 +48,7 @@ set -euo pipefail EXE="./build/starforth" echo "[CLEAN]"; make clean echo "[BUILD for control words profiling]" -make CFLAGS="-std=c99 -O3 -g -fno-omit-frame-pointer -DSTARFORTH_PERFORMANCE -DNDEBUG -march=native -Wall -Werror -Iinclude -Isrc/word_source -Isrc/test_runner/include -DSTRICT_PTR=1" LDFLAGS="" +make -f v3/Makefile CFLAGS="-std=c99 -O3 -g -fno-omit-frame-pointer -DSTARFORTH_PERFORMANCE -DNDEBUG -march=native -Wall -Werror -Iv3/include -Ikernel/include -Iv3/src/word_source -Iv3/src/test_runner/include -DSTRICT_PTR=1" LDFLAGS="" [[ -x "$EXE" ]] || { echo "ERROR: $EXE missing/not executable"; exit 2; } diff --git a/scripts/remove_loop_conditionals.sh b/scripts/remove_loop_conditionals.sh index 50c9e6bb..7070b0a0 100755 --- a/scripts/remove_loop_conditionals.sh +++ b/scripts/remove_loop_conditionals.sh @@ -50,9 +50,9 @@ echo "Removing ENABLE_LOOP conditional compilation directives..." # Files to process FILES=( - "src/vm.c" - "src/inference_engine.c" - "src/doe_metrics.c" + "v3/src/vm.c" + "v3/src/inference_engine.c" + "v3/src/doe_metrics.c" ) for file in "${FILES[@]}"; do diff --git a/tools/README.md b/tools/README.md index 2799879f..272fdd21 100644 --- a/tools/README.md +++ b/tools/README.md @@ -7,7 +7,7 @@ toolchain. | File | Purpose | |------|---------| -| `mkcapsule.c` | Assembles `.4th` capsule files into `capsule_generated.c` baked into the kernel image. Invoked automatically by `Makefile.starkernel`. | +| `mkcapsule.c` | Assembles `.4th` capsule files into `capsule_generated.c` baked into the kernel image. Invoked automatically by `kernel/Makefile`. | | `mkcapsule` | Compiled host binary (rebuilt on demand). | | `ttftest.c` | Host TTF glyph-rendering test โ€” font rasterization unit tests, no QEMU needed. | | `pe_reloc_gen.py` | Generates PE32+ relocation tables for the UEFI loader. | @@ -21,7 +21,7 @@ toolchain. ```bash # Invoked automatically by the kernel build: -make -f Makefile.starkernel ARCH=amd64 clean qemu +make -f kernel/Makefile ARCH=amd64 clean qemu # Manual invocation (for inspection): ./tools/mkcapsule capsules/ build/amd64/kernel/capsule_generated.c @@ -33,5 +33,5 @@ type `(m)` to `init.4th` and `(p)` to everything else. ## See also - [`capsules/README.md`](../capsules/README.md) โ€” capsule file format and block namespace -- [`Makefile.starkernel`](../Makefile.starkernel) โ€” kernel build system +- [`kernel/Makefile`](../kernel/Makefile) โ€” kernel build system - [Project root](../README.md) diff --git a/tools/ttftest.c b/tools/ttftest.c index 756298b3..ed93aabc 100644 --- a/tools/ttftest.c +++ b/tools/ttftest.c @@ -25,7 +25,7 @@ #include #include -#include "../include/starkernel/ttf.h" +#include "../kernel/include/starkernel/ttf.h" typedef struct { uint32_t codepoint; diff --git a/v3/Makefile b/v3/Makefile new file mode 100644 index 00000000..930d6253 --- /dev/null +++ b/v3/Makefile @@ -0,0 +1,1340 @@ +# ============================================================================== +# StarForth Build System - The Fastest Forth in the West! +# ============================================================================== +# +# Quick Start: +# make - Standard optimized build (auto ARCH, TARGET=standard) +# make TARGET=fastest - Maximum performance build +# make ARCH=arm64 TARGET=fastest - Build for arm64 (e.g., Raspberry Pi 4) +# make help - Show all available targets +# +# ============================================================================== + +# ============================================================================== +# CONFIGURATION +# ============================================================================== + +VERSION ?= 3.2.0 +CC = gcc + +# Isabelle configuration +# NOTE: Isabelle must be installed separately and available on PATH +# See docs/DEVELOPER.md for installation instructions +ISABELLE ?= isabelle + +# Architecture / target selection +ARCH ?= $(shell uname -m) +ARCH := $(strip $(ARCH)) +TARGET ?= standard +TARGET := $(strip $(TARGET)) + +# Friendly guardrail: 32-bit builds are not supported +unsupported_32bit_arches := i386 i486 i586 i686 x86 armv6 armv7 armv7l arm +ifneq ($(filter $(ARCH),$(unsupported_32bit_arches)),) + $(error StarForth targets 64-bit platforms only. ARCH='$(ARCH)' is unsupported. Please build on amd64/arm64/raspi/riscv64.) +endif + +# Canonical architecture normalization (x86_64โ†’amd64, aarch64โ†’arm64, etc.) +canon_arch = $(strip $(if $(filter x86_64,$1),amd64,$(if $(filter amd64,$1),amd64,$(if $(filter aarch64 arm64,$1),arm64,$(if $(filter riscv riscv64,$1),riscv64,$1))))) +ARCH_DIR := $(call canon_arch,$(ARCH)) +# Normalize ARCH for consistent ifeq matching +ARCH := $(call canon_arch,$(ARCH)) + +# Kconfig bridge (menuconfig/xconfig/config/oldconfig/*_defconfig). See +# mk/Kconfig.mk for why KCONFIG_ARCH_DIR must be set here, before include. +# .DEFAULT_GOAL is pinned explicitly because mk/Kconfig.mk's first rule +# would otherwise silently become Make's default goal, since it's included +# before this Makefile's own `all:` target is defined below. +.DEFAULT_GOAL := all +KCONFIG_ARCH_DIR := $(ARCH_DIR) +include mk/Kconfig.mk + +# Kconfig platform-mode choice (Phase 5): PLATFORM_DEFAULT/PLATFORM_MINIMAL +# in Kconfig.variant (PLATFORM_L4RE removed -- L4Re support is historical, +# see the "Platform support" section below). Must run this early -- before +# anything below that branches on MINIMAL -- since Make evaluates a Makefile +# top-to-bottom and a variable's value at the point an `ifdef` is reached is +# whatever it resolved to *so far*, not its final value. Only applies when a +# developer hasn't already set MINIMAL explicitly (command line or +# environment) -- `ifdef` in the "Platform support" section below cares +# about definedness, not value, so this can't reuse the kconfig_bool/ +# kconfig_int pattern (those always define their target variable once +# active). Checked with $(origin ...) so an explicit `make MINIMAL=1` (or +# unset) always wins over whatever .config says. +ifeq ($(KCONFIG_ACTIVE),1) +ifeq ($(origin MINIMAL),undefined) +ifeq ($(CONFIG_PLATFORM_MINIMAL),y) +MINIMAL := 1 +endif +endif +endif + +ifeq ($(ARCH),amd64) + ARCH_NAME = x86_64 + ARCH_FLAGS = -march=native + ARCH_DEFINES = -DARCH_X86_64=1 + ASM_SYNTAX = -masm=intel +else ifeq ($(ARCH),arm64) + ARCH_NAME = ARM64 + ARCH_FLAGS = -march=armv8-a+crc+simd -mtune=cortex-a72 + ARCH_DEFINES = -DARCH_ARM64=1 + ASM_SYNTAX = +else ifeq ($(ARCH),raspi) + ARCH_NAME = Raspberry Pi 4 (ARM64) + ARCH_FLAGS = -march=armv8-a+crc+simd -mtune=cortex-a72 + ARCH_DEFINES = -DARCH_ARM64=1 -DRASPBERRY_PI_BUILD=1 + ASM_SYNTAX = +else ifeq ($(ARCH),riscv64) + ARCH_NAME = RISC-V 64 (QEMU) + ARCH_FLAGS = -march=rv64gc -mabi=lp64d -mcmodel=medany + ARCH_DEFINES = -DARCH_RISCV64=1 + ASM_SYNTAX = +else ifeq ($(ARCH),riscv) + ARCH_NAME = RISC-V 64 (QEMU) + ARCH_FLAGS = -march=rv64gc -mabi=lp64d -mcmodel=medany + ARCH_DEFINES = -DARCH_RISCV64=1 + ASM_SYNTAX = +else + $(warning Unknown architecture: $(ARCH), using generic flags) + ARCH_NAME = generic + ARCH_FLAGS = + ARCH_DEFINES = + ASM_SYNTAX = +endif + +# Compiler flags +# Feature switches (default: enabled) +# Physics/SSM knob family: repointed through the Kconfig bridge (see +# mk/Kconfig.mk's kconfig_bool/kconfig_int) as of the Kconfig migration's +# Phase 3. Each call below is a drop-in replacement for a bare `?=`: when +# no build/$(ARCH)/.config exists (KCONFIG_ACTIVE unset), it's exactly +# `VAR ?= default`, identical to before; once a .config exists, the +# Kconfig-fed value takes over. `make VAR=x` on the command line always +# wins regardless of which branch fires. +# +# STRICT_PTR: VM memory bounds checking on every pointer access +# Default: 1 (enabled). Disable only for raw benchmarking comparisons. +$(eval $(call kconfig_bool,STRICT_PTR,1)) + +# ENABLE_HOTWORDS_CACHE: Physics-driven hot-words cache (1.78ร— speedup on dictionary lookups) +# Default: 1 (enabled - experiments show cache is optimal) +# Set ENABLE_HOTWORDS_CACHE=0 to disable (for research comparison only) +$(eval $(call kconfig_bool,ENABLE_HOTWORDS_CACHE,0)) + +# ENABLE_PIPELINING: Speculative execution via word transition prediction +# Default: 1 (enabled - experiments show pipelining is optimal) +# Set ENABLE_PIPELINING=0 to disable (for research comparison only) +# NOTE: As of 2025-11-19, all future experiments use both cache and pipelining enabled +$(eval $(call kconfig_bool,ENABLE_PIPELINING,0)) + +# EMERGENCY_CONSOLE_ENABLED: 1 = REPL recovers from errors and continues (interactive fallthrough) +# 0 = errors are non-recoverable; REPL exits and vm_fault_handler() is called instead +# Default: 1 (dev/recovery builds) +# Set EMERGENCY_CONSOLE_ENABLED=0 for production, embedded, or high-security builds +# where no interactive fallthrough surface should exist. +# Heartbeat family: repointed through the Kconfig bridge (Phase 4). Same +# drop-in-replacement-for-`?=` behavior as the physics/SSM family (Phase 3). +$(eval $(call kconfig_bool,EMERGENCY_CONSOLE_ENABLED,1)) + +# Heartbeat configuration +# HEARTBEAT_THREAD_ENABLED: 1 = run vm_tick() in background thread (OPTIMAL), 0 = inline (legacy) +# Default: 1 (experiments show threaded heartbeat is optimal for adaptive tuning) +# NOTE: As of 2025-11-19, all future experiments use heartbeat enabled +$(eval $(call kconfig_bool,HEARTBEAT_THREAD_ENABLED,1)) + +# HEARTBEAT_TICK_NS: Wake frequency for heartbeat thread (default 1ms) +$(eval $(call kconfig_int,HEARTBEAT_TICK_NS,10000)) + +# HEARTBEAT_CHECK_FREQUENCY / HEARTBEAT_WINDOW_TUNING_FREQUENCY / +# HEARTBEAT_SLOPE_VALIDATION_FREQUENCY: previously unwired in the hosted +# Makefile -- no `?=` and no -D forwarding existed for any of these three +# before Phase 4, so hosted builds always got starforth_config.h's bare +# defaults (256/1000/5000) with no override mechanism at all. The kernel +# Makefile has always had opt-in forwarding for them (VM_FEATURE_FLAG_VARS). +# Promoted here for parity, same treatment as Phase 3's SSM_* knobs. +$(eval $(call kconfig_int,HEARTBEAT_CHECK_FREQUENCY,256)) +$(eval $(call kconfig_int,HEARTBEAT_WINDOW_TUNING_FREQUENCY,1000)) +$(eval $(call kconfig_int,HEARTBEAT_SLOPE_VALIDATION_FREQUENCY,5000)) + +# HISTORICAL: L4Re had no pthreads, so this forced HEARTBEAT_THREAD_ENABLED +# off whenever L4RE=1 was set. L4Re support is no longer an active target; +# see "Platform support" below. +# ifeq ($(L4RE),1) +# HEARTBEAT_THREAD_ENABLED := 0 +# endif + +# Feedback Loop Toggle Switches (for systematic performance measurement) +# ============================================================================ +# These allow turning each feedback loop on/off to measure additive performance gains +# EXP_00-BASELINE: all loops OFF (plain FORTH-79) +# EXP_01: Loop #1 ON +# EXP_02: Loops #1-2 ON +# ... etc, building cumulatively to measure each loop's contribution + +# ============================================================================== +# SSM (Steady State Machine) Configuration - Data-Driven Architecture +# ============================================================================== +# Based on 2^7 DoE with 300 reps (128 configs, 38,400 runs). +# Top 5% analysis (speed + stability) reveals optimal loop combinations. +# +# Experimentally Validated Architecture: +# L1 (heat_tracking): DISABLED (harmful in 86% of top configs) +# L4 (pipelining_metrics): DISABLED (harmful in 100% of top configs) +# L7 (adaptive_heartrate): ALWAYS ON (beneficial in 71% of top configs) +# L2, L3, L5, L6: Runtime-controlled by L8 (workload-dependent) +# L8 (Jacquard): 4-bit mode selector (16 modes: C0-C15) +# +# L8 dynamically controls L2/L3/L5/L6 based on entropy, CV, and temporal metrics. +# Top 5% validated modes: C4, C7, C9, C11, C12 (see v3/src/ssm_jacquard.c) + +# Tuning Knobs (Physics-driven Optimization System) +# ============================================================================ +# Knob #7: ROLLING_WINDOW_SIZE (Initial execution history capture) +# - Default: 4096 (conservative, ensures statistical significance at cold start) +# - Usage: make ROLLING_WINDOW_SIZE=8192 (larger for complex workloads) +# or ROLLING_WINDOW_SIZE=2048 (smaller for memory constraints) +# - System AUTOMATICALLY shrinks during execution if diminishing returns detected +# - Window starts conservative, self-tunes down if pattern diversity plateaus +# - Window becomes "warm" (representative) after N executions, then adapts +$(eval $(call kconfig_int,ROLLING_WINDOW_SIZE,4096)) + +# Knob #6: TRANSITION_WINDOW_SIZE (Pipelining context depth) +# - Default: 8 (see starforth_config.h for the exact shipped value) +# - Usage: make TRANSITION_WINDOW_SIZE=1 (or 2, 4 for shallower context) +# - Empirically tuned via binary chop: 1 vs 2 vs 4 vs 8 +$(eval $(call kconfig_int,TRANSITION_WINDOW_SIZE,8)) + +# SPECULATION_THRESHOLD_Q48 / SPECULATION_DEPTH / MIN_SAMPLES_FOR_SPECULATION / +# MISPREDICTION_COST_Q48 / MINIMUM_PREFETCH_ROI: previously hardcoded, +# non-overridable #define in physics_pipelining_metrics.h -- no Makefile +# knob or -D forwarding existed for any of these five before Phase 5. +# Promoted here for parity, same treatment as Phase 3/4's other +# previously-unwired constants. All five are Q48.16-fixed-point or plain +# counts meaningful only when ENABLE_PIPELINING is on; see Kconfig.physics +# for the exact hex/decimal defaults. MINIMUM_PREFETCH_ROI's default was +# corrected from the long-shipped 0x11999A to 0x1199A (rev y) -- the +# former was ~17.6 in Q48.16, not the documented 1.10. +$(eval $(call kconfig_int,SPECULATION_THRESHOLD_Q48,0x8000)) +$(eval $(call kconfig_int,SPECULATION_DEPTH,1)) +$(eval $(call kconfig_int,MIN_SAMPLES_FOR_SPECULATION,10)) +$(eval $(call kconfig_int,MISPREDICTION_COST_Q48,0x190000)) +$(eval $(call kconfig_int,MINIMUM_PREFETCH_ROI,0x1199A)) + +# Knobs #8-11: Adaptive Window Shrinking Control +# ============================================================================ +# These control how aggressively the rolling window learns and adapts +# (NOT the initial window size - that's ROLLING_WINDOW_SIZE above) + +# Knob #8: ADAPTIVE_SHRINK_RATE (percentage to retain when shrinking) +# - Default: 50 (shrink to 50% = discard 50% each cycle) +# - Range: 50-95 (lower = more aggressive, higher = more conservative) +# - Usage: make ADAPTIVE_SHRINK_RATE=75 (slower learning) or 90 (slow learning) +$(eval $(call kconfig_int,ADAPTIVE_SHRINK_RATE,50)) + +# Knob #9: ADAPTIVE_MIN_WINDOW_SIZE (floor to prevent over-shrinking) +# - Default: 256 (never shrink below 256 word IDs) +# - Range: 64-1024 (smaller = leaner, larger = safer) +# - Usage: make ADAPTIVE_MIN_WINDOW_SIZE=512 (conservative) or 128 (lean) +$(eval $(call kconfig_int,ADAPTIVE_MIN_WINDOW_SIZE,256)) + +# Knob #10: ADAPTIVE_CHECK_FREQUENCY (how often to measure diversity) +# - Default: 512 (check after every 512 executions) +# - Range: 32-1024 (more = faster response, less = less overhead) +# - Usage: make ADAPTIVE_CHECK_FREQUENCY=128 (responsive) or 256 (default of comparable knobs) +$(eval $(call kconfig_int,ADAPTIVE_CHECK_FREQUENCY,512)) + +# Knob #11: ADAPTIVE_GROWTH_THRESHOLD (growth rate that signals saturation) +# - Default: 5 (shrink when growth < 5%) +# - Range: 0-10 (lower = eager shrinking, higher = cautious) +# - Usage: make ADAPTIVE_GROWTH_THRESHOLD=0 (aggressive) or 1 (less conservative) +$(eval $(call kconfig_int,ADAPTIVE_GROWTH_THRESHOLD,5)) + +# Knob #11a: INITIAL_DECAY_SLOPE_Q48 (Starting decay slope for inference engine) +# - Default: 21845 (1/3 in Q48.16 format, = 0.333... starting slope) +# - Range: 13107-43691 (0.2 to 0.67 in Q48.16) +# - Usage: make INITIAL_DECAY_SLOPE_Q48=13107 (0.2) or 32768 (0.5) or 43691 (0.67) +# - DoE: OPP #3 tests 0.2, 0.33, 0.5, 0.67 to find optimal starting point for convergence +# - Note: Inference engine adapts this value at runtime; this is just the cold-start value +$(eval $(call kconfig_int,INITIAL_DECAY_SLOPE_Q48,21845)) + +# Knob #11b: DECAY_MIN_INTERVAL (Minimum time before decay applies) +# - Default: 500 (nanoseconds) +# - Range: 500-5000 (balance between decay sensitivity and overhead) +# - Usage: make DECAY_MIN_INTERVAL=1000 (slower decay) or 2000 (slower still) +# - NOTE: as of the tick-based Loop #3 decay conversion (rev t, see +# docs/working/architecture/VM-FLEET-ATTRACTOR-DESIGN-20260705.md), +# Loop #3 no longer consults this value at all -- decay is gated on +# elapsed heartbeat ticks, not elapsed nanoseconds. Kept only because +# doe_metrics.c still reports it as a metrics field; informational, +# not load-bearing. +$(eval $(call kconfig_int,DECAY_MIN_INTERVAL,500)) + +# Knob #11d: HEARTBEAT_INFERENCE_FREQUENCY (How often to run inference engine) +# - Default: 1000 (ticks between inference runs) +# - Set VERY HIGH (999999) to effectively disable inference (static mode) +# - Set LOW for frequent inference (adaptive mode) +# - DoE: OPP #3 tests 999999 (static, no Loop #6) vs 1000 (adaptive, with Loop #6) +# - Measures: Inference engine cost vs benefit in optimized performance +$(eval $(call kconfig_int,HEARTBEAT_INFERENCE_FREQUENCY,1000)) + +# Knob #12: DECAY_RATE_PER_US_Q16 (Heat decay rate in Q16 fixed-point) +# - Default: 1 (1/65536 heat units decayed per microsecond) +# - Range: 0-65536 (0 = no decay, 65536 = 1 heat/ยตs) +# - Half-life: ~6.5 seconds at default (100-heat word โ†’ 50-heat in 6.5s) +# - Usage: make DECAY_RATE_PER_US_Q16=2 (faster decay) or 0 (no decay for baseline) +# - DoE: Vary this to measure impact of heat decay on performance +$(eval $(call kconfig_int,DECAY_RATE_PER_US_Q16,1)) + +# L8 Jacquard mode selector thresholds (ssm_jacquard.h). Previously unwired -- +# no Makefile knob or -D forwarding existed for these before the Kconfig +# migration's Phase 3; ssm_jacquard.h's own #ifndef fallback was the only +# place any of these five values lived. See Kconfig.physics for the +# rationale behind modeling the four float thresholds as Kconfig `string` +# symbols (Kconfig has no native float type). +$(eval $(call kconfig_int,SSM_ENTROPY_HIGH_THRESHOLD,0.75)) +$(eval $(call kconfig_int,SSM_CV_HIGH_THRESHOLD,0.15)) +$(eval $(call kconfig_int,SSM_TEMPORAL_DECAY_THRESHOLD,0.5)) +$(eval $(call kconfig_int,SSM_TEMPORAL_DECAY_LOW_THRESHOLD,0.3)) +$(eval $(call kconfig_int,SSM_HYSTERESIS_TICKS,5)) + +# Build the CFLAGS with tuning knobs +# L8 FINAL INTEGRATION: All experimental loop flags removed. +# L1-L7 are now always-on internal physics layers. +# L8 Jacquard mode selector is the sole policy engine. +BASE_CFLAGS = -std=c99 -Wall -Werror -Iv3/include -Ikernel/include -Iv3/src/word_source -Iv3/src/test_runner/include \ + -DSTRICT_PTR=$(STRICT_PTR) \ + -DENABLE_HOTWORDS_CACHE=$(ENABLE_HOTWORDS_CACHE) \ + -DENABLE_PIPELINING=$(ENABLE_PIPELINING) \ + -DROLLING_WINDOW_SIZE=$(ROLLING_WINDOW_SIZE) \ + -DTRANSITION_WINDOW_SIZE=$(TRANSITION_WINDOW_SIZE) \ + -DSPECULATION_THRESHOLD_Q48=$(SPECULATION_THRESHOLD_Q48) \ + -DSPECULATION_DEPTH=$(SPECULATION_DEPTH) \ + -DMIN_SAMPLES_FOR_SPECULATION=$(MIN_SAMPLES_FOR_SPECULATION) \ + -DMISPREDICTION_COST_Q48=$(MISPREDICTION_COST_Q48) \ + -DMINIMUM_PREFETCH_ROI=$(MINIMUM_PREFETCH_ROI) \ + -DADAPTIVE_SHRINK_RATE=$(ADAPTIVE_SHRINK_RATE) \ + -DADAPTIVE_MIN_WINDOW_SIZE=$(ADAPTIVE_MIN_WINDOW_SIZE) \ + -DADAPTIVE_CHECK_FREQUENCY=$(ADAPTIVE_CHECK_FREQUENCY) \ + -DADAPTIVE_GROWTH_THRESHOLD=$(ADAPTIVE_GROWTH_THRESHOLD) \ + -DINITIAL_DECAY_SLOPE_Q48=$(INITIAL_DECAY_SLOPE_Q48) \ + -DDECAY_RATE_PER_US_Q16=$(DECAY_RATE_PER_US_Q16) \ + -DHEARTBEAT_THREAD_ENABLED=$(HEARTBEAT_THREAD_ENABLED) \ + -DHEARTBEAT_TICK_NS=$(HEARTBEAT_TICK_NS) \ + -DHEARTBEAT_INFERENCE_FREQUENCY=$(HEARTBEAT_INFERENCE_FREQUENCY) \ + -DHEARTBEAT_CHECK_FREQUENCY=$(HEARTBEAT_CHECK_FREQUENCY) \ + -DHEARTBEAT_WINDOW_TUNING_FREQUENCY=$(HEARTBEAT_WINDOW_TUNING_FREQUENCY) \ + -DHEARTBEAT_SLOPE_VALIDATION_FREQUENCY=$(HEARTBEAT_SLOPE_VALIDATION_FREQUENCY) \ + -DEMERGENCY_CONSOLE_ENABLED=$(EMERGENCY_CONSOLE_ENABLED) \ + -DSSM_ENTROPY_HIGH_THRESHOLD=$(SSM_ENTROPY_HIGH_THRESHOLD) \ + -DSSM_CV_HIGH_THRESHOLD=$(SSM_CV_HIGH_THRESHOLD) \ + -DSSM_TEMPORAL_DECAY_THRESHOLD=$(SSM_TEMPORAL_DECAY_THRESHOLD) \ + -DSSM_TEMPORAL_DECAY_LOW_THRESHOLD=$(SSM_TEMPORAL_DECAY_LOW_THRESHOLD) \ + -DSSM_HYSTERESIS_TICKS=$(SSM_HYSTERESIS_TICKS) + +ifeq ($(HEARTBEAT_THREAD_ENABLED),1) +# HISTORICAL: this used to branch on L4RE (no pthreads there) -- +# THREAD_FLAGS := if L4RE else -pthread. L4Re support is no longer an +# active target; see "Platform support" below. +THREAD_FLAGS := -pthread +else +THREAD_FLAGS := +endif + +BASE_CFLAGS += $(THREAD_FLAGS) + +# Build profiles (TARGET values) +SUPPORTED_TARGETS := standard fast fastest turbo asan + +TARGET_DESCRIPTION_standard := Standard optimized build +TARGET_CFLAGS_standard := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O2 -flto=auto -fuse-linker-plugin -DNDEBUG \ + -DUSE_ASM_OPT=1 \ + -ffunction-sections -fdata-sections -fomit-frame-pointer \ + -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-strict-aliasing +TARGET_LDFLAGS_standard := -Wl,--gc-sections -s -flto=auto -fuse-linker-plugin -static $(THREAD_FLAGS) + +TARGET_DESCRIPTION_fast := Fast optimized build (no LTO, easier debugging) +TARGET_CFLAGS_fast := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG +TARGET_LDFLAGS_fast := -s $(THREAD_FLAGS) + +TARGET_DESCRIPTION_fastest := Maximum performance build (ASM + LTO + direct threading) +TARGET_CFLAGS_fastest := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG \ + -flto=auto -fuse-linker-plugin -funroll-loops -finline-functions -fomit-frame-pointer -fno-plt -fno-semantic-interposition +TARGET_LDFLAGS_fastest := -flto=auto -fuse-linker-plugin -s -Wl,--gc-sections $(THREAD_FLAGS) + +TARGET_DESCRIPTION_turbo := Assembly-optimized build (no direct threading) +TARGET_CFLAGS_turbo := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O3 -DUSE_ASM_OPT=1 -DNDEBUG -flto +TARGET_LDFLAGS_turbo := -flto -s $(THREAD_FLAGS) + +TARGET_DESCRIPTION_asan := ASan/UBSan instrumented build for memory error detection +TARGET_CFLAGS_asan := $(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O1 -g \ + -fsanitize=address,undefined -fno-omit-frame-pointer +TARGET_LDFLAGS_asan := -fsanitize=address,undefined $(THREAD_FLAGS) + +define TARGET_POST_fastest + @echo "" + @echo "๐ŸŽฏ You've built the FASTEST FORTH IN THE WEST!" + @echo "" + @echo "Quick-draw benchmark:" + @time -f " โฑ๏ธ Time: %E seconds" ./$(BINARY) -c ": BENCH 1000000 0 DO 1 2 + DROP LOOP ; BENCH BYE" 2>/dev/null || true +endef + +TARGET_DESCRIPTION := $(TARGET_DESCRIPTION_$(TARGET)) +ifeq ($(strip $(TARGET_DESCRIPTION)),) + $(error Unknown TARGET '$(TARGET)'. Supported targets: $(SUPPORTED_TARGETS)) +endif + +TARGET_CFLAGS_SELECTED := $(TARGET_CFLAGS_$(TARGET)) +TARGET_LDFLAGS_SELECTED := $(TARGET_LDFLAGS_$(TARGET)) +TARGET_POST := $(or $(TARGET_POST_$(TARGET)),@:) + +CFLAGS ?= $(TARGET_CFLAGS_SELECTED) +LDFLAGS ?= $(TARGET_LDFLAGS_SELECTED) + +CFLAGS += $(EXTRA_CFLAGS) +LDFLAGS += $(EXTRA_LDFLAGS) + +USE_ASM_OPT := $(if $(findstring -DUSE_ASM_OPT=1,$(CFLAGS)),1,0) +USE_LTO := $(if $(or $(findstring -flto,$(CFLAGS)),$(findstring -flto,$(LDFLAGS))),1,0) + +# Platform support +# +# HISTORICAL: L4Re/Fiasco.OC was a supported platform target (`make L4RE=1`) +# through mid-2026. Removed as an active target; v3/src/platform/l4re/time.c +# is retained for reference but no longer wired into any build. To restore: +# reinstate the `else ifdef L4RE` branch below and the L4RE-conditional +# logic marked HISTORICAL elsewhere in this Makefile (search "L4RE"/"L4Re"). +# +# ifdef MINIMAL +# ... +# else ifdef L4RE +# CFLAGS += -D__l4__=1 +# PLATFORM_TIME_SRC = v3/src/platform/l4re/time.c v3/src/platform/platform_init.c +# PLATFORM_ALLOC_SRC = v3/src/platform/alloc_kernel.c +# else +# ... +# endif +ifdef MINIMAL +# DISABLED 2026-07-08: this was never a finished feature, not a small bug. +# v3/src/platform/starforth_minimal.c (referenced below) does not exist +# anywhere in the repo, and only 5 of ~90 source files under v3/src/ have any +# STARFORTH_MINIMAL awareness despite -nostdlib -ffreestanding applying to +# the entire tree. Confirmed by trying it: even a throwaway empty stub for +# the missing file lets the build report "success" while linking a binary +# with no _start entry point (this build's specific -nostdlib/-static/ +# -pthread/-flto flag combination doesn't actually exclude libc, so most +# calls silently resolve anyway -- the illusion of success is the trap). +# Reviving this needs an actual freestanding platform layer written from +# scratch, not a quick fix -- failing loudly here instead of letting +# anyone hit a confusing compile error or, worse, a binary that "builds" +# but can't run. See .claude/CLAUDE.md's punch list for status. +$(error MINIMAL=1 build is disabled: incomplete freestanding platform layer, not currently supported. See the comment immediately above this line for why) +CFLAGS += -DSTARFORTH_MINIMAL=1 -nostdlib -ffreestanding +LDFLAGS += -nostdlib +PLATFORM_SRC = v3/src/platform/starforth_minimal.c +PLATFORM_ALLOC_SRC = v3/src/platform/alloc_kernel.c +else +PLATFORM_TIME_SRC = v3/src/platform/linux/time.c v3/src/platform/linux/io.c v3/src/platform/platform_init.c +PLATFORM_ALLOC_SRC = v3/src/platform/alloc_host.c +endif + +PLATFORM_COMMON_SRC = v3/src/platform/threading.c $(PLATFORM_ALLOC_SRC) + +# Source and object files +SRC = $(wildcard v3/src/*.c v3/src/word_source/*.c v3/src/test_runner/*.c v3/src/test_runner/modules/*.c) $(PLATFORM_SRC) $(PLATFORM_TIME_SRC) $(PLATFORM_COMMON_SRC) +BUILD_ROOT ?= build +build_dir = $(BUILD_ROOT)/$(call canon_arch,$(or $2,$(ARCH)))/$1 +binary_path = $(call build_dir,$1,$2)/starforth +BUILD_DIR = $(call build_dir,$(TARGET),$(ARCH)) +BINARY = $(call binary_path,$(TARGET),$(ARCH)) +OBJ = $(patsubst v3/src/%.c,$(BUILD_DIR)/%.o,$(SRC)) +ASM_FILES = $(patsubst v3/src/%.c,$(BUILD_DIR)/%.s,$(SRC)) + +# Profiler support for test targets +PROFILE_LEVEL := $(strip $(PROFILE)) +ifeq ($(PROFILE_LEVEL),) +PROFILE_ARGS := +else +PROFILE_ARGS := --profile $(PROFILE_LEVEL) +PROFILE_REPORT ?= 1 +ifneq ($(strip $(PROFILE_REPORT)),0) +PROFILE_ARGS += --profile-report +endif +endif + +# Installation directories +PREFIX ?= . +BINDIR = $(PREFIX)/bin +MANDIR = $(PREFIX)/share/man/man1 +INFODIR = $(PREFIX)/share/info +DOCDIR = $(PREFIX)/share/doc/starforth +CONFDIR = $(PREFIX)/etc/starforth + +# ============================================================================== +# PHONY TARGETS +# ============================================================================== + +.PHONY: all banner help clean clean-obj clean-docs starkernel mkcapsule capsule-gen capsule-manifest +.PHONY: fastest fast turbo +.PHONY: rpi4 rpi4-cross rpi4-fastest riscv64-clang +.PHONY: minimal debug profile performance +.PHONY: test bench benchmark +.PHONY: asm sbom +.PHONY: docs api-docs docs-latex docs-isabelle isabelle-build isabelle-check info math-companion math-companion-clean +.PHONY: refinement-status refinement-init refinement-phase1 verify-defect refinement-annotate-check refinement-report +.PHONY: install uninstall package deb rpm +.PHONY: quality compile_commands clang_tidy cppcheck gcc_analyzer +.PHONY: FORCE version-info build-manifest + +# ============================================================================== +# MAIN TARGETS +# ============================================================================== + +all: banner $(BINARY) + @echo "" + @echo "โœ“ Build complete: $(BINARY)" + @echo " Architecture: $(ARCH_NAME)" + @echo " Profile: $(TARGET_DESCRIPTION) ($(TARGET))" + @echo " Output directory: $(BUILD_DIR)" + @echo " Optimizations: $(if $(findstring USE_ASM_OPT,$(CFLAGS)),Enabled,Disabled)" + @echo " Direct Threading: $(if $(findstring USE_DIRECT_THREADING,$(CFLAGS)),Enabled,Disabled)" + @mkdir -p lfs/$(ARCH_DIR) + @cp $(BINARY) lfs/$(ARCH_DIR)/starforth + @echo " LFS copy: lfs/$(ARCH_DIR)/starforth" + $(TARGET_POST) + +banner: + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo " โšก Building the Fastest Forth in the West! โšก" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo " Target Architecture: $(ARCH_NAME) ($(ARCH_DIR))" + @echo " Build Profile: $(TARGET_DESCRIPTION) ($(TARGET))" + @echo "" + +# ============================================================================== +# OPTIMIZATION BUILDS - The Fastest in the West +# ============================================================================== + +# Maximum performance - no compromises +fastest: + @echo "๐Ÿ† Building FASTEST configuration..." + @echo " - Architecture: $(ARCH_NAME)" + @echo " - Assembly optimizations: ENABLED" + @echo " - Direct threading: ENABLED" + @echo "" + @$(MAKE) -f v3/Makefile TARGET=fastest all + +# Fast without LTO (easier debugging) +fast: + @echo "โšก Building FAST configuration (no LTO for debugging)..." + @$(MAKE) -f v3/Makefile TARGET=fast all + +# Assembly optimizations only (no direct threading) +turbo: + @echo "๐Ÿš€ Building TURBO configuration (ASM only)..." + @$(MAKE) -f v3/Makefile TARGET=turbo all + +# ============================================================================== +# PLATFORM-SPECIFIC BUILDS +# ============================================================================== + +# Raspberry Pi 4 - native build +rpi4: + @echo "๐Ÿฅง Building for Raspberry Pi 4 (native)..." + @$(MAKE) -f v3/Makefile ARCH=raspi TARGET=fastest CFLAGS="$(BASE_CFLAGS) -march=armv8-a+crc+simd -mtune=cortex-a72 -DARCH_ARM64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto" LDFLAGS="-flto -s" all + @echo "โœ“ Raspberry Pi build ready: $(call binary_path,fastest,raspi)" + +# Raspberry Pi 4 - cross-compile from x86_64 +rpi4-cross: + @echo "๐Ÿฅง Cross-compiling for Raspberry Pi 4..." + @$(MAKE) -f v3/Makefile ARCH=raspi TARGET=fastest CC=aarch64-linux-gnu-gcc \ + CFLAGS="$(BASE_CFLAGS) -march=armv8-a+crc+simd -mtune=cortex-a72 -DARCH_ARM64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto -static" \ + LDFLAGS="-flto -s -static" \ + all + @echo "โœ“ Cross-compiled binary ready: $(call binary_path,fastest,raspi)" + @echo " Copy to RPi4: scp $(call binary_path,fastest,raspi) pi@raspberrypi.local:~/" + +# Raspberry Pi 4 - maximum optimization +rpi4-fastest: + @echo "๐Ÿฅงโšก Building FASTEST for Raspberry Pi 4..." + @$(MAKE) -f v3/Makefile ARCH=raspi TARGET=fastest CC=aarch64-linux-gnu-gcc \ + CFLAGS="$(BASE_CFLAGS) -march=armv8-a+crc+simd+crypto -mtune=cortex-a72 -DARCH_ARM64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto -funroll-loops -finline-functions" \ + LDFLAGS="-flto -s -static" \ + all + @echo "โœ“ Raspberry Pi FASTEST build ready: $(call binary_path,fastest,raspi)" + +# RISC-V 64 - cross-compile via clang (GCC fails to build this tree under +# -std=c99: a nanosleep visibility failure, not yet root-caused โ€” see +# docs/lithosananke/hosted-acceptance-test/README.md and +# docs/working/archive/session-logs/2026-07-24-punch-list.md item #3). +# CFLAGS deliberately does NOT reuse $(BASE_CFLAGS): BASE_CFLAGS hardcodes +# -std=c99, and clang needs -std=c11 -pthread here. This mirrors the exact +# recipe verified in the hosted-acceptance-test doc, kept in sync with it. +riscv64-clang: + @echo "๐Ÿฆ€ Cross-compiling for RISC-V 64 (clang)..." + @$(MAKE) -f v3/Makefile ARCH=riscv64 TARGET=fastest \ + CC="clang-18 --target=riscv64-linux-gnu --sysroot=/usr/riscv64-linux-gnu" \ + CFLAGS="-std=c11 -pthread -Wall -Werror -Iv3/include -Ikernel/include -Iv3/src/word_source -Iv3/src/test_runner/include -DSTRICT_PTR=1 -march=rv64gc -mabi=lp64d -mcmodel=medany -DARCH_RISCV64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto -static" \ + LDFLAGS="-flto -s -static -fuse-ld=lld" \ + all + @echo "โœ“ Cross-compiled binary ready: $(call binary_path,fastest,riscv64)" + @echo " Run: qemu-riscv64 $(call binary_path,fastest,riscv64)" + +# Minimal/embedded build +minimal: + $(MAKE) -f v3/Makefile MINIMAL=1 + +# HISTORICAL: L4Re support removed as an active target (see "Platform +# support" above). This target cross-compiled a minimal build with the +# L4Re toolchain (l4-gcc) for smoke-testing without real L4Re headers. +# fake-l4re: +# $(MAKE) -f v3/Makefile MINIMAL=1 CC=l4-gcc CFLAGS="$(BASE_CFLAGS) -DL4RE_TARGET=1" + +# ============================================================================== +# DEBUG & DEVELOPMENT BUILDS +# ============================================================================== + +# Debug build with symbols +debug: banner + @echo "๐Ÿ› Building DEBUG configuration..." + $(MAKE) -f v3/Makefile CFLAGS="$(BASE_CFLAGS) -O0 -g -DDEBUG" LDFLAGS="" $(BINARY) + +# Build with profiler support +profile: + $(MAKE) -f v3/Makefile CFLAGS="$(BASE_CFLAGS) -g -O1" $(BINARY) + +# Performance build (legacy alias - redirects to 'fastest') +performance: fastest + +# ============================================================================== +# BUILD RULES +# ============================================================================== + +# Generate version header from Makefile VERSION, ARCH, TARGET, and timestamp +v3/include/version.h: FORCE + @mkdir -p v3/include + @echo "Generating version header..." + @BUILD_TS=$$(date -Iseconds 2>/dev/null || echo "unknown"); \ + printf '#ifndef STARFORTH_VERSION_H\n#define STARFORTH_VERSION_H\n\n' > $@; \ + printf '#define STARFORTH_VERSION "%s"\n' "$(VERSION)" >> $@; \ + printf '#define STARFORTH_ARCH "%s"\n' "$(ARCH_NAME)" >> $@; \ + printf '#define STARFORTH_TARGET "%s"\n' "$(TARGET)" >> $@; \ + printf '#define STARFORTH_TIMESTAMP "%s"\n' "$$BUILD_TS" >> $@; \ + printf '#define STARFORTH_VERSION_FULL "StarForth v%s %s %s %s"\n\n' "$(VERSION)" "$(ARCH_NAME)" "$(TARGET)" "$$BUILD_TS" >> $@; \ + printf '#endif /* STARFORTH_VERSION_H */\n' >> $@ + +# Ensure version.h exists and is up-to-date before compilation +FORCE: + +# ============================================================================== +# CAPSULE SUBSYSTEM +# ============================================================================== + +CAPSULES_DIR ?= capsules +MKCAPSULE_SRC = tools/mkcapsule.c +MKCAPSULE_BIN = $(BUILD_DIR)/tools/mkcapsule +CAPSULE_GENERATED = $(BUILD_DIR)/capsule_generated.c +CAPSULE_GENERATED_OBJ = $(BUILD_DIR)/capsule_generated.o +CAPSULE_MANIFEST = $(CAPSULES_DIR)/MANIFEST_AUTO.md + +# Build the mkcapsule host tool +$(MKCAPSULE_BIN): $(MKCAPSULE_SRC) + @mkdir -p $(dir $@) + @echo " HOSTCC $<" + @$(CC) -O2 -Wall -o $@ $< + +# Run mkcapsule to generate the capsule directory C source +$(CAPSULE_GENERATED): $(MKCAPSULE_BIN) $(CAPSULES_DIR) + @mkdir -p $(dir $@) + @echo " MKCAP $(CAPSULES_DIR) -> $@" + @$(MKCAPSULE_BIN) $(CAPSULES_DIR) $@ + +# Compile the generated capsule directory +$(CAPSULE_GENERATED_OBJ): $(CAPSULE_GENERATED) | v3/include/version.h + @mkdir -p $(dir $@) + @echo " CC $<" + @$(CC) $(CFLAGS) -c $< -o $@ + +.PHONY: mkcapsule capsule-gen capsule-manifest +mkcapsule: $(MKCAPSULE_BIN) +capsule-manifest: $(MKCAPSULE_BIN) + @echo " MANIFEST $(CAPSULES_DIR) -> $(CAPSULE_MANIFEST)" + @$(MKCAPSULE_BIN) --manifest $(CAPSULES_DIR) $(CAPSULE_MANIFEST) +capsule-gen: $(CAPSULE_GENERATED) capsule-manifest + +# starkernel: full capsule-aware build +# 1. Build mkcapsule tool +# 2. Generate capsule_generated.c from capsules/ +# 3. Compile StarForth with __STARKERNEL__ and capsule_generated.o linked in +starkernel: $(MKCAPSULE_BIN) $(CAPSULE_GENERATED_OBJ) + @$(MAKE) -f v3/Makefile $(BINARY) \ + EXTRA_CFLAGS="-D__STARKERNEL__=1 -Iv3/include -Ikernel/include" \ + EXTRA_OBJ="$(CAPSULE_GENERATED_OBJ)" + +# ============================================================================== +# Main executable +$(BINARY): $(OBJ) $(EXTRA_OBJ) + @echo "๐Ÿ”— Linking $(BINARY)..." + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +# Pattern rule for all C files (consolidates 5 repetitive rules) +# Order-only dependency: version.h must exist before compilation, but changes don't trigger rebuild +$(BUILD_DIR)/%.o: v3/src/%.c | v3/include/version.h + @mkdir -p $(dir $@) + @echo " CC $<" + @$(CC) $(CFLAGS) -c $< -o $@ +ifdef ASM + @$(CC) $(CFLAGS) -S $(ASM_SYNTAX) $< -o $(patsubst %.o,%.s,$@) +endif + +# Files that include version.h - rebuild when timestamp changes +$(BUILD_DIR)/main.o: v3/include/version.h +$(BUILD_DIR)/cli.o: v3/include/version.h +$(BUILD_DIR)/word_source/starforth_words.o: v3/include/version.h + +# ============================================================================== +# TESTING & BENCHMARKING +# ============================================================================== + +# Quick benchmark +bench: $(BINARY) + @echo "" + @echo "๐Ÿ‡ Running quick-draw benchmark..." + @echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + @echo "Test: 1 million stack operations" + @time -f "Time: %E seconds" ./$(BINARY) -c ": BENCH 1000000 0 DO 1 2 + DROP LOOP ; BENCH BYE" 2>/dev/null || echo "Benchmark complete" + @echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + +# Full benchmark suite +benchmark: $(BINARY) + @echo "" + @echo "๐ŸŽฏ Full Benchmark Suite - Fastest Forth in the West" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo "" + @echo "๐Ÿ“Š Stack Operations (1M iterations):" + @time -f " โฑ๏ธ %E seconds" ./$(BINARY) -c ": BENCH-STACK 1000000 0 DO 1 2 3 DROP DROP DROP LOOP ; BENCH-STACK BYE" 2>/dev/null || true + @echo "" + @echo "๐Ÿ“Š Arithmetic Operations (1M iterations):" + @time -f " โฑ๏ธ %E seconds" ./$(BINARY) -c ": BENCH-MATH 1000000 0 DO 10 20 + 5 * 100 / DROP LOOP ; BENCH-MATH BYE" 2>/dev/null || true + @echo "" + @echo "๐Ÿ“Š Logic Operations (1M iterations):" + @time -f " โฑ๏ธ %E seconds" ./$(BINARY) -c ": BENCH-LOGIC 1000000 0 DO 255 DUP AND DUP OR XOR DROP LOOP ; BENCH-LOGIC BYE" 2>/dev/null || true + @echo "" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + +# ============================================================================== +# ASSEMBLY OUTPUT & ANALYSIS +# ============================================================================== + +# Generate assembly files for inspection +asm: banner + @echo "๐Ÿ“ Generating assembly output..." + @echo " Cleaning to force rebuild..." + @$(MAKE) -f v3/Makefile clean-obj > /dev/null 2>&1 + $(MAKE) -f v3/Makefile ASM=1 CFLAGS="$(BASE_CFLAGS) $(ARCH_FLAGS) $(ARCH_DEFINES) -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1" LDFLAGS="" $(BINARY) + @echo "โœ“ Assembly files generated in $(BUILD_DIR)/" + @echo " Files generated: $$(find $(BUILD_DIR) -name '*.s' | wc -l)" + @echo " Example: less $(BUILD_DIR)/stack_management.s" + +# Generate Software Bill of Materials (SBOM) in SPDX format +sbom: + @echo "๐Ÿ“‹ Generating SBOM (Software Bill of Materials)..." + @if ! which syft >/dev/null 2>&1; then \ + echo "Error: syft not found. Install from https://github.com/anchore/syft"; \ + exit 1; \ + fi + @syft dir:. -o spdx-json=sbom.spdx.json -o spdx=sbom.spdx \ + --source-name LithosAnanke \ + --source-version $(VERSION) \ + --exclude './build/**' --exclude './tools/**' --exclude './.git/**' + @echo "โœ… SBOM generated:" + @echo " SPDX JSON: sbom.spdx.json" + @echo " SPDX: sbom.spdx" + @echo " Version: $(VERSION)" + +# ============================================================================== +# DOCUMENTATION +# ============================================================================== + +# Generate API documentation (Doxygen XML โ†’ AsciiDoc) +api-docs: + @echo "๐Ÿ“š Generating API documentation from Doxygen..." + @if [ ! -f scripts/generate-doxygen-appendix.sh ]; then \ + echo "Error: scripts/generate-doxygen-appendix.sh not found"; \ + exit 1; \ + fi + @./scripts/generate-doxygen-appendix.sh + @echo "โœ… API documentation generated: docs/src/appendix/" + +# ---------------------------------------------------------------------------- +# Math companion to the SSRN paper. +# Builds docs/SSRN_companion/Math_Companion_SSRN.pdf from the LaTeX source. +# Requires: pdflatex (texlive-latex-base, texlive-latex-extra, texlive-science). +# ---------------------------------------------------------------------------- +math-companion: + @echo "Building SSRN math companion (docs/SSRN_companion/Math_Companion_SSRN.pdf)..." + @if ! command -v pdflatex >/dev/null 2>&1; then \ + echo "Error: pdflatex not found."; \ + echo " Install with: apt-get install texlive-latex-base texlive-latex-extra texlive-science"; \ + exit 1; \ + fi + @cd docs/SSRN_companion && \ + pdflatex -interaction=nonstopmode -halt-on-error Math_Companion_SSRN.tex >/dev/null && \ + pdflatex -interaction=nonstopmode -halt-on-error Math_Companion_SSRN.tex >/dev/null && \ + pdflatex -interaction=nonstopmode -halt-on-error Math_Companion_SSRN.tex >/dev/null + @echo "Built: docs/SSRN_companion/Math_Companion_SSRN.pdf" + @cd docs/SSRN_companion && ls -lh Math_Companion_SSRN.pdf | awk '{print " Size:", $$5, " Pages: see pdfinfo"}' + +math-companion-clean: + @rm -f docs/SSRN_companion/Math_Companion_SSRN.{aux,log,out,toc,lof,lot,nav,snm,vrb} + @rm -f docs/SSRN_companion/Math_Companion_SSRN.pdf + @echo "Cleaned math companion build artifacts." + +# Convert all AsciiDoc to LaTeX +docs-latex: + @echo "๐Ÿ“„ Converting AsciiDoc to LaTeX..." + @if [ ! -f scripts/asciidoc-to-latex.sh ]; then \ + echo "Error: scripts/asciidoc-to-latex.sh not found"; \ + exit 1; \ + fi + @./scripts/asciidoc-to-latex.sh + @echo "โœ… LaTeX files generated: docs/latex/" + +# Build and verify Isabelle theories +isabelle-build: + @echo "๐Ÿ”ฌ Building Isabelle formal verification theories..." + @if ! command -v $(ISABELLE) >/dev/null 2>&1; then \ + echo "Error: Isabelle not found: $(ISABELLE)"; \ + echo " Install Isabelle or set ISABELLE variable"; \ + exit 1; \ + fi + @echo " Using: $$(command -v $(ISABELLE))" + @echo " Building StarForth_Formal session (VM + Physics)..." + @cd docs/src/internal/formal && $(ISABELLE) build -v -d . StarForth_Formal + @echo "โœ… Isabelle theories verified successfully" + +# Quick check of Isabelle theories (faster than full build) +isabelle-check: + @echo "๐Ÿ”ฌ Quick-checking Isabelle theories..." + @if ! command -v $(ISABELLE) >/dev/null 2>&1; then \ + echo "Error: Isabelle not found: $(ISABELLE)"; \ + exit 1; \ + fi + @cd docs/src/internal/formal && \ + for thy in *.thy; do \ + echo " Checking $$thy..."; \ + $(ISABELLE) process -T "$$thy" 2>&1 | head -5; \ + done + @echo "โœ… Quick check complete" + +# Generate comprehensive Isabelle documentation (for auditing & CI/CD) +# This generates documentation and verification reports regardless of proof status +# Suitable for Jenkinsfile pipelines - shows complete state including errors +docs-isabelle: + @echo "๐Ÿ“š Generating comprehensive Isabelle documentation (audit mode)..." + @mkdir -p docs/src/isabelle + @echo "" + @echo "Step 1: Attempting to verify Isabelle theories..." + @echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + @cd docs/src/internal/formal && \ + if $(ISABELLE) build -v -d . StarForth_Formal > "$(CURDIR)/docs/src/isabelle/build.log" 2>&1; then \ + echo "โœ… All theories verified successfully"; \ + else \ + echo "โš ๏ธ Some theories have incomplete proofs (see build.log for details)"; \ + fi + @echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" + @echo "" + @echo "Step 2: Generating documentation from theory source..." + @if [ ! -f scripts/isabelle-to-adoc.sh ]; then \ + echo "โš ๏ธ Warning: scripts/isabelle-to-adoc.sh not found"; \ + echo " Creating default script..."; \ + mkdir -p scripts; \ + echo '#!/bin/bash' > scripts/isabelle-to-adoc.sh; \ + echo 'echo "Generating Isabelle theory reports to AsciiDoc..."' >> scripts/isabelle-to-adoc.sh; \ + echo 'cd docs/src/internal/formal' >> scripts/isabelle-to-adoc.sh; \ + echo 'for thy in *.thy; do' >> scripts/isabelle-to-adoc.sh; \ + echo ' base=$$(basename "$$thy" .thy)' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "= $$base Theory" > "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "Formal verification theory for StarForth VM." >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "== Theory Source" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "[source,isabelle]" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "----" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' cat "$$thy" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo ' echo "----" >> "../../../isabelle/$$base.adoc"' >> scripts/isabelle-to-adoc.sh; \ + echo 'done' >> scripts/isabelle-to-adoc.sh; \ + chmod +x scripts/isabelle-to-adoc.sh; \ + fi + @bash scripts/isabelle-to-adoc.sh + @echo "" + @echo "Step 3: Creating audit summary..." + @echo "โœ… Comprehensive Isabelle documentation generated: docs/src/isabelle/" + @echo "" + @echo "๐Ÿ“‚ Documentation includes:" + @echo " โ€ข index.adoc - Master index of all theories" + @echo " โ€ข VERIFICATION_REPORT.adoc - Audit report" + @echo " โ€ข .adoc - Individual theory documentation with source" + @echo " โ€ข build.log - Isabelle build output (verification status)" + +# ============================================================================== +# REFINEMENT VERIFICATION (C โŠ‘ Isabelle) +# ============================================================================== + +# Refinement status dashboard +refinement-status: + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo " StarForth C โŠ‘ Isabelle Refinement Status" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo "" + @if [ ! -f docs/REFINEMENT_CAPA.adoc ]; then \ + echo "โš ๏ธ No REFINEMENT_CAPA.adoc found. Initialize with: make refinement-init"; \ + echo ""; \ + echo "Refinement infrastructure status: UNINITIALIZED"; \ + else \ + echo "๐Ÿ“‹ Defect Summary:"; \ + echo ""; \ + echo -n " Total Defects: "; grep -c "^== DEFECT-" docs/REFINEMENT_CAPA.adoc || echo "0"; \ + echo -n " OPEN: "; grep "| OPEN" docs/REFINEMENT_CAPA.adoc | wc -l; \ + echo -n " IN-PROGRESS: "; grep "| IN-PROGRESS" docs/REFINEMENT_CAPA.adoc | wc -l; \ + echo -n " CLOSED: "; grep "| CLOSED" docs/REFINEMENT_CAPA.adoc | wc -l; \ + fi + @echo "" + @echo "๐Ÿ† Phase Status:" + @echo " Phase 1: vm.c core .............. NOT STARTED" + @echo " Phase 2: Root utilities ......... NOT STARTED" + @echo " Phase 3: Test harness .......... NOT STARTED" + @echo " Phase 4: Primitive dictionary .. NOT STARTED" + @echo " Phase 5: VM expansion .......... NOT STARTED" + @echo "" + @echo "๐Ÿ“‚ Documentation:" + @echo " โ€ข docs/REFINEMENT_CAPA.adoc - Defect tracking" + @echo " โ€ข docs/REFINEMENT_ANNOTATIONS.adoc - Code annotation guide" + @echo "" + @echo "Next steps: make refinement-phase1 (to start Phase 1 proofs)" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + +# Initialize refinement tracking +refinement-init: + @echo "Initializing refinement tracking..." + @if [ -f docs/REFINEMENT_CAPA.adoc ]; then \ + echo "โœ… docs/REFINEMENT_CAPA.adoc already exists"; \ + else \ + echo "๐Ÿ“‹ Creating REFINEMENT_CAPA.adoc"; \ + fi + @if [ -f docs/REFINEMENT_ANNOTATIONS.adoc ]; then \ + echo "โœ… docs/REFINEMENT_ANNOTATIONS.adoc already exists"; \ + else \ + echo "๐Ÿ“‹ Creating REFINEMENT_ANNOTATIONS.adoc"; \ + fi + @echo "โœ… Refinement infrastructure ready" + @echo "" + @echo "Next: Review docs/REFINEMENT_ANNOTATIONS.adoc" + @echo " Then: make refinement-phase1" + +# Phase 1: VM Core refinement +refinement-phase1: + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo " โš™๏ธ PHASE 1: VM Core Refinement (C โŠ‘ Isabelle)" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo "" + @echo "Building refinement proofs for:" + @echo " โ€ข stack_push / stack_pop (DEFECT-001, DEFECT-002)" + @echo " โ€ข execute_call / execute_return (DEFECT-002)" + @echo " โ€ข instruction_dispatch (DEFECT-003)" + @echo "" + @echo "Proof target: StarForth_Refinement (Isabelle theory)" + @if ! command -v $(ISABELLE) >/dev/null 2>&1; then \ + echo "Error: Isabelle not found. Install or set ISABELLE variable"; \ + exit 1; \ + fi + @echo "" + @echo "Step 1: Creating StarForth_Refinement.thy if needed..." + @if [ ! -f docs/src/internal/formal/StarForth_Refinement.thy ]; then \ + echo "Creating template..."; \ + mkdir -p docs/src/internal/formal; \ + touch docs/src/internal/formal/StarForth_Refinement.thy; \ + echo "TODO: Add refinement proofs here" > docs/src/internal/formal/StarForth_Refinement.thy; \ + fi + @echo "" + @echo "Step 2: Attempting to build refinement proofs..." + @echo "(This will fail until proofs are written)" + @cd docs/src/internal/formal && \ + $(ISABELLE) build -v -d . StarForth_Formal 2>&1 | tail -20 + @echo "" + @echo "๐Ÿ“‹ Next steps:" + @echo " 1. Review open defects: grep 'OPEN' docs/REFINEMENT_CAPA.adoc" + @echo " 2. Start working on DEFECT-001 (stack_push)" + @echo " 3. Add refinement proofs to StarForth_Refinement.thy" + @echo " 4. Run: make verify-defect DEFECT=001" + +# Verify specific defect resolution +verify-defect: + @if [ -z "$(DEFECT)" ]; then \ + echo "Usage: make verify-defect DEFECT=001"; \ + echo ""; \ + echo "Available defects:"; \ + grep "== DEFECT-" docs/REFINEMENT_CAPA.adoc | sed 's/== / /'; \ + exit 1; \ + fi + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo " ๐Ÿ” Verifying Resolution: $(DEFECT)" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo "" + @if ! grep -q "== DEFECT-$(DEFECT):" docs/REFINEMENT_CAPA.adoc; then \ + echo "โŒ DEFECT-$(DEFECT) not found in REFINEMENT_CAPA.adoc"; \ + exit 1; \ + fi + @echo "Defect Details:" + @grep -A 30 "== DEFECT-$(DEFECT):" docs/REFINEMENT_CAPA.adoc | head -35 + @echo "" + @echo "Next: Implement corrective action, then run this again" + +# Check code annotation coverage +refinement-annotate-check: + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo " ๐Ÿ“ Checking Code Annotation Coverage" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo "" + @echo "Phase 1 target functions:" + @echo "" + @for func in stack_push stack_pop execute_instruction execute_call execute_return; do \ + if grep -q "REFINEMENT.*$$func\|void $$func" v3/src/vm.c; then \ + if grep -q "REFINEMENT:" v3/src/vm.c | grep -q "$$func"; then \ + echo " โœ… $$func - ANNOTATED"; \ + else \ + echo " โŒ $$func - MISSING ANNOTATION"; \ + fi; \ + else \ + echo " โš ๏ธ $$func - NOT FOUND"; \ + fi; \ + done + @echo "" + @echo "Guide: docs/REFINEMENT_ANNOTATIONS.adoc" + +# Generate refinement report +refinement-report: + @echo "๐Ÿ”„ Generating refinement status report..." + @mkdir -p docs/reports + @echo "# StarForth Refinement Status" > docs/reports/refinement-status.md + @echo "" >> docs/reports/refinement-status.md + @echo "Generated: $$(date)" >> docs/reports/refinement-status.md + @echo "" >> docs/reports/refinement-status.md + @echo "## Summary" >> docs/reports/refinement-status.md + @echo "" >> docs/reports/refinement-status.md + @grep -c "== DEFECT-" docs/REFINEMENT_CAPA.adoc | xargs -I {} echo "Total Defects: {}" >> docs/reports/refinement-status.md + @echo "" >> docs/reports/refinement-status.md + @echo "See docs/REFINEMENT_CAPA.adoc for details" >> docs/reports/refinement-status.md + @echo "โœ… Report: docs/reports/refinement-status.md" + +# Generate GNU info documentation +docs/starforth.info: + @if [ ! -f docs/starforth.texi ]; then \ + echo "โš ๏ธ Skipping info docs: docs/starforth.texi not present"; \ + touch docs/starforth.info; \ + else \ + echo "๐Ÿ“– Building GNU info documentation..."; \ + if ! command -v makeinfo >/dev/null 2>&1; then \ + echo "Warning: makeinfo not found. Install with: sudo apt-get install texinfo"; \ + touch docs/starforth.info; \ + else \ + makeinfo docs/starforth.texi -o docs/starforth.info && \ + echo "โœ… Info documentation: docs/starforth.info"; \ + fi; \ + fi + +# Generate all documentation +docs: api-docs docs-isabelle + @echo "โœ… All documentation generated!" + @echo "" + @echo "๐Ÿ“‚ Documentation locations:" + @echo " โ€ข API docs: docs/src/appendix/" + @echo " โ€ข Isabelle docs: docs/src/isabelle/" + @echo " โ€ข LaTeX: docs/latex/" + +# Clean generated documentation +clean-docs: + @echo "๐Ÿ—‘๏ธ Cleaning generated documentation..." + @rm -rf docs/src/appendix/ docs/latex/ docs/src/isabelle/ + @echo "โœ… Documentation cleaned" + +# ============================================================================== +# INSTALLATION +# ============================================================================== + +install: $(BINARY) + @echo "๐Ÿ“ฆ Installing StarForth to $(PREFIX)..." + @install -d $(BINDIR) + @install -m 755 $(BINARY) $(BINDIR)/starforth + @echo " โœ“ Binary installed: $(BINDIR)/starforth" + @if [ -f capsules/init.4th ]; then \ + install -d $(CONFDIR); \ + install -m 644 capsules/init.4th $(CONFDIR)/init.4th; \ + echo " โœ“ Config installed: $(CONFDIR)/init.4th"; \ + fi + @if [ -f man/starforth.1 ]; then \ + install -d $(MANDIR); \ + install -m 644 man/starforth.1 $(MANDIR)/starforth.1; \ + echo " โœ“ Man page installed: $(MANDIR)/starforth.1"; \ + fi + @if [ -f docs/starforth.info ]; then \ + install -d $(INFODIR); \ + install -m 644 docs/starforth.info $(INFODIR)/starforth.info; \ + install-info --info-dir=$(INFODIR) $(INFODIR)/starforth.info 2>/dev/null || true; \ + echo " โœ“ Info docs installed: $(INFODIR)/starforth.info"; \ + fi + @install -d $(DOCDIR) + @if [ -f README.md ]; then install -m 644 README.md $(DOCDIR)/; fi + @if [ -f QUICKSTART.md ]; then install -m 644 QUICKSTART.md $(DOCDIR)/; fi + @if ls docs/*.md >/dev/null 2>&1; then install -m 644 docs/*.md $(DOCDIR)/ 2>/dev/null || true; fi + @echo " โœ“ Documentation installed: $(DOCDIR)/" + @echo "โœ… Installation complete!" + +uninstall: + @echo "๐Ÿ—‘๏ธ Uninstalling StarForth from $(PREFIX)..." + @rm -f $(BINDIR)/starforth + @rm -f $(MANDIR)/starforth.1 + @install-info --delete --info-dir=$(INFODIR) $(INFODIR)/starforth.info 2>/dev/null || true + @rm -f $(INFODIR)/starforth.info + @rm -rf $(DOCDIR) + @rm -rf $(CONFDIR) + @echo "โœ… Uninstall complete!" + +# ============================================================================== +# PACKAGING +# ============================================================================== + +# Build Debian package +deb: $(BINARY) + @echo "๐Ÿ“ฆ Building Debian package..." + @if ! command -v fpm >/dev/null 2>&1; then \ + echo "Error: fpm not found. Install with: gem install fpm"; \ + echo " or: sudo apt-get install ruby-dev && gem install fpm"; \ + exit 1; \ + fi + @mkdir -p package/deb + @fpm -s dir -t deb \ + -n starforth \ + -v $(VERSION) \ + -a native \ + --description "StarForth - The Fastest Forth in the West" \ + --url "https://github.com/yourusername/starforth" \ + --maintainer "StarForth Team" \ + --license "MIT" \ + --category "devel" \ + --package package/deb/ \ + --deb-compression xz \ + $(BINARY)=/usr/bin/starforth \ + capsules/init.4th=/etc/starforth/init.4th \ + README.md=/usr/share/doc/starforth/README.md + @echo "โœ… Debian package created: package/deb/starforth_$(VERSION)_*.deb" + +# Build RPM package +rpm: $(BINARY) + @echo "๐Ÿ“ฆ Building RPM package..." + @if ! command -v fpm >/dev/null 2>&1; then \ + echo "Error: fpm not found. Install with: gem install fpm"; \ + exit 1; \ + fi + @mkdir -p package/rpm + @fpm -s dir -t rpm \ + -n starforth \ + -v $(VERSION) \ + -a native \ + --description "StarForth - The Fastest Forth in the West" \ + --url "https://github.com/yourusername/starforth" \ + --maintainer "StarForth Team" \ + --license "MIT" \ + --category "Development/Languages" \ + --package package/rpm/ \ + $(BINARY)=/usr/bin/starforth \ + capsules/init.4th=/etc/starforth/init.4th \ + README.md=/usr/share/doc/starforth/README.md + @echo "โœ… RPM package created: package/rpm/starforth-$(VERSION)-*.rpm" + +# Build all packages +package: deb rpm + @echo "" + @echo "โœ… All packages built successfully!" + @echo " Debian: package/deb/" + @echo " RPM: package/rpm/" + +# ============================================================================== +# VERSIONING & BUILD MANIFEST (Workflow/Governance Integration) +# ============================================================================== + +# Parse version from v3/include/version.h +GET_VERSION = $(shell grep "define STARFORTH_VERSION" v3/include/version.h | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | head -1) + +.PHONY: version-info +version-info: + @echo "Current Version: $(GET_VERSION)" + @grep "STARFORTH_VERSION" v3/include/version.h | grep define + +.PHONY: build-manifest +build-manifest: $(BINARY) + @echo "๐Ÿ“‹ Generating BUILD_MANIFEST.json..." + @mkdir -p builds/manifest + @VERSION=$$(grep "STARFORTH_VERSION_STRING" v3/include/version.h | grep -o '"[^"]*"' | tr -d '"'); \ + GIT_HASH=$$(git rev-parse --short HEAD 2>/dev/null || echo "0000000"); \ + GIT_BRANCH=$$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown"); \ + BUILD_TIME=$$(date -Iseconds); \ + BINARY_PATH="$(BINARY)"; \ + if [ -f "$$BINARY_PATH" ]; then \ + BINARY_SHA256=$$(sha256sum "$$BINARY_PATH" | awk '{print $$1}'); \ + else \ + BINARY_SHA256="not-built"; \ + fi; \ + cat > builds/manifest/BUILD_MANIFEST.json << EOF; \ +{ \ + "version": "$$VERSION", \ + "timestamp": "$$BUILD_TIME", \ + "git": { \ + "commit_hash": "$$GIT_HASH", \ + "branch": "$$GIT_BRANCH", \ + "tag": "v$$VERSION" \ + }, \ + "build": { \ + "timestamp": "$$BUILD_TIME", \ + "compiler": "$$(gcc --version | head -1)", \ + "compiler_flags": "$(CFLAGS) $(ARCH_FLAGS)", \ + "target_architecture": "$(ARCH_NAME)", \ + "use_asm_opt": $(USE_ASM_OPT), \ + "use_lto": $(USE_LTO) \ + }, \ + "testing": { \ + "total_tests": 936, \ + "passed_tests": 0, \ + "failed_tests": 0, \ + "code_coverage_percent": 0, \ + "smoke_test_result": "N/A" \ + }, \ + "binary": { \ + "path": "$$BINARY_PATH", \ + "sha256": "$$BINARY_SHA256" \ + }, \ + "signatures": { \ + "builder": "jenkins-agent", \ + "approval_timestamp": "$(shell date -Iseconds)" \ + } \ +} \ +EOF + @echo "โœ“ BUILD_MANIFEST created: builds/manifest/BUILD_MANIFEST.json" + @cat builds/manifest/BUILD_MANIFEST.json | head -20 + +# ============================================================================== +# CLEANUP +# ============================================================================== + +clean: + @echo "๐Ÿงน Cleaning build artifacts..." + @rm -rfv build/* + @rm -f v3/src/*.gcda v3/src/word_source/*.gcda v3/src/*.gcno v3/src/word_source/*.gcno + @echo "โœ“ Clean complete" + +clean-obj: + @echo "๐Ÿงน Cleaning object files..." + @find build -name "*.o" -type f -delete 2>/dev/null || true + @echo "โœ“ Object files cleaned" + +# ============================================================================== +# HELP +# ============================================================================== + +help: + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo " โšก StarForth Build System - Fastest in the West! โšก" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + @echo "" + @echo "๐Ÿ› ๏ธ Variables:" + @echo " ARCH= (default: $(ARCH); canonical directory: $(ARCH_DIR))" + @echo " TARGET= (standard | fast | fastest | turbo)" + @echo "" + @echo "๐Ÿ† OPTIMIZATION BUILDS:" + @echo " fastest - Maximum performance (ASM + direct threading + LTO)" + @echo " fast - Fast without LTO (easier debugging)" + @echo " turbo - Assembly optimizations only" + @echo "" + @echo "๐Ÿฅง PLATFORM-SPECIFIC BUILDS:" + @echo " rpi4 - Native build on Raspberry Pi 4" + @echo " rpi4-cross - Cross-compile from x86_64" + @echo " rpi4-fastest - Maximum optimization for RPi4" + @echo " riscv64-clang - Cross-compile for RISC-V 64 via clang (GCC fails here)" + @echo " minimal - Minimal/embedded build" + @echo "" + @echo "๐Ÿ”ง DEBUG & DEVELOPMENT:" + @echo " all - Standard optimized build (default)" + @echo " debug - Debug build with symbols (-g -O0)" + @echo " profile - Build with profiling support" + @echo " performance - Legacy performance build (use 'fastest')" + @echo "" + @echo "๐Ÿงช TESTING & BENCHMARKING:" + @echo " test - Run full test suite" + @echo " bench - Quick benchmark" + @echo " benchmark - Full benchmark suite" + @echo "" + @echo "๐Ÿ“ ANALYSIS & DOCUMENTATION:" + @echo " asm - Generate assembly output" + @echo " sbom - Generate SBOM (Software Bill of Materials, SPDX)" + @echo " docs - Generate all documentation" + @echo " api-docs - Generate API docs (Doxygen โ†’ AsciiDoc)" + @echo " docs-latex - Convert AsciiDoc to LaTeX" + @echo " docs-isabelle - Generate Isabelle documentation for auditing (includes build log)" + @echo " isabelle-build - Build and verify Isabelle formal theories (strict verification)" + @echo " isabelle-check - Quick-check Isabelle theories" + @echo " info - Build GNU info documentation" + @echo "" + @echo "๐Ÿ”ฌ REFINEMENT VERIFICATION (C โŠ‘ Isabelle):" + @echo " refinement-init - Initialize refinement tracking (CAPA + annotations)" + @echo " refinement-status - Show refinement defect summary and phase status" + @echo " refinement-phase1 - Build Phase 1 refinement proofs (vm.c core)" + @echo " verify-defect - Verify specific defect (Usage: make verify-defect DEFECT=001)" + @echo " refinement-annotate-check - Check code annotation coverage" + @echo " refinement-report - Generate refinement status report" + @echo "" + @echo "๐Ÿ“ฆ INSTALLATION & PACKAGING:" + @echo " install - Install to PREFIX (default: .)" + @echo " uninstall - Uninstall from PREFIX" + @echo " deb - Build Debian package" + @echo " rpm - Build RPM package" + @echo " package - Build all packages" + @echo "" + @echo "๐Ÿงน CLEANUP:" + @echo " clean - Remove all build artifacts" + @echo " clean-obj - Remove object files only" + @echo " clean-docs - Remove generated documentation" + @echo "" + @echo "โš™๏ธ CONFIGURATION VARIABLES:" + @echo " CC - Compiler (default: gcc)" + @echo " CFLAGS - Compiler flags (override defaults)" + @echo " LDFLAGS - Linker flags (override defaults)" + @echo " PREFIX - Install prefix (default: .)" + @echo " MINIMAL=1 - Minimal build mode (DISABLED -- incomplete, errors out)" + @echo " ASM=1 - Generate assembly files during build" + @echo "" + @echo "๐Ÿ“‹ EXAMPLES:" + @echo " make fastest # Fastest build for current platform" + @echo " make rpi4-cross # Cross-compile for Raspberry Pi 4" + @echo " make riscv64-clang # Cross-compile for RISC-V 64 (clang)" + @echo " make asm # Generate assembly for inspection" + @echo " make debug # Debug build" + @echo " make PREFIX=/usr/local install # Install system-wide" + @echo "" + @echo "๐ŸŒŸ CURRENT PLATFORM: $(ARCH_NAME)" + @echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + +quality: compile_commands clang_tidy cppcheck gcc_analyzer + +compile_commands: + bear --output build/compile_commands.json -- make -j$(nproc) + +clang_tidy: + clang-tidy -p build $(shell find src -name '*.c' -o -name '*.h') | tee build/clang-tidy.txt + +cppcheck: + cppcheck --enable=all --inconclusive --std=c99 src 2> build/cppcheck.txt || true + +gcc_analyzer: + $(MAKE) -f v3/Makefile clean + CFLAGS="$(CFLAGS) -fanalyzer -Wall -Wextra" $(MAKE) -f v3/Makefile all 2>&1 | tee build/gcc-analyzer.txt diff --git a/include/README.md b/v3/include/README.md similarity index 100% rename from include/README.md rename to v3/include/README.md diff --git a/include/arch_detect.h b/v3/include/arch_detect.h similarity index 100% rename from include/arch_detect.h rename to v3/include/arch_detect.h diff --git a/include/blkcfg.h b/v3/include/blkcfg.h similarity index 100% rename from include/blkcfg.h rename to v3/include/blkcfg.h diff --git a/include/blkio.h b/v3/include/blkio.h similarity index 100% rename from include/blkio.h rename to v3/include/blkio.h diff --git a/include/blkio_factory.h b/v3/include/blkio_factory.h similarity index 100% rename from include/blkio_factory.h rename to v3/include/blkio_factory.h diff --git a/include/block_subsystem.h b/v3/include/block_subsystem.h similarity index 100% rename from include/block_subsystem.h rename to v3/include/block_subsystem.h diff --git a/include/cli.h b/v3/include/cli.h similarity index 100% rename from include/cli.h rename to v3/include/cli.h diff --git a/include/compudynamics.h b/v3/include/compudynamics.h similarity index 100% rename from include/compudynamics.h rename to v3/include/compudynamics.h diff --git a/include/dictionary_heat_optimization.h b/v3/include/dictionary_heat_optimization.h similarity index 100% rename from include/dictionary_heat_optimization.h rename to v3/include/dictionary_heat_optimization.h diff --git a/include/dictionary_management.h b/v3/include/dictionary_management.h similarity index 100% rename from include/dictionary_management.h rename to v3/include/dictionary_management.h diff --git a/include/doe_metrics.h b/v3/include/doe_metrics.h similarity index 100% rename from include/doe_metrics.h rename to v3/include/doe_metrics.h diff --git a/include/inference_engine.h b/v3/include/inference_engine.h similarity index 100% rename from include/inference_engine.h rename to v3/include/inference_engine.h diff --git a/include/io.h b/v3/include/io.h similarity index 100% rename from include/io.h rename to v3/include/io.h diff --git a/include/log.h b/v3/include/log.h similarity index 100% rename from include/log.h rename to v3/include/log.h diff --git a/include/math_portable.h b/v3/include/math_portable.h similarity index 100% rename from include/math_portable.h rename to v3/include/math_portable.h diff --git a/include/memory_management.h b/v3/include/memory_management.h similarity index 100% rename from include/memory_management.h rename to v3/include/memory_management.h diff --git a/include/physics_execution_hooks.h b/v3/include/physics_execution_hooks.h similarity index 100% rename from include/physics_execution_hooks.h rename to v3/include/physics_execution_hooks.h diff --git a/include/physics_hotwords_cache.h b/v3/include/physics_hotwords_cache.h similarity index 100% rename from include/physics_hotwords_cache.h rename to v3/include/physics_hotwords_cache.h diff --git a/include/physics_metadata.h b/v3/include/physics_metadata.h similarity index 100% rename from include/physics_metadata.h rename to v3/include/physics_metadata.h diff --git a/include/physics_pipelining_metrics.h b/v3/include/physics_pipelining_metrics.h similarity index 100% rename from include/physics_pipelining_metrics.h rename to v3/include/physics_pipelining_metrics.h diff --git a/include/physics_runtime.h b/v3/include/physics_runtime.h similarity index 100% rename from include/physics_runtime.h rename to v3/include/physics_runtime.h diff --git a/include/platform_alloc.h b/v3/include/platform_alloc.h similarity index 100% rename from include/platform_alloc.h rename to v3/include/platform_alloc.h diff --git a/include/platform_io.h b/v3/include/platform_io.h similarity index 100% rename from include/platform_io.h rename to v3/include/platform_io.h diff --git a/include/platform_lock.h b/v3/include/platform_lock.h similarity index 100% rename from include/platform_lock.h rename to v3/include/platform_lock.h diff --git a/include/platform_time.h b/v3/include/platform_time.h similarity index 100% rename from include/platform_time.h rename to v3/include/platform_time.h diff --git a/include/profiler.h b/v3/include/profiler.h similarity index 100% rename from include/profiler.h rename to v3/include/profiler.h diff --git a/include/q48_16.h b/v3/include/q48_16.h similarity index 100% rename from include/q48_16.h rename to v3/include/q48_16.h diff --git a/include/repl.h b/v3/include/repl.h similarity index 100% rename from include/repl.h rename to v3/include/repl.h diff --git a/include/rolling_window_knobs.h b/v3/include/rolling_window_knobs.h similarity index 100% rename from include/rolling_window_knobs.h rename to v3/include/rolling_window_knobs.h diff --git a/include/rolling_window_of_truth.h b/v3/include/rolling_window_of_truth.h similarity index 100% rename from include/rolling_window_of_truth.h rename to v3/include/rolling_window_of_truth.h diff --git a/include/ssm_jacquard.h b/v3/include/ssm_jacquard.h similarity index 100% rename from include/ssm_jacquard.h rename to v3/include/ssm_jacquard.h diff --git a/include/starforth_config.h b/v3/include/starforth_config.h similarity index 100% rename from include/starforth_config.h rename to v3/include/starforth_config.h diff --git a/include/startup.h b/v3/include/startup.h similarity index 100% rename from include/startup.h rename to v3/include/startup.h diff --git a/v3/include/version.h b/v3/include/version.h new file mode 100644 index 00000000..6603a0b5 --- /dev/null +++ b/v3/include/version.h @@ -0,0 +1,10 @@ +#ifndef STARFORTH_VERSION_H +#define STARFORTH_VERSION_H + +#define STARFORTH_VERSION "3.2.0" +#define STARFORTH_ARCH "x86_64" +#define STARFORTH_TARGET "standard" +#define STARFORTH_TIMESTAMP "2026-10-01T15:21:25-04:00" +#define STARFORTH_VERSION_FULL "StarForth v3.2.0 x86_64 standard 2026-10-01T15:21:25-04:00" + +#endif /* STARFORTH_VERSION_H */ diff --git a/include/vm.h b/v3/include/vm.h similarity index 100% rename from include/vm.h rename to v3/include/vm.h diff --git a/include/vm_api.h b/v3/include/vm_api.h similarity index 100% rename from include/vm_api.h rename to v3/include/vm_api.h diff --git a/include/vm_asm_opt.h b/v3/include/vm_asm_opt.h similarity index 100% rename from include/vm_asm_opt.h rename to v3/include/vm_asm_opt.h diff --git a/include/vm_asm_opt_arm64.h b/v3/include/vm_asm_opt_arm64.h similarity index 100% rename from include/vm_asm_opt_arm64.h rename to v3/include/vm_asm_opt_arm64.h diff --git a/include/vm_asm_opt_riscv64.h b/v3/include/vm_asm_opt_riscv64.h similarity index 100% rename from include/vm_asm_opt_riscv64.h rename to v3/include/vm_asm_opt_riscv64.h diff --git a/include/vm_debug.h b/v3/include/vm_debug.h similarity index 100% rename from include/vm_debug.h rename to v3/include/vm_debug.h diff --git a/include/vm_host.h b/v3/include/vm_host.h similarity index 100% rename from include/vm_host.h rename to v3/include/vm_host.h diff --git a/include/vm_inner_interp_arm64.h b/v3/include/vm_inner_interp_arm64.h similarity index 100% rename from include/vm_inner_interp_arm64.h rename to v3/include/vm_inner_interp_arm64.h diff --git a/include/vm_inner_interp_asm.h b/v3/include/vm_inner_interp_asm.h similarity index 100% rename from include/vm_inner_interp_asm.h rename to v3/include/vm_inner_interp_asm.h diff --git a/include/vm_inner_interp_riscv64.h b/v3/include/vm_inner_interp_riscv64.h similarity index 100% rename from include/vm_inner_interp_riscv64.h rename to v3/include/vm_inner_interp_riscv64.h diff --git a/include/word_registry.h b/v3/include/word_registry.h similarity index 100% rename from include/word_registry.h rename to v3/include/word_registry.h diff --git a/src/README.md b/v3/src/README.md similarity index 100% rename from src/README.md rename to v3/src/README.md diff --git a/src/blkio_factory.c b/v3/src/blkio_factory.c similarity index 100% rename from src/blkio_factory.c rename to v3/src/blkio_factory.c diff --git a/src/blkio_file.c b/v3/src/blkio_file.c similarity index 100% rename from src/blkio_file.c rename to v3/src/blkio_file.c diff --git a/src/blkio_ram.c b/v3/src/blkio_ram.c similarity index 100% rename from src/blkio_ram.c rename to v3/src/blkio_ram.c diff --git a/src/block_subsystem.c b/v3/src/block_subsystem.c similarity index 100% rename from src/block_subsystem.c rename to v3/src/block_subsystem.c diff --git a/src/cli.c b/v3/src/cli.c similarity index 100% rename from src/cli.c rename to v3/src/cli.c diff --git a/src/compudynamics.c b/v3/src/compudynamics.c similarity index 100% rename from src/compudynamics.c rename to v3/src/compudynamics.c diff --git a/src/dictionary_heat_optimization.c b/v3/src/dictionary_heat_optimization.c similarity index 100% rename from src/dictionary_heat_optimization.c rename to v3/src/dictionary_heat_optimization.c diff --git a/src/dictionary_management.c b/v3/src/dictionary_management.c similarity index 100% rename from src/dictionary_management.c rename to v3/src/dictionary_management.c diff --git a/src/doe_metrics.c b/v3/src/doe_metrics.c similarity index 100% rename from src/doe_metrics.c rename to v3/src/doe_metrics.c diff --git a/src/heartbeat_export.c b/v3/src/heartbeat_export.c similarity index 100% rename from src/heartbeat_export.c rename to v3/src/heartbeat_export.c diff --git a/src/inference_engine.c b/v3/src/inference_engine.c similarity index 100% rename from src/inference_engine.c rename to v3/src/inference_engine.c diff --git a/src/io.c b/v3/src/io.c similarity index 100% rename from src/io.c rename to v3/src/io.c diff --git a/src/log.c b/v3/src/log.c similarity index 100% rename from src/log.c rename to v3/src/log.c diff --git a/src/main.c b/v3/src/main.c similarity index 100% rename from src/main.c rename to v3/src/main.c diff --git a/src/math_portable.c b/v3/src/math_portable.c similarity index 100% rename from src/math_portable.c rename to v3/src/math_portable.c diff --git a/src/memory_management.c b/v3/src/memory_management.c similarity index 100% rename from src/memory_management.c rename to v3/src/memory_management.c diff --git a/src/physics_execution_hooks.c b/v3/src/physics_execution_hooks.c similarity index 100% rename from src/physics_execution_hooks.c rename to v3/src/physics_execution_hooks.c diff --git a/src/physics_hotwords_cache.c b/v3/src/physics_hotwords_cache.c similarity index 100% rename from src/physics_hotwords_cache.c rename to v3/src/physics_hotwords_cache.c diff --git a/src/physics_metadata.c b/v3/src/physics_metadata.c similarity index 100% rename from src/physics_metadata.c rename to v3/src/physics_metadata.c diff --git a/src/physics_pipelining_metrics.c b/v3/src/physics_pipelining_metrics.c similarity index 100% rename from src/physics_pipelining_metrics.c rename to v3/src/physics_pipelining_metrics.c diff --git a/src/physics_runtime.c b/v3/src/physics_runtime.c similarity index 100% rename from src/physics_runtime.c rename to v3/src/physics_runtime.c diff --git a/src/platform/README.md b/v3/src/platform/README.md similarity index 100% rename from src/platform/README.md rename to v3/src/platform/README.md diff --git a/src/platform/alloc_host.c b/v3/src/platform/alloc_host.c similarity index 100% rename from src/platform/alloc_host.c rename to v3/src/platform/alloc_host.c diff --git a/src/platform/alloc_kernel.c b/v3/src/platform/alloc_kernel.c similarity index 100% rename from src/platform/alloc_kernel.c rename to v3/src/platform/alloc_kernel.c diff --git a/src/platform/l4re/README.md b/v3/src/platform/l4re/README.md similarity index 100% rename from src/platform/l4re/README.md rename to v3/src/platform/l4re/README.md diff --git a/src/platform/l4re/time.c b/v3/src/platform/l4re/time.c similarity index 100% rename from src/platform/l4re/time.c rename to v3/src/platform/l4re/time.c diff --git a/src/platform/linux/README.md b/v3/src/platform/linux/README.md similarity index 100% rename from src/platform/linux/README.md rename to v3/src/platform/linux/README.md diff --git a/src/platform/linux/io.c b/v3/src/platform/linux/io.c similarity index 100% rename from src/platform/linux/io.c rename to v3/src/platform/linux/io.c diff --git a/src/platform/linux/time.c b/v3/src/platform/linux/time.c similarity index 100% rename from src/platform/linux/time.c rename to v3/src/platform/linux/time.c diff --git a/src/platform/platform_init.c b/v3/src/platform/platform_init.c similarity index 100% rename from src/platform/platform_init.c rename to v3/src/platform/platform_init.c diff --git a/src/platform/threading.c b/v3/src/platform/threading.c similarity index 100% rename from src/platform/threading.c rename to v3/src/platform/threading.c diff --git a/src/profiler.c b/v3/src/profiler.c similarity index 100% rename from src/profiler.c rename to v3/src/profiler.c diff --git a/src/repl.c b/v3/src/repl.c similarity index 100% rename from src/repl.c rename to v3/src/repl.c diff --git a/src/rolling_window_of_truth.c b/v3/src/rolling_window_of_truth.c similarity index 100% rename from src/rolling_window_of_truth.c rename to v3/src/rolling_window_of_truth.c diff --git a/src/ssm_jacquard.c b/v3/src/ssm_jacquard.c similarity index 100% rename from src/ssm_jacquard.c rename to v3/src/ssm_jacquard.c diff --git a/src/stack_management.c b/v3/src/stack_management.c similarity index 100% rename from src/stack_management.c rename to v3/src/stack_management.c diff --git a/src/test_runner/README.md b/v3/src/test_runner/README.md similarity index 100% rename from src/test_runner/README.md rename to v3/src/test_runner/README.md diff --git a/src/test_runner/include/README.md b/v3/src/test_runner/include/README.md similarity index 100% rename from src/test_runner/include/README.md rename to v3/src/test_runner/include/README.md diff --git a/src/test_runner/include/test_common.h b/v3/src/test_runner/include/test_common.h similarity index 99% rename from src/test_runner/include/test_common.h rename to v3/src/test_runner/include/test_common.h index c6154902..aa8942ab 100644 --- a/src/test_runner/include/test_common.h +++ b/v3/src/test_runner/include/test_common.h @@ -50,8 +50,8 @@ #ifndef TEST_COMMON_H #define TEST_COMMON_H -#include "../include/vm.h" -#include "../include/log.h" +#include "../../../include/vm.h" +#include "../../../include/log.h" #include "test_contracts.h" /** @name Test Configuration diff --git a/src/test_runner/include/test_contracts.h b/v3/src/test_runner/include/test_contracts.h similarity index 100% rename from src/test_runner/include/test_contracts.h rename to v3/src/test_runner/include/test_contracts.h diff --git a/src/test_runner/include/test_runner.h b/v3/src/test_runner/include/test_runner.h similarity index 100% rename from src/test_runner/include/test_runner.h rename to v3/src/test_runner/include/test_runner.h diff --git a/src/test_runner/modules/README.md b/v3/src/test_runner/modules/README.md similarity index 100% rename from src/test_runner/modules/README.md rename to v3/src/test_runner/modules/README.md diff --git a/src/test_runner/modules/acl_words_test.c b/v3/src/test_runner/modules/acl_words_test.c similarity index 100% rename from src/test_runner/modules/acl_words_test.c rename to v3/src/test_runner/modules/acl_words_test.c diff --git a/src/test_runner/modules/arithmetic_words_test.c b/v3/src/test_runner/modules/arithmetic_words_test.c similarity index 100% rename from src/test_runner/modules/arithmetic_words_test.c rename to v3/src/test_runner/modules/arithmetic_words_test.c diff --git a/src/test_runner/modules/block_words_test.c b/v3/src/test_runner/modules/block_words_test.c similarity index 100% rename from src/test_runner/modules/block_words_test.c rename to v3/src/test_runner/modules/block_words_test.c diff --git a/src/test_runner/modules/break_me_tests.c b/v3/src/test_runner/modules/break_me_tests.c similarity index 100% rename from src/test_runner/modules/break_me_tests.c rename to v3/src/test_runner/modules/break_me_tests.c diff --git a/src/test_runner/modules/control_words_test.c b/v3/src/test_runner/modules/control_words_test.c similarity index 100% rename from src/test_runner/modules/control_words_test.c rename to v3/src/test_runner/modules/control_words_test.c diff --git a/src/test_runner/modules/defining_words_tests.c b/v3/src/test_runner/modules/defining_words_tests.c similarity index 100% rename from src/test_runner/modules/defining_words_tests.c rename to v3/src/test_runner/modules/defining_words_tests.c diff --git a/src/test_runner/modules/dictionary_manipulation_words_test.c b/v3/src/test_runner/modules/dictionary_manipulation_words_test.c similarity index 100% rename from src/test_runner/modules/dictionary_manipulation_words_test.c rename to v3/src/test_runner/modules/dictionary_manipulation_words_test.c diff --git a/src/test_runner/modules/dictionary_words_test.c b/v3/src/test_runner/modules/dictionary_words_test.c similarity index 100% rename from src/test_runner/modules/dictionary_words_test.c rename to v3/src/test_runner/modules/dictionary_words_test.c diff --git a/src/test_runner/modules/double_words_test.c b/v3/src/test_runner/modules/double_words_test.c similarity index 100% rename from src/test_runner/modules/double_words_test.c rename to v3/src/test_runner/modules/double_words_test.c diff --git a/src/test_runner/modules/format_words_test.c b/v3/src/test_runner/modules/format_words_test.c similarity index 100% rename from src/test_runner/modules/format_words_test.c rename to v3/src/test_runner/modules/format_words_test.c diff --git a/src/test_runner/modules/inference_words_test.c b/v3/src/test_runner/modules/inference_words_test.c similarity index 100% rename from src/test_runner/modules/inference_words_test.c rename to v3/src/test_runner/modules/inference_words_test.c diff --git a/src/test_runner/modules/integration_tests.c b/v3/src/test_runner/modules/integration_tests.c similarity index 100% rename from src/test_runner/modules/integration_tests.c rename to v3/src/test_runner/modules/integration_tests.c diff --git a/src/test_runner/modules/io_words_test.c b/v3/src/test_runner/modules/io_words_test.c similarity index 100% rename from src/test_runner/modules/io_words_test.c rename to v3/src/test_runner/modules/io_words_test.c diff --git a/src/test_runner/modules/logical_words_test.c b/v3/src/test_runner/modules/logical_words_test.c similarity index 100% rename from src/test_runner/modules/logical_words_test.c rename to v3/src/test_runner/modules/logical_words_test.c diff --git a/src/test_runner/modules/mama_forth_words_test.c b/v3/src/test_runner/modules/mama_forth_words_test.c similarity index 100% rename from src/test_runner/modules/mama_forth_words_test.c rename to v3/src/test_runner/modules/mama_forth_words_test.c diff --git a/src/test_runner/modules/memory_words_test.c b/v3/src/test_runner/modules/memory_words_test.c similarity index 100% rename from src/test_runner/modules/memory_words_test.c rename to v3/src/test_runner/modules/memory_words_test.c diff --git a/src/test_runner/modules/mixed_arithmetic_words_test.c b/v3/src/test_runner/modules/mixed_arithmetic_words_test.c similarity index 100% rename from src/test_runner/modules/mixed_arithmetic_words_test.c rename to v3/src/test_runner/modules/mixed_arithmetic_words_test.c diff --git a/src/test_runner/modules/physics_freeze_words_test.c b/v3/src/test_runner/modules/physics_freeze_words_test.c similarity index 100% rename from src/test_runner/modules/physics_freeze_words_test.c rename to v3/src/test_runner/modules/physics_freeze_words_test.c diff --git a/src/test_runner/modules/q48_words_test.c b/v3/src/test_runner/modules/q48_words_test.c similarity index 100% rename from src/test_runner/modules/q48_words_test.c rename to v3/src/test_runner/modules/q48_words_test.c diff --git a/src/test_runner/modules/return_stack_words_test.c b/v3/src/test_runner/modules/return_stack_words_test.c similarity index 100% rename from src/test_runner/modules/return_stack_words_test.c rename to v3/src/test_runner/modules/return_stack_words_test.c diff --git a/src/test_runner/modules/stack_words_test.c b/v3/src/test_runner/modules/stack_words_test.c similarity index 100% rename from src/test_runner/modules/stack_words_test.c rename to v3/src/test_runner/modules/stack_words_test.c diff --git a/src/test_runner/modules/starforth_words_test.c b/v3/src/test_runner/modules/starforth_words_test.c similarity index 100% rename from src/test_runner/modules/starforth_words_test.c rename to v3/src/test_runner/modules/starforth_words_test.c diff --git a/src/test_runner/modules/stress_tests.c b/v3/src/test_runner/modules/stress_tests.c similarity index 100% rename from src/test_runner/modules/stress_tests.c rename to v3/src/test_runner/modules/stress_tests.c diff --git a/src/test_runner/modules/string_words_test.c b/v3/src/test_runner/modules/string_words_test.c similarity index 100% rename from src/test_runner/modules/string_words_test.c rename to v3/src/test_runner/modules/string_words_test.c diff --git a/src/test_runner/modules/system_words_test.c b/v3/src/test_runner/modules/system_words_test.c similarity index 100% rename from src/test_runner/modules/system_words_test.c rename to v3/src/test_runner/modules/system_words_test.c diff --git a/src/test_runner/modules/vocabulary_words_test.c b/v3/src/test_runner/modules/vocabulary_words_test.c similarity index 100% rename from src/test_runner/modules/vocabulary_words_test.c rename to v3/src/test_runner/modules/vocabulary_words_test.c diff --git a/src/test_runner/test_common.c b/v3/src/test_runner/test_common.c similarity index 100% rename from src/test_runner/test_common.c rename to v3/src/test_runner/test_common.c diff --git a/src/test_runner/test_contracts.c b/v3/src/test_runner/test_contracts.c similarity index 100% rename from src/test_runner/test_contracts.c rename to v3/src/test_runner/test_contracts.c diff --git a/src/test_runner/test_runner.c b/v3/src/test_runner/test_runner.c similarity index 100% rename from src/test_runner/test_runner.c rename to v3/src/test_runner/test_runner.c diff --git a/src/vm.c b/v3/src/vm.c similarity index 100% rename from src/vm.c rename to v3/src/vm.c diff --git a/src/vm_api.c b/v3/src/vm_api.c similarity index 100% rename from src/vm_api.c rename to v3/src/vm_api.c diff --git a/src/vm_bootstrap.c b/v3/src/vm_bootstrap.c similarity index 99% rename from src/vm_bootstrap.c rename to v3/src/vm_bootstrap.c index b933918e..f0e7d0f3 100644 --- a/src/vm_bootstrap.c +++ b/v3/src/vm_bootstrap.c @@ -65,8 +65,8 @@ #include "word_source/include/vocabulary_words.h" #ifdef __STARKERNEL__ -#include "../include/starkernel/capsule_birth.h" -#include "../include/starkernel/capsule_run.h" +#include "starkernel/capsule_birth.h" +#include "starkernel/capsule_run.h" #endif #include diff --git a/src/vm_debug.c b/v3/src/vm_debug.c similarity index 100% rename from src/vm_debug.c rename to v3/src/vm_debug.c diff --git a/src/vm_internal.h b/v3/src/vm_internal.h similarity index 100% rename from src/vm_internal.h rename to v3/src/vm_internal.h diff --git a/src/vm_time.c b/v3/src/vm_time.c similarity index 100% rename from src/vm_time.c rename to v3/src/vm_time.c diff --git a/src/word_registry.c b/v3/src/word_registry.c similarity index 100% rename from src/word_registry.c rename to v3/src/word_registry.c diff --git a/src/word_source/README.md b/v3/src/word_source/README.md similarity index 100% rename from src/word_source/README.md rename to v3/src/word_source/README.md diff --git a/src/word_source/acl_words.c b/v3/src/word_source/acl_words.c similarity index 100% rename from src/word_source/acl_words.c rename to v3/src/word_source/acl_words.c diff --git a/src/word_source/arithmetic_words.c b/v3/src/word_source/arithmetic_words.c similarity index 100% rename from src/word_source/arithmetic_words.c rename to v3/src/word_source/arithmetic_words.c diff --git a/src/word_source/block_words.c b/v3/src/word_source/block_words.c similarity index 100% rename from src/word_source/block_words.c rename to v3/src/word_source/block_words.c diff --git a/src/word_source/control_words.c b/v3/src/word_source/control_words.c similarity index 100% rename from src/word_source/control_words.c rename to v3/src/word_source/control_words.c diff --git a/src/word_source/defer_words.c b/v3/src/word_source/defer_words.c similarity index 100% rename from src/word_source/defer_words.c rename to v3/src/word_source/defer_words.c diff --git a/src/word_source/defining_words.c b/v3/src/word_source/defining_words.c similarity index 100% rename from src/word_source/defining_words.c rename to v3/src/word_source/defining_words.c diff --git a/src/word_source/dictionary_heat_diagnostic_words.c b/v3/src/word_source/dictionary_heat_diagnostic_words.c similarity index 100% rename from src/word_source/dictionary_heat_diagnostic_words.c rename to v3/src/word_source/dictionary_heat_diagnostic_words.c diff --git a/src/word_source/dictionary_manipulation_words.c b/v3/src/word_source/dictionary_manipulation_words.c similarity index 100% rename from src/word_source/dictionary_manipulation_words.c rename to v3/src/word_source/dictionary_manipulation_words.c diff --git a/src/word_source/dictionary_words.c b/v3/src/word_source/dictionary_words.c similarity index 100% rename from src/word_source/dictionary_words.c rename to v3/src/word_source/dictionary_words.c diff --git a/src/word_source/double_words.c b/v3/src/word_source/double_words.c similarity index 100% rename from src/word_source/double_words.c rename to v3/src/word_source/double_words.c diff --git a/src/word_source/editor_words.c b/v3/src/word_source/editor_words.c similarity index 100% rename from src/word_source/editor_words.c rename to v3/src/word_source/editor_words.c diff --git a/src/word_source/format_words.c b/v3/src/word_source/format_words.c similarity index 100% rename from src/word_source/format_words.c rename to v3/src/word_source/format_words.c diff --git a/src/word_source/framebuffer_words.c b/v3/src/word_source/framebuffer_words.c similarity index 100% rename from src/word_source/framebuffer_words.c rename to v3/src/word_source/framebuffer_words.c diff --git a/src/word_source/include/README.md b/v3/src/word_source/include/README.md similarity index 100% rename from src/word_source/include/README.md rename to v3/src/word_source/include/README.md diff --git a/src/word_source/include/acl_words.h b/v3/src/word_source/include/acl_words.h similarity index 100% rename from src/word_source/include/acl_words.h rename to v3/src/word_source/include/acl_words.h diff --git a/src/word_source/include/arithmetic_words.h b/v3/src/word_source/include/arithmetic_words.h similarity index 100% rename from src/word_source/include/arithmetic_words.h rename to v3/src/word_source/include/arithmetic_words.h diff --git a/src/word_source/include/block_words.h b/v3/src/word_source/include/block_words.h similarity index 100% rename from src/word_source/include/block_words.h rename to v3/src/word_source/include/block_words.h diff --git a/src/word_source/include/control_words.h b/v3/src/word_source/include/control_words.h similarity index 100% rename from src/word_source/include/control_words.h rename to v3/src/word_source/include/control_words.h diff --git a/src/word_source/include/defer_words.h b/v3/src/word_source/include/defer_words.h similarity index 89% rename from src/word_source/include/defer_words.h rename to v3/src/word_source/include/defer_words.h index cc24580b..1015e3d0 100644 --- a/src/word_source/include/defer_words.h +++ b/v3/src/word_source/include/defer_words.h @@ -10,7 +10,7 @@ #ifndef DEFER_WORDS_H #define DEFER_WORDS_H -#include "../../include/vm.h" +#include "../../../include/vm.h" void register_defer_words(VM *vm); diff --git a/src/word_source/include/defining_words.h b/v3/src/word_source/include/defining_words.h similarity index 100% rename from src/word_source/include/defining_words.h rename to v3/src/word_source/include/defining_words.h diff --git a/src/word_source/include/dictionary_heat_diagnostic_words.h b/v3/src/word_source/include/dictionary_heat_diagnostic_words.h similarity index 100% rename from src/word_source/include/dictionary_heat_diagnostic_words.h rename to v3/src/word_source/include/dictionary_heat_diagnostic_words.h diff --git a/src/word_source/include/dictionary_manipulation_words.h b/v3/src/word_source/include/dictionary_manipulation_words.h similarity index 100% rename from src/word_source/include/dictionary_manipulation_words.h rename to v3/src/word_source/include/dictionary_manipulation_words.h diff --git a/src/word_source/include/dictionary_words.h b/v3/src/word_source/include/dictionary_words.h similarity index 100% rename from src/word_source/include/dictionary_words.h rename to v3/src/word_source/include/dictionary_words.h diff --git a/src/word_source/include/double_words.h b/v3/src/word_source/include/double_words.h similarity index 100% rename from src/word_source/include/double_words.h rename to v3/src/word_source/include/double_words.h diff --git a/src/word_source/include/editor_words.h b/v3/src/word_source/include/editor_words.h similarity index 100% rename from src/word_source/include/editor_words.h rename to v3/src/word_source/include/editor_words.h diff --git a/src/word_source/include/format_words.h b/v3/src/word_source/include/format_words.h similarity index 100% rename from src/word_source/include/format_words.h rename to v3/src/word_source/include/format_words.h diff --git a/src/word_source/include/framebuffer_words.h b/v3/src/word_source/include/framebuffer_words.h similarity index 100% rename from src/word_source/include/framebuffer_words.h rename to v3/src/word_source/include/framebuffer_words.h diff --git a/src/word_source/include/inference_words.h b/v3/src/word_source/include/inference_words.h similarity index 100% rename from src/word_source/include/inference_words.h rename to v3/src/word_source/include/inference_words.h diff --git a/src/word_source/include/io_words.h b/v3/src/word_source/include/io_words.h similarity index 100% rename from src/word_source/include/io_words.h rename to v3/src/word_source/include/io_words.h diff --git a/src/word_source/include/keyboard_words.h b/v3/src/word_source/include/keyboard_words.h similarity index 100% rename from src/word_source/include/keyboard_words.h rename to v3/src/word_source/include/keyboard_words.h diff --git a/src/word_source/include/log_words.h b/v3/src/word_source/include/log_words.h similarity index 100% rename from src/word_source/include/log_words.h rename to v3/src/word_source/include/log_words.h diff --git a/src/word_source/include/logical_words.h b/v3/src/word_source/include/logical_words.h similarity index 100% rename from src/word_source/include/logical_words.h rename to v3/src/word_source/include/logical_words.h diff --git a/src/word_source/include/mama_forth_words.h b/v3/src/word_source/include/mama_forth_words.h similarity index 100% rename from src/word_source/include/mama_forth_words.h rename to v3/src/word_source/include/mama_forth_words.h diff --git a/src/word_source/include/memory_words.h b/v3/src/word_source/include/memory_words.h similarity index 100% rename from src/word_source/include/memory_words.h rename to v3/src/word_source/include/memory_words.h diff --git a/src/word_source/include/mixed_arithmetic_words.h b/v3/src/word_source/include/mixed_arithmetic_words.h similarity index 100% rename from src/word_source/include/mixed_arithmetic_words.h rename to v3/src/word_source/include/mixed_arithmetic_words.h diff --git a/src/word_source/include/physics_benchmark_words.h b/v3/src/word_source/include/physics_benchmark_words.h similarity index 100% rename from src/word_source/include/physics_benchmark_words.h rename to v3/src/word_source/include/physics_benchmark_words.h diff --git a/src/word_source/include/physics_diagnostic_words.h b/v3/src/word_source/include/physics_diagnostic_words.h similarity index 100% rename from src/word_source/include/physics_diagnostic_words.h rename to v3/src/word_source/include/physics_diagnostic_words.h diff --git a/src/word_source/include/physics_freeze_words.h b/v3/src/word_source/include/physics_freeze_words.h similarity index 100% rename from src/word_source/include/physics_freeze_words.h rename to v3/src/word_source/include/physics_freeze_words.h diff --git a/src/word_source/include/physics_pipelining_diagnostic_words.h b/v3/src/word_source/include/physics_pipelining_diagnostic_words.h similarity index 100% rename from src/word_source/include/physics_pipelining_diagnostic_words.h rename to v3/src/word_source/include/physics_pipelining_diagnostic_words.h diff --git a/src/word_source/include/q48_words.h b/v3/src/word_source/include/q48_words.h similarity index 100% rename from src/word_source/include/q48_words.h rename to v3/src/word_source/include/q48_words.h diff --git a/src/word_source/include/return_stack_words.h b/v3/src/word_source/include/return_stack_words.h similarity index 100% rename from src/word_source/include/return_stack_words.h rename to v3/src/word_source/include/return_stack_words.h diff --git a/src/word_source/include/scroll_words.h b/v3/src/word_source/include/scroll_words.h similarity index 100% rename from src/word_source/include/scroll_words.h rename to v3/src/word_source/include/scroll_words.h diff --git a/src/word_source/include/stack_words.h b/v3/src/word_source/include/stack_words.h similarity index 100% rename from src/word_source/include/stack_words.h rename to v3/src/word_source/include/stack_words.h diff --git a/src/word_source/include/starforth_words.h b/v3/src/word_source/include/starforth_words.h similarity index 100% rename from src/word_source/include/starforth_words.h rename to v3/src/word_source/include/starforth_words.h diff --git a/src/word_source/include/string_words.h b/v3/src/word_source/include/string_words.h similarity index 100% rename from src/word_source/include/string_words.h rename to v3/src/word_source/include/string_words.h diff --git a/src/word_source/include/system_words.h b/v3/src/word_source/include/system_words.h similarity index 100% rename from src/word_source/include/system_words.h rename to v3/src/word_source/include/system_words.h diff --git a/src/word_source/include/ttf_words.h b/v3/src/word_source/include/ttf_words.h similarity index 100% rename from src/word_source/include/ttf_words.h rename to v3/src/word_source/include/ttf_words.h diff --git a/src/word_source/include/vocabulary_words.h b/v3/src/word_source/include/vocabulary_words.h similarity index 100% rename from src/word_source/include/vocabulary_words.h rename to v3/src/word_source/include/vocabulary_words.h diff --git a/src/word_source/inference_words.c b/v3/src/word_source/inference_words.c similarity index 100% rename from src/word_source/inference_words.c rename to v3/src/word_source/inference_words.c diff --git a/src/word_source/io_words.c b/v3/src/word_source/io_words.c similarity index 100% rename from src/word_source/io_words.c rename to v3/src/word_source/io_words.c diff --git a/src/word_source/keyboard_words.c b/v3/src/word_source/keyboard_words.c similarity index 100% rename from src/word_source/keyboard_words.c rename to v3/src/word_source/keyboard_words.c diff --git a/src/word_source/lifecycle_words_hosted.c b/v3/src/word_source/lifecycle_words_hosted.c similarity index 100% rename from src/word_source/lifecycle_words_hosted.c rename to v3/src/word_source/lifecycle_words_hosted.c diff --git a/src/word_source/log_words.c b/v3/src/word_source/log_words.c similarity index 100% rename from src/word_source/log_words.c rename to v3/src/word_source/log_words.c diff --git a/src/word_source/logical_words.c b/v3/src/word_source/logical_words.c similarity index 100% rename from src/word_source/logical_words.c rename to v3/src/word_source/logical_words.c diff --git a/src/word_source/memory_words.c b/v3/src/word_source/memory_words.c similarity index 100% rename from src/word_source/memory_words.c rename to v3/src/word_source/memory_words.c diff --git a/src/word_source/mixed_arithmetic_words.c b/v3/src/word_source/mixed_arithmetic_words.c similarity index 100% rename from src/word_source/mixed_arithmetic_words.c rename to v3/src/word_source/mixed_arithmetic_words.c diff --git a/src/word_source/physics_benchmark_words.c b/v3/src/word_source/physics_benchmark_words.c similarity index 100% rename from src/word_source/physics_benchmark_words.c rename to v3/src/word_source/physics_benchmark_words.c diff --git a/src/word_source/physics_diagnostic_words.c b/v3/src/word_source/physics_diagnostic_words.c similarity index 100% rename from src/word_source/physics_diagnostic_words.c rename to v3/src/word_source/physics_diagnostic_words.c diff --git a/src/word_source/physics_freeze_words.c b/v3/src/word_source/physics_freeze_words.c similarity index 100% rename from src/word_source/physics_freeze_words.c rename to v3/src/word_source/physics_freeze_words.c diff --git a/src/word_source/physics_pipelining_diagnostic_words.c b/v3/src/word_source/physics_pipelining_diagnostic_words.c similarity index 99% rename from src/word_source/physics_pipelining_diagnostic_words.c rename to v3/src/word_source/physics_pipelining_diagnostic_words.c index 662d9431..1e928c35 100644 --- a/src/word_source/physics_pipelining_diagnostic_words.c +++ b/v3/src/word_source/physics_pipelining_diagnostic_words.c @@ -50,9 +50,9 @@ */ -#include "../include/vm.h" -#include "../include/physics_pipelining_metrics.h" -#include "../include/word_registry.h" +#include "../../include/vm.h" +#include "../../include/physics_pipelining_metrics.h" +#include "../../include/word_registry.h" #include #include #include diff --git a/src/word_source/q48_16_words.c b/v3/src/word_source/q48_16_words.c similarity index 99% rename from src/word_source/q48_16_words.c rename to v3/src/word_source/q48_16_words.c index 0b0279b4..b6e5b190 100644 --- a/src/word_source/q48_16_words.c +++ b/v3/src/word_source/q48_16_words.c @@ -45,7 +45,7 @@ #include #include -#include "../include/q48_16.h" +#include "../../include/q48_16.h" /* ============================================================================ * Core Arithmetic: Multiply diff --git a/src/word_source/q48_words.c b/v3/src/word_source/q48_words.c similarity index 100% rename from src/word_source/q48_words.c rename to v3/src/word_source/q48_words.c diff --git a/src/word_source/return_stack_words.c b/v3/src/word_source/return_stack_words.c similarity index 100% rename from src/word_source/return_stack_words.c rename to v3/src/word_source/return_stack_words.c diff --git a/src/word_source/scroll_words.c b/v3/src/word_source/scroll_words.c similarity index 100% rename from src/word_source/scroll_words.c rename to v3/src/word_source/scroll_words.c diff --git a/src/word_source/stack_words.c b/v3/src/word_source/stack_words.c similarity index 100% rename from src/word_source/stack_words.c rename to v3/src/word_source/stack_words.c diff --git a/src/word_source/starforth_words.c b/v3/src/word_source/starforth_words.c similarity index 100% rename from src/word_source/starforth_words.c rename to v3/src/word_source/starforth_words.c diff --git a/src/word_source/string_words.c b/v3/src/word_source/string_words.c similarity index 100% rename from src/word_source/string_words.c rename to v3/src/word_source/string_words.c diff --git a/src/word_source/system_words.c b/v3/src/word_source/system_words.c similarity index 100% rename from src/word_source/system_words.c rename to v3/src/word_source/system_words.c diff --git a/src/word_source/ttf_words.c b/v3/src/word_source/ttf_words.c similarity index 100% rename from src/word_source/ttf_words.c rename to v3/src/word_source/ttf_words.c diff --git a/src/word_source/vocabulary_words.c b/v3/src/word_source/vocabulary_words.c similarity index 100% rename from src/word_source/vocabulary_words.c rename to v3/src/word_source/vocabulary_words.c diff --git a/v4/README.md b/v4/README.md new file mode 100644 index 00000000..d1beb6b1 --- /dev/null +++ b/v4/README.md @@ -0,0 +1,9 @@ +# v4/ + +StarForth v4: the 32-instruction F18-derived core. The design lives in +`docs/v4.0.0/JUSTIFICATION.md` (why) and `docs/v4.0.0/DECOMPOSITION.md` +(every v3 word mapped to a v4 fate). + +There is no code yet. The first deliverable is the hosted C99 golden model +(`JUSTIFICATION.md` ยง10, step 1). It must pass POST and hold Kโ‰ก1.0 with +32- and 64-bit cells on all three host ISAs.