/* MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
   RUMPK HAL // RISC-V 64 CONTEXT SWITCH (Boundaries Protected)
   
   RISC-V LP64 ABI Saved Registers + Bounds:
   - ra (return address)
   - gp (global pointer)
   - tp (thread pointer)
   - s0-s11 (12 saved registers)
   
   Frame: 16 regs * 8 = 128 bytes (16-byte aligned)
*/

.global cpu_switch_to
.type cpu_switch_to, @function

# void cpu_switch_to(uint64_t* prev_sp_ptr, uint64_t next_sp);
# a0 = prev_sp_ptr
# a1 = next_sp

cpu_switch_to:
    # 1. Allocate Stack (128 bytes)
    addi sp, sp, -128
    
    # 2. Save Context
    sd ra,  0(sp)
    sd gp,  8(sp)
    sd tp,  16(sp)
    sd s0,  24(sp)
    sd s1,  32(sp)
    sd s2,  40(sp)
    sd s3,  48(sp)
    sd s4,  56(sp)
    sd s5,  64(sp)
    sd s6,  72(sp)
    sd s7,  80(sp)
    sd s8,  88(sp)
    sd s9,  96(sp)
    sd s10, 104(sp)
    sd s11, 112(sp)

    # 3. Save Old SP
    sd sp, 0(a0)

    # 4. Load New SP
    mv sp, a1

    # 5. Restore Context
    ld ra,  0(sp)
    ld gp,  8(sp)
    ld tp,  16(sp)
    ld s0,  24(sp)
    ld s1,  32(sp)
    ld s2,  40(sp)
    ld s3,  48(sp)
    ld s4,  56(sp)
    ld s5,  64(sp)
    ld s6,  72(sp)
    ld s7,  80(sp)
    ld s8,  88(sp)
    ld s9,  96(sp)
    ld s10, 104(sp)
    ld s11, 112(sp)

    addi sp, sp, 128
    ret

/*
   THE YIELD GUARD
   Protects Kernel GP during subject-to-kernel yield calls.
*/
.global rumpk_yield_guard
.type rumpk_yield_guard, @function

rumpk_yield_guard:
    # 1. Save Subject State
    addi sp, sp, -16
    sd gp, 0(sp)
    sd ra, 8(sp)

    # 2. Restore Kernel Global Pointer (Static Relocation)
    .option push
    .option norelax
    la gp, __global_pointer$
    .option pop

    # 3. Call Nim Internal Logic
    # (rumpk_yield_internal is a Nim cdecl proc)
    call rumpk_yield_internal

    # 4. Restore Subject State
    ld gp, 0(sp)
    ld ra, 8(sp)
    addi sp, sp, 16
    ret

.global rumpk_enter_userland
.type rumpk_enter_userland, @function

# void rumpk_enter_userland(uint64_t entry);
# a0 = entry
rumpk_enter_userland:
    # 🏛️ RESET STATE (Clean slate for the New Consciousness)
    # We keep SP as is for now (it's the fiber stack) 
    # OR we point it to a dedicated User Stack if needed.
    # Subject Entry usually handles its own stack init.
    
    # Disable Supervisor Interrupts during handoff
    csrw sie, zero
    
    # Jump to the Summoned Body
    jr a0
