|
|
// /////////////////////////////////////////////////////////////////////////////// // // Module Name: EFIASM.S - IA64 EFI Physical Mode Calls // // Description: // Target Platform: Merced // // Reuse: None // ///////////////////////////////////////////////////////////////////////////////
#include "regia64.h"
#include "kxia64.h"
.global HalpCallEfiPhysical .global HalpPhysBSPointer .global HalpPhysStackPointer .text
//++ // Name: HalpCallEfiPhysical() // // Routine Description: // // Arguments: // // Arg 0 to Arg 5 // EntryPoint // GlobalPointer // // Return Value: EFI_STATUS // //--
NESTED_ENTRY(HalpCallEfiPhysical) NESTED_SETUP(8,2,0,0)
// // Aliases // rSaveEP = t22 rSaveGP = t21 rSaveA5 = t20 rSaveA4 = t19 rSaveA3 = t18 rSaveA2 = t17 rSaveA1 = t16 rSaveA0 = t15
rSaveSp = t14 rSaveBSP = t13 rSavePfs = t12 rSaveBrp = t11 rSaveRSC = t10 rSaveRNAT = t9 rSavePSR = t8
rNewSp = t7 rNewBSP = t6
rT1 = t1 rT2 = t2 rT3 = t3 // Save Arguements in static Registers mov rSaveA0 = a0 mov rSaveA1 = a1 mov rSaveA2 = a2 mov rSaveA3 = a3 mov rSaveA4 = a4 mov rSaveA5 = a5 mov rSaveEP = a6 mov rSaveGP = a7
mov rSaveSp = sp mov rSavePfs = ar.pfs mov rSaveBrp = brp // // Setup Physical sp, bsp //
add rT1 = @gprel(HalpPhysStackPointer), gp add rT2 = @gprel(HalpPhysBSPointer), gp ;;
ld8 rNewSp = [rT1] ld8 rNewBSP = [rT2]
// Allocate 0 ;;
alloc rT1 = 0,0,0,0
// Flush RSE ;;
flushrs ;;
mov rSavePSR = psr movl rT2 = (1 << PSR_BN) ;;
or rSavePSR = rT2, rSavePSR // psr.bn stays on rsm (1 << PSR_I) mov rSaveRSC = ar.rsc
// Flush RSE to enforced lazy mode by clearing both RSC.mode bits
mov rT1 = RSC_KERNEL_DISABLED ;;
mov ar.rsc = rT1 ;;
// // save RSC, RNAT, BSP, PSR, SP in the allocated space during initialization // mov rSaveBSP = ar.bsp mov rSaveRNAT = ar.rnat // // IC = 0; I = 0;
// ;;
rsm (1 << PSR_IC) ;;
// // IIP = HceContinuePhysical: IPSR is physical // movl rT1 = (1 << PSR_IT) | (1 << PSR_RT) | (1 << PSR_DT) | (1 << PSR_I) movl rT2 = 0xffffffffffffffff ;;
xor rT1 = rT1, rT2 ;;
and rT1 = rT1, rSavePSR // rT1 = old PSR & zero it, dt, rt, i srlz.i ;;
mov cr.ipsr = rT1 mov cr.ifs = zero ;;
movl rT2 = HceContinuePhysical movl rT3 = 0xe0000000ffffffff ;;
and rT2 = rT2, rT3 ;;
tpa rT2 = rT2 // phys address of new ip ;;
mov cr.iip = rT2 ;;
rfi ;;
// // Now in physical mode, ic = 1, i = 0 //
HceContinuePhysical::
// // Switch to new bsp, sp // mov sp = rNewSp mov ar.bspstore = rNewBSP ;;
mov ar.rnat = zero ;;
// // Enable RSC // mov ar.rsc = RSC_KERNEL
// // Allocate frame on new bsp // ;;
alloc rT1 = ar.pfs,0,7,6,0
// // Save caller's state in register stack //
mov loc0 = rSaveRNAT mov loc1 = rSaveSp mov loc2 = rSaveBSP mov loc3 = rSaveRSC mov loc4 = rSaveBrp mov loc5 = rSavePfs mov loc6 = rSavePSR ;;
// Setup Arguements
mov out0 = rSaveA0 mov out1 = rSaveA1 mov out2 = rSaveA2 mov out3 = rSaveA3 mov out4 = rSaveA4 mov out5 = rSaveA5
movl rT1 = HceEfiReturnAddress movl rT2 = 0xe0000000FFFFFFFF ;;
and rT2 = rT2, rT1 ;;
tpa rT2 = rT2 ;;
mov brp = rT2 mov gp = rSaveGP mov bt0 = rSaveEP ;;
br.call.sptk brp = bt0 ;;
HceEfiReturnAddress:: // // In physical mode: switch to virtual //
// // Restore saved state // mov rSaveRNAT = loc0 mov rSaveSp = loc1 mov rSaveBSP = loc2 mov rSaveRSC = loc3 mov rSaveBrp = loc4 mov rSavePfs = loc5 mov rSavePSR = loc6 ;;
// // Restore BSP, SP // ;;
mov ar.rsc = RSC_KERNEL_DISABLED ;;
alloc rT1 = 0,0,0,0 ;;
mov ar.bspstore = rSaveBSP ;;
mov ar.rnat = rSaveRNAT mov sp = rSaveSp ;;
rsm (1 << PSR_IC) ;;
movl rT1 = HceContinueVirtual movl rT2 = 0xe0000000ffffffff ;;
and rT1 = rT2, rT1 ;;
srlz.i ;;
mov cr.iip = rT1 mov cr.ipsr = rSavePSR mov cr.ifs = zero ;;
rfi ;;
// // Now in virtual mode, ic = 1, i = 1 // HceContinueVirtual::
// // Restore psf, brp and return // mov ar.rsc = rSaveRSC ;;
mov ar.pfs = rSavePfs mov brp = rSaveBrp ;;
br.ret.sptk brp NESTED_EXIT(HalpCallEfiPhysical)
//++ // // VOID // HalpCallEfiVirtual( // ULONGLONG a0, /* Arg 1 */ // ULONGLONG a1, /* Arg 2 */ // ULONGLONG a2, /* Arg 3 */ // ULONGLONG a3, /* Arg 4 */ // ULONGLONG a4, /* Arg 5 */ // ULONGLONG a5, /* Arg 6 */ // ULONGLONG a6, /* Entry Point */ // ULONGLONG a7 /* GP */ // );
// // Routine Description: // // Return Values: // r8->r11 contain the 4 64-bit return values, r8 is the status //--
NESTED_ENTRY(HalpCallEfiVirtual) NESTED_SETUP(8,2,8,0) // copy args to outs mov out0 = a0 mov out1 = a1 mov out2 = a2 mov out3 = a3 mov out4 = a4 mov out5 = a5 mov out6 = a6 mov out7 = a7 ;;
// Simply load the address and branch to it
mov gp = a7 ;;
mov bt0 = a6 ;;
br.call.sptk brp = bt0 ;;
NESTED_RETURN NESTED_EXIT(HalpCallEfiVirtual)
|