code wiki / (root) / nx_hal_test.nx

nx_hal_test.nx source

↩ module page · 163 lines · 6856 B

1// nx_hal_test.nx -- smoke for the substrate HAL. 2 3import "nx_syscalls.nx" 4import "nx_hal.nx" 5 6func main() -> i64 { 7 // ----- 1. Sealed-enum gates ----- 8 if nx_hal_op_is_valid(NX_HAL_OP_CLOCK_NOW_NS) != 1 { return 1 } 9 if nx_hal_op_is_valid(NX_HAL_OP_ALLOC_PAGES) != 1 { return 2 } 10 if nx_hal_op_is_valid(NX_HAL_OP_RELEASE_PAGES) != 1 { return 3 } 11 if nx_hal_op_is_valid(NX_HAL_OP_CONSOLE_WRITE) != 1 { return 4 } 12 if nx_hal_op_is_valid(NX_HAL_OP_RANDOM_BYTES) != 1 { return 5 } 13 if nx_hal_op_is_valid(NX_HAL_OP_YIELD) != 1 { return 6 } 14 if nx_hal_op_is_valid(NX_HAL_OP_EXIT) != 1 { return 7 } 15 if nx_hal_op_is_valid(-1) != 0 { return 8 } 16 if nx_hal_op_is_valid(NX_HAL_OP_N_KINDS) != 0 { return 9 } 17 18 if nx_hal_shim_is_valid(NX_HAL_SHIM_LINUX) != 1 { return 10 } 19 if nx_hal_shim_is_valid(NX_HAL_SHIM_BARE_METAL) != 1 { return 11 } 20 if nx_hal_shim_is_valid(NX_HAL_SHIM_NISHI_SILICON) != 1 { return 12 } 21 if nx_hal_shim_is_valid(-1) != 0 { return 13 } 22 if nx_hal_shim_is_valid(NX_HAL_SHIM_N_KINDS) != 0 { return 14 } 23 24 if nx_hal_verdict_is_valid(NX_HAL_OK) != 1 { return 15 } 25 if nx_hal_verdict_is_valid(NX_HAL_FAULT) != 1 { return 16 } 26 if nx_hal_verdict_is_valid(-1) != 0 { return 17 } 27 if nx_hal_verdict_is_valid(NX_HAL_N_VERDICTS) != 0 { return 18 } 28 29 // ----- 2. Active shim is Linux today ----- 30 if nx_hal_active_shim() != NX_HAL_SHIM_LINUX { return 19 } 31 32 // ----- 3. nx_hal_clock_now_ns ----- 33 let t0: i64 = nx_hal_clock_now_ns() 34 if t0 <= 0 { return 20 } 35 // Second call must be >= first (monotonic). 36 let t1: i64 = nx_hal_clock_now_ns() 37 if t1 < t0 { return 21 } 38 39 // ----- 4. nx_hal_alloc_pages ----- 40 let p: *u8 = nx_hal_alloc_pages(4096) 41 if (p as i64) == 0 { return 22 } 42 // Zero-initialised. 43 if p[0] != 0 { return 23 } 44 if p[4095] != 0 { return 24 } 45 // Writable. 46 p[0] = 42 47 p[4095] = 99 48 if p[0] != 42 { return 25 } 49 if p[4095] != 99 { return 26 } 50 // Bad inputs. 51 if (nx_hal_alloc_pages(0) as i64) != 0 { return 27 } 52 if (nx_hal_alloc_pages(-1) as i64) != 0 { return 28 } 53 54 // ----- 5. nx_hal_release_pages -- V1 returns NO_BACKING ----- 55 let rel_rc: i64 = nx_hal_release_pages(p, 4096) 56 if rel_rc != (0 - NX_HAL_NO_BACKING) { return 29 } 57 // Bad inputs still rejected. 58 let null_p: *u8 = (0 as i64) as *u8 59 if nx_hal_release_pages(null_p, 4096) != (0 - NX_HAL_BAD_INPUT) { return 30 } 60 if nx_hal_release_pages(p, 0) != (0 - NX_HAL_BAD_INPUT) { return 31 } 61 if nx_hal_release_pages(p, -1) != (0 - NX_HAL_BAD_INPUT) { return 32 } 62 63 // ----- 6. nx_hal_console_write ----- 64 let msg: *u8 = "[HAL smoke] console write OK\n" as *u8 65 let written: i64 = nx_hal_console_write(msg, 29) 66 if written != 29 { return 33 } 67 // Empty write is a no-op. 68 if nx_hal_console_write(msg, 0) != NX_HAL_OK { return 34 } 69 // Bad inputs. 70 if nx_hal_console_write(null_p, 5) != (0 - NX_HAL_BAD_INPUT) { return 35 } 71 if nx_hal_console_write(msg, -1) != (0 - NX_HAL_BAD_INPUT) { return 36 } 72 73 // ----- 7. nx_hal_random_bytes ----- 74 let r: *u8 = nx_hal_alloc_pages(32) 75 if nx_hal_random_bytes(r, 32) != NX_HAL_OK { return 37 } 76 // Bytes are NOT all zero (probabilistic; vanishingly unlikely 77 // for 32 bytes of true entropy). 78 var i: i64 = 0 79 var nonzero_count: i64 = 0 80 while i < 32 { 81 if r[i] != 0 { nonzero_count = nonzero_count + 1 } 82 i = i + 1 83 } 84 if nonzero_count < 8 { return 38 } 85 // Bad inputs. 86 if nx_hal_random_bytes(null_p, 32) != (0 - NX_HAL_BAD_INPUT) { return 39 } 87 if nx_hal_random_bytes(r, -1) != (0 - NX_HAL_BAD_INPUT) { return 40 } 88 if nx_hal_random_bytes(r, 0) != NX_HAL_OK { return 41 } 89 90 // ----- 8. nx_hal_yield ----- 91 if nx_hal_yield() != NX_HAL_OK { return 42 } 92 93 // ----- 9. Clock monotonicity over yield ----- 94 let t_pre: i64 = nx_hal_clock_now_ns() 95 nx_hal_yield() 96 let t_post: i64 = nx_hal_clock_now_ns() 97 if t_post < t_pre { return 43 } 98 99 // nx_hal_exit deliberately NOT tested (it terminates). 100 101 // ----- 10. nx_hal_spawn + nx_hal_wait: substrate becomes parent ----- 102 // /bin/true is a universal Linux binary that exits 0. 103 let true_path: *u8 = "/bin/true" as *u8 104 let argv_true: *i64 = (sys_mmap(16)) as *i64 105 argv_true[0] = true_path as i64 106 argv_true[1] = 0 // null-terminator 107 let null_envp: *i64 = (0 as i64) as *i64 108 let pid: i64 = nx_hal_spawn(true_path, argv_true, null_envp) 109 if pid <= 0 { return 44 } 110 111 let exit_out: *i64 = (sys_mmap(8)) as *i64 112 exit_out[0] = -1 113 let wait_rc: i64 = nx_hal_wait(pid, exit_out) 114 if wait_rc != NX_HAL_OK { return 45 } 115 if exit_out[0] != 0 { return 46 } 116 117 // ----- 11. /bin/false returns non-zero ----- 118 let false_path: *u8 = "/bin/false" as *u8 119 let argv_false: *i64 = (sys_mmap(16)) as *i64 120 argv_false[0] = false_path as i64 121 argv_false[1] = 0 122 let pid2: i64 = nx_hal_spawn(false_path, argv_false, null_envp) 123 if pid2 <= 0 { return 47 } 124 exit_out[0] = 0 125 if nx_hal_wait(pid2, exit_out) != NX_HAL_OK { return 48 } 126 if exit_out[0] != 1 { return 49 } 127 128 // ----- 12. Spawn /bin/echo: visible side-effect via stdout ----- 129 let echo_path: *u8 = "/bin/echo" as *u8 130 let echo_msg: *u8 = "[substrate spawn] child child child" as *u8 131 let argv_echo: *i64 = (sys_mmap(32)) as *i64 132 argv_echo[0] = echo_path as i64 133 argv_echo[1] = echo_msg as i64 134 argv_echo[2] = 0 135 let pid3: i64 = nx_hal_spawn(echo_path, argv_echo, null_envp) 136 if pid3 <= 0 { return 50 } 137 if nx_hal_wait(pid3, exit_out) != NX_HAL_OK { return 51 } 138 if exit_out[0] != 0 { return 52 } 139 140 // ----- 13. nx_hal_spawn bad-input gates ----- 141 let null_u8: *u8 = (0 as i64) as *u8 142 let null_i64: *i64 = (0 as i64) as *i64 143 if nx_hal_spawn(null_u8, argv_true, null_envp) != (0 - NX_HAL_BAD_INPUT) { return 53 } 144 if nx_hal_spawn(true_path, null_i64, null_envp) != (0 - NX_HAL_BAD_INPUT) { return 54 } 145 146 // ----- 14. nx_hal_wait bad-input ----- 147 if nx_hal_wait(-1, null_i64) != (0 - NX_HAL_BAD_INPUT) { return 55 } 148 149 // ----- 15. nx_hal_kill bad-input gates ----- 150 if nx_hal_kill(0, 15) != (0 - NX_HAL_BAD_INPUT) { return 56 } 151 if nx_hal_kill(-1, 15) != (0 - NX_HAL_BAD_INPUT) { return 57 } 152 if nx_hal_kill(1, 0) != (0 - NX_HAL_BAD_INPUT) { return 58 } 153 if nx_hal_kill(1, -1) != (0 - NX_HAL_BAD_INPUT) { return 59 } 154 if nx_hal_kill(1, 65) != (0 - NX_HAL_BAD_INPUT) { return 60 } 155 156 // ----- 16. New sealed-enum gates ----- 157 if nx_hal_op_is_valid(NX_HAL_OP_SPAWN) != 1 { return 61 } 158 if nx_hal_op_is_valid(NX_HAL_OP_WAIT) != 1 { return 62 } 159 if nx_hal_op_is_valid(NX_HAL_OP_KILL) != 1 { return 63 } 160 if nx_hal_op_is_valid(NX_HAL_OP_N_KINDS) != 0 { return 64 } 161 162 return 0 163}