mirror of
				https://gitlab.com/qemu-project/edk2.git
				synced 2025-11-03 07:59:00 +08:00 
			
		
		
		
	The debug print incorrectly uses "%016x" to print a UINT64 PhysicalAddress. This can cause truncation since "%x" expects UINT32. Update the format specifier to "%016llx" to properly handle UINT64 values and ensure correct output across all architectures. Signed-off-by: Aaron Li <aaron.li@intel.com>
		
			
				
	
	
		
			523 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			523 lines
		
	
	
		
			17 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;
 | 
						|
 | 
						|
GLOBAL_REMOVE_IF_UNREFERENCED STATIC  PRM_RUNTIME_MMIO_RANGES  **mRuntimeMmioRanges;
 | 
						|
 | 
						|
/**
 | 
						|
  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_, __func__));
 | 
						|
 | 
						|
  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_,
 | 
						|
      __func__,
 | 
						|
      Index
 | 
						|
      ));
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_INFO,
 | 
						|
      "      %a %a: Physical address = 0x%016llx. Length = 0x%x.\n",
 | 
						|
      _DBGMSGID_,
 | 
						|
      __func__,
 | 
						|
      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 == EfiGcdMemoryTypeNonExistent)) {
 | 
						|
      // The MMIO range was found in the GCD, but is non-existent. We need to add this MMIO range to the GCD so that
 | 
						|
      // the PRM module can use it. As such, mark it as not found, as the behavior we want is the same as in that
 | 
						|
      // case.
 | 
						|
      Status = EFI_NOT_FOUND;
 | 
						|
    } else 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%016llx.\n",
 | 
						|
        _DBGMSGID_,
 | 
						|
        __func__,
 | 
						|
        Status,
 | 
						|
        RuntimeMmioRanges->Range[Index].PhysicalBaseAddress
 | 
						|
        ));
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((Descriptor.Attributes & EFI_MEMORY_RUNTIME) != 0) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    // The memory space descriptor access attributes are not accurate. Don't pass
 | 
						|
    // in access attributes so SetMemorySpaceAttributes() doesn't update them.
 | 
						|
    // EFI_MEMORY_RUNTIME is not a CPU arch attribute, so calling
 | 
						|
    // SetMemorySpaceAttributes() with only it set will not clear existing page table
 | 
						|
    // attributes for this region, such as EFI_MEMORY_XP
 | 
						|
    Status = gDS->SetMemorySpaceAttributes (
 | 
						|
                    RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
 | 
						|
                    (UINT64)RuntimeMmioRanges->Range[Index].Length,
 | 
						|
                    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%016llx.\n",
 | 
						|
        _DBGMSGID_,
 | 
						|
        __func__,
 | 
						|
        Status,
 | 
						|
        RuntimeMmioRanges->Range[Index].PhysicalBaseAddress
 | 
						|
        ));
 | 
						|
    } else {
 | 
						|
      DEBUG ((DEBUG_INFO, "      %a %a: Successfully set runtime attribute for the MMIO range.\n", _DBGMSGID_, __func__));
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Stores pointers or pointer to resources that should be converted in the virtual address change event.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
StoreVirtualMemoryAddressChangePointers (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS           Status;
 | 
						|
  UINTN                HandleCount;
 | 
						|
  UINTN                HandleIndex;
 | 
						|
  UINTN                RangeIndex;
 | 
						|
  EFI_HANDLE           *HandleBuffer;
 | 
						|
  PRM_CONFIG_PROTOCOL  *PrmConfigProtocol;
 | 
						|
 | 
						|
  DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __func__));
 | 
						|
 | 
						|
  RangeIndex = 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_,
 | 
						|
      __func__
 | 
						|
      ));
 | 
						|
    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;
 | 
						|
      }
 | 
						|
 | 
						|
      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_,
 | 
						|
            __func__,
 | 
						|
            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_,
 | 
						|
      __func__,
 | 
						|
      RangeIndex
 | 
						|
      ));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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_, __func__));
 | 
						|
    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_, __func__));
 | 
						|
    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_, __func__));
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  if (IsZeroGuid (&PrmContextBuffer->HandlerGuid)) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "  %a %a: The PRM context buffer GUID is zero.\n", _DBGMSGID_, __func__));
 | 
						|
    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_,
 | 
						|
      __func__,
 | 
						|
      &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 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.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
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_, __func__));
 | 
						|
 | 
						|
  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_,
 | 
						|
        __func__,
 | 
						|
        &PrmConfigProtocol->ModuleContextBuffers.ModuleGuid
 | 
						|
        ));
 | 
						|
 | 
						|
      DEBUG ((DEBUG_INFO, "      %a %a: Validating module context buffers...\n", _DBGMSGID_, __func__));
 | 
						|
      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_,
 | 
						|
            __func__,
 | 
						|
            CurrentContextBuffer->HandlerGuid
 | 
						|
            ));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      DEBUG ((DEBUG_INFO, "      %a %a: Module context buffer validation complete.\n", _DBGMSGID_, __func__));
 | 
						|
 | 
						|
      if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {
 | 
						|
        DEBUG ((
 | 
						|
          DEBUG_INFO,
 | 
						|
          "    %a %a: Found %d PRM runtime MMIO ranges.\n",
 | 
						|
          _DBGMSGID_,
 | 
						|
          __func__,
 | 
						|
          PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges->Count
 | 
						|
          ));
 | 
						|
        SetRuntimeMemoryRangeAttributes (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges);
 | 
						|
        mMaxRuntimeMmioRangeCount++;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    StoreVirtualMemoryAddressChangePointers ();
 | 
						|
  }
 | 
						|
 | 
						|
  if (HandleBuffer != NULL) {
 | 
						|
    gBS->FreePool (HandleBuffer);
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->CloseEvent (Event);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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_, __func__));
 | 
						|
 | 
						|
  //
 | 
						|
  // 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;
 | 
						|
}
 |