3 * Copyright (c) 2011, ARM Limited. All rights reserved.
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
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.
16 // The package level header files this module uses
20 // The protocols, PPI and GUID defintions for this module
22 #include <Ppi/MasterBootMode.h>
23 #include <Ppi/BootInRecoveryMode.h>
24 #include <Guid/MemoryTypeInformation.h>
26 // The Library classes this module consumes
28 #include <Library/DebugLib.h>
29 #include <Library/PeimEntryPoint.h>
30 #include <Library/PcdLib.h>
31 #include <Library/HobLib.h>
32 #include <Library/PeiServicesLib.h>
33 #include <Library/ArmLib.h>
34 #include <Library/IoLib.h>
35 #include <Library/MemoryAllocationLib.h>
36 #include <Library/ArmPlatformLib.h>
47 ARM_MEMORY_REGION_DESCRIPTOR
*MemoryTable
;
48 VOID
*TranslationTableBase
;
49 UINTN TranslationTableSize
;
51 // Get Virtual Memory Map from the Platform Library
52 ArmPlatformGetVirtualMemoryMap(&MemoryTable
);
54 //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
55 // DRAM (even at the top of DRAM as it is the first permanent memory allocation)
56 ArmConfigureMmu (MemoryTable
, &TranslationTableBase
, &TranslationTableSize
);
59 // May want to put this into a library so you only need the PCD setings if you are using the feature?
61 BuildMemoryTypeInformationHob (
65 EFI_MEMORY_TYPE_INFORMATION Info
[10];
67 Info
[0].Type
= EfiACPIReclaimMemory
;
68 Info
[0].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory
);
69 Info
[1].Type
= EfiACPIMemoryNVS
;
70 Info
[1].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS
);
71 Info
[2].Type
= EfiReservedMemoryType
;
72 Info
[2].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiReservedMemoryType
);
73 Info
[3].Type
= EfiRuntimeServicesData
;
74 Info
[3].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData
);
75 Info
[4].Type
= EfiRuntimeServicesCode
;
76 Info
[4].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode
);
77 Info
[5].Type
= EfiBootServicesCode
;
78 Info
[5].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiBootServicesCode
);
79 Info
[6].Type
= EfiBootServicesData
;
80 Info
[6].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiBootServicesData
);
81 Info
[7].Type
= EfiLoaderCode
;
82 Info
[7].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiLoaderCode
);
83 Info
[8].Type
= EfiLoaderData
;
84 Info
[8].NumberOfPages
= PcdGet32 (PcdMemoryTypeEfiLoaderData
);
86 // Terminator for the list
87 Info
[9].Type
= EfiMaxMemoryType
;
88 Info
[9].NumberOfPages
= 0;
91 BuildGuidDataHob (&gEfiMemoryTypeInformationGuid
, &Info
, sizeof (Info
));
102 FileHandle - Handle of the file being invoked.
103 PeiServices - Describes the list of possible PEI Services.
107 Status - EFI_SUCCESS if the boot mode could be set
113 IN EFI_PEI_FILE_HANDLE FileHandle
,
114 IN CONST EFI_PEI_SERVICES
**PeiServices
118 EFI_RESOURCE_ATTRIBUTE_TYPE Attributes
;
119 ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR
* EfiMemoryMap
;
121 UINTN SystemMemoryTop
;
122 UINTN UefiMemoryBase
;
123 UINTN UefiMemorySize
;
125 DEBUG ((EFI_D_ERROR
, "Memory Init PEIM Loaded\n"));
127 // Ensure PcdSystemMemorySize has been set
128 ASSERT (FixedPcdGet32 (PcdSystemMemorySize
) != 0);
130 SystemMemoryTop
= FixedPcdGet32 (PcdSystemMemoryBase
) + FixedPcdGet32 (PcdSystemMemorySize
);
133 // Initialize the System Memory (DRAM)
135 if (FeaturePcdGet(PcdStandalone
)) {
136 // In case of a standalone version, the DRAM is already initialized
137 ArmPlatformInitializeSystemMemory();
141 // Declare the UEFI memory to PEI
143 if (FeaturePcdGet(PcdStandalone
)) {
144 // In case of standalone UEFI, we set the UEFI memory region at the top of the DRAM
145 UefiMemoryBase
= SystemMemoryTop
- FixedPcdGet32 (PcdSystemMemoryUefiRegionSize
);
147 // In case of a non standalone UEFI, we set the UEFI memory below the Firmware Volume
148 UefiMemoryBase
= FixedPcdGet32 (PcdNormalFdBaseAddress
) - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize
);
150 UefiMemorySize
= FixedPcdGet32 (PcdSystemMemoryUefiRegionSize
);
151 Status
= PeiServicesInstallPeiMemory (UefiMemoryBase
,UefiMemorySize
);
152 ASSERT_EFI_ERROR (Status
);
155 // Now, the permanent memory has been installed, we can call AllocatePages()
158 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
159 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
160 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
161 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
162 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
163 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
|
164 EFI_RESOURCE_ATTRIBUTE_TESTED
167 // If it is not a standalone build we must reserved the space above the base address of the firmware volume
168 if (!FeaturePcdGet(PcdStandalone
)) {
169 // Check if firmware volume has not be copied at the top of DRAM then we must reserve the extra space
170 // between the firmware and the top
171 if (SystemMemoryTop
!= FixedPcdGet32 (PcdNormalFdBaseAddress
) + FixedPcdGet32 (PcdNormalFdSize
)) {
172 BuildResourceDescriptorHob (
173 EFI_RESOURCE_SYSTEM_MEMORY
,
174 Attributes
& (~EFI_RESOURCE_ATTRIBUTE_TESTED
),
175 FixedPcdGet32 (PcdNormalFdBaseAddress
) + FixedPcdGet32 (PcdNormalFdSize
),
176 SystemMemoryTop
- (FixedPcdGet32 (PcdNormalFdBaseAddress
) + FixedPcdGet32 (PcdNormalFdSize
))
180 // Reserved the memory space occupied by the firmware volume
181 BuildResourceDescriptorHob (
182 EFI_RESOURCE_SYSTEM_MEMORY
,
183 Attributes
& (~EFI_RESOURCE_ATTRIBUTE_PRESENT
),
184 (UINT32
)FixedPcdGet32 (PcdNormalFdBaseAddress
),
185 (UINT32
)FixedPcdGet32 (PcdNormalFdSize
)
189 // Check there is no overlap between UEFI and Fix Address Regions
190 ASSERT (FixedPcdGet32 (PcdSystemMemoryBase
) + FixedPcdGet32 (PcdSystemMemoryFixRegionSize
) <= UefiMemoryBase
);
192 // Reserved the UEFI Memory Region
193 BuildResourceDescriptorHob (
194 EFI_RESOURCE_SYSTEM_MEMORY
,
200 // Reserved the Fix Address Region
201 BuildResourceDescriptorHob (
202 EFI_RESOURCE_SYSTEM_MEMORY
,
204 FixedPcdGet32 (PcdSystemMemoryBase
),
205 FixedPcdGet32 (PcdSystemMemoryFixRegionSize
)
208 // Reserved the memory between UEFI and Fix Address regions
209 if (FixedPcdGet32 (PcdSystemMemoryBase
) + FixedPcdGet32 (PcdSystemMemoryFixRegionSize
) != UefiMemoryBase
) {
210 BuildResourceDescriptorHob (
211 EFI_RESOURCE_SYSTEM_MEMORY
,
212 Attributes
& (~EFI_RESOURCE_ATTRIBUTE_TESTED
),
213 FixedPcdGet32 (PcdSystemMemoryBase
) + FixedPcdGet32 (PcdSystemMemoryFixRegionSize
),
214 UefiMemoryBase
- (FixedPcdGet32 (PcdSystemMemoryBase
) + FixedPcdGet32 (PcdSystemMemoryFixRegionSize
))
218 // If a platform has system memory extensions, it can declare those in this function
219 Status
= ArmPlatformGetAdditionalSystemMemory (&EfiMemoryMap
);
220 if (!EFI_ERROR(Status
)) {
221 // Install the EFI Memory Map
222 for (Index
= 0; EfiMemoryMap
[Index
].ResourceAttribute
!= 0; Index
++) {
223 BuildResourceDescriptorHob (
224 EFI_RESOURCE_SYSTEM_MEMORY
,
225 EfiMemoryMap
[Index
].ResourceAttribute
,
226 EfiMemoryMap
[Index
].PhysicalStart
,
227 EfiMemoryMap
[Index
].NumberOfBytes
230 FreePool (EfiMemoryMap
);
233 // Build Memory Allocation Hob
236 if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob
)) {
237 // Optional feature that helps prevent EFI memory map fragmentation.
238 BuildMemoryTypeInformationHob ();