82 lines
2.8 KiB
Nim
82 lines
2.8 KiB
Nim
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
|