/trunk/boot/arch/ia64/loader/gefi/lib/ia64/palproc.S |
---|
0,0 → 1,170 |
//++ |
// Copyright (c) 1996-99 Intel Corp. |
// All Rights Reserved |
// |
// INTEL CORPORATION PROPRIETARY INFORMATION |
// |
// This software is supplied under the terms of a license |
// agreement or nondisclosure agreement with Intel Corpo- |
// ration and may not be copied or disclosed except in |
// accordance with the terms of that agreement. |
// |
// |
// |
// Module Name: |
// |
// palproc.s |
// |
// Abstract: |
// |
// Contains an implementation for making PAL PROC calls on |
// IA-64 architecture. |
// |
// |
// |
// Revision History: |
// |
//-- |
.file "palproc.s" |
#include "palproc.h" |
//----------------------------------------------------------------------------- |
//++ |
// MakeStaticPALCall |
// |
// This routine is called whenever an architected static calling convention |
// based PAL call is to be made. This call does use RSE actually, but our policy |
// in making static PAL calls before memory is available is to make sure that |
// we do not nest too deep and allocate beyond 96 banked registers. In other |
// words we carefully code calls and control flow before memory is available. |
// |
// Arguments : All parameters set up to do static PAL call. |
// |
// On Entry : |
// |
// Return Value: |
// |
// As per static calling conventions. |
// |
//-- |
//--------------------------------------------------------------------------- |
PROCEDURE_ENTRY(MakeStaticPALCall) |
NESTED_SETUP (5,8,0,0) |
mov loc3 = b5 |
mov loc4 = r2 |
mov loc7 = r1;; |
movl loc6 = PAL_MC_CLEAR_LOG |
mov r2 = psr;; |
mov loc5 = r2 |
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 |
// (p6)dep r2 = r0,r2,13,1;; // psr.ic = 0 |
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 = StaticComeBackFromPALCall - StaticGetPALLocalIP,loc2;; |
mov b0 = loc2 // return address after Pal call |
mov r28 = in1 // get the input parameters to 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. |
StaticComeBackFromPALCall: |
mov psr.l = loc5;; |
srlz.d;; // Needs data serailization. |
srlz.i;; // Needs instruction serailization. |
mov b5 = loc3 |
mov r2 = loc4 |
mov r1 = loc7 |
NESTED_RETURN |
PROCEDURE_EXIT(MakeStaticPALCall) |
//----------------------------------------------------------------------------- |
//++ |
// MakeStackedPALCall |
// |
// This routine is called whenever an architected stacked calling convention |
// based PAL call is to be made. This call is made after memory is available. |
// Although stacked calls could be made directly from 'C', there is a PAL |
// requirement which forces the index to be in GR28 and hence this stub is |
// needed |
// |
// Arguments : All parameters set up to do stacted PAL call. |
// |
// On Entry : |
// in0: PAL_PROC entrypoint |
// in1-in4 : PAL_PROC arguments |
// |
// Return Value: |
// |
// As per stacked calling conventions. |
// |
//-- |
//--------------------------------------------------------------------------- |
PROCEDURE_ENTRY(MakeStackedPALCall) |
NESTED_SETUP (5,8,4,0) |
mov loc3 = b5 |
mov loc4 = r2 |
mov loc7 = r1 |
mov r2 = psr;; |
mov loc5 = r2;; |
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 r28 = in1 // get the input parameters to PAL call |
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. |
StackedComeBackFromPALCall: |
mov psr.l = loc5;; |
srlz.d;; // Needs data serailization. |
srlz.i;; // Needs instruction serailization. |
mov b5 = loc3 |
mov r2 = loc4 |
mov r1 = loc7 |
NESTED_RETURN |
PROCEDURE_EXIT(MakeStackedPALCall) |
/trunk/boot/arch/ia64/loader/gefi/lib/ia64/initplat.c |
---|
0,0 → 1,31 |
/*++ |
Copyright (c) 1999 Intel Corporation |
Module Name: |
initplat.c |
Abstract: |
Functions to make SAL and PAL proc calls |
Revision History |
--*/ |
#include "lib.h" |
//#include "palproc.h" |
VOID |
InitializeLibPlatform ( |
IN EFI_HANDLE ImageHandle, |
IN EFI_SYSTEM_TABLE *SystemTable |
) |
{ |
PLABEL SalPlabel; |
UINT64 PalEntry; |
LibInitSalAndPalProc (&SalPlabel, &PalEntry); |
} |
/trunk/boot/arch/ia64/loader/gefi/lib/ia64/palproc.h |
---|
0,0 → 1,60 |
// |
// |
// Copyright (c) 1996-99 Intel Corp. |
// All Rights Reserved |
// |
// INTEL CORPORATION PROPRIETARY INFORMATION |
// |
// This software is supplied under the terms of a license |
// agreement or nondisclosure agreement with Intel Corpo- |
// ration and may not be copied or disclosed except in |
// accordance with the terms of that agreement. |
// |
// |
// |
//Module Name: |
// |
// palproc.h |
// |
//Abstract: |
// |
// This module contains generic macros for an IA64 assembly writer. |
// |
// |
//Revision History |
// |
#ifndef _PALPROC_H |
#define _PALPROC_H |
#define PROCEDURE_ENTRY(name) .##text; \ |
.##type name, @function; \ |
.##global name; \ |
.##proc name; \ |
name: |
#define PROCEDURE_EXIT(name) .##endp name |
// Note: use of NESTED_SETUP requires number of locals (l) >= 3 |
#define NESTED_SETUP(i,l,o,r) \ |
alloc loc1=ar##.##pfs,i,l,o,r ;\ |
mov loc0=b0 |
#define NESTED_RETURN \ |
mov b0=loc0 ;\ |
mov ar##.##pfs=loc1 ;;\ |
br##.##ret##.##dpnt b0;; |
// defines needed in palproc.s |
#define PAL_MC_CLEAR_LOG 0x0015 |
#define PAL_MC_DRAIN 0x0016 |
#define PAL_MC_EXPECTED 0x0017 |
#define PAL_MC_DYNAMIC_STATE 0x0018 |
#define PAL_MC_ERROR_INFO 0x0019 |
#define PAL_MC_RESUME 0x001a |
#define PAL_MC_REGISTER_MEM 0x001b |
#endif // _PALPROC_H |
/trunk/boot/arch/ia64/loader/gefi/lib/ia64/math.c |
---|
0,0 → 1,86 |
/*++ |
Copyright (c) 1998 Intel Corporation |
Module Name: |
math.c |
Abstract: |
Revision History |
--*/ |
#include "lib.h" |
// |
// Declare runtime functions |
// |
#ifdef RUNTIME_CODE |
#pragma RUNTIME_CODE(LShiftU64) |
#pragma RUNTIME_CODE(RShiftU64) |
#pragma RUNTIME_CODE(MultU64x32) |
#pragma RUNTIME_CODE(DivU64x32) |
#endif |
// |
// |
// |
UINT64 |
LShiftU64 ( |
IN UINT64 Operand, |
IN UINTN Count |
) |
// Left shift 64bit by 32bit and get a 64bit result |
{ |
return Operand << Count; |
} |
UINT64 |
RShiftU64 ( |
IN UINT64 Operand, |
IN UINTN Count |
) |
// Right shift 64bit by 32bit and get a 64bit result |
{ |
return Operand >> Count; |
} |
UINT64 |
MultU64x32 ( |
IN UINT64 Multiplicand, |
IN UINTN Multiplier |
) |
// Multiple 64bit by 32bit and get a 64bit result |
{ |
return Multiplicand * Multiplier; |
} |
UINT64 |
DivU64x32 ( |
IN UINT64 Dividend, |
IN UINTN Divisor, |
OUT UINTN *Remainder OPTIONAL |
) |
// divide 64bit by 32bit and get a 64bit result |
// N.B. only works for 31bit divisors!! |
{ |
ASSERT (Divisor != 0); |
if (Remainder) { |
*Remainder = Dividend % Divisor; |
} |
return Dividend / Divisor; |
} |
/trunk/boot/arch/ia64/loader/gefi/lib/ia64/salpal.c |
---|
0,0 → 1,335 |
/*++ |
Copyright (c) 1999 Intel Corporation |
Module Name: |
salpal.c |
Abstract: |
Functions to make SAL and PAL proc calls |
Revision History |
--*/ |
#include "lib.h" |
#include "palproc.h" |
#include "salproc.h" |
/*++ |
Copyright (c) 1999 Intel Corporation |
Module Name: |
EfiRtLib.h |
Abstract: |
EFI Runtime library functions |
Revision History |
--*/ |
#include "efi.h" |
#include "efilib.h" |
rArg |
MakeStaticPALCall ( |
IN UINT64 PALPROCPtr, |
IN UINT64 Arg1, |
IN UINT64 Arg2, |
IN UINT64 Arg3, |
IN UINT64 Arg4 |
); |
rArg |
MakeStackedPALCall ( |
IN UINT64 PALPROCPtr, |
IN UINT64 Arg1, |
IN UINT64 Arg2, |
IN UINT64 Arg3, |
IN UINT64 Arg4 |
); |
PLABEL SalProcPlabel; |
PLABEL PalProcPlabel; |
CALL_SAL_PROC GlobalSalProc; |
CALL_PAL_PROC GlobalPalProc; |
VOID |
LibInitSalAndPalProc ( |
OUT PLABEL *SalPlabel, |
OUT UINT64 *PalEntry |
) |
{ |
SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; |
EFI_STATUS Status; |
GlobalSalProc = NULL; |
GlobalPalProc = NULL; |
Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID **)&SalSystemTable); |
if (EFI_ERROR(Status)) { |
return; |
} |
// |
// BugBug: Add code to test checksum on the Sal System Table |
// |
if (SalSystemTable->Entry0.Type != 0) { |
return; |
} |
SalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.SalProcEntry; |
SalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer; |
GlobalSalProc = (CALL_SAL_PROC)&SalProcPlabel.ProcEntryPoint; |
// |
// Need to check the PAL spec to make sure I'm not responsible for |
// storing more state. |
// We are passing in a Plabel that should be ignorred by the PAL. Call |
// this way will cause use to retore our gp after the PAL returns. |
// |
PalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.PalProcEntry; |
PalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer; |
GlobalPalProc = (CALL_PAL_PROC)PalProcPlabel.ProcEntryPoint; |
*PalEntry = PalProcPlabel.ProcEntryPoint; |
*SalPlabel = SalProcPlabel; |
} |
EFI_STATUS |
LibGetSalIoPortMapping ( |
OUT UINT64 *IoPortMapping |
) |
/*++ |
Get the IO Port Map from the SAL System Table. |
DO NOT USE THIS TO DO YOU OWN IO's!!!!!!!!!!!! |
Only use this for getting info, or initing the built in EFI IO abstraction. |
Always use the EFI Device IO protoocl to access IO space. |
--*/ |
{ |
SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; |
SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc; |
EFI_STATUS Status; |
Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID **)&SalSystemTable); |
if (EFI_ERROR(Status)) { |
return EFI_UNSUPPORTED; |
} |
// |
// BugBug: Add code to test checksum on the Sal System Table |
// |
if (SalSystemTable->Entry0.Type != 0) { |
return EFI_UNSUPPORTED; |
} |
// |
// The SalSystemTable pointer includes the Type 0 entry. |
// The SalMemDesc is Type 1 so it comes next. |
// |
SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1); |
while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) { |
if (SalMemDesc->MemoryType == SAL_IO_PORT_MAPPING) { |
*IoPortMapping = SalMemDesc->PhysicalMemoryAddress; |
return EFI_SUCCESS; |
} |
SalMemDesc++; |
} |
return EFI_UNSUPPORTED; |
} |
EFI_STATUS |
LibGetSalIpiBlock ( |
OUT UINT64 *IpiBlock |
) |
/*++ |
Get the IPI block from the SAL system table |
--*/ |
{ |
SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; |
SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc; |
EFI_STATUS Status; |
Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID*)&SalSystemTable); |
if (EFI_ERROR(Status)) { |
return EFI_UNSUPPORTED; |
} |
// |
// BugBug: Add code to test checksum on the Sal System Table |
// |
if (SalSystemTable->Entry0.Type != 0) { |
return EFI_UNSUPPORTED; |
} |
// |
// The SalSystemTable pointer includes the Type 0 entry. |
// The SalMemDesc is Type 1 so it comes next. |
// |
SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1); |
while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) { |
if (SalMemDesc->MemoryType == SAL_SAPIC_IPI_BLOCK ) { |
*IpiBlock = SalMemDesc->PhysicalMemoryAddress; |
return EFI_SUCCESS; |
} |
SalMemDesc++; |
} |
return EFI_UNSUPPORTED; |
} |
EFI_STATUS |
LibGetSalWakeupVector ( |
OUT UINT64 *WakeVector |
) |
/*++ |
Get the wakeup vector from the SAL system table |
--*/ |
{ |
SAL_ST_AP_WAKEUP_DECRIPTOR *ApWakeUp; |
ApWakeUp = LibSearchSalSystemTable (SAL_ST_AP_WAKEUP); |
if (!ApWakeUp) { |
*WakeVector = -1; |
return EFI_UNSUPPORTED; |
} |
*WakeVector = ApWakeUp->ExternalInterruptVector; |
return EFI_SUCCESS; |
} |
VOID * |
LibSearchSalSystemTable ( |
IN UINT8 EntryType |
) |
{ |
EFI_STATUS Status; |
UINT8 *SalTableHack; |
SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; |
UINT16 EntryCount; |
UINT16 Count; |
Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID*)&SalSystemTable); |
if (EFI_ERROR(Status)) { |
return NULL; |
} |
EntryCount = SalSystemTable->Header.EntryCount; |
if (EntryCount == 0) { |
return NULL; |
} |
// |
// BugBug: Add code to test checksum on the Sal System Table |
// |
SalTableHack = (UINT8 *)&SalSystemTable->Entry0; |
for (Count = 0; Count < EntryCount ;Count++) { |
if (*SalTableHack == EntryType) { |
return (VOID *)SalTableHack; |
} |
switch (*SalTableHack) { |
case SAL_ST_ENTRY_POINT: |
SalTableHack += 48; |
break; |
case SAL_ST_MEMORY_DESCRIPTOR: |
SalTableHack += 32; |
break; |
case SAL_ST_PLATFORM_FEATURES: |
SalTableHack += 16; |
break; |
case SAL_ST_TR_USAGE: |
SalTableHack += 32; |
break; |
case SAL_ST_PTC: |
SalTableHack += 16; |
break; |
case SAL_ST_AP_WAKEUP: |
SalTableHack += 16; |
break; |
default: |
ASSERT(FALSE); |
break; |
} |
} |
return NULL; |
} |
VOID |
LibSalProc ( |
IN UINT64 Arg1, |
IN UINT64 Arg2, |
IN UINT64 Arg3, |
IN UINT64 Arg4, |
IN UINT64 Arg5, |
IN UINT64 Arg6, |
IN UINT64 Arg7, |
IN UINT64 Arg8, |
OUT rArg *Results OPTIONAL |
) |
{ |
rArg ReturnValue; |
ReturnValue.p0 = -3; // SAL status return completed with error |
if (GlobalSalProc) { |
ReturnValue = GlobalSalProc(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); |
} |
if (Results) { |
CopyMem (Results, &ReturnValue, sizeof(rArg)); |
} |
} |
VOID |
LibPalProc ( |
IN UINT64 Arg1, // Pal Proc index |
IN UINT64 Arg2, |
IN UINT64 Arg3, |
IN UINT64 Arg4, |
OUT rArg *Results OPTIONAL |
) |
{ |
rArg ReturnValue; |
ReturnValue.p0 = -3; // PAL status return completed with error |
// |
// check for valid PalProc entry point |
// |
if (!GlobalPalProc) { |
if (Results) |
CopyMem (Results, &ReturnValue, sizeof(rArg)); |
return; |
} |
// |
// check if index falls within stacked or static register calling conventions |
// and call appropriate Pal stub call |
// |
if (((Arg1 >=255) && (Arg1 <=511)) || |
((Arg1 >=768) && (Arg1 <=1023))) { |
ReturnValue = MakeStackedPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4); |
} |
else { |
ReturnValue = MakeStaticPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4); |
} |
if (Results) |
CopyMem (Results, &ReturnValue, sizeof(rArg)); |
return; |
} |