code wiki / _hdl_build / nx_virtio_hs_emit.nx

nx_virtio_hs_emit.nx

buildroot/runtime/_hdl_build/nx_virtio_hs_emit.nx

39031 B589 linesdepth 3pulls 3 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_virtio_hs_emit.nx -- the virtio-MMIO HANDSHAKE emitter (K-R2-001a of the kernel-up ladder). A NEW transport bring-up IS A SPEC FILE: reads the legacy virtio-MMIO register block (base + offsets), the device identity (magic/version/device-id), the status-progression bits, and the banner from knowledge/specs/virtio_blk_handshake_virt .spec and AUTHORS a bare-metal rv64 flat image whose driver performs the REAL device- initialization handshake (virtio v1.2 sec 3.1): verify MagicValue == "virt", Version, DeviceID == 2 (block) -> emit "VIO " Status |= ACKNOWLEDGE | DRIVER -> emit "ACK " read HostFeatures, write GuestFeatures, Status |= FEATURES_OK -> emit "DRV " re-read Status, confirm FEATURES_OK stuck -> emit "FEAT " Status |= DRIVER_OK -> emit "OK\n" write the SiFive finisher -> clean halt. Any verify that fails BRANCHES PAST the rest of the handshake straight to the finisher, so the transcript loses its tail (the DRIVER_OK "OK\n" canary, and the segments before it) -- that is what the gate's tamper test exploits. Zero hand-written machine code: the emitter is a tiny rv64 encoder (lui/addi/lw/sw/sb + B-type bne/beq + R-type and + jal) and the IMAGE + the GOLDEN transcript are TABLE-COMPUTED from the spec. The image is authored in TWO passes (a measure pass that fixes the finisher byte-offset, then the real pass that backfills the fail-branch targets) so every forward branch is structurally derived, never typed -- byte-reproducibly. nx_virtio_hs_emit <specpath> -> writes the flat image to the spec's `out` and the table-computed golden transcript to <out>.gold VERDICT log -> knowledge/status/virtio_blk.log (VIRTEMIT rows, the gate's evidence). Sovereign: syscalls only, no gcc/.sh. license_tier: ORIGINAL X-DRV-W1 stage A refactor: the rv64 mini-encoder + the four shape-op families (WIRE_TLV / COMMAND_QUEUE / STATE_MACHINE / STRUCT_WALK) now live in the DEVICE-AGNOSTIC nx_driver_shapes library, and every vh_* encoder/emit function below DELEGATES to its ds_* twin. The virtio identity lives ONLY in the spec-derived cfg[] table threaded into vh_emit_image -- the shape library contains zero virtio knowledge. The op bodies are byte-for-byte the same code path as before (a thin pass-through), so this emitter re-emits its image BYTE-IDENTICALLY (the stage-A regression guard the gate proves).

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_driver_shapes.nx nx_virtio_hs_emit.nx

imports: nx_syscalls.nxnx_driver_shapes.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main vh_p sys_write sys_exit sys_mmap sys_read_file sys_openat_rd sys_lseek sys_mmap ↻ sys_read sys_close vh_log sys_openat_append vh_fp sys_write ↻ vh_fn sys_mmap ↻ sys_write ↻ sys_close ↻ vh_num_field sys_mmap ↻ vh_parse_num vh_str_field vh_fn ↻ vh_emit_image vh_w32 ds_w32 ds_lui vh_emit_verify ds_emit_verify ds_w32 ↻ ds_load ds_li32 ds_w32 ↻ ds_lui ↻ ds_addi ds_branch vh_emit_str ds_emit_str ds_w32 ↻

structs

none

consts

35const VH_MAGIC_8192: i64 = 8192
38const VH_UART: i64 = 0x10000000 // NS16550A THR (write a byte = transmit)
39const VH_FIN: i64 = 0x100000 // SiFive test finisher (write to exit)
40const VH_PASS: i64 = 0x5555 // FINISHER_PASS low half -> clean halt
42const RV_X0: i64 = 0
43const RV_T0: i64 = 5 // UART base
44const RV_T1: i64 = 6 // scratch / transcript byte
45const RV_T2: i64 = 7 // device base
46const RV_T3: i64 = 28 // loaded register value (actual)
47const RV_T4: i64 = 29 // expected constant
48const RV_T5: i64 = 30 // finisher base / feature scratch
51const VC_OFF_MAGIC: i64 = 0
52const VC_OFF_VERSION: i64 = 1
53const VC_OFF_DEVICEID: i64 = 2
54const VC_OFF_VENDORID: i64 = 3
55const VC_OFF_HOSTFEAT: i64 = 4
56const VC_OFF_GUESTFEAT: i64 = 5
57const VC_OFF_STATUS: i64 = 6
58const VC_MAGIC: i64 = 7
59const VC_VERSION: i64 = 8
60const VC_DEVICEID: i64 = 9
61const VC_HOSTFEAT: i64 = 10
62const VC_ACK: i64 = 11
63const VC_DRIVER: i64 = 12
64const VC_FEATOK: i64 = 13
65const VC_DRIVEROK: i64 = 14
66const VC_BASE: i64 = 15
68const VC_OFF_QSEL: i64 = 16
69const VC_OFF_QNUMMAX: i64 = 17
70const VC_OFF_QNUM: i64 = 18
71const VC_OFF_QALIGN: i64 = 19
72const VC_OFF_QPFN: i64 = 20
73const VC_OFF_QNOTIFY: i64 = 21
74const VC_QSEL: i64 = 22
75const VC_QALIGN: i64 = 23
76const VC_QNUM: i64 = 24
77const VC_QPFN: i64 = 25
78const VC_QNOTIFY: i64 = 26
82const VC_QEND: i64 = 27
84const VC_OFF_QDESCPEEK: i64 = 27
85const VC_OFF_DESC_ADDR: i64 = 28
86const VC_OFF_DESC_LEN: i64 = 29
87const VC_OFF_DESC_FLAGS:i64 = 30
88const VC_OFF_DESC_NEXT: i64 = 31
89const VC_RING_ADDR: i64 = 32
90const VC_DESC_ADDR_LO: i64 = 33
91const VC_DESC_LEN: i64 = 34
92const VC_DESC_FLAGS: i64 = 35
93const VC_DESC_NEXT: i64 = 36
97const VC_DEND: i64 = 37
99const VC_OFF_QUSEDIDXPEEK: i64 = 37
100const VC_AVAIL_RING_OFF: i64 = 38
101const VC_AVAIL_IDX_OFF: i64 = 39
102const VC_USED_RING_OFF: i64 = 40
103const VC_USED_IDX_OFF: i64 = 41
104const VC_AVAIL_HEAD: i64 = 42
105const VC_AVAIL_IDX_VAL: i64 = 43
106const VC_USED_IDX_EXP: i64 = 44
111const VC_DEND2: i64 = 45
113const VC_OFF_QSTATPEEK: i64 = 45
114const VC_STAT_BUF_ADDR: i64 = 46
115const VC_STAT_BUF_LO: i64 = 47
116const VC_BLK_S_OK: i64 = 48
117const VC_STAT_EXPECTED: i64 = 49
122const VC_DEND3: i64 = 50
124const VC_OFF_QSECTPEEK: i64 = 50
125const VC_OFF_DATA_SECTOR: i64 = 51
126const VC_SECT_PATTERN: i64 = 52
127const VC_SECT_DATA_EXP: i64 = 53
128const VC_N: i64 = 54

functions

130func vh_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
called by 1: main calls 1: sys_write
131func vh_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 }
called by 1: vh_log calls 1: sys_write
132func vh_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 }
called by 2: vh_logmain calls 2: sys_mmapsys_write
133func vh_hex(fd: i64, v: i64) -> i64 { let d: *u8=sys_mmap(16); var i: i64=0; while i<8{let nib: i64=(v >> ((7-i)*4)) & 0xf; if nib<10{d[i]=(48+nib) as u8} else {d[i]=(87+nib) as u8} i=i+1}; sys_write(fd,d,8); return 0 }
called by 1: main calls 2: sys_mmapsys_write
139func vh_w32(buf: *u8, off: i64, w: i64) -> i64 { return ds_w32(buf, off, w) }
called by 1: vh_emit_image calls 1: ds_w32
140func vh_li32(buf: *u8, off: i64, rd: i64, val: i64) -> i64 { return ds_li32(buf, off, rd, val) }
calls 1: ds_li32
141func vh_li32u(buf: *u8, off: i64, rd: i64, val: i64) -> i64 { return ds_li32u(buf, off, rd, val) }
called by 1: vh_emit_image calls 1: ds_li32u
142func vh_load(rd: i64, rs1: i64, f3: i64, imm: i64) -> i64 { return ds_load(rd, rs1, f3, imm) }
called by 1: vh_emit_image calls 1: ds_load
143func vh_emit_str(buf: *u8, off: i64, s: *u8, n: i64) -> i64 { return ds_emit_str(buf, off, s, n) }
called by 1: vh_emit_image calls 1: ds_emit_str
145func vh_emit_verify(buf: *u8, off: i64, regoff: i64, expected: i64, fail_off: i64) -> i64 { return ds_emit_verify(buf, off, regoff, expected, fail_off) }
called by 1: vh_emit_image calls 1: ds_emit_verify
146func vh_emit_verify_u(buf: *u8, off: i64, regoff: i64, expected: i64, fail_off: i64) -> i64 { return ds_emit_verify_u(buf, off, regoff, expected, fail_off) }
called by 1: vh_emit_image calls 1: ds_emit_verify_u
147func vh_emit_regwrite(buf: *u8, off: i64, regoff: i64, val: i64) -> i64 { return ds_emit_regwrite(buf, off, regoff, val) }
called by 1: vh_emit_image calls 1: ds_emit_regwrite
148func vh_emit_checkbit(buf: *u8, off: i64, regoff: i64, mask: i64, fail_off: i64) -> i64 { return ds_emit_checkbit(buf, off, regoff, mask, fail_off) }
called by 1: vh_emit_image calls 1: ds_emit_checkbit
150func vh_emit_memstore(buf: *u8, off: i64, base_reg: i64, memoff: i64, f3: i64, val: i64) -> i64 { return ds_emit_memstore(buf, off, base_reg, memoff, f3, val) }
called by 1: vh_emit_image calls 1: ds_emit_memstore
152func vh_emit_finisher(buf: *u8, off: i64) -> i64 { return ds_emit_finisher(buf, off) }
called by 1: vh_emit_image calls 1: ds_emit_finisher
160func vh_emit_image(buf: *u8, cfg: *i64, tail: *u8, segs: *i64, fail_off: i64, stage_mode: i64) -> i64
281func vh_parse_num(buf: *u8, p: i64, le: i64, endp: *i64) -> i64
called by 1: vh_num_field
315func vh_num_field(buf: *u8, ls: i64, le: i64, key: *u8, out: *i64) -> i64
called by 1: main calls 2: sys_mmapvh_parse_num
328func vh_str_field(buf: *u8, ls: i64, le: i64, key: *u8, out: *u8) -> i64
called by 1: main
342func vh_log(name: *u8, bytes: i64, golden: *u8, verdict: *u8) -> i64
353func main(argc: i64, argv: *i64) -> i64