code wiki / _hdl_build / nx_driver_shapes.nx

nx_driver_shapes.nx

buildroot/runtime/_hdl_build/nx_driver_shapes.nx

14992 B251 linesdepth 2pulls 2 transitivereach 3 importersview sourcekind librarytopic driver
docsdependenciesstructsconstsfunctions

about

SUPERSEDED 2026-06-13 (no-sprawl consolidation): the CANONICAL driver-from-spec path is the op-list-driven nx_drv_proto_emit.nx (a new device class = a new op-list SPEC, zero emitter change). This shape library + its consumer nx_drvgen are KEPT only as the byte-identical virtio re-emit regression reference (NVMEGATE stage=B PROOF-1). See nx_drvgen.nx header + nvme_oplist_virt.spec. nx_driver_shapes.nx -- the DEVICE-AGNOSTIC driver shape library (X-DRV-W1 stage A). This is the emitter-of-emitters substrate for driver bring-up: a tiny rv64 mini-encoder plus four SPEC-DATA-DRIVEN emit-op families that, between them, express the structure of ANY register- programmed device-init driver. ZERO virtio (or NVMe) identity is baked here -- every offset and constant an op touches arrives as a PARAMETER, pulled by the caller from a generic field table. The device identity lives entirely in the spec; this library only knows how to turn (offset, value) tuples into bytes. The four shapes: WIRE_TLV verify "reg-at-offset == const" / write "const -> reg-at-offset". The bring-up handshake is a list of WIRE_TLV ops (virtio MagicValue/Version/DeviceID verifies + Status ORs; NVMe would be CAP/VS verifies + AQA/ASQ/ACQ writes). Provided by ds_emit_verify / ds_emit_verify_u / ds_emit_regwrite. COMMAND_QUEUE bind a queue (write base/PFN regs) + kick a doorbell/notify + read an instrument register back and verify it. virtio's QueuePFN+QueueNotify and NVMe's ASQ/ACQ+ SQyTDBL are the SAME op over different spec rows -- the caller threads the bind regs, the kick reg/val, and the result reg/expected. The read-back verify is ds_emit_verify / ds_emit_verify_u; the kick is ds_emit_regwrite. STATE_MACHINE an enable/progress step that is EITHER monotonic-OR-write (virtio Status) OR write-then-poll-until-bit-set (NVMe CC.EN -> CSTS.RDY). ds_emit_regwrite covers the OR-write half; ds_emit_poll_until_set synthesises the poll-loop control flow (a real backward branch) from a spec field -- the structure comes from DATA, not from code (the eoe / X-AUT-006d principle). Virtio uses only the OR-write half; the poll half is exercised by the 2nd device class (stage B). STRUCT_WALK store struct fields at base_reg + memoff with width w, driven by a field table (off, width, value). virtio's 16-byte split-virtqueue descriptor and NVMe's 64-byte SQE are the SAME op over different field tables. Provided by ds_emit_memstore (and ds_li32 / ds_li32u for materialising a struct base addr). Byte-reproducibility: every op keeps the two-pass measure/backfill invariant of the original virtio emitter (instruction COUNT identical across passes; only immediates differ), so a forward fail-branch target is structurally derived, never typed. This file is lifted VERBATIM (byte-for- byte logic) from nx_virtio_hs_emit's encoder so the refactored virtio emitter that now CALLS these ops re-emits its image byte-identically (the stage-A regression guard). Sovereign: pure integer arithmetic, no syscalls beyond what the importer pulls in via nx_syscalls. license_tier: ORIGINAL

dependencies 1 imports · 3 importers

nx_syscalls.nx nx_driver_shapes.nx _ds_smoke.nx nx_drvgen.nx nx_virtio_hs_emit.nx

imports: nx_syscalls.nx

imported by: _ds_smoke.nxnx_drvgen.nxnx_virtio_hs_emit.nx

structs

none

consts

43const DS_UART: i64 = 0x10000000 // NS16550A THR (write a byte = transmit a transcript char)
44const DS_FIN: i64 = 0x100000 // SiFive test finisher (write to exit the machine cleanly)
45const DS_PASS: i64 = 0x5555 // FINISHER_PASS low half -> clean halt
47const DS_X0: i64 = 0
48const DS_T0: i64 = 5 // UART base
49const DS_T1: i64 = 6 // scratch / transcript byte
50const DS_T2: i64 = 7 // device base
51const DS_T3: i64 = 28 // loaded register value (actual)
52const DS_T4: i64 = 29 // expected constant / poll mask
53const DS_T5: i64 = 30 // finisher base / struct-base scratch

functions

56func ds_lui(rd: i64, imm20: i64) -> i64 { return ((imm20 & 0xFFFFF) << 12) | (rd << 7) | 0x37 }
57func ds_addi(rd: i64, rs1: i64, imm: i64) -> i64 { return ((imm & 0xFFF) << 20) | (rs1 << 15) | (rd << 7) | 0x13 }
called by 2: ds_li32ds_emit_str
59func ds_load(rd: i64, rs1: i64, f3: i64, imm: i64) -> i64 { return ((imm & 0xFFF) << 20) | (rs1 << 15) | (f3 << 12) | (rd << 7) | 0x03 }
61func ds_store(rs2: i64, rs1: i64, f3: i64, imm: i64) -> i64
67func ds_branch(rs1: i64, rs2: i64, f3: i64, imm: i64) -> i64
75func ds_jal(rd: i64, imm: i64) -> i64
called by 1: ds_emit_finisher
83func ds_and(rd: i64, rs1: i64, rs2: i64) -> i64 { return (rs2 << 20) | (rs1 << 15) | (7 << 12) | (rd << 7) | 0x33 }
85func ds_shift(rd: i64, rs1: i64, f3: i64, shamt: i64) -> i64 { return ((shamt & 0x3f) << 20) | (rs1 << 15) | (f3 << 12) | (rd << 7) | 0x13 }
called by 1: ds_li32u
87func ds_w32(buf: *u8, off: i64, w: i64) -> i64
99func ds_li32(buf: *u8, off: i64, rd: i64, val: i64) -> i64
111func ds_li32u(buf: *u8, off: i64, rd: i64, val: i64) -> i64
119func ds_emit_str(buf: *u8, off: i64, s: *u8, n: i64) -> i64
133func ds_emit_verify(buf: *u8, off: i64, regoff: i64, expected: i64, fail_off: i64) -> i64
145func ds_emit_verify_u(buf: *u8, off: i64, regoff: i64, expected: i64, fail_off: i64) -> i64
155func ds_emit_regwrite(buf: *u8, off: i64, regoff: i64, val: i64) -> i64
163func ds_emit_checkbit(buf: *u8, off: i64, regoff: i64, mask: i64, fail_off: i64) -> i64
178func ds_emit_regwrite_far(buf: *u8, off: i64, regaddr: i64, val: i64) -> i64
called by 1: nv_emit_image calls 3: ds_li32ds_w32ds_store
188func ds_emit_verify_far(buf: *u8, off: i64, regaddr: i64, expected: i64, fail_off: i64) -> i64
200func ds_emit_memstore(buf: *u8, off: i64, base_reg: i64, memoff: i64, f3: i64, val: i64) -> i64
215func ds_emit_poll_until_set(buf: *u8, off: i64, en_off: i64, en_val: i64, rdy_off: i64, rdy_mask: i64) -> i64
234func ds_emit_poll_mem_until_set(buf: *u8, off: i64, base_reg: i64, poll_off: i64, mask: i64) -> i64
245func ds_emit_finisher(buf: *u8, off: i64) -> i64