mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 03:57:26 +00:00 
			
		
		
		
	1. Do not use tab characters 2. No trailing white space in one line 3. All files must end with CRLF Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com>
		
			
				
	
	
		
			209 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  This module sets default policy for attributes of EfiACPIMemoryNVS and EfiReservedMemoryType.
 | 
						|
 | 
						|
  This module sets EFI_MEMORY_XP for attributes of EfiACPIMemoryNVS and EfiReservedMemoryType
 | 
						|
  in UEFI memory map, if and only of PropertiesTable is published and has BIT0 set.
 | 
						|
 | 
						|
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
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.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include <Uefi.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Library/DxeServicesTableLib.h>
 | 
						|
#include <Library/UefiLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Guid/EventGroup.h>
 | 
						|
#include <Guid/PropertiesTable.h>
 | 
						|
 | 
						|
/**
 | 
						|
  Converts a number of EFI_PAGEs to a size in bytes.
 | 
						|
 | 
						|
  NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.
 | 
						|
 | 
						|
  @param  Pages     The number of EFI_PAGES.
 | 
						|
 | 
						|
  @return  The number of bytes associated with the number of EFI_PAGEs specified
 | 
						|
           by Pages.
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EfiPagesToSize (
 | 
						|
  IN UINT64 Pages
 | 
						|
  )
 | 
						|
{
 | 
						|
  return LShiftU64 (Pages, EFI_PAGE_SHIFT);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Set memory attributes according to default policy.
 | 
						|
 | 
						|
  @param  MemoryMap        A pointer to the buffer in which firmware places the current memory map.
 | 
						|
  @param  MemoryMapSize    Size, in bytes, of the MemoryMap buffer.
 | 
						|
  @param  DescriptorSize   size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
SetMemorySpaceAttributesDefault (
 | 
						|
  IN EFI_MEMORY_DESCRIPTOR  *MemoryMap,
 | 
						|
  IN UINTN                  MemoryMapSize,
 | 
						|
  IN UINTN                  DescriptorSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_MEMORY_DESCRIPTOR       *MemoryMapEntry;
 | 
						|
  EFI_MEMORY_DESCRIPTOR       *MemoryMapEnd;
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
 | 
						|
  DEBUG ((EFI_D_INFO, "SetMemorySpaceAttributesDefault\n"));
 | 
						|
 | 
						|
  MemoryMapEntry = MemoryMap;
 | 
						|
  MemoryMapEnd   = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);
 | 
						|
  while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
 | 
						|
    if (MemoryMapEntry->PhysicalStart < BASE_1MB) {
 | 
						|
      //
 | 
						|
      // Do not touch memory space below 1MB
 | 
						|
      //
 | 
						|
      MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    switch (MemoryMapEntry->Type) {
 | 
						|
    case EfiRuntimeServicesCode:
 | 
						|
    case EfiRuntimeServicesData:
 | 
						|
      //
 | 
						|
      // should be handled later;
 | 
						|
      //
 | 
						|
      break;
 | 
						|
    case EfiReservedMemoryType:
 | 
						|
    case EfiACPIMemoryNVS:
 | 
						|
      //
 | 
						|
      // Handle EfiReservedMemoryType and EfiACPIMemoryNVS, because there might be firmware executable there.
 | 
						|
      //
 | 
						|
      DEBUG ((EFI_D_INFO, "SetMemorySpaceAttributes - %016lx - %016lx (%016lx) ...\n",
 | 
						|
        MemoryMapEntry->PhysicalStart,
 | 
						|
        MemoryMapEntry->PhysicalStart + EfiPagesToSize (MemoryMapEntry->NumberOfPages),
 | 
						|
        MemoryMapEntry->Attribute
 | 
						|
        ));
 | 
						|
      Status = gDS->SetMemorySpaceCapabilities (
 | 
						|
                      MemoryMapEntry->PhysicalStart,
 | 
						|
                      EfiPagesToSize (MemoryMapEntry->NumberOfPages),
 | 
						|
                      MemoryMapEntry->Attribute | EFI_MEMORY_XP
 | 
						|
                      );
 | 
						|
      DEBUG ((EFI_D_INFO, "SetMemorySpaceCapabilities - %r\n", Status));
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
 | 
						|
  }
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Update memory attributes according to default policy.
 | 
						|
 | 
						|
  @param[in]  Event     The Event this notify function registered to.
 | 
						|
  @param[in]  Context   Pointer to the context data registered to the Event.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
UpdateMemoryAttributesDefault (
 | 
						|
  EFI_EVENT                               Event,
 | 
						|
  VOID                                    *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  EFI_MEMORY_DESCRIPTOR       *MemoryMap;
 | 
						|
  UINTN                       MemoryMapSize;
 | 
						|
  UINTN                       MapKey;
 | 
						|
  UINTN                       DescriptorSize;
 | 
						|
  UINT32                      DescriptorVersion;
 | 
						|
  EFI_PROPERTIES_TABLE        *PropertiesTable;
 | 
						|
 | 
						|
  DEBUG ((EFI_D_INFO, "UpdateMemoryAttributesDefault\n"));
 | 
						|
  Status = EfiGetSystemConfigurationTable (&gEfiPropertiesTableGuid, (VOID **) &PropertiesTable);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (PropertiesTable != NULL);
 | 
						|
 | 
						|
  DEBUG ((EFI_D_INFO, "MemoryProtectionAttribute - 0x%016lx\n", PropertiesTable->MemoryProtectionAttribute));
 | 
						|
  if ((PropertiesTable->MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the EFI memory map.
 | 
						|
  //
 | 
						|
  MemoryMapSize  = 0;
 | 
						|
  MemoryMap      = NULL;
 | 
						|
  Status = gBS->GetMemoryMap (
 | 
						|
                  &MemoryMapSize,
 | 
						|
                  MemoryMap,
 | 
						|
                  &MapKey,
 | 
						|
                  &DescriptorSize,
 | 
						|
                  &DescriptorVersion
 | 
						|
                  );
 | 
						|
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
 | 
						|
  do {
 | 
						|
    MemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (MemoryMapSize);
 | 
						|
    ASSERT (MemoryMap != NULL);
 | 
						|
    Status = gBS->GetMemoryMap (
 | 
						|
                    &MemoryMapSize,
 | 
						|
                    MemoryMap,
 | 
						|
                    &MapKey,
 | 
						|
                    &DescriptorSize,
 | 
						|
                    &DescriptorVersion
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (MemoryMap);
 | 
						|
    }
 | 
						|
  } while (Status == EFI_BUFFER_TOO_SMALL);
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  SetMemorySpaceAttributesDefault (MemoryMap, MemoryMapSize, DescriptorSize);
 | 
						|
 | 
						|
Done:
 | 
						|
  gBS->CloseEvent (Event);
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  The entrypoint of properties table attribute driver.
 | 
						|
 | 
						|
  @param  ImageHandle    The firmware allocated handle for the EFI image.
 | 
						|
  @param  SystemTable    A pointer to the EFI System Table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS    It always returns EFI_SUCCESS.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InitializePropertiesTableAttributesDxe (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  EFI_EVENT   ReadyToBootEvent;
 | 
						|
 | 
						|
  Status = gBS->CreateEventEx (
 | 
						|
                  EVT_NOTIFY_SIGNAL,
 | 
						|
                  TPL_CALLBACK,
 | 
						|
                  UpdateMemoryAttributesDefault,
 | 
						|
                  NULL,
 | 
						|
                  &gEfiEventReadyToBootGuid,
 | 
						|
                  &ReadyToBootEvent
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |