code wiki / _hdl_build / _nvme_diag.nx

_nvme_diag.nx source

↩ module page · 78 lines · 4241 B

1// _nvme_diag.nx -- diagnostic: load the NVMe image, run it on the sovereign emu, then DUMP the 2// NVMe controller storage + ACQ RAM so we can see whether the doorbell DMA posted the CQE. 3// Sovereign. license_tier: ORIGINAL 4import "rv64im_min_sim.nx" 5import "rv64im_min_csr.nx" 6import "rv64im_min_clint.nx" 7import "rv64im_min_uart.nx" 8import "rv64im_min_virtio.nx" 9import "rv64im_min_nvme.nx" 10 11const D_MEM_BASE: i64 = 0x80000000 12const D_MEM_SIZE: i64 = 65536 13const D_TX_CAP: i64 = 4096 14const D_MAX_STEPS: i64 = 100000 15 16func d_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 17func d_n(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(1,bb,k); return 0 } 18func d_hex(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(1,d,8); return 0 } 19 20func main(argc: i64, argv: *i64) -> i64 { 21 var binp: *u8 = "runtime/_hdl_build/_nvme_admin_virt.bin" as *u8 22 if argc >= 2 { binp = argv[1] as *u8 } 23 let lenp: *i64 = sys_mmap(16) as *i64 24 let img: *u8 = sys_read_file(binp, lenp) 25 let ilen: i64 = lenp[0] 26 if ilen <= 0 { d_p("diag: image missing\n" as *u8); sys_exit(1); return 1 } 27 28 let rf_storage: *i64 = (sys_mmap(8 * NX_RV64IM_RF_N_REGS)) as *i64 29 let csr_storage: *i64 = (sys_mmap(8 * NX_CSR_SLOT_N)) as *i64 30 let clint_storage: *i64 = (sys_mmap(8 * NX_CLINT_SLOT_N)) as *i64 31 let uart_storage: *i64 = (sys_mmap(8 * NX_UART_SLOT_N)) as *i64 32 let virtio_storage:*i64 = (sys_mmap(8 * NX_VIRTIO_SLOT_N)) as *i64 33 let vnet_storage: *i64 = (sys_mmap(8 * NX_VIRTIO_SLOT_N)) as *i64 34 let nvme_storage: *i64 = (sys_mmap(8 * NX_NVME_SLOT_N)) as *i64 35 let mem: *u8 = sys_mmap(D_MEM_SIZE) 36 let tx_buf: *u8 = sys_mmap(D_TX_CAP) 37 let rf: *NxRv64imRegfile = (sys_mmap(64)) as *NxRv64imRegfile 38 let csr: *NxRv64imCsrFile = (sys_mmap(64)) as *NxRv64imCsrFile 39 let clint: *NxClint = (sys_mmap(64)) as *NxClint 40 let uart: *NxUart = (sys_mmap(64)) as *NxUart 41 let virtio:*NxVirtioMmio = (sys_mmap(64)) as *NxVirtioMmio 42 let vnet: *NxVirtioMmio = (sys_mmap(64)) as *NxVirtioMmio 43 let nvme: *NxNvmeCtrl = (sys_mmap(64)) as *NxNvmeCtrl 44 let sim: *NxRv64imSim = (sys_mmap(128)) as *NxRv64imSim 45 46 nx_rv64im_rf_init(rf, rf_storage) 47 nx_rv64im_csr_init(csr, csr_storage, 0) 48 nx_clint_init(clint, clint_storage) 49 nx_uart_init(uart, uart_storage, tx_buf, D_TX_CAP) 50 nx_virtio_init(virtio, virtio_storage) 51 nx_virtio_init_net(vnet, vnet_storage) 52 nx_nvme_init(nvme, nvme_storage) 53 nx_rv64im_sim_init(sim, rf, csr, clint, uart, D_MEM_BASE, mem, D_MEM_SIZE, 0) 54 nx_rv64im_sim_attach_virtio(sim, virtio) 55 nx_rv64im_sim_attach_virtio_net(sim, vnet) 56 nx_rv64im_sim_attach_nvme(sim, nvme) 57 58 var i: i64 = 0 59 while i < ilen { mem[i] = img[i]; i = i + 1 } 60 61 nx_rv64im_sim_run(sim, D_MAX_STEPS) 62 63 let cnt: i64 = nx_uart_tx_count(uart) 64 d_p("serial: " as *u8); sys_write(1, tx_buf, cnt); d_p("\n" as *u8) 65 d_p("halted=" as *u8); d_n(sim.halted); d_p(" steps=" as *u8); d_n(sim.steps); d_p("\n" as *u8) 66 d_p("CC=0x" as *u8); d_hex(nvme_storage[NX_NVME_SLOT_CC]) 67 d_p(" CSTS=0x" as *u8); d_hex(nvme_storage[NX_NVME_SLOT_CSTS]) 68 d_p(" ASQ_LO=0x" as *u8); d_hex(nvme_storage[NX_NVME_SLOT_ASQ_LO]) 69 d_p(" ACQ_LO=0x" as *u8); d_hex(nvme_storage[NX_NVME_SLOT_ACQ_LO]) 70 d_p(" SQTAIL=" as *u8); d_n(nvme_storage[NX_NVME_SLOT_SQTAIL]) 71 d_p(" CQPEEK=0x" as *u8); d_hex(nvme_storage[NX_NVME_SLOT_CQPEEK]); d_p("\n" as *u8) 72 // dump SQE bytes at asq off 0x5000 (opcode@0, cid@2) 73 d_p("SQE[0..4]=" as *u8); var j: i64 = 0; while j < 4 { d_hex(mem[0x5000 + j] as i64); d_p(" " as *u8); j = j + 1 } d_p("\n" as *u8) 74 // dump CQE bytes at acq off 0x6000 (cid@12, status@14) 75 d_p("CQE[10..16]=" as *u8); var k: i64 = 10; while k < 16 { d_hex(mem[0x6000 + k] as i64); d_p(" " as *u8); k = k + 1 } d_p("\n" as *u8) 76 sys_exit(0) 77 return 0 78}