1/** @file 2* 3* Copyright (c) 2011, ARM Limited. All rights reserved. 4* 5* This program and the accompanying materials 6* are licensed and made available under the terms and conditions of the BSD License 7* which accompanies this distribution. The full text of the license may be found at 8* http://opensource.org/licenses/bsd-license.php 9* 10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12* 13**/ 14 15#include <PiPei.h> 16 17// 18// The protocols, PPI and GUID defintions for this module 19// 20#include <Ppi/MasterBootMode.h> 21#include <Ppi/BootInRecoveryMode.h> 22#include <Guid/MemoryTypeInformation.h> 23// 24// The Library classes this module consumes 25// 26#include <Library/ArmPlatformLib.h> 27#include <Library/DebugLib.h> 28#include <Library/HobLib.h> 29#include <Library/PeimEntryPoint.h> 30#include <Library/PeiServicesLib.h> 31#include <Library/PcdLib.h> 32 33EFI_STATUS 34EFIAPI 35MemoryPeim ( 36 IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, 37 IN UINT64 UefiMemorySize 38 ); 39 40// May want to put this into a library so you only need the PCD settings if you are using the feature? 41VOID 42BuildMemoryTypeInformationHob ( 43 VOID 44 ) 45{ 46 EFI_MEMORY_TYPE_INFORMATION Info[10]; 47 48 Info[0].Type = EfiACPIReclaimMemory; 49 Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory); 50 Info[1].Type = EfiACPIMemoryNVS; 51 Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS); 52 Info[2].Type = EfiReservedMemoryType; 53 Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType); 54 Info[3].Type = EfiRuntimeServicesData; 55 Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData); 56 Info[4].Type = EfiRuntimeServicesCode; 57 Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode); 58 Info[5].Type = EfiBootServicesCode; 59 Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode); 60 Info[6].Type = EfiBootServicesData; 61 Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData); 62 Info[7].Type = EfiLoaderCode; 63 Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode); 64 Info[8].Type = EfiLoaderData; 65 Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData); 66 67 // Terminator for the list 68 Info[9].Type = EfiMaxMemoryType; 69 Info[9].NumberOfPages = 0; 70 71 BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info)); 72} 73 74/*++ 75 76Routine Description: 77 78 79 80Arguments: 81 82 FileHandle - Handle of the file being invoked. 83 PeiServices - Describes the list of possible PEI Services. 84 85Returns: 86 87 Status - EFI_SUCCESS if the boot mode could be set 88 89--*/ 90EFI_STATUS 91EFIAPI 92InitializeMemory ( 93 IN EFI_PEI_FILE_HANDLE FileHandle, 94 IN CONST EFI_PEI_SERVICES **PeiServices 95 ) 96{ 97 EFI_STATUS Status; 98 UINTN SystemMemoryBase; 99 UINT64 SystemMemoryTop; 100 UINTN FdBase; 101 UINTN FdTop; 102 UINTN UefiMemoryBase; 103 104 DEBUG ((EFI_D_LOAD | EFI_D_INFO, "Memory Init PEIM Loaded\n")); 105 106 // 107 // Initialize the System Memory (DRAM) 108 // 109 if (!FeaturePcdGet (PcdSystemMemoryInitializeInSec)) { 110 // In case the DRAM has not been initialized by the secure firmware 111 ArmPlatformInitializeSystemMemory (); 112 } 113 114 // Ensure PcdSystemMemorySize has been set 115 ASSERT (PcdGet64 (PcdSystemMemorySize) != 0); 116 ASSERT (PcdGet64 (PcdSystemMemoryBase) < (UINT64)MAX_ADDRESS); 117 118 SystemMemoryBase = (UINTN)PcdGet64 (PcdSystemMemoryBase); 119 SystemMemoryTop = SystemMemoryBase + PcdGet64 (PcdSystemMemorySize); 120 if (SystemMemoryTop - 1 > MAX_ADDRESS) { 121 SystemMemoryTop = (UINT64)MAX_ADDRESS + 1; 122 } 123 FdBase = (UINTN)PcdGet64 (PcdFdBaseAddress); 124 FdTop = FdBase + (UINTN)PcdGet32 (PcdFdSize); 125 126 // 127 // Declare the UEFI memory to PEI 128 // 129 130 // In case the firmware has been shadowed in the System Memory 131 if ((FdBase >= SystemMemoryBase) && (FdTop <= SystemMemoryTop)) { 132 // Check if there is enough space between the top of the system memory and the top of the 133 // firmware to place the UEFI memory (for PEI & DXE phases) 134 if (SystemMemoryTop - FdTop >= FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) { 135 UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); 136 } else { 137 // Check there is enough space for the UEFI memory 138 ASSERT (SystemMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) <= FdBase); 139 140 UefiMemoryBase = FdBase - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); 141 } 142 } else { 143 // Check the Firmware does not overlapped with the system memory 144 ASSERT ((FdBase < SystemMemoryBase) || (FdBase >= SystemMemoryTop)); 145 ASSERT ((FdTop <= SystemMemoryBase) || (FdTop > SystemMemoryTop)); 146 147 UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); 148 } 149 150 Status = PeiServicesInstallPeiMemory (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); 151 ASSERT_EFI_ERROR (Status); 152 153 // Initialize MMU and Memory HOBs (Resource Descriptor HOBs) 154 Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); 155 ASSERT_EFI_ERROR (Status); 156 157 return Status; 158} 159