ReactOS  r74006
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 
39 typedef VOID
41  VOID
42  );
43 
44 typedef VOID
46  VOID
47  );
48 
49 typedef NTSTATUS
54  );
55 
56 typedef NTSTATUS
60  );
61 
62 typedef VOID
64  VOID
65  );
66 
67 typedef VOID
70  );
71 
72 typedef VOID
74  VOID
75  );
76 
77 typedef NTSTATUS
81  );
82 
83 typedef NTSTATUS
87  _In_ ULONG Size,
88  _In_ ULONG CacheAttributes
89  );
90 
91 typedef NTSTATUS
95  _In_ ULONG Size,
96  _In_ ULONG CacheAttributes
97  );
98 
99 typedef BOOLEAN
103  _Out_opt_ PULONG CacheAttributes
104  );
105 
113 
118 
120 
121 /* FUNCTIONS *****************************************************************/
122 
123 BOOLEAN
125  VOID
126  )
127 {
128  /* Return if paging is on */
129  return ((CurrentExecutionContext) &&
131 }
132 
133 VOID
135  VOID
136  )
137 {
138  /* Nothing to do */
139  return;
140 }
141 
142 VOID
144  VOID
145  )
146 {
147  if (MmPteBase != (PVOID)PTE_BASE)
148  {
149  EfiPrintf(L"Supposed to relocate CR3\r\n");
150  }
151 }
152 
153 NTSTATUS
155  _In_ PVOID DestinationAddress,
156  _In_ PVOID SourceAddress,
157  _In_ ULONGLONG Size
158  )
159 {
160  EfiPrintf(L"Supposed to move shit\r\n");
161  return STATUS_NOT_IMPLEMENTED;
162 }
163 
164 NTSTATUS
166  _In_ PVOID DestinationAddress,
167  _In_ ULONGLONG Size
168  )
169 {
170  EfiPrintf(L"Supposed to zero shit\r\n");
171  return STATUS_NOT_IMPLEMENTED;
172 }
173 
174 BOOLEAN
176  _In_ PVOID VirtualAddress,
177  _Out_opt_ PPHYSICAL_ADDRESS PhysicalAddress,
178  _Out_opt_ PULONG CachingFlags
179  )
180 {
182 
183  /* Check if paging is on */
184  if ((CurrentExecutionContext) &&
186  {
187  /* Yes -- we have to translate this from virtual */
188  return Mmx86TranslateVirtualAddress(VirtualAddress,
189  PhysicalAddress,
190  CachingFlags);
191  }
192 
193  /* Look in all descriptors except truncated and firmware ones */
197  (ULONG_PTR)VirtualAddress >> PAGE_SHIFT);
198 
199  /* Return the virtual address as the physical address */
200  if (PhysicalAddress)
201  {
202  PhysicalAddress->HighPart = 0;
203  PhysicalAddress->LowPart = (ULONG_PTR)VirtualAddress;
204  }
205 
206  /* There's no caching on physical memory */
207  if (CachingFlags)
208  {
209  *CachingFlags = 0;
210  }
211 
212  /* Success is if we found a descriptor */
213  return Descriptor != NULL;
214 }
215 
216 VOID
218  VOID
219  )
220 {
221  EfiPrintf(L"No destroy\r\n");
222 }
223 
224 VOID
226  _In_ PVOID VirtualAddress
227  )
228 {
229  /* Flush the TLB */
230  __invlpg(VirtualAddress);
231 }
232 
233 VOID
235  VOID
236  )
237 {
238  /* Flush the TLB */
240 }
241 
242 NTSTATUS
244  _In_ PVOID VirtualAddress,
245  _In_ ULONG Size
246  )
247 {
248  EfiPrintf(L"No unmap\r\n");
249  return STATUS_NOT_IMPLEMENTED;
250 }
251 
252 NTSTATUS
254  _In_ PPHYSICAL_ADDRESS PhysicalAddress,
255  _Out_ PVOID VirtualAddress,
256  _In_ ULONG Size,
257  _In_ ULONG CacheAttributes
258  )
259 {
260  EfiPrintf(L"No remap\r\n");
261  return STATUS_NOT_IMPLEMENTED;
262 }
263 
264 NTSTATUS
266  _In_ PHYSICAL_ADDRESS PhysicalAddress,
267  _In_ PVOID VirtualAddress,
268  _In_ ULONG Size,
269  _In_ ULONG CacheAttributes
270  )
271 {
273  ULONG i, PageCount, PdeOffset;
274  ULONGLONG CurrentAddress;
275  PMMPDE Pde;
276  PMMPTE Pte;
278  PHYSICAL_ADDRESS PageTableAddress;
280 
281  /* Check if paging is on yet */
282  Enabled = BlMmIsTranslationEnabled();
283 
284  /* Get the physical address aligned */
285  CurrentAddress = (PhysicalAddress.QuadPart >> PAGE_SHIFT) << PAGE_SHIFT;
286 
287  /* Get the number of pages and loop through each one */
288  PageCount = Size >> PAGE_SHIFT;
289  for (i = 0; i < PageCount; i++)
290  {
291  /* Check if translation already exists for this page */
292  if (Mmx86TranslateVirtualAddress(VirtualAddress, NULL, NULL))
293  {
294  /* Ignore it and move to the next one */
295  VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
296  CurrentAddress += PAGE_SIZE;
297  continue;
298  }
299 
300  /* Get the PDE offset */
301  PdeOffset = MiAddressToPdeOffset(VirtualAddress);
302 
303  /* Check if paging is actually turned on */
304  if (Enabled)
305  {
306  /* Get the PDE entry using the self-map */
307  Pde = MiAddressToPde(VirtualAddress);
308  }
309  else
310  {
311  /* Get it using our physical mappings */
312  Pde = &MmPdpt[PdeOffset];
313  PageTable = (PMMPDE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT);
314  }
315 
316  /* Check if we don't yet have a PDE */
317  if (!Pde->u.Hard.Valid)
318  {
319  /* Allocate a page table */
320  Status = MmPapAllocatePhysicalPagesInRange(&PageTableAddress,
322  1,
323  0,
324  0,
326  0,
327  0);
328  if (!NT_SUCCESS(Status))
329  {
330  return STATUS_NO_MEMORY;
331  }
332 
333  /* This is our page table */
334  PageTable = (PVOID)(ULONG_PTR)PageTableAddress.QuadPart;
335 
336  /* Build the PDE for it */
337  Pde->u.Hard.PageFrameNumber = PageTableAddress.QuadPart >> PAGE_SHIFT;
338  Pde->u.Hard.Write = 1;
339  Pde->u.Hard.CacheDisable = 1;
340  Pde->u.Hard.WriteThrough = 1;
341  Pde->u.Hard.Valid = 1;
342 
343  /* Check if paging is enabled */
344  if (Enabled)
345  {
346  /* Then actually, get the page table's virtual address */
347  PageTable = (PVOID)PAGE_ROUND_DOWN(MiAddressToPte(VirtualAddress));
348 
349  /* Flush the TLB */
350  Mmx86FlushTlb();
351  }
352 
353  /* Zero out the page table */
354  RtlZeroMemory(PageTable, PAGE_SIZE);
355 
356  /* Reset caching attributes now */
357  Pde->u.Hard.CacheDisable = 0;
358  Pde->u.Hard.WriteThrough = 0;
359 
360  /* Check for paging again */
361  if (Enabled)
362  {
363  /* Flush the TLB entry for the page table only */
364  Mmx86FlushTlbEntry(PageTable);
365  }
366  }
367 
368  /* Add a reference to this page table */
369  MmArchReferencePage[PdeOffset]++;
370 
371  /* Check if a physical address was given */
372  if (PhysicalAddress.QuadPart != -1)
373  {
374  /* Check if paging is turned on */
375  if (Enabled)
376  {
377  /* Get the PTE using the self-map */
378  Pte = MiAddressToPte(VirtualAddress);
379  }
380  else
381  {
382  /* Get the PTE using physical addressing */
383  Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)];
384  }
385 
386  /* Build a valid PTE for it */
387  Pte->u.Hard.PageFrameNumber = CurrentAddress >> PAGE_SHIFT;
388  Pte->u.Hard.Write = 1;
389  Pte->u.Hard.Valid = 1;
390 
391  /* Check if this is uncached */
392  if (CacheAttributes == BlMemoryUncached)
393  {
394  /* Set the flags */
395  Pte->u.Hard.CacheDisable = 1;
396  Pte->u.Hard.WriteThrough = 1;
397  }
398  else if (CacheAttributes == BlMemoryWriteThrough)
399  {
400  /* It's write-through, set the flag */
401  Pte->u.Hard.WriteThrough = 1;
402  }
403  }
404 
405  /* Move to the next physical/virtual address */
406  VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
407  CurrentAddress += PAGE_SIZE;
408  }
409 
410  /* All done! */
411  return STATUS_SUCCESS;
412 }
413 
414 BOOLEAN
416  _In_ PVOID VirtualAddress,
417  _Out_ PPHYSICAL_ADDRESS PhysicalAddress,
418  _Out_opt_ PULONG CacheAttributes
419  )
420 {
421  PMMPDE Pde;
422  PMMPTE Pte;
425 
426  /* Is there no page directory yet? */
427  if (!MmPdpt)
428  {
429  return FALSE;
430  }
431 
432  /* Is paging enabled? */
433  Enabled = BlMmIsTranslationEnabled();
434 
435  /* Check if paging is actually turned on */
436  if (Enabled)
437  {
438  /* Get the PDE entry using the self-map */
439  Pde = MiAddressToPde(VirtualAddress);
440  }
441  else
442  {
443  /* Get it using our physical mappings */
444  Pde = &MmPdpt[MiAddressToPdeOffset(VirtualAddress)];
445  }
446 
447  /* Is the PDE valid? */
448  if (!Pde->u.Hard.Valid)
449  {
450  return FALSE;
451  }
452 
453  /* Check if paging is turned on */
454  if (Enabled)
455  {
456  /* Get the PTE using the self-map */
457  Pte = MiAddressToPte(VirtualAddress);
458  }
459  else
460  {
461  /* Get the PTE using physical addressing */
462  PageTable = (PMMPTE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT);
463  Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)];
464  }
465 
466  /* Is the PTE valid? */
467  if (!Pte->u.Hard.Valid)
468  {
469  return FALSE;
470  }
471 
472  /* Does caller want the physical address? */
473  if (PhysicalAddress)
474  {
475  /* Return it */
476  PhysicalAddress->QuadPart = (Pte->u.Hard.PageFrameNumber << PAGE_SHIFT) +
477  BYTE_OFFSET(VirtualAddress);
478  }
479 
480  /* Does caller want cache attributes? */
481  if (CacheAttributes)
482  {
483  /* Not yet -- lie and say it's cached */
484  EfiPrintf(L"Cache checking not yet enabled\r\n");
485  *CacheAttributes = BlMemoryWriteBack;
486  }
487 
488  /* It exists! */
489  return TRUE;
490 }
491 
492 NTSTATUS
494  _Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr,
495  _Inout_ PVOID* VirtualAddressPtr,
496  _Inout_ PULONGLONG SizePtr,
497  _In_ ULONG CacheAttributes
498  )
499 {
500  ULONGLONG Size;
504  ULONG_PTR CurrentAddress, VirtualAddressEnd;
506 
507  /* Fail if any parameters are missing */
508  if (!(PhysicalAddressPtr) || !(VirtualAddressPtr) || !(SizePtr))
509  {
511  }
512 
513  /* Fail if the size is over 32-bits */
514  Size = *SizePtr;
515  if (Size > 0xFFFFFFFF)
516  {
518  }
519 
520  /* Nothing to do if we're in physical mode */
521  if (MmTranslationType == BlNone)
522  {
523  return STATUS_SUCCESS;
524  }
525 
526  /* Can't use virtual memory in real mode */
528  {
529  return STATUS_UNSUCCESSFUL;
530  }
531 
532  /* Capture the current virtual and physical addresses */
533  VirtualAddress = *VirtualAddressPtr;
534  PhysicalAddress = PhysicalAddressPtr->QuadPart;
535 
536  /* Check if a physical address was requested */
537  if (PhysicalAddress != 0xFFFFFFFF)
538  {
539  /* Round down the base addresses */
540  PhysicalAddress = PAGE_ROUND_DOWN(PhysicalAddress);
541  VirtualAddress = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
542 
543  /* Round up the size */
544  Size = ROUND_TO_PAGES(PhysicalAddressPtr->QuadPart -
545  PhysicalAddress +
546  Size);
547 
548  /* Loop every virtual page */
549  CurrentAddress = (ULONG_PTR)VirtualAddress;
550  VirtualAddressEnd = CurrentAddress + Size - 1;
551  while (CurrentAddress < VirtualAddressEnd)
552  {
553  /* Get the physical page of this virtual page */
554  if (MmArchTranslateVirtualAddress((PVOID)CurrentAddress,
555  &TranslatedAddress,
556  &CacheAttributes))
557  {
558  /* Make sure the physical page of the virtual page, matches our page */
559  if (TranslatedAddress.QuadPart !=
560  (PhysicalAddress +
561  (CurrentAddress - (ULONG_PTR)VirtualAddress)))
562  {
563  /* There is an existing virtual mapping for a different address */
564  EfiPrintf(L"Existing mapping exists: %lx vs %lx\r\n",
565  TranslatedAddress.QuadPart,
566  PhysicalAddress + (CurrentAddress - (ULONG_PTR)VirtualAddress));
567  EfiStall(10000000);
569  }
570  }
571 
572  /* Try the next one */
573  CurrentAddress += PAGE_SIZE;
574  }
575  }
576 
577  /* Aactually do the mapping */
578  TranslatedAddress.QuadPart = PhysicalAddress;
579  Status = Mmx86MapPhysicalAddress(TranslatedAddress,
580  VirtualAddress,
581  Size,
582  CacheAttributes);
583  if (!NT_SUCCESS(Status))
584  {
585  EfiPrintf(L"Failed to map!: %lx\r\n", Status);
586  return Status;
587  }
588 
589  /* Return aligned/fixed up output parameters */
590  PhysicalAddressPtr->QuadPart = PhysicalAddress;
591  *VirtualAddressPtr = VirtualAddress;
592  *SizePtr = Size;
593 
594  /* Flush the TLB if paging is enabled */
596  {
597  Mmx86FlushTlb();
598  }
599 
600  /* All good! */
601  return STATUS_SUCCESS;
602 }
603 
604 NTSTATUS
606  _In_ PVOID VirtualAddress,
607  _In_ ULONGLONG Size,
608  _In_ PHYSICAL_ADDRESS PhysicalAddress
609  )
610 {
612 
613  /* Make a virtual mapping for this physical address */
614  Status = MmMapPhysicalAddress(&PhysicalAddress, &VirtualAddress, &Size, 0);
615  if (!NT_SUCCESS(Status))
616  {
617  return Status;
618  }
619 
620  /* Nothing else to do if we're not in paging mode */
621  if (MmTranslationType == BlNone)
622  {
623  return STATUS_SUCCESS;
624  }
625 
626  /* Otherwise, remove this region from the list of free virtual ranges */
629  (ULONG_PTR)VirtualAddress >> PAGE_SHIFT,
630  Size >> PAGE_SHIFT,
631  0);
632  if (!NT_SUCCESS(Status))
633  {
634  /* Unmap the address if that failed */
635  MmUnmapVirtualAddress(&VirtualAddress, &Size);
636  }
637 
638  /* Return back to caller */
639  return Status;
640 }
641 
642 VOID
644  _In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList
645  )
646 {
647  ULONGLONG EndPage, VirtualEndPage;
649  PLIST_ENTRY NextEntry;
650 
651  NextEntry = DescriptorList->First->Flink;
652  while (NextEntry != DescriptorList->First)
653  {
654  MemoryDescriptor = CONTAINING_RECORD(NextEntry,
656  ListEntry);
657 
658  EndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
659  if (MemoryDescriptor->VirtualPage != 0)
660  {
661  VirtualEndPage = MemoryDescriptor->VirtualPage + MemoryDescriptor->PageCount;
662  }
663  else
664  {
665  VirtualEndPage = 0;
666  }
667 
668  EfiPrintf(L"%p - [%08llx-%08llx @ %08llx-%08llx]:%x\r\n",
669  MemoryDescriptor,
670  MemoryDescriptor->BasePage << PAGE_SHIFT,
671  (EndPage << PAGE_SHIFT) - 1,
672  MemoryDescriptor->VirtualPage << PAGE_SHIFT,
673  VirtualEndPage ? (VirtualEndPage << PAGE_SHIFT) - 1 : 0,
674  (ULONG)MemoryDescriptor->Type);
675 
676  NextEntry = NextEntry->Flink;
677  }
678 }
679 
680 NTSTATUS
682  _In_ ULONG Phase,
683  _In_ PBL_MEMORY_DATA MemoryData
684  )
685 {
686  BOOLEAN DoDeferred;
687  ULONG DescriptorCount;
689  ULONG FinalOffset;
691  ULONGLONG Size;
694  BL_MEMORY_DESCRIPTOR_LIST FirmwareMdl;
695  PLIST_ENTRY Head, NextEntry;
696 
697  /* Check which phase this is */
698  if (Phase == 1)
699  {
700  /* In phase 1 we don't initialize deferred mappings */
701  DoDeferred = FALSE;
702  }
703  else
704  {
705  /* Don't do anything if there's nothing to initialize */
707  {
708  return STATUS_SUCCESS;
709  }
710 
711  /* We'll do deferred descriptors in phase 2 */
712  DoDeferred = TRUE;
713  }
714 
715  /*
716  * Because BL supports cross x86-x64 application launches and a LIST_ENTRY
717  * is of variable size, care must be taken here to ensure that we see a
718  * consistent view of descriptors. BL uses some offset magic to figure out
719  * where the data actually starts, since everything is ULONGLONG past the
720  * LIST_ENTRY itself
721  */
722  FinalOffset = MemoryData->MdListOffset + MemoryData->DescriptorOffset;
723  Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)MemoryData + FinalOffset -
725 
726  /* Scan all of them */
727  DescriptorCount = MemoryData->DescriptorCount;
728  while (DescriptorCount != 0)
729  {
730  /* Ignore application data */
731  if (Descriptor->Type != BlApplicationData)
732  {
733  /* If this is a ramdisk, do it in phase 2 */
734  if ((Descriptor->Type == BlLoaderRamDisk) == DoDeferred)
735  {
736  /* Get the current physical address and size */
737  PhysicalAddress.QuadPart = Descriptor->BasePage << PAGE_SHIFT;
738  Size = Descriptor->PageCount << PAGE_SHIFT;
739 
740  /* Check if it was already mapped */
741  if (Descriptor->VirtualPage)
742  {
743  /* Use the existing address */
744  VirtualAddress = (PVOID)(ULONG_PTR)(Descriptor->VirtualPage << PAGE_SHIFT);
745  }
746  else
747  {
748  /* Use the physical address */
749  VirtualAddress = (PVOID)(ULONG_PTR)PhysicalAddress.QuadPart;
750  }
751 
752  /* Crete the mapping */
753  Status = Mmx86MapInitStructure(VirtualAddress,
754  Size,
755  PhysicalAddress);
756  if (!NT_SUCCESS(Status))
757  {
758  return Status;
759  }
760  }
761 
762  /* Check if we're in phase 1 and deferring RAM disk */
763  if ((Phase == 1) && (Descriptor->Type == BlLoaderRamDisk))
764  {
766  }
767  }
768 
769  /* Move on to the next descriptor */
770  DescriptorCount--;
771  Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)Descriptor + MemoryData->DescriptorSize);
772  }
773 
774  /* In phase 1, also do UEFI mappings */
775  if (Phase != 2)
776  {
777  /* Get the memory map */
778  MmMdInitializeListHead(&FirmwareMdl);
779  Status = MmFwGetMemoryMap(&FirmwareMdl, BL_MM_FLAG_REQUEST_COALESCING);
780  if (!NT_SUCCESS(Status))
781  {
782  return Status;
783  }
784 
785  /* Iterate over it */
786  Head = FirmwareMdl.First;
787  NextEntry = Head->Flink;
788  while (NextEntry != Head)
789  {
790  /* Check if this is a UEFI-related descriptor, unless it's the self-map page */
791  Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
792  if (((Descriptor->Type == BlEfiBootMemory) ||
793  (Descriptor->Type == BlEfiRuntimeMemory) ||
794  (Descriptor->Type == BlLoaderMemory)) &&
795  ((Descriptor->BasePage << PAGE_SHIFT) != Mmx86SelfMapBase.QuadPart))
796  {
797  /* Identity-map it */
798  PhysicalAddress.QuadPart = Descriptor->BasePage << PAGE_SHIFT;
799  Status = Mmx86MapInitStructure((PVOID)((ULONG_PTR)Descriptor->BasePage << PAGE_SHIFT),
800  Descriptor->PageCount << PAGE_SHIFT,
801  PhysicalAddress);
802  if (!NT_SUCCESS(Status))
803  {
804  return Status;
805  }
806  }
807 
808  /* Move to the next descriptor */
809  NextEntry = NextEntry->Flink;
810  }
811 
812  /* Reset */
813  NextEntry = Head->Flink;
814  while (NextEntry != Head)
815  {
816  /* Get the descriptor */
817  Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
818 
819  /* Skip to the next entry before we free */
820  NextEntry = NextEntry->Flink;
821 
822  /* Remove and free it */
823  MmMdRemoveDescriptorFromList(&FirmwareMdl, Descriptor);
824  MmMdFreeDescriptor(Descriptor);
825  }
826  }
827 
828  /* All library mappings identity mapped now */
829  return STATUS_SUCCESS;
830 }
831 
832 NTSTATUS
834  _In_ ULONG Phase,
835  _In_ PBL_MEMORY_DATA MemoryData
836  )
837 {
838  ULONG ImageSize;
839  PVOID ImageBase;
840  KDESCRIPTOR Gdt, Idt;
843 
844  /* If this is phase 2, map the memory regions */
845  if (Phase != 1)
846  {
847  return Mmx86pMapMemoryRegions(Phase, MemoryData);
848  }
849 
850  /* Get the application image base/size */
851  Status = BlGetApplicationBaseAndSize(&ImageBase, &ImageSize);
852  if (!NT_SUCCESS(Status))
853  {
854  return Status;
855  }
856 
857  /* Map the image back at the same place */
858  PhysicalAddress.QuadPart = (ULONG_PTR)ImageBase;
859  Status = Mmx86MapInitStructure(ImageBase, ImageSize, PhysicalAddress);
860  if (!NT_SUCCESS(Status))
861  {
862  return Status;
863  }
864 
865  /* Map the first 4MB of memory */
866  PhysicalAddress.QuadPart = 0;
867  Status = Mmx86MapInitStructure(NULL, 4 * 1024 * 1024, PhysicalAddress);
868  if (!NT_SUCCESS(Status))
869  {
870  return Status;
871  }
872 
873  /* Map the GDT */
874  _sgdt(&Gdt.Limit);
875  PhysicalAddress.QuadPart = Gdt.Base;
876  Status = Mmx86MapInitStructure((PVOID)Gdt.Base, Gdt.Limit + 1, PhysicalAddress);
877  if (!NT_SUCCESS(Status))
878  {
879  return Status;
880  }
881 
882  /* Map the IDT */
883  __sidt(&Idt.Limit);
884  PhysicalAddress.QuadPart = Idt.Base;
885  Status = Mmx86MapInitStructure((PVOID)Idt.Base, Idt.Limit + 1, PhysicalAddress);
886  if (!NT_SUCCESS(Status))
887  {
888  return Status;
889  }
890 
891  /* Map the reference page */
892  PhysicalAddress.QuadPart = (ULONG_PTR)MmArchReferencePage;
895  PhysicalAddress);
896  if (!NT_SUCCESS(Status))
897  {
898  return Status;
899  }
900 
901  /* More to do */
902  return Mmx86pMapMemoryRegions(Phase, MemoryData);
903 }
904 
905 NTSTATUS
907  _In_ PBL_MEMORY_DATA MemoryData,
908  _In_ BL_TRANSLATION_TYPE TranslationType
909  )
910 {
913  ULONG PdeIndex;
914 
915  /* Set the global function pointers for memory translation */
916  Mmx86TranslateVirtualAddress = MmDefpTranslateVirtualAddress;
917  Mmx86MapPhysicalAddress = MmDefpMapPhysicalAddress;
918  Mmx86UnmapVirtualAddress = MmDefpUnmapVirtualAddress;
919  Mmx86RemapVirtualAddress = MmDefpRemapVirtualAddress;
920  Mmx86FlushTlb = MmDefpFlushTlb;
921  Mmx86FlushTlbEntry = MmDefpFlushTlbEntry;
922  Mmx86DestroySelfMap = MmDefpDestroySelfMap;
923 
924  /* Check what mode we're currently in */
925  if (TranslationType == BlVirtual)
926  {
927  EfiPrintf(L"Virtual->Virtual not yet supported\r\n");
928  return STATUS_NOT_IMPLEMENTED;
929  }
930  else if (TranslationType != BlNone)
931  {
932  /* Not even Windows supports PAE->Virtual downgrade */
933  return STATUS_NOT_IMPLEMENTED;
934  }
935 
936  /* The None->Virtual case */
937  MmPdpt = NULL;
938  Mmx86SelfMapBase.QuadPart = 0;
940 
941  /* Truncate all memory above 4GB so that we don't use it @TODO: FIXME */
942  EfiPrintf(L"Warning: not truncating > 4GB memory. Don't boot with more than 4GB of RAM!\r\n");
943  //Status = MmPaTruncateMemory(0x100000);
944  Status = STATUS_SUCCESS;
945  if (!NT_SUCCESS(Status))
946  {
947  goto Quickie;
948  }
949 
950  /* Allocate a page directory */
951  Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
953  1,
954  0,
955  0,
957  0,
958  0);
959  if (!NT_SUCCESS(Status))
960  {
961  goto Quickie;
962  }
963 
964  /* Zero out the page directory */
965  MmPdpt = (PVOID)PhysicalAddress.LowPart;
966  RtlZeroMemory(MmPdpt, PAGE_SIZE);
967 
968  /* Set the page size */
970 
971  /* Allocate the self-map page */
972  Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
974  1,
975  0,
976  0,
978  0,
979  0);
980  if (!NT_SUCCESS(Status))
981  {
982  goto Quickie;
983  }
984 
985  /* Set the reference page */
986  MmArchReferencePage = (PVOID)PhysicalAddress.LowPart;
987 
988  /* Zero it out */
990 
991  /* Allocate 4MB worth of self-map pages */
992  Status = MmPaReserveSelfMapPages(&Mmx86SelfMapBase,
993  (4 * 1024 * 1024) >> PAGE_SHIFT,
994  (4 * 1024 * 1024) >> PAGE_SHIFT);
995  if (!NT_SUCCESS(Status))
996  {
997  goto Quickie;
998  }
999 
1000  /* Zero them out */
1001  RtlZeroMemory((PVOID)Mmx86SelfMapBase.LowPart, 4 * 1024 * 1024);
1002  EfiPrintf(L"PDPT at 0x%p Reference Page at 0x%p Self-map at 0x%p\r\n",
1003  MmPdpt, MmArchReferencePage, Mmx86SelfMapBase.LowPart);
1004 
1005  /* Align PTE base to 4MB region */
1006  MmPteBase = (PVOID)(Mmx86SelfMapBase.LowPart & ~0x3FFFFF);
1007 
1008  /* The PDE is the PTE of the PTE base */
1010  PdeIndex = MiAddressToPdeOffset(MmPdeBase);
1011  MmPdpt[PdeIndex].u.Hard.Valid = 1;
1012  MmPdpt[PdeIndex].u.Hard.Write = 1;
1013  MmPdpt[PdeIndex].u.Hard.PageFrameNumber = (ULONG_PTR)MmPdpt >> PAGE_SHIFT;
1014  MmArchReferencePage[PdeIndex]++;
1015 
1016  /* Remove PTE_BASE from free virtual memory */
1019  PTE_BASE >> PAGE_SHIFT,
1020  (4 * 1024 * 1024) >> PAGE_SHIFT,
1021  0);
1022  if (!NT_SUCCESS(Status))
1023  {
1024  goto Quickie;
1025  }
1026 
1027  /* Remove HAL_HEAP from free virtual memory */
1031  (4 * 1024 * 1024) >> PAGE_SHIFT,
1032  0);
1033  if (!NT_SUCCESS(Status))
1034  {
1035  goto Quickie;
1036  }
1037 
1038  /* Initialize the virtual->physical memory mappings */
1039  Status = Mmx86InitializeMemoryMap(1, MemoryData);
1040  if (!NT_SUCCESS(Status))
1041  {
1042  goto Quickie;
1043  }
1044 
1045  EfiPrintf(L"Ready to turn on motherfucking paging, brah!\r\n");
1046  Status = STATUS_NOT_IMPLEMENTED;
1047 
1048 Quickie:
1049  /* Free reference page if we allocated it */
1050  if (MmArchReferencePage)
1051  {
1052  PhysicalAddress.QuadPart = (ULONG_PTR)MmArchReferencePage;
1053  BlMmFreePhysicalPages(PhysicalAddress);
1054  }
1055 
1056  /* Free page directory if we allocated it */
1057  if (MmPdpt)
1058  {
1059  PhysicalAddress.QuadPart = (ULONG_PTR)MmPdpt;
1060  BlMmFreePhysicalPages(PhysicalAddress);
1061  }
1062 
1063  /* Free the self map if we allocated it */
1064  if (Mmx86SelfMapBase.QuadPart)
1065  {
1066  MmPaReleaseSelfMapPages(Mmx86SelfMapBase);
1067  }
1068 
1069  /* All done */
1070  return Status;
1071 }
1072 
1073 NTSTATUS
1075  _In_ ULONG Phase,
1076  _In_ PBL_MEMORY_DATA MemoryData,
1077  _In_ BL_TRANSLATION_TYPE TranslationType,
1078  _In_ BL_TRANSLATION_TYPE RequestedTranslationType
1079  )
1080 {
1081  NTSTATUS Status;
1082  ULONGLONG IncreaseUserVa, PerfCounter, CpuRandom;
1083  INT CpuInfo[4];
1084 
1085  /* For phase 2, just map deferred regions */
1086  if (Phase != 1)
1087  {
1088  return Mmx86pMapMemoryRegions(2, MemoryData);
1089  }
1090 
1091  /* What translation type are we switching to? */
1092  switch (RequestedTranslationType)
1093  {
1094  /* Physical memory */
1095  case BlNone:
1096 
1097  /* Initialize everything to default/null values */
1098  MmArchLargePageSize = 1;
1099  MmArchKsegBase = 0;
1100  MmArchKsegBias = 0;
1101  MmArchKsegAddressRange.Minimum = 0;
1102  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
1104  Mmx86SelfMapBase.QuadPart = 0;
1105 
1106  /* Set stub functions */
1107  BlMmRelocateSelfMap = MmArchNullFunction;
1108  BlMmFlushTlb = MmArchNullFunction;
1109 
1110  /* Set success */
1111  Status = STATUS_SUCCESS;
1112  break;
1113 
1114  case BlVirtual:
1115 
1116  /* Set the large page size to 1024 pages (4MB) */
1117  MmArchLargePageSize = (4 * 1024 * 1024) / PAGE_SIZE;
1118 
1119  /* Check if /USERVA option was used */
1122  &IncreaseUserVa);
1123  if (NT_SUCCESS(Status) && (IncreaseUserVa))
1124  {
1125  /* Yes -- load the kernel at 0xE0000000 instead */
1126  MmArchKsegBase = 0xE0000000;
1127  }
1128  else
1129  {
1130  /* Nope, load at the standard 2GB split */
1131  MmArchKsegBase = 0x80000000;
1132  }
1133 
1134  /* Check if CPUID 01h is supported */
1135  CpuRandom = 0;
1137  {
1138  /* Call it */
1139  BlArchCpuId(1, 0, CpuInfo);
1140 
1141  /* Check if RDRAND is supported */
1142  if (CpuInfo[2] & 0x40000000)
1143  {
1144  EfiPrintf(L"Your CPU can do RDRAND! Good for you!\r\n");
1145  CpuRandom = 0;
1146  }
1147  }
1148 
1149  /* Read the TSC */
1150  PerfCounter = BlArchGetPerformanceCounter();
1151  PerfCounter >>= 4;
1152  _rotl16(PerfCounter, 5);
1153 
1154  /* Set the address range */
1155  MmArchKsegAddressRange.Minimum = 0;
1156  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
1157 
1158  /* Set the KASLR bias */
1159  MmArchKsegBias = ((PerfCounter ^ CpuRandom) & 0xFFF) << 12;
1160  MmArchKsegBias = 0;
1162 
1163  /* Set the kernel range */
1164  MmArchKsegAddressRange.Minimum = MmArchKsegBase;
1165  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
1166 
1167  /* Set the boot application top maximum */
1168  MmArchTopOfApplicationAddressSpace = 0x70000000 - 1; // Windows bug
1169 
1170  /* Initialize virtual address space translation */
1171  Status = MmDefInitializeTranslation(MemoryData, TranslationType);
1172  if (NT_SUCCESS(Status))
1173  {
1174  /* Set stub functions */
1175  BlMmRelocateSelfMap = MmDefRelocateSelfMap;
1176  BlMmFlushTlb = Mmx86FlushTlb;
1177  BlMmMoveVirtualAddressRange = MmDefMoveVirtualAddressRange;
1178  BlMmZeroVirtualAddressRange = MmDefZeroVirtualAddressRange;
1179  }
1180  break;
1181 
1182  case BlPae:
1183 
1184  /* We don't support PAE */
1185  Status = STATUS_NOT_SUPPORTED;
1186  break;
1187 
1188  default:
1189 
1190  /* Invalid architecture type*/
1191  Status = STATUS_INVALID_PARAMETER;
1192  break;
1193  }
1194 
1195  /* Back to caller */
1196  return Status;
1197 }
DWORD *typedef PVOID
Definition: winlogon.h:52
NTSTATUS MmDefZeroVirtualAddressRange(_In_ PVOID DestinationAddress, _In_ ULONGLONG Size)
Definition: mmx86.c:165
BOOLEAN(* PBL_MM_TRANSLATE_VIRTUAL_ADDRESS)(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CacheAttributes)
Definition: mmx86.c:100
NTSTATUS BlGetApplicationBaseAndSize(_Out_ PVOID *ImageBase, _Out_ PULONG ImageSize)
Definition: bootlib.c:424
ULONG64 Write
Definition: mmtypes.h:170
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
NTSTATUS MmDefpRemapVirtualAddress(_In_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:253
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MM_HAL_VA_START
Definition: ketypes.h:256
ULONG MmArchReferencePageSize
Definition: mmx86.c:37
VOID(* PBL_MM_RELOCATE_SELF_MAP)(VOID)
Definition: mmx86.c:45
NTSTATUS MmMapPhysicalAddress(_Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr, _Inout_ PVOID *VirtualAddressPtr, _Inout_ PULONGLONG SizePtr, _In_ ULONG CacheAttributes)
Definition: mmx86.c:493
_Out_ PNDIS_BUFFER _In_ NDIS_HANDLE _In_ PVOID MemoryDescriptor
Definition: ndis.h:3251
PVOID MmPdeBase
Definition: mmx86.c:36
#define MiAddressToPde(x)
Definition: mmx86.c:20
NTSTATUS EfiStall(_In_ ULONG StallTime)
Definition: firmware.c:638
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
Definition: bidi.c:75
FORCEINLINE VOID MmMdInitializeListHead(_In_ PBL_MEMORY_DESCRIPTOR_LIST List)
Definition: bl.h:1297
PBL_MM_TRANSLATE_VIRTUAL_ADDRESS Mmx86TranslateVirtualAddress
Definition: mmx86.c:106
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS(* PBL_MM_MAP_PHYSICAL_ADDRESS)(_In_ PHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:92
PVOID MmPteBase
Definition: mmx86.c:35
NTSTATUS MmDefMoveVirtualAddressRange(_In_ PVOID DestinationAddress, _In_ PVOID SourceAddress, _In_ ULONGLONG Size)
Definition: mmx86.c:154
NTSTATUS MmUnmapVirtualAddress(_Inout_ PVOID *VirtualAddress, _Inout_ PULONGLONG Size)
Definition: mm.c:235
#define TRUE
Definition: numbers.c:17
NTSTATUS(* PBL_MM_UNMAP_VIRTUAL_ADDRESS)(_In_ PVOID VirtualAddress, _In_ ULONG Size)
Definition: mmx86.c:78
#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:108
PBL_MM_UNMAP_VIRTUAL_ADDRESS Mmx86UnmapVirtualAddress
Definition: mmx86.c:109
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1601
#define BL_MM_REMOVE_PHYSICAL_REGION_FLAG
Definition: bl.h:125
NTSTATUS BlMmFreePhysicalPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1066
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:681
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2268
PBL_MM_FLUSH_TLB_ENTRY Mmx86FlushTlbEntry
Definition: mmx86.c:111
ULONG_PTR MmArchKsegBias
Definition: mmx86.c:27
int32_t INT
Definition: typedefs.h:57
PVOID Base
Definition: ketypes.h:486
int WINAPI EndPage(_In_ HDC)
enum _BL_TRANSLATION_TYPE BL_TRANSLATION_TYPE
NTSTATUS MmMdRemoveRegionFromMdlEx(__in PBL_MEMORY_DESCRIPTOR_LIST MdList, __in ULONG Flags, __in ULONGLONG BasePage, __in ULONGLONG PageCount, __in PBL_MEMORY_DESCRIPTOR_LIST NewMdList)
Definition: descriptor.c:614
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:928
union _MMPTE::@1889 u
USHORT Limit
Definition: ketypes.h:485
ULONG ContextFlags
Definition: bl.h:922
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:64
Definition: bl.h:232
PBL_MM_MAP_PHYSICAL_ADDRESS Mmx86MapPhysicalAddress
Definition: mmx86.c:107
VOID MmArchNullFunction(VOID)
Definition: mmx86.c:134
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1572
GLenum GLclampf GLint i
Definition: glfuncs.h:14
BL_MEMORY_TYPE Type
Definition: bl.h:764
#define MiAddressToPte(x)
Definition: mmx86.c:19
VOID MmMdRemoveDescriptorFromList(_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, _In_ PBL_MEMORY_DESCRIPTOR Entry)
Definition: descriptor.c:335
PHYSICAL_ADDRESS Mmx86SelfMapBase
Definition: mmx86.c:31
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:1813
struct _BL_MEMORY_DESCRIPTOR * PBL_MEMORY_DESCRIPTOR
PBL_BCD_OPTION BcdData
Definition: bl.h:790
#define NULL
Definition: mystdio.h:57
PBL_MM_FLUSH_TLB Mmx86FlushTlb
Definition: mmx86.c:110
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:316
ULONG64 WriteThrough
Definition: mmtypes.h:161
BL_TRANSLATION_TYPE MmTranslationType
Definition: mm.c:17
struct _MMPTE * PMMPDE
Definition: bl.h:240
#define _Out_
Definition: no_sal2.h:323
ULONGLONG PageCount
Definition: bl.h:762
PBL_ARCH_CONTEXT CurrentExecutionContext
Definition: arch.c:17
unsigned short _rotl16(unsigned short _Value, unsigned char _Shift)
Definition: intrin_ppc.h:495
BOOLEAN BlArchIsCpuIdFunctionSupported(_In_ ULONG Function)
Definition: util.c:799
NTSTATUS MmDefpMapPhysicalAddress(_In_ PHYSICAL_ADDRESS PhysicalAddress, _In_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:265
UINTN Size
Definition: acefiex.h:550
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:120
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:1074
ULONGLONG Maximum
Definition: bl.h:936
NTSTATUS MmFwGetMemoryMap(_Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap, _In_ ULONG Flags)
Definition: firmware.c:1387
Definition: bl.h:231
PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE BlMmMoveVirtualAddressRange
Definition: mmx86.c:116
uint64_t ULONGLONG
Definition: typedefs.h:66
ULONG64 Valid
Definition: mmtypes.h:150
struct _MMPTE * PMMPTE
NTSTATUS MmPaReleaseSelfMapPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1384
VOID MmDefpFlushTlb(VOID)
Definition: mmx86.c:234
#define _Inout_
Definition: no_sal2.h:244
NTSTATUS MmPaReserveSelfMapPages(_Inout_ PPHYSICAL_ADDRESS PhysicalAddress, _In_ ULONG Alignment, _In_ ULONG PageCount)
Definition: pagealloc.c:1443
ULONG64 CacheDisable
Definition: mmtypes.h:162
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1060
static PEMS_PAGE PageTable
Definition: emsdrv.c:39
VOID MmMdDbgDumpList(_In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList)
Definition: mmx86.c:643
#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:117
#define VOID
Definition: acefi.h:69
PBL_MM_FLUSH_TLB BlMmFlushTlb
Definition: mmx86.c:115
ULONG LowPart
Definition: typedefs.h:105
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PTE_BASE
Definition: mmx86.c:14
Definition: typedefs.h:118
ULONG MmArchLargePageSize
Definition: mmx86.c:28
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3772
VOID(* PBL_MM_DESTROY_SELF_MAP)(VOID)
Definition: mmx86.c:63
NTSTATUS MmDefpUnmapVirtualAddress(_In_ PVOID VirtualAddress, _In_ ULONG Size)
Definition: mmx86.c:243
PULONG MmArchReferencePage
Definition: mmx86.c:34
VOID MmDefRelocateSelfMap(VOID)
Definition: mmx86.c:143
VOID MmDefpFlushTlbEntry(_In_ PVOID VirtualAddress)
Definition: mmx86.c:225
ULONGLONG Minimum
Definition: bl.h:935
__INTRIN_INLINE void _sgdt(void *Destination)
Definition: intrin_x86.h:1818
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
PBL_MEMORY_DESCRIPTOR MmMdFindDescriptor(_In_ ULONG WhichList, _In_ ULONG Flags, _In_ ULONGLONG Page)
Definition: descriptor.c:904
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONGLONG BasePage
Definition: bl.h:753
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
LONG NTSTATUS
Definition: DriverTester.h:11
BOOLEAN BlMmIsTranslationEnabled(VOID)
Definition: mmx86.c:124
BL_ADDRESS_RANGE MmArchKsegAddressRange
Definition: mmx86.c:29
#define ROUND_TO_PAGES(Size)
BOOL Enabled
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned int * PULONG
Definition: retypes.h:1
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
ULONGLONG BlArchGetPerformanceCounter(VOID)
Definition: util.c:841
BOOLEAN MmDefpTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CacheAttributes)
Definition: mmx86.c:415
PMMPTE MmPdpt
Definition: mmx86.c:33
NTSTATUS MmDefInitializeTranslation(_In_ PBL_MEMORY_DATA MemoryData, _In_ BL_TRANSLATION_TYPE TranslationType)
Definition: mmx86.c:906
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1758
#define BOOLEAN
Definition: pedump.c:73
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:382
#define FALSE
Definition: numbers.c:16
NTSTATUS(* PBL_MM_REMAP_VIRTUAL_ADDRESS)(_In_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:84
BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated
Definition: pagealloc.c:38
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define MiAddressToPdeOffset(x)
Definition: mmx86.c:22
#define NTSTATUS
Definition: env_spec_w32.h:77
#define MiAddressToPteOffset(x)
Definition: mmx86.c:21
BL_ARCH_MODE Mode
Definition: bl.h:920
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Out_ PPHYSICAL_ADDRESS DestinationAddress
Definition: iotypes.h:1089
PBL_MM_DESTROY_SELF_MAP Mmx86DestroySelfMap
Definition: mmx86.c:112
NTSTATUS Mmx86MapInitStructure(_In_ PVOID VirtualAddress, _In_ ULONGLONG Size, _In_ PHYSICAL_ADDRESS PhysicalAddress)
Definition: mmx86.c:605
VOID BlArchCpuId(_In_ ULONG Function, _In_ ULONG SubFunction, _Out_ INT *Result)
Definition: util.c:858
ULONGLONG VirtualPage
Definition: bl.h:754
VOID(* PBL_MM_FLUSH_TLB_ENTRY)(_In_ PVOID VirtualAddress)
Definition: mmx86.c:68
PBL_MM_RELOCATE_SELF_MAP BlMmRelocateSelfMap
Definition: mmx86.c:114
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1089
VOID MmDefpDestroySelfMap(VOID)
Definition: mmx86.c:217
BL_MEMORY_DESCRIPTOR_LIST MmMdlFreeVirtual
Definition: pagealloc.c:45
NTSTATUS(* PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE)(_In_ PVOID DestinationAddress, _In_ PVOID SourceAddress, _In_ ULONGLONG Size)
Definition: mmx86.c:50
#define BYTE_OFFSET(Va)
Definition: bl.h:233
NTSTATUS Mmx86InitializeMemoryMap(_In_ ULONG Phase, _In_ PBL_MEMORY_DATA MemoryData)
Definition: mmx86.c:833
NTSTATUS(* PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE)(_In_ PVOID DestinationAddress, _In_ ULONGLONG Size)
Definition: mmx86.c:57
LONGLONG QuadPart
Definition: typedefs.h:113
VOID(* PBL_MM_FLUSH_TLB)(VOID)
Definition: mmx86.c:40
BOOLEAN MmArchTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_opt_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CachingFlags)
Definition: mmx86.c:175
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966