Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2725 → Rev 2726

/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;
}