code wiki / _hdl_build / nx_hw_discover.nx
nx_hw_discover.nx
buildroot/runtime/_hdl_build/nx_hw_discover.nx
about
nx_hw_discover.nx -- GATE: SOVEREIGN HARDWARE AUTO-DISCOVERY by parsing a REAL device tree (FDT/DTB). Reads the
ACTUAL device tree QEMU's RISC-V virt machine hands the guest (knowledge/hw/virt.dtb, dumped live via
`qemu-system-riscv64 -M virt,dumpdtb=`), walks the flattened-device-tree binary (big-endian FDT, magic 0xd00dfeed),
and produces a DEVICE MANIFEST: every node's type + base address. This is how a real OS discovers its hardware --
no hard-coded device list; the machine tells us what it has. Feeds nx_driver_gen (generate a driver per device).
T1 parse the real DTB: valid FDT magic + find the 8 virtio-mmio transport slots.
T2 KAT: the 8 virtio-mmio base addresses == 0x10001000..0x10008000 (the real virt-machine layout).
T3 discover the UART (serial@10000000) + PLIC + CLINT + main memory@0x80000000.
T4 teeth: a corrupted FDT magic is REFUSED (no false discovery). T5 deterministic (re-parse = same manifest).
expect_exit: 0 Sovereign: nx_syscalls. Grounded: knowledge/hw/virt.dtb (a live QEMU artifact).
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_itoa_lib.nxnx_g_puts_lib.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 24 | const FDT_BEGIN_NODE: i64 = 1 |
| 25 | const FDT_END_NODE: i64 = 2 |
| 26 | const FDT_PROP: i64 = 3 |
| 27 | const FDT_NOP: i64 = 4 |
| 28 | const FDT_END: i64 = 9 |
| 29 | const FDT_MAGIC: i64 = 0xd00dfeed |
| 34 | const D_VIRTIO: i64 = 1 |
| 35 | const D_UART: i64 = 2 |
| 36 | const D_PLIC: i64 = 3 |
| 37 | const D_CLINT: i64 = 4 |
| 38 | const D_MEMORY: i64 = 5 |
| 39 | const D_CPU: i64 = 6 |
| 40 | const D_OTHER: i64 = 0 |
functions
| 19 | func g_pn(v: i64) -> i64 { nxi_out(v); return 0 } |
| 20 | func g_hex(v: i64) -> i64 { g_puts("0x" as *u8); let b: *u8=sys_mmap(20); var started: i64=0; var k: i64=0; var i: i64=60; while i>=0 { let nib: i64=(v>>i)&15; if nib!=0 { started=1 } if started==1 { if nib<10 { b[k]=(48+nib) as u8 } else { b[k]=(87+nib) as u8 } k=k+1 } i=i-4 } if k==0 { b[0]=48 as u8; k=1 } sys_write(1,b,k); return 0 } |
| 21 | func ck(name: *u8, c: i64) -> i64 { if c==1 { g_puts(" PASS " as *u8) } else { g_puts(" FAIL " as *u8) } g_puts(name); g_puts("\n" as *u8); return c } |
| 30 | func be32(b: *u8, o: i64) -> i64 { return ((b[o] as i64)<<24)|((b[o+1] as i64)<<16)|((b[o+2] as i64)<<8)|(b[o+3] as i64) } |
| 31 | func align4(x: i64) -> i64 { return (x+3) & (0-4) } called by 1: fdt_discover |
| 32 | func hexval(c: i64) -> i64 { if c>=48 { if c<=57 { return c-48 } } if c>=97 { if c<=102 { return c-87 } } if c>=65 { if c<=70 { return c-55 } } return 0-1 } called by 1: addr_after_at |
| 41 | func tname(t: i64) -> *u8 { if t==1 { return "virtio-mmio" as *u8 } if t==2 { return "uart(ns16550)" as *u8 } if t==3 { return "plic" as *u8 } if t==4 { return "clint" as *u8 } if t==5 { return "memory" as *u8 } if t==6 { return "cpu" as *u8 } return "other" as *u8 } called by 1: main |
| 43 | func starts(name: *u8, o: i64, lit: *u8) -> i64 { var i: i64=0; while lit[i]!=(0 as u8) { if name[o+i]!=lit[i] { return 0 } i=i+1 } return 1 } called by 1: classify |
| 45 | func addr_after_at(b: *u8, o: i64) -> i64 |
| 53 | func classify(b: *u8, o: i64) -> i64 |
| 64 | func fdt_discover(b: *u8, n: i64, dtype: *i64, daddr: *i64, cap: i64) -> i64 |
| 86 | func count_type(dtype: *i64, n: i64, ty: i64) -> i64 { var c: i64=0; var i: i64=0; while i<n { if dtype[i]==ty { c=c+1 } i=i+1 } return c } called by 1: main |
| 87 | func find_addr(dtype: *i64, daddr: *i64, n: i64, ty: i64, addr: i64) -> i64 { var i: i64=0; while i<n { if dtype[i]==ty { if daddr[i]==addr { return 1 } } i=i+1 } return 0 } called by 1: main |
| 89 | func main() -> i64 |