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
This commit is contained in:
lgao4 2006-12-14 10:14:24 +00:00
parent d43eee260f
commit 3ec2611d34
18 changed files with 464 additions and 616 deletions

View File

@ -130,6 +130,7 @@ extern EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage;
extern EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1]; extern EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1];
extern BOOLEAN gDispatcherRunning; extern BOOLEAN gDispatcherRunning;
extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate;
// //
// Service Initialization Functions // 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 EFI_STATUS
CoreInitializeImageServices ( CoreInitializeImageServices (
IN VOID *HobStart 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 VOID
CoreNotifyOnArchProtocolInstallation ( CoreNotifyOnArchProtocolInstallation (
VOID VOID

View File

@ -157,7 +157,7 @@ EFI_METRONOME_ARCH_PROTOCOL *gMetronome = NULL;
EFI_TIMER_ARCH_PROTOCOL *gTimer = NULL; EFI_TIMER_ARCH_PROTOCOL *gTimer = NULL;
EFI_BDS_ARCH_PROTOCOL *gBds = NULL; EFI_BDS_ARCH_PROTOCOL *gBds = NULL;
EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer = NULL; EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer = NULL;
EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = NULL;
// //
// BugBug: I'n not runtime, but is the PPI? // BugBug: I'n not runtime, but is the PPI?
@ -324,6 +324,26 @@ EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {
#endif #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 Core Global Variables for the EFI System Table, Boot Services Table,
// DXE Services Table, and Runtime Services Table // DXE Services Table, and Runtime Services Table
@ -886,11 +906,11 @@ CoreExitBootServices (
Routine Description: Routine Description:
EFI 1.0 API to terminate Boot Services Terminates all boot services.
Arguments: 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. MapKey -Key to the latest memory map.
@ -926,16 +946,6 @@ Returns:
// //
gCpu->DisableInterrupt (gCpu); 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 // Report that ExitBootServices() has been called
// //
@ -964,7 +974,12 @@ Returns:
// //
SetMem (gBS, sizeof (EFI_BOOT_SERVICES), 0); SetMem (gBS, sizeof (EFI_BOOT_SERVICES), 0);
gBS = NULL; gBS = NULL;
//
// Update the AtRuntime field in Runtiem AP.
//
gRuntime->AtRuntime = TRUE;
return Status; return Status;
} }

View File

@ -128,6 +128,8 @@ Returns:
ARCHITECTURAL_PROTOCOL_ENTRY *Entry; ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
VOID *Protocol; VOID *Protocol;
BOOLEAN Found; BOOLEAN Found;
LIST_ENTRY *Link;
LIST_ENTRY TempLinkNode;
Found = FALSE; Found = FALSE;
for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) { for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
@ -160,6 +162,34 @@ Returns:
// When runtime architectural protocol is available, updates CRC32 in the Debug Table // When runtime architectural protocol is available, updates CRC32 in the Debug Table
// //
CoreUpdateDebugTableCrc32 (); 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;
} }
} }

View File

@ -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 VOID
CoreDispatchEventNotifies ( CoreDispatchEventNotifies (
IN EFI_TPL Priority IN EFI_TPL Priority
@ -559,7 +515,12 @@ Returns:
// //
// Keep a list of all RT events so we can tell the RT AP. // 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 (); CoreAcquireEventLock ();
@ -835,11 +796,11 @@ Returns:
// //
// If the event is queued somewhere, remove it // If the event is queued somewhere, remove it
// //
if (Event->RuntimeLink.ForwardLink != NULL) { if (Event->RuntimeData.Link.ForwardLink != NULL) {
RemoveEntryList (&Event->RuntimeLink); RemoveEntryList (&Event->RuntimeData.Link);
} }
if (Event->NotifyLink.ForwardLink != NULL) { if (Event->NotifyLink.ForwardLink != NULL) {
RemoveEntryList (&Event->NotifyLink); RemoveEntryList (&Event->NotifyLink);
} }

View File

@ -49,7 +49,3 @@ UINTN gEventPending = 0;
// //
LIST_ENTRY gEventSignalQueue = INITIALIZE_LIST_HEAD_VARIABLE (gEventSignalQueue); 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);

View File

@ -56,7 +56,7 @@ typedef struct {
// //
// A list of all runtime events // A list of all runtime events
// //
LIST_ENTRY RuntimeLink; EFI_RUNTIME_EVENT_ENTRY RuntimeData;
// //
// Information by event type // Information by event type
@ -204,6 +204,5 @@ extern UINTN gEventPending;
extern LIST_ENTRY gEventQueue[]; extern LIST_ENTRY gEventQueue[];
extern LIST_ENTRY gEventSignalQueue; extern LIST_ENTRY gEventSignalQueue;
extern UINT8 gHSB[]; extern UINT8 gHSB[];
extern LIST_ENTRY mRuntimeEventList;
#endif #endif

View File

@ -53,11 +53,9 @@ typedef struct {
EFI_EBC_PROTOCOL *Ebc; // EBC Protocol pointer EFI_EBC_PROTOCOL *Ebc; // EBC Protocol pointer
BOOLEAN RuntimeFixupValid; // True if RT image needs fixup EFI_RUNTIME_IMAGE_ENTRY *RuntimeData; // Runtime image list
VOID *RuntimeFixup; // Copy of fixup data;
LIST_ENTRY Link; // List of RT LOADED_IMAGE_PRIVATE_DATA
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; // PeCoffLoader ImageContext PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; // PeCoffLoader ImageContext
} LOADED_IMAGE_PRIVATE_DATA; } LOADED_IMAGE_PRIVATE_DATA;

View File

@ -24,11 +24,6 @@ Abstract:
// Module Globals // 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; LOADED_IMAGE_PRIVATE_DATA *mCurrentImage = NULL;
LOAD_PE32_IMAGE_PRIVATE_DATA mLoadPe32PrivateData = { LOAD_PE32_IMAGE_PRIVATE_DATA mLoadPe32PrivateData = {
@ -78,9 +73,7 @@ LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = {
NULL, // JumpContext NULL, // JumpContext
0, // Machine 0, // Machine
NULL, // Ebc NULL, // Ebc
FALSE, // RuntimeFixupValid NULL, // RuntimeData
NULL, // RuntimeFixup
{ NULL, NULL }, // Link
}; };
@ -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 EFI_STATUS
CoreLoadPeImage ( CoreLoadPeImage (
IN VOID *Pe32Handle, IN VOID *Pe32Handle,
@ -253,8 +200,9 @@ Returns:
--*/ --*/
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINTN Size; BOOLEAN DstBufAlocated;
UINTN Size;
ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext)); ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext));
@ -281,7 +229,7 @@ Returns:
// //
// Allocate memory of the correct memory type aligned on the required image boundry // Allocate memory of the correct memory type aligned on the required image boundry
// //
DstBufAlocated = FALSE;
if (DstBuffer == 0) { if (DstBuffer == 0) {
// //
// Allocate Destination Buffer as caller did not pass it in // Allocate Destination Buffer as caller did not pass it in
@ -308,8 +256,7 @@ Returns:
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
DstBufAlocated = TRUE;
Image->ImageBasePage = Image->ImageContext.ImageAddress;
} else { } else {
// //
@ -334,9 +281,9 @@ Returns:
Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment); Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);
Image->ImageContext.ImageAddress = DstBuffer; Image->ImageContext.ImageAddress = DstBuffer;
Image->ImageBasePage = Image->ImageContext.ImageAddress;
} }
Image->ImageBasePage = Image->ImageContext.ImageAddress;
Image->ImageContext.ImageAddress = Image->ImageContext.ImageAddress =
(Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) & (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &
~((UINTN)Image->ImageContext.SectionAlignment - 1); ~((UINTN)Image->ImageContext.SectionAlignment - 1);
@ -346,7 +293,7 @@ Returns:
// //
Status = gEfiPeiPeCoffLoader->LoadImage (gEfiPeiPeCoffLoader, &Image->ImageContext); Status = gEfiPeiPeCoffLoader->LoadImage (gEfiPeiPeCoffLoader, &Image->ImageContext);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; goto Done;
} }
// //
@ -361,13 +308,6 @@ Returns:
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto Done; 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); Status = gEfiPeiPeCoffLoader->RelocateImage (gEfiPeiPeCoffLoader, &Image->ImageContext);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; goto Done;
} }
// //
@ -438,7 +378,23 @@ Returns:
Image->Info.ImageSize = Image->ImageContext.ImageSize; Image->Info.ImageSize = Image->ImageContext.ImageSize;
Image->Info.ImageCodeType = Image->ImageContext.ImageCodeMemoryType; Image->Info.ImageCodeType = Image->ImageContext.ImageCodeMemoryType;
Image->Info.ImageDataType = Image->ImageContext.ImageDataMemoryType; 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 // Fill in the entry point of the image if it is available
// //
@ -489,10 +445,19 @@ Returns:
return EFI_SUCCESS; return EFI_SUCCESS;
Done: 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; return Status;
} }
@ -1168,13 +1133,16 @@ Returns:
); );
} }
if (Image->RuntimeFixupValid) { 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! //
// // Remove the Image from the Runtime Image list as we are about to Free it!
RemoveEntryList (&Image->Link); //
RemoveEntryList (&Image->RuntimeData->Link);
}
CoreFreePool (Image->RuntimeData);
} }
// //
// Free the Image from memory // Free the Image from memory
// //

View File

@ -41,10 +41,20 @@ RuntimeDriverCalculateCrc32 (
Routine Description: Routine Description:
Calculate CRC32 for target data
Arguments: Arguments:
Data - The target data.
DataSize - The target data size.
CrcOut - The CRC32 for target data.
Returns: 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; UINT32 Crc;
@ -72,10 +82,16 @@ ReverseBits (
Routine Description: Routine Description:
Reverse bits for 32bit data.
Arguments: Arguments:
Value - the data to be reversed.
Returns: Returns:
UINT32 data reversed.
--*/ --*/
{ {
UINTN Index; UINTN Index;
@ -99,10 +115,16 @@ RuntimeDriverInitializeCrc32Table (
Routine Description: Routine Description:
Initialize CRC32 table.
Arguments: Arguments:
None.
Returns: Returns:
None.
--*/ --*/
{ {
UINTN TableEntry; UINTN TableEntry;

View File

@ -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);
}

View File

@ -55,16 +55,12 @@ Revision History:
#include "Runtime.h" #include "Runtime.h"
// //
// This is a only short term solution. // Global Variables
// There is a change coming to the Runtime AP that
// will make it so the Runtime driver will not have to allocate any buffers.
// //
#define MAX_RUNTIME_IMAGE_NUM (64) EFI_MEMORY_DESCRIPTOR *mVirtualMap = NULL;
#define MAX_RUNTIME_EVENT_NUM (64) UINTN mVirtualMapDescriptorSize;
RUNTIME_IMAGE_RELOCATION_DATA mRuntimeImageBuffer[MAX_RUNTIME_IMAGE_NUM]; UINTN mVirtualMapMaxIndex;
RUNTIME_NOTIFY_EVENT_DATA mRuntimeEventBuffer[MAX_RUNTIME_EVENT_NUM]; VOID *mMyImageBase;
UINTN mRuntimeImageNumber;
UINTN mRuntimeEventNumber;
// //
// The handle onto which the Runtime Architectural Protocol instance is installed // 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 // The Runtime Architectural Protocol instance produced by this driver
// //
EFI_RUNTIME_ARCH_PROTOCOL mRuntime = { EFI_RUNTIME_ARCH_PROTOCOL mRuntime = {
RuntimeDriverRegisterImage, INITIALIZE_LIST_HEAD_VARIABLE (mRuntime.ImageHead),
RuntimeDriverRegisterEvent INITIALIZE_LIST_HEAD_VARIABLE (mRuntime.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
}; };
//
// 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;
EFI_LOADED_IMAGE_PROTOCOL *mMyLoadedImage;
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
STATIC EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID;
#endif
// //
// Worker Functions // Worker Functions
// //
@ -129,136 +122,32 @@ Returns:
Hdr->CRC32 = Crc; Hdr->CRC32 = Crc;
} }
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
)
/*++
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.
Arguments:
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:
EFI_SUCCESS - The Event has been registered.
--*/
{
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 EFI_STATUS
EFIAPI EFIAPI
RuntimeDriverConvertPointer ( RuntimeDriverConvertPointer (
IN UINTN DebugDisposition, IN UINTN DebugDisposition,
IN OUT VOID **ConvertAddress 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.
--*/
{ {
UINTN Address; UINTN Address;
VOID *PlabelConvertAddress; VOID *PlabelConvertAddress;
@ -297,7 +186,7 @@ RuntimeDriverConvertPointer (
// platforms. If you get this ASSERT remove the UINTN and do a 64-bit // platforms. If you get this ASSERT remove the UINTN and do a 64-bit
// multiply. // 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 ((VirtEntry->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
if (Address >= VirtEntry->PhysicalStart) { if (Address >= VirtEntry->PhysicalStart) {
@ -339,6 +228,26 @@ EFI_STATUS
RuntimeDriverConvertInternalPointer ( RuntimeDriverConvertInternalPointer (
IN OUT VOID **ConvertAddress 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); return RuntimeDriverConvertPointer (0x0, ConvertAddress);
} }
@ -351,10 +260,36 @@ RuntimeDriverSetVirtualAddressMap (
IN UINT32 DescriptorVersion, IN UINT32 DescriptorVersion,
IN EFI_MEMORY_DESCRIPTOR *VirtualMap 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; EFI_STATUS Status;
RUNTIME_NOTIFY_EVENT_DATA *RuntimeEvent; EFI_RUNTIME_EVENT_ENTRY *RuntimeEvent;
RUNTIME_IMAGE_RELOCATION_DATA *RuntimeImage; EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage;
LIST_ENTRY *Link; LIST_ENTRY *Link;
UINTN Index; UINTN Index;
UINTN Index1; UINTN Index1;
@ -369,7 +304,7 @@ RuntimeDriverSetVirtualAddressMap (
// Can only switch to virtual addresses once the memory map is locked down, // Can only switch to virtual addresses once the memory map is locked down,
// and can only set it once // and can only set it once
// //
if (!EfiAtRuntime () || mEfiVirtualMode) { if (!mRuntime.AtRuntime || mRuntime.VirtualMode) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
// //
@ -379,44 +314,18 @@ RuntimeDriverSetVirtualAddressMap (
return EFI_INVALID_PARAMETER; 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! // 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 // ConvertPointer() needs this mVirtualMap to do the conversion. So set up
// globals we need to parse the virtual address map. // globals we need to parse the virtual address map.
// //
mVirtualMapDescriptorSize = DescriptorSize; mVirtualMapDescriptorSize = DescriptorSize;
mVirtualMapMaxIndex = MemoryMapSize / DescriptorSize;
mVirtualMap = VirtualMap; 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 // Currently the bug in StatusCode/RuntimeLib has been fixed, it will
// check whether in Runtime or not (this is judged by looking at // 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 // Signal all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE events.
// ready for runtime yet. The Status Code driver calls data hub with does // All runtime events are stored in a list in Runtime AP.
// a bunch of Boot Service things (locks, AllocatePool) and hangs somewhere
// on the way.
// //
// ReportStatusCode ( for (Link = mRuntime.EventHead.ForwardLink; Link != &mRuntime.EventHead; Link = Link->ForwardLink) {
// EfiProgressCode, EfiMaxErrorSeverity, RuntimeEvent = _CR (Link, EFI_RUNTIME_EVENT_ENTRY, Link);
// 0x03, 0x01, 12, // ReadyToBoot Progress code
// 0x00, 30, L"ConvertPointer"
// );
//
for (Link = mEventList.ForwardLink; Link != &mEventList; Link = Link->ForwardLink) {
RuntimeEvent = _CR (Link, RUNTIME_NOTIFY_EVENT_DATA, Link);
if ((RuntimeEvent->Type & EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) { if ((RuntimeEvent->Type & EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {
RuntimeEvent->NotifyFunction ( RuntimeEvent->NotifyFunction (
RuntimeEvent->Event, 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.
//
for (Link = mRelocationList.ForwardLink; Link != &mRelocationList; Link = Link->ForwardLink) {
RuntimeImage = _CR (Link, RUNTIME_IMAGE_RELOCATION_DATA, Link);
if (RuntimeImage->Valid) {
VirtImageBase = RuntimeImage->ImageBase; //
// Relocate runtime images. All runtime images are stored in a list in Runtime AP.
//
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 = (EFI_PHYSICAL_ADDRESS) (UINTN) RuntimeImage->ImageBase;
Status = RuntimeDriverConvertPointer (0, (VOID **) &VirtImageBase); Status = RuntimeDriverConvertPointer (0, (VOID **) &VirtImageBase);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
PeCoffLoaderRelocateImageForRuntime ( PeCoffLoaderRelocateImageForRuntime (
RuntimeImage->ImageBase, (EFI_PHYSICAL_ADDRESS) (UINTN) RuntimeImage->ImageBase,
VirtImageBase, VirtImageBase,
RuntimeImage->ImageSize, (UINTN) RuntimeImage->ImageSize,
RuntimeImage->RelocationData 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() // Convert all the Runtime Services except ConvertPointer() and SetVirtualAddressMap()
// and recompute the CRC-32 // and recompute the CRC-32
@ -480,6 +384,9 @@ RuntimeDriverSetVirtualAddressMap (
RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetWakeupTime); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetWakeupTime);
RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetWakeupTime); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetWakeupTime);
RuntimeDriverConvertInternalPointer ((VOID **) &gRT->ResetSystem); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->ResetSystem);
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
RuntimeDriverConvertInternalPointer ((VOID **) &gRT->ReportStatusCode);
#endif
RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextHighMonotonicCount); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextHighMonotonicCount);
RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetVariable); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetVariable);
RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetVariable); RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetVariable);
@ -495,7 +402,7 @@ RuntimeDriverSetVirtualAddressMap (
// Convert the UGA OS Handoff Table if it is present in the Configuration Table // Convert the UGA OS Handoff Table if it is present in the Configuration Table
// //
for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { 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; DriverOsHandoffHeader = gST->ConfigurationTable[Index].VendorTable;
for (Index1 = 0; Index1 < DriverOsHandoffHeader->NumberOfEntries; Index1++) { for (Index1 = 0; Index1 < DriverOsHandoffHeader->NumberOfEntries; Index1++) {
DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *) DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)
@ -511,8 +418,9 @@ RuntimeDriverSetVirtualAddressMap (
RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &(gST->ConfigurationTable[Index].VendorTable)); RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &(gST->ConfigurationTable[Index].VendorTable));
} }
#if (EFI_SPECIFICATION_VERSION >= 0x00020000) #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
if (CompareGuid (&mEfiCapsuleHeaderGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { if (CompareGuid (&gEfiCapsuleGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
CapsuleTable = gST->ConfigurationTable[Index].VendorTable; CapsuleTable = gST->ConfigurationTable[Index].VendorTable;
for (Index1 = 0; Index1 < CapsuleTable->CapsuleArrayNumber; Index1++) { for (Index1 = 0; Index1 < CapsuleTable->CapsuleArrayNumber; Index1++) {
RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &CapsuleTable->CapsulePtr[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 // This image needs to be exclued from relocation for virtual mode, so cache
@ -574,9 +483,10 @@ Returns:
Status = gBS->HandleProtocol ( Status = gBS->HandleProtocol (
ImageHandle, ImageHandle,
&gEfiLoadedImageProtocolGuid, &gEfiLoadedImageProtocolGuid,
(VOID **) &mMyLoadedImage &MyLoadedImage
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
mMyImageBase = MyLoadedImage->ImageBase;
// //
// Initialize the table used to compute 32-bit CRCs // 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 // Fill in the entries of the EFI Boot Services and EFI Runtime Services Tables
// //
gBS->CalculateCrc32 = RuntimeDriverCalculateCrc32; gBS->CalculateCrc32 = RuntimeDriverCalculateCrc32;
gRT->SetVirtualAddressMap = RuntimeDriverSetVirtualAddressMap; gRT->SetVirtualAddressMap = RuntimeDriverSetVirtualAddressMap;
gRT->ConvertPointer = RuntimeDriverConvertPointer; gRT->ConvertPointer = RuntimeDriverConvertPointer;
@ -600,9 +510,6 @@ Returns:
NULL NULL
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
mRuntimeImageNumber = 0; return EFI_SUCCESS;
mRuntimeEventNumber = 0;
return Status;
} }

View File

@ -17,88 +17,152 @@ Abstract:
Runtime Architectural Protocol as defined in the DXE CIS 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_ #ifndef _RUNTIME_H_
#define _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 // Function Prototypes
// //
VOID
RelocatePeImageForRuntime (
RUNTIME_IMAGE_RELOCATION_DATA *Image
);
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
RuntimeDriverCalculateCrc32 ( RuntimeDriverCalculateCrc32 (
IN VOID *Data, IN VOID *Data,
IN UINTN DataSize, IN UINTN DataSize,
OUT UINT32 *CrcOut OUT UINT32 *CrcOut
); )
/*++
EFI_STATUS Routine Description:
EFIAPI
RuntimeDriverRegisterImage (
IN EFI_RUNTIME_ARCH_PROTOCOL *This,
IN EFI_PHYSICAL_ADDRESS ImageBase,
IN UINTN ImageSize,
IN VOID *RelocationData
);
EFI_STATUS Calculate CRC32 for target data
EFIAPI
RuntimeDriverRegisterEvent ( Arguments:
IN EFI_RUNTIME_ARCH_PROTOCOL *This,
IN UINT32 Type, Data - The target data.
IN EFI_TPL NotifyTpl, DataSize - The target data size.
IN EFI_EVENT_NOTIFY NotifyFunction, CrcOut - The CRC32 for target data.
IN VOID *NotifyContext,
IN EFI_EVENT *Event 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 EFI_STATUS
EFIAPI EFIAPI
RuntimeDriverConvertPointer ( RuntimeDriverConvertPointer (
IN UINTN DebugDisposition, IN UINTN DebugDisposition,
IN OUT VOID **ConvertAddress 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 VOID
RuntimeDriverInitializeCrc32Table ( RuntimeDriverInitializeCrc32Table (
VOID VOID
); )
/*++
Routine Description:
Initialize CRC32 table.
Arguments:
None.
Returns:
None.
--*/
;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
RuntimeDriverInitialize ( RuntimeDriverInitialize (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable 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 #endif

View File

@ -70,10 +70,18 @@
<Protocol Usage="ALWAYS_CONSUMED"> <Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName> <ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName>
</Protocol> </Protocol>
<Protocol Usage="ALWAYS_CONSUMED"> <Protocol Usage="SOMETIMES_CONSUMED">
<ProtocolCName>gEfiUgaIoProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_PRODUCED">
<ProtocolCName>gEfiRuntimeArchProtocolGuid</ProtocolCName> <ProtocolCName>gEfiRuntimeArchProtocolGuid</ProtocolCName>
</Protocol> </Protocol>
</Protocols> </Protocols>
<Guids>
<GuidCNames Usage="SOMETIMES_CONSUMED">
<GuidCName>gEfiCapsuleGuid</GuidCName>
</GuidCNames>
</Guids>
<Externs> <Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification> <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification> <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>

View File

@ -203,4 +203,14 @@ typedef INTN RETURN_STATUS;
typedef UINT64 PHYSICAL_ADDRESS; typedef UINT64 PHYSICAL_ADDRESS;
//
// LIST_ENTRY definition
//
typedef struct _LIST_ENTRY LIST_ENTRY;
struct _LIST_ENTRY {
LIST_ENTRY *ForwardLink;
LIST_ENTRY *BackLink;
};
#endif #endif

View File

@ -25,7 +25,7 @@
Module Name: Runtime.h Module Name: Runtime.h
@par Revision Reference: @par Revision Reference:
Version 0.90. Version 0.91.
**/ **/
@ -36,115 +36,89 @@
// Global ID for the Runtime Architectural Protocol // Global ID for the Runtime Architectural Protocol
// //
#define EFI_RUNTIME_ARCH_PROTOCOL_GUID \ #define EFI_RUNTIME_ARCH_PROTOCOL_GUID \
{ 0x96d08253, 0x8483, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } { 0xb7dfb4e1, 0x52f, 0x449f, {0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33 } }
typedef struct _EFI_RUNTIME_ARCH_PROTOCOL EFI_RUNTIME_ARCH_PROTOCOL; typedef struct _EFI_RUNTIME_ARCH_PROTOCOL EFI_RUNTIME_ARCH_PROTOCOL;
/** //
When a SetVirtualAddressMap() is performed all the runtime images loaded by // LIST_ENTRY from BaseType
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 typedef LIST_ENTRY EFI_LIST_ENTRY;
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.
@param This The EFI_RUNTIME_ARCH_PROTOCOL instance. typedef struct _EFI_RUNTIME_IMAGE_ENTRY EFI_RUNTIME_IMAGE_ENTRY;
@param ImageBase Start of image that has been loaded in memory. It is either
a pointer to the DOS or PE header of the image.
@param ImageSize Size of the image in bytes.
@param 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.
@retval EFI_SUCCESS The ImageBase has been registered. struct _EFI_RUNTIME_IMAGE_ENTRY {
@retval EFI_OUT_OF_RESOURCES There are not enough resources to register ImageBase. VOID *ImageBase;
UINT64 ImageSize;
VOID *RelocationData;
EFI_HANDLE Handle;
EFI_LIST_ENTRY Link;
};
**/ typedef struct _EFI_RUNTIME_EVENT_ENTRY EFI_RUNTIME_EVENT_ENTRY;
typedef
EFI_STATUS
(EFIAPI *EFI_RUNTIME_REGISTER_IMAGE) (
IN EFI_RUNTIME_ARCH_PROTOCOL *This,
IN EFI_PHYSICAL_ADDRESS ImageBase,
IN UINTN ImageSize,
IN VOID *RelocationData
);
struct _EFI_RUNTIME_EVENT_ENTRY {
/** UINT32 Type;
This function is used to support the required runtime events. Currently only EFI_TPL NotifyTpl;
runtime events of type EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE needs to be EFI_EVENT_NOTIFY NotifyFunction;
registered with this service. All the runtime events that exist in the DXE VOID *NotifyContext;
Core should be registered with this service when ExitBootServices() is called. EFI_EVENT *Event;
All the events that are registered with this service must have been created EFI_LIST_ENTRY Link;
with the Boot Service CreateEvent(). As a result, no parameter checking needs };
to be performed.
@param This The EFI_RUNTIME_ARCH_PROTOCOL instance.
@param Type The same as Type passed into CreateEvent().
@param NotifyTpl The same as NotifyTpl passed into CreateEvent().
@param NotifyFunction The same as NotifyFunction passed into CreateEvent().
@param NotifyContext The same as NotifyContext passed into CreateEvent().
@param Event The EFI_EVENT returned by CreateEvent(). Event must be in
runtime memory.
@retval EFI_SUCCESS The Event has been registered.
@retval EFI_OUT_OF_RESOURCES There are not enough resources to register Event.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_RUNTIME_REGISTER_EVENT) (
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
);
// //
// Interface stucture for the Runtime Architectural Protocol // Interface stucture for the Runtime Architectural Protocol
// //
/** /**
@par Protocol Description: @par Protocol Description:
The DXE driver that produces this protocol must be a runtime driver. This Allows the runtime functionality of the DXE Foundation to be contained in a
driver is responsible for initializing the SetVirtualAddressMap() and separate driver. It also provides hooks for the DXE Foundation to export
ConvertPointer() fields of the EFI Runtime Services Table and the information that is needed at runtime. As such, this protocol allows the DXE
CalculateCrc32() field of the EFI Boot Services Table. See the Runtime Foundation to manage runtime drivers and events. This protocol also implies
Services chapter and the Boot Services chapter for details on these services. that the runtime services required to transition to virtual mode,
After the two fields of the EFI Runtime Services Table and the one field of SetVirtualAddressMap() and ConvertPointer(), have been registered into the
the EFI Boot Services Table have been initialized, the driver must install EFI Runtime Table in the EFI System Partition. This protocol must be produced
the EFI_RUNTIME_ARCH_PROTOCOL_GUID on a new handle with an EFI_RUNTIME_ARCH_ by a runtime DXE driver and may only be consumed by the DXE Foundation.
PROTOCOL interface pointer. The installation of this protocol informs the
DXE core that the virtual memory services and the 32-bit CRC services are
now available, and the DXE core must update the 32-bit CRC of the EFI Runtime
Services Table and the 32-bit CRC of the EFI Boot Services Table.
All runtime core services are provided by the EFI_RUNTIME_ARCH_PROTOCOL. @param ImageHead
This includes the support for registering runtime images that must be A list of type EFI_RUNTIME_IMAGE_ENTRY.
re-fixed up when a transition is made from physical mode to virtual mode.
This protocol also supports all events that are defined to fire at runtime.
This protocol also contains a CRC-32 function that will be used by the DXE
core as a boot service. The EFI_RUNTIME_ARCH_PROTOCOL needs the CRC-32
function when a transition is made from physical mode to virtual mode and
the EFI System Table and EFI Runtime Table are fixed up with virtual pointers.
@param RegisterRuntimeImage @param EventHead
Register a runtime image so it can be converted to virtual mode if the EFI Runtime Services A list of type EFI_RUNTIME_EVENT_ENTRY.
SetVirtualAddressMap() is called.
@param RegisterRuntimeEvent @param MemoryDescriptorSize
Register an event than needs to be notified at runtime. Size of a memory descriptor that is return by GetMemoryMap().
@param MemoryDescriptorVersion
Version of a memory descriptor that is return by GetMemoryMap().
@param MemoryMapSize
Size of the memory map in bytes contained in MemoryMapPhysical and MemoryMapVirtual.
@param MemoryMapPhysical
Pointer to a runtime buffer that contains a copy of
the memory map returned via GetMemoryMap().
@param MemoryMapVirtual
Pointer to MemoryMapPhysical that is updated to virtual mode after SetVirtualAddressMap().
@param VirtualMode
Boolean that is TRUE if SetVirtualAddressMap() has been called.
@param AtRuntime
Boolean that is TRUE if ExitBootServices () has been called.
**/ **/
struct _EFI_RUNTIME_ARCH_PROTOCOL { struct _EFI_RUNTIME_ARCH_PROTOCOL {
EFI_RUNTIME_REGISTER_IMAGE RegisterImage; EFI_LIST_ENTRY ImageHead;
EFI_RUNTIME_REGISTER_EVENT RegisterEvent; EFI_LIST_ENTRY EventHead;
UINTN MemoryDescriptorSize;
UINT32 MemoryDesciptorVersion;
UINTN MemoryMapSize;
EFI_MEMORY_DESCRIPTOR *MemoryMapPhysical;
EFI_MEMORY_DESCRIPTOR *MemoryMapVirtual;
BOOLEAN VirtualMode;
BOOLEAN AtRuntime;
}; };
extern EFI_GUID gEfiRuntimeArchProtocolGuid; extern EFI_GUID gEfiRuntimeArchProtocolGuid;

View File

@ -449,7 +449,7 @@ EFI_STATUS
// DXE Services Table // DXE Services Table
// //
#define EFI_DXE_SERVICES_SIGNATURE 0x565245535f455844ULL #define EFI_DXE_SERVICES_SIGNATURE 0x565245535f455844ULL
#define EFI_DXE_SERVICES_REVISION ((0 << 16) | (25)) #define EFI_DXE_SERVICES_REVISION ((0 << 16) | (90))
typedef struct { typedef struct {
EFI_TABLE_HEADER Hdr; EFI_TABLE_HEADER Hdr;

View File

@ -696,16 +696,6 @@ BcdToDecimal8 (
IN UINT8 Value IN UINT8 Value
); );
//
// LIST_ENTRY definition
//
typedef struct _LIST_ENTRY LIST_ENTRY;
struct _LIST_ENTRY {
LIST_ENTRY *ForwardLink;
LIST_ENTRY *BackLink;
};
// //
// Linked List Functions and Macros // Linked List Functions and Macros
// //

View File

@ -1540,7 +1540,7 @@
</Entry> </Entry>
<Entry Name="Runtime"> <Entry Name="Runtime">
<C_Name>gEfiRuntimeArchProtocolGuid</C_Name> <C_Name>gEfiRuntimeArchProtocolGuid</C_Name>
<GuidValue>96D08253-8483-11D4-BCF1-0080C73C8881</GuidValue> <GuidValue>b7dfb4e1-052f-449f-87be-9818fc91b733</GuidValue>
<HelpText/> <HelpText/>
</Entry> </Entry>
<Entry Name="Security"> <Entry Name="Security">