From 3ec2611d34aec117fec295ab55dbf62363a7a7a9 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Thu, 14 Dec 2006 10:14:24 +0000 Subject: Merge R8->R9 tracker 5935 and 7080 to update runtime arch protocol to DxeCis 0.91. Update DxeCore and Runtime driver to follow new definitions. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2101 6f19259b-4bc3-4df7-8a09-765794883524 --- EdkModulePkg/Core/Dxe/DxeMain.h | 43 +-- EdkModulePkg/Core/Dxe/DxeMain/DxeMain.c | 43 ++- EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c | 30 ++ EdkModulePkg/Core/Dxe/Event/event.c | 59 +--- EdkModulePkg/Core/Dxe/Event/execdata.c | 4 - EdkModulePkg/Core/Dxe/Exec.h | 3 +- EdkModulePkg/Core/Dxe/Image.h | 6 +- EdkModulePkg/Core/Dxe/Image/Image.c | 124 +++----- EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c | 22 ++ .../Universal/Runtime/RuntimeDxe/PeHotRelocate.c | 53 ---- .../Universal/Runtime/RuntimeDxe/Runtime.c | 323 ++++++++------------- .../Universal/Runtime/RuntimeDxe/Runtime.h | 160 +++++++--- .../Universal/Runtime/RuntimeDxe/Runtime.msa | 10 +- 13 files changed, 377 insertions(+), 503 deletions(-) delete mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c (limited to 'EdkModulePkg') diff --git a/EdkModulePkg/Core/Dxe/DxeMain.h b/EdkModulePkg/Core/Dxe/DxeMain.h index 4ff23f3b0b..28c805703a 100644 --- a/EdkModulePkg/Core/Dxe/DxeMain.h +++ b/EdkModulePkg/Core/Dxe/DxeMain.h @@ -130,6 +130,7 @@ extern EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage; extern EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1]; extern BOOLEAN gDispatcherRunning; +extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate; // // Service Initialization Functions @@ -315,27 +316,6 @@ Returns: --*/ ; -EFI_STATUS -CoreShutdownEventServices ( - VOID - ) -/*++ - -Routine Description: - - Register all runtime events to make sure they are still available after ExitBootService. - -Arguments: - - None - -Returns: - - EFI_SUCCESS - Always return success - ---*/ -; - EFI_STATUS CoreInitializeImageServices ( IN VOID *HobStart @@ -358,27 +338,6 @@ Returns: --*/ ; -EFI_STATUS -CoreShutdownImageServices ( - VOID - ) -/*++ - -Routine Description: - - Transfer control of runtime images to runtime service - -Arguments: - - None - -Returns: - - EFI_SUCCESS - Function successfully returned - ---*/ -; - VOID CoreNotifyOnArchProtocolInstallation ( VOID diff --git a/EdkModulePkg/Core/Dxe/DxeMain/DxeMain.c b/EdkModulePkg/Core/Dxe/DxeMain/DxeMain.c index 5e5b95af38..6b1f084e77 100644 --- a/EdkModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/EdkModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -157,7 +157,7 @@ EFI_METRONOME_ARCH_PROTOCOL *gMetronome = NULL; EFI_TIMER_ARCH_PROTOCOL *gTimer = NULL; EFI_BDS_ARCH_PROTOCOL *gBds = NULL; EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer = NULL; -EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = NULL; + // // BugBug: I'n not runtime, but is the PPI? @@ -324,6 +324,26 @@ EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = { #endif }; +EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate = { + INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.ImageHead), + INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.EventHead), + + // + // Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will + // prevent people from having pointer math bugs in their code. + // now you have to use *DescriptorSize to make things work. + // + sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)), + EFI_MEMORY_DESCRIPTOR_VERSION, + 0, + NULL, + NULL, + FALSE, + FALSE +}; + +EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = &gRuntimeTemplate; + // // DXE Core Global Variables for the EFI System Table, Boot Services Table, // DXE Services Table, and Runtime Services Table @@ -886,11 +906,11 @@ CoreExitBootServices ( Routine Description: - EFI 1.0 API to terminate Boot Services + Terminates all boot services. Arguments: - ImageHandle - Handle that represents the identity of the calling image + ImageHandle - Handle that identifies the exiting image. MapKey -Key to the latest memory map. @@ -926,16 +946,6 @@ Returns: // gCpu->DisableInterrupt (gCpu); - // - // Register Runtime events with the Runtime Architectural Protocol - // - CoreShutdownEventServices (); - - // - // Register Runtime images with the Runtime Architectural Protocol - // - CoreShutdownImageServices (); - // // Report that ExitBootServices() has been called // @@ -964,7 +974,12 @@ Returns: // SetMem (gBS, sizeof (EFI_BOOT_SERVICES), 0); gBS = NULL; - + + // + // Update the AtRuntime field in Runtiem AP. + // + gRuntime->AtRuntime = TRUE; + return Status; } diff --git a/EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c b/EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c index 0ceb82d2c2..a4d653c5aa 100644 --- a/EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c +++ b/EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c @@ -128,6 +128,8 @@ Returns: ARCHITECTURAL_PROTOCOL_ENTRY *Entry; VOID *Protocol; BOOLEAN Found; + LIST_ENTRY *Link; + LIST_ENTRY TempLinkNode; Found = FALSE; for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) { @@ -160,6 +162,34 @@ Returns: // When runtime architectural protocol is available, updates CRC32 in the Debug Table // CoreUpdateDebugTableCrc32 (); + + // + // Update the Runtime Architectural protocol with the template that the core was + // using so there would not need to be a dependency on the Runtime AP + // + + // + // Copy all the registered Image to new gRuntime protocol + // + for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) { + CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY)); + InsertTailList (&gRuntime->ImageHead, Link); + } + // + // Copy all the registered Event to new gRuntime protocol + // + for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) { + CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY)); + InsertTailList (&gRuntime->EventHead, Link); + } + + // + // Clean up gRuntimeTemplate + // + gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead; + gRuntimeTemplate.ImageHead.BackLink = &gRuntimeTemplate.ImageHead; + gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead; + gRuntimeTemplate.EventHead.BackLink = &gRuntimeTemplate.EventHead; } } diff --git a/EdkModulePkg/Core/Dxe/Event/event.c b/EdkModulePkg/Core/Dxe/Event/event.c index ade810c5c1..08cff427ff 100644 --- a/EdkModulePkg/Core/Dxe/Event/event.c +++ b/EdkModulePkg/Core/Dxe/Event/event.c @@ -168,50 +168,6 @@ Returns: } -EFI_STATUS -CoreShutdownEventServices ( - VOID - ) -/*++ - -Routine Description: - - Register all runtime events to make sure they are still available after ExitBootService. - -Arguments: - - None - -Returns: - - EFI_SUCCESS - Always return success. - ---*/ -{ - LIST_ENTRY *Link; - IEVENT *Event; - - // - // The Runtime AP is required for the core to function! - // - ASSERT (gRuntime != NULL); - - for (Link = mRuntimeEventList.ForwardLink; Link != &mRuntimeEventList; Link = Link->ForwardLink) { - Event = CR (Link, IEVENT, RuntimeLink, EVENT_SIGNATURE); - gRuntime->RegisterEvent ( - gRuntime, - Event->Type, - Event->NotifyTpl, - Event->NotifyFunction, - Event->NotifyContext, - (VOID **)Event - ); - } - - return EFI_SUCCESS; -} - - VOID CoreDispatchEventNotifies ( IN EFI_TPL Priority @@ -559,7 +515,12 @@ Returns: // // Keep a list of all RT events so we can tell the RT AP. // - InsertTailList (&mRuntimeEventList, &IEvent->RuntimeLink); + IEvent->RuntimeData.Type = Type; + IEvent->RuntimeData.NotifyTpl = NotifyTpl; + IEvent->RuntimeData.NotifyFunction = NotifyFunction; + IEvent->RuntimeData.NotifyContext = (VOID *) NotifyContext; + IEvent->RuntimeData.Event = (EFI_EVENT *) IEvent; + InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link); } CoreAcquireEventLock (); @@ -835,11 +796,11 @@ Returns: // // If the event is queued somewhere, remove it // - - if (Event->RuntimeLink.ForwardLink != NULL) { - RemoveEntryList (&Event->RuntimeLink); + + if (Event->RuntimeData.Link.ForwardLink != NULL) { + RemoveEntryList (&Event->RuntimeData.Link); } - + if (Event->NotifyLink.ForwardLink != NULL) { RemoveEntryList (&Event->NotifyLink); } diff --git a/EdkModulePkg/Core/Dxe/Event/execdata.c b/EdkModulePkg/Core/Dxe/Event/execdata.c index e7a11c2400..6e9b68b8be 100644 --- a/EdkModulePkg/Core/Dxe/Event/execdata.c +++ b/EdkModulePkg/Core/Dxe/Event/execdata.c @@ -49,7 +49,3 @@ UINTN gEventPending = 0; // LIST_ENTRY gEventSignalQueue = INITIALIZE_LIST_HEAD_VARIABLE (gEventSignalQueue); -// -// LIST of runtime events that need to be fired by RT AP. -// -LIST_ENTRY mRuntimeEventList = INITIALIZE_LIST_HEAD_VARIABLE (mRuntimeEventList); diff --git a/EdkModulePkg/Core/Dxe/Exec.h b/EdkModulePkg/Core/Dxe/Exec.h index e7b0f7b660..376c381459 100644 --- a/EdkModulePkg/Core/Dxe/Exec.h +++ b/EdkModulePkg/Core/Dxe/Exec.h @@ -56,7 +56,7 @@ typedef struct { // // A list of all runtime events // - LIST_ENTRY RuntimeLink; + EFI_RUNTIME_EVENT_ENTRY RuntimeData; // // Information by event type @@ -204,6 +204,5 @@ extern UINTN gEventPending; extern LIST_ENTRY gEventQueue[]; extern LIST_ENTRY gEventSignalQueue; extern UINT8 gHSB[]; -extern LIST_ENTRY mRuntimeEventList; #endif diff --git a/EdkModulePkg/Core/Dxe/Image.h b/EdkModulePkg/Core/Dxe/Image.h index 9d3e41260c..87214d35d5 100644 --- a/EdkModulePkg/Core/Dxe/Image.h +++ b/EdkModulePkg/Core/Dxe/Image.h @@ -53,11 +53,9 @@ typedef struct { EFI_EBC_PROTOCOL *Ebc; // EBC Protocol pointer - BOOLEAN RuntimeFixupValid; // True if RT image needs fixup - VOID *RuntimeFixup; // Copy of fixup data; - LIST_ENTRY Link; // List of RT LOADED_IMAGE_PRIVATE_DATA + EFI_RUNTIME_IMAGE_ENTRY *RuntimeData; // Runtime image list - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; // PeCoffLoader ImageContext + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; // PeCoffLoader ImageContext } LOADED_IMAGE_PRIVATE_DATA; diff --git a/EdkModulePkg/Core/Dxe/Image/Image.c b/EdkModulePkg/Core/Dxe/Image/Image.c index a71c6f643a..4e6bd0843e 100644 --- a/EdkModulePkg/Core/Dxe/Image/Image.c +++ b/EdkModulePkg/Core/Dxe/Image/Image.c @@ -24,11 +24,6 @@ Abstract: // Module Globals // -// -// LIST of runtime images that need to be relocated. -// -LIST_ENTRY mRuntimeImageList = INITIALIZE_LIST_HEAD_VARIABLE (mRuntimeImageList); - LOADED_IMAGE_PRIVATE_DATA *mCurrentImage = NULL; LOAD_PE32_IMAGE_PRIVATE_DATA mLoadPe32PrivateData = { @@ -78,9 +73,7 @@ LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = { NULL, // JumpContext 0, // Machine NULL, // Ebc - FALSE, // RuntimeFixupValid - NULL, // RuntimeFixup - { NULL, NULL }, // Link + NULL, // RuntimeData }; @@ -173,52 +166,6 @@ Returns: ); } - -EFI_STATUS -CoreShutdownImageServices ( - VOID - ) -/*++ - -Routine Description: - - Transfer control of runtime images to runtime service - -Arguments: - - None - -Returns: - - EFI_SUCCESS - Function successfully returned - ---*/ -{ - LIST_ENTRY *Link; - LOADED_IMAGE_PRIVATE_DATA *Image; - - // - // The Runtime AP is required for the core to function! - // - ASSERT (gRuntime != NULL); - - for (Link = mRuntimeImageList.ForwardLink; Link != &mRuntimeImageList; Link = Link->ForwardLink) { - Image = CR (Link, LOADED_IMAGE_PRIVATE_DATA, Link, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE); - if (Image->RuntimeFixupValid) { - gRuntime->RegisterImage ( - gRuntime, - (UINT64)(UINTN)(Image->Info.ImageBase), - (EFI_SIZE_TO_PAGES ((UINTN)Image->Info.ImageSize)), - Image->RuntimeFixup - ); - } - } - - return EFI_SUCCESS; -} - - - EFI_STATUS CoreLoadPeImage ( IN VOID *Pe32Handle, @@ -253,8 +200,9 @@ Returns: --*/ { - EFI_STATUS Status; - UINTN Size; + EFI_STATUS Status; + BOOLEAN DstBufAlocated; + UINTN Size; ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext)); @@ -281,7 +229,7 @@ Returns: // // Allocate memory of the correct memory type aligned on the required image boundry // - + DstBufAlocated = FALSE; if (DstBuffer == 0) { // // Allocate Destination Buffer as caller did not pass it in @@ -308,8 +256,7 @@ Returns: if (EFI_ERROR (Status)) { return Status; } - - Image->ImageBasePage = Image->ImageContext.ImageAddress; + DstBufAlocated = TRUE; } else { // @@ -334,9 +281,9 @@ Returns: Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment); Image->ImageContext.ImageAddress = DstBuffer; - Image->ImageBasePage = Image->ImageContext.ImageAddress; } + Image->ImageBasePage = Image->ImageContext.ImageAddress; Image->ImageContext.ImageAddress = (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) & ~((UINTN)Image->ImageContext.SectionAlignment - 1); @@ -346,7 +293,7 @@ Returns: // Status = gEfiPeiPeCoffLoader->LoadImage (gEfiPeiPeCoffLoader, &Image->ImageContext); if (EFI_ERROR (Status)) { - return Status; + goto Done; } // @@ -361,13 +308,6 @@ Returns: Status = EFI_OUT_OF_RESOURCES; goto Done; } - - // - // Make a list off all the RT images so we can let the RT AP know about them - // - Image->RuntimeFixupValid = TRUE; - Image->RuntimeFixup = Image->ImageContext.FixupData; - InsertTailList (&mRuntimeImageList, &Image->Link); } } @@ -376,7 +316,7 @@ Returns: // Status = gEfiPeiPeCoffLoader->RelocateImage (gEfiPeiPeCoffLoader, &Image->ImageContext); if (EFI_ERROR (Status)) { - return Status; + goto Done; } // @@ -438,7 +378,23 @@ Returns: Image->Info.ImageSize = Image->ImageContext.ImageSize; Image->Info.ImageCodeType = Image->ImageContext.ImageCodeMemoryType; Image->Info.ImageDataType = Image->ImageContext.ImageDataMemoryType; - + if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) { + if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { + // + // Make a list off all the RT images so we can let the RT AP know about them. + // + Image->RuntimeData = CoreAllocateRuntimePool (sizeof(EFI_RUNTIME_IMAGE_ENTRY)); + if (Image->RuntimeData == NULL) { + goto Done; + } + Image->RuntimeData->ImageBase = Image->Info.ImageBase; + Image->RuntimeData->ImageSize = (UINT64) (Image->Info.ImageSize); + Image->RuntimeData->RelocationData = Image->ImageContext.FixupData; + Image->RuntimeData->Handle = Image->Handle; + InsertTailList (&gRuntime->ImageHead, &Image->RuntimeData->Link); + } + } + // // Fill in the entry point of the image if it is available // @@ -489,10 +445,19 @@ Returns: return EFI_SUCCESS; Done: + // - // Free memory + // Free memory. // - CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages); + + if (DstBufAlocated) { + CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages); + } + + if (Image->ImageContext.FixupData != NULL) { + CoreFreePool (Image->ImageContext.FixupData); + } + return Status; } @@ -1168,13 +1133,16 @@ Returns: ); } - if (Image->RuntimeFixupValid) { - // - // Remove the Image from the Runtime Image list as we are about to Free it! - // - RemoveEntryList (&Image->Link); + if (Image->RuntimeData != NULL) { + if (Image->RuntimeData->Link.ForwardLink != NULL) { + // + // Remove the Image from the Runtime Image list as we are about to Free it! + // + RemoveEntryList (&Image->RuntimeData->Link); + } + CoreFreePool (Image->RuntimeData); } - + // // Free the Image from memory // diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c index 675a5503c3..3692d978f4 100644 --- a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c +++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c @@ -41,10 +41,20 @@ RuntimeDriverCalculateCrc32 ( Routine Description: + Calculate CRC32 for target data + Arguments: + Data - The target data. + DataSize - The target data size. + CrcOut - The CRC32 for target data. + Returns: + EFI_SUCCESS - The CRC32 for target data is calculated successfully. + EFI_INVALID_PARAMETER - Some parameter is not valid, so the CRC32 is not + calculated. + --*/ { UINT32 Crc; @@ -72,10 +82,16 @@ ReverseBits ( Routine Description: + Reverse bits for 32bit data. + Arguments: + Value - the data to be reversed. + Returns: + UINT32 data reversed. + --*/ { UINTN Index; @@ -99,10 +115,16 @@ RuntimeDriverInitializeCrc32Table ( Routine Description: + Initialize CRC32 table. + Arguments: + None. + Returns: + None. + --*/ { UINTN TableEntry; diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c deleted file mode 100644 index fd980a7b6a..0000000000 --- a/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c +++ /dev/null @@ -1,53 +0,0 @@ -/*++ - -Copyright (c) 2006, 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: - - PeHotRelocate.c - -Abstract: - - ---*/ - -#include "Runtime.h" - -STATIC -VOID * -RuntimePeImageAddress ( - IN RUNTIME_IMAGE_RELOCATION_DATA *Image, - IN UINTN Address - ) -/*++ - -Routine Description: - - Converts an image address to the loaded address - -Arguments: - - Image - The relocation data of the image being loaded - - Address - The address to be converted to the loaded address - -Returns: - - NULL if the address can not be converted, otherwise, the converted address - ---*/ -{ - if (Address >= (Image->ImageSize) << EFI_PAGE_SHIFT) { - return NULL; - } - - return (CHAR8 *) ((UINTN) Image->ImageBase + Address); -} - diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c index 61dbd9c1fc..e6946bd897 100644 --- a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c +++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c @@ -55,16 +55,12 @@ Revision History: #include "Runtime.h" // -// This is a only short term solution. -// There is a change coming to the Runtime AP that -// will make it so the Runtime driver will not have to allocate any buffers. +// Global Variables // -#define MAX_RUNTIME_IMAGE_NUM (64) -#define MAX_RUNTIME_EVENT_NUM (64) -RUNTIME_IMAGE_RELOCATION_DATA mRuntimeImageBuffer[MAX_RUNTIME_IMAGE_NUM]; -RUNTIME_NOTIFY_EVENT_DATA mRuntimeEventBuffer[MAX_RUNTIME_EVENT_NUM]; -UINTN mRuntimeImageNumber; -UINTN mRuntimeEventNumber; +EFI_MEMORY_DESCRIPTOR *mVirtualMap = NULL; +UINTN mVirtualMapDescriptorSize; +UINTN mVirtualMapMaxIndex; +VOID *mMyImageBase; // // The handle onto which the Runtime Architectural Protocol instance is installed @@ -75,26 +71,23 @@ EFI_HANDLE mRuntimeHandle = NULL; // The Runtime Architectural Protocol instance produced by this driver // EFI_RUNTIME_ARCH_PROTOCOL mRuntime = { - RuntimeDriverRegisterImage, - RuntimeDriverRegisterEvent -}; - -// -// Global Variables -// -LIST_ENTRY mRelocationList = INITIALIZE_LIST_HEAD_VARIABLE(mRelocationList); -LIST_ENTRY mEventList = INITIALIZE_LIST_HEAD_VARIABLE(mEventList); -BOOLEAN mEfiVirtualMode = FALSE; -EFI_GUID mLocalEfiUgaIoProtocolGuid = EFI_UGA_IO_PROTOCOL_GUID; -EFI_MEMORY_DESCRIPTOR *mVirtualMap = NULL; -UINTN mVirtualMapDescriptorSize; -UINTN mVirtualMapMaxIndex; + INITIALIZE_LIST_HEAD_VARIABLE (mRuntime.ImageHead), + INITIALIZE_LIST_HEAD_VARIABLE (mRuntime.EventHead), -EFI_LOADED_IMAGE_PROTOCOL *mMyLoadedImage; + // + // Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will + // prevent people from having pointer math bugs in their code. + // now you have to use *DescriptorSize to make things work. + // + sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)), + EFI_MEMORY_DESCRIPTOR_VERSION, + 0, + NULL, + NULL, + FALSE, + FALSE +}; -#if (EFI_SPECIFICATION_VERSION >= 0x00020000) -STATIC EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID; -#endif // // Worker Functions // @@ -131,134 +124,30 @@ Returns: EFI_STATUS EFIAPI -RuntimeDriverRegisterImage ( - IN EFI_RUNTIME_ARCH_PROTOCOL *This, - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINTN ImageSize, - IN VOID *RelocationData - ) -/*++ - -Routine Description: - - When a SetVirtualAddressMap() is performed all the runtime images loaded by - DXE must be fixed up with the new virtual address map. To facilitate this the - Runtime Architectural Protocol needs to be informed of every runtime driver - that is registered. All the runtime images loaded by DXE should be registered - with this service by the DXE Core when ExitBootServices() is called. The - images that are registered with this service must have successfully been - loaded into memory with the Boot Service LoadImage(). As a result, no - parameter checking needs to be performed. - -Arguments: - - This - The EFI_RUNTIME_ARCH_PROTOCOL instance. - - ImageBase - Start of image that has been loaded in memory. It is either - a pointer to the DOS or PE header of the image. - - ImageSize - Size of the image in bytes. - - RelocationData - Information about the fixups that were performed on ImageBase - when it was loaded into memory. This information is needed - when the virtual mode fix-ups are reapplied so that data that - has been programmatically updated will not be fixed up. If - code updates a global variable the code is responsible for - fixing up the variable for virtual mode. - -Returns: - - EFI_SUCCESS - The ImageBase has been registered. - ---*/ -{ - RUNTIME_IMAGE_RELOCATION_DATA *RuntimeImage; - - if (mMyLoadedImage->ImageBase == (VOID *) (UINTN) ImageBase) { - // - // We don't want to relocate our selves, as we only run in physical mode. - // - return EFI_SUCCESS; - } - - RuntimeImage = &mRuntimeImageBuffer[mRuntimeImageNumber]; - mRuntimeImageNumber++; - ASSERT (mRuntimeImageNumber < MAX_RUNTIME_IMAGE_NUM); - - RuntimeImage->Valid = TRUE; - RuntimeImage->ImageBase = ImageBase; - RuntimeImage->ImageSize = ImageSize; - RuntimeImage->RelocationData = RelocationData; - - InsertTailList (&mRelocationList, &RuntimeImage->Link); - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -RuntimeDriverRegisterEvent ( - IN EFI_RUNTIME_ARCH_PROTOCOL *This, - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction, - IN VOID *NotifyContext, - IN EFI_EVENT *Event +RuntimeDriverConvertPointer ( + IN UINTN DebugDisposition, + IN OUT VOID **ConvertAddress ) /*++ Routine Description: - This function is used to support the required runtime events. Currently only - runtime events of type EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE needs to be - registered with this service. All the runtime events that exist in the DXE - Core should be registered with this service when ExitBootServices() is called. - All the events that are registered with this service must have been created - with the Boot Service CreateEvent(). As a result, no parameter checking needs - to be performed. + Determines the new virtual address that is to be used on subsequent memory accesses. Arguments: + + DebugDisposition - Supplies type information for the pointer being converted. + ConvertAddress - A pointer to a pointer that is to be fixed to be the value needed + for the new virtual address mappings being applied. - This - The EFI_RUNTIME_ARCH_PROTOCOL instance. - - Type - The same as Type passed into CreateEvent(). - - NotifyTpl - The same as NotifyTpl passed into CreateEvent(). - - NotifyFunction - The same as NotifyFunction passed into CreateEvent(). - - NotifyContext - The same as NotifyContext passed into CreateEvent(). - - Event - The EFI_EVENT returned by CreateEvent(). Event must be in - runtime memory. - -Returns: +Returns: - EFI_SUCCESS - The Event has been registered. + EFI_SUCCESS - The pointer pointed to by Address was modified. + EFI_NOT_FOUND - The pointer pointed to by Address was not found to be part + of the current memory map. This is normally fatal. + EFI_INVALID_PARAMETER - One of the parameters has an invalid value. --*/ -{ - RUNTIME_NOTIFY_EVENT_DATA *RuntimeEvent; - - RuntimeEvent = &mRuntimeEventBuffer[mRuntimeEventNumber]; - mRuntimeEventNumber++; - ASSERT (mRuntimeEventNumber < MAX_RUNTIME_EVENT_NUM); - - RuntimeEvent->Type = Type; - RuntimeEvent->NotifyTpl = NotifyTpl; - RuntimeEvent->NotifyFunction = NotifyFunction; - RuntimeEvent->NotifyContext = NotifyContext; - RuntimeEvent->Event = Event; - - InsertTailList (&mEventList, &RuntimeEvent->Link); - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -RuntimeDriverConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **ConvertAddress - ) { UINTN Address; VOID *PlabelConvertAddress; @@ -297,7 +186,7 @@ RuntimeDriverConvertPointer ( // platforms. If you get this ASSERT remove the UINTN and do a 64-bit // multiply. // - ASSERT ((VirtEntry->NumberOfPages < 0xffffffff) || (sizeof (UINTN) > 4)); + ASSERT (((UINTN) VirtEntry->NumberOfPages < 0xffffffff) || (sizeof (UINTN) > 4)); if ((VirtEntry->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) { if (Address >= VirtEntry->PhysicalStart) { @@ -339,6 +228,26 @@ EFI_STATUS RuntimeDriverConvertInternalPointer ( IN OUT VOID **ConvertAddress ) +/*++ + +Routine Description: + + Determines the new virtual address that is to be used on subsequent memory accesses + for internal pointers. + +Arguments: + + ConvertAddress - A pointer to a pointer that is to be fixed to be the value needed + for the new virtual address mappings being applied. + +Returns: + + EFI_SUCCESS - The pointer pointed to by Address was modified. + EFI_NOT_FOUND - The pointer pointed to by Address was not found to be part + of the current memory map. This is normally fatal. + EFI_INVALID_PARAMETER - One of the parameters has an invalid value. + +--*/ { return RuntimeDriverConvertPointer (0x0, ConvertAddress); } @@ -351,10 +260,36 @@ RuntimeDriverSetVirtualAddressMap ( IN UINT32 DescriptorVersion, IN EFI_MEMORY_DESCRIPTOR *VirtualMap ) +/*++ + +Routine Description: + + Changes the runtime addressing mode of EFI firmware from physical to virtual. + +Arguments: + + MemoryMapSize - The size in bytes of VirtualMap. + DescriptorSize - The size in bytes of an entry in the VirtualMap. + DescriptorVersion - The version of the structure entries in VirtualMap. + VirtualMap - An array of memory descriptors which contain new virtual + address mapping information for all runtime ranges. + +Returns: + + EFI_SUCCESS - The virtual address map has been applied. + EFI_UNSUPPORTED - EFI firmware is not at runtime, or the EFI firmware is already in + virtual address mapped mode. + EFI_INVALID_PARAMETER - DescriptorSize or DescriptorVersion is invalid. + EFI_NO_MAPPING - A virtual address was not supplied for a range in the memory + map that requires a mapping. + EFI_NOT_FOUND - A virtual address was supplied for an address that is not found + in the memory map. + +--*/ { EFI_STATUS Status; - RUNTIME_NOTIFY_EVENT_DATA *RuntimeEvent; - RUNTIME_IMAGE_RELOCATION_DATA *RuntimeImage; + EFI_RUNTIME_EVENT_ENTRY *RuntimeEvent; + EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage; LIST_ENTRY *Link; UINTN Index; UINTN Index1; @@ -369,7 +304,7 @@ RuntimeDriverSetVirtualAddressMap ( // Can only switch to virtual addresses once the memory map is locked down, // and can only set it once // - if (!EfiAtRuntime () || mEfiVirtualMode) { + if (!mRuntime.AtRuntime || mRuntime.VirtualMode) { return EFI_UNSUPPORTED; } // @@ -379,44 +314,18 @@ RuntimeDriverSetVirtualAddressMap ( return EFI_INVALID_PARAMETER; } // - // BugBug: Add code here to verify the memory map. We should - // cache a copy of the system memory map in the EFI System Table - // as a GUID pointer pair. - // - // - // Make sure all virtual translations are satisfied - // - mVirtualMapMaxIndex = MemoryMapSize / DescriptorSize; - - // - // BugBug :The following code does not work hence commented out. - // Need to be replaced by something that works. - // - // VirtEntry = VirtualMap; - // for (Index = 0; Index < mVirtualMapMaxIndex; Index++) { - // if (((VirtEntry->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) && - // (VirtEntry->VirtualStart != 0) ) { - // return EFI_NO_MAPPING; - // } - // VirtEntry = NextMemoryDescriptor(VirtEntry, DescriptorSize); - // } - // // We are now committed to go to virtual mode, so lets get to it! // - mEfiVirtualMode = TRUE; + mRuntime.VirtualMode = TRUE; // // ConvertPointer() needs this mVirtualMap to do the conversion. So set up // globals we need to parse the virtual address map. // mVirtualMapDescriptorSize = DescriptorSize; + mVirtualMapMaxIndex = MemoryMapSize / DescriptorSize; mVirtualMap = VirtualMap; - // - // Signal all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE events. - // The core call RuntimeDriverRegisterEvent() for - // every runtime event and we stored them in the mEventList - // // // Currently the bug in StatusCode/RuntimeLib has been fixed, it will // check whether in Runtime or not (this is judged by looking at @@ -428,19 +337,11 @@ RuntimeDriverSetVirtualAddressMap ( ); // - // BugBug - Commented out for now because the status code driver is not - // ready for runtime yet. The Status Code driver calls data hub with does - // a bunch of Boot Service things (locks, AllocatePool) and hangs somewhere - // on the way. - // - // ReportStatusCode ( - // EfiProgressCode, EfiMaxErrorSeverity, - // 0x03, 0x01, 12, // ReadyToBoot Progress code - // 0x00, 30, L"ConvertPointer" - // ); + // Signal all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE events. + // All runtime events are stored in a list in Runtime AP. // - for (Link = mEventList.ForwardLink; Link != &mEventList; Link = Link->ForwardLink) { - RuntimeEvent = _CR (Link, RUNTIME_NOTIFY_EVENT_DATA, Link); + for (Link = mRuntime.EventHead.ForwardLink; Link != &mRuntime.EventHead; Link = Link->ForwardLink) { + RuntimeEvent = _CR (Link, EFI_RUNTIME_EVENT_ENTRY, Link); if ((RuntimeEvent->Type & EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) { RuntimeEvent->NotifyFunction ( RuntimeEvent->Event, @@ -448,29 +349,32 @@ RuntimeDriverSetVirtualAddressMap ( ); } } + // - // Relocate runtime images. Runtime images loaded before the runtime AP was - // started will not be relocated, since they would not have gotten registered. - // This includes the code in this file. + // Relocate runtime images. All runtime images are stored in a list in Runtime AP. // - for (Link = mRelocationList.ForwardLink; Link != &mRelocationList; Link = Link->ForwardLink) { - RuntimeImage = _CR (Link, RUNTIME_IMAGE_RELOCATION_DATA, Link); - if (RuntimeImage->Valid) { + for (Link = mRuntime.ImageHead.ForwardLink; Link != &mRuntime.ImageHead; Link = Link->ForwardLink) { + RuntimeImage = _CR (Link, EFI_RUNTIME_IMAGE_ENTRY, Link); + // + // We don't want to relocate our selves, as we only run in physical mode. + // + if (mMyImageBase != RuntimeImage->ImageBase) { - VirtImageBase = RuntimeImage->ImageBase; + VirtImageBase = (EFI_PHYSICAL_ADDRESS) (UINTN) RuntimeImage->ImageBase; Status = RuntimeDriverConvertPointer (0, (VOID **) &VirtImageBase); ASSERT_EFI_ERROR (Status); PeCoffLoaderRelocateImageForRuntime ( - RuntimeImage->ImageBase, + (EFI_PHYSICAL_ADDRESS) (UINTN) RuntimeImage->ImageBase, VirtImageBase, - RuntimeImage->ImageSize, + (UINTN) RuntimeImage->ImageSize, RuntimeImage->RelocationData ); - InvalidateInstructionCacheRange ((VOID *)(UINTN)RuntimeImage->ImageBase, (UINTN)RuntimeImage->ImageSize); + InvalidateInstructionCacheRange (RuntimeImage->ImageBase, (UINTN)RuntimeImage->ImageSize); } } + // // Convert all the Runtime Services except ConvertPointer() and SetVirtualAddressMap() // and recompute the CRC-32 @@ -480,6 +384,9 @@ RuntimeDriverSetVirtualAddressMap ( RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetWakeupTime); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetWakeupTime); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->ResetSystem); +#if (EFI_SPECIFICATION_VERSION < 0x00020000) + RuntimeDriverConvertInternalPointer ((VOID **) &gRT->ReportStatusCode); +#endif RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextHighMonotonicCount); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetVariable); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetVariable); @@ -495,7 +402,7 @@ RuntimeDriverSetVirtualAddressMap ( // Convert the UGA OS Handoff Table if it is present in the Configuration Table // for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { - if (CompareGuid (&mLocalEfiUgaIoProtocolGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { + if (CompareGuid (&gEfiUgaIoProtocolGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { DriverOsHandoffHeader = gST->ConfigurationTable[Index].VendorTable; for (Index1 = 0; Index1 < DriverOsHandoffHeader->NumberOfEntries; Index1++) { DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *) @@ -511,8 +418,9 @@ RuntimeDriverSetVirtualAddressMap ( RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &(gST->ConfigurationTable[Index].VendorTable)); } + #if (EFI_SPECIFICATION_VERSION >= 0x00020000) - if (CompareGuid (&mEfiCapsuleHeaderGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { + if (CompareGuid (&gEfiCapsuleGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { CapsuleTable = gST->ConfigurationTable[Index].VendorTable; for (Index1 = 0; Index1 < CapsuleTable->CapsuleArrayNumber; Index1++) { RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &CapsuleTable->CapsulePtr[Index1]); @@ -565,7 +473,8 @@ Returns: --*/ { - EFI_STATUS Status; + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *MyLoadedImage; // // This image needs to be exclued from relocation for virtual mode, so cache @@ -574,9 +483,10 @@ Returns: Status = gBS->HandleProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, - (VOID **) &mMyLoadedImage + &MyLoadedImage ); ASSERT_EFI_ERROR (Status); + mMyImageBase = MyLoadedImage->ImageBase; // // Initialize the table used to compute 32-bit CRCs @@ -586,7 +496,7 @@ Returns: // // Fill in the entries of the EFI Boot Services and EFI Runtime Services Tables // - gBS->CalculateCrc32 = RuntimeDriverCalculateCrc32; + gBS->CalculateCrc32 = RuntimeDriverCalculateCrc32; gRT->SetVirtualAddressMap = RuntimeDriverSetVirtualAddressMap; gRT->ConvertPointer = RuntimeDriverConvertPointer; @@ -600,9 +510,6 @@ Returns: NULL ); ASSERT_EFI_ERROR (Status); - - mRuntimeImageNumber = 0; - mRuntimeEventNumber = 0; - - return Status; + + return EFI_SUCCESS; } diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h index 1aa0af5767..c2e4b39666 100644 --- a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h +++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h @@ -17,88 +17,152 @@ Abstract: Runtime Architectural Protocol as defined in the DXE CIS - This code is used to produce the EFI runtime virtual switch over + This code is used to produce the EFI runtime architectural protocol. --*/ #ifndef _RUNTIME_H_ #define _RUNTIME_H_ -// -// Data structures -// -typedef struct { - LIST_ENTRY Link; - BOOLEAN Valid; - EFI_PHYSICAL_ADDRESS ImageBase; - UINTN ImageSize; // In no. of pages - VOID *RelocationData; -} RUNTIME_IMAGE_RELOCATION_DATA; - -typedef struct { - LIST_ENTRY Link; - IN UINT32 Type; - IN EFI_TPL NotifyTpl; - IN EFI_EVENT_NOTIFY NotifyFunction; - IN VOID *NotifyContext; - IN EFI_EVENT Event; -} RUNTIME_NOTIFY_EVENT_DATA; - // // Function Prototypes // -VOID -RelocatePeImageForRuntime ( - RUNTIME_IMAGE_RELOCATION_DATA *Image - ); - EFI_STATUS EFIAPI RuntimeDriverCalculateCrc32 ( IN VOID *Data, IN UINTN DataSize, OUT UINT32 *CrcOut - ); + ) +/*++ -EFI_STATUS -EFIAPI -RuntimeDriverRegisterImage ( - IN EFI_RUNTIME_ARCH_PROTOCOL *This, - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINTN ImageSize, - IN VOID *RelocationData - ); +Routine Description: -EFI_STATUS -EFIAPI -RuntimeDriverRegisterEvent ( - IN EFI_RUNTIME_ARCH_PROTOCOL *This, - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction, - IN VOID *NotifyContext, - IN EFI_EVENT *Event - ); + Calculate CRC32 for target data + +Arguments: + + Data - The target data. + DataSize - The target data size. + CrcOut - The CRC32 for target data. + +Returns: + + EFI_SUCCESS - The CRC32 for target data is calculated successfully. + EFI_INVALID_PARAMETER - Some parameter is not valid, so the CRC32 is not + calculated. + +--*/ +; EFI_STATUS EFIAPI RuntimeDriverConvertPointer ( IN UINTN DebugDisposition, IN OUT VOID **ConvertAddress - ); + ) +/*++ + +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. + ConvertAddress - A pointer to a pointer that is to be fixed to be the value needed + for the new virtual address mappings being applied. + +Returns: + + EFI_SUCCESS - The pointer pointed to by Address was modified. + EFI_NOT_FOUND - The pointer pointed to by Address was not found to be part + of the current memory map. This is normally fatal. + EFI_INVALID_PARAMETER - One of the parameters has an invalid value. + +--*/ +; + +EFI_STATUS +EFIAPI +RuntimeDriverSetVirtualAddressMap ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ) +/*++ + +Routine Description: + + Changes the runtime addressing mode of EFI firmware from physical to virtual. + +Arguments: + + MemoryMapSize - The size in bytes of VirtualMap. + DescriptorSize - The size in bytes of an entry in the VirtualMap. + DescriptorVersion - The version of the structure entries in VirtualMap. + VirtualMap - An array of memory descriptors which contain new virtual + address mapping information for all runtime ranges. + +Returns: + + EFI_SUCCESS - The virtual address map has been applied. + EFI_UNSUPPORTED - EFI firmware is not at runtime, or the EFI firmware is already in + virtual address mapped mode. + EFI_INVALID_PARAMETER - DescriptorSize or DescriptorVersion is invalid. + EFI_NO_MAPPING - A virtual address was not supplied for a range in the memory + map that requires a mapping. + EFI_NOT_FOUND - A virtual address was supplied for an address that is not found + in the memory map. + +--*/ +; VOID RuntimeDriverInitializeCrc32Table ( VOID - ); + ) +/*++ + +Routine Description: + + Initialize CRC32 table. + +Arguments: + + None. + +Returns: + + None. + +--*/ +; EFI_STATUS EFIAPI RuntimeDriverInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable - ); + ) +/*++ + +Routine Description: + + Install Runtime AP. This code includes the EfiRuntimeLib, but it only + functions at RT in physical mode. +Arguments: + + ImageHandle - Image handle of this driver. + SystemTable - Pointer to the EFI System Table. +Returns: + + EFI_SUCEESS - Runtime Driver Architectural Protocol installed. + +--*/ +; #endif diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa index 936d81afc6..619c0980df 100644 --- a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa +++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa @@ -70,10 +70,18 @@ gEfiLoadedImageProtocolGuid - + + gEfiUgaIoProtocolGuid + + gEfiRuntimeArchProtocolGuid + + + gEfiCapsuleGuid + + EFI_SPECIFICATION_VERSION 0x00020000 EDK_RELEASE_VERSION 0x00020000 -- cgit v1.2.3