audk/MdePkg/Library/BaseLib/Ipf/AsmPalCall.s

159 lines
6.3 KiB
ArmAsm

/// @file
/// Contains an implementation of CallPalProcStacked on Itanium-based
/// architecture.
///
/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
/// This program and the accompanying materials
/// are licensed and made available under the terms and conditions of the BSD License
/// which accompanies this distribution. The full text of the license may be found at
/// http://opensource.org/licenses/bsd-license.php.
///
/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
///
/// Module Name: AsmPalCall.s
///
///
//-----------------------------------------------------------------------------
//++
// AsmPalCall
//
// Makes a PAL procedure call.
// This is function to make a PAL procedure call. Based on the Index
// value this API will make static or stacked PAL call. The following table
// describes the usage of PAL Procedure Index Assignment. Architected procedures
// may be designated as required or optional. If a PAL procedure is specified
// as optional, a unique return code of 0xFFFFFFFFFFFFFFFF is returned in the
// Status field of the PAL_CALL_RETURN structure.
// This indicates that the procedure is not present in this PAL implementation.
// It is the caller's responsibility to check for this return code after calling
// any optional PAL procedure.
// No parameter checking is performed on the 5 input parameters, but there are
// some common rules that the caller should follow when making a PAL call. Any
// address passed to PAL as buffers for return parameters must be 8-byte aligned.
// Unaligned addresses may cause undefined results. For those parameters defined
// as reserved or some fields defined as reserved must be zero filled or the invalid
// argument return value may be returned or undefined result may occur during the
// execution of the procedure. If the PalEntryPoint does not point to a valid
// PAL entry point then the system behavior is undefined. This function is only
// available on IPF.
//
// On Entry :
// in0: PAL_PROC entrypoint
// in1-in4 : PAL_PROC arguments
//
// Return Value:
//
// As per stacked calling conventions.
//
//--
//---------------------------------------------------------------------------
//
// PAL function calls
//
#define PAL_MC_CLEAR_LOG 0x0015
#define PAL_MC_DYNAMIC_STATE 0x0018
#define PAL_MC_ERROR_INFO 0x0019
#define PAL_MC_RESUME 0x001a
.text
.proc AsmPalCall
.type AsmPalCall, @function
AsmPalCall::
alloc loc1 = ar.pfs,5,8,4,0
mov loc0 = b0
mov loc3 = b5
mov loc4 = r2
mov loc7 = r1
mov r2 = psr;;
mov r28 = in1
mov loc5 = r2;;
movl loc6 = 0x100;;
cmp.ge p6,p7 = r28,loc6;;
(p6) movl loc6 = 0x1FF;;
(p7) br.dpnt.few PalCallStatic;; // 0 ~ 255 make a static Pal Call
(p6) cmp.le p6,p7 = r28,loc6;;
(p6) br.dpnt.few PalCallStacked;; // 256 ~ 511 make a stacked Pal Call
(p7) movl loc6 = 0x300;;
(p7) cmp.ge p6,p7 = r28,loc6;;
(p7) br.dpnt.few PalCallStatic;; // 512 ~ 767 make a static Pal Call
(p6) movl loc6 = 0x3FF;;
(p6) cmp.le p6,p7 = r28,loc6;;
(p6) br.dpnt.few PalCallStacked;; // 768 ~ 1023 make a stacked Pal Call
(p7) mov r8 = 0xFFFFFFFFFFFFFFFF;; // > 1024 return invalid
(p7) br.dpnt.few ComeBackFromPALCall;;
PalCallStatic:
movl loc6 = PAL_MC_CLEAR_LOG;;
cmp.eq p6,p7 = r28,loc6;;
(p7) movl loc6 = PAL_MC_DYNAMIC_STATE;;
(p7) cmp.eq p6,p7 = r28,loc6;;
(p7) movl loc6 = PAL_MC_ERROR_INFO;;
(p7) cmp.eq p6,p7 = r28,loc6;;
(p7) movl loc6 = PAL_MC_RESUME;;
(p7) cmp.eq p6,p7 = r28,loc6 ;;
mov loc6 = 0x1;;
(p7) dep r2 = loc6,r2,13,1;; // psr.ic = 1
// p6 will be true, if it is one of the MCHK calls. There has been lots of debate
// on psr.ic for these values. For now, do not do any thing to psr.ic
dep r2 = r0,r2,14,1;; // psr.i = 0
mov psr.l = r2
srlz.d // Needs data serailization.
srlz.i // Needs instruction serailization.
StaticGetPALLocalIP:
mov loc2 = ip;;
add loc2 = ComeBackFromPALCall - StaticGetPALLocalIP,loc2;;
mov b0 = loc2 // return address after Pal call
mov r29 = in2
mov r30 = in3
mov r31 = in4
mov b5 = in0;; // get the PalProcEntrypt from input
br.sptk b5;; // Take the plunge.
PalCallStacked:
dep r2 = r0,r2,14,1;; // psr.i = 0
mov psr.l = r2;;
srlz.d // Needs data serailization.
srlz.i // Needs instruction serailization.
StackedGetPALLocalIP:
mov out0 = in1
mov out1 = in2
mov out2 = in3
mov out3 = in4
mov b5 = in0 ;; // get the PalProcEntrypt from input
br.call.dpnt b0 = b5 ;; // Take the plunge.
ComeBackFromPALCall:
mov psr.l = loc5 ;;
srlz.d // Needs data serailization.
srlz.i // Needs instruction serailization.
mov b5 = loc3
mov r2 = loc4
mov r1 = loc7
mov b0 = loc0
mov ar.pfs = loc1;;
br.ret.dpnt b0;;
.endp AsmPalCall