ReactOS 0.4.15-dev-7924-g5949c20
mmx86.c
Go to the documentation of this file.
1/*
2* COPYRIGHT: See COPYING.ARM in the top level directory
3* PROJECT: ReactOS UEFI Boot Library
4* FILE: boot/environ/lib/mm/i386/mmx86.c
5* PURPOSE: Boot Library Memory Manager x86-Specific Code
6* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7*/
8
9/* INCLUDES ******************************************************************/
10
11#include "bl.h"
12#include "bcd.h"
13
14#define PTE_BASE 0xC0000000
15
16//
17// Specific PDE/PTE macros to be used inside the boot library environment
18//
19#define MiAddressToPte(x) ((PMMPTE)(((((ULONG)(x)) >> 12) << 2) + (ULONG_PTR)MmPteBase))
20#define MiAddressToPde(x) ((PMMPDE)(((((ULONG)(x)) >> 22) << 2) + (ULONG_PTR)MmPdeBase))
21#define MiAddressToPteOffset(x) ((((ULONG)(x)) << 10) >> 22)
22#define MiAddressToPdeOffset(x) (((ULONG)(x)) / (1024 * PAGE_SIZE))
23
24/* DATA VARIABLES ************************************************************/
25
38
46
51
53
54/* FUNCTIONS *****************************************************************/
55
58 VOID
59 )
60{
61 /* Return if paging is on */
62 return ((CurrentExecutionContext) &&
64}
65
66VOID
68 VOID
69 )
70{
71 /* Nothing to do */
72 return;
73}
74
75VOID
77 VOID
78 )
79{
80 if (MmPteBase != (PVOID)PTE_BASE)
81 {
82 EfiPrintf(L"Supposed to relocate CR3\r\n");
83 }
84}
85
91 )
92{
93 EfiPrintf(L"Supposed to move shit\r\n");
95}
96
101 )
102{
103 EfiPrintf(L"Supposed to zero shit\r\n");
105}
106
111 _Out_opt_ PULONG CachingFlags
112 )
113{
115
116 /* Check if paging is on */
119 {
120 /* Yes -- we have to translate this from virtual */
123 CachingFlags);
124 }
125
126 /* Look in all descriptors except truncated and firmware ones */
131
132 /* Return the virtual address as the physical address */
133 if (PhysicalAddress)
134 {
137 }
138
139 /* There's no caching on physical memory */
140 if (CachingFlags)
141 {
142 *CachingFlags = 0;
143 }
144
145 /* Success is if we found a descriptor */
146 return Descriptor != NULL;
147}
148
149VOID
151 VOID
152 )
153{
154 EfiPrintf(L"No destroy\r\n");
155}
156
157VOID
160 )
161{
162 /* Flush the TLB */
164}
165
166VOID
168 VOID
169 )
170{
171 /* Flush the TLB */
173}
174
179 )
180{
181 EfiPrintf(L"No unmap\r\n");
183}
184
190 _In_ ULONG CacheAttributes
191 )
192{
193 EfiPrintf(L"No remap\r\n");
195}
196
202 _In_ ULONG CacheAttributes
203 )
204{
206 ULONG i, PageCount, PdeOffset;
207 ULONGLONG CurrentAddress;
208 PMMPDE Pde;
209 PMMPTE Pte;
211 PHYSICAL_ADDRESS PageTableAddress;
213
214 /* Check if paging is on yet */
216
217 /* Get the physical address aligned */
218 CurrentAddress = (PhysicalAddress.QuadPart >> PAGE_SHIFT) << PAGE_SHIFT;
219
220 /* Get the number of pages and loop through each one */
221 PageCount = Size >> PAGE_SHIFT;
222 for (i = 0; i < PageCount; i++)
223 {
224 /* Check if translation already exists for this page */
226 {
227 /* Ignore it and move to the next one */
229 CurrentAddress += PAGE_SIZE;
230 continue;
231 }
232
233 /* Get the PDE offset */
235
236 /* Check if paging is actually turned on */
237 if (Enabled)
238 {
239 /* Get the PDE entry using the self-map */
241 }
242 else
243 {
244 /* Get it using our physical mappings */
245 Pde = &MmPdpt[PdeOffset];
247 }
248
249 /* Check if we don't yet have a PDE */
250 if (!Pde->u.Hard.Valid)
251 {
252 /* Allocate a page table */
253 Status = MmPapAllocatePhysicalPagesInRange(&PageTableAddress,
255 1,
256 0,
257 0,
259 0,
260 0);
261 if (!NT_SUCCESS(Status))
262 {
263 EfiPrintf(L"PDE alloc failed!\r\n");
264 EfiStall(1000000);
265 return STATUS_NO_MEMORY;
266 }
267
268 /* This is our page table */
269 PageTable = (PVOID)(ULONG_PTR)PageTableAddress.QuadPart;
270
271 /* Build the PDE for it */
272 Pde->u.Hard.PageFrameNumber = PageTableAddress.QuadPart >> PAGE_SHIFT;
273 Pde->u.Hard.Write = 1;
274 Pde->u.Hard.CacheDisable = 1;
275 Pde->u.Hard.WriteThrough = 1;
276 Pde->u.Hard.Valid = 1;
277
278 /* Check if paging is enabled */
279 if (Enabled)
280 {
281 /* Then actually, get the page table's virtual address */
283
284 /* Flush the TLB */
286 }
287
288 /* Zero out the page table */
290
291 /* Reset caching attributes now */
292 Pde->u.Hard.CacheDisable = 0;
293 Pde->u.Hard.WriteThrough = 0;
294
295 /* Check for paging again */
296 if (Enabled)
297 {
298 /* Flush the TLB entry for the page table only */
300 }
301 }
302
303 /* Add a reference to this page table */
304 MmArchReferencePage[PdeOffset]++;
305
306 /* Check if a physical address was given */
307 if (PhysicalAddress.QuadPart != -1)
308 {
309 /* Check if paging is turned on */
310 if (Enabled)
311 {
312 /* Get the PTE using the self-map */
314 }
315 else
316 {
317 /* Get the PTE using physical addressing */
319 }
320
321 /* Build a valid PTE for it */
322 Pte->u.Hard.PageFrameNumber = CurrentAddress >> PAGE_SHIFT;
323 Pte->u.Hard.Write = 1;
324 Pte->u.Hard.Valid = 1;
325
326 /* Check if this is uncached */
327 if (CacheAttributes == BlMemoryUncached)
328 {
329 /* Set the flags */
330 Pte->u.Hard.CacheDisable = 1;
331 Pte->u.Hard.WriteThrough = 1;
332 }
333 else if (CacheAttributes == BlMemoryWriteThrough)
334 {
335 /* It's write-through, set the flag */
336 Pte->u.Hard.WriteThrough = 1;
337 }
338 }
339
340 /* Move to the next physical/virtual address */
342 CurrentAddress += PAGE_SIZE;
343 }
344
345 /* All done! */
346 return STATUS_SUCCESS;
347}
348
353 _Out_opt_ PULONG CacheAttributes
354 )
355{
356 PMMPDE Pde;
357 PMMPTE Pte;
360
361 /* Is there no page directory yet? */
362 if (!MmPdpt)
363 {
364 return FALSE;
365 }
366
367 /* Is paging enabled? */
369
370 /* Check if paging is actually turned on */
371 if (Enabled)
372 {
373 /* Get the PDE entry using the self-map */
375 }
376 else
377 {
378 /* Get it using our physical mappings */
380 }
381
382 /* Is the PDE valid? */
383 if (!Pde->u.Hard.Valid)
384 {
385 return FALSE;
386 }
387
388 /* Check if paging is turned on */
389 if (Enabled)
390 {
391 /* Get the PTE using the self-map */
393 }
394 else
395 {
396 /* Get the PTE using physical addressing */
399 }
400
401 /* Is the PTE valid? */
402 if (!Pte->u.Hard.Valid)
403 {
404 return FALSE;
405 }
406
407 /* Does caller want the physical address? */
408 if (PhysicalAddress)
409 {
410 /* Return it */
413 }
414
415 /* Does caller want cache attributes? */
416 if (CacheAttributes)
417 {
418 /* Not yet -- lie and say it's cached */
419 EfiPrintf(L"Cache checking not yet enabled\r\n");
420 *CacheAttributes = BlMemoryWriteBack;
421 }
422
423 /* It exists! */
424 return TRUE;
425}
426
429 _Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr,
430 _Inout_ PVOID* VirtualAddressPtr,
431 _Inout_ PULONGLONG SizePtr,
432 _In_ ULONG CacheAttributes
433 )
434{
439 ULONG_PTR CurrentAddress, VirtualAddressEnd;
441
442 /* Fail if any parameters are missing */
443 if (!(PhysicalAddressPtr) || !(VirtualAddressPtr) || !(SizePtr))
444 {
446 }
447
448 /* Fail if the size is over 32-bits */
449 Size = *SizePtr;
450 if (Size > 0xFFFFFFFF)
451 {
453 }
454
455 /* Nothing to do if we're in physical mode */
457 {
458 return STATUS_SUCCESS;
459 }
460
461 /* Can't use virtual memory in real mode */
463 {
464 return STATUS_UNSUCCESSFUL;
465 }
466
467 /* Capture the current virtual and physical addresses */
468 VirtualAddress = *VirtualAddressPtr;
469 PhysicalAddress = PhysicalAddressPtr->QuadPart;
470
471 /* Check if a physical address was requested */
472 if (PhysicalAddress != 0xFFFFFFFF)
473 {
474 /* Round down the base addresses */
477
478 /* Round up the size */
479 Size = ROUND_TO_PAGES(PhysicalAddressPtr->QuadPart -
481 Size);
482
483 /* Loop every virtual page */
484 CurrentAddress = (ULONG_PTR)VirtualAddress;
485 VirtualAddressEnd = CurrentAddress + Size - 1;
486 while (CurrentAddress < VirtualAddressEnd)
487 {
488 /* Get the physical page of this virtual page */
489 if (MmArchTranslateVirtualAddress((PVOID)CurrentAddress,
491 &CacheAttributes))
492 {
493 /* Make sure the physical page of the virtual page, matches our page */
496 (CurrentAddress - (ULONG_PTR)VirtualAddress)))
497 {
498 /* There is an existing virtual mapping for a different address */
499 EfiPrintf(L"Existing mapping exists: %lx vs %lx\r\n",
501 PhysicalAddress + (CurrentAddress - (ULONG_PTR)VirtualAddress));
502 EfiStall(10000000);
504 }
505 }
506
507 /* Try the next one */
508 CurrentAddress += PAGE_SIZE;
509 }
510 }
511
512 /* Aactually do the mapping */
516 Size,
517 CacheAttributes);
518 if (!NT_SUCCESS(Status))
519 {
520 EfiPrintf(L"Failed to map!: %lx\r\n", Status);
521 EfiStall(1000000);
522 return Status;
523 }
524
525 /* Return aligned/fixed up output parameters */
526 PhysicalAddressPtr->QuadPart = PhysicalAddress;
527 *VirtualAddressPtr = VirtualAddress;
528 *SizePtr = Size;
529
530 /* Flush the TLB if paging is enabled */
532 {
534 }
535
536 /* All good! */
537 return STATUS_SUCCESS;
538}
539
545 )
546{
548
549 /* Make a virtual mapping for this physical address */
551 if (!NT_SUCCESS(Status))
552 {
553 return Status;
554 }
555
556 /* Nothing else to do if we're not in paging mode */
558 {
559 return STATUS_SUCCESS;
560 }
561
562 /* Otherwise, remove this region from the list of free virtual ranges */
566 Size >> PAGE_SHIFT,
567 0);
568 if (!NT_SUCCESS(Status))
569 {
570 /* Unmap the address if that failed */
572 }
573
574 /* Return back to caller */
575 return Status;
576}
577
578VOID
580 _In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList,
581 _In_opt_ ULONG MaxCount
582 )
583{
584 ULONGLONG EndPage, VirtualEndPage;
586 PLIST_ENTRY NextEntry;
587
588 /* If no maximum was provided, use essentially infinite */
589 if (MaxCount == 0)
590 {
591 MaxCount = 0xFFFFFFFF;
592 }
593
594 /* Loop the list as long as there's entries and max isn't reached */
595 NextEntry = DescriptorList->First->Flink;
596 while ((NextEntry != DescriptorList->First) && (MaxCount--))
597 {
598 /* Get the descriptor */
601 ListEntry);
602
603 /* Get the descriptor end page, and see if it was virtually mapepd */
604 EndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
605 if (MemoryDescriptor->VirtualPage)
606 {
607 /* Get the virtual end page too, then */
608 VirtualEndPage = MemoryDescriptor->VirtualPage +
609 MemoryDescriptor->PageCount;
610 }
611 else
612 {
613 VirtualEndPage = 0;
614 }
615
616 /* Print out the descriptor, physical range, virtual range, and type */
617 EfiPrintf(L"%p - [%08llx-%08llx @ %08llx-%08llx]:%x\r\n",
619 MemoryDescriptor->BasePage << PAGE_SHIFT,
620 (EndPage << PAGE_SHIFT) - 1,
621 MemoryDescriptor->VirtualPage << PAGE_SHIFT,
622 VirtualEndPage ? (VirtualEndPage << PAGE_SHIFT) - 1 : 0,
623 (ULONG)MemoryDescriptor->Type);
624
625 /* Next entry */
626 NextEntry = NextEntry->Flink;
627 }
628}
629
632 _In_ ULONG Phase,
633 _In_ PBL_MEMORY_DATA MemoryData
634 )
635{
636 BOOLEAN DoDeferred;
637 ULONG DescriptorCount;
639 ULONG FinalOffset;
644 BL_MEMORY_DESCRIPTOR_LIST FirmwareMdl;
645 PLIST_ENTRY Head, NextEntry;
646
647 /* Check which phase this is */
648 if (Phase == 1)
649 {
650 /* In phase 1 we don't initialize deferred mappings */
651 DoDeferred = FALSE;
652 }
653 else
654 {
655 /* Don't do anything if there's nothing to initialize */
657 {
658 return STATUS_SUCCESS;
659 }
660
661 /* We'll do deferred descriptors in phase 2 */
662 DoDeferred = TRUE;
663 }
664
665 /*
666 * Because BL supports cross x86-x64 application launches and a LIST_ENTRY
667 * is of variable size, care must be taken here to ensure that we see a
668 * consistent view of descriptors. BL uses some offset magic to figure out
669 * where the data actually starts, since everything is ULONGLONG past the
670 * LIST_ENTRY itself
671 */
672 FinalOffset = MemoryData->MdListOffset + MemoryData->DescriptorOffset;
673 Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)MemoryData + FinalOffset -
675
676 /* Scan all of them */
677 DescriptorCount = MemoryData->DescriptorCount;
678 while (DescriptorCount != 0)
679 {
680 /* Ignore application data */
681 if (Descriptor->Type != BlApplicationData)
682 {
683 /* If this is a ramdisk, do it in phase 2 */
684 if ((Descriptor->Type == BlLoaderRamDisk) == DoDeferred)
685 {
686 /* Get the current physical address and size */
688 Size = Descriptor->PageCount << PAGE_SHIFT;
689
690 /* Check if it was already mapped */
691 if (Descriptor->VirtualPage)
692 {
693 /* Use the existing address */
694 VirtualAddress = (PVOID)(ULONG_PTR)(Descriptor->VirtualPage << PAGE_SHIFT);
695 }
696 else
697 {
698 /* Use the physical address */
700 }
701
702 /* Crete the mapping */
704 Size,
706 if (!NT_SUCCESS(Status))
707 {
708 return Status;
709 }
710 }
711
712 /* Check if we're in phase 1 and deferring RAM disk */
713 if ((Phase == 1) && (Descriptor->Type == BlLoaderRamDisk))
714 {
716 }
717 }
718
719 /* Move on to the next descriptor */
720 DescriptorCount--;
721 Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)Descriptor + MemoryData->DescriptorSize);
722 }
723
724 /* In phase 1, also do UEFI mappings */
725 if (Phase != 2)
726 {
727 /* Get the memory map */
728 MmMdInitializeListHead(&FirmwareMdl);
730 if (!NT_SUCCESS(Status))
731 {
732 return Status;
733 }
734
735 /* Iterate over it */
736 Head = FirmwareMdl.First;
737 NextEntry = Head->Flink;
738 while (NextEntry != Head)
739 {
740 /* Check if this is a UEFI-related descriptor, unless it's the self-map page */
741 Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
742 if (((Descriptor->Type == BlEfiBootMemory) ||
744 (Descriptor->Type == BlEfiRuntimeDataMemory) || // WINBUG?
745 (Descriptor->Type == BlLoaderMemory)) &&
747 {
748 /* Identity-map it */
751 Descriptor->PageCount << PAGE_SHIFT,
753 if (!NT_SUCCESS(Status))
754 {
755 return Status;
756 }
757 }
758
759 /* Move to the next descriptor */
760 NextEntry = NextEntry->Flink;
761 }
762
763 /* Reset */
764 NextEntry = Head->Flink;
765 while (NextEntry != Head)
766 {
767 /* Get the descriptor */
768 Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
769
770 /* Skip to the next entry before we free */
771 NextEntry = NextEntry->Flink;
772
773 /* Remove and free it */
776 }
777 }
778
779 /* All library mappings identity mapped now */
780 return STATUS_SUCCESS;
781}
782
785 _In_ ULONG Phase,
786 _In_ PBL_MEMORY_DATA MemoryData
787 )
788{
789 ULONG ImageSize;
790 PVOID ImageBase;
791 KDESCRIPTOR Gdt, Idt;
794
795 /* If this is phase 2, map the memory regions */
796 if (Phase != 1)
797 {
798 return Mmx86pMapMemoryRegions(Phase, MemoryData);
799 }
800
801 /* Get the application image base/size */
802 Status = BlGetApplicationBaseAndSize(&ImageBase, &ImageSize);
803 if (!NT_SUCCESS(Status))
804 {
805 return Status;
806 }
807
808 /* Map the image back at the same place */
810 Status = Mmx86MapInitStructure(ImageBase, ImageSize, PhysicalAddress);
811 if (!NT_SUCCESS(Status))
812 {
813 return Status;
814 }
815
816 /* Map the first 4MB of memory */
819 if (!NT_SUCCESS(Status))
820 {
821 return Status;
822 }
823
824 /* Map the GDT */
825 _sgdt(&Gdt.Limit);
828 if (!NT_SUCCESS(Status))
829 {
830 return Status;
831 }
832
833 /* Map the IDT */
834 __sidt(&Idt.Limit);
837 if (!NT_SUCCESS(Status))
838 {
839 return Status;
840 }
841
842 /* Map the reference page */
847 if (!NT_SUCCESS(Status))
848 {
849 return Status;
850 }
851
852 /* More to do */
853 return Mmx86pMapMemoryRegions(Phase, MemoryData);
854}
855
858 _In_ PBL_MEMORY_DATA MemoryData,
859 _In_ BL_TRANSLATION_TYPE TranslationType
860 )
861{
864 ULONG PdeIndex;
865
866 /* Set the global function pointers for memory translation */
874
875 /* Check what mode we're currently in */
876 if (TranslationType == BlVirtual)
877 {
878 EfiPrintf(L"Virtual->Virtual not yet supported\r\n");
880 }
881 else if (TranslationType != BlNone)
882 {
883 /* Not even Windows supports PAE->Virtual downgrade */
885 }
886
887 /* The None->Virtual case */
888 MmPdpt = NULL;
891
892 /* Truncate all memory above 4GB so that we don't use it */
893 Status = MmPaTruncateMemory(0x100000);
894 if (!NT_SUCCESS(Status))
895 {
896 goto Failure;
897 }
898
899 /* Allocate a page directory */
902 1,
903 0,
904 0,
906 0,
907 0);
908 if (!NT_SUCCESS(Status))
909 {
910 goto Failure;
911 }
912
913 /* Zero out the page directory */
916
917 /* Set the page size */
919
920 /* Allocate the self-map page */
923 1,
924 0,
925 0,
927 0,
928 0);
929 if (!NT_SUCCESS(Status))
930 {
931 goto Failure;
932 }
933
934 /* Set the reference page */
936
937 /* Zero it out */
939
940 /* Allocate 4MB worth of self-map pages */
942 (4 * 1024 * 1024) >> PAGE_SHIFT,
943 (4 * 1024 * 1024) >> PAGE_SHIFT);
944 if (!NT_SUCCESS(Status))
945 {
946 goto Failure;
947 }
948
949 /* Zero them out */
950 RtlZeroMemory((PVOID)Mmx86SelfMapBase.LowPart, 4 * 1024 * 1024);
951 EfiPrintf(L"PDPT at 0x%p Reference Page at 0x%p Self-map at 0x%p\r\n",
953
954 /* Align PTE base to 4MB region */
955 MmPteBase = (PVOID)(Mmx86SelfMapBase.LowPart & ~0x3FFFFF);
956
957 /* The PDE is the PTE of the PTE base */
960 MmPdpt[PdeIndex].u.Hard.Valid = 1;
961 MmPdpt[PdeIndex].u.Hard.Write = 1;
963 MmArchReferencePage[PdeIndex]++;
964
965 /* Remove PTE_BASE from free virtual memory */
969 (4 * 1024 * 1024) >> PAGE_SHIFT,
970 0);
971 if (!NT_SUCCESS(Status))
972 {
973 goto Failure;
974 }
975
976 /* Remove HAL_HEAP from free virtual memory */
980 (4 * 1024 * 1024) >> PAGE_SHIFT,
981 0);
982 if (!NT_SUCCESS(Status))
983 {
984 goto Failure;
985 }
986
987 /* Initialize the virtual->physical memory mappings */
988 Status = Mmx86InitializeMemoryMap(1, MemoryData);
989 if (!NT_SUCCESS(Status))
990 {
991 goto Failure;
992 }
993
994 /* Turn on paging with the new CR3 */
997 EfiPrintf(L"Paging... %d\r\n", BlMmIsTranslationEnabled());
998
999 /* Return success */
1000 return Status;
1001
1002Failure:
1003 /* Free reference page if we allocated it */
1005 {
1008 }
1009
1010 /* Free page directory if we allocated it */
1011 if (MmPdpt)
1012 {
1015 }
1016
1017 /* Free the self map if we allocated it */
1019 {
1021 }
1022
1023 /* All done */
1024 return Status;
1025}
1026
1029 _In_ ULONG Phase,
1030 _In_ PBL_MEMORY_DATA MemoryData,
1031 _In_ BL_TRANSLATION_TYPE TranslationType,
1032 _In_ BL_TRANSLATION_TYPE RequestedTranslationType
1033 )
1034{
1036 ULONGLONG IncreaseUserVa, PerfCounter, CpuRandom;
1037 CPU_INFO CpuInfo;
1038
1039 /* For phase 2, just map deferred regions */
1040 if (Phase != 1)
1041 {
1042 return Mmx86pMapMemoryRegions(2, MemoryData);
1043 }
1044
1045 /* What translation type are we switching to? */
1046 switch (RequestedTranslationType)
1047 {
1048 /* Physical memory */
1049 case BlNone:
1050
1051 /* Initialize everything to default/null values */
1053 MmArchKsegBase = 0;
1054 MmArchKsegBias = 0;
1059
1060 /* Set stub functions */
1063
1064 /* Set success */
1066 break;
1067
1068 case BlVirtual:
1069
1070 /* Set the large page size to 1024 pages (4MB) */
1071 MmArchLargePageSize = (4 * 1024 * 1024) / PAGE_SIZE;
1072
1073 /* Check if /USERVA option was used */
1076 &IncreaseUserVa);
1077 if (NT_SUCCESS(Status) && (IncreaseUserVa))
1078 {
1079 /* Yes -- load the kernel at 0xE0000000 instead */
1080 MmArchKsegBase = 0xE0000000;
1081 }
1082 else
1083 {
1084 /* Nope, load at the standard 2GB split */
1085 MmArchKsegBase = 0x80000000;
1086 }
1087
1088 /* Check if CPUID 01h is supported */
1089 CpuRandom = 0;
1091 {
1092 /* Call it */
1093 BlArchCpuId(1, 0, &CpuInfo);
1094
1095 /* Check if RDRAND is supported */
1096 if (CpuInfo.Ecx & 0x40000000)
1097 {
1098 EfiPrintf(L"Your CPU can do RDRAND! Good for you!\r\n");
1099 CpuRandom = 0;
1100 }
1101 }
1102
1103 /* Read the TSC */
1104 PerfCounter = BlArchGetPerformanceCounter();
1105 PerfCounter >>= 4;
1106 _rotl16(PerfCounter, 5);
1107
1108 /* Set the address range */
1111
1112 /* Set the KASLR bias */
1113 MmArchKsegBias = ((PerfCounter ^ CpuRandom) & 0xFFF) << 12;
1114 MmArchKsegBias = 0;
1116
1117 /* Set the kernel range */
1120
1121 /* Set the boot application top maximum */
1122 MmArchTopOfApplicationAddressSpace = 0x70000000 - 1; // Windows bug
1123
1124 /* Initialize virtual address space translation */
1125 Status = MmDefInitializeTranslation(MemoryData, TranslationType);
1126 if (NT_SUCCESS(Status))
1127 {
1128 /* Set stub functions */
1133 }
1134 break;
1135
1136 case BlPae:
1137
1138 /* We don't support PAE */
1140 break;
1141
1142 default:
1143
1144 /* Invalid architecture type*/
1146 break;
1147 }
1148
1149 /* Back to caller */
1150 return Status;
1151}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
@ BcdOSLoaderInteger_IncreaseUserVa
Definition: bcd.h:125
NTSTATUS MmMdFreeDescriptor(_In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor)
Definition: descriptor.c:157
NTSTATUS MmPapAllocatePhysicalPagesInRange(_Inout_ PPHYSICAL_ADDRESS BaseAddress, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG Pages, _In_ ULONG Attributes, _In_ ULONG Alignment, _In_ PBL_MEMORY_DESCRIPTOR_LIST NewList, _In_opt_ PBL_ADDRESS_RANGE Range, _In_ ULONG RangeType)
Definition: pagealloc.c:438
VOID BlpArchEnableTranslation(VOID)
Definition: arch.c:189
@ BlLoaderMemory
Definition: bl.h:306
@ BlEfiRuntimeDataMemory
Definition: bl.h:338
@ BlEfiBootMemory
Definition: bl.h:330
@ BlEfiRuntimeCodeMemory
Definition: bl.h:332
@ BlLoaderReferencePage
Definition: bl.h:310
@ BlLoaderPageDirectory
Definition: bl.h:309
@ BlLoaderRamDisk
Definition: bl.h:311
@ BlApplicationData
Definition: bl.h:322
VOID BlArchCpuId(_In_ ULONG Function, _In_ ULONG SubFunction, _Out_ PCPU_INFO Result)
Definition: util.c:924
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
FORCEINLINE VOID MmMdInitializeListHead(_In_ PBL_MEMORY_DESCRIPTOR_LIST List)
Definition: bl.h:1376
NTSTATUS MmPaReserveSelfMapPages(_Inout_ PPHYSICAL_ADDRESS PhysicalAddress, _In_ ULONG Alignment, _In_ ULONG PageCount)
Definition: pagealloc.c:1564
#define BL_MM_FLAG_REQUEST_COALESCING
Definition: bl.h:87
#define BL_MM_INCLUDE_TRUNCATED_MEMORY
Definition: bl.h:103
BOOLEAN(* PBL_MM_TRANSLATE_VIRTUAL_ADDRESS)(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CacheAttributes)
Definition: bl.h:738
@ BlVirtual
Definition: bl.h:231
@ BlPae
Definition: bl.h:232
@ BlNone
Definition: bl.h:230
VOID(* PBL_MM_RELOCATE_SELF_MAP)(VOID)
Definition: bl.h:683
struct _BL_MEMORY_DESCRIPTOR * PBL_MEMORY_DESCRIPTOR
BL_TRANSLATION_TYPE MmTranslationType
Definition: mm.c:17
VOID MmMdRemoveDescriptorFromList(_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, _In_ PBL_MEMORY_DESCRIPTOR Entry)
Definition: descriptor.c:338
BOOLEAN BlArchIsCpuIdFunctionSupported(_In_ ULONG Function)
Definition: util.c:856
NTSTATUS BlMmFreePhysicalPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1187
BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated
Definition: pagealloc.c:38
NTSTATUS MmPaReleaseSelfMapPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1505
NTSTATUS(* PBL_MM_REMAP_VIRTUAL_ADDRESS)(_In_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: bl.h:722
NTSTATUS MmPaTruncateMemory(_In_ ULONGLONG BasePage)
Definition: pagealloc.c:51
NTSTATUS(* PBL_MM_UNMAP_VIRTUAL_ADDRESS)(_In_ PVOID VirtualAddress, _In_ ULONG Size)
Definition: bl.h:716
#define BL_MM_REMOVE_PHYSICAL_REGION_FLAG
Definition: bl.h:124
enum _BL_TRANSLATION_TYPE BL_TRANSLATION_TYPE
NTSTATUS(* PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE)(_In_ PVOID DestinationAddress, _In_ PVOID SourceAddress, _In_ ULONGLONG Size)
Definition: bl.h:688
NTSTATUS EfiStall(_In_ ULONG StallTime)
Definition: firmware.c:1003
PBL_ARCH_CONTEXT CurrentExecutionContext
Definition: arch.c:17
ULONGLONG BlArchGetPerformanceCounter(VOID)
Definition: util.c:902
BL_MEMORY_DESCRIPTOR_LIST MmMdlFreeVirtual
Definition: pagealloc.c:45
VOID(* PBL_MM_DESTROY_SELF_MAP)(VOID)
Definition: bl.h:701
NTSTATUS MmMdRemoveRegionFromMdlEx(__in PBL_MEMORY_DESCRIPTOR_LIST MdList, __in ULONG Flags, __in ULONGLONG BasePage, __in ULONGLONG PageCount, __in PBL_MEMORY_DESCRIPTOR_LIST NewMdList)
NTSTATUS MmUnmapVirtualAddress(_Inout_ PVOID *VirtualAddress, _Inout_ PULONGLONG Size)
Definition: mm.c:453
@ BlMemoryWriteThrough
Definition: bl.h:348
@ BlMemoryUncached
Definition: bl.h:346
@ BlMemoryWriteBack
Definition: bl.h:349
NTSTATUS BlGetApplicationBaseAndSize(_Out_ PVOID *ImageBase, _Out_ PULONG ImageSize)
Definition: bootlib.c:424
NTSTATUS(* PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE)(_In_ PVOID DestinationAddress, _In_ ULONGLONG Size)
Definition: bl.h:695
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
#define BL_MM_INCLUDE_NO_FIRMWARE_MEMORY
Definition: bl.h:107
#define BL_CONTEXT_PAGING_ON
Definition: bl.h:83
@ BlRealMode
Definition: bl.h:239
NTSTATUS MmFwGetMemoryMap(_Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap, _In_ ULONG Flags)
Definition: firmware.c:1845
NTSTATUS BlGetBootOptionInteger(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PULONGLONG Value)
Definition: bcdopt.c:467
VOID(* PBL_MM_FLUSH_TLB_ENTRY)(_In_ PVOID VirtualAddress)
Definition: bl.h:706
VOID(* PBL_MM_FLUSH_TLB)(VOID)
Definition: bl.h:678
NTSTATUS(* PBL_MM_MAP_PHYSICAL_ADDRESS)(_In_ PHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: bl.h:730
PBL_MEMORY_DESCRIPTOR MmMdFindDescriptor(_In_ ULONG WhichList, _In_ ULONG Flags, _In_ ULONGLONG Page)
Definition: descriptor.c:1049
#define BL_MM_REMOVE_VIRTUAL_REGION_FLAG
Definition: bl.h:125
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ unsigned short __cdecl _rotl16(_In_ unsigned short _Value, _In_ unsigned char _Shift)
__INTRIN_INLINE void _sgdt(void *Destination)
Definition: intrin_x86.h:2028
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1818
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1968
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1794
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
NTSTATUS MmDefZeroVirtualAddressRange(_In_ PVOID DestinationAddress, _In_ ULONGLONG Size)
Definition: mmx86.c:98
VOID MmDefpFlushTlbEntry(_In_ PVOID VirtualAddress)
Definition: mmx86.c:158
PVOID MmPdeBase
Definition: mmx86.c:36
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG_PTR MmArchKsegBias
Definition: mmx86.c:27
ULONG_PTR MmArchTopOfApplicationAddressSpace
Definition: mmx86.c:30
#define MiAddressToPteOffset(x)
Definition: mmx86.c:21
VOID MmArchNullFunction(VOID)
Definition: mmx86.c:67
NTSTATUS MmMapPhysicalAddress(_Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr, _Inout_ PVOID *VirtualAddressPtr, _Inout_ PULONGLONG SizePtr, _In_ ULONG CacheAttributes)
Definition: mmx86.c:428
VOID MmDefpDestroySelfMap(VOID)
Definition: mmx86.c:150
VOID MmMdDbgDumpList(_In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList, _In_opt_ ULONG MaxCount)
Definition: mmx86.c:579
VOID MmDefRelocateSelfMap(VOID)
Definition: mmx86.c:76
PBL_MM_MAP_PHYSICAL_ADDRESS Mmx86MapPhysicalAddress
Definition: mmx86.c:40
VOID MmDefpFlushTlb(VOID)
Definition: mmx86.c:167
PULONG MmArchReferencePage
Definition: mmx86.c:34
PBL_MM_RELOCATE_SELF_MAP BlMmRelocateSelfMap
Definition: mmx86.c:47
PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE BlMmMoveVirtualAddressRange
Definition: mmx86.c:49
NTSTATUS Mmx86pMapMemoryRegions(_In_ ULONG Phase, _In_ PBL_MEMORY_DATA MemoryData)
Definition: mmx86.c:631
BL_ADDRESS_RANGE MmArchKsegAddressRange
Definition: mmx86.c:29
BOOLEAN MmArchTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_opt_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CachingFlags)
Definition: mmx86.c:108
NTSTATUS Mmx86MapInitStructure(_In_ PVOID VirtualAddress, _In_ ULONGLONG Size, _In_ PHYSICAL_ADDRESS PhysicalAddress)
Definition: mmx86.c:541
ULONG MmDeferredMappingCount
Definition: mmx86.c:32
NTSTATUS MmDefpUnmapVirtualAddress(_In_ PVOID VirtualAddress, _In_ ULONG Size)
Definition: mmx86.c:176
PBL_MM_FLUSH_TLB BlMmFlushTlb
Definition: mmx86.c:48
PMMPTE MmPdpt
Definition: mmx86.c:33
PBL_MM_REMAP_VIRTUAL_ADDRESS Mmx86RemapVirtualAddress
Definition: mmx86.c:41
NTSTATUS MmDefMoveVirtualAddressRange(_In_ PVOID DestinationAddress, _In_ PVOID SourceAddress, _In_ ULONGLONG Size)
Definition: mmx86.c:87
NTSTATUS MmDefInitializeTranslation(_In_ PBL_MEMORY_DATA MemoryData, _In_ BL_TRANSLATION_TYPE TranslationType)
Definition: mmx86.c:857
NTSTATUS MmArchInitialize(_In_ ULONG Phase, _In_ PBL_MEMORY_DATA MemoryData, _In_ BL_TRANSLATION_TYPE TranslationType, _In_ BL_TRANSLATION_TYPE RequestedTranslationType)
Definition: mmx86.c:1028
#define PTE_BASE
Definition: mmx86.c:14
NTSTATUS MmDefpRemapVirtualAddress(_In_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:186
#define MiAddressToPdeOffset(x)
Definition: mmx86.c:22
PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE BlMmZeroVirtualAddressRange
Definition: mmx86.c:50
#define MiAddressToPde(x)
Definition: mmx86.c:20
NTSTATUS MmDefpMapPhysicalAddress(_In_ PHYSICAL_ADDRESS PhysicalAddress, _In_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:198
PBL_MM_UNMAP_VIRTUAL_ADDRESS Mmx86UnmapVirtualAddress
Definition: mmx86.c:42
ULONG_PTR MmArchKsegBase
Definition: mmx86.c:26
PVOID MmPteBase
Definition: mmx86.c:35
ULONG MmArchLargePageSize
Definition: mmx86.c:28
NTSTATUS Mmx86InitializeMemoryMap(_In_ ULONG Phase, _In_ PBL_MEMORY_DATA MemoryData)
Definition: mmx86.c:784
PBL_MM_FLUSH_TLB_ENTRY Mmx86FlushTlbEntry
Definition: mmx86.c:44
PBL_MM_FLUSH_TLB Mmx86FlushTlb
Definition: mmx86.c:43
PBL_MM_DESTROY_SELF_MAP Mmx86DestroySelfMap
Definition: mmx86.c:45
PBL_MM_TRANSLATE_VIRTUAL_ADDRESS Mmx86TranslateVirtualAddress
Definition: mmx86.c:39
PHYSICAL_ADDRESS Mmx86SelfMapBase
Definition: mmx86.c:31
BOOLEAN BlMmIsTranslationEnabled(VOID)
Definition: mmx86.c:57
ULONG MmArchReferencePageSize
Definition: mmx86.c:37
BOOLEAN MmDefpTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CacheAttributes)
Definition: mmx86.c:350
@ Enabled
Definition: mountmgr.h:159
#define _Out_opt_
Definition: ms_sal.h:346
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
#define MM_HAL_VA_START
Definition: ketypes.h:322
struct _MMPTE * PMMPTE
struct _MMPTE * PMMPDE
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONGLONG Maximum
Definition: bl.h:1015
ULONGLONG Minimum
Definition: bl.h:1014
BL_ARCH_MODE Mode
Definition: bl.h:999
ULONG ContextFlags
Definition: bl.h:1001
PBL_BCD_OPTION BcdData
Definition: bl.h:867
PLIST_ENTRY First
Definition: bl.h:1007
PVOID Base
Definition: ketypes.h:556
USHORT Limit
Definition: ketypes.h:555
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG64 CacheDisable
Definition: mmtypes.h:162
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 WriteThrough
Definition: mmtypes.h:161
ULONG64 Write
Definition: mmtypes.h:170
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2330 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG Ecx
Definition: ketypes.h:368
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ PWDF_MEMORY_DESCRIPTOR MemoryDescriptor
Definition: wdfusb.h:1339
int WINAPI EndPage(_In_ HDC)
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2275
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Out_ PPHYSICAL_ADDRESS DestinationAddress
Definition: iotypes.h:1128
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1127
#define ROUND_TO_PAGES(Size)
#define BYTE_OFFSET(Va)