runtime.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 529 行 · 第 1/2 页
C
529 行
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.
--*/
{
EFI_RUNTIME_EVENT_ENTRY *RuntimeEvent;
EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage;
EFI_LIST_ENTRY *Link;
UINTN Index;
UINTN Index1;
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
EFI_DRIVER_OS_HANDOFF_HEADER *DriverOsHandoffHeader;
EFI_DRIVER_OS_HANDOFF *DriverOsHandoff;
#endif
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
EFI_CAPSULE_TABLE *CapsuleTable;
#endif
//
// Can only switch to virtual addresses once the memory map is locked down,
// and can only set it once
//
if (!mRuntime.AtRuntime || mRuntime.VirtualMode) {
return EFI_UNSUPPORTED;
}
//
// Only understand the original descriptor format
//
if (DescriptorVersion != EFI_MEMORY_DESCRIPTOR_VERSION || DescriptorSize < sizeof (EFI_MEMORY_DESCRIPTOR)) {
return EFI_INVALID_PARAMETER;
}
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;
//
// Currently the bug in StatusCode/RuntimeLib has been fixed, it will
// check whether in Runtime or not (this is judged by looking at
// mEfiAtRuntime global), So this ReportStatusCode will work
//
EfiReportStatusCode (
EFI_PROGRESS_CODE,
(EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP),
0,
&gEfiCallerIdGuid,
NULL
);
//
// Signal all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE events.
// All runtime events are stored in a list in Runtime AP.
//
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,
RuntimeEvent->NotifyContext
);
}
}
//
// 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);
RelocatePeImageForRuntime (RuntimeImage);
}
//
// Convert all the Runtime Services except ConvertPointer() and SetVirtualAddressMap()
// and recompute the CRC-32.
//
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->GetTime);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->SetTime);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->GetWakeupTime);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->SetWakeupTime);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->ResetSystem);
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->ReportStatusCode);
#endif
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->GetNextHighMonotonicCount);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->GetVariable);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->SetVariable);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->GetNextVariableName);
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->QueryVariableInfo);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->UpdateCapsule);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyRT->QueryCapsuleCapabilities);
#endif
RuntimeDriverCalculateEfiHdrCrc (&mMyRT->Hdr);
//
// Convert the UGA OS Handoff Table if it is present in the Configuration Table.
//
for (Index = 0; Index < mMyST->NumberOfTableEntries; Index++) {
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
if (EfiCompareGuid (&mLocalEfiUgaIoProtocolGuid, &(mMyST->ConfigurationTable[Index].VendorGuid))) {
DriverOsHandoffHeader = mMyST->ConfigurationTable[Index].VendorTable;
for (Index1 = 0; Index1 < DriverOsHandoffHeader->NumberOfEntries; Index1++) {
DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)
(
(UINTN) DriverOsHandoffHeader +
DriverOsHandoffHeader->HeaderSize +
Index1 *
DriverOsHandoffHeader->SizeOfEntries
);
RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &DriverOsHandoff->DevicePath);
RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &DriverOsHandoff->PciRomImage);
}
RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &(mMyST->ConfigurationTable[Index].VendorTable));
}
#endif
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
if (EfiCompareGuid (&mEfiCapsuleHeaderGuid, &(mMyST->ConfigurationTable[Index].VendorGuid))) {
CapsuleTable = mMyST->ConfigurationTable[Index].VendorTable;
for (Index1 = 0; Index1 < CapsuleTable->CapsuleArrayNumber; Index1++) {
RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &CapsuleTable->CapsulePtr[Index1]);
}
RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &(mMyST->ConfigurationTable[Index].VendorTable));
}
#endif
}
//
// Convert the runtime fields of the EFI System Table and recompute the CRC-32.
//
RuntimeDriverConvertInternalPointer ((VOID **) &mMyST->FirmwareVendor);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyST->ConfigurationTable);
RuntimeDriverConvertInternalPointer ((VOID **) &mMyST->RuntimeServices);
RuntimeDriverCalculateEfiHdrCrc (&mMyST->Hdr);
//
// At this point, mMyRT and mMyST are physical pointers, but the contents of these tables
// have been converted to runtime.
//
//
// mVirtualMap is only valid during SetVirtualAddressMap() call.
//
mVirtualMap = NULL;
return EFI_SUCCESS;
}
EFI_DRIVER_ENTRY_POINT (RuntimeDriverInitialize)
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.
--*/
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *MyLoadedImage;
//
// Initialize EFI Runtime Driver.
//
EfiInitializeRuntimeDriverLib (ImageHandle, SystemTable, NULL);
//
// Save the EFI System Table and EFI Runtime Services Table into module globals
// for use after ExitBootServices().
//
mMyST = SystemTable;
mMyRT = SystemTable->RuntimeServices;
//
// This image needs to be exclued from relocation for virtual mode, so cache
// a copy of the Loaded Image protocol to test later.
//
Status = gBS->HandleProtocol (
ImageHandle,
&gEfiLoadedImageProtocolGuid,
&MyLoadedImage
);
ASSERT_EFI_ERROR (Status);
mMyImageBase = MyLoadedImage->ImageBase;
//
// Initialize the table used to compute 32-bit CRCs
//
RuntimeDriverInitializeCrc32Table ();
//
// Fill in the entries of the EFI Boot Services and EFI Runtime Services Tables
//
gBS->CalculateCrc32 = RuntimeDriverCalculateCrc32;
mMyRT->SetVirtualAddressMap = RuntimeDriverSetVirtualAddressMap;
mMyRT->ConvertPointer = RuntimeDriverConvertPointer;
//
// Install the Runtime Architectural Protocol onto a new handle
//
Status = gBS->InstallMultipleProtocolInterfaces (
&mRuntimeHandle,
&gEfiRuntimeArchProtocolGuid,
&mRuntime,
NULL
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?