mirror of https://github.com/acidanthera/audk.git
1318 lines
31 KiB
C
1318 lines
31 KiB
C
/*++
|
||
|
||
Copyright (c) 2004 - 2005, Intel Corporation
|
||
All rights reserved. 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:
|
||
|
||
RuntimeLib.c
|
||
|
||
Abstract:
|
||
|
||
Light weight lib to support Tiano Sal drivers.
|
||
|
||
--*/
|
||
|
||
#include "Tiano.h"
|
||
#include "EfiRuntimeLib.h"
|
||
#include EFI_PROTOCOL_DEFINITION (ExtendedSalBootService)
|
||
#include EFI_PROTOCOL_DEFINITION (ExtendedSalGuid)
|
||
#include "IpfDefines.h"
|
||
#include "SalApi.h"
|
||
|
||
//
|
||
// Worker functions in EsalLib.s
|
||
//
|
||
SAL_RETURN_REGS
|
||
GetEsalEntryPoint (
|
||
VOID
|
||
);
|
||
|
||
SAL_RETURN_REGS
|
||
SetEsalPhysicalEntryPoint (
|
||
IN UINT64 EntryPoint,
|
||
IN UINT64 Gp
|
||
);
|
||
|
||
SAL_RETURN_REGS
|
||
SetEsalVirtualEntryPoint (
|
||
IN UINT64 EntryPoint,
|
||
IN UINT64 Gp
|
||
);
|
||
|
||
VOID
|
||
SalFlushCache (
|
||
IN EFI_PHYSICAL_ADDRESS Start,
|
||
IN UINT64 Length
|
||
);
|
||
|
||
//
|
||
// Module Globals. It's not valid to use these after the
|
||
// EfiRuntimeLibVirtualNotifyEvent has fired.
|
||
//
|
||
static EFI_EVENT mEfiVirtualNotifyEvent;
|
||
static EFI_RUNTIME_SERVICES *mRT;
|
||
static EFI_PLABEL mPlabel;
|
||
static EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;
|
||
static BOOLEAN mRuntimeLibInitialized = FALSE;
|
||
|
||
VOID
|
||
EFIAPI
|
||
EfiRuntimeLibVirtualNotifyEvent (
|
||
IN EFI_EVENT Event,
|
||
IN VOID *Context
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Fixup internal data so that EFI and SAL can be call in virtual mode.
|
||
Call the passed in Child Notify event and convert any pointers in
|
||
lib to virtual mode.
|
||
|
||
Arguments:
|
||
|
||
Event - The Event that is being processed
|
||
|
||
Context - Event Context
|
||
|
||
Returns:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
EFI_EVENT_NOTIFY ChildNotify;
|
||
|
||
if (Context != NULL) {
|
||
//
|
||
// Call child event
|
||
//
|
||
ChildNotify = (EFI_EVENT_NOTIFY) (UINTN) Context;
|
||
ChildNotify (Event, NULL);
|
||
}
|
||
|
||
mRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mPlabel.EntryPoint);
|
||
mRT->ConvertPointer (EFI_INTERNAL_POINTER | EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);
|
||
|
||
SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
|
||
|
||
//
|
||
// Clear out BootService globals
|
||
//
|
||
gBS = NULL;
|
||
gST = NULL;
|
||
mRT = NULL;
|
||
|
||
//
|
||
// Pointers don't work you must use a direct lib call
|
||
//
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiInitializeRuntimeDriverLib (
|
||
IN EFI_HANDLE ImageHandle,
|
||
IN EFI_SYSTEM_TABLE *SystemTable,
|
||
IN EFI_EVENT_NOTIFY GoVirtualChildEvent
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Intialize runtime Driver Lib if it has not yet been initialized.
|
||
|
||
Arguments:
|
||
|
||
ImageHandle - The firmware allocated handle for the EFI image.
|
||
|
||
SystemTable - A pointer to the EFI System Table.
|
||
|
||
GoVirtualChildEvent - Caller can register a virtual notification event.
|
||
|
||
Returns:
|
||
|
||
EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
|
||
|
||
--*/
|
||
{
|
||
EFI_STATUS Status;
|
||
EFI_PLABEL *Plabel;
|
||
|
||
if (mRuntimeLibInitialized) {
|
||
return EFI_ALREADY_STARTED;
|
||
}
|
||
|
||
mRuntimeLibInitialized = TRUE;
|
||
|
||
gST = SystemTable;
|
||
gBS = SystemTable->BootServices;
|
||
mRT = SystemTable->RuntimeServices;
|
||
Status = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
|
||
ASSERT_EFI_ERROR (Status);
|
||
|
||
//
|
||
// The protocol contains a function pointer, which is an indirect procedure call.
|
||
// An indirect procedure call goes through a plabel, and pointer to a function is
|
||
// a pointer to a plabel. To implement indirect procedure calls that can work in
|
||
// both physical and virtual mode, two plabels are required (one physical and one
|
||
// virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
|
||
// away. We cache it in a module global, so we can register the vitrual version.
|
||
//
|
||
Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);
|
||
ASSERT_EFI_ERROR (Status);
|
||
|
||
Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;
|
||
|
||
mPlabel.EntryPoint = Plabel->EntryPoint;
|
||
mPlabel.GP = Plabel->GP;
|
||
|
||
SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
|
||
|
||
//
|
||
// Create a Virtual address change notification event. Pass in the callers
|
||
// GoVirtualChildEvent so it's get passed to the event as contex.
|
||
//
|
||
Status = gBS->CreateEvent (
|
||
EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
|
||
EFI_TPL_NOTIFY,
|
||
EfiRuntimeLibVirtualNotifyEvent,
|
||
(VOID *) GoVirtualChildEvent,
|
||
&mEfiVirtualNotifyEvent
|
||
);
|
||
ASSERT_EFI_ERROR (Status);
|
||
|
||
return EFI_SUCCESS;
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiShutdownRuntimeDriverLib (
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine will free some resources which have been allocated in
|
||
EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error,
|
||
it must call this routine to free the allocated resource before the exiting.
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Returns:
|
||
|
||
EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully
|
||
EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all
|
||
|
||
--*/
|
||
{
|
||
EFI_STATUS Status;
|
||
|
||
if (!mRuntimeLibInitialized) {
|
||
//
|
||
// You must call EfiInitializeRuntimeDriverLib() first
|
||
//
|
||
return EFI_UNSUPPORTED;
|
||
}
|
||
|
||
mRuntimeLibInitialized = FALSE;
|
||
|
||
//
|
||
// Close SetVirtualAddressMap () notify function
|
||
//
|
||
Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);
|
||
ASSERT_EFI_ERROR (Status);
|
||
|
||
return EFI_SUCCESS;
|
||
}
|
||
|
||
EFI_STATUS
|
||
RegisterEsalFunction (
|
||
IN UINT64 FunctionId,
|
||
IN EFI_GUID *ClassGuid,
|
||
IN SAL_INTERNAL_EXTENDED_SAL_PROC Function,
|
||
IN VOID *ModuleGlobal
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Register ESAL Class Function and it's asociated global.
|
||
This function is boot service only!
|
||
|
||
Arguments:
|
||
FunctionId - ID of function to register
|
||
ClassGuid - GUID of function class
|
||
Function - Function to register under ClassGuid/FunctionId pair
|
||
ModuleGlobal - Module global for Function.
|
||
|
||
Returns:
|
||
EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
|
||
|
||
--*/
|
||
{
|
||
return mEsalBootService->AddExtendedSalProc (
|
||
mEsalBootService,
|
||
ClassGuid,
|
||
FunctionId,
|
||
Function,
|
||
ModuleGlobal
|
||
);
|
||
}
|
||
|
||
EFI_STATUS
|
||
RegisterEsalClass (
|
||
IN EFI_GUID *ClassGuid,
|
||
IN VOID *ModuleGlobal,
|
||
...
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Register ESAL Class and it's asociated global.
|
||
This function is boot service only!
|
||
|
||
Arguments:
|
||
ClassGuid - GUID of function class
|
||
ModuleGlobal - Module global for Function.
|
||
... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
|
||
indicates the end of the list.
|
||
|
||
Returns:
|
||
EFI_SUCCESS - All members of ClassGuid registered
|
||
|
||
--*/
|
||
{
|
||
VA_LIST Args;
|
||
EFI_STATUS Status;
|
||
SAL_INTERNAL_EXTENDED_SAL_PROC Function;
|
||
UINT64 FunctionId;
|
||
EFI_HANDLE NewHandle;
|
||
|
||
VA_START (Args, ModuleGlobal);
|
||
|
||
Status = EFI_SUCCESS;
|
||
while (!EFI_ERROR (Status)) {
|
||
Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);
|
||
if (Function == NULL) {
|
||
break;
|
||
}
|
||
|
||
FunctionId = VA_ARG (Args, UINT64);
|
||
|
||
Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal);
|
||
}
|
||
|
||
if (EFI_ERROR (Status)) {
|
||
return Status;
|
||
}
|
||
|
||
NewHandle = NULL;
|
||
return gBS->InstallProtocolInterface (
|
||
&NewHandle,
|
||
ClassGuid,
|
||
EFI_NATIVE_INTERFACE,
|
||
NULL
|
||
);
|
||
}
|
||
|
||
SAL_RETURN_REGS
|
||
EfiCallEsalService (
|
||
IN EFI_GUID *ClassGuid,
|
||
IN UINT64 FunctionId,
|
||
IN UINT64 Arg2,
|
||
IN UINT64 Arg3,
|
||
IN UINT64 Arg4,
|
||
IN UINT64 Arg5,
|
||
IN UINT64 Arg6,
|
||
IN UINT64 Arg7,
|
||
IN UINT64 Arg8
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Call module that is not linked direclty to this module. This code is IP
|
||
relative and hides the binding issues of virtual or physical calling. The
|
||
function that gets dispatched has extra arguments that include the registered
|
||
module global and a boolean flag to indicate if the system is in virutal mode.
|
||
|
||
Arguments:
|
||
ClassGuid - GUID of function
|
||
FunctionId - Function in ClassGuid to call
|
||
Arg2 - Argument 2 ClassGuid/FunctionId defined
|
||
Arg3 - Argument 3 ClassGuid/FunctionId defined
|
||
Arg4 - Argument 4 ClassGuid/FunctionId defined
|
||
Arg5 - Argument 5 ClassGuid/FunctionId defined
|
||
Arg6 - Argument 6 ClassGuid/FunctionId defined
|
||
Arg7 - Argument 7 ClassGuid/FunctionId defined
|
||
Arg8 - Argument 8 ClassGuid/FunctionId defined
|
||
|
||
Returns:
|
||
Status of ClassGuid/FuncitonId
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
SAL_EXTENDED_SAL_PROC EsalProc;
|
||
|
||
ReturnReg = GetEsalEntryPoint ();
|
||
if (ReturnReg.Status != EFI_SAL_SUCCESS) {
|
||
return ReturnReg;
|
||
}
|
||
|
||
if (ReturnReg.r11 & PSR_IT_MASK) {
|
||
//
|
||
// Virtual mode plabel to entry point
|
||
//
|
||
EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;
|
||
} else {
|
||
//
|
||
// Physical mode plabel to entry point
|
||
//
|
||
EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;
|
||
}
|
||
|
||
return EsalProc (
|
||
ClassGuid,
|
||
FunctionId,
|
||
Arg2,
|
||
Arg3,
|
||
Arg4,
|
||
Arg5,
|
||
Arg6,
|
||
Arg7,
|
||
Arg8
|
||
);
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiConvertPointer (
|
||
IN UINTN DebugDisposition,
|
||
IN OUT VOID *Address
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Determines the new virtual address that is to be used on subsequent memory accesses.
|
||
|
||
Arguments:
|
||
|
||
DebugDisposition - Supplies type information for the pointer being converted.
|
||
Address - A pointer to a pointer that is to be fixed to be the value needed
|
||
for the new virtual address mappings being applied.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
return mRT->ConvertPointer (DebugDisposition, Address);
|
||
}
|
||
|
||
BOOLEAN
|
||
EfiGoneVirtual (
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Return TRUE if SetVirtualAddressMap () has been called
|
||
|
||
Arguments:
|
||
NONE
|
||
|
||
Returns:
|
||
TRUE - If SetVirtualAddressMap () has been called
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0);
|
||
|
||
return (BOOLEAN) (ReturnReg.r9 == 1);
|
||
}
|
||
|
||
BOOLEAN
|
||
EfiAtRuntime (
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Return TRUE if ExitBootService () has been called
|
||
|
||
Arguments:
|
||
NONE
|
||
|
||
Returns:
|
||
TRUE - If ExitBootService () has been called
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0);
|
||
|
||
return (BOOLEAN) (ReturnReg.r9 == 1);
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiReportStatusCode (
|
||
IN EFI_STATUS_CODE_TYPE CodeType,
|
||
IN EFI_STATUS_CODE_VALUE Value,
|
||
IN UINT32 Instance,
|
||
IN EFI_GUID * CallerId,
|
||
IN EFI_STATUS_CODE_DATA * Data OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Status Code reporter
|
||
|
||
Arguments:
|
||
|
||
CodeType - Type of Status Code.
|
||
|
||
Value - Value to output for Status Code.
|
||
|
||
Instance - Instance Number of this status code.
|
||
|
||
CallerId - ID of the caller of this status code.
|
||
|
||
Data - Optional data associated with this status code.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_PROTOCOL_GUID;
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
|
||
ReturnReg = EfiCallEsalService (
|
||
&Guid,
|
||
StatusCode,
|
||
(UINT64) CodeType,
|
||
(UINT64) Value,
|
||
(UINT64) Instance,
|
||
(UINT64) CallerId,
|
||
(UINT64) Data,
|
||
0,
|
||
0
|
||
);
|
||
|
||
return (EFI_STATUS) ReturnReg.Status;
|
||
}
|
||
//
|
||
// Sal Reset Driver Class
|
||
//
|
||
VOID
|
||
EfiResetSystem (
|
||
IN EFI_RESET_TYPE ResetType,
|
||
IN EFI_STATUS ResetStatus,
|
||
IN UINTN DataSize,
|
||
IN CHAR16 *ResetData
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Resets the entire platform.
|
||
|
||
Arguments:
|
||
|
||
ResetType - The type of reset to perform.
|
||
ResetStatus - The status code for the reset.
|
||
DataSize - The size, in bytes, of ResetData.
|
||
ResetData - A data buffer that includes a Null-terminated Unicode string, optionally
|
||
followed by additional binary data.
|
||
|
||
Returns:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID;
|
||
|
||
EfiCallEsalService (
|
||
&Guid,
|
||
ResetSystem,
|
||
(UINT64) ResetType,
|
||
(UINT64) ResetStatus,
|
||
(UINT64) DataSize,
|
||
(UINT64) ResetData,
|
||
0,
|
||
0,
|
||
0
|
||
);
|
||
}
|
||
//
|
||
// Sal MTC Driver Class
|
||
//
|
||
EFI_STATUS
|
||
EfiGetNextHighMonotonicCount (
|
||
OUT UINT32 *HighCount
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Returns the next high 32 bits of the platform<72><6D>s monotonic counter.
|
||
|
||
Arguments:
|
||
|
||
HighCount - Pointer to returned value.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_MTC_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, GetNextHighMonotonicCount, (UINT64) HighCount, 0, 0, 0, 0, 0, 0);
|
||
return (EFI_STATUS) ReturnReg.Status;
|
||
}
|
||
//
|
||
// Sal Variable Driver Class
|
||
//
|
||
EFI_STATUS
|
||
EfiGetVariable (
|
||
IN CHAR16 *VariableName,
|
||
IN EFI_GUID * VendorGuid,
|
||
OUT UINT32 *Attributes OPTIONAL,
|
||
IN OUT UINTN *DataSize,
|
||
OUT VOID *Data
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Returns the value of a variable.
|
||
|
||
Arguments:
|
||
|
||
VariableName - A Null-terminated Unicode string that is the name of the
|
||
vendor<6F><72>s variable.
|
||
VendorGuid - A unique identifier for the vendor.
|
||
Attributes - If not NULL, a pointer to the memory location to return the
|
||
attributes bitmask for the variable.
|
||
DataSize - On input, the size in bytes of the return Data buffer.
|
||
On output the size of data returned in Data.
|
||
Data - The buffer to return the contents of the variable.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (
|
||
&Guid,
|
||
EsalGetVariable,
|
||
(UINT64) VariableName,
|
||
(UINT64) VendorGuid,
|
||
(UINT64) Attributes,
|
||
(UINT64) DataSize,
|
||
(UINT64) Data,
|
||
0,
|
||
0
|
||
);
|
||
return (EFI_STATUS) ReturnReg.Status;
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiGetNextVariableName (
|
||
IN OUT UINTN *VariableNameSize,
|
||
IN OUT CHAR16 *VariableName,
|
||
IN OUT EFI_GUID *VendorGuid
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Enumerates the current variable names.
|
||
|
||
Arguments:
|
||
|
||
VariableNameSize - The size of the VariableName buffer.
|
||
VariableName - On input, supplies the last VariableName that was returned
|
||
by GetNextVariableName().
|
||
On output, returns the Nullterminated Unicode string of the
|
||
current variable.
|
||
VendorGuid - On input, supplies the last VendorGuid that was returned by
|
||
GetNextVariableName().
|
||
On output, returns the VendorGuid of the current variable.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (
|
||
&Guid,
|
||
EsalGetNextVariableName,
|
||
(UINT64) VariableNameSize,
|
||
(UINT64) VariableName,
|
||
(UINT64) VendorGuid,
|
||
0,
|
||
0,
|
||
0,
|
||
0
|
||
);
|
||
return (EFI_STATUS) ReturnReg.Status;
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiSetVariable (
|
||
IN CHAR16 *VariableName,
|
||
IN EFI_GUID *VendorGuid,
|
||
IN UINT32 Attributes,
|
||
IN UINTN DataSize,
|
||
IN VOID *Data
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Sets the value of a variable.
|
||
|
||
Arguments:
|
||
|
||
VariableName - A Null-terminated Unicode string that is the name of the
|
||
vendor<6F><72>s variable.
|
||
VendorGuid - A unique identifier for the vendor.
|
||
Attributes - Attributes bitmask to set for the variable.
|
||
DataSize - The size in bytes of the Data buffer.
|
||
Data - The contents for the variable.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (
|
||
&Guid,
|
||
EsalSetVariable,
|
||
(UINT64) VariableName,
|
||
(UINT64) VendorGuid,
|
||
(UINT64) Attributes,
|
||
(UINT64) DataSize,
|
||
(UINT64) Data,
|
||
0,
|
||
0
|
||
);
|
||
return (EFI_STATUS) ReturnReg.Status;
|
||
}
|
||
|
||
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
|
||
|
||
EFI_STATUS
|
||
EfiQueryVariableInfo (
|
||
IN UINT32 Attributes,
|
||
OUT UINT64 *MaximumVariableStorageSize,
|
||
OUT UINT64 *RemainingVariableStorageSize,
|
||
OUT UINT64 *MaximumVariableSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This code returns information about the EFI variables.
|
||
|
||
Arguments:
|
||
|
||
Attributes Attributes bitmask to specify the type of variables
|
||
on which to return information.
|
||
MaximumVariableStorageSize Pointer to the maximum size of the storage space available
|
||
for the EFI variables associated with the attributes specified.
|
||
RemainingVariableStorageSize Pointer to the remaining size of the storage space available
|
||
for the EFI variables associated with the attributes specified.
|
||
MaximumVariableSize Pointer to the maximum size of the individual EFI variables
|
||
associated with the attributes specified.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (
|
||
&Guid,
|
||
EsalQueryVariableInfo,
|
||
(UINT64) Attributes,
|
||
(UINT64) MaximumVariableStorageSize,
|
||
(UINT64) RemainingVariableStorageSize,
|
||
(UINT64) MaximumVariableSize,
|
||
0,
|
||
0,
|
||
0
|
||
);
|
||
return (EFI_STATUS) ReturnReg.Status;
|
||
}
|
||
|
||
#endif
|
||
|
||
//
|
||
// Sal RTC Driver Class.
|
||
//
|
||
EFI_STATUS
|
||
EfiGetTime (
|
||
OUT EFI_TIME *Time,
|
||
OUT EFI_TIME_CAPABILITIES *Capabilities
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Returns the current time and date information, and the time-keeping
|
||
capabilities of the hardware platform.
|
||
|
||
Arguments:
|
||
|
||
Time - A pointer to storage to receive a snapshot of the current time.
|
||
Capabilities - An optional pointer to a buffer to receive the real time clock device<63><65>s
|
||
capabilities.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, GetTime, (UINT64) Time, (UINT64) Capabilities, 0, 0, 0, 0, 0);
|
||
return ReturnReg.Status;
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiSetTime (
|
||
OUT EFI_TIME *Time
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Sets the current local time and date information.
|
||
|
||
Arguments:
|
||
|
||
Time - A pointer to the current time.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, SetTime, (UINT64) Time, 0, 0, 0, 0, 0, 0);
|
||
return ReturnReg.Status;
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiGetWakeupTime (
|
||
OUT BOOLEAN *Enabled,
|
||
OUT BOOLEAN *Pending,
|
||
OUT EFI_TIME *Time
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Returns the current wakeup alarm clock setting.
|
||
|
||
Arguments:
|
||
|
||
Enabled - Indicates if the alarm is currently enabled or disabled.
|
||
Pending - Indicates if the alarm signal is pending and requires acknowledgement.
|
||
Time - The current alarm setting.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, GetWakeupTime, (UINT64) Enabled, (UINT64) Pending, (UINT64) Time, 0, 0, 0, 0);
|
||
return ReturnReg.Status;
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiSetWakeupTime (
|
||
IN BOOLEAN Enable,
|
||
IN EFI_TIME *Time
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Sets the system wakeup alarm clock time.
|
||
|
||
Arguments:
|
||
|
||
Enable - Enable or disable the wakeup alarm.
|
||
Time - If Enable is TRUE, the time to set the wakeup alarm for.
|
||
If Enable is FALSE, then this parameter is optional, and may be NULL.
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, SetWakeupTime, (UINT64) Enable, (UINT64) Time, 0, 0, 0, 0, 0);
|
||
return ReturnReg.Status;
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Base IO Services
|
||
//
|
||
EFI_STATUS
|
||
EfiIoRead (
|
||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||
IN UINT64 Address,
|
||
IN UINTN Count,
|
||
IN OUT VOID *Buffer
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform an IO read into Buffer.
|
||
|
||
Arguments:
|
||
Width - Width of read transaction, and repeat operation to use
|
||
Address - IO address to read
|
||
Count - Number of times to read the IO address.
|
||
Buffer - Buffer to read data into. size is Width * Count
|
||
|
||
Returns:
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, IoRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
|
||
|
||
return ReturnReg.Status;
|
||
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiIoWrite (
|
||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||
IN UINT64 Address,
|
||
IN UINTN Count,
|
||
IN OUT VOID *Buffer
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform an IO write into Buffer.
|
||
|
||
Arguments:
|
||
Width - Width of write transaction, and repeat operation to use
|
||
Address - IO address to write
|
||
Count - Number of times to write the IO address.
|
||
Buffer - Buffer to write data from. size is Width * Count
|
||
|
||
Returns:
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, IoWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
|
||
|
||
return ReturnReg.Status;
|
||
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiMemRead (
|
||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||
IN UINT64 Address,
|
||
IN UINTN Count,
|
||
IN OUT VOID *Buffer
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform a Memory mapped IO read into Buffer.
|
||
|
||
Arguments:
|
||
Width - Width of each read transaction.
|
||
Address - Memory mapped IO address to read
|
||
Count - Number of Width quanta to read
|
||
Buffer - Buffer to read data into. size is Width * Count
|
||
|
||
Returns:
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, MemRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
|
||
|
||
return ReturnReg.Status;
|
||
|
||
}
|
||
|
||
EFI_STATUS
|
||
EfiMemWrite (
|
||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||
IN UINT64 Address,
|
||
IN UINTN Count,
|
||
IN OUT VOID *Buffer
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform a memory mapped IO write into Buffer.
|
||
|
||
Arguments:
|
||
Width - Width of write transaction, and repeat operation to use
|
||
Address - IO address to write
|
||
Count - Number of times to write the IO address.
|
||
Buffer - Buffer to write data from. size is Width * Count
|
||
|
||
Returns:
|
||
Status code
|
||
|
||
--*/
|
||
{
|
||
|
||
SAL_RETURN_REGS ReturnReg;
|
||
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
|
||
|
||
ReturnReg = EfiCallEsalService (&Guid, MemWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
|
||
|
||
return ReturnReg.Status;
|
||
|
||
}
|
||
|
||
|
||
#define EFI_PCI_ADDRESS_IPF(_seg, _bus, _devfunc, _reg) \
|
||
(((_seg) << 24) | ((_bus) << 16) | ((_devfunc) << 8) | (_reg)) & 0xFFFFFFFF
|
||
|
||
//
|
||
// PCI Class Functions
|
||
//
|
||
UINT8
|
||
PciRead8 (
|
||
UINT8 Segment,
|
||
UINT8 Bus,
|
||
UINT8 DevFunc,
|
||
UINT8 Register
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform an one byte PCI config cycle read
|
||
|
||
Arguments:
|
||
Segment - PCI Segment ACPI _SEG
|
||
Bus - PCI Bus
|
||
DevFunc - PCI Device(7:3) and Func(2:0)
|
||
Register - PCI config space register
|
||
|
||
Returns:
|
||
Data read from PCI config space
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
|
||
UINT64 Address;
|
||
SAL_RETURN_REGS Return;
|
||
|
||
Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
|
||
Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 1, 0, 0, 0, 0, 0);
|
||
|
||
return (UINT8) Return.r9;
|
||
}
|
||
|
||
|
||
UINT16
|
||
PciRead16 (
|
||
UINT8 Segment,
|
||
UINT8 Bus,
|
||
UINT8 DevFunc,
|
||
UINT8 Register
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform an two byte PCI config cycle read
|
||
|
||
Arguments:
|
||
Segment - PCI Segment ACPI _SEG
|
||
Bus - PCI Bus
|
||
DevFunc - PCI Device(7:3) and Func(2:0)
|
||
Register - PCI config space register
|
||
|
||
Returns:
|
||
Data read from PCI config space
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
|
||
UINT64 Address;
|
||
SAL_RETURN_REGS Return;
|
||
|
||
Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
|
||
Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 2, 0, 0, 0, 0, 0);
|
||
|
||
return (UINT16) Return.r9;
|
||
}
|
||
|
||
UINT32
|
||
PciRead32 (
|
||
UINT8 Segment,
|
||
UINT8 Bus,
|
||
UINT8 DevFunc,
|
||
UINT8 Register
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform an four byte PCI config cycle read
|
||
|
||
Arguments:
|
||
Segment - PCI Segment ACPI _SEG
|
||
Bus - PCI Bus
|
||
DevFunc - PCI Device(7:3) and Func(2:0)
|
||
Register - PCI config space register
|
||
|
||
Returns:
|
||
Data read from PCI config space
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
|
||
UINT64 Address;
|
||
SAL_RETURN_REGS Return;
|
||
|
||
Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
|
||
Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 4, 0, 0, 0, 0, 0);
|
||
|
||
return (UINT32) Return.r9;
|
||
}
|
||
|
||
VOID
|
||
PciWrite8 (
|
||
UINT8 Segment,
|
||
UINT8 Bus,
|
||
UINT8 DevFunc,
|
||
UINT8 Register,
|
||
UINT8 Data
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform an one byte PCI config cycle write
|
||
|
||
Arguments:
|
||
Segment - PCI Segment ACPI _SEG
|
||
Bus - PCI Bus
|
||
DevFunc - PCI Device(7:3) and Func(2:0)
|
||
Register - PCI config space register
|
||
Data - Data to write
|
||
|
||
Returns:
|
||
NONE
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
|
||
UINT64 Address;
|
||
|
||
Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
|
||
EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 1, Data, 0, 0, 0, 0);
|
||
}
|
||
|
||
VOID
|
||
PciWrite16 (
|
||
UINT8 Segment,
|
||
UINT8 Bus,
|
||
UINT8 DevFunc,
|
||
UINT8 Register,
|
||
UINT16 Data
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform an two byte PCI config cycle write
|
||
|
||
Arguments:
|
||
Segment - PCI Segment ACPI _SEG
|
||
Bus - PCI Bus
|
||
DevFunc - PCI Device(7:3) and Func(2:0)
|
||
Register - PCI config space register
|
||
Data - Data to write
|
||
|
||
Returns:
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
|
||
UINT64 Address;
|
||
|
||
Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
|
||
EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 2, Data, 0, 0, 0, 0);
|
||
}
|
||
|
||
VOID
|
||
PciWrite32 (
|
||
UINT8 Segment,
|
||
UINT8 Bus,
|
||
UINT8 DevFunc,
|
||
UINT8 Register,
|
||
UINT32 Data
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Perform an four byte PCI config cycle write
|
||
|
||
Arguments:
|
||
Segment - PCI Segment ACPI _SEG
|
||
Bus - PCI Bus
|
||
DevFunc - PCI Device(7:3) and Func(2:0)
|
||
Register - PCI config space register
|
||
Data - Data to write
|
||
|
||
Returns:
|
||
NONE
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
|
||
UINT64 Address;
|
||
|
||
Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
|
||
EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 4, Data, 0, 0, 0, 0);
|
||
}
|
||
|
||
//
|
||
// Stall class functions
|
||
//
|
||
VOID
|
||
EfiStall (
|
||
IN UINTN Microseconds
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Delay for at least the request number of microseconds
|
||
|
||
Arguments:
|
||
Microseconds - Number of microseconds to delay.
|
||
|
||
Returns:
|
||
NONE
|
||
|
||
--*/
|
||
{
|
||
EFI_GUID Guid = EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID;
|
||
|
||
if (EfiAtRuntime ()) {
|
||
EfiCallEsalService (&Guid, Stall, Microseconds, 4, 0, 0, 0, 0, 0);
|
||
} else {
|
||
gBS->Stall (Microseconds);
|
||
}
|
||
}
|
||
//
|
||
// Cache Flush Routine.
|
||
//
|
||
EFI_STATUS
|
||
EfiCpuFlushCache (
|
||
IN EFI_PHYSICAL_ADDRESS Start,
|
||
IN UINT64 Length
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Flush cache with specified range.
|
||
|
||
Arguments:
|
||
|
||
Start - Start address
|
||
Length - Length in bytes
|
||
|
||
Returns:
|
||
|
||
Status code
|
||
|
||
EFI_SUCCESS - success
|
||
|
||
--*/
|
||
{
|
||
SalFlushCache (Start, Length);
|
||
return EFI_SUCCESS;
|
||
}
|