]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/MemoryInitPei/MemoryInit.c
ArmPlatformPkg/ArmPlatformLib: Move the UEFI memory partionning to MemoryInitPei
[mirror_edk2.git] / ArmPlatformPkg / MemoryInitPei / MemoryInit.c
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 //
16 // The package level header files this module uses
17 //
18 #include <PiPei.h>
19 //
20 // The protocols, PPI and GUID defintions for this module
21 //
22 #include <Ppi/MasterBootMode.h>
23 #include <Ppi/BootInRecoveryMode.h>
24 #include <Guid/MemoryTypeInformation.h>
25 //
26 // The Library classes this module consumes
27 //
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>
37
38 //
39 // Module globals
40 //
41
42 VOID
43 InitMmu (
44 VOID
45 )
46 {
47 ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
48 VOID *TranslationTableBase;
49 UINTN TranslationTableSize;
50
51 // Get Virtual Memory Map from the Platform Library
52 ArmPlatformGetVirtualMemoryMap(&MemoryTable);
53
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);
57 }
58
59 // May want to put this into a library so you only need the PCD setings if you are using the feature?
60 VOID
61 BuildMemoryTypeInformationHob (
62 VOID
63 )
64 {
65 EFI_MEMORY_TYPE_INFORMATION Info[10];
66
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);
85
86 // Terminator for the list
87 Info[9].Type = EfiMaxMemoryType;
88 Info[9].NumberOfPages = 0;
89
90
91 BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
92 }
93
94 /*++
95
96 Routine Description:
97
98
99
100 Arguments:
101
102 FileHandle - Handle of the file being invoked.
103 PeiServices - Describes the list of possible PEI Services.
104
105 Returns:
106
107 Status - EFI_SUCCESS if the boot mode could be set
108
109 --*/
110 EFI_STATUS
111 EFIAPI
112 InitializeMemory (
113 IN EFI_PEI_FILE_HANDLE FileHandle,
114 IN CONST EFI_PEI_SERVICES **PeiServices
115 )
116 {
117 EFI_STATUS Status;
118 EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
119 ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR* EfiMemoryMap;
120 UINTN Index;
121 UINTN SystemMemoryTop;
122 UINTN UefiMemoryBase;
123 UINTN UefiMemorySize;
124
125 DEBUG ((EFI_D_ERROR, "Memory Init PEIM Loaded\n"));
126
127 // Ensure PcdSystemMemorySize has been set
128 ASSERT (FixedPcdGet32 (PcdSystemMemorySize) != 0);
129
130 SystemMemoryTop = FixedPcdGet32 (PcdSystemMemoryBase) + FixedPcdGet32 (PcdSystemMemorySize);
131
132 //
133 // Initialize the System Memory (DRAM)
134 //
135 if (FeaturePcdGet(PcdStandalone)) {
136 // In case of a standalone version, the DRAM is already initialized
137 ArmPlatformInitializeSystemMemory();
138 }
139
140 //
141 // Declare the UEFI memory to PEI
142 //
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);
146 } else {
147 // In case of a non standalone UEFI, we set the UEFI memory below the Firmware Volume
148 UefiMemoryBase = FixedPcdGet32 (PcdNormalFdBaseAddress) - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
149 }
150 UefiMemorySize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
151 Status = PeiServicesInstallPeiMemory (UefiMemoryBase,UefiMemorySize);
152 ASSERT_EFI_ERROR (Status);
153
154 //
155 // Now, the permanent memory has been installed, we can call AllocatePages()
156 //
157 Attributes = (
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
165 );
166
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))
177 );
178 }
179
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)
186 );
187 }
188
189 // Check there is no overlap between UEFI and Fix Address Regions
190 ASSERT (FixedPcdGet32 (PcdSystemMemoryBase) + FixedPcdGet32 (PcdSystemMemoryFixRegionSize) <= UefiMemoryBase);
191
192 // Reserved the UEFI Memory Region
193 BuildResourceDescriptorHob (
194 EFI_RESOURCE_SYSTEM_MEMORY,
195 Attributes,
196 UefiMemoryBase,
197 UefiMemorySize
198 );
199
200 // Reserved the Fix Address Region
201 BuildResourceDescriptorHob (
202 EFI_RESOURCE_SYSTEM_MEMORY,
203 Attributes,
204 FixedPcdGet32 (PcdSystemMemoryBase),
205 FixedPcdGet32 (PcdSystemMemoryFixRegionSize)
206 );
207
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))
215 );
216 }
217
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
228 );
229 }
230 FreePool (EfiMemoryMap);
231 }
232
233 // Build Memory Allocation Hob
234 InitMmu ();
235
236 if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
237 // Optional feature that helps prevent EFI memory map fragmentation.
238 BuildMemoryTypeInformationHob ();
239 }
240
241 return EFI_SUCCESS;
242 }