rumpk/core/fiber.nim

84 lines
2.1 KiB
Nim

# MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
# RUMPK CORE // FIBER
# The atom of execution.
{.push stackTrace: off, lineTrace: off.}
type
FiberState* = object
sp*: uint64 # The Stack Pointer (Must be first field!)
entry*: proc() {.cdecl.} # Entry point for this fiber
Fiber* = ptr FiberObject
FiberObject* = object
id*: uint64
name*: cstring
state*: FiberState
stack*: ptr UncheckedArray[uint8]
stack_size*: int
# Import the Assembly Magic
proc cpu_switch_to(prev_sp_ptr: ptr uint64, next_sp: uint64) {.importc, cdecl.}
# Import console for debugging
proc console_write(p: pointer, len: csize_t) {.importc, cdecl.}
proc debug(s: string) =
if s.len > 0:
console_write(unsafeAddr s[0], csize_t(s.len))
# Context Frame Size: 6 pairs * 16 bytes = 96 bytes (16-byte aligned!)
const CONTEXT_SIZE = 96
# Stack Helper (Simple 4KB aligned stack)
const STACK_SIZE* = 4096
# We need a "Main" fiber to represent the boot thread
var main_fiber: FiberObject
var current_fiber*: Fiber = addr main_fiber
# Trampoline that calls the fiber's entry point
proc fiber_trampoline() {.cdecl, exportc, noreturn.} =
let f = current_fiber
if f.state.entry != nil:
f.state.entry()
# If the fiber returns, halt
while true:
{.emit: "asm volatile(\"wfi\");".}
proc init_fiber*(f: Fiber, entry: proc() {.cdecl.}, stack_base: pointer) =
f.state.entry = entry
# Start at top of stack
var sp = cast[uint64](stack_base) + STACK_SIZE
# 1. Align to 16 bytes (Strict requirement)
sp = sp and not 15'u64
# 2. Reserve space for the context frame (96 bytes)
sp = sp - CONTEXT_SIZE
# 3. Setup the Context
var stack_ptr = cast[ptr UncheckedArray[uint64]](sp)
# Zero out registers x19-x28 (indices 0-9)
for i in 0..<10:
stack_ptr[i] = 0
# Set x29 (FP) to 0 - Offset 80 / 8 = index 10
stack_ptr[10] = 0
# Set x30 (LR) to trampoline - Offset 88 / 8 = index 11
stack_ptr[11] = cast[uint64](fiber_trampoline)
f.state.sp = sp
proc switch*(next: Fiber) =
let prev = current_fiber
current_fiber = next
cpu_switch_to(addr prev.state.sp, next.state.sp)
{.pop.}