52 lines
1.8 KiB
Nim
52 lines
1.8 KiB
Nim
# SPDX-License-Identifier: LSL-1.0
|
|
# Copyright (c) 2026 Markus Maiwald
|
|
# Stewardship: Self Sovereign Society Foundation
|
|
#
|
|
# This file is part of the Nexus Sovereign Core.
|
|
|
|
## Rumpk Layer 1: Typed Channels (SPEC-070)
|
|
|
|
import ion
|
|
import cspace
|
|
|
|
# Kernel logging
|
|
proc kprintln(s: cstring) {.importc, cdecl.}
|
|
|
|
proc get_channel_ring*(id: uint64): pointer =
|
|
## Map a Channel ID (object_id) to a physical HAL ring pointer
|
|
case id:
|
|
of 0x1000: return cast[pointer](chan_input.ring)
|
|
of 0x1001: return cast[pointer](chan_tx.ring) # console.output
|
|
of 0x500: return cast[pointer](chan_net_tx.ring)
|
|
of 0x501: return cast[pointer](chan_net_rx.ring)
|
|
else: return nil
|
|
|
|
proc channel_has_data*(id: uint64): bool =
|
|
## Check if a channel has data (for RX) or space (for TX)
|
|
## NOTE: This depends on whether the capability is for READ or WRITE.
|
|
## For now, we focus on RX (has data).
|
|
let ring_ptr = get_channel_ring(id)
|
|
if ring_ptr == nil: return false
|
|
|
|
# Cast to a generic HAL_Ring to check head/tail
|
|
# All IonPacket rings are 256 entries
|
|
let ring = cast[ptr HAL_Ring[IonPacket]](ring_ptr)
|
|
return ring.head != ring.tail
|
|
|
|
proc fiber_can_run_on_channels*(f_id: uint64, mask: uint64): bool {.exportc, cdecl.} =
|
|
## Check if any of the channels in the mask have active data
|
|
if mask == 0: return true # Not waiting on anything specific
|
|
|
|
for i in 0..<64:
|
|
if (mask and (1'u64 shl i)) != 0:
|
|
# Slot i is active in mask
|
|
let cap = cspace_lookup(f_id, uint(i))
|
|
if cap != nil:
|
|
# Cast pointer to Capability struct (wait, we need the Nim definition)
|
|
# Actually, let's just use a C helper if needed, but we can do it here.
|
|
# Capability is 32 bytes. object_id is at offset 4 (wait, 1+1+2 = 4).
|
|
let obj_id = cast[ptr uint64](cast[uint](cap) + 4)[]
|
|
if channel_has_data(obj_id):
|
|
return true
|
|
return false
|