code wiki / _hdl_build / _nvme_oplist_gate.nx

_nvme_oplist_gate.nx source

↩ module page · 171 lines · 9633 B

1// _nvme_oplist_gate.nx -- CONSOLIDATION gate for X-DRV-W1: NVMe as a GENERIC op-list on the 2// CANONICAL emitter nx_drv_proto_emit (NOT the parallel bespoke nx_drvgen). Proves the no-sprawl 3// consolidation: 4// (1) NVME -- the GENERIC nx_drv_proto_emit, driven by knowledge/specs/nvme_oplist_virt.spec 5// alone (zero emitter change), authors an NVMe-class bring-up driver; the SOVEREIGN rv64 emu 6// (+ the rv64im_min_nvme device model) runs it: CC.EN -> confirm CSTS.RDY -> bind ASQ/ACQ by 7// base-address regs -> lay the 64B SQE -> ring the SQ-Tail doorbell -> device DMAs + posts the 8// phase-tagged CQE -> driver reads NvmeCqPeek back == 0x12340001. Serial CONTAINS the golden 9// "NVMEENASQSQECQ" + a clean SiFive halt (BOOTSOV verdict=GREEN). 10// (2) DISTINCT -- the SAME emitter binary, driven by the virtio-blk op-list, yields a DIFFERENT 11// golden; NVMe is a 3rd device class as just-a-spec, not virtio in disguise. 12// (3) TAMPER x2 on the NVMe image: bump the device-base lui imm (byte 7) -> all MMIO targets a 13// non-device address -> the VS identity verify fails -> the whole transcript collapses; bump 14// the VS-expected li high byte (byte 15) -> the identity verify mismatches -> collapses. Each 15// must drop the golden (the no-false-green handle; a no-op driver would be immune). 16// 17// Every verdict is a PRINTED marker off a REAL sovereign run, never an asserted GREEN; raw bytes are 18// read SOVEREIGNLY (sys_read). NO qemu/gcc/openssl/python -- the sovereign emu IS the runtime; NVMe 19// is a last-mile probe. Marker -> knowledge/status/driver_spec.log (NVMEOPGATE row). Sovereign 20// orchestration (fork/dup3/execve/wait4). license_tier: ORIGINAL 21import "nx_syscalls.nx" 22 23const EMIT_ELF: *u8 = "_offc/nx_drv_proto_emit.elf" 24const SOV_ELF: *u8 = "_offc/nx_boot_run_sov.elf" 25 26func q_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 27func q_fp(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 28func q_fn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 29 30// run prog with one arg; stdout/serial -> outpath; return WEXITSTATUS (or 128+sig). 31func q_run1(prog: *u8, a1: *u8, outpath: *u8) -> i64 { 32 let pid: i64 = sys_fork() 33 if pid == 0 { 34 let ofd: i64 = sys_openat_wr(outpath, 0x1a4) 35 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) } 36 let argv: *i64 = sys_mmap(32) as *i64 37 argv[0] = prog as i64 38 argv[1] = a1 as i64 39 argv[2] = 0 40 let envp: *i64 = sys_mmap(16) as *i64 41 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 42 sys_execve(prog, argv, envp) 43 sys_exit(127) 44 } 45 let st: *i64 = sys_mmap(16) as *i64 46 sys_wait4(pid, st, 0) 47 let sig: i64 = st[0] & 0x7f 48 if sig != 0 { return 128 + sig } 49 return (st[0] >> 8) & 0xff 50} 51 52func q_read(path: *u8, buf: *u8, cap: i64) -> i64 { 53 let fd: i64 = sys_openat_rd(path) 54 if fd < 0 { return 0 } 55 var n: i64 = 0 56 var go: i64 = 1 57 while go == 1 { let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - 1 - n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap - 1 { go = 0 } } 58 sys_close(fd) 59 return n 60} 61 62func q_buf_has(buf: *u8, n: i64, pat: *u8, pl: i64) -> i64 { 63 if pl <= 0 { return 0 } 64 var i: i64 = 0 65 while i + pl <= n { 66 var k: i64 = 0; var hit: i64 = 1 67 while k < pl { if buf[i+k] != pat[k] { hit = 0; k = pl } else { k = k + 1 } } 68 if hit == 1 { return 1 } 69 i = i + 1 70 } 71 return 0 72} 73 74func q_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 75 76func q_streq(a: *u8, b: *u8) -> i64 { 77 var i: i64 = 0 78 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } 79 if b[i] != (0 as u8) { return 0 } 80 return 1 81} 82 83// emit a driver from spec, run it on the sovereign emu; return 1 iff serial CONTAINS golden + clean 84// SiFive halt. golden read from <out>.gold into gbuf (NUL-terminated). 85func q_emit_run(spec: *u8, out: *u8, goldout: *u8, gbuf: *u8, gcap: i64, serialpath: *u8) -> i64 { 86 let est: i64 = q_run1(EMIT_ELF, spec, "/tmp/_nvmeopl_emit.out" as *u8) 87 if est != 0 { return 0 } 88 let gn: i64 = q_read(goldout, gbuf, gcap) 89 if gn <= 0 { return 0 } 90 gbuf[gn] = 0 as u8 91 let rst: i64 = q_run1(SOV_ELF, out, serialpath) 92 let sbuf: *u8 = sys_mmap(65536) 93 let sbn: i64 = q_read(serialpath, sbuf, 65536) 94 let has: i64 = q_buf_has(sbuf, sbn, gbuf, gn) 95 let halt: i64 = q_buf_has(sbuf, sbn, "BOOTSOV verdict=GREEN" as *u8, 21) 96 if rst == 0 { if has == 1 { if halt == 1 { return 1 } } } 97 return 0 98} 99 100// run the NVMe image with byte[pos] bumped by 1; return 1 iff golden is now ABSENT (tamper bites). 101func q_tamper(srcbin: *u8, pos: i64, golden: *u8, gn: i64, tampbin: *u8, serialpath: *u8) -> i64 { 102 let ibuf: *u8 = sys_mmap(16384) 103 let ibn: i64 = q_read(srcbin, ibuf, 16384) 104 if ibn <= pos { return 0 } 105 ibuf[pos] = (ibuf[pos] + 1) as u8 106 let tfd: i64 = sys_openat_wr(tampbin, 0x1a4) 107 if tfd < 0 { return 0 } 108 sys_write(tfd, ibuf, ibn); sys_close(tfd) 109 let rst: i64 = q_run1(SOV_ELF, tampbin, serialpath) 110 let sbuf: *u8 = sys_mmap(65536) 111 let sbn: i64 = q_read(serialpath, sbuf, 65536) 112 let has: i64 = q_buf_has(sbuf, sbn, golden, gn) 113 if has == 0 { return 1 } // golden gone -> tamper bites 114 return 0 115} 116 117func main() -> i64 { 118 q_p("=== NVMe-op-list consolidation gate (X-DRV-W1: NVMe = a SPEC on the canonical nx_drv_proto_emit, sovereign emu, no qemu) ===\n" as *u8) 119 let lfd: i64 = sys_openat_append("knowledge/status/driver_spec.log" as *u8, 0x1a4) 120 121 let nvme_out: *u8 = "runtime/_hdl_build/_nvme_oplist.bin" as *u8 122 let nvme_gold: *u8 = "runtime/_hdl_build/_nvme_oplist.bin.gold" as *u8 123 let blk_out: *u8 = "runtime/_hdl_build/_drv_proto_blk.bin" as *u8 124 let blk_gold: *u8 = "runtime/_hdl_build/_drv_proto_blk.bin.gold" as *u8 125 126 let gN: *u8 = sys_mmap(2048) 127 let gB: *u8 = sys_mmap(2048) 128 129 // (1) NVMe round-trip on the sovereign emu, authored by the GENERIC op-list emitter. 130 let nvme_ok: i64 = q_emit_run("knowledge/specs/nvme_oplist_virt.spec" as *u8, nvme_out, nvme_gold, gN, 2048, "/tmp/_nvmeopl_serial.txt" as *u8) 131 // (2) virtio-blk op-list on the SAME emitter binary, for the distinctness comparison. 132 let blk_ok: i64 = q_emit_run("knowledge/specs/drv_proto_blk_virt.spec" as *u8, blk_out, blk_gold, gB, 2048, "/tmp/_nvmeopl_blk_serial.txt" as *u8) 133 var distinct: i64 = 0 134 if q_strlen(gN) > 0 { if q_strlen(gB) > 0 { if q_streq(gN, gB) == 0 { distinct = 1 } } } 135 136 // (3) TAMPER x2 on the NVMe image (device-base lui imm byte 7, VS-expected li high byte 15). 137 let gNn: i64 = q_strlen(gN) 138 let t1: i64 = q_tamper(nvme_out, 7, gN, gNn, "/tmp/_nvmeopl_t1.bin" as *u8, "/tmp/_nvmeopl_t1.txt" as *u8) 139 let t2: i64 = q_tamper(nvme_out, 15, gN, gNn, "/tmp/_nvmeopl_t2.bin" as *u8, "/tmp/_nvmeopl_t2.txt" as *u8) 140 var tamper_bites: i64 = 0 141 if t1 == 1 { if t2 == 1 { tamper_bites = 1 } } 142 // restore the clean NVMe image (re-emit; additive: leave _nvme_oplist.bin == the GREEN image). 143 q_run1(EMIT_ELF, "knowledge/specs/nvme_oplist_virt.spec" as *u8, "/tmp/_nvmeopl_emit.out" as *u8) 144 145 q_p(" nvme_oplist=" as *u8) 146 if nvme_ok == 1 { q_p("GREEN(NVME..CQ: CC.EN->CSTS.RDY enable + ASQ/ACQ base-addr bind + 64B SQE + SQ-Tail doorbell + phase-CQE + NvmeCqPeek readback, clean halt)" as *u8) } else { q_p("RED" as *u8) } 147 q_p(" distinct_vs_virtio=" as *u8) 148 if distinct == 1 { q_p("yes(goldenNVMe!=goldenBLK, same emitter binary)" as *u8) } else { q_p("no" as *u8) } 149 q_p(" tamper_bites=" as *u8) 150 if tamper_bites == 1 { q_p("yes(base-imm + VS-const corrupt -> golden drops)\n" as *u8) } else { q_p("no\n" as *u8) } 151 152 var pass: i64 = 0 153 if nvme_ok == 1 { if distinct == 1 { if tamper_bites == 1 { pass = 1 } } } 154 155 if pass == 1 { 156 q_p("NVMEOPGATE verdict=GREEN (the CANONICAL op-list emitter nx_drv_proto_emit authored an NVMe-class driver from nvme_oplist_virt.spec ALONE -- a 3rd device class as just-a-spec, zero emitter change -- which round-tripped on the sovereign rv64 emu against rv64im_min_nvme; golden distinct from virtio-blk; two image tampers REJECTED. NVMe is now CONSOLIDATED onto the canonical emitter -- the bespoke nx_drvgen/nx_driver_shapes path is superseded)\n" as *u8) 157 if lfd >= 0 { 158 q_fp(lfd, "NVMEOPGATE verdict=GREEN keystone=nvme-consolidated-onto-canonical-op-list-emitter runtime=sovereign-emu device=nvme-class enable=CC.EN->CSTS.RDY queue=ASQ/ACQ-base-addr+doorbell sqe=64B cqe=phase-tagged cqpeek-readback=verified emitter=nx_drv_proto_emit(zero-change) goldenNVMe=" as *u8) 159 q_fp(lfd, gN); q_fp(lfd, " distinct_vs_virtio=yes tamper=rejected(base-imm+VS-const) supersedes=nx_drvgen+nx_driver_shapes epoch=" as *u8); q_fn(lfd, sys_now_realtime_sec()); q_fp(lfd, "\n" as *u8); sys_close(lfd) 160 } 161 sys_exit(0); return 0 162 } 163 q_p("NVMEOPGATE verdict=RED (nvme_ok/distinct/tamper not all green)\n" as *u8) 164 if lfd >= 0 { 165 q_fp(lfd, "NVMEOPGATE verdict=RED nvme_ok=" as *u8); q_fn(lfd, nvme_ok) 166 q_fp(lfd, " distinct=" as *u8); q_fn(lfd, distinct) 167 q_fp(lfd, " t1=" as *u8); q_fn(lfd, t1); q_fp(lfd, " t2=" as *u8); q_fn(lfd, t2); q_fp(lfd, "\n" as *u8); sys_close(lfd) 168 } 169 sys_exit(1) 170 return 1 171}