import ../../core/ion import ../../core/ring const SYS_TABLE_ADDR* = 0x83000000'u64 type SysTable* = object magic*: uint32 reserved*: uint32 s_rx*: pointer s_tx*: pointer s_event*: pointer s_cmd*: pointer s_input*: pointer # Hypercalls (Phase 16) fn_vfs_open*: proc(path: cstring, flags: int32): int32 {.cdecl.} fn_vfs_read*: proc(fd: int32, buf: pointer, count: uint64): int64 {.cdecl.} fn_vfs_list*: proc(buf: pointer, max_len: uint64): int64 {.cdecl.} fn_vfs_write*: proc(fd: int32, buf: pointer, count: uint64): int64 {.cdecl.} fn_vfs_close*: proc(fd: int32): int32 {.cdecl.} fn_log*: pointer fn_pledge*: proc(promises: uint64): int32 {.cdecl.} # Phase 28 # Framebuffer (Phase 26: Visual Cortex) fb_addr*: uint64 fb_width*: uint32 fb_height*: uint32 fb_stride*: uint32 fb_bpp*: uint32 var membrane_rx_ring_ptr*: ptr RingBuffer[IonPacket, 256] var membrane_tx_ring_ptr*: ptr RingBuffer[IonPacket, 256] var membrane_cmd_ring_ptr*: ptr RingBuffer[CmdPacket, 256] var membrane_input_ring_ptr*: ptr RingBuffer[IonPacket, 256] proc ion_user_init*() {.exportc.} = when defined(is_membrane): let sys = cast[ptr SysTable](SYS_TABLE_ADDR) membrane_rx_ring_ptr = cast[ptr RingBuffer[IonPacket, 256]](sys.s_rx) membrane_tx_ring_ptr = cast[ptr RingBuffer[IonPacket, 256]](sys.s_tx) membrane_cmd_ring_ptr = cast[ptr RingBuffer[CmdPacket, 256]](sys.s_cmd) membrane_input_ring_ptr = cast[ptr RingBuffer[IonPacket, 256]](sys.s_input) proc ion_user_alloc*(out_pkt: ptr IonPacket): bool {.exportc.} = var pkt = ion_alloc() if pkt.data == nil: return false out_pkt[] = pkt return true proc ion_user_free*(pkt: IonPacket) {.exportc.} = ion_free(pkt) proc ion_user_return*(id: uint16) {.exportc.} = ## Return a kernel-allocated packet by sending CMD_ION_FREE if membrane_cmd_ring_ptr == nil: return var cmd: CmdPacket cmd.kind = uint32(CmdType.CMD_ION_FREE) cmd.arg = uint64(id) discard membrane_cmd_ring_ptr[].push(cmd) proc ion_user_tx*(pkt: IonPacket): bool {.exportc.} = when defined(is_membrane): if membrane_tx_ring_ptr == nil: return false return membrane_tx_ring_ptr[].push(pkt) else: return false proc ion_user_rx*(out_pkt: ptr IonPacket): bool {.exportc.} = if membrane_rx_ring_ptr == nil: return false if membrane_rx_ring_ptr[].isEmpty: return false let (ok, pkt) = membrane_rx_ring_ptr[].pop() if not ok: return false out_pkt[] = pkt return true proc ion_user_input*(out_pkt: ptr IonPacket): bool {.exportc.} = if membrane_input_ring_ptr == nil: return false if membrane_input_ring_ptr[].isEmpty: return false let (ok, pkt) = membrane_input_ring_ptr[].pop() if not ok: return false out_pkt[] = pkt return true