ruvix-aarch64 0.1.0

AArch64 support for RuVix Cognition Kernel (ADR-087)
Documentation
/*
 * AArch64 exception vector table
 *
 * The vector table must be 2KB (0x800) aligned.
 * Each entry is 128 bytes (0x80), with 16 entries total:
 * - 4 exception types (Sync, IRQ, FIQ, SError)
 * - 4 sources (Current EL SP0, Current EL SPx, Lower EL AArch64, Lower EL AArch32)
 */

.section .text.vectors
.balign 0x800
.global exception_vectors

exception_vectors:

/*
 * Current EL with SP0
 */
.balign 0x80
current_el_sp0_sync:
    b handle_exception_wrapper
.balign 0x80
current_el_sp0_irq:
    b handle_irq_wrapper
.balign 0x80
current_el_sp0_fiq:
    b handle_fiq_wrapper
.balign 0x80
current_el_sp0_serror:
    b handle_serror_wrapper

/*
 * Current EL with SPx
 */
.balign 0x80
current_el_spx_sync:
    b handle_exception_wrapper
.balign 0x80
current_el_spx_irq:
    b handle_irq_wrapper
.balign 0x80
current_el_spx_fiq:
    b handle_fiq_wrapper
.balign 0x80
current_el_spx_serror:
    b handle_serror_wrapper

/*
 * Lower EL using AArch64
 */
.balign 0x80
lower_el_aarch64_sync:
    b handle_exception_wrapper
.balign 0x80
lower_el_aarch64_irq:
    b handle_irq_wrapper
.balign 0x80
lower_el_aarch64_fiq:
    b handle_fiq_wrapper
.balign 0x80
lower_el_aarch64_serror:
    b handle_serror_wrapper

/*
 * Lower EL using AArch32
 */
.balign 0x80
lower_el_aarch32_sync:
    b handle_exception_wrapper
.balign 0x80
lower_el_aarch32_irq:
    b handle_irq_wrapper
.balign 0x80
lower_el_aarch32_fiq:
    b handle_fiq_wrapper
.balign 0x80
lower_el_aarch32_serror:
    b handle_serror_wrapper

/*
 * Exception wrapper macros
 * Save context, call Rust handler, restore context
 */

.macro SAVE_CONTEXT
    /* Allocate space on stack for ExceptionContext (264 bytes) */
    sub sp, sp, #264

    /* Save general purpose registers x0-x30 */
    stp x0, x1, [sp, #0]
    stp x2, x3, [sp, #16]
    stp x4, x5, [sp, #32]
    stp x6, x7, [sp, #48]
    stp x8, x9, [sp, #64]
    stp x10, x11, [sp, #80]
    stp x12, x13, [sp, #96]
    stp x14, x15, [sp, #112]
    stp x16, x17, [sp, #128]
    stp x18, x19, [sp, #144]
    stp x20, x21, [sp, #160]
    stp x22, x23, [sp, #176]
    stp x24, x25, [sp, #192]
    stp x26, x27, [sp, #208]
    stp x28, x29, [sp, #224]
    str x30, [sp, #240]

    /* Save SP, ELR, SPSR */
    mrs x0, sp_el0
    str x0, [sp, #248]
    mrs x0, elr_el1
    str x0, [sp, #256]
    mrs x0, spsr_el1
    str x0, [sp, #264]
.endm

.macro RESTORE_CONTEXT
    /* Restore SP, ELR, SPSR */
    ldr x0, [sp, #248]
    msr sp_el0, x0
    ldr x0, [sp, #256]
    msr elr_el1, x0
    ldr x0, [sp, #264]
    msr spsr_el1, x0

    /* Restore general purpose registers x0-x30 */
    ldp x0, x1, [sp, #0]
    ldp x2, x3, [sp, #16]
    ldp x4, x5, [sp, #32]
    ldp x6, x7, [sp, #48]
    ldp x8, x9, [sp, #64]
    ldp x10, x11, [sp, #80]
    ldp x12, x13, [sp, #96]
    ldp x14, x15, [sp, #112]
    ldp x16, x17, [sp, #128]
    ldp x18, x19, [sp, #144]
    ldp x20, x21, [sp, #160]
    ldp x22, x23, [sp, #176]
    ldp x24, x25, [sp, #192]
    ldp x26, x27, [sp, #208]
    ldp x28, x29, [sp, #224]
    ldr x30, [sp, #240]

    /* Deallocate stack space */
    add sp, sp, #264
.endm

/*
 * Exception handlers that save/restore context
 */

handle_exception_wrapper:
    SAVE_CONTEXT
    mov x0, sp  /* Pass context pointer to Rust */
    bl handle_sync_exception
    RESTORE_CONTEXT
    eret

handle_irq_wrapper:
    SAVE_CONTEXT
    mov x0, sp
    bl handle_irq
    RESTORE_CONTEXT
    eret

handle_fiq_wrapper:
    SAVE_CONTEXT
    mov x0, sp
    bl handle_fiq
    RESTORE_CONTEXT
    eret

handle_serror_wrapper:
    SAVE_CONTEXT
    mov x0, sp
    bl handle_serror
    RESTORE_CONTEXT
    eret