274 lines
8.3 KiB
Nim
274 lines
8.3 KiB
Nim
# MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
|
|
# Rumpk Layer 1: The Logic Core (Autonomous Immune System)
|
|
|
|
{.push stackTrace: off, lineTrace: off.}
|
|
|
|
import fiber
|
|
import ion
|
|
|
|
|
|
var ion_paused*: bool = false
|
|
var pause_start*: uint64 = 0
|
|
|
|
|
|
# =========================================================
|
|
# Fiber Management (Forward Declared)
|
|
# =========================================================
|
|
|
|
var fiber_ion: FiberObject
|
|
var fiber_nexshell: FiberObject
|
|
var fiber_ui: FiberObject
|
|
var fiber_subject: FiberObject
|
|
var fiber_watchdog: FiberObject
|
|
|
|
# Exports for Zig NPLs
|
|
proc console_write(p: pointer, len: csize_t) {.importc, cdecl.}
|
|
proc write*(fd: cint, p: pointer, len: csize_t): csize_t {.exportc, cdecl.} =
|
|
console_write(p, len)
|
|
return len
|
|
|
|
# Utility for Logic Core
|
|
proc kprint*(s: cstring) {.exportc, cdecl.} =
|
|
if s != nil:
|
|
let length = len(s)
|
|
if length > 0:
|
|
console_write(s, csize_t(length))
|
|
|
|
proc kprintln*(s: cstring) {.exportc, cdecl.} =
|
|
kprint(s); kprint("\n")
|
|
|
|
# =========================================================
|
|
# Shared Infrastructure
|
|
# =========================================================
|
|
|
|
const SYSTABLE_BASE = 0x83000000'u64
|
|
|
|
# Global Rings (The Pipes - L0 Physics)
|
|
var guest_rx_hal: HAL_Ring[IonPacket]
|
|
var guest_tx_hal: HAL_Ring[IonPacket]
|
|
var guest_event_hal: HAL_Ring[IonPacket]
|
|
var guest_cmd_hal: HAL_Ring[CmdPacket]
|
|
|
|
# Shared Channels (The Valves - L1 Logic)
|
|
var chan_rx*: SovereignChannel[IonPacket]
|
|
var chan_tx*: SovereignChannel[IonPacket]
|
|
var chan_event*: SovereignChannel[IonPacket]
|
|
var chan_cmd*: SovereignChannel[CmdPacket]
|
|
|
|
proc get_ion_load(): int =
|
|
## Calculate load of the Command Ring (The Heartbeat of the NPLs)
|
|
let head = guest_cmd_hal.head
|
|
let tail = guest_cmd_hal.tail
|
|
let mask = guest_cmd_hal.mask
|
|
return int((head - tail) and mask)
|
|
|
|
proc rumpk_yield_internal() {.cdecl, exportc.} =
|
|
let load = get_ion_load()
|
|
|
|
# 🏛️ ADAPTIVE GOVERNOR (Phase 3: FLOOD CONTROL)
|
|
# Ring Size = 256. 80% = ~200.
|
|
if load > 200:
|
|
# BACKPRESSURE MODE: Ring is filling up! Panic Flush!
|
|
# Force switch to ION Fiber to drain.
|
|
if current_fiber != addr fiber_ion:
|
|
switch(addr fiber_ion)
|
|
return
|
|
elif load > 0:
|
|
# WAR MODE: Priority to IO Loop. Bypass NexShell/Watchdog.
|
|
if current_fiber == addr fiber_subject:
|
|
switch(addr fiber_ion)
|
|
return
|
|
elif current_fiber == addr fiber_ion:
|
|
# If Subject is the main producer, we must let it run
|
|
switch(addr fiber_subject)
|
|
return
|
|
elif load == 0:
|
|
# IDLE MODE (Phase 3): No pending commands.
|
|
# We must enable interrupts to receive packets!
|
|
asm "csrsi sstatus, 2"
|
|
# We can just yield here, interrupts will fire and preempt us (if we had preemption)
|
|
# or fire and return to here.
|
|
# But if we just loop, we burn CPU.
|
|
# Ideally: WFI.
|
|
# For now: Just enable interrupts so ISR can fire.
|
|
# asm "wfi" # Optional: Save power.
|
|
|
|
# Normal Round Robin logic
|
|
if current_fiber == addr fiber_ion:
|
|
switch(addr fiber_nexshell)
|
|
elif current_fiber == addr fiber_nexshell:
|
|
switch(addr fiber_ui)
|
|
elif current_fiber == addr fiber_ui:
|
|
switch(addr fiber_subject)
|
|
elif current_fiber == addr fiber_subject:
|
|
switch(addr fiber_watchdog)
|
|
else:
|
|
switch(addr fiber_ion)
|
|
|
|
proc fiber_yield*() {.exportc, cdecl.} =
|
|
rumpk_yield_internal()
|
|
|
|
|
|
# Utility moved up
|
|
|
|
|
|
# Channel API (The Valve) - Wrappers for ION
|
|
# Channel API is imported from ion.nim
|
|
|
|
|
|
|
|
# HAL/NPL Entry points
|
|
proc rumpk_halt() {.importc, cdecl, noreturn.}
|
|
proc hal_io_init() {.importc, cdecl.}
|
|
proc nexshell_main() {.importc, cdecl.}
|
|
proc launch_subject() {.importc, cdecl.}
|
|
|
|
# Hardware Ingress (Zig -> Nim)
|
|
proc ion_ingress*(id: uint16, len: uint16) {.exportc, cdecl.} =
|
|
## Intercept raw hardware packet and push to Sovereign RX Channel
|
|
# kprint("[Kernel] Ingress ID: "); kprint_int(int(id)); kprint(" Len: "); kprint_int(int(len)); kprintln("")
|
|
let data = ion_get_virt(id)
|
|
var pkt = IonPacket(data: cast[ptr UncheckedArray[byte]](data), len: len, id: id)
|
|
chan_rx.send(pkt)
|
|
|
|
# Panic Handler
|
|
proc nimPanic(msg: cstring) {.exportc: "panic", cdecl, noreturn.} =
|
|
kprint("\n[PANIC] "); kprintln(msg)
|
|
rumpk_halt()
|
|
|
|
# =========================================================
|
|
# Fiber Entries
|
|
# =========================================================
|
|
|
|
var stack_ion: array[32768, uint8]
|
|
var stack_nexshell: array[32768, uint8]
|
|
var stack_ui: array[32768, uint8]
|
|
var stack_subject: array[65536, uint8]
|
|
var stack_watchdog: array[4096, uint8]
|
|
|
|
proc ui_fiber_entry() {.importc, cdecl.}
|
|
|
|
proc subject_fiber_entry() {.cdecl.} =
|
|
launch_subject()
|
|
|
|
# Include Watchdog Logic (Access to Kernel Globals)
|
|
include watchdog
|
|
|
|
# HAL Driver API
|
|
proc virtio_net_poll() {.importc, cdecl.}
|
|
proc virtio_net_send(data: pointer, len: csize_t) {.importc, cdecl.}
|
|
proc ion_free_raw(id: uint16) {.importc, cdecl.}
|
|
|
|
proc ion_fiber_entry() {.cdecl.} =
|
|
kprint("[ION] Fiber 1 Reporting for Duty.")
|
|
if ion_paused: kprintln(" (PAUSED)") else: kprintln("")
|
|
|
|
var pkt: IonPacket
|
|
var cmd: CmdPacket
|
|
|
|
while true:
|
|
# 0. Poll Hardware (The Heartbeat)
|
|
virtio_net_poll()
|
|
|
|
# 1. Process Commands (Drain the ring!)
|
|
while chan_cmd.recv(cmd):
|
|
if cmd.kind == uint32(CMD_ION_STOP):
|
|
kprintln("[ION] STOP received. Suspending IO.")
|
|
ion_paused = true
|
|
pause_start = cpu_ticks()
|
|
elif cmd.kind == uint32(CMD_ION_START):
|
|
kprintln("[ION] START received. Resuming IO.")
|
|
ion_paused = false
|
|
|
|
# 2. Process Data (if not paused, Drain the ring!)
|
|
if not ion_paused:
|
|
while chan_tx.recv(pkt):
|
|
# Transmit to Hardware
|
|
kprint("[ION] TX from chan_tx, len=")
|
|
# kprint_int(int(pkt.len))
|
|
kprintln("")
|
|
virtio_net_send(pkt.data, csize_t(pkt.len))
|
|
# Zero-Copy Ingest means we own the buffer now.
|
|
# Since virtio_net_send copies (for now), we must free the original slab.
|
|
ion_free_raw(pkt.id)
|
|
|
|
fiber_yield()
|
|
|
|
|
|
# =========================================================
|
|
# kmain: The Orchestrator
|
|
# =========================================================
|
|
|
|
proc kmain() {.exportc, cdecl.} =
|
|
kprintln("\n\n")
|
|
kprintln("╔═══════════════════════════════════════╗")
|
|
kprintln("║ NEXUS RUMK v1.1 - SOVEREIGN ║")
|
|
kprintln("╚═══════════════════════════════════════╝")
|
|
|
|
# 1. Hardware & Memory
|
|
kprintln("[Kernel] Initializing Memory Substrate...")
|
|
ion_pool_init()
|
|
hal_io_init()
|
|
|
|
# 2. Channel Infrastructure
|
|
kprintln("[Kernel] Mapping Sovereign Channels...")
|
|
|
|
# Initialize Invariant Shield (Masking)
|
|
for r in [addr guest_rx_hal, addr guest_tx_hal, addr guest_event_hal]:
|
|
r.head = 0
|
|
r.tail = 0
|
|
r.mask = 255
|
|
|
|
guest_cmd_hal.head = 0
|
|
guest_cmd_hal.tail = 0
|
|
guest_cmd_hal.mask = 255
|
|
|
|
chan_rx.ring = addr guest_rx_hal
|
|
chan_tx.ring = addr guest_tx_hal
|
|
chan_event.ring = addr guest_event_hal
|
|
chan_cmd.ring = addr guest_cmd_hal
|
|
|
|
let sys_table = cast[ptr SysTable](SYSTABLE_BASE)
|
|
sys_table.magic = 0x4E585553
|
|
sys_table.s_rx = addr guest_rx_hal
|
|
sys_table.s_tx = addr guest_tx_hal
|
|
sys_table.s_event = addr guest_event_hal
|
|
sys_table.s_cmd = addr guest_cmd_hal
|
|
|
|
|
|
# 3. The Nerve (Yield Anchor)
|
|
proc rumpk_yield_guard() {.importc, cdecl.}
|
|
let yield_ptr_loc = cast[ptr pointer](0x83000FF0'u64)
|
|
yield_ptr_loc[] = cast[pointer](rumpk_yield_guard)
|
|
|
|
# 4. Deployment
|
|
kprintln("[Kernel] Spawning System Fibers...")
|
|
|
|
# 1. ION FIBER (The Valve)
|
|
init_fiber(addr fiber_ion, ion_fiber_entry, addr stack_ion[0], sizeof(stack_ion))
|
|
|
|
# 2. NEXSHELL FIBER (The Brain)
|
|
init_fiber(addr fiber_nexshell, nexshell_main, addr stack_nexshell[0], sizeof(stack_nexshell))
|
|
|
|
# 3. UI FIBER (The Face)
|
|
init_fiber(addr fiber_ui, ui_fiber_entry, addr stack_ui[0], sizeof(stack_ui))
|
|
|
|
# 4. SUBJECT FIBER (The Payload)
|
|
init_fiber(addr fiber_subject, subject_fiber_entry, addr stack_subject[0],
|
|
sizeof(stack_subject))
|
|
|
|
# 5. WATCHDOG FIBER (The Immune System)
|
|
init_fiber(addr fiber_watchdog, watchdog_loop, addr stack_watchdog[0], sizeof(stack_watchdog))
|
|
|
|
# [FIX] GLOBAL INTERRUPT ENABLE
|
|
# Open the ear before we enter the loop.
|
|
kprintln("[Kernel] Enabling Supervisor Interrupts (SIE)...")
|
|
asm "csrsi sstatus, 2"
|
|
|
|
kprintln("[Kernel] All Systems Go. Entering Autonomous Loop.")
|
|
|
|
# Handover to Scheduler (The Heartbeat)
|
|
switch(addr fiber_ion)
|
|
|
|
{.pop.}
|