ReactOS  0.4.10-dev-19-g39281f0
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 
56 BOOLEAN
58  VOID
59  )
60 {
61  /* Return if paging is on */
62  return ((CurrentExecutionContext) &&
64 }
65 
66 VOID
68  VOID
69  )
70 {
71  /* Nothing to do */
72  return;
73 }
74 
75 VOID
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");
104  return STATUS_NOT_IMPLEMENTED;
105 }
106 
107 BOOLEAN
111  _Out_opt_ PULONG CachingFlags
112  )
113 {
115 
116  /* Check if paging is on */
117  if ((CurrentExecutionContext) &&
119  {
120  /* Yes -- we have to translate this from virtual */
121  return Mmx86TranslateVirtualAddress(VirtualAddress,
122  PhysicalAddress,
123  CachingFlags);
124  }
125 
126  /* Look in all descriptors except truncated and firmware ones */
130  (ULONG_PTR)VirtualAddress >> PAGE_SHIFT);
131 
132  /* Return the virtual address as the physical address */
133  if (PhysicalAddress)
134  {
135  PhysicalAddress->HighPart = 0;
136  PhysicalAddress->LowPart = (ULONG_PTR)VirtualAddress;
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 
149 VOID
151  VOID
152  )
153 {
154  EfiPrintf(L"No destroy\r\n");
155 }
156 
157 VOID
160  )
161 {
162  /* Flush the TLB */
163  __invlpg(VirtualAddress);
164 }
165 
166 VOID
168  VOID
169  )
170 {
171  /* Flush the TLB */
173 }
174 
175 NTSTATUS
178  _In_ ULONG Size
179  )
180 {
181  EfiPrintf(L"No unmap\r\n");
182  return STATUS_NOT_IMPLEMENTED;
183 }
184 
185 NTSTATUS
189  _In_ ULONG Size,
190  _In_ ULONG CacheAttributes
191  )
192 {
193  EfiPrintf(L"No remap\r\n");
194  return STATUS_NOT_IMPLEMENTED;
195 }
196 
197 NTSTATUS
201  _In_ ULONG Size,
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 */
215  Enabled = BlMmIsTranslationEnabled();
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 */
225  if (Mmx86TranslateVirtualAddress(VirtualAddress, NULL, NULL))
226  {
227  /* Ignore it and move to the next one */
228  VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
229  CurrentAddress += PAGE_SIZE;
230  continue;
231  }
232 
233  /* Get the PDE offset */
234  PdeOffset = MiAddressToPdeOffset(VirtualAddress);
235 
236  /* Check if paging is actually turned on */
237  if (Enabled)
238  {
239  /* Get the PDE entry using the self-map */
240  Pde = MiAddressToPde(VirtualAddress);
241  }
242  else
243  {
244  /* Get it using our physical mappings */
245  Pde = &MmPdpt[PdeOffset];
246  PageTable = (PMMPDE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT);
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 */
282  PageTable = (PVOID)PAGE_ROUND_DOWN(MiAddressToPte(VirtualAddress));
283 
284  /* Flush the TLB */
285  Mmx86FlushTlb();
286  }
287 
288  /* Zero out the page table */
289  RtlZeroMemory(PageTable, PAGE_SIZE);
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 */
299  Mmx86FlushTlbEntry(PageTable);
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 */
313  Pte = MiAddressToPte(VirtualAddress);
314  }
315  else
316  {
317  /* Get the PTE using physical addressing */
318  Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)];
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 */
341  VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
342  CurrentAddress += PAGE_SIZE;
343  }
344 
345  /* All done! */
346  return STATUS_SUCCESS;
347 }
348 
349 BOOLEAN
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? */
368  Enabled = BlMmIsTranslationEnabled();
369 
370  /* Check if paging is actually turned on */
371  if (Enabled)
372  {
373  /* Get the PDE entry using the self-map */
374  Pde = MiAddressToPde(VirtualAddress);
375  }
376  else
377  {
378  /* Get it using our physical mappings */
379  Pde = &MmPdpt[MiAddressToPdeOffset(VirtualAddress)];
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 */
392  Pte = MiAddressToPte(VirtualAddress);
393  }
394  else
395  {
396  /* Get the PTE using physical addressing */
397  PageTable = (PMMPTE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT);
398  Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)];
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 */
411  PhysicalAddress->QuadPart = (Pte->u.Hard.PageFrameNumber << PAGE_SHIFT) +
412  BYTE_OFFSET(VirtualAddress);
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 
427 NTSTATUS
429  _Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr,
430  _Inout_ PVOID* VirtualAddressPtr,
431  _Inout_ PULONGLONG SizePtr,
432  _In_ ULONG CacheAttributes
433  )
434 {
435  ULONGLONG Size;
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 */
456  if (MmTranslationType == BlNone)
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 */
475  PhysicalAddress = PAGE_ROUND_DOWN(PhysicalAddress);
476  VirtualAddress = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
477 
478  /* Round up the size */
479  Size = ROUND_TO_PAGES(PhysicalAddressPtr->QuadPart -
480  PhysicalAddress +
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,
490  &TranslatedAddress,
491  &CacheAttributes))
492  {
493  /* Make sure the physical page of the virtual page, matches our page */
494  if (TranslatedAddress.QuadPart !=
495  (PhysicalAddress +
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",
500  TranslatedAddress.QuadPart,
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 */
513  TranslatedAddress.QuadPart = PhysicalAddress;
514  Status = Mmx86MapPhysicalAddress(TranslatedAddress,
515  VirtualAddress,
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  {
533  Mmx86FlushTlb();
534  }
535 
536  /* All good! */
537  return STATUS_SUCCESS;
538 }
539 
540 NTSTATUS
545  )
546 {
548 
549  /* Make a virtual mapping for this physical address */
550  Status = MmMapPhysicalAddress(&PhysicalAddress, &VirtualAddress, &Size, 0);
551  if (!NT_SUCCESS(Status))
552  {
553  return Status;
554  }
555 
556  /* Nothing else to do if we're not in paging mode */
557  if (MmTranslationType == BlNone)
558  {
559  return STATUS_SUCCESS;
560  }
561 
562  /* Otherwise, remove this region from the list of free virtual ranges */
565  (ULONG_PTR)VirtualAddress >> PAGE_SHIFT,
566  Size >> PAGE_SHIFT,
567  0);
568  if (!NT_SUCCESS(Status))
569  {
570  /* Unmap the address if that failed */
571  MmUnmapVirtualAddress(&VirtualAddress, &Size);
572  }
573 
574  /* Return back to caller */
575  return Status;
576 }
577 
578 VOID
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 */
599  MemoryDescriptor = CONTAINING_RECORD(NextEntry,
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",
618  MemoryDescriptor,
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 
630 NTSTATUS
632  _In_ ULONG Phase,
633  _In_ PBL_MEMORY_DATA MemoryData
634  )
635 {
636  BOOLEAN DoDeferred;
637  ULONG DescriptorCount;
639  ULONG FinalOffset;
641  ULONGLONG Size;
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 */
687  PhysicalAddress.QuadPart = Descriptor->BasePage << PAGE_SHIFT;
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 */
699  VirtualAddress = (PVOID)(ULONG_PTR)PhysicalAddress.QuadPart;
700  }
701 
702  /* Crete the mapping */
703  Status = Mmx86MapInitStructure(VirtualAddress,
704  Size,
705  PhysicalAddress);
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);
729  Status = MmFwGetMemoryMap(&FirmwareMdl, BL_MM_FLAG_REQUEST_COALESCING);
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) ||
743  (Descriptor->Type == BlEfiRuntimeCodeMemory) ||
744  (Descriptor->Type == BlEfiRuntimeDataMemory) || // WINBUG?
745  (Descriptor->Type == BlLoaderMemory)) &&
746  ((Descriptor->BasePage << PAGE_SHIFT) != Mmx86SelfMapBase.QuadPart))
747  {
748  /* Identity-map it */
749  PhysicalAddress.QuadPart = Descriptor->BasePage << PAGE_SHIFT;
750  Status = Mmx86MapInitStructure((PVOID)((ULONG_PTR)Descriptor->BasePage << PAGE_SHIFT),
751  Descriptor->PageCount << PAGE_SHIFT,
752  PhysicalAddress);
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 */
774  MmMdRemoveDescriptorFromList(&FirmwareMdl, Descriptor);
775  MmMdFreeDescriptor(Descriptor);
776  }
777  }
778 
779  /* All library mappings identity mapped now */
780  return STATUS_SUCCESS;
781 }
782 
783 NTSTATUS
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 */
809  PhysicalAddress.QuadPart = (ULONG_PTR)ImageBase;
810  Status = Mmx86MapInitStructure(ImageBase, ImageSize, PhysicalAddress);
811  if (!NT_SUCCESS(Status))
812  {
813  return Status;
814  }
815 
816  /* Map the first 4MB of memory */
817  PhysicalAddress.QuadPart = 0;
818  Status = Mmx86MapInitStructure(NULL, 4 * 1024 * 1024, PhysicalAddress);
819  if (!NT_SUCCESS(Status))
820  {
821  return Status;
822  }
823 
824  /* Map the GDT */
825  _sgdt(&Gdt.Limit);
826  PhysicalAddress.QuadPart = Gdt.Base;
827  Status = Mmx86MapInitStructure((PVOID)Gdt.Base, Gdt.Limit + 1, PhysicalAddress);
828  if (!NT_SUCCESS(Status))
829  {
830  return Status;
831  }
832 
833  /* Map the IDT */
834  __sidt(&Idt.Limit);
835  PhysicalAddress.QuadPart = Idt.Base;
836  Status = Mmx86MapInitStructure((PVOID)Idt.Base, Idt.Limit + 1, PhysicalAddress);
837  if (!NT_SUCCESS(Status))
838  {
839  return Status;
840  }
841 
842  /* Map the reference page */
843  PhysicalAddress.QuadPart = (ULONG_PTR)MmArchReferencePage;
846  PhysicalAddress);
847  if (!NT_SUCCESS(Status))
848  {
849  return Status;
850  }
851 
852  /* More to do */
853  return Mmx86pMapMemoryRegions(Phase, MemoryData);
854 }
855 
856 NTSTATUS
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");
879  return STATUS_NOT_IMPLEMENTED;
880  }
881  else if (TranslationType != BlNone)
882  {
883  /* Not even Windows supports PAE->Virtual downgrade */
884  return STATUS_NOT_IMPLEMENTED;
885  }
886 
887  /* The None->Virtual case */
888  MmPdpt = NULL;
889  Mmx86SelfMapBase.QuadPart = 0;
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 */
900  Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
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 */
914  MmPdpt = (PVOID)PhysicalAddress.LowPart;
915  RtlZeroMemory(MmPdpt, PAGE_SIZE);
916 
917  /* Set the page size */
919 
920  /* Allocate the self-map page */
921  Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
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 */
935  MmArchReferencePage = (PVOID)PhysicalAddress.LowPart;
936 
937  /* Zero it out */
939 
940  /* Allocate 4MB worth of self-map pages */
941  Status = MmPaReserveSelfMapPages(&Mmx86SelfMapBase,
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",
952  MmPdpt, MmArchReferencePage, Mmx86SelfMapBase.LowPart);
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 */
959  PdeIndex = MiAddressToPdeOffset(MmPdeBase);
960  MmPdpt[PdeIndex].u.Hard.Valid = 1;
961  MmPdpt[PdeIndex].u.Hard.Write = 1;
962  MmPdpt[PdeIndex].u.Hard.PageFrameNumber = (ULONG_PTR)MmPdpt >> PAGE_SHIFT;
963  MmArchReferencePage[PdeIndex]++;
964 
965  /* Remove PTE_BASE from free virtual memory */
968  PTE_BASE >> PAGE_SHIFT,
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 */
995  __writecr3((ULONG_PTR)MmPdpt);
997  EfiPrintf(L"Paging... %d\r\n", BlMmIsTranslationEnabled());
998 
999  /* Return success */
1000  return Status;
1001 
1002 Failure:
1003  /* Free reference page if we allocated it */
1004  if (MmArchReferencePage)
1005  {
1006  PhysicalAddress.QuadPart = (ULONG_PTR)MmArchReferencePage;
1007  BlMmFreePhysicalPages(PhysicalAddress);
1008  }
1009 
1010  /* Free page directory if we allocated it */
1011  if (MmPdpt)
1012  {
1013  PhysicalAddress.QuadPart = (ULONG_PTR)MmPdpt;
1014  BlMmFreePhysicalPages(PhysicalAddress);
1015  }
1016 
1017  /* Free the self map if we allocated it */
1018  if (Mmx86SelfMapBase.QuadPart)
1019  {
1020  MmPaReleaseSelfMapPages(Mmx86SelfMapBase);
1021  }
1022 
1023  /* All done */
1024  return Status;
1025 }
1026 
1027 NTSTATUS
1029  _In_ ULONG Phase,
1030  _In_ PBL_MEMORY_DATA MemoryData,
1031  _In_ BL_TRANSLATION_TYPE TranslationType,
1032  _In_ BL_TRANSLATION_TYPE RequestedTranslationType
1033  )
1034 {
1035  NTSTATUS Status;
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 */
1052  MmArchLargePageSize = 1;
1053  MmArchKsegBase = 0;
1054  MmArchKsegBias = 0;
1055  MmArchKsegAddressRange.Minimum = 0;
1056  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
1058  Mmx86SelfMapBase.QuadPart = 0;
1059 
1060  /* Set stub functions */
1063 
1064  /* Set success */
1065  Status = STATUS_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 */
1109  MmArchKsegAddressRange.Minimum = 0;
1110  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
1111 
1112  /* Set the KASLR bias */
1113  MmArchKsegBias = ((PerfCounter ^ CpuRandom) & 0xFFF) << 12;
1114  MmArchKsegBias = 0;
1116 
1117  /* Set the kernel range */
1118  MmArchKsegAddressRange.Minimum = MmArchKsegBase;
1119  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
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 */
1139  Status = STATUS_NOT_SUPPORTED;
1140  break;
1141 
1142  default:
1143 
1144  /* Invalid architecture type*/
1145  Status = STATUS_INVALID_PARAMETER;
1146  break;
1147  }
1148 
1149  /* Back to caller */
1150  return Status;
1151 }
DWORD *typedef PVOID
Definition: winlogon.h:52
NTSTATUS MmDefZeroVirtualAddressRange(_In_ PVOID DestinationAddress, _In_ ULONGLONG Size)
Definition: mmx86.c:98
NTSTATUS BlGetApplicationBaseAndSize(_Out_ PVOID *ImageBase, _Out_ PULONG ImageSize)
Definition: bootlib.c:424
ULONG64 Write
Definition: mmtypes.h:170
NTSTATUS MmDefpRemapVirtualAddress(_In_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:186
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
VOID BlpArchEnableTranslation(VOID)
Definition: arch.c:189
#define MM_HAL_VA_START
Definition: ketypes.h:256
#define TRUE
Definition: types.h:120
ULONG MmArchReferencePageSize
Definition: mmx86.c:37
NTSTATUS MmMapPhysicalAddress(_Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr, _Inout_ PVOID *VirtualAddressPtr, _Inout_ PULONGLONG SizePtr, _In_ ULONG CacheAttributes)
Definition: mmx86.c:428
_Out_ PNDIS_BUFFER _In_ NDIS_HANDLE _In_ PVOID MemoryDescriptor
Definition: ndis.h:3252
PVOID MmPdeBase
Definition: mmx86.c:36
#define MiAddressToPde(x)
Definition: mmx86.c:20
NTSTATUS EfiStall(_In_ ULONG StallTime)
Definition: firmware.c:1003
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
Definition: bidi.c:85
FORCEINLINE VOID MmMdInitializeListHead(_In_ PBL_MEMORY_DESCRIPTOR_LIST List)
Definition: bl.h:1377
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:40
PBL_MM_TRANSLATE_VIRTUAL_ADDRESS Mmx86TranslateVirtualAddress
Definition: mmx86.c:39
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
return STATUS_SUCCESS
Definition: btrfs.c:2690
PVOID MmPteBase
Definition: mmx86.c:35
VOID(* PBL_MM_RELOCATE_SELF_MAP)(VOID)
Definition: bl.h:684
NTSTATUS MmDefMoveVirtualAddressRange(_In_ PVOID DestinationAddress, _In_ PVOID SourceAddress, _In_ ULONGLONG Size)
Definition: mmx86.c:87
NTSTATUS MmUnmapVirtualAddress(_Inout_ PVOID *VirtualAddress, _Inout_ PULONGLONG Size)
Definition: mm.c:453
VOID(* PBL_MM_FLUSH_TLB)(VOID)
Definition: bl.h:679
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#define BL_CONTEXT_PAGING_ON
Definition: bl.h:84
PBL_MM_REMAP_VIRTUAL_ADDRESS Mmx86RemapVirtualAddress
Definition: mmx86.c:41
PBL_MM_UNMAP_VIRTUAL_ADDRESS Mmx86UnmapVirtualAddress
Definition: mmx86.c:42
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1711
#define BL_MM_REMOVE_PHYSICAL_REGION_FLAG
Definition: bl.h:125
NTSTATUS BlMmFreePhysicalPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1187
ULONG MmDeferredMappingCount
Definition: mmx86.c:32
#define BL_MM_REMOVE_VIRTUAL_REGION_FLAG
Definition: bl.h:126
NTSTATUS Mmx86pMapMemoryRegions(_In_ ULONG Phase, _In_ PBL_MEMORY_DATA MemoryData)
Definition: mmx86.c:631
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2268
PBL_MM_FLUSH_TLB_ENTRY Mmx86FlushTlbEntry
Definition: mmx86.c:44
ULONG_PTR MmArchKsegBias
Definition: mmx86.c:27
union _MMPTE::@2171 u
PVOID Base
Definition: ketypes.h:486
int WINAPI EndPage(_In_ HDC)
enum _BL_TRANSLATION_TYPE BL_TRANSLATION_TYPE
#define _In_opt_
Definition: no_sal2.h:213
NTSTATUS MmMdRemoveRegionFromMdlEx(__in PBL_MEMORY_DESCRIPTOR_LIST MdList, __in ULONG Flags, __in ULONGLONG BasePage, __in ULONGLONG PageCount, __in PBL_MEMORY_DESCRIPTOR_LIST NewMdList)
ULONG_PTR MmArchTopOfApplicationAddressSpace
Definition: mmx86.c:30
NTSTATUS BlGetBootOptionInteger(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PULONGLONG Value)
Definition: bcdopt.c:467
PLIST_ENTRY First
Definition: bl.h:1008
USHORT Limit
Definition: ketypes.h:485
ULONG ContextFlags
Definition: bl.h:1002
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:63
Definition: bl.h:232
PBL_MM_MAP_PHYSICAL_ADDRESS Mmx86MapPhysicalAddress
Definition: mmx86.c:40
VOID MmArchNullFunction(VOID)
Definition: mmx86.c:67
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1680
GLenum GLclampf GLint i
Definition: glfuncs.h:14
BL_MEMORY_TYPE Type
Definition: bl.h:842
#define MiAddressToPte(x)
Definition: mmx86.c:19
VOID MmMdRemoveDescriptorFromList(_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, _In_ PBL_MEMORY_DESCRIPTOR Entry)
Definition: descriptor.c:338
#define FALSE
Definition: types.h:117
PHYSICAL_ADDRESS Mmx86SelfMapBase
Definition: mmx86.c:31
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:1925
struct _BL_MEMORY_DESCRIPTOR * PBL_MEMORY_DESCRIPTOR
PBL_BCD_OPTION BcdData
Definition: bl.h:868
PBL_MM_FLUSH_TLB Mmx86FlushTlb
Definition: mmx86.c:43
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(* PBL_MM_FLUSH_TLB_ENTRY)(_In_ PVOID VirtualAddress)
Definition: bl.h:707
ULONG64 WriteThrough
Definition: mmtypes.h:161
BL_TRANSLATION_TYPE MmTranslationType
Definition: mm.c:17
VOID MmMdDbgDumpList(_In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList, _In_opt_ ULONG MaxCount)
Definition: mmx86.c:579
smooth NULL
Definition: ftsmooth.c:416
struct _MMPTE * PMMPDE
Definition: bl.h:240
#define _Out_
Definition: no_sal2.h:323
ULONGLONG PageCount
Definition: bl.h:840
PBL_ARCH_CONTEXT CurrentExecutionContext
Definition: arch.c:17
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOLEAN BlArchIsCpuIdFunctionSupported(_In_ ULONG Function)
Definition: util.c:856
NTSTATUS MmDefpMapPhysicalAddress(_In_ PHYSICAL_ADDRESS PhysicalAddress, _In_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:198
UINTN Size
Definition: acefiex.h:555
ULONG_PTR MmArchKsegBase
Definition: mmx86.c:26
#define BL_MM_INCLUDE_NO_FIRMWARE_MEMORY
Definition: bl.h:108
#define _Out_opt_
Definition: no_sal2.h:339
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
NTSTATUS MmMdFreeDescriptor(_In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor)
Definition: descriptor.c:157
unsigned char BOOLEAN
NTSTATUS MmArchInitialize(_In_ ULONG Phase, _In_ PBL_MEMORY_DATA MemoryData, _In_ BL_TRANSLATION_TYPE TranslationType, _In_ BL_TRANSLATION_TYPE RequestedTranslationType)
Definition: mmx86.c:1028
ULONGLONG Maximum
Definition: bl.h:1016
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS MmFwGetMemoryMap(_Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap, _In_ ULONG Flags)
Definition: firmware.c:1845
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
Definition: bl.h:231
PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE BlMmMoveVirtualAddressRange
Definition: mmx86.c:49
uint64_t ULONGLONG
Definition: typedefs.h:65
ULONG64 Valid
Definition: mmtypes.h:150
struct _MMPTE * PMMPTE
ULONG Ecx
Definition: ketypes.h:298
VOID(* PBL_MM_DESTROY_SELF_MAP)(VOID)
Definition: bl.h:702
NTSTATUS MmPaReleaseSelfMapPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1505
VOID MmDefpFlushTlb(VOID)
Definition: mmx86.c:167
#define _Inout_
Definition: no_sal2.h:244
NTSTATUS MmPaReserveSelfMapPages(_Inout_ PPHYSICAL_ADDRESS PhysicalAddress, _In_ ULONG Alignment, _In_ ULONG PageCount)
Definition: pagealloc.c:1564
ULONG64 CacheDisable
Definition: mmtypes.h:162
NTSTATUS MmPaTruncateMemory(_In_ ULONGLONG BasePage)
Definition: pagealloc.c:51
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1060
#define BL_MM_INCLUDE_TRUNCATED_MEMORY
Definition: bl.h:104
#define BL_MM_FLAG_REQUEST_COALESCING
Definition: bl.h:88
PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE BlMmZeroVirtualAddressRange
Definition: mmx86.c:50
PBL_MM_FLUSH_TLB BlMmFlushTlb
Definition: mmx86.c:48
ULONG LowPart
Definition: typedefs.h:104
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PTE_BASE
Definition: mmx86.c:14
Definition: typedefs.h:117
ULONG MmArchLargePageSize
Definition: mmx86.c:28
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3773
NTSTATUS MmDefpUnmapVirtualAddress(_In_ PVOID VirtualAddress, _In_ ULONG Size)
Definition: mmx86.c:176
PULONG MmArchReferencePage
Definition: mmx86.c:34
VOID MmDefRelocateSelfMap(VOID)
Definition: mmx86.c:76
VOID MmDefpFlushTlbEntry(_In_ PVOID VirtualAddress)
Definition: mmx86.c:158
ULONGLONG Minimum
Definition: bl.h:1015
NTSTATUS(* PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE)(_In_ PVOID DestinationAddress, _In_ PVOID SourceAddress, _In_ ULONGLONG Size)
Definition: bl.h:689
__INTRIN_INLINE void _sgdt(void *Destination)
Definition: intrin_x86.h:1930
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
NTSTATUS(* PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE)(_In_ PVOID DestinationAddress, _In_ ULONGLONG Size)
Definition: bl.h:696
PBL_MEMORY_DESCRIPTOR MmMdFindDescriptor(_In_ ULONG WhichList, _In_ ULONG Flags, _In_ ULONGLONG Page)
Definition: descriptor.c:1049
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONGLONG BasePage
Definition: bl.h:831
BOOLEAN BlMmIsTranslationEnabled(VOID)
Definition: mmx86.c:57
BL_ADDRESS_RANGE MmArchKsegAddressRange
Definition: mmx86.c:29
#define ROUND_TO_PAGES(Size)
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
NTSTATUS(* PBL_MM_REMAP_VIRTUAL_ADDRESS)(_In_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: bl.h:723
unsigned int * PULONG
Definition: retypes.h:1
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
NTSTATUS(* PBL_MM_UNMAP_VIRTUAL_ADDRESS)(_In_ PVOID VirtualAddress, _In_ ULONG Size)
Definition: bl.h:717
ULONGLONG BlArchGetPerformanceCounter(VOID)
Definition: util.c:902
BOOLEAN MmDefpTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CacheAttributes)
Definition: mmx86.c:350
PMMPTE MmPdpt
Definition: mmx86.c:33
NTSTATUS MmDefInitializeTranslation(_In_ PBL_MEMORY_DATA MemoryData, _In_ BL_TRANSLATION_TYPE TranslationType)
Definition: mmx86.c:857
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1870
NTSTATUS(* PBL_MM_MAP_PHYSICAL_ADDRESS)(_In_ PHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: bl.h:731
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated
Definition: pagealloc.c:38
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
_Check_return_ unsigned short __cdecl _rotl16(_In_ unsigned short _Value, _In_ unsigned char _Shift)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
VOID BlArchCpuId(_In_ ULONG Function, _In_ ULONG SubFunction, _Out_ PCPU_INFO Result)
Definition: util.c:924
#define MiAddressToPdeOffset(x)
Definition: mmx86.c:22
#define MiAddressToPteOffset(x)
Definition: mmx86.c:21
BL_ARCH_MODE Mode
Definition: bl.h:1000
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Out_ PPHYSICAL_ADDRESS DestinationAddress
Definition: iotypes.h:1089
PBL_MM_DESTROY_SELF_MAP Mmx86DestroySelfMap
Definition: mmx86.c:45
NTSTATUS Mmx86MapInitStructure(_In_ PVOID VirtualAddress, _In_ ULONGLONG Size, _In_ PHYSICAL_ADDRESS PhysicalAddress)
Definition: mmx86.c:541
ULONGLONG VirtualPage
Definition: bl.h:832
PBL_MM_RELOCATE_SELF_MAP BlMmRelocateSelfMap
Definition: mmx86.c:47
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1089
VOID MmDefpDestroySelfMap(VOID)
Definition: mmx86.c:150
BL_MEMORY_DESCRIPTOR_LIST MmMdlFreeVirtual
Definition: pagealloc.c:45
BOOLEAN(* PBL_MM_TRANSLATE_VIRTUAL_ADDRESS)(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CacheAttributes)
Definition: bl.h:739
#define BYTE_OFFSET(Va)
Definition: bl.h:233
NTSTATUS Mmx86InitializeMemoryMap(_In_ ULONG Phase, _In_ PBL_MEMORY_DATA MemoryData)
Definition: mmx86.c:784
LONGLONG QuadPart
Definition: typedefs.h:112
BOOLEAN MmArchTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_opt_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CachingFlags)
Definition: mmx86.c:108
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966