]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
99bdeb11f9195ee5b13701e46146ab8ac25154f8
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformInitPei / MemoryPeim.c
1 /** @file
2
3 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
4
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 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 Module Name:
15
16
17 MemoryPeim.c
18
19 Abstract:
20
21 Tiano PEIM to provide the platform support functionality.
22 This file implements the Platform Memory Range PPI
23
24 --*/
25
26 #include "PlatformEarlyInit.h"
27
28 //
29 // Need min. of 48MB PEI phase
30 //
31 #define PEI_MIN_MEMORY_SIZE (6 * 0x800000)
32 #define PEI_RECOVERY_MIN_MEMORY_SIZE (6 * 0x800000)
33
34 //
35 // This is the memory needed for PEI to start up DXE.
36 //
37 // Over-estimating this size will lead to higher fragmentation
38 // of main memory. Under-estimation of this will cause catastrophic
39 // failure of PEI to load DXE. Generally, the failure may only be
40 // realized during capsule updates.
41 //
42 #define PRERESERVED_PEI_MEMORY ( \
43 EFI_SIZE_TO_PAGES (3 * 0x800000) /* PEI Core memory based stack */ \
44 )
45
46 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
47 { EfiACPIReclaimMemory, 0x40 }, // 0x40 pages = 256k for ASL
48 { EfiACPIMemoryNVS, 0x100 }, // 0x100 pages = 1 MB for S3, SMM, HII, etc
49 { EfiReservedMemoryType, 0x600 }, // 48k for BIOS Reserved
50 { EfiMemoryMappedIO, 0 },
51 { EfiMemoryMappedIOPortSpace, 0 },
52 { EfiPalCode, 0 },
53 { EfiRuntimeServicesCode, 0x200 },
54 { EfiRuntimeServicesData, 0x100 },
55 { EfiLoaderCode, 0x100 },
56 { EfiLoaderData, 0x100 },
57 { EfiBootServicesCode, 0x800 },
58 { EfiBootServicesData, 0x2500},
59 { EfiConventionalMemory, 0 },
60 { EfiUnusableMemory, 0 },
61 { EfiMaxMemoryType, 0 }
62 };
63
64 STATIC
65 EFI_STATUS
66 GetMemorySize (
67 IN CONST EFI_PEI_SERVICES **PeiServices,
68 OUT UINT64 *LowMemoryLength,
69 OUT UINT64 *HighMemoryLength
70 );
71
72
73
74 EFI_STATUS
75 EFIAPI
76 SetPeiCacheMode (
77 IN CONST EFI_PEI_SERVICES **PeiServices
78 )
79 {
80 EFI_STATUS Status;
81 PEI_CACHE_PPI *CachePpi;
82
83 EFI_BOOT_MODE BootMode;
84 UINT64 MemoryLength;
85 UINT64 MemOverflow;
86 UINT64 MemoryLengthUc;
87 UINT64 MaxMemoryLength;
88 UINT64 LowMemoryLength;
89 UINT64 HighMemoryLength;
90 UINT8 Index;
91 MTRR_SETTINGS MtrrSetting;
92
93 //
94 // Load Cache PPI
95 //
96 Status = (**PeiServices).LocatePpi (
97 PeiServices,
98 &gPeiCachePpiGuid, // GUID
99 0, // Instance
100 NULL, // EFI_PEI_PPI_DESCRIPTOR
101 (void **)&CachePpi // PPI
102 );
103 if (!EFI_ERROR(Status)) {
104 //
105 // Clear the CAR Settings (Default Cache Type => UC)
106 //
107 DEBUG ((EFI_D_INFO, "Reset cache attribute and disable CAR. \n"));
108 CachePpi->ResetCache(
109 (EFI_PEI_SERVICES**)PeiServices,
110 CachePpi
111 );
112 }
113
114
115 //
116 // Variable initialization
117 //
118 LowMemoryLength = 0;
119 HighMemoryLength = 0;
120 MemoryLengthUc = 0;
121
122 Status = (*PeiServices)->GetBootMode (
123 PeiServices,
124 &BootMode
125 );
126
127 //
128 // Determine memory usage
129 //
130 GetMemorySize (
131 PeiServices,
132 &LowMemoryLength,
133 &HighMemoryLength
134 );
135
136 LowMemoryLength = (EFI_PHYSICAL_ADDRESS)MmPci32( 0, 0, 2, 0, 0x70);
137 LowMemoryLength &= 0xFFF00000ULL;
138
139 MaxMemoryLength = LowMemoryLength;
140
141 //
142 // Round up to nearest 256MB with high memory and 64MB w/o high memory
143 //
144 if (HighMemoryLength != 0 ) {
145 MemOverflow = (LowMemoryLength & 0x0fffffff);
146 if (MemOverflow != 0) {
147 MaxMemoryLength = LowMemoryLength + (0x10000000 - MemOverflow);
148 }
149 } else {
150 MemOverflow = (LowMemoryLength & 0x03ffffff);
151 if (MemOverflow != 0) {
152 MaxMemoryLength = LowMemoryLength + (0x4000000 - MemOverflow);
153 }
154 }
155
156 ZeroMem (&MtrrSetting, sizeof(MTRR_SETTINGS));
157 for (Index = 0; Index < 2; Index++) {
158 MtrrSetting.Fixed.Mtrr[Index]=0x0606060606060606;
159 }
160 for (Index = 2; Index < 11; Index++) {
161 MtrrSetting.Fixed.Mtrr[Index]=0x0505050505050505;
162 }
163
164 //
165 // Cache the flash area to improve the boot performance in PEI phase
166 //
167 Index = 0;
168 MtrrSetting.Variables.Mtrr[0].Base = (FixedPcdGet32 (PcdFlashAreaBaseAddress) | CacheWriteProtected);
169 MtrrSetting.Variables.Mtrr[0].Mask = ((~((UINT64)(FixedPcdGet32 (PcdFlashAreaSize) - 1))) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED;
170 Index ++;
171
172 MemOverflow =0;
173 while (MaxMemoryLength > MemOverflow){
174 MtrrSetting.Variables.Mtrr[Index].Base = (MemOverflow & MTRR_LIB_CACHE_VALID_ADDRESS) | CacheWriteBack;
175 MemoryLength = MaxMemoryLength - MemOverflow;
176 MemoryLength = GetPowerOfTwo64 (MemoryLength);
177 MtrrSetting.Variables.Mtrr[Index].Mask = ((~(MemoryLength - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED;
178
179 MemOverflow += MemoryLength;
180 Index++;
181 }
182
183 MemoryLength = LowMemoryLength;
184
185 while (MaxMemoryLength != MemoryLength) {
186 MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - MemoryLength);
187
188 MtrrSetting.Variables.Mtrr[Index].Base = ((MaxMemoryLength - MemoryLengthUc) & MTRR_LIB_CACHE_VALID_ADDRESS) | CacheUncacheable;
189 MtrrSetting.Variables.Mtrr[Index].Mask= ((~(MemoryLengthUc - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED;
190 MaxMemoryLength -= MemoryLengthUc;
191 Index++;
192 }
193
194 MemOverflow =0x100000000;
195 while (HighMemoryLength > 0) {
196 MtrrSetting.Variables.Mtrr[Index].Base = (MemOverflow & MTRR_LIB_CACHE_VALID_ADDRESS) | CacheWriteBack;
197 MemoryLength = HighMemoryLength;
198 MemoryLength = GetPowerOfTwo64 (MemoryLength);
199
200 if (MemoryLength > MemOverflow){
201 MemoryLength = MemOverflow;
202 }
203
204 MtrrSetting.Variables.Mtrr[Index].Mask = ((~(MemoryLength - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED;
205
206 MemOverflow += MemoryLength;
207 HighMemoryLength -= MemoryLength;
208 Index++;
209 }
210
211
212 for (Index = 0; Index < MTRR_NUMBER_OF_VARIABLE_MTRR; Index++) {
213 if (MtrrSetting.Variables.Mtrr[Index].Base == 0){
214 break;
215 }
216 DEBUG ((EFI_D_INFO, "Base=%lx, Mask=%lx\n",MtrrSetting.Variables.Mtrr[Index].Base ,MtrrSetting.Variables.Mtrr[Index].Mask));
217 }
218
219 //
220 // set FE/E bits for IA32_MTRR_DEF_TYPE
221 //
222 MtrrSetting.MtrrDefType |= 3 <<10;
223
224 MtrrSetAllMtrrs(&MtrrSetting);
225 //
226 // Dump MTRR Setting
227 //
228 MtrrDebugPrintAllMtrrs ();
229
230 return EFI_SUCCESS;
231 }
232
233 EFI_STATUS
234 EFIAPI
235 SetDxeCacheMode (
236 IN CONST EFI_PEI_SERVICES **PeiServices
237 )
238 {
239 //
240 // This is not needed for now.
241 //
242 return EFI_SUCCESS;
243 }
244
245 STATIC
246 EFI_STATUS
247 GetMemorySize (
248 IN CONST EFI_PEI_SERVICES **PeiServices,
249 OUT UINT64 *LowMemoryLength,
250 OUT UINT64 *HighMemoryLength
251 )
252 {
253 EFI_STATUS Status;
254 EFI_PEI_HOB_POINTERS Hob;
255
256 *HighMemoryLength = 0;
257 *LowMemoryLength = 0x100000;
258
259 //
260 // Get the HOB list for processing
261 //
262 Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw);
263 if (EFI_ERROR(Status)) {
264 return Status;
265 }
266
267 //
268 // Collect memory ranges
269 //
270 while (!END_OF_HOB_LIST (Hob)) {
271 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
272 if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
273 //
274 // Need memory above 1MB to be collected here
275 //
276 if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
277 Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) {
278 *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
279 } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) {
280 *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
281 }
282 }
283 }
284 Hob.Raw = GET_NEXT_HOB (Hob);
285 }
286
287 return EFI_SUCCESS;
288 }
289
290
291 /**
292 Publish Memory Type Information.
293
294 @param NULL
295
296 @retval EFI_SUCCESS Success.
297 @retval Others Errors have occurred.
298 **/
299
300 EFI_STATUS
301 EFIAPI
302 PublishMemoryTypeInfo (
303 void
304 )
305 {
306 EFI_STATUS Status;
307 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
308 UINTN DataSize;
309 EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1];
310
311 Status = PeiServicesLocatePpi (
312 &gEfiPeiReadOnlyVariable2PpiGuid,
313 0,
314 NULL,
315 (void **)&Variable
316 );
317 if (EFI_ERROR(Status)) {
318 DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status));
319 DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
320 //
321 // Build the default GUID'd HOB for DXE
322 //
323 BuildGuidDataHob (
324 &gEfiMemoryTypeInformationGuid,
325 mDefaultMemoryTypeInformation,
326 sizeof (mDefaultMemoryTypeInformation)
327 );
328
329 return Status;
330 }
331
332
333 DataSize = sizeof (MemoryData);
334
335 //
336 // This variable is saved in BDS stage. Now read it back
337 //
338 Status = Variable->GetVariable (
339 Variable,
340 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
341 &gEfiMemoryTypeInformationGuid,
342 NULL,
343 &DataSize,
344 &MemoryData
345 );
346 if (EFI_ERROR (Status)) {
347 //
348 //build default
349 //
350 DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
351 BuildGuidDataHob (
352 &gEfiMemoryTypeInformationGuid,
353 mDefaultMemoryTypeInformation,
354 sizeof (mDefaultMemoryTypeInformation)
355 );
356
357 } else {
358 //
359 // Build the GUID'd HOB for DXE from variable
360 //
361 DEBUG((EFI_D_ERROR, "Build Hob from variable \n"));
362 BuildGuidDataHob (
363 &gEfiMemoryTypeInformationGuid,
364 MemoryData,
365 DataSize
366 );
367 }
368
369 return Status;
370 }
371