X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FUniversal%2FRuntime%2FRuntimeDxe%2FRuntime.c;h=0b6965c8a4725ededa76486fc886a6cc41fab06b;hp=61dbd9c1fc6c842338c7ff4b30a0fbcaa859669d;hb=ddb3d91caf129581e6686cd5127ca3517faca16e;hpb=92ea7f231b3948395e6348ab6e38e3467eff7a3d diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c index 61dbd9c1fc..0b6965c8a4 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 + (VOID**)&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; }