mirror of https://github.com/acidanthera/audk.git
560 lines
18 KiB
C
560 lines
18 KiB
C
|
/** @file
|
||
|
|
||
|
This file contains the implementation for a Platform Runtime Mechanism (PRM) configuration driver.
|
||
|
|
||
|
Copyright (c) Microsoft Corporation
|
||
|
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||
|
|
||
|
**/
|
||
|
|
||
|
#include <Library/BaseLib.h>
|
||
|
#include <Library/BaseMemoryLib.h>
|
||
|
#include <Library/DebugLib.h>
|
||
|
#include <Library/DxeServicesTableLib.h>
|
||
|
#include <Library/MemoryAllocationLib.h>
|
||
|
#include <Library/UefiBootServicesTableLib.h>
|
||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||
|
#include <Library/UefiLib.h>
|
||
|
|
||
|
#include <PiDxe.h>
|
||
|
#include <PrmContextBuffer.h>
|
||
|
#include <PrmDataBuffer.h>
|
||
|
#include <PrmMmio.h>
|
||
|
#include <Protocol/PrmConfig.h>
|
||
|
|
||
|
#define _DBGMSGID_ "[PRMCONFIG]"
|
||
|
|
||
|
STATIC UINTN mMaxRuntimeMmioRangeCount;
|
||
|
STATIC UINTN mMaxStaticDataBufferCount;
|
||
|
|
||
|
STATIC PRM_RUNTIME_MMIO_RANGES **mRuntimeMmioRanges;
|
||
|
STATIC PRM_DATA_BUFFER ***mStaticDataBuffers;
|
||
|
|
||
|
/**
|
||
|
Converts the runtime memory range physical addresses to virtual addresses.
|
||
|
|
||
|
@param[in] RuntimeMmioRanges A pointer to a PRM_RUNTIME_MMIO_RANGES buffer.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
ConvertRuntimeMemoryRangeAddresses (
|
||
|
IN PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges
|
||
|
)
|
||
|
{
|
||
|
UINTN Index;
|
||
|
|
||
|
if (RuntimeMmioRanges == NULL || RuntimeMmioRanges->Count == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (Index = 0; Index < (UINTN) RuntimeMmioRanges->Count; Index++) {
|
||
|
RuntimeMmioRanges->Range[Index].VirtualBaseAddress = RuntimeMmioRanges->Range[Index].PhysicalBaseAddress;
|
||
|
gRT->ConvertPointer (0x0, (VOID **) &(RuntimeMmioRanges->Range[Index].VirtualBaseAddress));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Sets the runtime memory range attributes.
|
||
|
|
||
|
The EFI_MEMORY_RUNTIME attribute is set for each PRM_RUNTIME_MMIO_RANGE present
|
||
|
in the buffer provided.
|
||
|
|
||
|
@param[in] RuntimeMmioRanges A pointer to a PRM_RUNTIME_MMIO_RANGES buffer.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
SetRuntimeMemoryRangeAttributes (
|
||
|
IN PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
EFI_STATUS Status2;
|
||
|
UINTN Index;
|
||
|
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
|
||
|
|
||
|
DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
|
||
|
if (RuntimeMmioRanges == NULL || RuntimeMmioRanges->Count == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (Index = 0; Index < (UINTN) RuntimeMmioRanges->Count; Index++) {
|
||
|
DEBUG ((
|
||
|
DEBUG_INFO, " %a %a: Runtime MMIO Range [%d].\n", _DBGMSGID_, __FUNCTION__, Index));
|
||
|
DEBUG ((
|
||
|
DEBUG_INFO,
|
||
|
" %a %a: Physical address = 0x%016x. Length = 0x%x.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
|
||
|
RuntimeMmioRanges->Range[Index].Length
|
||
|
));
|
||
|
|
||
|
// Runtime memory ranges should cover ranges on a page boundary
|
||
|
ASSERT ((RuntimeMmioRanges->Range[Index].PhysicalBaseAddress & EFI_PAGE_MASK) == 0);
|
||
|
ASSERT ((RuntimeMmioRanges->Range[Index].Length & EFI_PAGE_MASK) == 0);
|
||
|
|
||
|
Status2 = EFI_NOT_FOUND;
|
||
|
Status = gDS->GetMemorySpaceDescriptor (RuntimeMmioRanges->Range[Index].PhysicalBaseAddress, &Descriptor);
|
||
|
if (!EFI_ERROR (Status) &&
|
||
|
(
|
||
|
(Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo && Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) ||
|
||
|
((Descriptor.Length & EFI_PAGE_MASK) != 0)
|
||
|
)
|
||
|
) {
|
||
|
Status2 = gDS->RemoveMemorySpace (
|
||
|
RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
|
||
|
Descriptor.Length
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (Status == EFI_NOT_FOUND || !EFI_ERROR (Status2)) {
|
||
|
Status = gDS->AddMemorySpace (
|
||
|
EfiGcdMemoryTypeMemoryMappedIo,
|
||
|
RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
|
||
|
(UINT64) RuntimeMmioRanges->Range[Index].Length,
|
||
|
EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
|
||
|
Status = gDS->AllocateMemorySpace (
|
||
|
EfiGcdAllocateAddress,
|
||
|
EfiGcdMemoryTypeMemoryMappedIo,
|
||
|
0,
|
||
|
(UINT64) RuntimeMmioRanges->Range[Index].Length,
|
||
|
&RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
|
||
|
gImageHandle,
|
||
|
NULL
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
}
|
||
|
|
||
|
Status = gDS->GetMemorySpaceDescriptor (RuntimeMmioRanges->Range[Index].PhysicalBaseAddress, &Descriptor);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
DEBUG ((
|
||
|
DEBUG_ERROR,
|
||
|
" %a %a: Error [%r] finding descriptor for runtime memory range 0x%016x.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
Status,
|
||
|
RuntimeMmioRanges->Range[Index].PhysicalBaseAddress
|
||
|
));
|
||
|
continue;
|
||
|
}
|
||
|
if ((Descriptor.Attributes & EFI_MEMORY_RUNTIME) != 0) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
Status = gDS->SetMemorySpaceAttributes (
|
||
|
RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
|
||
|
(UINT64) RuntimeMmioRanges->Range[Index].Length,
|
||
|
Descriptor.Attributes | EFI_MEMORY_RUNTIME
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
DEBUG ((
|
||
|
DEBUG_ERROR,
|
||
|
" %a %a: Error [%r] setting descriptor for runtime memory range 0x%016x.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
Status,
|
||
|
RuntimeMmioRanges->Range[Index].PhysicalBaseAddress
|
||
|
));
|
||
|
} else {
|
||
|
DEBUG ((DEBUG_INFO, " %a %a: Successfully set runtime attribute for the MMIO range.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Stores pointers or pointer to resources that should be converted in the virtual address change event.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
StoreVirtualMemoryAddressChangePointers (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
UINTN BufferIndex;
|
||
|
UINTN HandleCount;
|
||
|
UINTN HandleIndex;
|
||
|
UINTN RangeIndex;
|
||
|
UINTN StaticDataBufferIndex;
|
||
|
EFI_HANDLE *HandleBuffer;
|
||
|
PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
|
||
|
PRM_CONTEXT_BUFFER *CurrentContextBuffer;
|
||
|
|
||
|
DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
|
||
|
RangeIndex = 0;
|
||
|
StaticDataBufferIndex = 0;
|
||
|
|
||
|
mRuntimeMmioRanges = AllocateRuntimeZeroPool (sizeof (*mRuntimeMmioRanges) * mMaxRuntimeMmioRangeCount);
|
||
|
if (mRuntimeMmioRanges == NULL && mMaxRuntimeMmioRangeCount > 0) {
|
||
|
DEBUG ((
|
||
|
DEBUG_ERROR,
|
||
|
" %a %a: Memory allocation for runtime MMIO pointer array failed.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__
|
||
|
));
|
||
|
ASSERT (FALSE);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
mStaticDataBuffers = AllocateRuntimeZeroPool (sizeof (*mStaticDataBuffers) * mMaxStaticDataBufferCount);
|
||
|
if (mStaticDataBuffers == NULL && mMaxStaticDataBufferCount > 0) {
|
||
|
DEBUG ((
|
||
|
DEBUG_ERROR,
|
||
|
" %a %a: Memory allocation for PRM static data buffer pointer array failed.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__
|
||
|
));
|
||
|
ASSERT (FALSE);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
HandleBuffer = NULL;
|
||
|
Status = gBS->LocateHandleBuffer (
|
||
|
ByProtocol,
|
||
|
&gPrmConfigProtocolGuid,
|
||
|
NULL,
|
||
|
&HandleCount,
|
||
|
&HandleBuffer
|
||
|
);
|
||
|
if (!EFI_ERROR (Status)) {
|
||
|
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
|
||
|
Status = gBS->HandleProtocol (
|
||
|
HandleBuffer[HandleIndex],
|
||
|
&gPrmConfigProtocolGuid,
|
||
|
(VOID **) &PrmConfigProtocol
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
if (EFI_ERROR (Status) || PrmConfigProtocol == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
for (BufferIndex = 0; BufferIndex < PrmConfigProtocol->ModuleContextBuffers.BufferCount; BufferIndex++) {
|
||
|
CurrentContextBuffer = &(PrmConfigProtocol->ModuleContextBuffers.Buffer[BufferIndex]);
|
||
|
|
||
|
if (CurrentContextBuffer->StaticDataBuffer != NULL) {
|
||
|
if (StaticDataBufferIndex >= mMaxStaticDataBufferCount) {
|
||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||
|
DEBUG ((
|
||
|
DEBUG_ERROR,
|
||
|
" %a %a: Index out of bounds - Actual count (%d) of PRM data buffers exceeds maximum count (%d).\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
StaticDataBufferIndex + 1,
|
||
|
mMaxStaticDataBufferCount
|
||
|
));
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
return;
|
||
|
}
|
||
|
mStaticDataBuffers[StaticDataBufferIndex++] = &CurrentContextBuffer->StaticDataBuffer;
|
||
|
}
|
||
|
}
|
||
|
if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {
|
||
|
if (RangeIndex >= mMaxRuntimeMmioRangeCount) {
|
||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||
|
DEBUG ((
|
||
|
DEBUG_ERROR,
|
||
|
" %a %a: Index out of bounds - Actual count (%d) of runtime MMIO ranges exceeds maximum count (%d).\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
RangeIndex + 1,
|
||
|
mMaxRuntimeMmioRangeCount
|
||
|
));
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
return;
|
||
|
}
|
||
|
mRuntimeMmioRanges[RangeIndex++] = PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges;
|
||
|
}
|
||
|
}
|
||
|
DEBUG ((
|
||
|
DEBUG_INFO,
|
||
|
" %a %a: %d MMIO ranges buffers saved for future virtual memory conversion.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
RangeIndex
|
||
|
));
|
||
|
DEBUG ((
|
||
|
DEBUG_INFO,
|
||
|
" %a %a: %d static buffers saved for future virtual memory conversion.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
StaticDataBufferIndex
|
||
|
));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Validates a data buffer for a PRM module.
|
||
|
|
||
|
Verifies the buffer header signature is valid and the length meets the minimum size.
|
||
|
|
||
|
@param[in] PrmDataBuffer A pointer to the data buffer for this PRM module.
|
||
|
|
||
|
@retval EFI_SUCCESS The data buffer was validated successfully.
|
||
|
@retval EFI_INVALID_PARAMETER The pointer given for PrmDataBuffer is NULL.
|
||
|
@retval EFI_NOT_FOUND The data buffer signature is not valid.
|
||
|
@retval EFI_BUFFER_TOO_SMALL The buffer size is too small.
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
ValidatePrmDataBuffer (
|
||
|
IN CONST PRM_DATA_BUFFER *PrmDataBuffer
|
||
|
)
|
||
|
{
|
||
|
if (PrmDataBuffer == NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
if (PrmDataBuffer->Header.Signature != PRM_DATA_BUFFER_HEADER_SIGNATURE) {
|
||
|
DEBUG ((DEBUG_ERROR, " %a %a: The PRM data buffer signature is invalid. PRM module.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
return EFI_NOT_FOUND;
|
||
|
}
|
||
|
if (PrmDataBuffer->Header.Length < sizeof (PRM_DATA_BUFFER_HEADER)) {
|
||
|
DEBUG ((DEBUG_ERROR, " %a %a: The PRM data buffer length is invalid.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
return EFI_BUFFER_TOO_SMALL;
|
||
|
}
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Validates a PRM context buffer.
|
||
|
|
||
|
Verifies the buffer header signature is valid and the GUID is set to a non-zero value.
|
||
|
|
||
|
@param[in] PrmContextBuffer A pointer to the context buffer for this PRM handler.
|
||
|
|
||
|
@retval EFI_SUCCESS The context buffer was validated successfully.
|
||
|
@retval EFI_INVALID_PARAMETER The pointer given for ContextBuffer is NULL.
|
||
|
@retval EFI_NOT_FOUND The proper value for a field was not found.
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
ValidatePrmContextBuffer (
|
||
|
IN CONST PRM_CONTEXT_BUFFER *PrmContextBuffer
|
||
|
)
|
||
|
{
|
||
|
if (PrmContextBuffer == NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
if (PrmContextBuffer->Signature != PRM_CONTEXT_BUFFER_SIGNATURE) {
|
||
|
DEBUG ((DEBUG_ERROR, " %a %a: The PRM context buffer signature is invalid.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
return EFI_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
if (IsZeroGuid (&PrmContextBuffer->HandlerGuid)) {
|
||
|
DEBUG ((DEBUG_ERROR, " %a %a: The PRM context buffer GUID is zero.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
return EFI_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
if (PrmContextBuffer->StaticDataBuffer != NULL && EFI_ERROR (ValidatePrmDataBuffer (PrmContextBuffer->StaticDataBuffer))) {
|
||
|
DEBUG ((
|
||
|
DEBUG_ERROR,
|
||
|
" %a %a: Error in static buffer for PRM handler %g.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
&PrmContextBuffer->HandlerGuid
|
||
|
));
|
||
|
return EFI_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
|
||
|
|
||
|
This is notification function converts any registered PRM_RUNTIME_MMIO_RANGE
|
||
|
addresses to a virtual address.
|
||
|
|
||
|
@param[in] Event Event whose notification function is being invoked.
|
||
|
@param[in] Context Pointer to the notification function's context.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
PrmConfigVirtualAddressChangeEvent (
|
||
|
IN EFI_EVENT Event,
|
||
|
IN VOID *Context
|
||
|
)
|
||
|
{
|
||
|
UINTN Index;
|
||
|
|
||
|
//
|
||
|
// Convert static data buffer pointers
|
||
|
//
|
||
|
for (Index = 0; Index < mMaxStaticDataBufferCount; Index++) {
|
||
|
gRT->ConvertPointer (0x0, (VOID **) mStaticDataBuffers[Index]);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Convert runtime MMIO ranges
|
||
|
//
|
||
|
for (Index = 0; Index < mMaxRuntimeMmioRangeCount; Index++) {
|
||
|
ConvertRuntimeMemoryRangeAddresses (mRuntimeMmioRanges[Index]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
The PRM Config END_OF_DXE protocol notification event handler.
|
||
|
|
||
|
Finds all of the PRM_CONFIG_PROTOCOL instances installed at end of DXE and
|
||
|
marks all PRM_RUNTIME_MMIO_RANGE entries as EFI_MEMORY_RUNTIME.
|
||
|
|
||
|
@param[in] Event Event whose notification function is being invoked.
|
||
|
@param[in] Context The pointer to the notification function's context,
|
||
|
which is implementation-dependent.
|
||
|
|
||
|
@retval EFI_SUCCESS The function executed successfully
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
PrmConfigEndOfDxeNotification (
|
||
|
IN EFI_EVENT Event,
|
||
|
IN VOID *Context
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
UINTN HandleCount;
|
||
|
UINTN BufferIndex;
|
||
|
UINTN HandleIndex;
|
||
|
EFI_HANDLE *HandleBuffer;
|
||
|
PRM_CONTEXT_BUFFER *CurrentContextBuffer;
|
||
|
PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
|
||
|
|
||
|
DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
|
||
|
HandleBuffer = NULL;
|
||
|
Status = gBS->LocateHandleBuffer (
|
||
|
ByProtocol,
|
||
|
&gPrmConfigProtocolGuid,
|
||
|
NULL,
|
||
|
&HandleCount,
|
||
|
&HandleBuffer
|
||
|
);
|
||
|
if (!EFI_ERROR (Status)) {
|
||
|
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
|
||
|
Status = gBS->HandleProtocol (
|
||
|
HandleBuffer[HandleIndex],
|
||
|
&gPrmConfigProtocolGuid,
|
||
|
(VOID **) &PrmConfigProtocol
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
if (EFI_ERROR (Status) || PrmConfigProtocol == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
DEBUG ((
|
||
|
DEBUG_INFO,
|
||
|
" %a %a: Found PRM configuration protocol for PRM module %g.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
&PrmConfigProtocol->ModuleContextBuffers.ModuleGuid
|
||
|
));
|
||
|
|
||
|
DEBUG ((DEBUG_INFO, " %a %a: Validating module context buffers...\n", _DBGMSGID_, __FUNCTION__));
|
||
|
for (BufferIndex = 0; BufferIndex < PrmConfigProtocol->ModuleContextBuffers.BufferCount; BufferIndex++) {
|
||
|
CurrentContextBuffer = &(PrmConfigProtocol->ModuleContextBuffers.Buffer[BufferIndex]);
|
||
|
|
||
|
Status = ValidatePrmContextBuffer (CurrentContextBuffer);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
DEBUG ((
|
||
|
DEBUG_ERROR,
|
||
|
" %a %a: Context buffer validation failed for PRM handler %g.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
CurrentContextBuffer->HandlerGuid
|
||
|
));
|
||
|
}
|
||
|
if (CurrentContextBuffer->StaticDataBuffer != NULL) {
|
||
|
mMaxStaticDataBufferCount++;
|
||
|
}
|
||
|
}
|
||
|
DEBUG ((DEBUG_INFO, " %a %a: Module context buffer validation complete.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
|
||
|
if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {
|
||
|
DEBUG ((
|
||
|
DEBUG_INFO,
|
||
|
" %a %a: Found %d PRM runtime MMIO ranges to convert.\n",
|
||
|
_DBGMSGID_,
|
||
|
__FUNCTION__,
|
||
|
PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges->Count
|
||
|
));
|
||
|
SetRuntimeMemoryRangeAttributes (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges);
|
||
|
mMaxRuntimeMmioRangeCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
StoreVirtualMemoryAddressChangePointers ();
|
||
|
}
|
||
|
|
||
|
if (HandleBuffer != NULL) {
|
||
|
gBS->FreePool (HandleBuffer);
|
||
|
}
|
||
|
gBS->CloseEvent(Event);
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
The entry point for this module.
|
||
|
|
||
|
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||
|
@param[in] SystemTable A pointer to the EFI System Table.
|
||
|
|
||
|
@retval EFI_SUCCESS The entry point is executed successfully.
|
||
|
@retval Others An error occurred when executing this entry point.
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
PrmConfigEntryPoint (
|
||
|
IN EFI_HANDLE ImageHandle,
|
||
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
EFI_EVENT Event;
|
||
|
|
||
|
DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
|
||
|
|
||
|
//
|
||
|
// Register a notification function to change memory attributes at end of DXE
|
||
|
//
|
||
|
Event = NULL;
|
||
|
Status = gBS->CreateEventEx(
|
||
|
EVT_NOTIFY_SIGNAL,
|
||
|
TPL_CALLBACK,
|
||
|
PrmConfigEndOfDxeNotification,
|
||
|
NULL,
|
||
|
&gEfiEndOfDxeEventGroupGuid,
|
||
|
&Event
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
|
||
|
//
|
||
|
// Register a notification function for virtual address change
|
||
|
//
|
||
|
Event = NULL;
|
||
|
Status = gBS->CreateEventEx (
|
||
|
EVT_NOTIFY_SIGNAL,
|
||
|
TPL_NOTIFY,
|
||
|
PrmConfigVirtualAddressChangeEvent,
|
||
|
NULL,
|
||
|
&gEfiEventVirtualAddressChangeGuid,
|
||
|
&Event
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|