ReactOS  r75907
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  EfiPrintf(L"PDE alloc failed!\r\n");
331  EfiStall(1000000);
332  return STATUS_NO_MEMORY;
333  }
334 
335  /* This is our page table */
336  PageTable = (PVOID)(ULONG_PTR)PageTableAddress.QuadPart;
337 
338  /* Build the PDE for it */
339  Pde->u.Hard.PageFrameNumber = PageTableAddress.QuadPart >> PAGE_SHIFT;
340  Pde->u.Hard.Write = 1;
341  Pde->u.Hard.CacheDisable = 1;
342  Pde->u.Hard.WriteThrough = 1;
343  Pde->u.Hard.Valid = 1;
344 
345  /* Check if paging is enabled */
346  if (Enabled)
347  {
348  /* Then actually, get the page table's virtual address */
349  PageTable = (PVOID)PAGE_ROUND_DOWN(MiAddressToPte(VirtualAddress));
350 
351  /* Flush the TLB */
352  Mmx86FlushTlb();
353  }
354 
355  /* Zero out the page table */
356  RtlZeroMemory(PageTable, PAGE_SIZE);
357 
358  /* Reset caching attributes now */
359  Pde->u.Hard.CacheDisable = 0;
360  Pde->u.Hard.WriteThrough = 0;
361 
362  /* Check for paging again */
363  if (Enabled)
364  {
365  /* Flush the TLB entry for the page table only */
366  Mmx86FlushTlbEntry(PageTable);
367  }
368  }
369 
370  /* Add a reference to this page table */
371  MmArchReferencePage[PdeOffset]++;
372 
373  /* Check if a physical address was given */
374  if (PhysicalAddress.QuadPart != -1)
375  {
376  /* Check if paging is turned on */
377  if (Enabled)
378  {
379  /* Get the PTE using the self-map */
380  Pte = MiAddressToPte(VirtualAddress);
381  }
382  else
383  {
384  /* Get the PTE using physical addressing */
385  Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)];
386  }
387 
388  /* Build a valid PTE for it */
389  Pte->u.Hard.PageFrameNumber = CurrentAddress >> PAGE_SHIFT;
390  Pte->u.Hard.Write = 1;
391  Pte->u.Hard.Valid = 1;
392 
393  /* Check if this is uncached */
394  if (CacheAttributes == BlMemoryUncached)
395  {
396  /* Set the flags */
397  Pte->u.Hard.CacheDisable = 1;
398  Pte->u.Hard.WriteThrough = 1;
399  }
400  else if (CacheAttributes == BlMemoryWriteThrough)
401  {
402  /* It's write-through, set the flag */
403  Pte->u.Hard.WriteThrough = 1;
404  }
405  }
406 
407  /* Move to the next physical/virtual address */
408  VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
409  CurrentAddress += PAGE_SIZE;
410  }
411 
412  /* All done! */
413  return STATUS_SUCCESS;
414 }
415 
416 BOOLEAN
418  _In_ PVOID VirtualAddress,
419  _Out_ PPHYSICAL_ADDRESS PhysicalAddress,
420  _Out_opt_ PULONG CacheAttributes
421  )
422 {
423  PMMPDE Pde;
424  PMMPTE Pte;
427 
428  /* Is there no page directory yet? */
429  if (!MmPdpt)
430  {
431  return FALSE;
432  }
433 
434  /* Is paging enabled? */
435  Enabled = BlMmIsTranslationEnabled();
436 
437  /* Check if paging is actually turned on */
438  if (Enabled)
439  {
440  /* Get the PDE entry using the self-map */
441  Pde = MiAddressToPde(VirtualAddress);
442  }
443  else
444  {
445  /* Get it using our physical mappings */
446  Pde = &MmPdpt[MiAddressToPdeOffset(VirtualAddress)];
447  }
448 
449  /* Is the PDE valid? */
450  if (!Pde->u.Hard.Valid)
451  {
452  return FALSE;
453  }
454 
455  /* Check if paging is turned on */
456  if (Enabled)
457  {
458  /* Get the PTE using the self-map */
459  Pte = MiAddressToPte(VirtualAddress);
460  }
461  else
462  {
463  /* Get the PTE using physical addressing */
464  PageTable = (PMMPTE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT);
465  Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)];
466  }
467 
468  /* Is the PTE valid? */
469  if (!Pte->u.Hard.Valid)
470  {
471  return FALSE;
472  }
473 
474  /* Does caller want the physical address? */
475  if (PhysicalAddress)
476  {
477  /* Return it */
478  PhysicalAddress->QuadPart = (Pte->u.Hard.PageFrameNumber << PAGE_SHIFT) +
479  BYTE_OFFSET(VirtualAddress);
480  }
481 
482  /* Does caller want cache attributes? */
483  if (CacheAttributes)
484  {
485  /* Not yet -- lie and say it's cached */
486  EfiPrintf(L"Cache checking not yet enabled\r\n");
487  *CacheAttributes = BlMemoryWriteBack;
488  }
489 
490  /* It exists! */
491  return TRUE;
492 }
493 
494 NTSTATUS
496  _Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr,
497  _Inout_ PVOID* VirtualAddressPtr,
498  _Inout_ PULONGLONG SizePtr,
499  _In_ ULONG CacheAttributes
500  )
501 {
502  ULONGLONG Size;
506  ULONG_PTR CurrentAddress, VirtualAddressEnd;
508 
509  /* Fail if any parameters are missing */
510  if (!(PhysicalAddressPtr) || !(VirtualAddressPtr) || !(SizePtr))
511  {
513  }
514 
515  /* Fail if the size is over 32-bits */
516  Size = *SizePtr;
517  if (Size > 0xFFFFFFFF)
518  {
520  }
521 
522  /* Nothing to do if we're in physical mode */
523  if (MmTranslationType == BlNone)
524  {
525  return STATUS_SUCCESS;
526  }
527 
528  /* Can't use virtual memory in real mode */
530  {
531  return STATUS_UNSUCCESSFUL;
532  }
533 
534  /* Capture the current virtual and physical addresses */
535  VirtualAddress = *VirtualAddressPtr;
536  PhysicalAddress = PhysicalAddressPtr->QuadPart;
537 
538  /* Check if a physical address was requested */
539  if (PhysicalAddress != 0xFFFFFFFF)
540  {
541  /* Round down the base addresses */
542  PhysicalAddress = PAGE_ROUND_DOWN(PhysicalAddress);
543  VirtualAddress = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
544 
545  /* Round up the size */
546  Size = ROUND_TO_PAGES(PhysicalAddressPtr->QuadPart -
547  PhysicalAddress +
548  Size);
549 
550  /* Loop every virtual page */
551  CurrentAddress = (ULONG_PTR)VirtualAddress;
552  VirtualAddressEnd = CurrentAddress + Size - 1;
553  while (CurrentAddress < VirtualAddressEnd)
554  {
555  /* Get the physical page of this virtual page */
556  if (MmArchTranslateVirtualAddress((PVOID)CurrentAddress,
557  &TranslatedAddress,
558  &CacheAttributes))
559  {
560  /* Make sure the physical page of the virtual page, matches our page */
561  if (TranslatedAddress.QuadPart !=
562  (PhysicalAddress +
563  (CurrentAddress - (ULONG_PTR)VirtualAddress)))
564  {
565  /* There is an existing virtual mapping for a different address */
566  EfiPrintf(L"Existing mapping exists: %lx vs %lx\r\n",
567  TranslatedAddress.QuadPart,
568  PhysicalAddress + (CurrentAddress - (ULONG_PTR)VirtualAddress));
569  EfiStall(10000000);
571  }
572  }
573 
574  /* Try the next one */
575  CurrentAddress += PAGE_SIZE;
576  }
577  }
578 
579  /* Aactually do the mapping */
580  TranslatedAddress.QuadPart = PhysicalAddress;
581  Status = Mmx86MapPhysicalAddress(TranslatedAddress,
582  VirtualAddress,
583  Size,
584  CacheAttributes);
585  if (!NT_SUCCESS(Status))
586  {
587  EfiPrintf(L"Failed to map!: %lx\r\n", Status);
588  EfiStall(1000000);
589  return Status;
590  }
591 
592  /* Return aligned/fixed up output parameters */
593  PhysicalAddressPtr->QuadPart = PhysicalAddress;
594  *VirtualAddressPtr = VirtualAddress;
595  *SizePtr = Size;
596 
597  /* Flush the TLB if paging is enabled */
599  {
600  Mmx86FlushTlb();
601  }
602 
603  /* All good! */
604  return STATUS_SUCCESS;
605 }
606 
607 NTSTATUS
609  _In_ PVOID VirtualAddress,
610  _In_ ULONGLONG Size,
611  _In_ PHYSICAL_ADDRESS PhysicalAddress
612  )
613 {
615 
616  /* Make a virtual mapping for this physical address */
617  Status = MmMapPhysicalAddress(&PhysicalAddress, &VirtualAddress, &Size, 0);
618  if (!NT_SUCCESS(Status))
619  {
620  return Status;
621  }
622 
623  /* Nothing else to do if we're not in paging mode */
624  if (MmTranslationType == BlNone)
625  {
626  return STATUS_SUCCESS;
627  }
628 
629  /* Otherwise, remove this region from the list of free virtual ranges */
632  (ULONG_PTR)VirtualAddress >> PAGE_SHIFT,
633  Size >> PAGE_SHIFT,
634  0);
635  if (!NT_SUCCESS(Status))
636  {
637  /* Unmap the address if that failed */
638  MmUnmapVirtualAddress(&VirtualAddress, &Size);
639  }
640 
641  /* Return back to caller */
642  return Status;
643 }
644 
645 VOID
647  _In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList,
648  _In_opt_ ULONG MaxCount
649  )
650 {
651  ULONGLONG EndPage, VirtualEndPage;
653  PLIST_ENTRY NextEntry;
654 
655  /* If no maximum was provided, use essentially infinite */
656  if (MaxCount == 0)
657  {
658  MaxCount = 0xFFFFFFFF;
659  }
660 
661  /* Loop the list as long as there's entries and max isn't reached */
662  NextEntry = DescriptorList->First->Flink;
663  while ((NextEntry != DescriptorList->First) && (MaxCount--))
664  {
665  /* Get the descriptor */
666  MemoryDescriptor = CONTAINING_RECORD(NextEntry,
668  ListEntry);
669 
670  /* Get the descriptor end page, and see if it was virtually mapepd */
671  EndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
672  if (MemoryDescriptor->VirtualPage)
673  {
674  /* Get the virtual end page too, then */
675  VirtualEndPage = MemoryDescriptor->VirtualPage +
676  MemoryDescriptor->PageCount;
677  }
678  else
679  {
680  VirtualEndPage = 0;
681  }
682 
683  /* Print out the descriptor, physical range, virtual range, and type */
684  EfiPrintf(L"%p - [%08llx-%08llx @ %08llx-%08llx]:%x\r\n",
685  MemoryDescriptor,
686  MemoryDescriptor->BasePage << PAGE_SHIFT,
687  (EndPage << PAGE_SHIFT) - 1,
688  MemoryDescriptor->VirtualPage << PAGE_SHIFT,
689  VirtualEndPage ? (VirtualEndPage << PAGE_SHIFT) - 1 : 0,
690  (ULONG)MemoryDescriptor->Type);
691 
692  /* Next entry */
693  NextEntry = NextEntry->Flink;
694  }
695 }
696 
697 NTSTATUS
699  _In_ ULONG Phase,
700  _In_ PBL_MEMORY_DATA MemoryData
701  )
702 {
703  BOOLEAN DoDeferred;
704  ULONG DescriptorCount;
706  ULONG FinalOffset;
708  ULONGLONG Size;
711  BL_MEMORY_DESCRIPTOR_LIST FirmwareMdl;
712  PLIST_ENTRY Head, NextEntry;
713 
714  /* Check which phase this is */
715  if (Phase == 1)
716  {
717  /* In phase 1 we don't initialize deferred mappings */
718  DoDeferred = FALSE;
719  }
720  else
721  {
722  /* Don't do anything if there's nothing to initialize */
724  {
725  return STATUS_SUCCESS;
726  }
727 
728  /* We'll do deferred descriptors in phase 2 */
729  DoDeferred = TRUE;
730  }
731 
732  /*
733  * Because BL supports cross x86-x64 application launches and a LIST_ENTRY
734  * is of variable size, care must be taken here to ensure that we see a
735  * consistent view of descriptors. BL uses some offset magic to figure out
736  * where the data actually starts, since everything is ULONGLONG past the
737  * LIST_ENTRY itself
738  */
739  FinalOffset = MemoryData->MdListOffset + MemoryData->DescriptorOffset;
740  Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)MemoryData + FinalOffset -
742 
743  /* Scan all of them */
744  DescriptorCount = MemoryData->DescriptorCount;
745  while (DescriptorCount != 0)
746  {
747  /* Ignore application data */
748  if (Descriptor->Type != BlApplicationData)
749  {
750  /* If this is a ramdisk, do it in phase 2 */
751  if ((Descriptor->Type == BlLoaderRamDisk) == DoDeferred)
752  {
753  /* Get the current physical address and size */
754  PhysicalAddress.QuadPart = Descriptor->BasePage << PAGE_SHIFT;
755  Size = Descriptor->PageCount << PAGE_SHIFT;
756 
757  /* Check if it was already mapped */
758  if (Descriptor->VirtualPage)
759  {
760  /* Use the existing address */
761  VirtualAddress = (PVOID)(ULONG_PTR)(Descriptor->VirtualPage << PAGE_SHIFT);
762  }
763  else
764  {
765  /* Use the physical address */
766  VirtualAddress = (PVOID)(ULONG_PTR)PhysicalAddress.QuadPart;
767  }
768 
769  /* Crete the mapping */
770  Status = Mmx86MapInitStructure(VirtualAddress,
771  Size,
772  PhysicalAddress);
773  if (!NT_SUCCESS(Status))
774  {
775  return Status;
776  }
777  }
778 
779  /* Check if we're in phase 1 and deferring RAM disk */
780  if ((Phase == 1) && (Descriptor->Type == BlLoaderRamDisk))
781  {
783  }
784  }
785 
786  /* Move on to the next descriptor */
787  DescriptorCount--;
788  Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)Descriptor + MemoryData->DescriptorSize);
789  }
790 
791  /* In phase 1, also do UEFI mappings */
792  if (Phase != 2)
793  {
794  /* Get the memory map */
795  MmMdInitializeListHead(&FirmwareMdl);
796  Status = MmFwGetMemoryMap(&FirmwareMdl, BL_MM_FLAG_REQUEST_COALESCING);
797  if (!NT_SUCCESS(Status))
798  {
799  return Status;
800  }
801 
802  /* Iterate over it */
803  Head = FirmwareMdl.First;
804  NextEntry = Head->Flink;
805  while (NextEntry != Head)
806  {
807  /* Check if this is a UEFI-related descriptor, unless it's the self-map page */
808  Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
809  if (((Descriptor->Type == BlEfiBootMemory) ||
810  (Descriptor->Type == BlEfiRuntimeCodeMemory) ||
811  (Descriptor->Type == BlEfiRuntimeDataMemory) || // WINBUG?
812  (Descriptor->Type == BlLoaderMemory)) &&
813  ((Descriptor->BasePage << PAGE_SHIFT) != Mmx86SelfMapBase.QuadPart))
814  {
815  /* Identity-map it */
816  PhysicalAddress.QuadPart = Descriptor->BasePage << PAGE_SHIFT;
817  Status = Mmx86MapInitStructure((PVOID)((ULONG_PTR)Descriptor->BasePage << PAGE_SHIFT),
818  Descriptor->PageCount << PAGE_SHIFT,
819  PhysicalAddress);
820  if (!NT_SUCCESS(Status))
821  {
822  return Status;
823  }
824  }
825 
826  /* Move to the next descriptor */
827  NextEntry = NextEntry->Flink;
828  }
829 
830  /* Reset */
831  NextEntry = Head->Flink;
832  while (NextEntry != Head)
833  {
834  /* Get the descriptor */
835  Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
836 
837  /* Skip to the next entry before we free */
838  NextEntry = NextEntry->Flink;
839 
840  /* Remove and free it */
841  MmMdRemoveDescriptorFromList(&FirmwareMdl, Descriptor);
842  MmMdFreeDescriptor(Descriptor);
843  }
844  }
845 
846  /* All library mappings identity mapped now */
847  return STATUS_SUCCESS;
848 }
849 
850 NTSTATUS
852  _In_ ULONG Phase,
853  _In_ PBL_MEMORY_DATA MemoryData
854  )
855 {
856  ULONG ImageSize;
857  PVOID ImageBase;
858  KDESCRIPTOR Gdt, Idt;
861 
862  /* If this is phase 2, map the memory regions */
863  if (Phase != 1)
864  {
865  return Mmx86pMapMemoryRegions(Phase, MemoryData);
866  }
867 
868  /* Get the application image base/size */
869  Status = BlGetApplicationBaseAndSize(&ImageBase, &ImageSize);
870  if (!NT_SUCCESS(Status))
871  {
872  return Status;
873  }
874 
875  /* Map the image back at the same place */
876  PhysicalAddress.QuadPart = (ULONG_PTR)ImageBase;
877  Status = Mmx86MapInitStructure(ImageBase, ImageSize, PhysicalAddress);
878  if (!NT_SUCCESS(Status))
879  {
880  return Status;
881  }
882 
883  /* Map the first 4MB of memory */
884  PhysicalAddress.QuadPart = 0;
885  Status = Mmx86MapInitStructure(NULL, 4 * 1024 * 1024, PhysicalAddress);
886  if (!NT_SUCCESS(Status))
887  {
888  return Status;
889  }
890 
891  /* Map the GDT */
892  _sgdt(&Gdt.Limit);
893  PhysicalAddress.QuadPart = Gdt.Base;
894  Status = Mmx86MapInitStructure((PVOID)Gdt.Base, Gdt.Limit + 1, PhysicalAddress);
895  if (!NT_SUCCESS(Status))
896  {
897  return Status;
898  }
899 
900  /* Map the IDT */
901  __sidt(&Idt.Limit);
902  PhysicalAddress.QuadPart = Idt.Base;
903  Status = Mmx86MapInitStructure((PVOID)Idt.Base, Idt.Limit + 1, PhysicalAddress);
904  if (!NT_SUCCESS(Status))
905  {
906  return Status;
907  }
908 
909  /* Map the reference page */
910  PhysicalAddress.QuadPart = (ULONG_PTR)MmArchReferencePage;
913  PhysicalAddress);
914  if (!NT_SUCCESS(Status))
915  {
916  return Status;
917  }
918 
919  /* More to do */
920  return Mmx86pMapMemoryRegions(Phase, MemoryData);
921 }
922 
923 NTSTATUS
925  _In_ PBL_MEMORY_DATA MemoryData,
926  _In_ BL_TRANSLATION_TYPE TranslationType
927  )
928 {
931  ULONG PdeIndex;
932 
933  /* Set the global function pointers for memory translation */
934  Mmx86TranslateVirtualAddress = MmDefpTranslateVirtualAddress;
935  Mmx86MapPhysicalAddress = MmDefpMapPhysicalAddress;
936  Mmx86UnmapVirtualAddress = MmDefpUnmapVirtualAddress;
937  Mmx86RemapVirtualAddress = MmDefpRemapVirtualAddress;
938  Mmx86FlushTlb = MmDefpFlushTlb;
939  Mmx86FlushTlbEntry = MmDefpFlushTlbEntry;
940  Mmx86DestroySelfMap = MmDefpDestroySelfMap;
941 
942  /* Check what mode we're currently in */
943  if (TranslationType == BlVirtual)
944  {
945  EfiPrintf(L"Virtual->Virtual not yet supported\r\n");
946  return STATUS_NOT_IMPLEMENTED;
947  }
948  else if (TranslationType != BlNone)
949  {
950  /* Not even Windows supports PAE->Virtual downgrade */
951  return STATUS_NOT_IMPLEMENTED;
952  }
953 
954  /* The None->Virtual case */
955  MmPdpt = NULL;
956  Mmx86SelfMapBase.QuadPart = 0;
958 
959  /* Truncate all memory above 4GB so that we don't use it */
960  Status = MmPaTruncateMemory(0x100000);
961  if (!NT_SUCCESS(Status))
962  {
963  goto Failure;
964  }
965 
966  /* Allocate a page directory */
967  Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
969  1,
970  0,
971  0,
973  0,
974  0);
975  if (!NT_SUCCESS(Status))
976  {
977  goto Failure;
978  }
979 
980  /* Zero out the page directory */
981  MmPdpt = (PVOID)PhysicalAddress.LowPart;
982  RtlZeroMemory(MmPdpt, PAGE_SIZE);
983 
984  /* Set the page size */
986 
987  /* Allocate the self-map page */
988  Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
990  1,
991  0,
992  0,
994  0,
995  0);
996  if (!NT_SUCCESS(Status))
997  {
998  goto Failure;
999  }
1000 
1001  /* Set the reference page */
1002  MmArchReferencePage = (PVOID)PhysicalAddress.LowPart;
1003 
1004  /* Zero it out */
1006 
1007  /* Allocate 4MB worth of self-map pages */
1008  Status = MmPaReserveSelfMapPages(&Mmx86SelfMapBase,
1009  (4 * 1024 * 1024) >> PAGE_SHIFT,
1010  (4 * 1024 * 1024) >> PAGE_SHIFT);
1011  if (!NT_SUCCESS(Status))
1012  {
1013  goto Failure;
1014  }
1015 
1016  /* Zero them out */
1017  RtlZeroMemory((PVOID)Mmx86SelfMapBase.LowPart, 4 * 1024 * 1024);
1018  EfiPrintf(L"PDPT at 0x%p Reference Page at 0x%p Self-map at 0x%p\r\n",
1019  MmPdpt, MmArchReferencePage, Mmx86SelfMapBase.LowPart);
1020 
1021  /* Align PTE base to 4MB region */
1022  MmPteBase = (PVOID)(Mmx86SelfMapBase.LowPart & ~0x3FFFFF);
1023 
1024  /* The PDE is the PTE of the PTE base */
1026  PdeIndex = MiAddressToPdeOffset(MmPdeBase);
1027  MmPdpt[PdeIndex].u.Hard.Valid = 1;
1028  MmPdpt[PdeIndex].u.Hard.Write = 1;
1029  MmPdpt[PdeIndex].u.Hard.PageFrameNumber = (ULONG_PTR)MmPdpt >> PAGE_SHIFT;
1030  MmArchReferencePage[PdeIndex]++;
1031 
1032  /* Remove PTE_BASE from free virtual memory */
1035  PTE_BASE >> PAGE_SHIFT,
1036  (4 * 1024 * 1024) >> PAGE_SHIFT,
1037  0);
1038  if (!NT_SUCCESS(Status))
1039  {
1040  goto Failure;
1041  }
1042 
1043  /* Remove HAL_HEAP from free virtual memory */
1047  (4 * 1024 * 1024) >> PAGE_SHIFT,
1048  0);
1049  if (!NT_SUCCESS(Status))
1050  {
1051  goto Failure;
1052  }
1053 
1054  /* Initialize the virtual->physical memory mappings */
1055  Status = Mmx86InitializeMemoryMap(1, MemoryData);
1056  if (!NT_SUCCESS(Status))
1057  {
1058  goto Failure;
1059  }
1060 
1061  /* Turn on paging with the new CR3 */
1062  __writecr3((ULONG_PTR)MmPdpt);
1064  EfiPrintf(L"Paging... %d\r\n", BlMmIsTranslationEnabled());
1065 
1066  /* Return success */
1067  return Status;
1068 
1069 Failure:
1070  /* Free reference page if we allocated it */
1071  if (MmArchReferencePage)
1072  {
1073  PhysicalAddress.QuadPart = (ULONG_PTR)MmArchReferencePage;
1074  BlMmFreePhysicalPages(PhysicalAddress);
1075  }
1076 
1077  /* Free page directory if we allocated it */
1078  if (MmPdpt)
1079  {
1080  PhysicalAddress.QuadPart = (ULONG_PTR)MmPdpt;
1081  BlMmFreePhysicalPages(PhysicalAddress);
1082  }
1083 
1084  /* Free the self map if we allocated it */
1085  if (Mmx86SelfMapBase.QuadPart)
1086  {
1087  MmPaReleaseSelfMapPages(Mmx86SelfMapBase);
1088  }
1089 
1090  /* All done */
1091  return Status;
1092 }
1093 
1094 NTSTATUS
1096  _In_ ULONG Phase,
1097  _In_ PBL_MEMORY_DATA MemoryData,
1098  _In_ BL_TRANSLATION_TYPE TranslationType,
1099  _In_ BL_TRANSLATION_TYPE RequestedTranslationType
1100  )
1101 {
1102  NTSTATUS Status;
1103  ULONGLONG IncreaseUserVa, PerfCounter, CpuRandom;
1104  INT CpuInfo[4];
1105 
1106  /* For phase 2, just map deferred regions */
1107  if (Phase != 1)
1108  {
1109  return Mmx86pMapMemoryRegions(2, MemoryData);
1110  }
1111 
1112  /* What translation type are we switching to? */
1113  switch (RequestedTranslationType)
1114  {
1115  /* Physical memory */
1116  case BlNone:
1117 
1118  /* Initialize everything to default/null values */
1119  MmArchLargePageSize = 1;
1120  MmArchKsegBase = 0;
1121  MmArchKsegBias = 0;
1122  MmArchKsegAddressRange.Minimum = 0;
1123  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
1125  Mmx86SelfMapBase.QuadPart = 0;
1126 
1127  /* Set stub functions */
1128  BlMmRelocateSelfMap = MmArchNullFunction;
1129  BlMmFlushTlb = MmArchNullFunction;
1130 
1131  /* Set success */
1132  Status = STATUS_SUCCESS;
1133  break;
1134 
1135  case BlVirtual:
1136 
1137  /* Set the large page size to 1024 pages (4MB) */
1138  MmArchLargePageSize = (4 * 1024 * 1024) / PAGE_SIZE;
1139 
1140  /* Check if /USERVA option was used */
1143  &IncreaseUserVa);
1144  if (NT_SUCCESS(Status) && (IncreaseUserVa))
1145  {
1146  /* Yes -- load the kernel at 0xE0000000 instead */
1147  MmArchKsegBase = 0xE0000000;
1148  }
1149  else
1150  {
1151  /* Nope, load at the standard 2GB split */
1152  MmArchKsegBase = 0x80000000;
1153  }
1154 
1155  /* Check if CPUID 01h is supported */
1156  CpuRandom = 0;
1158  {
1159  /* Call it */
1160  BlArchCpuId(1, 0, CpuInfo);
1161 
1162  /* Check if RDRAND is supported */
1163  if (CpuInfo[2] & 0x40000000)
1164  {
1165  EfiPrintf(L"Your CPU can do RDRAND! Good for you!\r\n");
1166  CpuRandom = 0;
1167  }
1168  }
1169 
1170  /* Read the TSC */
1171  PerfCounter = BlArchGetPerformanceCounter();
1172  PerfCounter >>= 4;
1173  _rotl16(PerfCounter, 5);
1174 
1175  /* Set the address range */
1176  MmArchKsegAddressRange.Minimum = 0;
1177  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
1178 
1179  /* Set the KASLR bias */
1180  MmArchKsegBias = ((PerfCounter ^ CpuRandom) & 0xFFF) << 12;
1181  MmArchKsegBias = 0;
1183 
1184  /* Set the kernel range */
1185  MmArchKsegAddressRange.Minimum = MmArchKsegBase;
1186  MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
1187 
1188  /* Set the boot application top maximum */
1189  MmArchTopOfApplicationAddressSpace = 0x70000000 - 1; // Windows bug
1190 
1191  /* Initialize virtual address space translation */
1192  Status = MmDefInitializeTranslation(MemoryData, TranslationType);
1193  if (NT_SUCCESS(Status))
1194  {
1195  /* Set stub functions */
1196  BlMmRelocateSelfMap = MmDefRelocateSelfMap;
1197  BlMmFlushTlb = Mmx86FlushTlb;
1198  BlMmMoveVirtualAddressRange = MmDefMoveVirtualAddressRange;
1199  BlMmZeroVirtualAddressRange = MmDefZeroVirtualAddressRange;
1200  }
1201  break;
1202 
1203  case BlPae:
1204 
1205  /* We don't support PAE */
1206  Status = STATUS_NOT_SUPPORTED;
1207  break;
1208 
1209  default:
1210 
1211  /* Invalid architecture type*/
1212  Status = STATUS_INVALID_PARAMETER;
1213  break;
1214  }
1215 
1216  /* Back to caller */
1217  return Status;
1218 }
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
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
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
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:495
_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:1003
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
Definition: bidi.c:75
FORCEINLINE VOID MmMdInitializeListHead(_In_ PBL_MEMORY_DESCRIPTOR_LIST List)
Definition: bl.h:1299
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
return STATUS_SUCCESS
Definition: btrfs.c:2664
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:453
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: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:698
_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
#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:930
USHORT Limit
Definition: ketypes.h:485
ULONG ContextFlags
Definition: bl.h:924
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:766
#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:1813
struct _BL_MEMORY_DESCRIPTOR * PBL_MEMORY_DESCRIPTOR
PBL_BCD_OPTION BcdData
Definition: bl.h:792
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:438
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:646
smooth NULL
Definition: ftsmooth.c:513
struct _MMPTE * PMMPDE
Definition: bl.h:240
#define _Out_
Definition: no_sal2.h:323
ULONGLONG PageCount
Definition: bl.h:764
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:856
NTSTATUS MmDefpMapPhysicalAddress(_In_ PHYSICAL_ADDRESS PhysicalAddress, _In_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes)
Definition: mmx86.c:265
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: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:1095
ULONGLONG Maximum
Definition: bl.h:938
NTSTATUS MmFwGetMemoryMap(_Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap, _In_ ULONG Flags)
Definition: firmware.c:1845
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:1505
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: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
static PEMS_PAGE PageTable
Definition: emsdrv.c:39
#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:82
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:937
__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:1049
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONGLONG BasePage
Definition: bl.h:755
#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)
#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:902
BOOLEAN MmDefpTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress, _Out_opt_ PULONG CacheAttributes)
Definition: mmx86.c:417
PMMPTE MmPdpt
Definition: mmx86.c:33
NTSTATUS MmDefInitializeTranslation(_In_ PBL_MEMORY_DATA MemoryData, _In_ BL_TRANSLATION_TYPE TranslationType)
Definition: mmx86.c:924
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1758
#define BOOLEAN
Definition: pedump.c:73
union _MMPTE::@2087 u
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:382
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:922
_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:608
VOID BlArchCpuId(_In_ ULONG Function, _In_ ULONG SubFunction, _Out_ INT *Result)
Definition: util.c:924
ULONGLONG VirtualPage
Definition: bl.h:756
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:851
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