TianoCore EDK2 master
Loading...
Searching...
No Matches
MemDetect.c
Go to the documentation of this file.
1
15//
16// The package level header files this module uses
17//
20#include <PiPei.h>
21
22//
23// The Library classes this module consumes
24//
25#include <Library/BaseLib.h>
27#include <Library/DebugLib.h>
28#include <Library/HobLib.h>
29#include <Library/IoLib.h>
30#include <Library/PcdLib.h>
31#include <Library/PciLib.h>
34#include <Library/MtrrLib.h>
35
36#include "Platform.h"
37#include "Cmos.h"
38
39UINT8 mPhysMemAddressWidth;
40
41STATIC UINT32 mS3AcpiReservedMemoryBase;
42STATIC UINT32 mS3AcpiReservedMemorySize;
43
44STATIC UINT16 mQ35TsegMbytes;
45
46BOOLEAN mQ35SmramAtDefaultSmbase = FALSE;
47
48VOID
49Q35TsegMbytesInitialization (
50 VOID
51 )
52{
53 UINT16 ExtendedTsegMbytes;
54 RETURN_STATUS PcdStatus;
55
56 if (mHostBridgeDevId != INTEL_Q35_MCH_DEVICE_ID) {
57 DEBUG ((
58 DEBUG_ERROR,
59 "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
60 "only DID=0x%04x (Q35) is supported\n",
61 __func__,
62 mHostBridgeDevId,
63 INTEL_Q35_MCH_DEVICE_ID
64 ));
65 ASSERT (FALSE);
66 CpuDeadLoop ();
67 }
68
69 //
70 // Check if QEMU offers an extended TSEG.
71 //
72 // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the MCH_EXT_TSEG_MB
73 // register, and reading back the register.
74 //
75 // On a QEMU machine type that does not offer an extended TSEG, the initial
76 // write overwrites whatever value a malicious guest OS may have placed in
77 // the (unimplemented) register, before entering S3 or rebooting.
78 // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged.
79 //
80 // On a QEMU machine type that offers an extended TSEG, the initial write
81 // triggers an update to the register. Subsequently, the value read back
82 // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us the
83 // number of megabytes.
84 //
85 PciWrite16 (DRAMC_REGISTER_Q35 (MCH_EXT_TSEG_MB), MCH_EXT_TSEG_MB_QUERY);
86 ExtendedTsegMbytes = PciRead16 (DRAMC_REGISTER_Q35 (MCH_EXT_TSEG_MB));
87 if (ExtendedTsegMbytes == MCH_EXT_TSEG_MB_QUERY) {
88 mQ35TsegMbytes = PcdGet16 (PcdQ35TsegMbytes);
89 return;
90 }
91
92 DEBUG ((
93 DEBUG_INFO,
94 "%a: QEMU offers an extended TSEG (%d MB)\n",
95 __func__,
96 ExtendedTsegMbytes
97 ));
98 PcdStatus = PcdSet16S (PcdQ35TsegMbytes, ExtendedTsegMbytes);
99 ASSERT_RETURN_ERROR (PcdStatus);
100 mQ35TsegMbytes = ExtendedTsegMbytes;
101}
102
103UINT32
104GetSystemMemorySizeBelow4gb (
105 VOID
106 )
107{
108 UINT8 Cmos0x34;
109 UINT8 Cmos0x35;
110
111 //
112 // CMOS 0x34/0x35 specifies the system memory above 16 MB.
113 // * CMOS(0x35) is the high byte
114 // * CMOS(0x34) is the low byte
115 // * The size is specified in 64kb chunks
116 // * Since this is memory above 16MB, the 16MB must be added
117 // into the calculation to get the total memory size.
118 //
119
120 Cmos0x34 = (UINT8)CmosRead8 (0x34);
121 Cmos0x35 = (UINT8)CmosRead8 (0x35);
122
123 return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
124}
125
126STATIC
127UINT64
128GetSystemMemorySizeAbove4gb (
129 )
130{
131 UINT32 Size;
132 UINTN CmosIndex;
133
134 //
135 // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
136 // * CMOS(0x5d) is the most significant size byte
137 // * CMOS(0x5c) is the middle size byte
138 // * CMOS(0x5b) is the least significant size byte
139 // * The size is specified in 64kb chunks
140 //
141
142 Size = 0;
143 for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
144 Size = (UINT32)(Size << 8) + (UINT32)CmosRead8 (CmosIndex);
145 }
146
147 return LShiftU64 (Size, 16);
148}
149
153STATIC
154UINT64
156 VOID
157 )
158{
159 UINT64 FirstNonAddress;
160 UINT64 Pci64Base, Pci64Size;
161 RETURN_STATUS PcdStatus;
162
163 FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
164
165 //
166 // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
167 // resources to 32-bit anyway. See DegradeResource() in
168 // "PciResourceSupport.c".
169 //
170 #ifdef MDE_CPU_IA32
171 if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
172 return FirstNonAddress;
173 }
174
175 #endif
176
177 //
178 // Otherwise, in order to calculate the highest address plus one, we must
179 // consider the 64-bit PCI host aperture too. Fetch the default size.
180 //
181 Pci64Size = PcdGet64 (PcdPciMmio64Size);
182
183 if (Pci64Size == 0) {
184 if (mBootMode != BOOT_ON_S3_RESUME) {
185 DEBUG ((
186 DEBUG_INFO,
187 "%a: disabling 64-bit PCI host aperture\n",
188 __func__
189 ));
190 PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);
191 ASSERT_RETURN_ERROR (PcdStatus);
192 }
193
194 //
195 // There's nothing more to do; the amount of memory above 4GB fully
196 // determines the highest address plus one. The memory hotplug area (see
197 // below) plays no role for the firmware in this case.
198 //
199 return FirstNonAddress;
200 }
201
202 //
203 // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
204 // that the host can map it with 1GB hugepages. Follow suit.
205 //
206 Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
207 Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
208
209 //
210 // The 64-bit PCI host aperture should also be "naturally" aligned. The
211 // alignment is determined by rounding the size of the aperture down to the
212 // next smaller or equal power of two. That is, align the aperture by the
213 // largest BAR size that can fit into it.
214 //
215 Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
216
217 if (mBootMode != BOOT_ON_S3_RESUME) {
218 //
219 // The core PciHostBridgeDxe driver will automatically add this range to
220 // the GCD memory space map through our PciHostBridgeLib instance; here we
221 // only need to set the PCDs.
222 //
223 PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base);
224 ASSERT_RETURN_ERROR (PcdStatus);
225 PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size);
226 ASSERT_RETURN_ERROR (PcdStatus);
227
228 DEBUG ((
229 DEBUG_INFO,
230 "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
231 __func__,
232 Pci64Base,
233 Pci64Size
234 ));
235 }
236
237 //
238 // The useful address space ends with the 64-bit PCI host aperture.
239 //
240 FirstNonAddress = Pci64Base + Pci64Size;
241 return FirstNonAddress;
242}
243
247VOID
249 VOID
250 )
251{
252 UINT64 FirstNonAddress;
253
254 //
255 // As guest-physical memory size grows, the permanent PEI RAM requirements
256 // are dominated by the identity-mapping page tables built by the DXE IPL.
257 // The DXL IPL keys off of the physical address bits advertized in the CPU
258 // HOB. To conserve memory, we calculate the minimum address width here.
259 //
260 FirstNonAddress = GetFirstNonAddress ();
261 mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
262
263 //
264 // If FirstNonAddress is not an integral power of two, then we need an
265 // additional bit.
266 //
267 if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
268 ++mPhysMemAddressWidth;
269 }
270
271 //
272 // The minimum address width is 36 (covers up to and excluding 64 GB, which
273 // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
274 // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
275 // can simply assert that here, since 48 bits are good enough for 256 TB.
276 //
277 if (mPhysMemAddressWidth <= 36) {
278 mPhysMemAddressWidth = 36;
279 }
280
281 ASSERT (mPhysMemAddressWidth <= 48);
282}
283
287STATIC
288UINT32
290 VOID
291 )
292{
293 BOOLEAN Page1GSupport;
294 UINT32 RegEax;
295 UINT32 RegEdx;
296 UINT32 Pml4Entries;
297 UINT32 PdpEntries;
298 UINTN TotalPages;
299
300 //
301 // If DXE is 32-bit, then just return the traditional 64 MB cap.
302 //
303 #ifdef MDE_CPU_IA32
304 if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
305 return SIZE_64MB;
306 }
307
308 #endif
309
310 //
311 // Dependent on physical address width, PEI memory allocations can be
312 // dominated by the page tables built for 64-bit DXE. So we key the cap off
313 // of those. The code below is based on CreateIdentityMappingPageTables() in
314 // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".
315 //
316 Page1GSupport = FALSE;
317 if (PcdGetBool (PcdUse1GPageTable)) {
318 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
319 if (RegEax >= 0x80000001) {
320 AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
321 if ((RegEdx & BIT26) != 0) {
322 Page1GSupport = TRUE;
323 }
324 }
325 }
326
327 if (mPhysMemAddressWidth <= 39) {
328 Pml4Entries = 1;
329 PdpEntries = 1 << (mPhysMemAddressWidth - 30);
330 ASSERT (PdpEntries <= 0x200);
331 } else {
332 Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
333 ASSERT (Pml4Entries <= 0x200);
334 PdpEntries = 512;
335 }
336
337 TotalPages = Page1GSupport ? Pml4Entries + 1 :
338 (PdpEntries + 1) * Pml4Entries + 1;
339 ASSERT (TotalPages <= 0x40201);
340
341 //
342 // Add 64 MB for miscellaneous allocations. Note that for
343 // mPhysMemAddressWidth values close to 36, the cap will actually be
344 // dominated by this increment.
345 //
346 return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);
347}
348
357 VOID
358 )
359{
360 EFI_STATUS Status;
361 EFI_PHYSICAL_ADDRESS MemoryBase;
362 UINT64 MemorySize;
363 UINT32 LowerMemorySize;
364 UINT32 PeiMemoryCap;
365
366 LowerMemorySize = GetSystemMemorySizeBelow4gb ();
367 if (FeaturePcdGet (PcdSmmSmramRequire)) {
368 //
369 // TSEG is chipped from the end of low RAM
370 //
371 LowerMemorySize -= mQ35TsegMbytes * SIZE_1MB;
372 }
373
374 //
375 // If S3 is supported, then the S3 permanent PEI memory is placed next,
376 // downwards. Its size is primarily dictated by CpuMpPei. The formula below
377 // is an approximation.
378 //
379 if (mS3Supported) {
380 mS3AcpiReservedMemorySize = SIZE_512KB +
381 mMaxCpuCount *
382 PcdGet32 (PcdCpuApStackSize);
383 mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;
384 LowerMemorySize = mS3AcpiReservedMemoryBase;
385 }
386
387 if (mBootMode == BOOT_ON_S3_RESUME) {
388 MemoryBase = mS3AcpiReservedMemoryBase;
389 MemorySize = mS3AcpiReservedMemorySize;
390 } else {
391 PeiMemoryCap = GetPeiMemoryCap ();
392 DEBUG ((
393 DEBUG_INFO,
394 "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",
395 __func__,
396 mPhysMemAddressWidth,
397 PeiMemoryCap >> 10
398 ));
399
400 //
401 // Determine the range of memory to use during PEI
402 //
403 // Technically we could lay the permanent PEI RAM over SEC's temporary
404 // decompression and scratch buffer even if "secure S3" is needed, since
405 // their lifetimes don't overlap. However, PeiFvInitialization() will cover
406 // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory
407 // allocation HOB, and other allocations served from the permanent PEI RAM
408 // shouldn't overlap with that HOB.
409 //
410 MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?
411 PcdGet32 (PcdOvmfDecompressionScratchEnd) :
412 PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
413 MemorySize = LowerMemorySize - MemoryBase;
414 if (MemorySize > PeiMemoryCap) {
415 MemoryBase = LowerMemorySize - PeiMemoryCap;
416 MemorySize = PeiMemoryCap;
417 }
418 }
419
420 //
421 // Publish this memory to the PEI Core
422 //
423 Status = PublishSystemMemory (MemoryBase, MemorySize);
424 ASSERT_EFI_ERROR (Status);
425
426 return Status;
427}
428
433STATIC
434VOID
436 VOID
437 )
438{
439 UINT64 LowerMemorySize;
440 UINT64 UpperMemorySize;
441 MTRR_SETTINGS MtrrSettings;
442 EFI_STATUS Status;
443
444 DEBUG ((DEBUG_INFO, "%a called\n", __func__));
445
446 //
447 // Determine total memory size available
448 //
449 LowerMemorySize = GetSystemMemorySizeBelow4gb ();
450 UpperMemorySize = GetSystemMemorySizeAbove4gb ();
451
452 if (mBootMode == BOOT_ON_S3_RESUME) {
453 //
454 // Create the following memory HOB as an exception on the S3 boot path.
455 //
456 // Normally we'd create memory HOBs only on the normal boot path. However,
457 // CpuMpPei specifically needs such a low-memory HOB on the S3 path as
458 // well, for "borrowing" a subset of it temporarily, for the AP startup
459 // vector.
460 //
461 // CpuMpPei saves the original contents of the borrowed area in permanent
462 // PEI RAM, in a backup buffer allocated with the normal PEI services.
463 // CpuMpPei restores the original contents ("returns" the borrowed area) at
464 // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before
465 // transferring control to the OS's wakeup vector in the FACS.
466 //
467 // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to
468 // restore the original contents. Furthermore, we expect all such PEIMs
469 // (CpuMpPei included) to claim the borrowed areas by producing memory
470 // allocation HOBs, and to honor preexistent memory allocation HOBs when
471 // looking for an area to borrow.
472 //
473 AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
474 } else {
475 //
476 // Create memory HOBs
477 //
478 AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
479
480 if (FeaturePcdGet (PcdSmmSmramRequire)) {
481 UINT32 TsegSize;
482
483 TsegSize = mQ35TsegMbytes * SIZE_1MB;
484 AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
485 AddReservedMemoryBaseSizeHob (
486 LowerMemorySize - TsegSize,
487 TsegSize,
488 TRUE
489 );
490 } else {
491 AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
492 }
493
494 if (UpperMemorySize != 0) {
495 AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
496 }
497 }
498
499 //
500 // We'd like to keep the following ranges uncached:
501 // - [640 KB, 1 MB)
502 // - [LowerMemorySize, 4 GB)
503 //
504 // Everything else should be WB. Unfortunately, programming the inverse (ie.
505 // keeping the default UC, and configuring the complement set of the above as
506 // WB) is not reliable in general, because the end of the upper RAM can have
507 // practically any alignment, and we may not have enough variable MTRRs to
508 // cover it exactly.
509 //
510 if (IsMtrrSupported ()) {
511 MtrrGetAllMtrrs (&MtrrSettings);
512
513 //
514 // See SecMtrrSetup(), default type should be write back
515 //
516 ASSERT ((MtrrSettings.MtrrDefType & BIT11) != 0);
517 ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0);
518 ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == MTRR_CACHE_WRITE_BACK);
519
520 //
521 // flip default type to writeback
522 //
523 SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, MTRR_CACHE_WRITE_BACK);
524 ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables);
525 MtrrSettings.MtrrDefType |= BIT10;
526 MtrrSetAllMtrrs (&MtrrSettings);
527
528 //
529 // Set memory range from 640KB to 1MB to uncacheable
530 //
531 Status = MtrrSetMemoryAttribute (
532 BASE_512KB + BASE_128KB,
533 BASE_1MB - (BASE_512KB + BASE_128KB),
534 CacheUncacheable
535 );
536 ASSERT_EFI_ERROR (Status);
537
538 //
539 // Set memory range from the "top of lower RAM" (RAM below 4GB) to 4GB as
540 // uncacheable
541 //
542 Status = MtrrSetMemoryAttribute (
543 LowerMemorySize,
544 SIZE_4GB - LowerMemorySize,
545 CacheUncacheable
546 );
547 ASSERT_EFI_ERROR (Status);
548 }
549}
550
555VOID
557 VOID
558 )
559{
561
562 if (mS3Supported && (mBootMode != BOOT_ON_S3_RESUME)) {
563 //
564 // This is the memory range that will be used for PEI on S3 resume
565 //
567 mS3AcpiReservedMemoryBase,
568 mS3AcpiReservedMemorySize,
570 );
571
572 //
573 // Cover the initial RAM area used as stack and temporary PEI heap.
574 //
575 // This is reserved as ACPI NVS so it can be used on S3 resume.
576 //
578 PcdGet32 (PcdOvmfSecPeiTempRamBase),
579 PcdGet32 (PcdOvmfSecPeiTempRamSize),
581 );
582
583 //
584 // SEC stores its table of GUIDed section handlers here.
585 //
587 PcdGet64 (PcdGuidedExtractHandlerTableAddress),
588 PcdGet32 (PcdGuidedExtractHandlerTableSize),
590 );
591
592 #ifdef MDE_CPU_X64
593 //
594 // Reserve the initial page tables built by the reset vector code.
595 //
596 // Since this memory range will be used by the Reset Vector on S3
597 // resume, it must be reserved as ACPI NVS.
598 //
600 (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase),
601 (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize),
603 );
604 #endif
605 }
606
607 if (mBootMode != BOOT_ON_S3_RESUME) {
608 if (!FeaturePcdGet (PcdSmmSmramRequire)) {
609 //
610 // Reserve the lock box storage area
611 //
612 // Since this memory range will be used on S3 resume, it must be
613 // reserved as ACPI NVS.
614 //
615 // If S3 is unsupported, then various drivers might still write to the
616 // LockBox area. We ought to prevent DXE from serving allocation requests
617 // such that they would overlap the LockBox storage.
618 //
619 ZeroMem (
620 (VOID *)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase),
621 (UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize)
622 );
624 (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase),
625 (UINT64)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize),
627 );
628 }
629
630 if (FeaturePcdGet (PcdSmmSmramRequire)) {
631 UINT32 TsegSize;
632
633 //
634 // Make sure the TSEG area that we reported as a reserved memory resource
635 // cannot be used for reserved memory allocations.
636 //
637 TsegSize = mQ35TsegMbytes * SIZE_1MB;
639 GetSystemMemorySizeBelow4gb () - TsegSize,
640 TsegSize,
642 );
643 }
644 }
645}
UINT64 UINTN
VOID EFIAPI BuildMemoryAllocationHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN EFI_MEMORY_TYPE MemoryType)
Definition: HobLib.c:601
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
UINT64 EFIAPI GetPowerOfTwo64(IN UINT64 Operand)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
INTN EFIAPI HighBitSet64(IN UINT64 Operand)
Definition: HighBitSet64.c:27
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT8 EFIAPI CmosRead8(IN UINTN Index)
Definition: Cmos.c:25
VOID AddressWidthInitialization(VOID)
Definition: MemDetect.c:248
STATIC UINT64 GetFirstNonAddress(VOID)
Definition: MemDetect.c:155
EFI_STATUS PublishPeiMemory(VOID)
Definition: MemDetect.c:356
STATIC UINT32 GetPeiMemoryCap(VOID)
Definition: MemDetect.c:289
STATIC VOID QemuInitializeRam(VOID)
Definition: MemDetect.c:435
VOID InitializeRamRegions(VOID)
Definition: MemDetect.c:556
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define ASSERT_RETURN_ERROR(StatusParameter)
Definition: DebugLib.h:493
#define DEBUG(Expression)
Definition: DebugLib.h:434
UINT16 EFIAPI PciWrite16(IN UINTN Address, IN UINT16 Value)
Definition: PciLib.c:422
UINT16 EFIAPI PciRead16(IN UINTN Address)
Definition: PciLib.c:396
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
MTRR_SETTINGS *EFIAPI MtrrSetAllMtrrs(IN MTRR_SETTINGS *MtrrSetting)
Definition: MtrrLib.c:2908
BOOLEAN EFIAPI IsMtrrSupported(VOID)
Definition: MtrrLib.c:2960
RETURN_STATUS EFIAPI MtrrSetMemoryAttribute(IN PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN MTRR_MEMORY_CACHE_TYPE Attribute)
Definition: MtrrLib.c:2782
MTRR_SETTINGS *EFIAPI MtrrGetAllMtrrs(OUT MTRR_SETTINGS *MtrrSetting)
Definition: MtrrLib.c:2851
VOID AddMemoryRangeHob(EFI_PHYSICAL_ADDRESS MemoryBase, EFI_PHYSICAL_ADDRESS MemoryLimit)
Definition: Platform.c:139
#define PcdGet16(TokenName)
Definition: PcdLib.h:349
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
#define PcdSet16S(TokenName, Value)
Definition: PcdLib.h:483
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
RETURN_STATUS EFIAPI PublishSystemMemory(IN PHYSICAL_ADDRESS MemoryBegin, IN UINT64 MemoryLength)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
@ EfiBootServicesData
@ EfiReservedMemoryType
@ EfiACPIMemoryNVS