rumpk/core/netswitch.nim

78 lines
2.5 KiB
Nim

# core/rumpk/core/netswitch.nim
# Phase 36.2: The Traffic Cop (Network Membrane Layer 2 Switch)
#
# Responsibilities:
# - Poll VirtIO-Net hardware for incoming packets
# - Route RX packets to s_net_rx ring (Kernel -> Userland)
# - Drain s_net_tx ring and transmit via VirtIO-Net (Userland -> Kernel)
# - Never yield during active traffic (War Mode latency optimization)
{.push stackTrace: off, lineTrace: off.}
import ion
# Forward declare fiber_yield to avoid circular import
proc fiber_yield*() {.importc, cdecl.}
# HAL Imports
proc virtio_net_poll() {.importc, cdecl.}
proc virtio_net_send(data: pointer, len: uint32) {.importc, cdecl.}
# Logging
proc kprintln(s: cstring) {.importc, cdecl.}
var netswitch_initialized: bool = false
proc netswitch_init*() =
## Initialize network channels and populate SysTable
## MUST be called before userland starts!
ion_init_network()
kprintln("[NetSwitch] Network Rings Initialized")
netswitch_initialized = true
proc netswitch_attach_systable*(sys: ptr SysTable) =
## Attach network ring pointers to SysTable for userland access
sys.s_net_rx = chan_net_rx.ring
sys.s_net_tx = chan_net_tx.ring
kprintln("[NetSwitch] SysTable Rings Attached")
proc fiber_netswitch_entry*() {.cdecl.} =
kprintln("[NetSwitch] Fiber Entry - The Traffic Cop is ON DUTY")
var rx_activity: bool = false
var tx_activity: bool = false
while true:
rx_activity = false
tx_activity = false
# ============================================
# RX PATH: Hardware -> chan_net_rx -> Userland
# ============================================
# virtio_net_poll() internally calls ion_ingress() which pushes
# received packets to the hardware driver's internal ring.
# We poll here to drive the RX path.
virtio_net_poll()
# ============================================
# TX PATH: Userland -> chan_net_tx -> Hardware
# ============================================
var tx_pkt: IonPacket
while chan_net_tx.recv(tx_pkt):
if tx_pkt.data != nil and tx_pkt.len > 0:
virtio_net_send(cast[pointer](tx_pkt.data), uint32(tx_pkt.len))
ion_free(tx_pkt)
tx_activity = true
# ============================================
# YIELD STRATEGY
# ============================================
if rx_activity or tx_activity:
# War Mode: Continue processing if we moved data
continue
else:
# Peace Mode: Yield to let other fibers run
fiber_yield()
{.pop.}