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 33 EFI_STATUS 34 EFIAPI 35 MemoryPeim ( 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? 41 VOID 42 BuildMemoryTypeInformationHob ( 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 76 Routine Description: 77 78 79 80 Arguments: 81 82 FileHandle - Handle of the file being invoked. 83 PeiServices - Describes the list of possible PEI Services. 84 85 Returns: 86 87 Status - EFI_SUCCESS if the boot mode could be set 88 89 --*/ 90 EFI_STATUS 91 EFIAPI 92 InitializeMemory ( 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