]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
IntelFsp2WrapperPkg: Update gFspWrapperTokenSpaceGuid to gIntelFsp2WrapperTokenSpaceGuid.
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformInitPei / MemoryPeim.c
1 /** @file
2
3 Copyright (c) 2004 - 2014, 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
227
228 return EFI_SUCCESS;
229 }
230
231 EFI_STATUS
232 EFIAPI
233 SetDxeCacheMode (
234 IN CONST EFI_PEI_SERVICES **PeiServices
235 )
236 {
237 //
238 // This is not needed for now.
239 //
240 return EFI_SUCCESS;
241 }
242
243 STATIC
244 EFI_STATUS
245 GetMemorySize (
246 IN CONST EFI_PEI_SERVICES **PeiServices,
247 OUT UINT64 *LowMemoryLength,
248 OUT UINT64 *HighMemoryLength
249 )
250 {
251 EFI_STATUS Status;
252 EFI_PEI_HOB_POINTERS Hob;
253
254 *HighMemoryLength = 0;
255 *LowMemoryLength = 0x100000;
256
257 //
258 // Get the HOB list for processing
259 //
260 Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw);
261 if (EFI_ERROR(Status)) {
262 return Status;
263 }
264
265 //
266 // Collect memory ranges
267 //
268 while (!END_OF_HOB_LIST (Hob)) {
269 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
270 if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
271 //
272 // Need memory above 1MB to be collected here
273 //
274 if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
275 Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) {
276 *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
277 } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) {
278 *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
279 }
280 }
281 }
282 Hob.Raw = GET_NEXT_HOB (Hob);
283 }
284
285 return EFI_SUCCESS;
286 }
287
288
289 /**
290 Publish Memory Type Information.
291
292 @param NULL
293
294 @retval EFI_SUCCESS Success.
295 @retval Others Errors have occurred.
296 **/
297
298 EFI_STATUS
299 EFIAPI
300 PublishMemoryTypeInfo (
301 void
302 )
303 {
304 EFI_STATUS Status;
305 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
306 UINTN DataSize;
307 EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1];
308
309 Status = PeiServicesLocatePpi (
310 &gEfiPeiReadOnlyVariable2PpiGuid,
311 0,
312 NULL,
313 (void **)&Variable
314 );
315 if (EFI_ERROR(Status)) {
316 DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status));
317 DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
318 //
319 // Build the default GUID'd HOB for DXE
320 //
321 BuildGuidDataHob (
322 &gEfiMemoryTypeInformationGuid,
323 mDefaultMemoryTypeInformation,
324 sizeof (mDefaultMemoryTypeInformation)
325 );
326
327 return Status;
328 }
329
330
331 DataSize = sizeof (MemoryData);
332
333 //
334 // This variable is saved in BDS stage. Now read it back
335 //
336 Status = Variable->GetVariable (
337 Variable,
338 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
339 &gEfiMemoryTypeInformationGuid,
340 NULL,
341 &DataSize,
342 &MemoryData
343 );
344 if (EFI_ERROR (Status)) {
345 //
346 //build default
347 //
348 DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
349 BuildGuidDataHob (
350 &gEfiMemoryTypeInformationGuid,
351 mDefaultMemoryTypeInformation,
352 sizeof (mDefaultMemoryTypeInformation)
353 );
354
355 } else {
356 //
357 // Build the GUID'd HOB for DXE from variable
358 //
359 DEBUG((EFI_D_ERROR, "Build Hob from variable \n"));
360 BuildGuidDataHob (
361 &gEfiMemoryTypeInformationGuid,
362 MemoryData,
363 DataSize
364 );
365 }
366
367 return Status;
368 }
369