/* MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
   RUMPK HAL // RISC-V 64 CONTEXT SWITCH (Boundaries Protected)
*/

.global cpu_switch_to
.type cpu_switch_to, @function

cpu_switch_to:
    addi sp, sp, -128
    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)
    csrr t0, sscratch
    sd t0, 120(sp)
    sd sp, 0(a0)
    mv sp, a1
    ld t0, 120(sp)
    csrw sscratch, t0
    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

.global rumpk_yield_guard
.type rumpk_yield_guard, @function

rumpk_yield_guard:
    addi sp, sp, -16
    sd gp, 0(sp)
    sd ra, 8(sp)
    .option push
    .option norelax
    la gp, __global_pointer$
    .option pop
    call rumpk_yield_internal
    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, uint64_t argc, uint64_t argv, uint64_t sp);
# a0 = entry, a1 = argc, a2 = argv, a3 = sp
rumpk_enter_userland:
    # 🏛️ PIVOT TO USER MODE (C-ABI Handover)
    
    # 1. Prepare Program Counter
    csrw sepc, a0
    
    # 2. Prepare Stack and sscratch
    # sscratch MUST contain the Kernel Stack for the trap handler
    csrw sscratch, sp
    mv   sp, a3
    
    # 3. Prepare Arguments (argc, argv)
    mv   t0, a1      # Temporarily store argc
    mv   a1, a2      # a1 = argv
    mv   a0, t0      # a0 = argc
    
    # 4. Configure sstatus for U-mode transition
    li t0, (1 << 8)
    csrc sstatus, t0     # Clear SPP (User)
    
    li t0, (1 << 5)
    csrs sstatus, t0     # Enable SPIE
    
    li t0, (1 << 18)
    csrs sstatus, t0     # Enable SUM (Supervisor User Memory)
    
    # 5. Flush Caches
    fence.i

    # 6. The Leap of Faith
    sret
