MemoryInitPeiLib.c revision bb5420bb2b5fa146de1ddf2da5932b214e5743a9
1/** @file 2* 3* Copyright (c) 2011-2014, 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#include <Library/ArmPlatformLib.h> 18#include <Library/DebugLib.h> 19#include <Library/HobLib.h> 20#include <Library/MemoryAllocationLib.h> 21#include <Library/PcdLib.h> 22 23VOID 24BuildMemoryTypeInformationHob ( 25 VOID 26 ); 27 28VOID 29InitMmu ( 30 VOID 31 ) 32{ 33 ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable; 34 VOID *TranslationTableBase; 35 UINTN TranslationTableSize; 36 RETURN_STATUS Status; 37 38 // Get Virtual Memory Map from the Platform Library 39 ArmPlatformGetVirtualMemoryMap (&MemoryTable); 40 41 //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in 42 // DRAM (even at the top of DRAM as it is the first permanent memory allocation) 43 Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize); 44 if (EFI_ERROR (Status)) { 45 DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n")); 46 } 47} 48 49/*++ 50 51Routine Description: 52 53 54 55Arguments: 56 57 FileHandle - Handle of the file being invoked. 58 PeiServices - Describes the list of possible PEI Services. 59 60Returns: 61 62 Status - EFI_SUCCESS if the boot mode could be set 63 64--*/ 65EFI_STATUS 66EFIAPI 67MemoryPeim ( 68 IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, 69 IN UINT64 UefiMemorySize 70 ) 71{ 72 EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; 73 UINT64 ResourceLength; 74 EFI_PEI_HOB_POINTERS NextHob; 75 EFI_PHYSICAL_ADDRESS FdTop; 76 EFI_PHYSICAL_ADDRESS SystemMemoryTop; 77 EFI_PHYSICAL_ADDRESS ResourceTop; 78 BOOLEAN Found; 79 80 // Ensure PcdSystemMemorySize has been set 81 ASSERT (PcdGet64 (PcdSystemMemorySize) != 0); 82 83 // 84 // Now, the permanent memory has been installed, we can call AllocatePages() 85 // 86 ResourceAttributes = ( 87 EFI_RESOURCE_ATTRIBUTE_PRESENT | 88 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 89 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | 90 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | 91 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | 92 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | 93 EFI_RESOURCE_ATTRIBUTE_TESTED 94 ); 95 96 // Reserved the memory space occupied by the firmware volume 97 BuildResourceDescriptorHob ( 98 EFI_RESOURCE_SYSTEM_MEMORY, 99 ResourceAttributes, 100 PcdGet64 (PcdSystemMemoryBase), 101 PcdGet64 (PcdSystemMemorySize) 102 ); 103 104 SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemoryBase) + (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemorySize); 105 FdTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFdBaseAddress) + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFdSize); 106 107 // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE 108 // core to overwrite this area we must mark the region with the attribute non-present 109 if ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) { 110 Found = FALSE; 111 112 // Search for System Memory Hob that contains the firmware 113 NextHob.Raw = GetHobList (); 114 while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) { 115 if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) && 116 (PcdGet64 (PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) && 117 (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength)) 118 { 119 ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute; 120 ResourceLength = NextHob.ResourceDescriptor->ResourceLength; 121 ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength; 122 123 if (PcdGet64 (PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) { 124 if (SystemMemoryTop == FdTop) { 125 NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT; 126 } else { 127 // Create the System Memory HOB for the firmware with the non-present attribute 128 BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, 129 ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT, 130 PcdGet64 (PcdFdBaseAddress), 131 PcdGet32 (PcdFdSize)); 132 133 // Top of the FD is system memory available for UEFI 134 NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize); 135 NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize); 136 } 137 } else { 138 // Create the System Memory HOB for the firmware with the non-present attribute 139 BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, 140 ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT, 141 PcdGet64 (PcdFdBaseAddress), 142 PcdGet32 (PcdFdSize)); 143 144 // Update the HOB 145 NextHob.ResourceDescriptor->ResourceLength = PcdGet64 (PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart; 146 147 // If there is some memory available on the top of the FD then create a HOB 148 if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) { 149 // Create the System Memory HOB for the remaining region (top of the FD) 150 BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, 151 ResourceAttributes, 152 FdTop, 153 ResourceTop - FdTop); 154 } 155 } 156 Found = TRUE; 157 break; 158 } 159 NextHob.Raw = GET_NEXT_HOB (NextHob); 160 } 161 162 ASSERT(Found); 163 } 164 165 // Build Memory Allocation Hob 166 InitMmu (); 167 168 if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { 169 // Optional feature that helps prevent EFI memory map fragmentation. 170 BuildMemoryTypeInformationHob (); 171 } 172 173 return EFI_SUCCESS; 174} 175