code wiki / _hdl_build / _gpu_oplist_gate.nx
_gpu_oplist_gate.nx source
↩ module page · 168 lines · 9315 B
1// _gpu_oplist_gate.nx -- GPU-class driver-from-spec gate (X-DRV-W1 -> X-DRV-003 / GPU trajectory):
2// the 4th device class as a GENERIC op-list on the CANONICAL emitter nx_drv_proto_emit, composing
3// with the sovereign SPIR-V lane. Proves:
4// (1) GPU -- the GENERIC nx_drv_proto_emit, driven by knowledge/specs/gpu_dispatch_virt.spec alone
5// (zero emitter change), authors a GPU-class command-submission driver; the SOVEREIGN rv64 emu
6// (+ the rv64im_min_gpu device model, via the dedicated _gpu_run runner) runs it: CTRL.EN ->
7// confirm STATUS.READY -> bind the command ring -> lay a command packet carrying the SPIR-V
8// magic 0x07230203 -> ring the DOORBELL -> device validates the SPIR-V magic, signals the
9// FENCE + latches RESULTPEEK -> driver verifies FENCE==seqno and RESULTPEEK==(operand<<16)|seqno.
10// Serial CONTAINS golden "GPUENRINGCMDFENCE" + a clean halt (BOOTSOV verdict=GREEN).
11// (2) DISTINCT -- the SAME emitter binary, driven by the NVMe op-list, yields a DIFFERENT golden;
12// the GPU class is just-a-spec, not NVMe/virtio in disguise.
13// (3) TAMPER x2 on the GPU image: bump the device-base lui imm (byte 7) -> all MMIO targets a non-
14// device address -> the ID identity verify fails -> transcript collapses; bump the ID-expected
15// li high byte (byte 15) -> identity mismatch -> collapses. Each must drop the golden.
16//
17// Every verdict is a PRINTED marker off a REAL sovereign run; raw bytes read SOVEREIGNLY (sys_read).
18// NO qemu/gcc/openssl/python. Marker -> knowledge/status/driver_spec.log (GPUOPGATE row). Sovereign
19// orchestration (fork/dup3/execve/wait4). license_tier: ORIGINAL
20import "nx_syscalls.nx"
21
22const EMIT_ELF: *u8 = "_offc/nx_drv_proto_emit.elf"
23const SOV_ELF: *u8 = "_offc/_gpu_run.elf"
24
25func 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 }
26func 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 }
27func 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 }
28
29func q_run1(prog: *u8, a1: *u8, outpath: *u8) -> i64 {
30 let pid: i64 = sys_fork()
31 if pid == 0 {
32 let ofd: i64 = sys_openat_wr(outpath, 0x1a4)
33 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) }
34 let argv: *i64 = sys_mmap(32) as *i64
35 argv[0] = prog as i64
36 argv[1] = a1 as i64
37 argv[2] = 0
38 let envp: *i64 = sys_mmap(16) as *i64
39 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0
40 sys_execve(prog, argv, envp)
41 sys_exit(127)
42 }
43 let st: *i64 = sys_mmap(16) as *i64
44 sys_wait4(pid, st, 0)
45 let sig: i64 = st[0] & 0x7f
46 if sig != 0 { return 128 + sig }
47 return (st[0] >> 8) & 0xff
48}
49
50func q_read(path: *u8, buf: *u8, cap: i64) -> i64 {
51 let fd: i64 = sys_openat_rd(path)
52 if fd < 0 { return 0 }
53 var n: i64 = 0
54 var go: i64 = 1
55 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 } }
56 sys_close(fd)
57 return n
58}
59
60func q_buf_has(buf: *u8, n: i64, pat: *u8, pl: i64) -> i64 {
61 if pl <= 0 { return 0 }
62 var i: i64 = 0
63 while i + pl <= n {
64 var k: i64 = 0; var hit: i64 = 1
65 while k < pl { if buf[i+k] != pat[k] { hit = 0; k = pl } else { k = k + 1 } }
66 if hit == 1 { return 1 }
67 i = i + 1
68 }
69 return 0
70}
71
72func q_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
73
74func q_streq(a: *u8, b: *u8) -> i64 {
75 var i: i64 = 0
76 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
77 if b[i] != (0 as u8) { return 0 }
78 return 1
79}
80
81func q_emit_run(spec: *u8, out: *u8, goldout: *u8, gbuf: *u8, gcap: i64, serialpath: *u8) -> i64 {
82 let est: i64 = q_run1(EMIT_ELF, spec, "/tmp/_gpuopl_emit.out" as *u8)
83 if est != 0 { return 0 }
84 let gn: i64 = q_read(goldout, gbuf, gcap)
85 if gn <= 0 { return 0 }
86 gbuf[gn] = 0 as u8
87 let rst: i64 = q_run1(SOV_ELF, out, serialpath)
88 let sbuf: *u8 = sys_mmap(65536)
89 let sbn: i64 = q_read(serialpath, sbuf, 65536)
90 let has: i64 = q_buf_has(sbuf, sbn, gbuf, gn)
91 let halt: i64 = q_buf_has(sbuf, sbn, "BOOTSOV verdict=GREEN" as *u8, 21)
92 if rst == 0 { if has == 1 { if halt == 1 { return 1 } } }
93 return 0
94}
95
96func q_tamper(srcbin: *u8, pos: i64, golden: *u8, gn: i64, tampbin: *u8, serialpath: *u8) -> i64 {
97 let ibuf: *u8 = sys_mmap(16384)
98 let ibn: i64 = q_read(srcbin, ibuf, 16384)
99 if ibn <= pos { return 0 }
100 ibuf[pos] = (ibuf[pos] + 1) as u8
101 let tfd: i64 = sys_openat_wr(tampbin, 0x1a4)
102 if tfd < 0 { return 0 }
103 sys_write(tfd, ibuf, ibn); sys_close(tfd)
104 let rst: i64 = q_run1(SOV_ELF, tampbin, serialpath)
105 let sbuf: *u8 = sys_mmap(65536)
106 let sbn: i64 = q_read(serialpath, sbuf, 65536)
107 let has: i64 = q_buf_has(sbuf, sbn, golden, gn)
108 if has == 0 { return 1 }
109 return 0
110}
111
112func main() -> i64 {
113 q_p("=== GPU-op-list driver gate (X-DRV-W1->GPU: GPU-class driver = a SPEC on the canonical nx_drv_proto_emit, SPIR-V-magic-gated, sovereign emu, no qemu) ===\n" as *u8)
114 let lfd: i64 = sys_openat_append("knowledge/status/driver_spec.log" as *u8, 0x1a4)
115
116 let gpu_out: *u8 = "runtime/_hdl_build/_gpu_dispatch.bin" as *u8
117 let gpu_gold: *u8 = "runtime/_hdl_build/_gpu_dispatch.bin.gold" as *u8
118 let nvme_out: *u8 = "runtime/_hdl_build/_nvme_oplist.bin" as *u8
119 let nvme_gold: *u8 = "runtime/_hdl_build/_nvme_oplist.bin.gold" as *u8
120
121 let gG: *u8 = sys_mmap(2048)
122 let gN: *u8 = sys_mmap(2048)
123
124 // (1) GPU round-trip on the sovereign emu, authored by the GENERIC op-list emitter.
125 let gpu_ok: i64 = q_emit_run("knowledge/specs/gpu_dispatch_virt.spec" as *u8, gpu_out, gpu_gold, gG, 2048, "/tmp/_gpuopl_serial.txt" as *u8)
126 // (2) NVMe op-list on the SAME emitter binary, for the distinctness comparison (golden only).
127 let nest: i64 = q_run1(EMIT_ELF, "knowledge/specs/nvme_oplist_virt.spec" as *u8, "/tmp/_gpuopl_nvme_emit.out" as *u8)
128 let ngn: i64 = q_read(nvme_gold, gN, 2048)
129 if ngn > 0 { gN[ngn] = 0 as u8 }
130 var distinct: i64 = 0
131 if q_strlen(gG) > 0 { if q_strlen(gN) > 0 { if q_streq(gG, gN) == 0 { distinct = 1 } } }
132
133 // (3) TAMPER x2 on the GPU image (device-base lui imm byte 7, ID-expected li high byte 15).
134 let gGn: i64 = q_strlen(gG)
135 let t1: i64 = q_tamper(gpu_out, 7, gG, gGn, "/tmp/_gpuopl_t1.bin" as *u8, "/tmp/_gpuopl_t1.txt" as *u8)
136 let t2: i64 = q_tamper(gpu_out, 15, gG, gGn, "/tmp/_gpuopl_t2.bin" as *u8, "/tmp/_gpuopl_t2.txt" as *u8)
137 var tamper_bites: i64 = 0
138 if t1 == 1 { if t2 == 1 { tamper_bites = 1 } }
139 // restore the clean GPU image (re-emit; additive).
140 q_run1(EMIT_ELF, "knowledge/specs/gpu_dispatch_virt.spec" as *u8, "/tmp/_gpuopl_emit.out" as *u8)
141
142 q_p(" gpu_dispatch=" as *u8)
143 if gpu_ok == 1 { q_p("GREEN(GPU..FENCE: CTRL.EN->STATUS.READY + ring bind + SPIR-V-magic command packet + DOORBELL + fence-signal + RESULTPEEK readback, clean halt)" as *u8) } else { q_p("RED" as *u8) }
144 q_p(" distinct_vs_nvme=" as *u8)
145 if distinct == 1 { q_p("yes(goldenGPU!=goldenNVMe, same emitter binary)" as *u8) } else { q_p("no" as *u8) }
146 q_p(" tamper_bites=" as *u8)
147 if tamper_bites == 1 { q_p("yes(base-imm + ID-const corrupt -> golden drops)\n" as *u8) } else { q_p("no\n" as *u8) }
148
149 var pass: i64 = 0
150 if gpu_ok == 1 { if distinct == 1 { if tamper_bites == 1 { pass = 1 } } }
151
152 if pass == 1 {
153 q_p("GPUOPGATE verdict=GREEN (the CANONICAL op-list emitter nx_drv_proto_emit authored a GPU-class command-submission driver from gpu_dispatch_virt.spec ALONE -- a 4th device class as just-a-spec, zero emitter change -- which round-tripped on the sovereign rv64 emu against rv64im_min_gpu; the command packet carried the SPIR-V magic 0x07230203 the device VALIDATED before signalling the fence; golden distinct from NVMe; two image tampers REJECTED. The driver-from-spec arc now reaches the GPU/CUDA/DirectX trajectory -- composing with the sovereign SPIR-V lane)\n" as *u8)
154 if lfd >= 0 {
155 q_fp(lfd, "GPUOPGATE verdict=GREEN keystone=gpu-class-driver-from-op-list-spec runtime=sovereign-emu device=gpu-class enable=CTRL.EN->STATUS.READY queue=ring-base+doorbell dispatch=spirv-magic-gated(0x07230203) fence+resultpeek-readback=verified emitter=nx_drv_proto_emit(zero-change) goldenGPU=" as *u8)
156 q_fp(lfd, gG); q_fp(lfd, " distinct_vs_nvme=yes tamper=rejected(base-imm+ID-const) composes=spirv-lane epoch=" as *u8); q_fn(lfd, sys_now_realtime_sec()); q_fp(lfd, "\n" as *u8); sys_close(lfd)
157 }
158 sys_exit(0); return 0
159 }
160 q_p("GPUOPGATE verdict=RED (gpu_ok/distinct/tamper not all green)\n" as *u8)
161 if lfd >= 0 {
162 q_fp(lfd, "GPUOPGATE verdict=RED gpu_ok=" as *u8); q_fn(lfd, gpu_ok)
163 q_fp(lfd, " distinct=" as *u8); q_fn(lfd, distinct)
164 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)
165 }
166 sys_exit(1)
167 return 1
168}