ax-cpu 0.10.0

Privileged instruction and structure abstractions for various CPU architectures
Documentation
//! LVZ entry layout and final host stack restoration.

use core::mem::{offset_of, size_of};

use super::super::virtualization::{GuestContext, Vcpu};

core::arch::global_asm!(
    include_str!("walker.S"),
    include_str!("guest.S"),
    ctx_size = const size_of::<GuestContext>(),
    sepc = const offset_of!(GuestContext, sepc),
    gcsr_crmd = const offset_of!(GuestContext, gcsr_crmd),
    gcsr_prmd = const offset_of!(GuestContext, gcsr_prmd),
    gcsr_euen = const offset_of!(GuestContext, gcsr_euen),
    gcsr_misc = const offset_of!(GuestContext, gcsr_misc),
    gcsr_ectl = const offset_of!(GuestContext, gcsr_ectl),
    gcsr_estat = const offset_of!(GuestContext, gcsr_estat),
    gcsr_era = const offset_of!(GuestContext, gcsr_era),
    gcsr_badv = const offset_of!(GuestContext, gcsr_badv),
    gcsr_badi = const offset_of!(GuestContext, gcsr_badi),
    gcsr_eentry = const offset_of!(GuestContext, gcsr_eentry),
    gcsr_tlbidx = const offset_of!(GuestContext, gcsr_tlbidx),
    gcsr_tlbehi = const offset_of!(GuestContext, gcsr_tlbehi),
    gcsr_tlbelo0 = const offset_of!(GuestContext, gcsr_tlbelo0),
    gcsr_tlbelo1 = const offset_of!(GuestContext, gcsr_tlbelo1),
    gcsr_asid = const offset_of!(GuestContext, gcsr_asid),
    gcsr_pgdl = const offset_of!(GuestContext, gcsr_pgdl),
    gcsr_pgdh = const offset_of!(GuestContext, gcsr_pgdh),
    gcsr_pgd = const offset_of!(GuestContext, gcsr_pgd),
    gcsr_pwcl = const offset_of!(GuestContext, gcsr_pwcl),
    gcsr_pwch = const offset_of!(GuestContext, gcsr_pwch),
    gcsr_stlbps = const offset_of!(GuestContext, gcsr_stlbps),
    gcsr_ravcfg = const offset_of!(GuestContext, gcsr_ravcfg),
    gcsr_cpuid = const offset_of!(GuestContext, gcsr_cpuid),
    gcsr_prcfg1 = const offset_of!(GuestContext, gcsr_prcfg1),
    gcsr_prcfg2 = const offset_of!(GuestContext, gcsr_prcfg2),
    gcsr_prcfg3 = const offset_of!(GuestContext, gcsr_prcfg3),
    gcsr_save0 = const offset_of!(GuestContext, gcsr_save0),
    gcsr_save1 = const offset_of!(GuestContext, gcsr_save1),
    gcsr_save2 = const offset_of!(GuestContext, gcsr_save2),
    gcsr_save3 = const offset_of!(GuestContext, gcsr_save3),
    gcsr_save4 = const offset_of!(GuestContext, gcsr_save4),
    gcsr_save5 = const offset_of!(GuestContext, gcsr_save5),
    gcsr_save6 = const offset_of!(GuestContext, gcsr_save6),
    gcsr_save7 = const offset_of!(GuestContext, gcsr_save7),
    gcsr_save8 = const offset_of!(GuestContext, gcsr_save8),
    gcsr_save9 = const offset_of!(GuestContext, gcsr_save9),
    gcsr_save10 = const offset_of!(GuestContext, gcsr_save10),
    gcsr_save11 = const offset_of!(GuestContext, gcsr_save11),
    gcsr_save12 = const offset_of!(GuestContext, gcsr_save12),
    gcsr_save13 = const offset_of!(GuestContext, gcsr_save13),
    gcsr_save14 = const offset_of!(GuestContext, gcsr_save14),
    gcsr_save15 = const offset_of!(GuestContext, gcsr_save15),
    gcsr_tid = const offset_of!(GuestContext, gcsr_tid),
    gcsr_tcfg = const offset_of!(GuestContext, gcsr_tcfg),
    gcsr_cntc = const offset_of!(GuestContext, gcsr_cntc),
    gcsr_ticlr = const offset_of!(GuestContext, gcsr_ticlr),
    gcsr_llbctl = const offset_of!(GuestContext, gcsr_llbctl),
    gcsr_tlbrentry = const offset_of!(GuestContext, gcsr_tlbrentry),
    gcsr_tlbrbadv = const offset_of!(GuestContext, gcsr_tlbrbadv),
    gcsr_tlbrera = const offset_of!(GuestContext, gcsr_tlbrera),
    gcsr_tlbrsave = const offset_of!(GuestContext, gcsr_tlbrsave),
    gcsr_tlbrelo0 = const offset_of!(GuestContext, gcsr_tlbrelo0),
    gcsr_tlbrelo1 = const offset_of!(GuestContext, gcsr_tlbrelo1),
    gcsr_tlbrehi = const offset_of!(GuestContext, gcsr_tlbrehi),
    gcsr_tlbrprmd = const offset_of!(GuestContext, gcsr_tlbrprmd),
    gcsr_dmw0 = const offset_of!(GuestContext, gcsr_dmw0),
    gcsr_dmw1 = const offset_of!(GuestContext, gcsr_dmw1),
    gcsr_dmw2 = const offset_of!(GuestContext, gcsr_dmw2),
    gcsr_dmw3 = const offset_of!(GuestContext, gcsr_dmw3),
    host_estat = const offset_of!(GuestContext, host_estat),
    host_era = const offset_of!(GuestContext, host_era),
    host_badv = const offset_of!(GuestContext, host_badv),
    host_badi = const offset_of!(GuestContext, host_badi),
    host_tlbrbadv = const offset_of!(GuestContext, host_tlbrbadv),
    host_tlbrera = const offset_of!(GuestContext, host_tlbrera),
    host_pgdl = const offset_of!(GuestContext, host_pgdl),
    host_pgdh = const offset_of!(GuestContext, host_pgdh),
    host_pwcl = const offset_of!(GuestContext, host_pwcl),
    host_pwch = const offset_of!(GuestContext, host_pwch),
    host_stlbps = const offset_of!(GuestContext, host_stlbps),
    host_tlbrentry = const offset_of!(GuestContext, host_tlbrentry),
    host_asid = const offset_of!(GuestContext, host_asid),
    host_eentry = const offset_of!(GuestContext, host_eentry),
    host_ecfg = const offset_of!(GuestContext, host_ecfg),
    guest_tlbrentry = const offset_of!(GuestContext, guest_tlbrentry),
    guest_eentry = const offset_of!(GuestContext, guest_eentry),
    gpr0 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, zero),
    gpr1 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, ra),
    gpr2 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, tp),
    gpr3 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, sp),
    gpr4 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, a0),
    gpr5 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, a1),
    gpr6 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, a2),
    gpr7 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, a3),
    gpr8 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, a4),
    gpr9 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, a5),
    gpr10 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, a6),
    gpr11 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, a7),
    gpr12 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t0),
    gpr13 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t1),
    gpr14 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t2),
    gpr15 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t3),
    gpr16 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t4),
    gpr17 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t5),
    gpr18 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t6),
    gpr19 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t7),
    gpr20 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, t8),
    gpr21 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, u0),
    gpr22 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, fp),
    gpr23 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s0),
    gpr24 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s1),
    gpr25 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s2),
    gpr26 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s3),
    gpr27 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s4),
    gpr28 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s5),
    gpr29 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s6),
    gpr30 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s7),
    gpr31 = const offset_of!(GuestContext, x) + offset_of!(crate::registers::GeneralRegisters, s8),
);

#[unsafe(naked)]
#[unsafe(no_mangle)]
unsafe extern "C" fn __ax_cpu_lvzvmexit_trampoline() -> ! {
    core::arch::naked_asm!(
        "move $s0, $sp",
        "move $s1, $a0",
        "li.d $a0, {guest_fp}",
        "add.d $a0, $s0, $a0",
        "bl {save_fp}",
        "li.d $a0, {host_fp}",
        "add.d $a0, $s0, $a0",
        "bl {restore_fp}",
        "move $a0, $s1",
        "addi.d $t0, $s0, {ctx_size}",
        "ld.d $t1, $t0, 0",
        "move $sp, $t1",
        "ld.d $ra, $sp, 0",
        "ld.d $s0, $sp, 8",
        "ld.d $s1, $sp, 16",
        "ld.d $s2, $sp, 24",
        "ld.d $s3, $sp, 32",
        "ld.d $s4, $sp, 40",
        "ld.d $s5, $sp, 48",
        "ld.d $s6, $sp, 56",
        "ld.d $s7, $sp, 64",
        "ld.d $s8, $sp, 72",
        "ld.d $fp, $sp, 80",
        "ld.d $tp, $sp, 88",
        // SAVE_GUEST_REGS restored the CPU-owned r21 from the KS3 shadow.
        "addi.d $sp, $sp, 14 * 8",
        "jr $ra",
        host_fp = const offset_of!(Vcpu, host_fp),
        guest_fp = const offset_of!(Vcpu, fp),
        save_fp = sym super::super::fp::save_fp_registers,
        restore_fp = sym super::super::fp::restore_fp_registers,
        ctx_size = const core::mem::size_of::<GuestContext>(),
    )
}