Star forth v4.0.0 #3
@@ -1,5 +1,5 @@
|
||||
# Capsule Block Manifest — Auto-generated
|
||||
<!-- Generated by mkcapsule --manifest 2026-10-07T14:56:10Z -->
|
||||
<!-- Generated by mkcapsule --manifest 2026-10-07T15:31:38Z -->
|
||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||
<!-- Hand-written justifications and immutability notes live -->
|
||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||
|
||||
@@ -194,7 +194,7 @@ program with the node as its interpreter. That is withdrawn. From here:
|
||||
|
||||
**What the two share (confirmed by Captain Bob the same day, "yes,
|
||||
exactly"):** the engine in `v4/src`; the FORTH-79 capsule,
|
||||
`capsules/v4/forth79.4th`; and its POST, `capsules/v4/post79.4th`. **The
|
||||
`capsules/v4/forth79.4th`; and its POST (then `capsules/v4/post79.4th`; since `MESH.md` step 6b, 2026-10-07, the kernel's cases, `v4/system/post_cases.c`). **The
|
||||
nuclei are separate.** The bare-metal nucleus needs word IDs in its
|
||||
headers and words that are called where the hosted one compiles them in
|
||||
line; the hosted nucleus need not have either. The hosted product may
|
||||
@@ -346,7 +346,7 @@ not written yet. Nothing of it is built.
|
||||
| `v4/system/boot.c`: its own capsule loader and `PARITY:V4_*` lines | Stays for the hosted product. On bare metal v3's birth protocol loads the capsules and prints v3's parity lines (step 4). |
|
||||
| The node's prompt loop, and the code that strips ` ok` from its output | Goes at step 1. |
|
||||
| `capsules/v4/forth79.4th`, `post79.4th`, `mkpost.py`, the rules | Stay. POST is the gate for every word moved out of the nucleus. |
|
||||
| `(CATCH)`, `(EMIT-HOOK)`, `NODE-ERROR` by name | Stay; POST uses them. |
|
||||
| `(CATCH)`, `(EMIT-HOOK)`, `NODE-ERROR` by name | `NODE-ERROR` stays. `(CATCH)` and `(EMIT-HOOK)` went with the POST capsule, `MESH.md` step 6b, 2026-10-07: POST is the kernel's and needs neither. |
|
||||
| The per-call-target count (`v4/src/heat.c`, `call[]`) | Goes at step 3, when the node does at `call` what v3 does. |
|
||||
| The hosted Linux product (`v4/tools/hosted.c`, `v4/system/boot.c`) | Stays, as its own product (3c). |
|
||||
|
||||
|
||||
+18
-10
@@ -753,15 +753,21 @@ Each is tested, committed and pushed before the next.
|
||||
- *The boot* (`v4/system/boot.c`) runs it after the capsules, prints
|
||||
`PARITY:V4_SYSTEM`, and seals. `capsules/v4/post79.4th`, `(CATCH)` and
|
||||
`(EMIT-HOOK)` are gone.
|
||||
- *First built* with what the cases define left in the dictionary
|
||||
(`4bdb210a`; `logs/20261007-105118`, `-105335`, `-105651`).
|
||||
- *Review, 2026-10-07*, by a fresh reviewer. It found that v3 does not
|
||||
leave them (above, and `NUCLEUS.md` 6.3), and that a case the node did
|
||||
not come back from would have stalled the boot for hours where the
|
||||
capsule had ended it. Changed: the boot seals, runs POST, and has the
|
||||
node do `COLD`; the runner ends POST at such a case and names it;
|
||||
`hosted-check` boots a program whose POST has failing cases
|
||||
(`v4/tests/post_cases_fail.c`) and requires `PARITY:FAIL`, `POST:
|
||||
FAILED`, no prompt, and none of a case's printing on the console.
|
||||
- *Verified.* `make -C v4 test`, `sanitize` and `hosted-check`; three
|
||||
bare-metal boots, `logs/20261007-105118` (amd64), `-105335`
|
||||
(aarch64), `-105651` (riscv64). On all six: POST 538 of 538,
|
||||
`word_count=411`, `dict_hash=0x6fb1d09418b189ee`. At the prompt `T{`
|
||||
is unknown, and `RS1`, which a case defines, prints `42 42` before and
|
||||
after `COLD`. A hosted program built with one case's expected output
|
||||
changed names the case and ends `PARITY:FAIL`, `POST: FAILED`.
|
||||
- What the cases define takes 1,385 cells of the dictionary space's
|
||||
5,632.
|
||||
bare-metal boots, `logs/20261007-112638` (amd64), `-112901`
|
||||
(aarch64), `-113220` (riscv64). On all six: POST 538 of 538,
|
||||
`word_count=314`, `dict_hash=0x220ab283a504a3b3`. At the prompt `T{`
|
||||
and `RS1` are unknown words, and `HERE` is 8300.
|
||||
|
||||
Acceptance, as approved:
|
||||
1. *Same verdict.* The three hosted programs and the three bare-metal
|
||||
@@ -771,8 +777,10 @@ Each is tested, committed and pushed before the next.
|
||||
2. *Nothing of the harness is on the node.* At the prompt `T{` is an
|
||||
unknown word, and `(CATCH)` and `(EMIT-HOOK)` are gone from the
|
||||
nucleus.
|
||||
3. *What the cases define is there.* A word a case defines can be used
|
||||
at the prompt after boot, and survives `COLD`.
|
||||
3. ~~What the cases define is there.~~ **Reversed 2026-10-07:** *POST
|
||||
leaves nothing.* A word a case defines is unknown at the prompt
|
||||
after boot. (The first form rested on a false statement about v3;
|
||||
`NUCLEUS.md` 6.3.)
|
||||
4. *The judge can fail.* Given a case with a wrong expected stack, one
|
||||
with wrong expected output, one that must end in an error and does
|
||||
not, and one that ends in an error and must not, the runner reports
|
||||
|
||||
+28
-10
@@ -76,7 +76,7 @@ moved.
|
||||
| File | Capsule name | Contents |
|
||||
|---|---|---|
|
||||
| `capsules/v4/forth79.4th` | `v4:forth79.4th` | The Required Word Set as colon definitions |
|
||||
| `capsules/v4/post79.4th` | `v4:post79.4th` | The POST harness and its cases |
|
||||
| ~~`capsules/v4/post79.4th`~~ | | Gone 2026-10-07: POST is the kernel's (6.3); its cases are `v4/system/post_cases.c` |
|
||||
|
||||
Both are ordinary `.4th` capsules: `Block N` headers, lines of at most 64
|
||||
characters, at most 16 lines to a block. `tools/mkcapsule.c` bakes them into
|
||||
@@ -168,8 +168,10 @@ for the record.
|
||||
the interpreter, reads the VM's error flag, and puts the VM's stack
|
||||
pointers, error and mode back (`test_common.c`, `run_single_test`). It
|
||||
runs once at boot on the first VM, against block RAM of POST's own, and
|
||||
the parity line is taken afterwards. Whatever the cases define stays in
|
||||
the dictionary.
|
||||
the parity line is taken afterwards. What the cases define does not stay:
|
||||
`run_test_suite` saves the dictionary before each word's cases and puts it
|
||||
back after them, "to remove test-created words" (`test_common.c:333`,
|
||||
`:365`).
|
||||
|
||||
**v4.**
|
||||
|
||||
@@ -190,12 +192,28 @@ the dictionary.
|
||||
ended in an error if any of its lines did.
|
||||
- *What it prints.* For a failing case, `POST FAIL: name out<...>
|
||||
stack<...>`. Then `PARITY:V4_POST tests=N pass=N fail=N`.
|
||||
- *What is left.* What the cases define stays in the dictionary, as in
|
||||
v3 (ruled 2026-10-07, on being told that the capsule had ended with
|
||||
`FORGET` and left nothing). The system is sealed after POST, so `COLD`
|
||||
comes back to those words and `FORGET` will not go below them. Measured
|
||||
2026-10-07: they take about 1,290 cells of the 5,632 in the dictionary
|
||||
space.
|
||||
- *What is left: nothing*, as in v3. The system is sealed before POST,
|
||||
and after the last case the kernel has the node do `COLD`, which comes
|
||||
back to the system as sealed; what `COLD` prints is not shown. The
|
||||
dictionary is put back once, after all the cases, and not after each
|
||||
word's as v3 does: the expected results were taken from one v3 session
|
||||
in which nothing was put back between cases (6.4), and the capsule did
|
||||
the same with its one `FORGET` at the end.
|
||||
**How this came to be ruled twice.** On 2026-10-07 Captain Bob was told
|
||||
that v3 leaves the cases' definitions in the dictionary, and ruled "as
|
||||
v3: they stay". That was false: it was read from `run_single_test`,
|
||||
which puts back only the stacks, without reading `run_test_suite`. It
|
||||
was built so, and the review of the step found it; shown what v3 does,
|
||||
he ruled that POST leaves nothing.
|
||||
- *A case the node does not come back from* — it has stopped, or runs for
|
||||
ever — fails, and POST ends there: the runner names it and says how many
|
||||
cases were not run.
|
||||
- *What use still changes.* After POST and `COLD`, `HERE` and `LATEST` are
|
||||
where they were, but the dictionary hash is not what it was before POST:
|
||||
each word POST had interpreted has a different TTL in its entry, the
|
||||
count of uses left before its access is checked again
|
||||
(`v4/capsule/compile.v4`, `(ACL?)`). 138 cells, measured 2026-10-07. It
|
||||
is the same on every system, so the six still agree.
|
||||
- *Gone:* `capsules/v4/post79.4th` and its blocks 7000 up; the harness
|
||||
words; `(CATCH)` and `(EMIT-HOOK)`, with what `EMIT` and the prompt
|
||||
loop did for them.
|
||||
@@ -332,7 +350,7 @@ check for the FPGA gateway and is not part of this acceptance.
|
||||
| Hosted builds per ISA | `v4/Makefile` | Cross-compiler targets for aarch64 and riscv64 |
|
||||
|
||||
New: the shared v4 boot sequence (one file), the v4 dictionary hash, the
|
||||
case-extraction script, `forth79.4th` and `post79.4th`.
|
||||
case-extraction script, `forth79.4th` and `post79.4th` (the last gone since step 6b, 6.3).
|
||||
|
||||
The v3 boot is untouched: `STARFORTH_V4` defaults to off.
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
[2J[001;001H[=3h[2J[001;001H[2J[001;001H[8;042;160t[2J[001;001H[2J[001;001H[8;056;240t[2J[001;001HBdsDxe: loading Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)
|
||||
BdsDxe: starting Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)
|
||||
[2J[001;001H[=3h[2J[001;001HStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
RAW SERIAL UP
|
||||
[CKPT 002] Serial (COM1) initialized
|
||||
Monolithic build - kernel linked directly
|
||||
Collecting boot information...
|
||||
CmdLine: parsed OK
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
GOP: linear framebuffer found
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
EBS...
|
||||
EBS OK
|
||||
Calling kernel_main (monolithic)...
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0
|
||||
Architecture: amd64
|
||||
Build: Oct 7 2026 11:26:09
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 131
|
||||
Total memory: 1023 MB
|
||||
Usable memory: 966 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 248742
|
||||
Free pages : 247219
|
||||
Used pages : 1523
|
||||
Total MB : 971
|
||||
Free MB : 965
|
||||
Used MB : 5
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
APIC: IA32_APIC_BASE MSR=0x00000000fee00900
|
||||
APIC: stale-ISR drain: 0 EOI(s) issued
|
||||
APIC: initialized (xAPIC MMIO, TPR=0, SIVR=0x1FF, EOI-clear)
|
||||
APIC: init done
|
||||
|
||||
I/O APIC: init...
|
||||
I/O APIC: base=0xfec00000, gsi_base=0, overrides=5
|
||||
override: source=00 gsi=2 flags=0x0000
|
||||
override: source=05 gsi=5 flags=0x000d
|
||||
override: source=09 gsi=9 flags=0x000d
|
||||
override: source=0a gsi=10 flags=0x000d
|
||||
override: source=0b gsi=11 flags=0x000d
|
||||
i8042: keyboard ACKed enable-scanning
|
||||
i8042: IRQ1 enabled in controller config byte
|
||||
I/O APIC: keyboard IRQ1 routed (masked)
|
||||
|
||||
Timer: init...
|
||||
Timer: init start
|
||||
Timer: PM_TMR_BLK discovered from FADT at port 1544
|
||||
Timer: VM mode detected (hypervisor present).
|
||||
Timer: HPET calibration disabled (VM-exit MMIO would poison timing).
|
||||
Timer: WARNING: invariant TSC not present under hypervisor.
|
||||
Timer: continuing in RELATIVE mode (no determinism guarantees).
|
||||
Timer: RDTSCP not present; using RDTSC (less serialized).
|
||||
Timer: CPUID frequency unavailable; trying PM Timer...
|
||||
Timer: trust=1 (0=NONE,1=REL,2=ABS), TSC=1876630930 Hz
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 536870872
|
||||
Free bytes: 536870872
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 24641536
|
||||
Heap end addr: 561512448
|
||||
|
||||
Heartbeat: init...
|
||||
APIC Timer: calibrating...
|
||||
APIC Timer: apic_hz=908830414, tick_hz=100, initial_count=9088304
|
||||
APIC Timer: configured (masked, ready to start)
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=314 dict_hash=0x220ab283a504a3b3
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
PCI: ECAM mapped (amd64)
|
||||
virtio-blk: found device
|
||||
Artemis: virtio-blk attached
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 80247384] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
ok> : SQ DUP * ;
|
||||
ok
|
||||
ok> 7 SQ . 3 4 U* . .
|
||||
49 0 12 ok
|
||||
ok> T{
|
||||
UNKNOWN WORD: 'T{'
|
||||
ERROR
|
||||
ok> RS1
|
||||
UNKNOWN WORD: 'RS1'
|
||||
ERROR
|
||||
ok> COLD
|
||||
FORTH-79 Cold Start
|
||||
System initialized.
|
||||
ok
|
||||
ok> 3 4 U* . .
|
||||
0 12 ok
|
||||
ok> FORGET U*
|
||||
Protected word
|
||||
ERROR
|
||||
ok> 9 KERNEL-WORD ASK9 ASK9
|
||||
Argument out of range
|
||||
ERROR
|
||||
ok> 1 BLOCK C@ . 2047 BLOCK C@ .
|
||||
0 0 ok
|
||||
ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
|
||||
65 ok
|
||||
ok> 3072 BLOCK C@ .
|
||||
0 ok
|
||||
ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
|
||||
Storage refused
|
||||
ERROR
|
||||
ok> 9999999 BLOCK
|
||||
Block out of range
|
||||
ERROR
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
@@ -0,0 +1,128 @@
|
||||
UEFI firmware (version 2025.11-3ubuntu7.3 built at 15:40:26 on Sep 23 2026)
|
||||
[2J[001;001H[=3h[2J[001;001H[2J[001;001H[8;031;100t[2J[001;001HBdsDxe: failed to load Boot0002 "UEFI Misc Device" from PciRoot(0x0)/Pci(0x2,0x0): Not Found
|
||||
BdsDxe: failed to load Boot0003 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:04.0-1" from PciRoot(0x0)/Pci(0x4,0x0)/USB(0x0,0x0): Not Found
|
||||
BdsDxe: loading Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0)
|
||||
BdsDxe: starting Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0)
|
||||
[2J[001;001H[=3h[2J[001;001HStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
Collecting boot information...
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0
|
||||
Architecture: aarch64
|
||||
Build: Oct 7 2026 11:28:32
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 108
|
||||
Total memory: 4093 MB
|
||||
Usable memory: 4054 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 1039356
|
||||
Free pages : 1037945
|
||||
Used pages : 1411
|
||||
Total MB : 4059
|
||||
Free MB : 4054
|
||||
Used MB : 5
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
AArch64: running at EL1
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
PSCI: no DTB -- using HVC (QEMU virt-machine default)
|
||||
GICv2: no DTB GIC node -- using QEMU virt-machine defaults
|
||||
GICv2: distributor+CPU interface enabled, PPI 30
|
||||
APIC: init done
|
||||
|
||||
Timer: init...
|
||||
Timer: AArch64 generic timer initialised.
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 2147483608
|
||||
Free bytes: 2147483608
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 1207959552
|
||||
Heap end addr: 3355443200
|
||||
|
||||
Heartbeat: init...
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=314 dict_hash=0x220ab283a504a3b3
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
Artemis: virtio-blk attached
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 1493527] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
ok> : SQ DUP * ;
|
||||
ok
|
||||
ok> 7 SQ . 3 4 U* . .
|
||||
49 0 12 ok
|
||||
ok> T{
|
||||
UNKNOWN WORD: 'T{'
|
||||
ERROR
|
||||
ok> RS1
|
||||
UNKNOWN WORD: 'RS1'
|
||||
ERROR
|
||||
ok> COLD
|
||||
FORTH-79 Cold Start
|
||||
System initialized.
|
||||
ok
|
||||
ok> 3 4 U* . .
|
||||
0 12 ok
|
||||
ok> FORGET U*
|
||||
Protected word
|
||||
ERROR
|
||||
ok> 9 KERNEL-WORD ASK9 ASK9
|
||||
Argument out of range
|
||||
ERROR
|
||||
ok> 1 BLOCK C@ . 2047 BLOCK C@ .
|
||||
0 0 ok
|
||||
ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
|
||||
65 ok
|
||||
ok> 3072 BLOCK C@ .
|
||||
0 ok
|
||||
ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
|
||||
Storage refused
|
||||
ERROR
|
||||
ok> 9999999 BLOCK
|
||||
Block out of range
|
||||
ERROR
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
@@ -0,0 +1,198 @@
|
||||
|
||||
OpenSBI v1.8
|
||||
____ _____ ____ _____
|
||||
/ __ \ / ____| _ \_ _|
|
||||
| | | |_ __ ___ _ __ | (___ | |_) || |
|
||||
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
|
||||
| |__| | |_) | __/ | | |____) | |_) || |_
|
||||
\____/| .__/ \___|_| |_|_____/|____/_____|
|
||||
| |
|
||||
|_|
|
||||
|
||||
Platform Name : riscv-virtio,qemu
|
||||
Platform Features : medeleg
|
||||
Platform HART Count : 1
|
||||
Platform HART Protection : pmp
|
||||
Platform IPI Device : aclint-mswi
|
||||
Platform Timer Device : aclint-mtimer @ 10000000Hz
|
||||
Platform Console Device : uart8250
|
||||
Platform HSM Device : ---
|
||||
Platform PMU Device : ---
|
||||
Platform Reboot Device : syscon-reboot
|
||||
Platform Shutdown Device : syscon-poweroff
|
||||
Platform Suspend Device : ---
|
||||
Platform CPPC Device : ---
|
||||
Firmware Base : 0x80000000
|
||||
Firmware Size : 321 KB
|
||||
Firmware RW Offset : 0x40000
|
||||
Firmware RW Size : 65 KB
|
||||
Firmware Heap Offset : 0x47000
|
||||
Firmware Heap Size : 37 KB (total), 0 KB (reserved), 12 KB (used), 23 KB (free)
|
||||
Firmware Scratch Size : 4096 B (total), 1464 B (used), 2632 B (free)
|
||||
Runtime SBI Version : 3.0
|
||||
Standard SBI Extensions : ipi,pmu,srst,sse,hsm,rfnc,fwft,time,base,legacy,dbcn,dbtr
|
||||
Experimental SBI Extensions : none
|
||||
|
||||
Domain0 Name : root
|
||||
Domain0 Boot HART : 0
|
||||
Domain0 HARTs : 0*
|
||||
Domain0 Region00 : 0x0000000080040000-0x000000008005ffff M: (F,R,W) S/U: ()
|
||||
Domain0 Region01 : 0x0000000080000000-0x000000008003ffff M: (F,R,X) S/U: ()
|
||||
Domain0 Region02 : 0x0000000000100000-0x0000000000100fff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region03 : 0x0000000010000000-0x0000000010000fff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region04 : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: ()
|
||||
Domain0 Region05 : 0x000000000c400000-0x000000000c5fffff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region06 : 0x000000000c000000-0x000000000c3fffff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region07 : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)
|
||||
Domain0 Next Address : 0x0000000020000000
|
||||
Domain0 Next Arg1 : 0x00000000bfe00000
|
||||
Domain0 Next Mode : S-mode
|
||||
Domain0 SysReset : yes
|
||||
Domain0 SysSuspend : yes
|
||||
|
||||
Boot HART ID : 0
|
||||
Boot HART Domain : root
|
||||
Boot HART Priv Version : v1.12
|
||||
Boot HART Base ISA : rv64imafdch
|
||||
Boot HART ISA Extensions : sstc,zicntr,zihpm,zicboz,zicbom,sdtrig,svadu
|
||||
Boot HART PMP Count : 16
|
||||
Boot HART PMP Granularity : 2 bits
|
||||
Boot HART PMP Address Bits : 54
|
||||
Boot HART MHPM Info : 16 (0x0007fff8)
|
||||
Boot HART Debug Triggers : 2 triggers
|
||||
Boot HART MIDELEG : 0x0000000000001666
|
||||
Boot HART MEDELEG : 0x0000000000f4b509
|
||||
[2J[004D[=3h[2J[009D[2J[004D[8;031;100t[2J[016DRISC-V EDK2 firmware version 2025.11-3ubuntu7.3
|
||||
Press ESCAPE within 5 seconds for boot options ERROR: C40000002:V03051002 I0 6D33944A-EC75-4855-A54D-809C75241F6C 83FFF850
|
||||
BdsDxe: failed to load Boot0001 "UEFI Misc Device" fr
|
||||
om PciRoot(0x0)/Pci(0x1,0x0): Not Found
|
||||
[2J[001;001H[=3h[2J[009DStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
Monolithic build - kernel linked directly
|
||||
Collecting boot information...
|
||||
CmdLine: parsed OK
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
GOP: linear framebuffer found
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
Calling kernel_main (monolithic)...
|
||||
riscv64 item 4.3.5a: satp state at kernel entry (before switch)
|
||||
satp.MODE = 0x000000000000000a
|
||||
satp.PPN = 0x00000000000bf868
|
||||
__kernel_start = 0x00000000bdca29f8
|
||||
riscv64: satp cleared -- Bare mode, explicit (item 4.3.5a)
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0
|
||||
Architecture: riscv64
|
||||
Build: Oct 7 2026 11:31:39
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 100
|
||||
Total memory: 1020 MB
|
||||
Usable memory: 975 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 250273
|
||||
Free pages : 249621
|
||||
Used pages : 652
|
||||
Total MB : 977
|
||||
Free MB : 975
|
||||
Used MB : 2
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
PLIC: no DTB PLIC node -- using QEMU virt-machine default (base=0x0c000000)
|
||||
PLIC: init (S-mode context 1, threshold=0)
|
||||
APIC: init done
|
||||
|
||||
Timer: init...
|
||||
Timer: RISC-V time CSR @ 10000000 Hz (FALLBACK, no devicetree)
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 536870872
|
||||
Free bytes: 536870872
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 2214588416
|
||||
Heap end addr: 2751459328
|
||||
|
||||
Heartbeat: init...
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=314 dict_hash=0x220ab283a504a3b3
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
Artemis: virtio-blk attached
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 24420207] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
ok> : SQ DUP * ;
|
||||
ok
|
||||
ok> 7 SQ . 3 4 U* . .
|
||||
49 0 12 ok
|
||||
ok> T{
|
||||
UNKNOWN WORD: 'T{'
|
||||
ERROR
|
||||
ok> RS1
|
||||
UNKNOWN WORD: 'RS1'
|
||||
ERROR
|
||||
ok> COLD
|
||||
FORTH-79 Cold Start
|
||||
System initialized.
|
||||
ok
|
||||
ok> 3 4 U* . .
|
||||
0 12 ok
|
||||
ok> FORGET U*
|
||||
Protected word
|
||||
ERROR
|
||||
ok> 9 KERNEL-WORD ASK9 ASK9
|
||||
Argument out of range
|
||||
ERROR
|
||||
ok> 1 BLOCK C@ . 2047 BLOCK C@ .
|
||||
0 0 ok
|
||||
ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
|
||||
65 ok
|
||||
ok> 3072 BLOCK C@ .
|
||||
0 ok
|
||||
ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
|
||||
Storage refused
|
||||
ERROR
|
||||
ok> 9999999 BLOCK
|
||||
Block out of range
|
||||
ERROR
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
+20
-4
@@ -27,7 +27,7 @@ CFLAGS ?= $(CSTD) $(WARN) $(OPT)
|
||||
HERE := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
|
||||
|
||||
SRCS := $(wildcard $(HERE)/src/*.c)
|
||||
TESTS := $(wildcard $(HERE)/tests/*.c)
|
||||
TESTS := $(wildcard $(HERE)/tests/test_*.c)
|
||||
|
||||
# Cell widths to build and verify. 32 is the F18/Zynq case, 64 the aarch64
|
||||
# host case; see DECOMPOSITION.md D-5.
|
||||
@@ -183,10 +183,11 @@ post79:
|
||||
# PARITY:OK, POST: PASSED and the prompt: the same hashes on every ISA. It
|
||||
# also checks that what the boot loaded is part of the system: after COLD
|
||||
# the capsule's words and the kernel's are still there, and FORGET refuses
|
||||
# them.
|
||||
# them; that POST has left nothing of itself or of what its cases defined;
|
||||
# and that a boot whose POST has a failing case fails.
|
||||
.PHONY: hosted hosted-check
|
||||
hosted: $(foreach i,$(HOSTED_ISAS),$(BINDIR)/starforth4-$(i))
|
||||
hosted-check: $(foreach i,$(HOSTED_ISAS),$(BINDIR)/boot-$(i).txt)
|
||||
hosted-check: $(foreach i,$(HOSTED_ISAS),$(BINDIR)/boot-$(i).txt) $(BINDIR)/starforth4-postfail
|
||||
@grep -q '^POST: PASSED$$' $(BINDIR)/boot-amd64.txt || { echo "hosted-check: no POST: PASSED"; exit 1; }
|
||||
@cmp $(BINDIR)/boot-amd64.txt $(BINDIR)/boot-aarch64.txt
|
||||
@cmp $(BINDIR)/boot-amd64.txt $(BINDIR)/boot-riscv64.txt
|
||||
@@ -194,7 +195,22 @@ hosted-check: $(foreach i,$(HOSTED_ISAS),$(BINDIR)/boot-$(i).txt)
|
||||
@grep -q '^ok> 0 12 ok$$' $(BINDIR)/cold-amd64.txt || { echo "hosted-check: COLD lost the capsule's words"; cat $(BINDIR)/cold-amd64.txt; exit 1; }
|
||||
@grep -q '^ok> Protected word$$' $(BINDIR)/cold-amd64.txt || { echo "hosted-check: a capsule word could be forgotten"; exit 1; }
|
||||
@grep -q '^ok> Goodbye!$$' $(BINDIR)/cold-amd64.txt || { echo "hosted-check: COLD lost BYE"; exit 1; }
|
||||
@echo "hosted-check: amd64, aarch64 and riscv64 boot identically"
|
||||
@printf 'RS1\nT{\nWORDS\n' | $(BINDIR)/starforth4-amd64 > $(BINDIR)/after-post-amd64.txt
|
||||
@grep -q "^ok> UNKNOWN WORD: 'RS1'$$" $(BINDIR)/after-post-amd64.txt || { echo "hosted-check: a word a POST case defined is still there"; exit 1; }
|
||||
@grep -q "^ok> UNKNOWN WORD: 'T{'$$" $(BINDIR)/after-post-amd64.txt || { echo "hosted-check: POST's harness is on the node"; exit 1; }
|
||||
@$(BINDIR)/starforth4-postfail < /dev/null > $(BINDIR)/postfail.txt; test $$? -ne 0 || { echo "hosted-check: a boot with a failing case did not fail"; exit 1; }
|
||||
@grep -q '^POST FAIL: fail.wrong out<5 5 $$' $(BINDIR)/postfail.txt || { echo "hosted-check: the failing case was not named"; cat $(BINDIR)/postfail.txt; exit 1; }
|
||||
@grep -q '^POST FAIL: fail.many out<QQQQ' $(BINDIR)/postfail.txt || { echo "hosted-check: the case that prints too much was not named"; exit 1; }
|
||||
@grep -q '^PARITY:V4_POST tests=4 pass=2 fail=2$$' $(BINDIR)/postfail.txt || { echo "hosted-check: the tally is wrong"; cat $(BINDIR)/postfail.txt; exit 1; }
|
||||
@grep -q '^POST: FAILED$$' $(BINDIR)/postfail.txt && grep -q '^PARITY:FAIL$$' $(BINDIR)/postfail.txt || { echo "hosted-check: no PARITY:FAIL, POST: FAILED"; exit 1; }
|
||||
@! grep -q '^ok> \|^5 5 $$\|PARITY:OK\|PARITY:V4_SYSTEM' $(BINDIR)/postfail.txt || { echo "hosted-check: a failed boot gave a prompt, or showed a case's printing"; exit 1; }
|
||||
@echo "hosted-check: amd64, aarch64 and riscv64 boot identically; a boot with a failing case fails"
|
||||
|
||||
# A hosted program whose POST has a case that fails (tests/post_cases_fail.c
|
||||
# in the place of system/post_cases.c): hosted-check boots it and requires
|
||||
# that the boot stops there. docs/v4.0.0/MESH.md step 6b, acceptance 4.
|
||||
$(BINDIR)/starforth4-postfail: $(BINDIR)/starforth4-amd64 $(HERE)/tests/post_cases_fail.c
|
||||
$(CC) $(SYSTEM_CFLAGS) -static $(BINDIR)/hosted-amd64.o $(BINDIR)/v4_image_64.c $(CAPSULE_DIR_C) $(ENGINE_SRCS) $(filter-out %/post_cases.c,$(SYSTEM_SRCS)) $(HERE)/tests/post_cases_fail.c $(BINDIR)/v3o-amd64/*.o -o $@
|
||||
|
||||
.PHONY: all test sanitize clean $(addprefix test-,$(WIDTHS))
|
||||
|
||||
|
||||
+9
-5
@@ -62,7 +62,7 @@ load `v4:forth79.4th`, pass POST and reach `ok>`, with the same lines:
|
||||
PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=... capsule_hash=0x97a655081b2af559 words=298
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=... dict_hash=...
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_CAPSULE name=v4:post79.4th capsule_id=... dict_hash=...
|
||||
PARITY:V4_SYSTEM word_count=314 dict_hash=...
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
ok>
|
||||
@@ -174,10 +174,14 @@ and the v3 cases left out, are listed with reasons in
|
||||
The runner, `v4/system/post.c`, feeds each case to the node a line at a
|
||||
time, keeps what the node prints, reads its data stack from outside, and
|
||||
judges: an error exactly if one is expected, and otherwise the stack and
|
||||
every character printed. Nothing of POST is in the node's dictionary. What
|
||||
the cases define stays there, as in v3, and the system is sealed after
|
||||
POST. The boot then prints `PARITY:V4_SYSTEM word_count=N dict_hash=0x...`,
|
||||
and passes only if no case failed (`v4/system/boot.c`).
|
||||
every character printed. Nothing of POST is in the node's dictionary, and
|
||||
POST leaves nothing: the system is sealed before it, and afterwards the
|
||||
kernel puts the node back to the system as sealed, as v3 puts the
|
||||
dictionary back after each of its suites. The boot then prints
|
||||
`PARITY:V4_SYSTEM word_count=N dict_hash=0x...`, and passes only if no
|
||||
case failed (`v4/system/boot.c`). A case the node does not come back from
|
||||
ends POST there, named. `make -C v4 hosted-check` also boots a program
|
||||
whose POST has failing cases and requires that the boot fails.
|
||||
|
||||
Not tested: `KEY`, `EXPECT`, `QUERY` (the keyboard) and `QUIT` (it returns
|
||||
without ` ok`).
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
\ written here as text for the text assembler (v4/include/v4/text.h).
|
||||
\
|
||||
\ Constants the loader supplies: N-1 (cell bits - 1), NODE-ERROR, CONSOLE-TX,
|
||||
\ CONSOLE-RX, CONSOLE-STATUS, BASE, (EMIT-HOOK), (MSG), (REPLY), (ME), (OUT),
|
||||
\ CONSOLE-RX, CONSOLE-STATUS, BASE, (MSG), (REPLY), (ME), (OUT),
|
||||
\ (OUT^), (CONSOLE), (ROUTES), (ROUTE#), (ROUTE-DEFAULT), (PRINT-TO),
|
||||
\ (PRINT-PORT).
|
||||
\
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
*
|
||||
* PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x... capsule_hash=0x... words=N
|
||||
* PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x... capsule_hash=0x... dict_hash=0x...
|
||||
* PARITY:V4_POST tests=N pass=N fail=N (printed by the POST capsule)
|
||||
* PARITY:V4_CAPSULE name=v4:post79.4th capsule_id=0x... capsule_hash=0x... dict_hash=0x...
|
||||
* PARITY:V4_POST tests=N pass=N fail=N (POST is the kernel's: v4/post.h)
|
||||
* PARITY:V4_SYSTEM word_count=N dict_hash=0x... (the system as sealed, after POST)
|
||||
* PARITY:OK
|
||||
* POST: PASSED
|
||||
*
|
||||
|
||||
+10
-3
@@ -37,7 +37,14 @@ extern const unsigned v4_post_case_count;
|
||||
* of it; and judges. A case passes when it ended in an error exactly if
|
||||
* one was expected and, if none was, its stack and its printing are what
|
||||
* the table has. It has ended in an error if any of its lines did. What
|
||||
* the cases define stays in the node's dictionary, as in v3. */
|
||||
* the cases define is still in the node's dictionary when the runner
|
||||
* returns: whoever runs POST puts the dictionary back afterwards, as v3
|
||||
* does after each of its suites (v3/src/test_runner/test_common.c,
|
||||
* run_test_suite: "to remove test-created words").
|
||||
*
|
||||
* If the node does not come back from a line -- it has stopped, or runs for
|
||||
* ever -- that case fails and POST ends there: the runner says which case
|
||||
* it was and how many were not run. */
|
||||
#define V4_POST_OUT 1024u /* the most of a case's printing that is kept */
|
||||
|
||||
typedef struct {
|
||||
@@ -54,8 +61,8 @@ typedef struct {
|
||||
typedef struct { unsigned tests, pass, fail; } v4_post_tally;
|
||||
|
||||
/* Run the cases. Prints "POST FAIL: name out<...> stack<...>" for each
|
||||
* failing case and then "PARITY:V4_POST tests=N pass=N fail=N". Returns 1
|
||||
* if none failed. */
|
||||
* failing case and then "PARITY:V4_POST tests=N pass=N fail=N", where tests
|
||||
* is how many were run. Returns 1 if every case was run and none failed. */
|
||||
int v4_post_run(const v4_post_host *h, const v4_post_case *cases, unsigned count, v4_post_tally *tally);
|
||||
|
||||
#endif /* V4_POST_H */
|
||||
|
||||
+21
-6
@@ -19,8 +19,9 @@ static const char *const boot_capsules[] = {
|
||||
};
|
||||
|
||||
/* POST is part of the boot, and is the kernel's (v4/include/v4/post.h;
|
||||
* docs/v4.0.0/NUCLEUS.md 6.3): when the capsules are in, the kernel feeds
|
||||
* its cases to the node and judges them, and the boot passes only if none
|
||||
* docs/v4.0.0/NUCLEUS.md 6.3): when the capsules are in and the system is
|
||||
* sealed, the kernel feeds its cases to the node and judges them, puts the
|
||||
* node back to the system as sealed, and the boot passes only if none
|
||||
* failed. -DV4_POST_AT_BOOT=0 leaves it out, for work on a vocabulary
|
||||
* that does not pass yet. */
|
||||
#ifndef V4_POST_AT_BOOT
|
||||
@@ -367,22 +368,36 @@ int v4_boot_run(const v4_boot *b)
|
||||
|
||||
for (i = 0; i < sizeof boot_capsules / sizeof boot_capsules[0]; i++)
|
||||
if (!load_capsule(b, boot_capsules[i])) { say(b, "PARITY:FAIL\nPOST: FAILED\n"); return 0; }
|
||||
/* The kernel's words and the capsules are the system: COLD comes back
|
||||
* to here, and FORGET will not go below it. */
|
||||
v4_image_seal(b->n, b->im);
|
||||
|
||||
#if V4_POST_AT_BOOT
|
||||
{
|
||||
static const char cold[] = "COLD";
|
||||
v4_post_host host;
|
||||
v4_post_tally tally;
|
||||
unsigned printed = 0;
|
||||
int how;
|
||||
|
||||
host.self = (void *)b; host.n = b->n; host.line = post_line; host.say = post_say;
|
||||
if (!v4_post_run(&host, v4_post_cases, v4_post_case_count, &tally)) {
|
||||
say(b, "V4: POST reported failures\nPARITY:FAIL\nPOST: FAILED\n");
|
||||
return 0;
|
||||
}
|
||||
/* POST leaves nothing: the node is put back to the system as it was
|
||||
* sealed, as v3 puts the dictionary back after each of its suites
|
||||
* (v3/src/test_runner/test_common.c, run_test_suite). What COLD
|
||||
* prints is not shown. */
|
||||
v4_dstack_reset(&b->n->ds);
|
||||
how = run_line(b, cold, (unsigned)sizeof cold - 1u, (char *)cold, 0u, &printed);
|
||||
if (how != V4_TEXT_COMPLETED && how != V4_TEXT_QUIT) {
|
||||
say(b, "V4: the node did not come back to the system after POST\nPARITY:FAIL\nPOST: FAILED\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The kernel's words, the capsules and what POST's cases defined are
|
||||
* the system, as in v3: COLD comes back to here, and FORGET will not go
|
||||
* below it. */
|
||||
v4_image_seal(b->n, b->im);
|
||||
say(b, "PARITY:V4_SYSTEM word_count="); say_dec(b, word_count(b->n, b->im));
|
||||
say(b, " dict_hash="); say_hex(b, v4_boot_dict_hash(b->n, b->im));
|
||||
say(b, "\n");
|
||||
|
||||
+12
-2
@@ -44,18 +44,19 @@ int v4_post_run(const v4_post_host *h, const v4_post_case *cases, unsigned count
|
||||
for (i = 0; i < count; i++) {
|
||||
const v4_post_case *c = &cases[i];
|
||||
unsigned kept = 0, total = 0, len = 0, depth;
|
||||
int errored = 0, came_back = 1, ok, how;
|
||||
int errored = 0, came_back = 1, lost = 0, ok, how;
|
||||
|
||||
/* every case starts from the same state */
|
||||
v4_dstack_reset(&h->n->ds);
|
||||
how = h->line(h->self, state_line, (unsigned)sizeof state_line - 1u, out, 0u, &len);
|
||||
if (how < 0) lost = 1;
|
||||
if (how != V4_TEXT_COMPLETED) came_back = 0;
|
||||
v4_dstack_reset(&h->n->ds);
|
||||
|
||||
for (k = 0; came_back && k < c->line_count; k++) {
|
||||
len = 0;
|
||||
how = h->line(h->self, c->lines[k], length(c->lines[k]), out + kept, V4_POST_OUT - kept, &len);
|
||||
if (how < 0) { came_back = 0; break; }
|
||||
if (how < 0) { came_back = 0; lost = 1; break; }
|
||||
if (how == V4_TEXT_ERROR) errored = 1;
|
||||
total += len;
|
||||
kept = total < V4_POST_OUT ? total : V4_POST_OUT;
|
||||
@@ -95,6 +96,15 @@ int v4_post_run(const v4_post_host *h, const v4_post_case *cases, unsigned count
|
||||
say(h, "> stack<");
|
||||
for (k = depth < SHOWN_STACK ? depth : SHOWN_STACK; k-- > 0; ) { say_number(h, (long long)left[k]); say(h, " "); }
|
||||
say(h, ">\n");
|
||||
|
||||
/* The node did not come back from a line: it is stopped, or will
|
||||
* run for ever. Nothing more can be asked of it, so POST ends
|
||||
* here and says which case it was. */
|
||||
if (lost) {
|
||||
say(h, "POST: the node did not come back from "); say(h, c->name);
|
||||
say(h, "; "); say_number(h, (long long)(count - i - 1u)); say(h, " not run\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
say(h, "PARITY:V4_POST tests="); say_number(h, (long long)tally->tests);
|
||||
say(h, " pass="); say_number(h, (long long)tally->pass);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/* post_cases_fail.c -- a table of cases for the boot to fail on.
|
||||
* docs/v4.0.0/MESH.md step 6b, acceptance 4; v4/Makefile, hosted-check.
|
||||
*
|
||||
* Linked into a hosted program in the place of v4/system/post_cases.c, so
|
||||
* that the boot itself (v4/system/boot.c) is seen to stop on a failing
|
||||
* case, to keep what a case prints off the console, and to hold no more of
|
||||
* it than it has room for. It is not a test program of its own: the suite
|
||||
* does not build it.
|
||||
*/
|
||||
#include "v4/post.h"
|
||||
|
||||
static const char *const l_right[] = { "5 DUP . . CR" };
|
||||
static const char *const l_wrong[] = { "5 DUP . . CR" };
|
||||
static const char *const l_many[] = { ": MANY 2000 0 DO 81 EMIT LOOP ;", "MANY" };
|
||||
static const char *const l_two[] = { "65 EMIT", "66 EMIT" };
|
||||
|
||||
const v4_post_case v4_post_cases[] = {
|
||||
{ "fail.right", l_right, 1u, V4_POST_STACK, 0, 0u, "5 5 \012", 5u },
|
||||
{ "fail.wrong", l_wrong, 1u, V4_POST_STACK, 0, 0u, "5 6 \012", 5u },
|
||||
{ "fail.many", l_many, 2u, V4_POST_STACK, 0, 0u, "Q", 1u },
|
||||
{ "fail.twoline", l_two, 2u, V4_POST_STACK, 0, 0u, "AB", 2u },
|
||||
};
|
||||
|
||||
const unsigned v4_post_case_count = 4u;
|
||||
+23
-15
@@ -361,10 +361,11 @@ static const char *say(const char *input)
|
||||
}
|
||||
/* POST's RUNNER (v4/system/post.c), with these tests as its host: a line is
|
||||
* sent to the node as the console sends one, and what the node prints is
|
||||
* handed back and not shown. `post_lost` is the text of a line that is
|
||||
* never to come back, and `post_state_fails` makes the line that sets the
|
||||
* state end in an error; `post_said` is what the runner printed. */
|
||||
static const char *post_lost;
|
||||
* handed back and not shown. `post_step_limit` is how long a line may
|
||||
* take before the node is given up on, and `post_state_fails` makes the
|
||||
* line that sets the state end in an error; `post_said` is what the runner
|
||||
* printed. */
|
||||
static long post_step_limit = 40000000;
|
||||
static int post_state_fails;
|
||||
static char post_said[4096];
|
||||
static unsigned post_said_len;
|
||||
@@ -373,12 +374,11 @@ static int post_line(void *self, const char *text, unsigned text_len, char *o, u
|
||||
int ended;
|
||||
(void)self;
|
||||
*len = 0;
|
||||
if (post_lost && strlen(post_lost) == text_len && memcmp(post_lost, text, text_len) == 0) return -1;
|
||||
if (post_state_fails && text_len == 25 && memcmp(text, "DECIMAL FORTH DEFINITIONS", 25) == 0) text = "NOSUCHWORD-FOR-STATE ";
|
||||
if (!v4_message_text(&to_node, 0, 1, V4_MSG_TEXT, text, text_len)) return -1;
|
||||
to_sent = 0; from_node.count = 0;
|
||||
shown_len = 0; shown_dropped = 0;
|
||||
ended = run_line(40000000);
|
||||
ended = run_line(post_step_limit);
|
||||
if (ended != 1) return -1;
|
||||
*len = shown_dropped ? (unsigned)sizeof shown + 1u : shown_len;
|
||||
memcpy(o, shown, shown_len < cap ? shown_len : cap);
|
||||
@@ -1259,22 +1259,30 @@ int main(void)
|
||||
CHECK(post_one("many", "MANY", 0, V4_POST_STACK, 0, 0, big) == 0 && strstr(post_said, "POST FAIL: many ") != NULL, "a case that prints more than the runner keeps fails, by name");
|
||||
CHECK(post_one("after.many", "1 2 +", 0, V4_POST_STACK, three, 1, "") == 1, "and the next case is judged as usual");
|
||||
|
||||
/* a line that never comes back */
|
||||
post_lost = "LOST-LINE";
|
||||
/* output on more than one line of a case */
|
||||
CHECK(post_one("two.out", "65 EMIT", "66 EMIT", V4_POST_STACK, 0, 0, "AB") == 1 && post_one("two.out2", "65 EMIT", "66 EMIT", V4_POST_STACK, 0, 0, "AA") == 0,
|
||||
"what a case prints on its second line follows what it printed on its first");
|
||||
|
||||
/* a case the node does not come back from: POST stops there */
|
||||
CHECK(is(say(": SPIN BEGIN 0 UNTIL ;\n"), " ok\nok> "), "a word that never ends");
|
||||
{
|
||||
static const char *const la[] = { "1 2 +" }, *const lb[] = { "LOST-LINE" }, *const lc[] = { "65 EMIT" };
|
||||
static const char *const la[] = { "1 2 +" }, *const lb[] = { "SPIN" }, *const lc[] = { "65 EMIT" };
|
||||
static const v4_post_case three_cases[] = {
|
||||
{ "first", la, 1u, V4_POST_STACK, three, 1u, "", 0u },
|
||||
{ "lost", lb, 1u, V4_POST_STACK, 0, 0u, "", 0u },
|
||||
{ "last", lc, 1u, V4_POST_STACK, 0, 0u, "A", 1u },
|
||||
{ "spins", lb, 1u, V4_POST_STACK, 0, 0u, "", 0u },
|
||||
{ "never.run", lc, 1u, V4_POST_STACK, 0, 0u, "A", 1u },
|
||||
};
|
||||
v4_post_tally t;
|
||||
post_said_len = 0; post_said[0] = 0;
|
||||
CHECK(v4_post_run(&post_host, three_cases, 3, &t) == 0 && t.tests == 3 && t.pass == 2 && t.fail == 1
|
||||
&& strstr(post_said, "POST FAIL: lost ") != NULL && strstr(post_said, "PARITY:V4_POST tests=3 pass=2 fail=1\n") != NULL,
|
||||
"a line that does not come back fails its case; the others are still judged, and the run is not a pass: \"%s\"", post_said);
|
||||
post_step_limit = 2000000;
|
||||
CHECK(v4_post_run(&post_host, three_cases, 3, &t) == 0 && t.tests == 2 && t.pass == 1 && t.fail == 1,
|
||||
"the run is not a pass, and the case after it is not run: %u run, %u passed, %u failed", t.tests, t.pass, t.fail);
|
||||
CHECK(strstr(post_said, "POST FAIL: spins ") != NULL && strstr(post_said, "POST: the node did not come back from spins; 1 not run\n") != NULL
|
||||
&& strstr(post_said, "never.run") == NULL && strstr(post_said, "PARITY:V4_POST tests=2 pass=1 fail=1\n") != NULL,
|
||||
"it is named as the case the node did not come back from, with how many were not run: \"%s\"", post_said);
|
||||
post_step_limit = 40000000;
|
||||
}
|
||||
post_lost = 0;
|
||||
boot(); /* the node was left spinning */
|
||||
}
|
||||
|
||||
/* ---- nothing of POST is on the node (NUCLEUS.md 6.3) ---- */
|
||||
|
||||
@@ -344,7 +344,7 @@ int main(void)
|
||||
printf("v4 unit tests: V4_CELL_BITS=%d, V4_NODE_WORDS=%u\n", V4_CELL_BITS, (unsigned)V4_NODE_WORDS);
|
||||
if (V4_CELL_BITS != 64) {
|
||||
/* The capsules the unit is built from are the 64-bit products': the
|
||||
* expected results in post79.4th are v3's, on 64-bit cells, and the
|
||||
* expected results in POST's table are v3's, on 64-bit cells, and the
|
||||
* nucleus capsule is nucleus-64. POST has never been run on 32-bit
|
||||
* cells (docs/v4.0.0/MESH.md, step 5). */
|
||||
printf(" not run at this width: the capsules are the 64-bit products'\n");
|
||||
@@ -400,16 +400,30 @@ int main(void)
|
||||
}
|
||||
CHECK(strcmp(tell(10, "NODE-ME ."), "0 ") == 0 && refused == 0, "it asks where it is, and is answered");
|
||||
CHECK(load(10, "forth79.4th") == 0, "it takes in FORTH-79");
|
||||
CHECK(told(10, "(SEAL)"), "the nucleus and FORTH-79 are the system POST is run on");
|
||||
{
|
||||
static v4_cell before[V4_NODE_WORDS];
|
||||
v4_post_host host;
|
||||
v4_post_tally tally;
|
||||
host.self = 0; host.n = node_numbered(10); host.line = post_line; host.say = post_say;
|
||||
v4_node *hera = node_numbered(10);
|
||||
v4_cell here = hera->mem[DP] / 4, k, changed = 0, first = -1;
|
||||
uint64_t hash = v4_image_dict_hash(hera, &im);
|
||||
memcpy(before, hera->mem, sizeof before);
|
||||
host.self = 0; host.n = hera; host.line = post_line; host.say = post_say;
|
||||
CHECK(v4_post_run(&host, v4_post_cases, v4_post_case_count, &tally) && tally.tests == 538 && tally.pass == 538 && tally.fail == 0
|
||||
&& strstr(post_said, "PARITY:V4_POST tests=538 pass=538 fail=0\n") != NULL && strstr(post_said, "POST FAIL") == NULL,
|
||||
"and passes POST, which the kernel runs on her: %u of %u, %u failed; \"%s\"", tally.pass, tally.tests, tally.fail, post_said);
|
||||
CHECK(strcmp(tell(10, "RS1"), "42 42 \n") == 0, "while POST runs, what its cases define is on her: \"%s\"", printed);
|
||||
CHECK(strstr(tell(10, "COLD"), "Cold Start") != NULL, "the kernel puts her back to the system as it was sealed");
|
||||
CHECK(hera->mem[DP] == before[DP] && hera->mem[LATEST] == before[LATEST], "HERE and LATEST are where they were before POST");
|
||||
for (k = 0; k < here; k++) if (hera->mem[k] != before[k]) { if (first < 0) first = k; changed++; }
|
||||
/* What differs is the TTL in the entry of each word POST had interpreted: a count of uses left before
|
||||
* the word's access is checked again, which every use counts down (compile.v4, (ACL?)), as in v3. */
|
||||
printf(" after POST and COLD: %ld of the %ld cells below HERE differ from before POST (the first at %ld); dict_hash %s\n",
|
||||
(long)changed, (long)here, (long)first, v4_image_dict_hash(hera, &im) == hash ? "the same" : "differs");
|
||||
}
|
||||
CHECK(strstr(tell(10, "T{"), "UNKNOWN WORD") != NULL, "nothing of POST's harness is on her: \"%s\"", printed);
|
||||
CHECK(strcmp(tell(10, "RS1"), "42 42 \n") == 0, "what POST's cases defined is: \"%s\"", printed);
|
||||
CHECK(strstr(tell(10, "RS1"), "UNKNOWN WORD") != NULL && strstr(tell(10, "ZERO"), "UNKNOWN WORD") != NULL, "nor anything POST's cases defined: POST leaves nothing, as in v3: \"%s\"", printed);
|
||||
CHECK(load(10, "hera.4th") == 0, "and its own capsule, which makes it Hera");
|
||||
CHECK(told(10, "(SEAL)"), "that is the system it comes back to");
|
||||
|
||||
@@ -423,7 +437,6 @@ int main(void)
|
||||
CHECK(post_passed[10] == 0 && post_passed[11] == 0 && post_passed[12] == 0 && post_passed[13] == 0 && post_passed[14] == 0 && post_other == 0,
|
||||
"a node she births is not POSTed, and no node prints a POST tally: POST is the kernel's, once, on Hera: %u %u %u %u %u, %u failed",
|
||||
post_passed[10], post_passed[11], post_passed[12], post_passed[13], post_passed[14], post_other);
|
||||
CHECK(strstr(tell(10, "COLD"), "Cold Start") != NULL && strcmp(tell(10, "RS1"), "42 42 \n") == 0, "COLD on Hera comes back to a system that has what POST's cases defined: \"%s\"", printed);
|
||||
CHECK(parity_count == 4 && parity_number[0] == 11 && parity_number[1] == 12 && parity_number[2] == 13 && parity_number[3] == 14, "the parity of each was recorded: %u", parity_count);
|
||||
CHECK(parity_hash[0] == parity_hash[1] && parity_hash[1] == parity_hash[2] && parity_hash[2] == parity_hash[3],
|
||||
"and their dictionary hashes are the same: %016llx %016llx %016llx %016llx",
|
||||
|
||||
Reference in New Issue
Block a user