]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/PlatformPei/MemDetect.c
MdeModulePkg/UefiBootManagerLib: Expose *GetLoadOptionBuffer() API
[mirror_edk2.git] / OvmfPkg / PlatformPei / MemDetect.c
CommitLineData
49ba9447 1/**@file\r
2 Memory Detection for Virtual Machines.\r
3\r
4b455f7b 4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
56d7640a 5 This program and the accompanying materials\r
49ba9447 6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13Module Name:\r
14\r
15 MemDetect.c\r
16\r
17**/\r
18\r
19//\r
20// The package level header files this module uses\r
21//\r
22#include <PiPei.h>\r
23\r
24//\r
25// The Library classes this module consumes\r
26//\r
6a7cba79 27#include <Library/BaseMemoryLib.h>\r
49ba9447 28#include <Library/DebugLib.h>\r
29#include <Library/HobLib.h>\r
30#include <Library/IoLib.h>\r
c1c2669c 31#include <Library/PcdLib.h>\r
49ba9447 32#include <Library/PeimEntryPoint.h>\r
33#include <Library/ResourcePublicationLib.h>\r
e8e5cd4a 34#include <Library/MtrrLib.h>\r
7e5b1b67 35#include <Library/QemuFwCfgLib.h>\r
49ba9447 36\r
37#include "Platform.h"\r
38#include "Cmos.h"\r
39\r
bc89fe48
LE
40UINT8 mPhysMemAddressWidth;\r
41\r
4b455f7b 42UINT32\r
c0e10976 43GetSystemMemorySizeBelow4gb (\r
4b455f7b 44 VOID\r
49ba9447 45 )\r
46{\r
47 UINT8 Cmos0x34;\r
48 UINT8 Cmos0x35;\r
49\r
50 //\r
51 // CMOS 0x34/0x35 specifies the system memory above 16 MB.\r
52 // * CMOS(0x35) is the high byte\r
53 // * CMOS(0x34) is the low byte\r
54 // * The size is specified in 64kb chunks\r
55 // * Since this is memory above 16MB, the 16MB must be added\r
56 // into the calculation to get the total memory size.\r
57 //\r
58\r
59 Cmos0x34 = (UINT8) CmosRead8 (0x34);\r
60 Cmos0x35 = (UINT8) CmosRead8 (0x35);\r
61\r
c4046161 62 return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);\r
49ba9447 63}\r
64\r
65\r
c0e10976 66STATIC\r
67UINT64\r
68GetSystemMemorySizeAbove4gb (\r
69 )\r
70{\r
71 UINT32 Size;\r
72 UINTN CmosIndex;\r
73\r
74 //\r
75 // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.\r
76 // * CMOS(0x5d) is the most significant size byte\r
77 // * CMOS(0x5c) is the middle size byte\r
78 // * CMOS(0x5b) is the least significant size byte\r
79 // * The size is specified in 64kb chunks\r
80 //\r
81\r
82 Size = 0;\r
83 for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {\r
84 Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);\r
85 }\r
86\r
87 return LShiftU64 (Size, 16);\r
88}\r
89\r
bc89fe48 90\r
d5371680
LE
91/**\r
92 Return the highest address that DXE could possibly use, plus one.\r
93**/\r
94STATIC\r
95UINT64\r
96GetFirstNonAddress (\r
97 VOID\r
98 )\r
99{\r
100 UINT64 FirstNonAddress;\r
7e5b1b67
LE
101 UINT64 Pci64Base, Pci64Size;\r
102 CHAR8 MbString[7 + 1];\r
103 EFI_STATUS Status;\r
104 FIRMWARE_CONFIG_ITEM FwCfgItem;\r
105 UINTN FwCfgSize;\r
106 UINT64 HotPlugMemoryEnd;\r
d5371680
LE
107\r
108 FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();\r
7e5b1b67
LE
109\r
110 //\r
111 // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO\r
112 // resources to 32-bit anyway. See DegradeResource() in\r
113 // "PciResourceSupport.c".\r
114 //\r
115#ifdef MDE_CPU_IA32\r
116 if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
117 return FirstNonAddress;\r
118 }\r
119#endif\r
120\r
121 //\r
122 // Otherwise, in order to calculate the highest address plus one, we must\r
123 // consider the 64-bit PCI host aperture too. Fetch the default size.\r
124 //\r
125 Pci64Size = PcdGet64 (PcdPciMmio64Size);\r
126\r
127 //\r
128 // See if the user specified the number of megabytes for the 64-bit PCI host\r
129 // aperture. The number of non-NUL characters in MbString allows for\r
130 // 9,999,999 MB, which is approximately 10 TB.\r
131 //\r
132 // As signaled by the "X-" prefix, this knob is experimental, and might go\r
133 // away at any time.\r
134 //\r
135 Status = QemuFwCfgFindFile ("opt/ovmf/X-PciMmio64Mb", &FwCfgItem,\r
136 &FwCfgSize);\r
137 if (!EFI_ERROR (Status)) {\r
138 if (FwCfgSize >= sizeof MbString) {\r
139 DEBUG ((EFI_D_WARN,\r
140 "%a: ignoring malformed 64-bit PCI host aperture size from fw_cfg\n",\r
141 __FUNCTION__));\r
142 } else {\r
143 QemuFwCfgSelectItem (FwCfgItem);\r
144 QemuFwCfgReadBytes (FwCfgSize, MbString);\r
145 MbString[FwCfgSize] = '\0';\r
146 Pci64Size = LShiftU64 (AsciiStrDecimalToUint64 (MbString), 20);\r
147 }\r
148 }\r
149\r
150 if (Pci64Size == 0) {\r
151 if (mBootMode != BOOT_ON_S3_RESUME) {\r
152 DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",\r
153 __FUNCTION__));\r
154 PcdSet64 (PcdPciMmio64Size, 0);\r
155 }\r
156\r
157 //\r
158 // There's nothing more to do; the amount of memory above 4GB fully\r
159 // determines the highest address plus one. The memory hotplug area (see\r
160 // below) plays no role for the firmware in this case.\r
161 //\r
162 return FirstNonAddress;\r
163 }\r
164\r
165 //\r
166 // The "etc/reserved-memory-end" fw_cfg file, when present, contains an\r
167 // absolute, exclusive end address for the memory hotplug area. This area\r
168 // starts right at the end of the memory above 4GB. The 64-bit PCI host\r
169 // aperture must be placed above it.\r
170 //\r
171 Status = QemuFwCfgFindFile ("etc/reserved-memory-end", &FwCfgItem,\r
172 &FwCfgSize);\r
173 if (!EFI_ERROR (Status) && FwCfgSize == sizeof HotPlugMemoryEnd) {\r
174 QemuFwCfgSelectItem (FwCfgItem);\r
175 QemuFwCfgReadBytes (FwCfgSize, &HotPlugMemoryEnd);\r
176\r
177 ASSERT (HotPlugMemoryEnd >= FirstNonAddress);\r
178 FirstNonAddress = HotPlugMemoryEnd;\r
179 }\r
180\r
181 //\r
182 // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so\r
183 // that the host can map it with 1GB hugepages. Follow suit.\r
184 //\r
185 Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);\r
186 Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);\r
187\r
188 //\r
189 // The 64-bit PCI host aperture should also be "naturally" aligned. The\r
190 // alignment is determined by rounding the size of the aperture down to the\r
191 // next smaller or equal power of two. That is, align the aperture by the\r
192 // largest BAR size that can fit into it.\r
193 //\r
194 Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));\r
195\r
196 if (mBootMode != BOOT_ON_S3_RESUME) {\r
197 //\r
198 // The core PciHostBridgeDxe driver will automatically add this range to\r
199 // the GCD memory space map through our PciHostBridgeLib instance; here we\r
200 // only need to set the PCDs.\r
201 //\r
202 PcdSet64 (PcdPciMmio64Base, Pci64Base);\r
203 PcdSet64 (PcdPciMmio64Size, Pci64Size);\r
204 DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",\r
205 __FUNCTION__, Pci64Base, Pci64Size));\r
206 }\r
207\r
208 //\r
209 // The useful address space ends with the 64-bit PCI host aperture.\r
210 //\r
211 FirstNonAddress = Pci64Base + Pci64Size;\r
d5371680
LE
212 return FirstNonAddress;\r
213}\r
214\r
215\r
bc89fe48
LE
216/**\r
217 Initialize the mPhysMemAddressWidth variable, based on guest RAM size.\r
218**/\r
219VOID\r
220AddressWidthInitialization (\r
221 VOID\r
222 )\r
223{\r
224 UINT64 FirstNonAddress;\r
225\r
226 //\r
227 // As guest-physical memory size grows, the permanent PEI RAM requirements\r
228 // are dominated by the identity-mapping page tables built by the DXE IPL.\r
229 // The DXL IPL keys off of the physical address bits advertized in the CPU\r
230 // HOB. To conserve memory, we calculate the minimum address width here.\r
231 //\r
d5371680 232 FirstNonAddress = GetFirstNonAddress ();\r
bc89fe48
LE
233 mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);\r
234\r
235 //\r
236 // If FirstNonAddress is not an integral power of two, then we need an\r
237 // additional bit.\r
238 //\r
239 if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {\r
240 ++mPhysMemAddressWidth;\r
241 }\r
242\r
243 //\r
244 // The minimum address width is 36 (covers up to and excluding 64 GB, which\r
245 // is the maximum for Ia32 + PAE). The theoretical architecture maximum for\r
246 // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We\r
247 // can simply assert that here, since 48 bits are good enough for 256 TB.\r
248 //\r
249 if (mPhysMemAddressWidth <= 36) {\r
250 mPhysMemAddressWidth = 36;\r
251 }\r
252 ASSERT (mPhysMemAddressWidth <= 48);\r
253}\r
254\r
255\r
256/**\r
257 Calculate the cap for the permanent PEI memory.\r
258**/\r
259STATIC\r
260UINT32\r
261GetPeiMemoryCap (\r
262 VOID\r
263 )\r
264{\r
265 BOOLEAN Page1GSupport;\r
266 UINT32 RegEax;\r
267 UINT32 RegEdx;\r
268 UINT32 Pml4Entries;\r
269 UINT32 PdpEntries;\r
270 UINTN TotalPages;\r
271\r
272 //\r
273 // If DXE is 32-bit, then just return the traditional 64 MB cap.\r
274 //\r
275#ifdef MDE_CPU_IA32\r
276 if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
277 return SIZE_64MB;\r
278 }\r
279#endif\r
280\r
281 //\r
282 // Dependent on physical address width, PEI memory allocations can be\r
283 // dominated by the page tables built for 64-bit DXE. So we key the cap off\r
284 // of those. The code below is based on CreateIdentityMappingPageTables() in\r
285 // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".\r
286 //\r
287 Page1GSupport = FALSE;\r
288 if (PcdGetBool (PcdUse1GPageTable)) {\r
289 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
290 if (RegEax >= 0x80000001) {\r
291 AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
292 if ((RegEdx & BIT26) != 0) {\r
293 Page1GSupport = TRUE;\r
294 }\r
295 }\r
296 }\r
297\r
298 if (mPhysMemAddressWidth <= 39) {\r
299 Pml4Entries = 1;\r
300 PdpEntries = 1 << (mPhysMemAddressWidth - 30);\r
301 ASSERT (PdpEntries <= 0x200);\r
302 } else {\r
303 Pml4Entries = 1 << (mPhysMemAddressWidth - 39);\r
304 ASSERT (Pml4Entries <= 0x200);\r
305 PdpEntries = 512;\r
306 }\r
307\r
308 TotalPages = Page1GSupport ? Pml4Entries + 1 :\r
309 (PdpEntries + 1) * Pml4Entries + 1;\r
310 ASSERT (TotalPages <= 0x40201);\r
311\r
312 //\r
313 // Add 64 MB for miscellaneous allocations. Note that for\r
314 // mPhysMemAddressWidth values close to 36, the cap will actually be\r
315 // dominated by this increment.\r
316 //\r
317 return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);\r
318}\r
319\r
320\r
36658fff
WL
321/**\r
322 Publish PEI core memory\r
323\r
324 @return EFI_SUCCESS The PEIM initialized successfully.\r
325\r
326**/\r
327EFI_STATUS\r
328PublishPeiMemory (\r
329 VOID\r
330 )\r
331{\r
332 EFI_STATUS Status;\r
333 EFI_PHYSICAL_ADDRESS MemoryBase;\r
334 UINT64 MemorySize;\r
335 UINT64 LowerMemorySize;\r
bc89fe48 336 UINT32 PeiMemoryCap;\r
36658fff 337\r
8e54500f
JJ
338 if (mBootMode == BOOT_ON_S3_RESUME) {\r
339 MemoryBase = PcdGet32 (PcdS3AcpiReservedMemoryBase);\r
340 MemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);\r
341 } else {\r
342 LowerMemorySize = GetSystemMemorySizeBelow4gb ();\r
b09c1c6f
LE
343 if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
344 //\r
345 // TSEG is chipped from the end of low RAM\r
346 //\r
347 LowerMemorySize -= FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB;\r
348 }\r
8e54500f 349\r
bc89fe48
LE
350 PeiMemoryCap = GetPeiMemoryCap ();\r
351 DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",\r
352 __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));\r
353\r
8e54500f
JJ
354 //\r
355 // Determine the range of memory to use during PEI\r
356 //\r
efb0f16e
LE
357 // Technically we could lay the permanent PEI RAM over SEC's temporary\r
358 // decompression and scratch buffer even if "secure S3" is needed, since\r
359 // their lifetimes don't overlap. However, PeiFvInitialization() will cover\r
360 // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory\r
361 // allocation HOB, and other allocations served from the permanent PEI RAM\r
362 // shouldn't overlap with that HOB.\r
363 //\r
364 MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?\r
365 PcdGet32 (PcdOvmfDecompressionScratchEnd) :\r
366 PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);\r
8e54500f 367 MemorySize = LowerMemorySize - MemoryBase;\r
bc89fe48
LE
368 if (MemorySize > PeiMemoryCap) {\r
369 MemoryBase = LowerMemorySize - PeiMemoryCap;\r
370 MemorySize = PeiMemoryCap;\r
8e54500f 371 }\r
36658fff
WL
372 }\r
373\r
374 //\r
375 // Publish this memory to the PEI Core\r
376 //\r
377 Status = PublishSystemMemory(MemoryBase, MemorySize);\r
378 ASSERT_EFI_ERROR (Status);\r
379\r
380 return Status;\r
381}\r
382\r
c0e10976 383\r
49ba9447 384/**\r
c034906e 385 Peform Memory Detection for QEMU / KVM\r
49ba9447 386\r
387**/\r
c034906e
JJ
388STATIC\r
389VOID\r
390QemuInitializeRam (\r
391 VOID\r
49ba9447 392 )\r
393{\r
c0e10976 394 UINT64 LowerMemorySize;\r
395 UINT64 UpperMemorySize;\r
79d274b8
LE
396 MTRR_SETTINGS MtrrSettings;\r
397 EFI_STATUS Status;\r
49ba9447 398\r
c034906e 399 DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));\r
49ba9447 400\r
401 //\r
402 // Determine total memory size available\r
403 //\r
c0e10976 404 LowerMemorySize = GetSystemMemorySizeBelow4gb ();\r
405 UpperMemorySize = GetSystemMemorySizeAbove4gb ();\r
49ba9447 406\r
bd386eaf
JJ
407 if (mBootMode != BOOT_ON_S3_RESUME) {\r
408 //\r
409 // Create memory HOBs\r
410 //\r
bd386eaf 411 AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);\r
b09c1c6f
LE
412\r
413 if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
414 UINT32 TsegSize;\r
415\r
416 TsegSize = FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB;\r
417 AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);\r
418 AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize,\r
419 TRUE);\r
420 } else {\r
421 AddMemoryRangeHob (BASE_1MB, LowerMemorySize);\r
422 }\r
423\r
cfc80e2e
LE
424 if (UpperMemorySize != 0) {\r
425 AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);\r
426 }\r
bd386eaf 427 }\r
49ba9447 428\r
79d274b8
LE
429 //\r
430 // We'd like to keep the following ranges uncached:\r
431 // - [640 KB, 1 MB)\r
432 // - [LowerMemorySize, 4 GB)\r
433 //\r
434 // Everything else should be WB. Unfortunately, programming the inverse (ie.\r
435 // keeping the default UC, and configuring the complement set of the above as\r
436 // WB) is not reliable in general, because the end of the upper RAM can have\r
437 // practically any alignment, and we may not have enough variable MTRRs to\r
438 // cover it exactly.\r
439 //\r
440 if (IsMtrrSupported ()) {\r
441 MtrrGetAllMtrrs (&MtrrSettings);\r
442\r
443 //\r
444 // MTRRs disabled, fixed MTRRs disabled, default type is uncached\r
445 //\r
446 ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0);\r
447 ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0);\r
448 ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0);\r
449\r
450 //\r
451 // flip default type to writeback\r
452 //\r
453 SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06);\r
454 ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables);\r
455 MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6;\r
456 MtrrSetAllMtrrs (&MtrrSettings);\r
e8e5cd4a 457\r
79d274b8
LE
458 //\r
459 // Set memory range from 640KB to 1MB to uncacheable\r
460 //\r
461 Status = MtrrSetMemoryAttribute (BASE_512KB + BASE_128KB,\r
462 BASE_1MB - (BASE_512KB + BASE_128KB), CacheUncacheable);\r
463 ASSERT_EFI_ERROR (Status);\r
e8e5cd4a 464\r
79d274b8
LE
465 //\r
466 // Set memory range from the "top of lower RAM" (RAM below 4GB) to 4GB as\r
467 // uncacheable\r
468 //\r
469 Status = MtrrSetMemoryAttribute (LowerMemorySize,\r
470 SIZE_4GB - LowerMemorySize, CacheUncacheable);\r
471 ASSERT_EFI_ERROR (Status);\r
c0e10976 472 }\r
49ba9447 473}\r
474\r
c034906e
JJ
475/**\r
476 Publish system RAM and reserve memory regions\r
477\r
478**/\r
479VOID\r
480InitializeRamRegions (\r
481 VOID\r
482 )\r
483{\r
2818c158
JJ
484 if (!mXen) {\r
485 QemuInitializeRam ();\r
486 } else {\r
2818c158
JJ
487 XenPublishRamRegions ();\r
488 }\r
8e54500f
JJ
489\r
490 if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {\r
491 //\r
492 // This is the memory range that will be used for PEI on S3 resume\r
493 //\r
494 BuildMemoryAllocationHob (\r
495 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdS3AcpiReservedMemoryBase),\r
496 (UINT64)(UINTN) PcdGet32 (PcdS3AcpiReservedMemorySize),\r
497 EfiACPIMemoryNVS\r
498 );\r
e249f906
LE
499\r
500 //\r
501 // Cover the initial RAM area used as stack and temporary PEI heap.\r
502 //\r
503 // This is reserved as ACPI NVS so it can be used on S3 resume.\r
504 //\r
505 BuildMemoryAllocationHob (\r
506 PcdGet32 (PcdOvmfSecPeiTempRamBase),\r
507 PcdGet32 (PcdOvmfSecPeiTempRamSize),\r
508 EfiACPIMemoryNVS\r
509 );\r
78a38b73 510\r
ad43bc6b
LE
511 //\r
512 // SEC stores its table of GUIDed section handlers here.\r
513 //\r
514 BuildMemoryAllocationHob (\r
515 PcdGet64 (PcdGuidedExtractHandlerTableAddress),\r
516 PcdGet32 (PcdGuidedExtractHandlerTableSize),\r
517 EfiACPIMemoryNVS\r
518 );\r
519\r
78a38b73
LE
520#ifdef MDE_CPU_X64\r
521 //\r
522 // Reserve the initial page tables built by the reset vector code.\r
523 //\r
524 // Since this memory range will be used by the Reset Vector on S3\r
525 // resume, it must be reserved as ACPI NVS.\r
526 //\r
527 BuildMemoryAllocationHob (\r
528 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecPageTablesBase),\r
529 (UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),\r
530 EfiACPIMemoryNVS\r
531 );\r
532#endif\r
0e8a31f5 533 }\r
6a7cba79 534\r
0e8a31f5 535 if (mBootMode != BOOT_ON_S3_RESUME) {\r
1a7edbbc
LE
536 if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
537 //\r
538 // Reserve the lock box storage area\r
539 //\r
540 // Since this memory range will be used on S3 resume, it must be\r
541 // reserved as ACPI NVS.\r
542 //\r
543 // If S3 is unsupported, then various drivers might still write to the\r
544 // LockBox area. We ought to prevent DXE from serving allocation requests\r
545 // such that they would overlap the LockBox storage.\r
546 //\r
547 ZeroMem (\r
548 (VOID*)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),\r
549 (UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize)\r
550 );\r
551 BuildMemoryAllocationHob (\r
552 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),\r
553 (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),\r
554 mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData\r
555 );\r
556 }\r
b09c1c6f
LE
557\r
558 if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
559 UINT32 TsegSize;\r
560\r
561 //\r
562 // Make sure the TSEG area that we reported as a reserved memory resource\r
563 // cannot be used for reserved memory allocations.\r
564 //\r
565 TsegSize = FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB;\r
566 BuildMemoryAllocationHob (\r
567 GetSystemMemorySizeBelow4gb() - TsegSize,\r
568 TsegSize,\r
569 EfiReservedMemoryType\r
570 );\r
571 }\r
8e54500f 572 }\r
c034906e 573}\r