__FUNCTION__ is a pre-standard extension that gcc and Visual C++ among others support, while __func__ was standardized in C99. Since it's more standard, replace __FUNCTION__ with __func__ throughout OvmfPkg. Signed-off-by: Rebecca Cran <rebecca@bsdio.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
		
			
				
	
	
		
			336 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			336 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Memory Detection for Virtual Machines.
 | 
						|
 | 
						|
  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
 | 
						|
  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
Module Name:
 | 
						|
 | 
						|
  MemDetect.c
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
//
 | 
						|
// The package level header files this module uses
 | 
						|
//
 | 
						|
#include <PiPei.h>
 | 
						|
 | 
						|
//
 | 
						|
// The Library classes this module consumes
 | 
						|
//
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/HobLib.h>
 | 
						|
#include <Library/IoLib.h>
 | 
						|
#include <Library/PcdLib.h>
 | 
						|
#include <Library/PeimEntryPoint.h>
 | 
						|
#include <Library/ResourcePublicationLib.h>
 | 
						|
#include <Library/BaseRiscVSbiLib.h>
 | 
						|
#include <Register/RiscV64/RiscVEncoding.h>
 | 
						|
#include <Library/PrePiLib.h>
 | 
						|
#include <libfdt.h>
 | 
						|
#include <Guid/FdtHob.h>
 | 
						|
 | 
						|
VOID
 | 
						|
BuildMemoryTypeInformationHob (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Create memory range resource HOB using the memory base
 | 
						|
  address and size.
 | 
						|
 | 
						|
  @param  MemoryBase     Memory range base address.
 | 
						|
  @param  MemorySize     Memory range size.
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
AddMemoryBaseSizeHob (
 | 
						|
  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
 | 
						|
  IN UINT64                MemorySize
 | 
						|
  )
 | 
						|
{
 | 
						|
  BuildResourceDescriptorHob (
 | 
						|
    EFI_RESOURCE_SYSTEM_MEMORY,
 | 
						|
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
 | 
						|
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
 | 
						|
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
 | 
						|
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
 | 
						|
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
 | 
						|
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
 | 
						|
    EFI_RESOURCE_ATTRIBUTE_TESTED,
 | 
						|
    MemoryBase,
 | 
						|
    MemorySize
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Create memory range resource HOB using memory base
 | 
						|
  address and top address of the memory range.
 | 
						|
 | 
						|
  @param  MemoryBase     Memory range base address.
 | 
						|
  @param  MemoryLimit    Memory range size.
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
AddMemoryRangeHob (
 | 
						|
  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
 | 
						|
  IN EFI_PHYSICAL_ADDRESS  MemoryLimit
 | 
						|
  )
 | 
						|
{
 | 
						|
  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Configure MMU
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
InitMmu (
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Set supervisor translation mode to Bare mode
 | 
						|
  //
 | 
						|
  RiscVSetSupervisorAddressTranslationRegister ((UINT64)SATP_MODE_OFF << 60);
 | 
						|
  DEBUG ((DEBUG_INFO, "%a: Set Supervisor address mode to bare-metal mode.\n", __func__));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Publish system RAM and reserve memory regions.
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
InitializeRamRegions (
 | 
						|
  IN EFI_PHYSICAL_ADDRESS  SystemMemoryBase,
 | 
						|
  IN UINT64                SystemMemorySize
 | 
						|
  )
 | 
						|
{
 | 
						|
  AddMemoryRangeHob (
 | 
						|
    SystemMemoryBase,
 | 
						|
    SystemMemoryBase + SystemMemorySize
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
/** Get the number of cells for a given property
 | 
						|
 | 
						|
  @param[in]  Fdt   Pointer to Device Tree (DTB)
 | 
						|
  @param[in]  Node  Node
 | 
						|
  @param[in]  Name  Name of the property
 | 
						|
 | 
						|
  @return           Number of cells.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
INT32
 | 
						|
GetNumCells (
 | 
						|
  IN VOID         *Fdt,
 | 
						|
  IN INT32        Node,
 | 
						|
  IN CONST CHAR8  *Name
 | 
						|
  )
 | 
						|
{
 | 
						|
  CONST INT32  *Prop;
 | 
						|
  INT32        Len;
 | 
						|
  UINT32       Val;
 | 
						|
 | 
						|
  Prop = fdt_getprop (Fdt, Node, Name, &Len);
 | 
						|
  if (Prop == NULL) {
 | 
						|
    return Len;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Len != sizeof (*Prop)) {
 | 
						|
    return -FDT_ERR_BADNCELLS;
 | 
						|
  }
 | 
						|
 | 
						|
  Val = fdt32_to_cpu (*Prop);
 | 
						|
  if (Val > FDT_MAX_NCELLS) {
 | 
						|
    return -FDT_ERR_BADNCELLS;
 | 
						|
  }
 | 
						|
 | 
						|
  return (INT32)Val;
 | 
						|
}
 | 
						|
 | 
						|
/** Mark reserved memory ranges in the EFI memory map
 | 
						|
 | 
						|
  The M-mode firmware ranges should not be used by the
 | 
						|
  EDK2/OS. These ranges are passed via device tree using reserved
 | 
						|
  memory nodes. Parse the DT and mark those ranges as of
 | 
						|
  type EfiReservedMemoryType.
 | 
						|
 | 
						|
  NOTE: Device Tree spec section 3.5.4 says reserved memory regions
 | 
						|
  without no-map property should be installed as EfiBootServicesData.
 | 
						|
  As per UEFI spec, memory of type EfiBootServicesData can be used
 | 
						|
  by the OS after ExitBootServices().
 | 
						|
  This is not an issue for DT since OS can parse the DT also along
 | 
						|
  with EFI memory map and avoid using these ranges. But with ACPI,
 | 
						|
  there is no such mechanisms possible.
 | 
						|
  Since EDK2 needs to support both DT and ACPI, we are deviating
 | 
						|
  from the DT spec and marking all reserved memory ranges as
 | 
						|
  EfiReservedMemoryType itself irrespective of no-map.
 | 
						|
 | 
						|
  @param FdtPointer Pointer to FDT
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
AddReservedMemoryMap (
 | 
						|
  IN VOID  *FdtPointer
 | 
						|
  )
 | 
						|
{
 | 
						|
  CONST INT32           *RegProp;
 | 
						|
  INT32                 Node;
 | 
						|
  INT32                 SubNode;
 | 
						|
  INT32                 Len;
 | 
						|
  EFI_PHYSICAL_ADDRESS  Addr;
 | 
						|
  UINT64                Size;
 | 
						|
  INTN                  NumRsv, i;
 | 
						|
  INT32                 NumAddrCells, NumSizeCells;
 | 
						|
 | 
						|
  NumRsv = fdt_num_mem_rsv (FdtPointer);
 | 
						|
 | 
						|
  /* Look for an existing entry and add it to the efi mem map. */
 | 
						|
  for (i = 0; i < NumRsv; i++) {
 | 
						|
    if (fdt_get_mem_rsv (FdtPointer, i, &Addr, &Size) != 0) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    BuildMemoryAllocationHob (
 | 
						|
      Addr,
 | 
						|
      Size,
 | 
						|
      EfiReservedMemoryType
 | 
						|
      );
 | 
						|
  }
 | 
						|
 | 
						|
  /* process reserved-memory */
 | 
						|
  Node = fdt_subnode_offset (FdtPointer, 0, "reserved-memory");
 | 
						|
  if (Node >= 0) {
 | 
						|
    NumAddrCells = GetNumCells (FdtPointer, Node, "#address-cells");
 | 
						|
    if (NumAddrCells <= 0) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    NumSizeCells = GetNumCells (FdtPointer, Node, "#size-cells");
 | 
						|
    if (NumSizeCells <= 0) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    fdt_for_each_subnode (SubNode, FdtPointer, Node) {
 | 
						|
      RegProp = fdt_getprop (FdtPointer, SubNode, "reg", &Len);
 | 
						|
 | 
						|
      if ((RegProp != 0) && (Len == ((NumAddrCells + NumSizeCells) * sizeof (INT32)))) {
 | 
						|
        Addr = fdt32_to_cpu (RegProp[0]);
 | 
						|
 | 
						|
        if (NumAddrCells > 1) {
 | 
						|
          Addr = (Addr << 32) | fdt32_to_cpu (RegProp[1]);
 | 
						|
        }
 | 
						|
 | 
						|
        RegProp += NumAddrCells;
 | 
						|
        Size     = fdt32_to_cpu (RegProp[0]);
 | 
						|
 | 
						|
        if (NumSizeCells > 1) {
 | 
						|
          Size = (Size << 32) | fdt32_to_cpu (RegProp[1]);
 | 
						|
        }
 | 
						|
 | 
						|
        DEBUG ((
 | 
						|
          DEBUG_INFO,
 | 
						|
          "%a: Adding Reserved Memory Addr = 0x%llx, Size = 0x%llx\n",
 | 
						|
          __func__,
 | 
						|
          Addr,
 | 
						|
          Size
 | 
						|
          ));
 | 
						|
 | 
						|
        BuildMemoryAllocationHob (
 | 
						|
          Addr,
 | 
						|
          Size,
 | 
						|
          EfiReservedMemoryType
 | 
						|
          );
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize memory hob based on the DTB information.
 | 
						|
 | 
						|
  @return EFI_SUCCESS     The memory hob added successfully.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MemoryPeimInitialization (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
 | 
						|
  CONST UINT64                *RegProp;
 | 
						|
  CONST CHAR8                 *Type;
 | 
						|
  UINT64                      CurBase, CurSize;
 | 
						|
  INT32                       Node, Prev;
 | 
						|
  INT32                       Len;
 | 
						|
  VOID                        *FdtPointer;
 | 
						|
 | 
						|
  FirmwareContext = NULL;
 | 
						|
  GetFirmwareContextPointer (&FirmwareContext);
 | 
						|
 | 
						|
  if (FirmwareContext == NULL) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __func__));
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  FdtPointer = (VOID *)FirmwareContext->FlattenedDeviceTree;
 | 
						|
  if (FdtPointer == NULL) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "%a: Invalid FDT pointer\n", __func__));
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  // Look for the lowest memory node
 | 
						|
  for (Prev = 0; ; Prev = Node) {
 | 
						|
    Node = fdt_next_node (FdtPointer, Prev, NULL);
 | 
						|
    if (Node < 0) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    // Check for memory node
 | 
						|
    Type = fdt_getprop (FdtPointer, Node, "device_type", &Len);
 | 
						|
    if (Type && (AsciiStrnCmp (Type, "memory", Len) == 0)) {
 | 
						|
      // Get the 'reg' property of this node. For now, we will assume
 | 
						|
      // two 8 byte quantities for base and size, respectively.
 | 
						|
      RegProp = fdt_getprop (FdtPointer, Node, "reg", &Len);
 | 
						|
      if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) {
 | 
						|
        CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
 | 
						|
        CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
 | 
						|
 | 
						|
        DEBUG ((
 | 
						|
          DEBUG_INFO,
 | 
						|
          "%a: System RAM @ 0x%lx - 0x%lx\n",
 | 
						|
          __func__,
 | 
						|
          CurBase,
 | 
						|
          CurBase + CurSize - 1
 | 
						|
          ));
 | 
						|
 | 
						|
        InitializeRamRegions (
 | 
						|
          CurBase,
 | 
						|
          CurSize
 | 
						|
          );
 | 
						|
      } else {
 | 
						|
        DEBUG ((
 | 
						|
          DEBUG_ERROR,
 | 
						|
          "%a: Failed to parse FDT memory node\n",
 | 
						|
          __func__
 | 
						|
          ));
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  AddReservedMemoryMap (FdtPointer);
 | 
						|
 | 
						|
  InitMmu ();
 | 
						|
 | 
						|
  BuildMemoryTypeInformationHob ();
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |