]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
Vlv2TbltDevicePkg: Remove reference deprecated macro.
[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 Initializes the valid address mask for MTRRs.
75
76 This function initializes the valid bits mask and valid address mask for MTRRs.
77
78 **/
79 UINT64
80 InitializeAddressMtrrMask (
81 VOID
82 )
83 {
84 UINT32 RegEax;
85 UINT8 PhysicalAddressBits;
86 UINT64 ValidMtrrBitsMask;
87
88 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
89
90 if (RegEax >= 0x80000008) {
91 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
92
93 PhysicalAddressBits = (UINT8) RegEax;
94 } else {
95 PhysicalAddressBits = 36;
96 }
97
98 ValidMtrrBitsMask = LShiftU64 (1, PhysicalAddressBits) - 1;
99 return (ValidMtrrBitsMask & 0xfffffffffffff000ULL);
100 }
101
102 EFI_STATUS
103 EFIAPI
104 SetPeiCacheMode (
105 IN CONST EFI_PEI_SERVICES **PeiServices
106 )
107 {
108 EFI_STATUS Status;
109 PEI_CACHE_PPI *CachePpi;
110
111 EFI_BOOT_MODE BootMode;
112 UINT64 MemoryLength;
113 UINT64 MemOverflow;
114 UINT64 MemoryLengthUc;
115 UINT64 MaxMemoryLength;
116 UINT64 LowMemoryLength;
117 UINT64 HighMemoryLength;
118 UINT8 Index;
119 MTRR_SETTINGS MtrrSetting;
120 UINT64 ValidMtrrAddressMask;
121
122 //
123 // Load Cache PPI
124 //
125 Status = (**PeiServices).LocatePpi (
126 PeiServices,
127 &gPeiCachePpiGuid, // GUID
128 0, // Instance
129 NULL, // EFI_PEI_PPI_DESCRIPTOR
130 (void **)&CachePpi // PPI
131 );
132 if (!EFI_ERROR(Status)) {
133 //
134 // Clear the CAR Settings (Default Cache Type => UC)
135 //
136 DEBUG ((EFI_D_INFO, "Reset cache attribute and disable CAR. \n"));
137 CachePpi->ResetCache(
138 (EFI_PEI_SERVICES**)PeiServices,
139 CachePpi
140 );
141 }
142
143
144 //
145 // Variable initialization
146 //
147 LowMemoryLength = 0;
148 HighMemoryLength = 0;
149 MemoryLengthUc = 0;
150
151 Status = (*PeiServices)->GetBootMode (
152 PeiServices,
153 &BootMode
154 );
155
156 ValidMtrrAddressMask = InitializeAddressMtrrMask ();
157
158 //
159 // Determine memory usage
160 //
161 GetMemorySize (
162 PeiServices,
163 &LowMemoryLength,
164 &HighMemoryLength
165 );
166
167 LowMemoryLength = (EFI_PHYSICAL_ADDRESS)MmPci32( 0, 0, 2, 0, 0x70);
168 LowMemoryLength &= 0xFFF00000ULL;
169
170 MaxMemoryLength = LowMemoryLength;
171
172 //
173 // Round up to nearest 256MB with high memory and 64MB w/o high memory
174 //
175 if (HighMemoryLength != 0 ) {
176 MemOverflow = (LowMemoryLength & 0x0fffffff);
177 if (MemOverflow != 0) {
178 MaxMemoryLength = LowMemoryLength + (0x10000000 - MemOverflow);
179 }
180 } else {
181 MemOverflow = (LowMemoryLength & 0x03ffffff);
182 if (MemOverflow != 0) {
183 MaxMemoryLength = LowMemoryLength + (0x4000000 - MemOverflow);
184 }
185 }
186
187 ZeroMem (&MtrrSetting, sizeof(MTRR_SETTINGS));
188 for (Index = 0; Index < 2; Index++) {
189 MtrrSetting.Fixed.Mtrr[Index]=0x0606060606060606;
190 }
191 for (Index = 2; Index < 11; Index++) {
192 MtrrSetting.Fixed.Mtrr[Index]=0x0505050505050505;
193 }
194
195 //
196 // Cache the flash area to improve the boot performance in PEI phase
197 //
198 Index = 0;
199 ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Base)->Uint64 = FixedPcdGet32 (PcdFlashAreaBaseAddress);
200 ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Base)->Bits.Type = CacheWriteProtected;
201 ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Mask)->Uint64 = (~((UINT64)(FixedPcdGet32 (PcdFlashAreaSize) - 1))) & ValidMtrrAddressMask;
202 ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Mask)->Bits.V = 1;
203
204 Index ++;
205
206 MemOverflow =0;
207 while (MaxMemoryLength > MemOverflow){
208 MemoryLength = MaxMemoryLength - MemOverflow;
209 MemoryLength = GetPowerOfTwo64 (MemoryLength);
210
211 ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = MemOverflow & ValidMtrrAddressMask;
212 ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheWriteBack;
213 ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLength - 1)) & ValidMtrrAddressMask;
214 ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
215
216 MemOverflow += MemoryLength;
217 Index++;
218 }
219
220 MemoryLength = LowMemoryLength;
221
222 while (MaxMemoryLength != MemoryLength) {
223 MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - MemoryLength);
224
225 ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = (MaxMemoryLength - MemoryLengthUc) & ValidMtrrAddressMask;
226 ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheUncacheable;
227 ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLengthUc - 1)) & ValidMtrrAddressMask;
228 ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
229
230 MaxMemoryLength -= MemoryLengthUc;
231 Index++;
232 }
233
234 MemOverflow =0x100000000;
235 while (HighMemoryLength > 0) {
236
237 MemoryLength = HighMemoryLength;
238 MemoryLength = GetPowerOfTwo64 (MemoryLength);
239 if (MemoryLength > MemOverflow){
240 MemoryLength = MemOverflow;
241 }
242
243 ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = MemOverflow & ValidMtrrAddressMask;
244 ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheWriteBack;
245 ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLength - 1)) & ValidMtrrAddressMask;
246 ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
247
248 MemOverflow += MemoryLength;
249 HighMemoryLength -= MemoryLength;
250 Index++;
251 }
252
253
254 for (Index = 0; Index < MTRR_NUMBER_OF_VARIABLE_MTRR; Index++) {
255 if (MtrrSetting.Variables.Mtrr[Index].Base == 0){
256 break;
257 }
258 DEBUG ((EFI_D_INFO, "Base=%lx, Mask=%lx\n",MtrrSetting.Variables.Mtrr[Index].Base ,MtrrSetting.Variables.Mtrr[Index].Mask));
259 }
260
261 //
262 // set FE/E bits for IA32_MTRR_DEF_TYPE
263 //
264 MtrrSetting.MtrrDefType |= 3 <<10;
265
266 MtrrSetAllMtrrs(&MtrrSetting);
267 //
268 // Dump MTRR Setting
269 //
270 MtrrDebugPrintAllMtrrs ();
271
272 return EFI_SUCCESS;
273 }
274
275 EFI_STATUS
276 EFIAPI
277 SetDxeCacheMode (
278 IN CONST EFI_PEI_SERVICES **PeiServices
279 )
280 {
281 //
282 // This is not needed for now.
283 //
284 return EFI_SUCCESS;
285 }
286
287 STATIC
288 EFI_STATUS
289 GetMemorySize (
290 IN CONST EFI_PEI_SERVICES **PeiServices,
291 OUT UINT64 *LowMemoryLength,
292 OUT UINT64 *HighMemoryLength
293 )
294 {
295 EFI_STATUS Status;
296 EFI_PEI_HOB_POINTERS Hob;
297
298 *HighMemoryLength = 0;
299 *LowMemoryLength = 0x100000;
300
301 //
302 // Get the HOB list for processing
303 //
304 Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw);
305 if (EFI_ERROR(Status)) {
306 return Status;
307 }
308
309 //
310 // Collect memory ranges
311 //
312 while (!END_OF_HOB_LIST (Hob)) {
313 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
314 if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
315 //
316 // Need memory above 1MB to be collected here
317 //
318 if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
319 Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) {
320 *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
321 } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) {
322 *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
323 }
324 }
325 }
326 Hob.Raw = GET_NEXT_HOB (Hob);
327 }
328
329 return EFI_SUCCESS;
330 }
331
332
333 /**
334 Publish Memory Type Information.
335
336 @param NULL
337
338 @retval EFI_SUCCESS Success.
339 @retval Others Errors have occurred.
340 **/
341
342 EFI_STATUS
343 EFIAPI
344 PublishMemoryTypeInfo (
345 void
346 )
347 {
348 EFI_STATUS Status;
349 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
350 UINTN DataSize;
351 EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1];
352
353 Status = PeiServicesLocatePpi (
354 &gEfiPeiReadOnlyVariable2PpiGuid,
355 0,
356 NULL,
357 (void **)&Variable
358 );
359 if (EFI_ERROR(Status)) {
360 DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status));
361 DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
362 //
363 // Build the default GUID'd HOB for DXE
364 //
365 BuildGuidDataHob (
366 &gEfiMemoryTypeInformationGuid,
367 mDefaultMemoryTypeInformation,
368 sizeof (mDefaultMemoryTypeInformation)
369 );
370
371 return Status;
372 }
373
374
375 DataSize = sizeof (MemoryData);
376
377 //
378 // This variable is saved in BDS stage. Now read it back
379 //
380 Status = Variable->GetVariable (
381 Variable,
382 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
383 &gEfiMemoryTypeInformationGuid,
384 NULL,
385 &DataSize,
386 &MemoryData
387 );
388 if (EFI_ERROR (Status)) {
389 //
390 //build default
391 //
392 DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
393 BuildGuidDataHob (
394 &gEfiMemoryTypeInformationGuid,
395 mDefaultMemoryTypeInformation,
396 sizeof (mDefaultMemoryTypeInformation)
397 );
398
399 } else {
400 //
401 // Build the GUID'd HOB for DXE from variable
402 //
403 DEBUG((EFI_D_ERROR, "Build Hob from variable \n"));
404 BuildGuidDataHob (
405 &gEfiMemoryTypeInformationGuid,
406 MemoryData,
407 DataSize
408 );
409 }
410
411 return Status;
412 }
413