OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
VirtualMemory.c
Go to the documentation of this file.
1
16#include <Uefi.h>
17
18#include <Library/UefiLib.h>
19#include <Library/BaseMemoryLib.h>
20#include <Library/BaseOverflowLib.h>
21#include <Library/MtrrLib.h>
23#include <Library/OcMemoryLib.h>
24
25#include <Register/Intel/Cpuid.h>
26
27//
28// Index on MTRR value.
29// (ref. table 11-8)
30//
31STATIC CHAR8 *MtrrTypeStrings[] = {
32 "UC",
33 "WC",
34 "Reserved",
35 "Reserved",
36 "WT",
37 "WP",
38 "WB"
39};
40
41//
42// Index on PAT type in PAT MSR register, which itself is
43// indexed on PAT bits from page table.
44// (ref. table 11-10)
45//
46STATIC CHAR8 *PatTypeStrings[] = {
47 "UC",
48 "WC",
49 "Reserved",
50 "Reserved",
51 "WT",
52 "WP",
53 "WB",
54 "UC-"
55};
56
57CHAR8 *
59 UINT8 MtrrType
60 )
61{
62 if (MtrrType >= ARRAY_SIZE (MtrrTypeStrings)) {
63 return "Invalid";
64 } else {
65 return MtrrTypeStrings[MtrrType];
66 }
67}
68
69CHAR8 *
71 UINT8 PatType
72 )
73{
74 if (PatType >= ARRAY_SIZE (PatTypeStrings)) {
75 return "Invalid";
76 } else {
77 return PatTypeStrings[PatType];
78 }
79}
80
81BOOLEAN
83 VOID
84 )
85{
86 CPUID_VERSION_INFO_EDX Edx;
87
88 //
89 // Check CPUID(1).EDX[16] for PAT capability
90 //
91 AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32);
92
93 return (Edx.Bits.PAT != 0);
94}
95
98 OUT UINTN *Flags OPTIONAL
99 )
100{
102 UINTN Cr3;
103
104 Cr3 = AsmReadCr3 ();
105
106 PageTable = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)(Cr3 & CR3_ADDR_MASK);
107
108 if (Flags != NULL) {
109 *Flags = Cr3 & (CR3_FLAG_PWT | CR3_FLAG_PCD);
110 }
111
112 return PageTable;
113}
114
115STATIC
116BOOLEAN
118 VOID
119 )
120{
121 UINTN Cr0;
122
123 Cr0 = AsmReadCr0 ();
124
125 if ((Cr0 & CR0_WP) != 0) {
126 AsmWriteCr0 (Cr0 & ~CR0_WP);
127 return TRUE;
128 }
129
130 return FALSE;
131}
132
133STATIC
134VOID
136 VOID
137 )
138{
139 UINTN Cr0;
140
141 Cr0 = AsmReadCr0 ();
142 AsmWriteCr0 (Cr0 | CR0_WP);
143}
144
145EFI_STATUS
147 IN PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL,
148 IN EFI_VIRTUAL_ADDRESS VirtualAddr,
149 OUT EFI_PHYSICAL_ADDRESS *PhysicalAddr
150 )
151{
153 PageTable,
154 VirtualAddr,
155 PhysicalAddr,
156 NULL,
157 NULL,
158 NULL,
159 FALSE
160 );
161}
162
163EFI_STATUS
165 IN PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL,
166 IN EFI_VIRTUAL_ADDRESS VirtualAddr,
167 IN UINT64 Length,
168 IN PAT_INDEX *PatIndex
169 )
170{
171 EFI_STATUS Status;
172 EFI_VIRTUAL_ADDRESS EndAddr;
173 EFI_PHYSICAL_ADDRESS PhysicalAddr;
174 UINT8 Level;
175
176 if (BaseOverflowAddU64 (VirtualAddr, Length, &EndAddr)) {
177 return EFI_INVALID_PARAMETER;
178 }
179
180 do {
182 PageTable,
183 VirtualAddr,
184 &PhysicalAddr,
185 &Level,
186 NULL,
187 PatIndex,
188 TRUE
189 );
190
191 if (EFI_ERROR (Status)) {
192 return Status;
193 }
194
195 if (VirtualAddr != PhysicalAddr) {
196 return EFI_UNSUPPORTED;
197 }
198
199 switch (Level) {
200 case 1:
201 VirtualAddr += SIZE_1GB;
202 break;
203
204 case 2:
205 VirtualAddr += SIZE_2MB;
206 break;
207
208 case 4:
209 VirtualAddr += SIZE_4KB;
210 break;
211
212 default:
213 return EFI_UNSUPPORTED;
214 }
215 } while (VirtualAddr < EndAddr);
216
217 return EFI_SUCCESS;
218}
219
220EFI_STATUS
222 IN PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL,
223 IN EFI_VIRTUAL_ADDRESS VirtualAddr,
224 OUT EFI_PHYSICAL_ADDRESS *PhysicalAddr OPTIONAL,
225 OUT UINT8 *Level OPTIONAL,
226 OUT UINT64 *Bits OPTIONAL,
227 IN OUT PAT_INDEX *PatIndex OPTIONAL,
228 IN BOOLEAN SetPat
229 )
230{
231 EFI_PHYSICAL_ADDRESS Start;
232 VIRTUAL_ADDR VA;
233 VIRTUAL_ADDR VAStart;
234 VIRTUAL_ADDR VAEnd;
238 PAGE_TABLE_4K_ENTRY *PTE4K;
239 PAGE_TABLE_2M_ENTRY *PTE2M;
240 PAGE_TABLE_1G_ENTRY *PTE1G;
241
242 //
243 // Ensure unused bits are zero.
244 //
245 if (!SetPat && (PatIndex != NULL)) {
246 PatIndex->Index = 0;
247 }
248
249 if (PageTable == NULL) {
250 PageTable = OcGetCurrentPageTable (NULL);
251 }
252
253 VA.Uint64 = (UINT64)VirtualAddr;
254
255 //
256 // PML4
257 //
258 PML4 = PageTable;
259 PML4 += VA.Pg4K.PML4Offset;
260 VAStart.Uint64 = 0;
261 VAStart.Pg4K.PML4Offset = VA.Pg4K.PML4Offset;
262 VA_FIX_SIGN_EXTEND (VAStart);
263 VAEnd.Uint64 = ~(UINT64)0;
264 VAEnd.Pg4K.PML4Offset = VA.Pg4K.PML4Offset;
265 VA_FIX_SIGN_EXTEND (VAEnd);
266
267 if (!PML4->Bits.Present) {
268 return EFI_NO_MAPPING;
269 }
270
271 //
272 // PDPE
273 //
275 PDPE += VA.Pg4K.PDPOffset;
276 VAStart.Pg4K.PDPOffset = VA.Pg4K.PDPOffset;
277 VAEnd.Pg4K.PDPOffset = VA.Pg4K.PDPOffset;
278
279 if (!PDPE->Bits.Present) {
280 return EFI_NO_MAPPING;
281 }
282
283 if (PDPE->Bits.MustBeZero & 0x1) {
284 //
285 // 1GB PDPE
286 //
287 PTE1G = (PAGE_TABLE_1G_ENTRY *)PDPE;
289
290 if (PhysicalAddr != NULL) {
291 *PhysicalAddr = Start + VA.Pg1G.PhysPgOffset;
292 }
293
294 if (Level != NULL) {
295 *Level = 1;
296 }
297
298 if (PatIndex != NULL) {
299 if (SetPat) {
300 PTE1G->Bits.WriteThrough = PatIndex->Bits.WriteThrough;
301 PTE1G->Bits.CacheDisabled = PatIndex->Bits.CacheDisabled;
302 PTE1G->Bits.PAT = PatIndex->Bits.PAT;
303 } else {
304 PatIndex->Bits.WriteThrough = (UINT8)PTE1G->Bits.WriteThrough;
305 PatIndex->Bits.CacheDisabled = (UINT8)PTE1G->Bits.CacheDisabled;
306 PatIndex->Bits.PAT = (UINT8)PTE1G->Bits.PAT;
307 }
308 }
309
310 if (Bits != NULL) {
311 *Bits = PTE1G->Uint64;
312 }
313
314 return EFI_SUCCESS;
315 }
316
317 //
318 // PDE
319 //
321 PDE += VA.Pg4K.PDOffset;
322 VAStart.Pg4K.PDOffset = VA.Pg4K.PDOffset;
323 VAEnd.Pg4K.PDOffset = VA.Pg4K.PDOffset;
324
325 if (!PDE->Bits.Present) {
326 return EFI_NO_MAPPING;
327 }
328
329 if (PDE->Bits.MustBeZero & 0x1) {
330 //
331 // 2MB PDE
332 //
333 PTE2M = (PAGE_TABLE_2M_ENTRY *)PDE;
335
336 if (PhysicalAddr != NULL) {
337 *PhysicalAddr = Start + VA.Pg2M.PhysPgOffset;
338 }
339
340 if (Level != NULL) {
341 *Level = 2;
342 }
343
344 if (PatIndex != NULL) {
345 if (SetPat) {
346 PTE2M->Bits.WriteThrough = PatIndex->Bits.WriteThrough;
347 PTE2M->Bits.CacheDisabled = PatIndex->Bits.CacheDisabled;
348 PTE2M->Bits.PAT = PatIndex->Bits.PAT;
349 } else {
350 PatIndex->Bits.WriteThrough = (UINT8)PTE2M->Bits.WriteThrough;
351 PatIndex->Bits.CacheDisabled = (UINT8)PTE2M->Bits.CacheDisabled;
352 PatIndex->Bits.PAT = (UINT8)PTE2M->Bits.PAT;
353 }
354 }
355
356 if (Bits != NULL) {
357 *Bits = PTE2M->Uint64;
358 }
359
360 return EFI_SUCCESS;
361 }
362
363 //
364 // PTE
365 //
366 PTE4K = (PAGE_TABLE_4K_ENTRY *)(UINTN)(PDE->Uint64 & PAGING_4K_ADDRESS_MASK_64);
367 PTE4K += VA.Pg4K.PTOffset;
368 VAStart.Pg4K.PTOffset = VA.Pg4K.PTOffset;
369 VAEnd.Pg4K.PTOffset = VA.Pg4K.PTOffset;
370
371 if (!PTE4K->Bits.Present) {
372 return EFI_NO_MAPPING;
373 }
374
376
377 if (PhysicalAddr != NULL) {
378 *PhysicalAddr = Start + VA.Pg4K.PhysPgOffset;
379 }
380
381 if (Level != NULL) {
382 *Level = 4;
383 }
384
385 if (PatIndex != NULL) {
386 if (SetPat) {
387 PTE4K->Bits.WriteThrough = PatIndex->Bits.WriteThrough;
388 PTE4K->Bits.CacheDisabled = PatIndex->Bits.CacheDisabled;
389 PTE4K->Bits.PAT = PatIndex->Bits.PAT;
390 } else {
391 PatIndex->Bits.WriteThrough = (UINT8)PTE4K->Bits.WriteThrough;
392 PatIndex->Bits.CacheDisabled = (UINT8)PTE4K->Bits.CacheDisabled;
393 PatIndex->Bits.PAT = (UINT8)PTE4K->Bits.PAT;
394 }
395 }
396
397 if (Bits != NULL) {
398 *Bits = PTE4K->Uint64;
399 }
400
401 return EFI_SUCCESS;
402}
403
404//
405// MTRR types would ideally be passed as MTRR_MEMORY_CACHE_TYPE, but this
406// requires Library/MtrrLib.h in the .inf and .c files of everything which
407// consumes OcMemoryLib.
408//
409EFI_STATUS
411 IN EFI_PHYSICAL_ADDRESS Address,
412 IN UINT8 MtrrType,
413 OUT UINT64 *Length OPTIONAL
414 )
415{
416 EFI_PHYSICAL_ADDRESS Walker;
417 UINT8 OriginalMtrrType;
418
419 if (Length != NULL) {
420 *Length = 0;
421 }
422
423 if (!IsMtrrSupported ()) {
424 return EFI_UNSUPPORTED;
425 }
426
427 Walker = Address;
428 OriginalMtrrType = MtrrGetMemoryAttribute (Walker);
429 do {
430 Walker += SIZE_2MB;
431 } while (OriginalMtrrType == MtrrGetMemoryAttribute (Walker));
432
433 if (Length != NULL) {
434 *Length = Walker - Address;
435 }
436
437 return MtrrSetMemoryAttribute (Address, Walker - Address, MtrrType);
438}
439
440EFI_STATUS
442 OUT OC_VMEM_CONTEXT *Context,
443 IN UINTN NumPages,
444 IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL
445 )
446{
447 EFI_STATUS Status;
448 EFI_PHYSICAL_ADDRESS Addr;
449
450 Addr = BASE_4GB;
451 Status = OcAllocatePagesFromTop (
452 EfiBootServicesData,
453 NumPages,
454 &Addr,
455 GetMemoryMap,
456 NULL,
457 NULL
458 );
459
460 if (!EFI_ERROR (Status)) {
461 Context->MemoryPool = (UINT8 *)(UINTN)Addr;
462 Context->FreePages = NumPages;
463 }
464
465 return Status;
466}
467
468VOID *
470 IN OUT OC_VMEM_CONTEXT *Context,
471 IN UINTN NumPages
472 )
473{
474 VOID *AllocatedPages;
475
476 AllocatedPages = NULL;
477
478 if (Context->FreePages >= NumPages) {
479 AllocatedPages = Context->MemoryPool;
480 Context->MemoryPool += EFI_PAGES_TO_SIZE (NumPages);
481 Context->FreePages -= NumPages;
482 }
483
484 return AllocatedPages;
485}
486
487EFI_STATUS
489 IN OUT OC_VMEM_CONTEXT *Context,
490 IN OUT PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL,
491 IN EFI_VIRTUAL_ADDRESS VirtualAddr,
492 IN EFI_PHYSICAL_ADDRESS PhysicalAddr
493 )
494{
495 EFI_PHYSICAL_ADDRESS Start;
496 VIRTUAL_ADDR VA;
497 VIRTUAL_ADDR VAStart;
498 VIRTUAL_ADDR VAEnd;
502 PAGE_TABLE_4K_ENTRY *PTE4K;
503 PAGE_TABLE_4K_ENTRY *PTE4KTmp;
504 PAGE_TABLE_2M_ENTRY *PTE2M;
505 PAGE_TABLE_1G_ENTRY *PTE1G;
506 UINTN Index;
507 BOOLEAN WriteProtected;
508
509 if (PageTable == NULL) {
510 PageTable = OcGetCurrentPageTable (NULL);
511 }
512
513 WriteProtected = DisablePageTableWriteProtection ();
514
515 VA.Uint64 = (UINT64)VirtualAddr;
516
517 //
518 // PML4
519 //
520 PML4 = PageTable;
521 PML4 += VA.Pg4K.PML4Offset;
522
523 //
524 // There is a problem if our PML4 points to the same table as first PML4 entry
525 // since we may mess the mapping of first virtual region (happens in VBox and probably DUET).
526 // Check for this on first call and if true, just clear our PML4 - we'll rebuild at a later step.
527 //
528 if ( (PML4 != PageTable) && PML4->Bits.Present
529 && (PageTable->Bits.PageTableBaseAddress == PML4->Bits.PageTableBaseAddress))
530 {
531 PML4->Uint64 = 0;
532 }
533
534 VAStart.Uint64 = 0;
535 VAStart.Pg4K.PML4Offset = VA.Pg4K.PML4Offset;
536 VA_FIX_SIGN_EXTEND (VAStart);
537 VAEnd.Uint64 = ~(UINT64)0;
538 VAEnd.Pg4K.PML4Offset = VA.Pg4K.PML4Offset;
539 VA_FIX_SIGN_EXTEND (VAEnd);
540
541 if (!PML4->Bits.Present) {
542 PDPE = (PAGE_MAP_AND_DIRECTORY_POINTER *)VmAllocatePages (Context, 1);
543
544 if (PDPE == NULL) {
545 if (WriteProtected) {
547 }
548
549 return EFI_NO_MAPPING;
550 }
551
552 ZeroMem (PDPE, EFI_PAGE_SIZE);
553
554 //
555 // Init this whole 512 GB region with 512 1GB entry pages to map
556 // the first 512 GB physical space.
557 //
558 PTE1G = (PAGE_TABLE_1G_ENTRY *)PDPE;
559 Start = 0;
560 for (Index = 0; Index < 512; ++Index) {
562 PTE1G->Bits.ReadWrite = 1;
563 PTE1G->Bits.Present = 1;
564 PTE1G->Bits.MustBe1 = 1;
565 PTE1G++;
566 Start += BASE_1GB;
567 }
568
569 //
570 // Put it to PML4.
571 //
572 PML4->Uint64 = ((UINT64)(UINTN)PDPE) & PAGING_4K_ADDRESS_MASK_64;
573 PML4->Bits.ReadWrite = 1;
574 PML4->Bits.Present = 1;
575 }
576
577 //
578 // PDPE
579 //
581 PDPE += VA.Pg4K.PDPOffset;
582 VAStart.Pg4K.PDPOffset = VA.Pg4K.PDPOffset;
583 VAEnd.Pg4K.PDPOffset = VA.Pg4K.PDPOffset;
584
585 if (!PDPE->Bits.Present || (PDPE->Bits.MustBeZero & 0x1)) {
587
588 if (PDE == NULL) {
589 if (WriteProtected) {
591 }
592
593 return EFI_NO_MAPPING;
594 }
595
596 ZeroMem (PDE, EFI_PAGE_SIZE);
597
598 if (PDPE->Bits.MustBeZero & 0x1) {
599 //
600 // This is 1 GB page. Init new PDE array to get the same
601 // mapping but with 2MB pages.
602 //
603 PTE2M = (PAGE_TABLE_2M_ENTRY *)PDE;
605
606 for (Index = 0; Index < 512; ++Index) {
608 PTE2M->Bits.ReadWrite = 1;
609 PTE2M->Bits.Present = 1;
610 PTE2M->Bits.MustBe1 = 1;
611 PTE2M++;
612 Start += BASE_2MB;
613 }
614 }
615
616 //
617 // Put it to PDPE.
618 //
619 PDPE->Uint64 = ((UINT64)(UINTN)PDE) & PAGING_4K_ADDRESS_MASK_64;
620 PDPE->Bits.ReadWrite = 1;
621 PDPE->Bits.Present = 1;
622 }
623
624 //
625 // PDE
626 //
628 PDE += VA.Pg4K.PDOffset;
629 VAStart.Pg4K.PDOffset = VA.Pg4K.PDOffset;
630 VAEnd.Pg4K.PDOffset = VA.Pg4K.PDOffset;
631
632 if (!PDE->Bits.Present || (PDE->Bits.MustBeZero & 0x1)) {
633 PTE4K = (PAGE_TABLE_4K_ENTRY *)VmAllocatePages (Context, 1);
634
635 if (PTE4K == NULL) {
636 if (WriteProtected) {
638 }
639
640 return EFI_NO_MAPPING;
641 }
642
643 ZeroMem (PTE4K, EFI_PAGE_SIZE);
644
645 if (PDE->Bits.MustBeZero & 0x1) {
646 //
647 // This is 2 MB page. Init new PTE array to get the same
648 // mapping but with 4KB pages.
649 //
650 PTE4KTmp = (PAGE_TABLE_4K_ENTRY *)PTE4K;
652
653 for (Index = 0; Index < 512; ++Index) {
655 PTE4KTmp->Bits.ReadWrite = 1;
656 PTE4KTmp->Bits.Present = 1;
657 PTE4KTmp++;
658 Start += BASE_4KB;
659 }
660 }
661
662 //
663 // Put it to PDE.
664 //
665 PDE->Uint64 = ((UINT64)(UINTN)PTE4K) & PAGING_4K_ADDRESS_MASK_64;
666 PDE->Bits.ReadWrite = 1;
667 PDE->Bits.Present = 1;
668 }
669
670 //
671 // PTE
672 //
673 PTE4K = (PAGE_TABLE_4K_ENTRY *)(UINTN)(PDE->Uint64 & PAGING_4K_ADDRESS_MASK_64);
674 PTE4K += VA.Pg4K.PTOffset;
675 VAStart.Pg4K.PTOffset = VA.Pg4K.PTOffset;
676 VAEnd.Pg4K.PTOffset = VA.Pg4K.PTOffset;
677
678 //
679 // Put it to PTE.
680 //
681 PTE4K->Uint64 = ((UINT64)PhysicalAddr) & PAGING_4K_ADDRESS_MASK_64;
682 PTE4K->Bits.ReadWrite = 1;
683 PTE4K->Bits.Present = 1;
684
685 if (WriteProtected) {
687 }
688
689 return EFI_SUCCESS;
690}
691
692EFI_STATUS
694 IN OUT OC_VMEM_CONTEXT *Context,
695 IN OUT PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL,
696 IN EFI_VIRTUAL_ADDRESS VirtualAddr,
697 IN UINT64 NumPages,
698 IN EFI_PHYSICAL_ADDRESS PhysicalAddr
699 )
700{
701 EFI_STATUS Status;
702
703 if (PageTable == NULL) {
704 PageTable = OcGetCurrentPageTable (NULL);
705 }
706
707 Status = EFI_SUCCESS;
708
709 while (NumPages > 0 && !EFI_ERROR (Status)) {
710 Status = VmMapVirtualPage (
711 Context,
712 PageTable,
713 VirtualAddr,
714 PhysicalAddr
715 );
716
717 VirtualAddr += EFI_PAGE_SIZE;
718 PhysicalAddr += EFI_PAGE_SIZE;
719 NumPages--;
720 }
721
722 return Status;
723}
724
725VOID
727 VOID
728 )
729{
730 //
731 // Simply reload CR3 register.
732 //
733 AsmWriteCr3 (AsmReadCr3 ());
734}
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
UINT64 Start
UINT64 Length
#define PAGING_2M_ADDRESS_MASK_64
#define CR3_ADDR_MASK
#define CR3_FLAG_PWT
#define CR3_FLAG_PCD
#define VA_FIX_SIGN_EXTEND(VA)
#define CR0_WP
#define PAGING_4K_ADDRESS_MASK_64
#define PAGING_1G_ADDRESS_MASK_64
EFI_STATUS OcAllocatePagesFromTop(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN OUT EFI_PHYSICAL_ADDRESS *Memory, IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, IN EFI_ALLOCATE_PAGES AllocatePages OPTIONAL, IN CHECK_ALLOCATION_RANGE CheckRange OPTIONAL)
Definition MemoryAlloc.c:27
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT32 AsmCpuid(IN UINT32 Index, OUT UINT32 *Eax, OPTIONAL OUT UINT32 *Ebx, OPTIONAL OUT UINT32 *Ecx, OPTIONAL OUT UINT32 *Edx OPTIONAL)
Definition UserMisc.c:45
EFI_STATUS VmMapVirtualPage(IN OUT OC_VMEM_CONTEXT *Context, IN OUT PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, IN EFI_VIRTUAL_ADDRESS VirtualAddr, IN EFI_PHYSICAL_ADDRESS PhysicalAddr)
PAGE_MAP_AND_DIRECTORY_POINTER * OcGetCurrentPageTable(OUT UINTN *Flags OPTIONAL)
EFI_STATUS OcGetPhysicalAddress(IN PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, IN EFI_VIRTUAL_ADDRESS VirtualAddr, OUT EFI_PHYSICAL_ADDRESS *PhysicalAddr)
STATIC CHAR8 * PatTypeStrings[]
VOID VmFlushCaches(VOID)
STATIC VOID EnablePageTableWriteProtection(VOID)
EFI_STATUS OcSetPatIndexForAddressRange(IN PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, IN EFI_VIRTUAL_ADDRESS VirtualAddr, IN UINT64 Length, IN PAT_INDEX *PatIndex)
STATIC CHAR8 * MtrrTypeStrings[]
BOOLEAN OcIsPatSupported(VOID)
EFI_STATUS VmMapVirtualPages(IN OUT OC_VMEM_CONTEXT *Context, IN OUT PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, IN EFI_VIRTUAL_ADDRESS VirtualAddr, IN UINT64 NumPages, IN EFI_PHYSICAL_ADDRESS PhysicalAddr)
EFI_STATUS OcModifyMtrrRange(IN EFI_PHYSICAL_ADDRESS Address, IN UINT8 MtrrType, OUT UINT64 *Length OPTIONAL)
EFI_STATUS VmAllocateMemoryPool(OUT OC_VMEM_CONTEXT *Context, IN UINTN NumPages, IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL)
CHAR8 * OcGetPatTypeString(UINT8 PatType)
EFI_STATUS OcGetSetPageTableInfoForAddress(IN PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, IN EFI_VIRTUAL_ADDRESS VirtualAddr, OUT EFI_PHYSICAL_ADDRESS *PhysicalAddr OPTIONAL, OUT UINT8 *Level OPTIONAL, OUT UINT64 *Bits OPTIONAL, IN OUT PAT_INDEX *PatIndex OPTIONAL, IN BOOLEAN SetPat)
STATIC BOOLEAN DisablePageTableWriteProtection(VOID)
CHAR8 * OcGetMtrrTypeString(UINT8 MtrrType)
VOID * VmAllocatePages(IN OUT OC_VMEM_CONTEXT *Context, IN UINTN NumPages)
struct PAGE_MAP_AND_DIRECTORY_POINTER::@69 Bits
struct PAGE_TABLE_1G_ENTRY::@72 Bits
struct PAGE_TABLE_2M_ENTRY::@71 Bits
struct PAGE_TABLE_4K_ENTRY::@70 Bits
struct VIRTUAL_ADDR::@76 Pg1G
struct VIRTUAL_ADDR::@74 Pg4K
UINT64 PhysPgOffset
struct VIRTUAL_ADDR::@75 Pg2M