code wiki / _hdl_build / nx_virtio_scan_emit.nx
nx_virtio_scan_emit.nx source
↩ module page · 30 lines · 3183 B
1// nx_virtio_scan_emit.nx -- emit a REAL RV64 guest (via nx_rv64_asm) that scans the 8 virtio-mmio slots on QEMU's
2// virt machine, reads each slot's MagicValue + DeviceID from live MMIO, and prints "<slot>:<deviceid>" over the
3// NS16550 UART, then halts via the SiFive finisher. Booted in qemu-system-riscv64 with real virtio devices attached,
4// this proves LIVE hardware discovery (device IDs read from actual QEMU virtio hardware) + validates the assembler.
5// Writes knowledge/hw/virtio_scan.bin. expect_exit:0 license_tier: ORIGINAL
6import "nx_rv64_asm.nx"
7const K_MAGIC_65536: i64 = 65536
8
9func vs_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
10func vs_pn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var x: i64=v; if x==0{b[0]=48;sys_write(1,b,1);return 0} var d: i64=0; var y: i64=x; while y>0{d=d+1;y=y/10} var i: i64=d-1; y=x; while i>=0{b[i]=(48+(y%10)) as u8;y=y/10;i=i-1} sys_write(1,b,d); return 0 }
11func vs_hx(v: i64) -> i64 { vs_puts("0x" as *u8); let b: *u8=sys_mmap(16); var i: i64=7; var k: i64=0; while i>=0 { let nib: i64=(v>>(i*4))&15; if nib<10 { b[k]=(48+nib) as u8 } else { b[k]=(87+nib) as u8 } k=k+1; i=i-1 } sys_write(1,b,8); return 0 }
12
13func main() -> i64 {
14 vs_puts("nx_virtio_scan_emit assemble a real RV64 virtio-mmio scanner into a QEMU-bootable binary\n" as *u8)
15 let out: *u8 = sys_mmap(K_MAGIC_65536)
16 // the scanner, in RV64 assembly (passed as a literal -- avoids const-ptr indexing). s0=slot0 base, s2=UART, s3=magic, s4=slot.
17 let nb: i64 = rvasm_assemble_str(" lui s0, 0x10001\n li s1, 8\n lui s2, 0x10000\n lui s3, 0x74727\n addi s3, s3, -0x68a\n li s4, 0\nloop:\n slli t0, s4, 12\n add t0, s0, t0\n lw t1, 0(t0)\n bne t1, s3, next\n lw t3, 8(t0)\n addi a0, s4, 48\n sb a0, 0(s2)\n li a0, 58\n sb a0, 0(s2)\n addi a0, t3, 48\n sb a0, 0(s2)\n li a0, 10\n sb a0, 0(s2)\nnext:\n addi s4, s4, 1\n blt s4, s1, loop\n lui a0, 0x100\n lui a1, 0x5\n addi a1, a1, 0x555\n sw a1, 0(a0)\nhalt:\n j halt\n" as *u8, out, K_MAGIC_65536)
18 if nb<0 { vs_puts(" ASSEMBLE FAILED rc="); vs_pn(0-nb); vs_puts("\n" as *u8); sys_exit(1); return 1 }
19 vs_puts(" assembled bytes="); vs_pn(nb); vs_puts(" words:\n" as *u8)
20 var i: i64=0; while i*4<nb { let w: i64=(out[i*4] as i64)|((out[i*4+1] as i64)<<8)|((out[i*4+2] as i64)<<16)|((out[i*4+3] as i64)<<24); vs_puts(" [") ; vs_pn(i); vs_puts("] @"); vs_pn(i*4); vs_puts(" = "); vs_hx(w); vs_puts("\n" as *u8); i=i+1 }
21 let w0: i64=(out[0] as i64)|((out[1] as i64)<<8)|((out[2] as i64)<<16)|((out[3] as i64)<<24)
22 let expect0: i64 = ((0x10001 & 0xFFFFF)<<12)|(8<<7)|0x37
23 if w0!=expect0 { vs_puts(" SANITY FAIL\n" as *u8); sys_exit(1); return 1 }
24 let fd: i64 = sys_openat_wr("knowledge/hw/virtio_scan.bin" as *u8, 420)
25 if fd<0 { vs_puts(" cannot write bin\n" as *u8); sys_exit(1); return 1 }
26 sys_write(fd, out, nb); sys_close(fd)
27 vs_puts(" wrote knowledge/hw/virtio_scan.bin bytes="); vs_pn(nb); vs_puts(" boot it in qemu-system-riscv64 with virtio devices attached\n" as *u8)
28 vs_puts("verdict=GREEN RV64 virtio-mmio scanner assembled and emitted\n" as *u8)
29 sys_exit(0); return 0
30}