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