diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/Runtime/Runtime.c | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/EM/Runtime/Runtime.c')
-rw-r--r-- | Core/EM/Runtime/Runtime.c | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/Core/EM/Runtime/Runtime.c b/Core/EM/Runtime/Runtime.c new file mode 100644 index 0000000..cebe355 --- /dev/null +++ b/Core/EM/Runtime/Runtime.c @@ -0,0 +1,579 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Core/Runtime/Runtime.c 23 6/16/11 9:07a Felixp $ +// +// $Revision: 23 $ +// +// $Date: 6/16/11 9:07a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Core/Runtime/Runtime.c $ +// +// 23 6/16/11 9:07a Felixp +// Enhancements(EIP 49676): +// 1. FindDescriptor: upated to ignore boot time memory map descriptors +// 2. SetVirtualAddressMap: updated to skip virtual address change +// callbacks that reside in the boot time memory. +// +// 22 9/22/10 6:57p Felixp +// Minor improvements: use InitAmiRuntimeLib instead of InitAmiLib +// +// 21 3/12/10 12:00p Felixp +// +// 20 3/12/10 10:26a Felixp +// Bug fix: Potential problems with UEFI OS. +// pST was used here even after it has been virtualized in the +// AmiLibGoVirtual. +// The local copy of the pointer is created. +// +// 19 7/08/09 12:00p Felixp +// +// 18 6/24/09 4:23p Robert +// updated comments, copyright and some coding standard items +// +// 17 5/14/09 9:34a Felixp +// New feature: SMM version of Runtime Services +// Runtime driver is updated to install SMM version of the runtime +// services table. +// +// 15 11/20/08 2:58p Felixp +// Bug fix in SetVirtualAddressMap( bug fix in the runtime images fixup +// logic ) +// +// 14 11/07/07 11:54a Felixp +// Bug fix in FindDescriptor routine +// +// 13 8/07/07 2:23p Felixp +// New StatusCodes added +// +// 7 10/27/06 10:31a Felixp +// checkpoints on begin/end of SetVirtualAddressMap added +// +// 6 10/27/06 10:15a Felixp +// Bug fixes in SetVirtualAddressMap +// +// 5 10/07/06 10:22a Felixp +// New Runtime protocol defined by DXE CIS 0.91 implemented +// (Old(DXE CIS 0.90) Runtime protocol and AMI Runtime protocols removed). +// +// 3 1/18/05 3:22p Felixp +// PrintDebugMessage renamed to Trace +// +// 14 12/23/04 9:29a Felixp +// ArchProtocols moved to Include\Protocols +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: Runtime.c +// +// Description: +// This file contains the Runtime Architectural Protocol along with +// some runtime functions that are included in the Runtime Services Table +// SetVirtualAddressMap, ConvertPointer, and CalculateCrc32. The entry +// point for the Runtime Driver also contains a call to InitParts which +// uses the RuntimeInitialize and RuntimeSmmInitialize eLinks to +// initialize other pieces of the Runtime Structure +// +//<AMI_FHDR_END> +//********************************************************************** + +//============================================================================= +// Includes +#include <Protocol/Runtime.h> +#include <Protocol/LoadedImage.h> +#include <AmiDxeLib.h> + +//============================================================================= +// Protocol Definition +EFI_RUNTIME_ARCH_PROTOCOL Runtime = +{ + {&Runtime.ImageHead,&Runtime.ImageHead}, //EFI_LIST_ENTRY ImageHead; + {&Runtime.EventHead,&Runtime.EventHead}, //EFI_LIST_ENTRY EventHead; + 0, //UINTN MemoryDescriptorSize; + 0, //UINT32 MemoryDesciptorVersion; + 0, //UINTN MemoryMapSize; + NULL, //EFI_MEMORY_DESCRIPTOR *MemoryMapPhysical; + NULL, //EFI_MEMORY_DESCRIPTOR *MemoryMapVirtual; + FALSE, //BOOLEAN VirtualMode; + FALSE //BOOLEAN AtRuntime; +} ; + + +//============================================================================= +// Module specific Global Variables + +static EFI_MEMORY_DESCRIPTOR *pMap = NULL; +static UINTN MapSize, DescSize; +static UINT32 CrcTable[256]; + +//============================================================================= +// Function Prototypes + +//this funciton is created from InitList.c template file during build process +VOID InitParts(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable); + + +EFI_STATUS SetVirtualAddressMap( + IN UINTN MemoryMapSize, IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, IN EFI_MEMORY_DESCRIPTOR *VirtualMap +); + +EFI_STATUS ConvertPointer( + IN UINTN DebugDisposition, IN VOID **Address +); + +EFI_STATUS CalculateCrc32( + IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32 +); + +VOID InitCrc(); + +//============================================================================= +// Function Definitions + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RuntimeInitialize +// +// Description: +// This function is the Initialization function for the runtime driver that is +// outside of SMM. It sets up all the pieces of the Runtime Architectural +// Protocol that exist outside of SMM +// +// Input: +// EFI_HANDLE ImageHandle - The firmware allocated handle for this driver +// EFI_SYSTEM_TABLE *SystemTable - Pointer to the UEFI SystemTable +// +// Output: +// EFI_SUCCESS +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS RuntimeInitialize( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_HANDLE Handle = NULL; + + InitAmiRuntimeLib(ImageHandle, SystemTable, NULL, NULL); + InitCrc(); + + //this funciton is created from InitList.c template file during build process + InitParts(ImageHandle, SystemTable); + + // Initialize pointers in the Runtime Services Table + pRS->SetVirtualAddressMap = SetVirtualAddressMap; + pRS->ConvertPointer = ConvertPointer; + pBS->CalculateCrc32 = CalculateCrc32; + + // install the Runtime Achitectural Protocol + pBS->InstallMultipleProtocolInterfaces( + &Handle, &gEfiRuntimeArchProtocolGuid, &Runtime, NULL + ); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: FindDescriptor +// +// Description: +// This function finds the memory descriptor that contains the pointer that +// is passed into the function. This is used by the ConvertPointer function +// to determine how to find the virtual fixup address of the pointer +// +// Input: +// VOID *p - Pointer that needs to be fixed up +// +// Output: +// EFI_MEMORY_DESCRIPTOR * - Memory descriptor that contain the pointer that is passed in +// +// Notes: +// Used only by ConvertPointer function to help it convert the pointer from +// a physical address to a virtual address +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_MEMORY_DESCRIPTOR* FindDescriptor(VOID *p) +{ + EFI_MEMORY_DESCRIPTOR *pD; + EFI_PHYSICAL_ADDRESS Address = (EFI_PHYSICAL_ADDRESS)(UINTN)p; + + if(!pMap) return NULL; + // Search for the memory descriptor that contains the address of the pointer + // that was passed in + for(pD = pMap + ;pD < (EFI_MEMORY_DESCRIPTOR*)((UINT8*)pMap + MapSize) + ;pD = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)pD + DescSize) + ) if ( (pD->Attribute & EFI_MEMORY_RUNTIME) + && pD->PhysicalStart <= Address + && pD->PhysicalStart + Shl64(pD->NumberOfPages, EFI_PAGE_SHIFT) + > Address + ) return pD; + return NULL; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SetVirtualAddressMap +// +// Description: +// This function is called by a UEFI OS. It changes the pointers for the +// Runtime Services Table and each of the function pointers and variables +// that are its elements from physical addresses to virtual addresses. +// +// Input: +// IN UINTN MemoryMapSize - Size of the Current Memory Map +// IN UINTN DescriptorSize - Size of one descriptor in the Memory Map +// IN UINT32 DescriptorVersion - Version of the MemoryDescriptor Data Structure +// IN EFI_MEMORY_DESCRIPTOR *VirtualMap - Address to the first Descriptor in the Virtual Memory Map +// +// Output: +// EFI_SUCCESS +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SetVirtualAddressMap( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap +) +{ + EFI_LIST_ENTRY *pLink; + VOID **p; + UINTN i; + UINT32 crc; + EFI_RUNTIME_IMAGE_ENTRY *pThisImageEntry; + VOID *VirtualImageBase; + + //Make a local copy of pRS or pST + //it case one of the runtime drivers linked with this module + //converts pRS or pST to virtual address in the event handler + EFI_SYSTEM_TABLE *pSTCopy = pST; + EFI_RUNTIME_SERVICES *pRSCopy = pRS; + + //SetVirtualAddressMap can only be called once + if(pMap) return EFI_UNSUPPORTED; + checkpoint(0xB0); + + //Initialize Global Variables + pMap = VirtualMap; + MapSize = MemoryMapSize; + DescSize = DescriptorSize; + + //Call Event notification funcitons + for(pLink = Runtime.EventHead.ForwardLink; pLink != &Runtime.EventHead; pLink = pLink->ForwardLink) + { + EFI_RUNTIME_EVENT_ENTRY *pEvent = OUTTER(pLink, Link, EFI_RUNTIME_EVENT_ENTRY); + if (!pEvent->NotifyFunction) continue; + //Let's see if the notification function we about to call is a runtime function + if (!FindDescriptor(pEvent->NotifyFunction)){ + TRACE((TRACE_DXE_CORE,"ERROR: Virtual address change callback at address %X resides in the boot time memory\n",pEvent->NotifyFunction)); + ASSERT(FALSE); + continue; + } + ASSERT(!pEvent->NotifyContext || FindDescriptor(pEvent->NotifyFunction)); + pEvent->NotifyFunction(*pEvent->Event, pEvent->NotifyContext); + } + + //Fixup runtime images + for(pLink = Runtime.ImageHead.ForwardLink; pLink != &Runtime.ImageHead; pLink = pLink->ForwardLink) + { + EFI_RUNTIME_IMAGE_ENTRY *pImage = OUTTER(pLink, Link, EFI_RUNTIME_IMAGE_ENTRY); + //skip this image; it will be fixed up later + if (TheImageHandle == pImage->Handle){ + pThisImageEntry = pImage; + continue; + } + VirtualImageBase = pImage->ImageBase; + ConvertPointer(0, &VirtualImageBase); + ReallocatePeImage(pImage->ImageBase, VirtualImageBase, pImage->RelocationData); + } + //Fixup RuntimeServices + for(p = (VOID**)((UINT8*)pRSCopy + sizeof(pRSCopy->Hdr)); p < (VOID**)(pRSCopy + 1); p++) + ConvertPointer(0, p); + //Fixup Configuration Table + for(i = 0; i < pSTCopy->NumberOfTableEntries; i++) + ConvertPointer(0, &pSTCopy->ConfigurationTable[i].VendorTable); + //Fixup SystemTable + ConvertPointer(0, &pSTCopy->ConfigurationTable); + ConvertPointer(0, &pSTCopy->RuntimeServices); + ConvertPointer(0, &pSTCopy->FirmwareVendor); + // Update CRC32 of the System Tables + pRSCopy->Hdr.CRC32 = 0; crc = 0; + CalculateCrc32(pRSCopy, sizeof(*pRSCopy), &crc); + pRSCopy->Hdr.CRC32 = crc; + pSTCopy->Hdr.CRC32 = 0; crc = 0; + CalculateCrc32(pSTCopy, sizeof(*pSTCopy), &crc); + pSTCopy->Hdr.CRC32 = crc; + + //finally, fixup ourself + VirtualImageBase = pThisImageEntry->ImageBase; + ConvertPointer(0, &VirtualImageBase); + ReallocatePeImage(pThisImageEntry->ImageBase, VirtualImageBase, pThisImageEntry->RelocationData); + + checkpoint(0xB1); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConvertPointer +// +// Description: +// This function converts pointers from a Physical Memory Map Pointer +// to a Virtual Memory Map Pointer. Called during the SetVirtualAddressMap +// function execution. +// +// Input: +// IN UINTN DebugDisposition - If set as EFI_OPTIONAL_POINTER, then Address is allowed to be NULL +// IN VOID **Address - Pointer to convert to a virtual address +// +// Output: +// EFI_SUCCESS - Pointer converted to Virtual Address +// EFI_INVALID_PARAMETER - DebugDisposition != EFI_OPTIONAL_POINTER and *Address == NULL +// EFI_INVALID_PARAMETER - Address == NULL +// EFI_UNSUPPORTED - Virtual Memory Map address has not be set +// EFI_NOT_FOUND - Descriptor not found that contains the address of *Address +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ConvertPointer( + IN UINTN DebugDisposition, + IN VOID **Address +) +{ + EFI_MEMORY_DESCRIPTOR *pD; + + // Check for error conditions + if(!pMap) return EFI_UNSUPPORTED; + if (!Address) return EFI_INVALID_PARAMETER; + if (!*Address) + return (DebugDisposition == EFI_OPTIONAL_PTR) ? EFI_SUCCESS : EFI_INVALID_PARAMETER; + + // find the descriptor that contains the address passed in If not found, return error + if (!(pD = FindDescriptor(*Address))) return EFI_NOT_FOUND; + + // if the descriptor is found, fixup the address to the new virtual address + *Address = (VOID*)((EFI_PHYSICAL_ADDRESS)*Address - pD->PhysicalStart + pD->VirtualStart); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitCrc +// +// Description: +// This function Initializes the CrcTable with lookup values for future +// use durning CRC32 calculations +// +// Input: +// None +// +// Output: +// None +// +// Notes: +// At the end of this function the CrcTable will be initialized with lookup +// values that make calculating CRC32 values much easier +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID InitCrc( VOID ) +{ + UINT32 i; + UINT32 j; + + for(i = 0; i < 256; i++) + { + CrcTable[i] = i; + for(j = 8; j > 0; j--) + CrcTable[i] = (CrcTable[i] & 1) + ? (CrcTable[i] >> 1)^0xedb88320 + : CrcTable[i] >> 1; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CalculateCrc32 +// +// Description: +// This function Calculates a CRC32 value using the Data Buffer that is +// and the DataSize passed in +// +// Input: +// IN VOID *Data - Pointer to the data to have the CRC function run on +// IN UINTN DataSize - Size in bytes of the Data pointed to by *Data +// +// Output: +// OUT UINT32 *Crc32 - CRC32 value calculated based on Data and Data Size +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS CalculateCrc32( + IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32 +) +{ + UINT32 i, crc = (UINT32)-1; + if (!Data || !DataSize || !Crc32) return EFI_INVALID_PARAMETER; + for(i = 0; i < DataSize; i++) crc = (crc >> 8)^CrcTable[(UINT8)crc^((UINT8*)Data)[i]]; + *Crc32 = ~crc; + return EFI_SUCCESS; +} + +//********************************************************************** +// RT SMM BEGIN +//********************************************************************** +//====================================================================== +// SMM externs +extern EFI_GUID SmmRsTableGuid; + +//====================================================================== +// SMM Function Prototypes + +//this funciton is created from InitList.c template file during build process +VOID InitParts2(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable); + + +//====================================================================== +// SMM Function Definitions +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DummySmmRtFunction +// +// Description: +// This function is a Dummy function that is used as a default function +// for the SMM instance of the Runtime Services Table +// +// Input: +// None +// +// Output: +// EFI_UNSUPPORTED +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DummySmmRtFunction(){ return EFI_UNSUPPORTED; } + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RuntimeSmmInitialize +// +// Description: +// This function initializes the SMM version of the Runtime Services Table +// +// Input: +// EFI_HANDLE ImageHandle - The firmware allocated handle for this driver +// EFI_SYSTEM_TABLE *SystemTable - Pointer to the UEFI SystemTable +// +// Output: +// EFI_STATUS - based on the return values of the SmmInstallConfigurationTable function +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS RuntimeSmmInitialize( + EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_RUNTIME_SERVICES SmmRs; + EFI_STATUS Status; + VOID **p; + + //copy header + SmmRs.Hdr = pRS->Hdr; + //Init Runtime Services function pointers with our dummy function + for(p = (VOID**)((UINT8*)&SmmRs + sizeof(SmmRs.Hdr)); p < (VOID**)(&SmmRs + 1); p++) + *p = DummySmmRtFunction; + + // install the SMM version of the Runtime Services Table SMM Configuration Table + Status = pSmst->SmmInstallConfigurationTable( + pSmst, &SmmRsTableGuid, &SmmRs, sizeof(EFI_RUNTIME_SERVICES) ); + ASSERT_EFI_ERROR(Status); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RuntimeEntry +// +// Description: +// This function is the entry point for the Runtime Driver. It initializes +// the AMI Library and then it calls the Initialization functions for both +// the SMM and NON-SMM versions of the Runtime Driver. It then calls the +// InitParts2 function which calls the functions in the RuntimeSmmInitialize +// eLink. +// +// Input: +// EFI_HANDLE ImageHandle - The firmware allocated handle for this driver +// EFI_SYSTEM_TABLE *SystemTable - Pointer to the UEFI SystemTable +// +// Output: +// EFI_STATUS - based on the return values of the InitSmmHandlerEx function +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS RuntimeEntry ( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status; + + // Initialize the AMI Library for this module + InitAmiLib(ImageHandle, SystemTable); + + // Initialize both the SMM and Non-SMM verions of the Runtime Services + Status = InitSmmHandlerEx( + ImageHandle, SystemTable, RuntimeSmmInitialize, RuntimeInitialize + ); + InitParts2(ImageHandle, SystemTable); + return Status; +} +//********************************************************************** +// RT SMM END +//********************************************************************** + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file |