fix(v4.0.0): three defects -- a refused device write, a failed starting state, a case that QUITs
A block write the device refuses after the kernel has taken the node's copy: the node was told "Storage refused" while the kernel's cache kept the new data, to be read back and perhaps written later. The kernel now puts its own copy back as it was. Tested with a device whose writes can be made to fail; it failed first. POST's runner: a case whose starting state could not be set says so, with what the node said, where it showed nothing; and a case that ends with QUIT fails, as it did when the cases were a capsule, where the runner had taken it for a completed line. Both tests failed first. The v4 boot says "Artemis: virtio-blk attached" only when the attach worked. make -C v4 test, sanitize and hosted-check pass; amd64, aarch64 and riscv64 boot, POST 538 of 538, dict_hash 0x5f0a949a6fc8ef2b on all six: logs/20261007-135741, -140004, -140329. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bc6deab3f5
commit
193523d873
@@ -1,5 +1,5 @@
|
||||
# Capsule Block Manifest — Auto-generated
|
||||
<!-- Generated by mkcapsule --manifest 2026-10-07T16:22:56Z -->
|
||||
<!-- Generated by mkcapsule --manifest 2026-10-07T18:02:47Z -->
|
||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||
<!-- Hand-written justifications and immutability notes live -->
|
||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||
|
||||
@@ -490,11 +490,12 @@ static void sk_v4_block_chain(void)
|
||||
}
|
||||
console_println("PCI: init...");
|
||||
pci_init(sk_v4_boot_info->acpi_table);
|
||||
if (virtio_blk_find_artemis(&artemis_dev) == 0) {
|
||||
console_println("Artemis: virtio-blk attached");
|
||||
blk_subsys_attach_device(&artemis_dev);
|
||||
} else {
|
||||
if (virtio_blk_find_artemis(&artemis_dev) != 0) {
|
||||
console_println("Artemis: no virtio-blk disk");
|
||||
} else if (blk_subsys_attach_device(&artemis_dev) == BLK_OK) {
|
||||
console_println("Artemis: virtio-blk attached");
|
||||
} else {
|
||||
console_println("Artemis: virtio-blk found, and could not be attached");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
[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 13:57:12
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 131
|
||||
Total memory: 1023 MB
|
||||
Usable memory: 966 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 248743
|
||||
Free pages : 247220
|
||||
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=2148522542 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=1032714420, tick_hz=100, initial_count=10327144
|
||||
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=0xbb8f7aba92a2f5dc capsule_hash=0xbb8f7aba92a2f5dc 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=0x145ecc5563d10b54
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=314 dict_hash=0x5f0a949a6fc8ef2b
|
||||
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
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 80492958] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
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> 5 7 PORT!
|
||||
No one on that port
|
||||
ERROR
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
@@ -0,0 +1,133 @@
|
||||
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 13:59:36
|
||||
|
||||
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=0xbb8f7aba92a2f5dc capsule_hash=0xbb8f7aba92a2f5dc 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=0x145ecc5563d10b54
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=314 dict_hash=0x5f0a949a6fc8ef2b
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 1398175] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
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> 5 7 PORT!
|
||||
No one on that port
|
||||
ERROR
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
@@ -0,0 +1,203 @@
|
||||
|
||||
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 = 0x00000000bdca0a04
|
||||
riscv64: satp cleared -- Bare mode, explicit (item 4.3.5a)
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0
|
||||
Architecture: riscv64
|
||||
Build: Oct 7 2026 14:02:48
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 100
|
||||
Total memory: 1020 MB
|
||||
Usable memory: 975 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 250271
|
||||
Free pages : 249619
|
||||
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=0xbb8f7aba92a2f5dc capsule_hash=0xbb8f7aba92a2f5dc 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=0x145ecc5563d10b54
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=314 dict_hash=0x5f0a949a6fc8ef2b
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 26484591] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
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> 5 7 PORT!
|
||||
No one on that port
|
||||
ERROR
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
@@ -34,7 +34,8 @@
|
||||
* by SAVE-BUFFERS or when its slot is wanted for another block. (v3's
|
||||
* UPDATE copies the slot to the kernel at once; the standard is followed.)
|
||||
* A slot whose block is not marked is taken before one whose block is. A
|
||||
* block that storage would not take is let go of: its slot is empty.
|
||||
* block that storage would not take is let go of: its slot is empty, and
|
||||
* the kernel keeps the block as it was before, not what was refused.
|
||||
*
|
||||
* When the kernel's chain of devices changes, everything in the slots is
|
||||
* let go and nothing of it is written, as v3 does (blk_vm_check_epoch).
|
||||
|
||||
@@ -36,7 +36,10 @@ extern const unsigned v4_post_case_count;
|
||||
* case's lines one at a time, keeping what the node prints and showing none
|
||||
* 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 table has. It has ended in an error if any of its lines did. A
|
||||
* case one of whose lines ends with QUIT fails: it went back to the
|
||||
* terminal and did not complete. So does one whose starting state could
|
||||
* not be set, and what the node said of that is shown. What
|
||||
* 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,
|
||||
|
||||
+15
-1
@@ -30,12 +30,14 @@ static v4_cell slot_addr(const v4_blocks *w, unsigned s)
|
||||
* no longer marked. */
|
||||
static int write_slot(v4_blocks *w, v4_node *n, unsigned s)
|
||||
{
|
||||
static uint8_t was[V4_BLOCK_CELLS * 4u]; /* the block as the kernel had it, in case it is refused */
|
||||
uint8_t *b = blk_get_buffer(w->block[s], 1);
|
||||
v4_cell at = slot_addr(w, s);
|
||||
unsigned i;
|
||||
|
||||
w->changed[s] = 0;
|
||||
if (!b) return V4_BLOCK_REFUSED;
|
||||
for (i = 0; i < V4_BLOCK_CELLS * 4u; i++) was[i] = b[i];
|
||||
for (i = 0; i < V4_BLOCK_CELLS; i++) {
|
||||
v4_ucell c = (v4_ucell)n->mem[at + (v4_cell)i];
|
||||
b[4u * i] = (uint8_t)(c & 0xFFu);
|
||||
@@ -43,7 +45,19 @@ static int write_slot(v4_blocks *w, v4_node *n, unsigned s)
|
||||
b[4u * i + 2u] = (uint8_t)((c >> 16) & 0xFFu);
|
||||
b[4u * i + 3u] = (uint8_t)((c >> 24) & 0xFFu);
|
||||
}
|
||||
return (blk_update(w->block[s]) == BLK_OK && blk_flush(w->block[s]) == BLK_OK) ? V4_BLOCK_OK : V4_BLOCK_REFUSED;
|
||||
if (blk_update(w->block[s]) == BLK_OK && blk_flush(w->block[s]) == BLK_OK) return V4_BLOCK_OK;
|
||||
|
||||
/* Storage would not have it. The node is told so, and the kernel does
|
||||
* not keep what was refused: its own copy is put back as it was, so
|
||||
* that the block reads as before and what was refused is not written
|
||||
* later. The buffer is asked for again, since the failed write may
|
||||
* have moved it. */
|
||||
b = blk_get_buffer(w->block[s], 1);
|
||||
if (b) {
|
||||
for (i = 0; i < V4_BLOCK_CELLS * 4u; i++) b[i] = was[i];
|
||||
(void)blk_update(w->block[s]);
|
||||
}
|
||||
return V4_BLOCK_REFUSED;
|
||||
}
|
||||
|
||||
/* A slot to put a block in: an empty one, or one whose block is not marked,
|
||||
|
||||
+10
-4
@@ -44,13 +44,16 @@ 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, lost = 0, ok, how;
|
||||
int errored = 0, came_back = 1, lost = 0, no_state = 0, quit = 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);
|
||||
how = h->line(h->self, state_line, (unsigned)sizeof state_line - 1u, out, V4_POST_OUT, &len);
|
||||
if (how < 0) lost = 1;
|
||||
if (how != V4_TEXT_COMPLETED) came_back = 0;
|
||||
if (how != V4_TEXT_COMPLETED) { /* what the node said of it is what is shown */
|
||||
came_back = 0; no_state = 1;
|
||||
total = len; kept = len < V4_POST_OUT ? len : V4_POST_OUT;
|
||||
}
|
||||
v4_dstack_reset(&h->n->ds);
|
||||
|
||||
for (k = 0; came_back && k < c->line_count; k++) {
|
||||
@@ -58,6 +61,7 @@ int v4_post_run(const v4_post_host *h, const v4_post_case *cases, unsigned count
|
||||
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; lost = 1; break; }
|
||||
if (how == V4_TEXT_ERROR) errored = 1;
|
||||
if (how == V4_TEXT_QUIT) quit = 1; /* it went back to the terminal: it did not complete */
|
||||
total += len;
|
||||
kept = total < V4_POST_OUT ? total : V4_POST_OUT;
|
||||
}
|
||||
@@ -70,7 +74,7 @@ int v4_post_run(const v4_post_host *h, const v4_post_case *cases, unsigned count
|
||||
}
|
||||
v4_dstack_reset(&h->n->ds);
|
||||
|
||||
if (!came_back) {
|
||||
if (!came_back || quit) {
|
||||
ok = 0;
|
||||
} else if (c->expect == V4_POST_ERROR) {
|
||||
ok = errored;
|
||||
@@ -92,6 +96,8 @@ int v4_post_run(const v4_post_host *h, const v4_post_case *cases, unsigned count
|
||||
if (ok) { tally->pass++; continue; }
|
||||
tally->fail++;
|
||||
say(h, "POST FAIL: "); say(h, c->name);
|
||||
if (no_state) say(h, " could not be put in its starting state:");
|
||||
if (quit) say(h, " ended with QUIT:");
|
||||
say(h, " out<"); h->say(h->self, out, kept < SHOWN_OUT ? kept : SHOWN_OUT);
|
||||
say(h, "> stack<");
|
||||
for (k = depth < SHOWN_STACK ? depth : SHOWN_STACK; k-- > 0; ) { say_number(h, (long long)left[k]); say(h, " "); }
|
||||
|
||||
@@ -52,6 +52,25 @@ static v4_cell tell(v4_cell request)
|
||||
static int in_window(v4_cell a) { return a >= WINDOW && a < WINDOW + (v4_cell)(V4_BLOCK_SLOTS * V4_BLOCK_CELLS) && (a - WINDOW) % (v4_cell)V4_BLOCK_CELLS == 0; }
|
||||
static unsigned char *chain_block(unsigned num) { return num < 2048u ? ram + ((size_t)num + BLK_FORTH_SYS_RESERVED) * 1024u : dev + (size_t)(num - 2048u) * 1024u; }
|
||||
|
||||
/* A device whose writes can be made to fail: 2048 blocks of RAM behind v3's
|
||||
* device interface (v3/include/blkio.h). */
|
||||
#define FAILING_BLOCKS 2048u
|
||||
static unsigned char failing_bytes[FAILING_BLOCKS * 1024u];
|
||||
static int failing;
|
||||
static int f_open(struct blkio_dev *d, const blkio_params_t *p) { (void)d; (void)p; return BLKIO_OK; }
|
||||
static int f_close(struct blkio_dev *d) { (void)d; return BLKIO_OK; }
|
||||
static int f_read(struct blkio_dev *d, uint32_t b, void *dst) { (void)d; memcpy(dst, failing_bytes + (size_t)b * 1024u, 1024); return BLKIO_OK; }
|
||||
static int f_write(struct blkio_dev *d, uint32_t b, const void *src)
|
||||
{
|
||||
(void)d;
|
||||
if (failing) return BLKIO_EIO;
|
||||
memcpy(failing_bytes + (size_t)b * 1024u, src, 1024);
|
||||
return BLKIO_OK;
|
||||
}
|
||||
static int f_flush(struct blkio_dev *d) { (void)d; return failing ? BLKIO_EIO : BLKIO_OK; }
|
||||
static int f_info(struct blkio_dev *d, blkio_info_t *out) { (void)d; memset(out, 0, sizeof *out); return BLKIO_OK; }
|
||||
static const blkio_vtable_t failing_vt = { f_open, f_close, f_read, f_write, f_flush, f_info };
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned i;
|
||||
@@ -165,6 +184,30 @@ int main(void)
|
||||
CHECK(ask(V4_REQ_BLOCK, 2070) == V4_BLOCK_OK && (n.mem[got_addr] & 0xFF) == 'N', "and the block is read again");
|
||||
}
|
||||
|
||||
/* ---- a write that fails on the device leaves the block as it was ---- */
|
||||
{
|
||||
static blkio_dev_t fdev;
|
||||
blkio_params_t params;
|
||||
uint32_t first = 0, n_blocks = 0;
|
||||
params.forth_block_size = 0; params.total_blocks = FAILING_BLOCKS; params.opaque = 0;
|
||||
CHECK(blkio_open(&fdev, &failing_vt, ¶ms) == BLKIO_OK && blk_subsys_attach_device(&fdev) == BLK_OK
|
||||
&& blk_get_device_range(&fdev, &first, &n_blocks) == BLK_OK && n_blocks > 8 && blk_subsys_confirm_format(first) == BLK_OK,
|
||||
"a disk joins the chain and is formatted: %u blocks from %u", n_blocks, first);
|
||||
CHECK(ask(V4_REQ_BLOCK, (v4_cell)first + 3) == V4_BLOCK_OK, "one of its blocks is asked for");
|
||||
for (i = 0; i < V4_BLOCK_CELLS; i++) n.mem[got_addr + (v4_cell)i] = (v4_cell)0x4F4F4F4F;
|
||||
CHECK(tell(V4_REQ_UPDATE) == V4_BLOCK_OK && tell(V4_REQ_SAVE_BUFFERS) == V4_BLOCK_OK, "and written: all O");
|
||||
CHECK(ask(V4_REQ_BLOCK, (v4_cell)first + 3) == V4_BLOCK_OK, "it is asked for again");
|
||||
for (i = 0; i < V4_BLOCK_CELLS; i++) n.mem[got_addr + (v4_cell)i] = (v4_cell)0x4E4E4E4E;
|
||||
failing = 1;
|
||||
CHECK(tell(V4_REQ_UPDATE) == V4_BLOCK_OK && tell(V4_REQ_SAVE_BUFFERS) == V4_BLOCK_REFUSED, "with the device failing, a write of all N is refused");
|
||||
failing = 0;
|
||||
(void)tell(V4_REQ_EMPTY_BUFFERS);
|
||||
CHECK(ask(V4_REQ_BLOCK, (v4_cell)first + 3) == V4_BLOCK_OK && n.mem[got_addr] == (v4_cell)0x4F4F4F4F && n.mem[got_addr + 255] == (v4_cell)0x4F4F4F4F,
|
||||
"and the block is what it was before: the kernel does not keep what the device refused: %lx", (unsigned long)n.mem[got_addr]);
|
||||
CHECK(blk_flush(0) == BLK_OK && ask(V4_REQ_BLOCK, (v4_cell)first + 3) == V4_BLOCK_OK && n.mem[got_addr] == (v4_cell)0x4F4F4F4F,
|
||||
"nor does it write it later, when the device works again");
|
||||
}
|
||||
|
||||
/* ---- what is not a block request ---- */
|
||||
v4_dstack_reset(&n.ds);
|
||||
v4_dstack_push(&n.ds, 11); v4_dstack_push(&n.ds, 22);
|
||||
|
||||
@@ -1250,9 +1250,17 @@ int main(void)
|
||||
CHECK(is(say("1 2 3 HEX\n"), " ok\nok> "), "the node is left in HEX with three values on its stack");
|
||||
CHECK(post_one("state", "10 .", 0, V4_POST_STACK, 0, 0, "10 ") == 1, "a case still starts in decimal with nothing on the stack");
|
||||
post_state_fails = 1;
|
||||
CHECK(post_one("state.bad", "1 2 +", 0, V4_POST_STACK, three, 1, "") == 0 && strstr(post_said, "POST FAIL: state.bad ") != NULL, "if the state cannot be set the case fails, by name");
|
||||
CHECK(post_one("state.bad", "1 2 +", 0, V4_POST_STACK, three, 1, "") == 0 && strstr(post_said, "POST FAIL: state.bad ") != NULL
|
||||
&& strstr(post_said, "could not be put in its starting state") != NULL && strstr(post_said, "NOSUCHWORD-FOR-STATE") != NULL,
|
||||
"if the state cannot be set the case fails, by name, and says that and what the node said: \"%s\"", post_said);
|
||||
post_state_fails = 0;
|
||||
|
||||
/* a case that ends with QUIT is not a case that completed */
|
||||
CHECK(post_one("quit.plain", "QUIT", 0, V4_POST_STACK, 0, 0, "\n") == 0 && strstr(post_said, "POST FAIL: quit.plain ") != NULL,
|
||||
"a case that ends with QUIT fails, though it left and printed what the table has: \"%s\"", post_said);
|
||||
CHECK(post_one("quit.err", "QUIT", 0, V4_POST_ERROR, 0, 0, "") == 0, "and it has not ended in an error either");
|
||||
CHECK(post_one("after.quit", "1 2 +", 0, V4_POST_STACK, three, 1, "") == 1, "the case after it is judged as usual");
|
||||
|
||||
/* a case that prints more than is kept */
|
||||
CHECK(is(say(": MANY 2000 0 DO 65 EMIT LOOP ;\n"), " ok\nok> "), "a word that prints 2,000 characters");
|
||||
memset(big, 'A', 2000); big[2000] = 0;
|
||||
|
||||
Reference in New Issue
Block a user