/* 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)
    sd sp, 0(a0)
    mv sp, a1
    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)
    sd s4,  56(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);
# a0 = entry
rumpk_enter_userland:
    # 🏛️ PIVOT TO USER MODE (Preserving Hart State)
    
    # 1. Set sepc = entry (a0)
    csrw sepc, a0
    
    # 2. Configure sstatus for U-mode transition
    #    - SPP (Previous Privilege Level) = 0 (User) - Bits 8
    #    - SPIE (Previous Interrupt Enable) = 1 (Enable Interrupts on sret) - Bit 5
    #    - SUM (Supervisor User Memory) - PRESERVE (Already set in kmain)
    
    # Clear SPP bit (bit 8)
    li t0, (1 << 8)
    csrc sstatus, t0
    
    # Set SPIE bit (bit 5)
    li t0, (1 << 5)
    csrs sstatus, t0
    
    # 3. Use sret to transit to U-mode
    sret
