code wiki / _hdl_build / nx_amd_pm4_gate.nx
nx_amd_pm4_gate.nx source
↩ module page · 46 lines · 3337 B
1// nx_amd_pm4_gate.nx -- gate for the sovereign AMD PM4 command-submission encoder (nx_pm4_asm) = the AMD R1
2// rung. Verifies the PM4 Type-3 packet headers our encoder produces against the documented AMD format for the
3// real IT opcodes tinygrad's AM driver submits (DISPATCH/SET_SH_REG/ACQUIRE_MEM/RELEASE_MEM/WAIT_REG_MEM).
4// HONEST SCOPE: spec-faithful (documented PM4 Type-3 + tinygrad-cross-referenced), NOT yet toolchain-bit-exact
5// (needs llvm-mc -triple=amdgcn / ROCm). No hw writes (Rule 26). expect_exit: 0 license_tier: ORIGINAL
6import "nx_syscalls.nx"
7import "nx_pm4_asm.nx"
8import "nx_gate_verdict.nx"
9
10func bp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11func bx(v: i64) -> i64 { bp("0x" as *u8); let bb:*u8=sys_mmap(20); var k:i64=0; var m:i64=v; if m==0{bb[0]=48 as u8;k=1} while m>0{ let d:i64=m&15; if d<10{bb[k]=(48+d) as u8}else{bb[k]=(87+d) as u8}; m=(m>>4); k=k+1 } var i:i64=0; let o:*u8=sys_mmap(20); while i<k{o[i]=bb[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
12func bd(v: i64) -> i64 { let p: *u8=sys_mmap(1); p[0]=(48+v) as u8; sys_write(1,p,1); return 0 }
13
14func chk(name: *u8, got: i64, ref: i64, st: *i64) -> i64 {
15 bp(" PACKET3 " as *u8); bp(name); bp(" -> " as *u8); bx(got)
16 if got==ref { bp(" == AMD-spec ref PASS\n" as *u8); st[0]=st[0]+1; return 0 }
17 bp(" != ref " as *u8); bx(ref); bp(" FAIL\n" as *u8); return 0
18}
19
20func main() -> i64 {
21 bp("=== SOVEREIGN AMD PM4 command-submission encoder (nx_pm4_asm) -- AMD R1, spec-faithful + tinygrad-cross-ref ===\n" as *u8)
22 let st: *i64 = sys_mmap(8); st[0]=0
23 chk("SET_SH_REG count=3 " as *u8, pm4_packet3(PM4_IT_SET_SH_REG, 3), 0xc0037600, st)
24 chk("DISPATCH_DIRECT cnt=3 " as *u8, pm4_packet3(PM4_IT_DISPATCH_DIRECT, 3), 0xc0031500, st)
25 chk("ACQUIRE_MEM count=6 " as *u8, pm4_packet3(PM4_IT_ACQUIRE_MEM, 6), 0xc0065800, st)
26 chk("RELEASE_MEM count=6 " as *u8, pm4_packet3(PM4_IT_RELEASE_MEM, 6), 0xc0064900, st)
27 chk("WAIT_REG_MEM count=5 " as *u8, pm4_packet3(PM4_IT_WAIT_REG_MEM, 5), 0xc0053c00, st)
28 chk("SET_UCONFIG_REG cnt=1 " as *u8, pm4_packet3(PM4_IT_SET_UCONFIG_REG, 1), 0xc0017900, st)
29
30 // negative control: distinct opcodes MUST yield distinct headers (proves the encoder reads the opcode)
31 var neg_ok: i64 = 0
32 if pm4_packet3(PM4_IT_SET_SH_REG, 3) != pm4_packet3(PM4_IT_DISPATCH_DIRECT, 3) { neg_ok = 1 }
33 bp(" NEG SET_SH_REG != DISPATCH header: " as *u8); if neg_ok==1 { bp("PASS(differs)\n" as *u8) } else { bp("FAIL\n" as *u8) }
34
35 let pass: i64 = st[0]
36 bp("AMD-PM4-GATE passed " as *u8); bd(pass); bp("/6 neg=" as *u8); bd(neg_ok); bp("\n" as *u8)
37 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
38 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
39 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
40 let ctr__dry: *i64 = gv_ctr()
41 ctr__dry[0] = pass
42 ctr__dry[1] = 6
43 let rc__dry: i64 = gv_verdict("AMD-PM4-GATE" as *u8, ctr__dry, "sovereign AMD PM4 PACKET3 encoder = AMD R1 command-submit, spec-faithful + tinygrad-cross-ref; the 2nd-vendor backend on the universal ladder. Upgrade to bit-exact = llvm-mc/ROCm)" as *u8)
44 sys_exit(rc__dry)
45 return rc__dry
46}