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)
9 /* INCLUDES ******************************************************************/
13 #include "../../../../../ntoskrnl/include/internal/i386/mm.h"
15 /* DATA VARIABLES ************************************************************/
17 ULONG_PTR MmArchKsegBase
;
18 ULONG_PTR MmArchKsegBias
;
19 ULONG MmArchLargePageSize
;
20 BL_ADDRESS_RANGE MmArchKsegAddressRange
;
21 ULONG_PTR MmArchTopOfApplicationAddressSpace
;
22 PHYSICAL_ADDRESS Mmx86SelfMapBase
;
23 ULONG MmDeferredMappingCount
;
25 PULONG MmArchReferencePage
;
28 ULONG MmArchReferencePageSize
;
36 (*PBL_MM_RELOCATE_SELF_MAP
) (
41 (*PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE
) (
42 _In_ PVOID DestinationAddress
,
43 _In_ PVOID SourceAddress
,
48 (*PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE
) (
49 _In_ PVOID DestinationAddress
,
54 (*PBL_MM_DESTROY_SELF_MAP
) (
59 (*PBL_MM_FLUSH_TLB_ENTRY
) (
60 _In_ PVOID VirtualAddress
69 (*PBL_MM_UNMAP_VIRTUAL_ADDRESS
) (
70 _In_ PVOID VirtualAddress
,
75 (*PBL_MM_REMAP_VIRTUAL_ADDRESS
) (
76 _In_ PPHYSICAL_ADDRESS PhysicalAddress
,
77 _Out_ PVOID VirtualAddress
,
79 _In_ ULONG CacheAttributes
83 (*PBL_MM_MAP_PHYSICAL_ADDRESS
) (
84 _In_ PPHYSICAL_ADDRESS PhysicalAddress
,
85 _Out_ PVOID VirtualAddress
,
87 _In_ ULONG CacheAttributes
91 (*PBL_MM_TRANSLATE_VIRTUAL_ADDRESS
) (
92 _In_ PVOID VirtualAddress
,
93 _Out_ PPHYSICAL_ADDRESS PhysicalAddress
,
94 _Out_opt_ PULONG CacheAttributes
97 PBL_MM_TRANSLATE_VIRTUAL_ADDRESS Mmx86TranslateVirtualAddress
;
98 PBL_MM_MAP_PHYSICAL_ADDRESS Mmx86MapPhysicalAddress
;
99 PBL_MM_REMAP_VIRTUAL_ADDRESS Mmx86RemapVirtualAddress
;
100 PBL_MM_UNMAP_VIRTUAL_ADDRESS Mmx86UnmapVirtualAddress
;
101 PBL_MM_FLUSH_TLB Mmx86FlushTlb
;
102 PBL_MM_FLUSH_TLB_ENTRY Mmx86FlushTlbEntry
;
103 PBL_MM_DESTROY_SELF_MAP Mmx86DestroySelfMap
;
105 PBL_MM_RELOCATE_SELF_MAP BlMmRelocateSelfMap
;
106 PBL_MM_FLUSH_TLB BlMmFlushTlb
;
107 PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE BlMmMoveVirtualAddressRange
;
108 PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE BlMmZeroVirtualAddressRange
;
110 PBL_MM_FLUSH_TLB Mmx86FlushTlb
;
112 /* FUNCTIONS *****************************************************************/
124 MmDefRelocateSelfMap (
128 if (MmPteBase
!= (PVOID
)PTE_BASE
)
130 EfiPrintf(L
"Supposed to relocate CR3\r\n");
135 MmDefMoveVirtualAddressRange (
136 _In_ PVOID DestinationAddress
,
137 _In_ PVOID SourceAddress
,
141 EfiPrintf(L
"Supposed to move shit\r\n");
142 return STATUS_NOT_IMPLEMENTED
;
146 MmDefZeroVirtualAddressRange (
147 _In_ PVOID DestinationAddress
,
151 EfiPrintf(L
"Supposed to zero shit\r\n");
152 return STATUS_NOT_IMPLEMENTED
;
156 Mmx86pMapMemoryRegions (
158 _In_ PBL_MEMORY_DATA MemoryData
163 /* In phase 1 we don't initialize deferred mappings*/
170 /* Don't do anything if there's nothing to initialize */
171 if (!MmDeferredMappingCount
)
173 return STATUS_SUCCESS
;
181 EfiPrintf(L
"Deferred todo\r\n");
184 EfiPrintf(L
"Phase 1 TODO\r\n");
185 return STATUS_NOT_IMPLEMENTED
;
189 MmArchTranslateVirtualAddress (
190 _In_ PVOID VirtualAddress
,
191 _Out_opt_ PPHYSICAL_ADDRESS PhysicalAddress
,
192 _Out_opt_ PULONG CachingFlags
195 PBL_MEMORY_DESCRIPTOR Descriptor
;
197 /* Check if paging is on */
198 if ((CurrentExecutionContext
) &&
199 (CurrentExecutionContext
->ContextFlags
& BL_CONTEXT_PAGING_ON
))
201 /* Yes -- we have to translate this from virtual */
202 return Mmx86TranslateVirtualAddress(VirtualAddress
,
207 /* Look in all descriptors except truncated and firmware ones */
208 Descriptor
= MmMdFindDescriptor(BL_MM_INCLUDE_NO_FIRMWARE_MEMORY
&
209 ~BL_MM_INCLUDE_TRUNCATED_MEMORY
,
210 BL_MM_REMOVE_PHYSICAL_REGION_FLAG
,
211 (ULONG_PTR
)VirtualAddress
>> PAGE_SHIFT
);
213 /* Return the virtual address as the physical address */
216 PhysicalAddress
->HighPart
= 0;
217 PhysicalAddress
->LowPart
= (ULONG_PTR
)VirtualAddress
;
220 /* There's no caching on physical memory */
226 /* Success is if we found a descriptor */
227 return Descriptor
!= NULL
;
231 MmDefpDestroySelfMap (
235 EfiPrintf(L
"No destroy\r\n");
239 MmDefpFlushTlbEntry (
240 _In_ PVOID VirtualAddress
244 __invlpg(VirtualAddress
);
253 __writecr3(__readcr3());
257 MmDefpUnmapVirtualAddress (
258 _In_ PVOID VirtualAddress
,
262 EfiPrintf(L
"No unmap\r\n");
263 return STATUS_NOT_IMPLEMENTED
;
267 MmDefpRemapVirtualAddress (
268 _In_ PPHYSICAL_ADDRESS PhysicalAddress
,
269 _Out_ PVOID VirtualAddress
,
271 _In_ ULONG CacheAttributes
274 EfiPrintf(L
"No remap\r\n");
275 return STATUS_NOT_IMPLEMENTED
;
279 MmDefpMapPhysicalAddress (
280 _In_ PPHYSICAL_ADDRESS PhysicalAddress
,
281 _Out_ PVOID VirtualAddress
,
283 _In_ ULONG CacheAttributes
286 EfiPrintf(L
"No map\r\n");
287 return STATUS_NOT_IMPLEMENTED
;
291 MmDefpTranslateVirtualAddress (
292 _In_ PVOID VirtualAddress
,
293 _Out_ PPHYSICAL_ADDRESS PhysicalAddress
,
294 _Out_opt_ PULONG CacheAttributes
297 EfiPrintf(L
"No translate\r\n");
302 MmSelectMappingAddress (
303 _Out_ PVOID
* MappingAddress
,
305 _In_ ULONG AllocationAttributes
,
307 _In_ PHYSICAL_ADDRESS PhysicalAddress
310 /* Are we in physical mode? */
311 if (MmTranslationType
== BlNone
)
313 /* Just return the physical address as the mapping address */
314 *MappingAddress
= (PVOID
)PhysicalAddress
.LowPart
;
315 return STATUS_SUCCESS
;
318 /* We don't support virtual memory yet @TODO */
319 #ifdef _MSC_VER // Fuck gcc.
320 EfiPrintf(L
"not yet implemented in " __FUNCTION__
"\r\n");
323 return STATUS_NOT_IMPLEMENTED
;
327 BlMmIsTranslationEnabled (
331 /* Return if paging is on */
332 return ((CurrentExecutionContext
) &&
333 (CurrentExecutionContext
->Mode
& BL_CONTEXT_PAGING_ON
));
337 MmMapPhysicalAddress (
338 _Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr
,
339 _Inout_ PVOID
* VirtualAddressPtr
,
340 _Inout_ PULONGLONG SizePtr
,
341 _In_ ULONG CacheAttributes
344 ULONGLONG Size
, TotalSize
;
345 ULONGLONG PhysicalAddress
;
346 PVOID VirtualAddress
;
347 PHYSICAL_ADDRESS TranslatedAddress
;
348 ULONG_PTR CurrentAddress
, VirtualAddressEnd
;
351 /* Fail if any parameters are missing */
352 if (!(PhysicalAddressPtr
) || !(VirtualAddressPtr
) || !(SizePtr
))
354 return STATUS_INVALID_PARAMETER
;
357 /* Fail if the size is over 32-bits */
359 if (Size
> 0xFFFFFFFF)
361 return STATUS_INVALID_PARAMETER
;
364 /* Nothing to do if we're in physical mode */
365 if (MmTranslationType
== BlNone
)
367 return STATUS_SUCCESS
;
370 /* Can't use virtual memory in real mode */
371 if (CurrentExecutionContext
->Mode
== BlRealMode
)
373 return STATUS_UNSUCCESSFUL
;
376 /* Capture the current virtual and physical addresses */
377 VirtualAddress
= *VirtualAddressPtr
;
378 PhysicalAddress
= PhysicalAddressPtr
->QuadPart
;
380 /* Check if a physical address was requested */
381 if (PhysicalAddress
!= 0xFFFFFFFF)
383 /* Round down the base addresses */
384 PhysicalAddress
= PAGE_ROUND_DOWN(PhysicalAddress
);
385 VirtualAddress
= (PVOID
)PAGE_ROUND_DOWN(VirtualAddress
);
387 /* Round up the size */
388 TotalSize
= ROUND_TO_PAGES(PhysicalAddressPtr
->QuadPart
-
392 /* Loop every virtual page */
393 CurrentAddress
= (ULONG_PTR
)VirtualAddress
;
394 VirtualAddressEnd
= CurrentAddress
+ TotalSize
- 1;
395 while (CurrentAddress
< VirtualAddressEnd
)
397 /* Get the physical page of this virtual page */
398 if (MmArchTranslateVirtualAddress((PVOID
)CurrentAddress
,
402 /* Make sure the physical page of the virtual page, matches our page */
403 if (TranslatedAddress
.QuadPart
!=
405 (CurrentAddress
- (ULONG_PTR
)VirtualAddress
)))
407 /* There is an existing virtual mapping for a different address */
408 EfiPrintf(L
"Existing mapping exists: %lx vs %lx\r\n",
409 TranslatedAddress
.QuadPart
,
410 PhysicalAddress
+ (CurrentAddress
- (ULONG_PTR
)VirtualAddress
));
411 return STATUS_INVALID_PARAMETER
;
415 /* Try the next one */
416 CurrentAddress
+= PAGE_SIZE
;
420 /* Aactually do the mapping */
421 TranslatedAddress
.QuadPart
= PhysicalAddress
;
422 Status
= Mmx86MapPhysicalAddress(&TranslatedAddress
,
426 if (!NT_SUCCESS(Status
))
428 EfiPrintf(L
"Failed to map!: %lx\r\n", Status
);
432 /* Return aligned/fixed up output parameters */
433 PhysicalAddressPtr
->QuadPart
= PhysicalAddress
;
434 *VirtualAddressPtr
= VirtualAddress
;
437 /* Flush the TLB if paging is enabled */
438 if (BlMmIsTranslationEnabled())
444 return STATUS_SUCCESS
;
448 Mmx86MapInitStructure (
449 _In_ PVOID VirtualAddress
,
451 _In_ PHYSICAL_ADDRESS PhysicalAddress
456 /* Make a virtual mapping for this physical address */
457 Status
= MmMapPhysicalAddress(&PhysicalAddress
, &VirtualAddress
, &Size
, 0);
458 if (!NT_SUCCESS(Status
))
463 /* Nothing else to do if we're not in paging mode */
464 if (MmTranslationType
== BlNone
)
466 return STATUS_SUCCESS
;
469 /* Otherwise, remove this region from the list of free virtual ranges */
470 Status
= MmMdRemoveRegionFromMdlEx(&MmMdlFreeVirtual
,
471 BL_MM_REMOVE_VIRTUAL_REGION_FLAG
,
472 (ULONG_PTR
)VirtualAddress
>> PAGE_SHIFT
,
475 if (!NT_SUCCESS(Status
))
477 /* Unmap the address if that failed */
478 MmUnmapVirtualAddress(&VirtualAddress
, &Size
);
481 /* Return back to caller */
486 Mmx86InitializeMemoryMap (
488 _In_ PBL_MEMORY_DATA MemoryData
493 KDESCRIPTOR Gdt
, Idt
;
495 PHYSICAL_ADDRESS PhysicalAddress
;
497 /* If this is phase 2, map the memory regions */
500 return Mmx86pMapMemoryRegions(Phase
, MemoryData
);
503 /* Get the application image base/size */
504 Status
= BlGetApplicationBaseAndSize(&ImageBase
, &ImageSize
);
505 if (!NT_SUCCESS(Status
))
510 /* Map the image back at the same place */
511 PhysicalAddress
.QuadPart
= (ULONG_PTR
)ImageBase
;
512 Status
= Mmx86MapInitStructure(ImageBase
, ImageSize
, PhysicalAddress
);
513 if (!NT_SUCCESS(Status
))
518 /* Map the first 4MB of memory */
519 PhysicalAddress
.QuadPart
= 0;
520 Status
= Mmx86MapInitStructure(NULL
, 4 * 1024 * 1024, PhysicalAddress
);
521 if (!NT_SUCCESS(Status
))
528 PhysicalAddress
.QuadPart
= Gdt
.Base
;
529 Status
= Mmx86MapInitStructure((PVOID
)Gdt
.Base
, Gdt
.Limit
+ 1, PhysicalAddress
);
530 if (!NT_SUCCESS(Status
))
537 PhysicalAddress
.QuadPart
= Idt
.Base
;
538 Status
= Mmx86MapInitStructure((PVOID
)Idt
.Base
, Idt
.Limit
+ 1, PhysicalAddress
);
539 if (!NT_SUCCESS(Status
))
544 /* Map the reference page */
545 PhysicalAddress
.QuadPart
= (ULONG_PTR
)MmArchReferencePage
;
546 Status
= Mmx86MapInitStructure(MmArchReferencePage
,
547 MmArchReferencePageSize
,
549 if (!NT_SUCCESS(Status
))
555 EfiPrintf(L
"VM more work\r\n");
556 return STATUS_NOT_IMPLEMENTED
;
560 MmDefInitializeTranslation (
561 _In_ PBL_MEMORY_DATA MemoryData
,
562 _In_ BL_TRANSLATION_TYPE TranslationType
566 PHYSICAL_ADDRESS PhysicalAddress
;
569 /* Set the global function pointers for memory translation */
570 Mmx86TranslateVirtualAddress
= MmDefpTranslateVirtualAddress
;
571 Mmx86MapPhysicalAddress
= MmDefpMapPhysicalAddress
;
572 Mmx86UnmapVirtualAddress
= MmDefpUnmapVirtualAddress
;
573 Mmx86RemapVirtualAddress
= MmDefpRemapVirtualAddress
;
574 Mmx86FlushTlb
= MmDefpFlushTlb
;
575 Mmx86FlushTlbEntry
= MmDefpFlushTlbEntry
;
576 Mmx86DestroySelfMap
= MmDefpDestroySelfMap
;
578 /* Check what mode we're currently in */
579 if (TranslationType
== BlVirtual
)
581 EfiPrintf(L
"Virtual->Virtual not yet supported\r\n");
582 return STATUS_NOT_IMPLEMENTED
;
584 else if (TranslationType
!= BlNone
)
586 /* Not even Windows supports PAE->Virtual downgrade */
587 return STATUS_NOT_IMPLEMENTED
;
590 /* The None->Virtual case */
592 Mmx86SelfMapBase
.QuadPart
= 0;
593 MmArchReferencePage
= NULL
;
595 /* Truncate all memory above 4GB so that we don't use it @TODO: FIXME */
596 EfiPrintf(L
"Warning: not truncating > 4GB memory. Don't boot with more than 4GB of RAM!\r\n");
597 //Status = MmPaTruncateMemory(0x100000);
598 Status
= STATUS_SUCCESS
;
599 if (!NT_SUCCESS(Status
))
604 /* Allocate a page directory */
605 Status
= MmPapAllocatePhysicalPagesInRange(&PhysicalAddress
,
606 BlLoaderPageDirectory
,
610 &MmMdlUnmappedAllocated
,
613 if (!NT_SUCCESS(Status
))
618 /* Zero out the page directory */
619 MmPdpt
= (PVOID
)PhysicalAddress
.LowPart
;
620 RtlZeroMemory(MmPdpt
, PAGE_SIZE
);
622 /* Set the page size */
623 MmArchReferencePageSize
= PAGE_SIZE
;
625 /* Allocate the self-map page */
626 Status
= MmPapAllocatePhysicalPagesInRange(&PhysicalAddress
,
627 BlLoaderReferencePage
,
631 &MmMdlUnmappedAllocated
,
634 if (!NT_SUCCESS(Status
))
639 /* Set the reference page */
640 MmArchReferencePage
= (PVOID
)PhysicalAddress
.LowPart
;
643 RtlZeroMemory(MmArchReferencePage
, MmArchReferencePageSize
);
645 /* Allocate 4MB worth of self-map pages */
646 Status
= MmPaReserveSelfMapPages(&Mmx86SelfMapBase
,
647 (4 * 1024 * 1024) >> PAGE_SHIFT
,
648 (4 * 1024 * 1024) >> PAGE_SHIFT
);
649 if (!NT_SUCCESS(Status
))
655 RtlZeroMemory((PVOID
)Mmx86SelfMapBase
.LowPart
, 4 * 1024 * 1024);
656 EfiPrintf(L
"PDPT at 0x%p Reference Page at 0x%p Self-map at 0x%p\r\n",
657 MmPdpt
, MmArchReferencePage
, Mmx86SelfMapBase
.LowPart
);
659 /* Align PTE base to 4MB region */
660 MmPteBase
= (PVOID
)(Mmx86SelfMapBase
.LowPart
& ~0x3FFFFF);
662 /* The PDE is the PTE of the PTE base */
663 MmPdeBase
= MiAddressToPte(MmPteBase
);
664 PdeIndex
= MiGetPdeOffset(MmPdeBase
);
665 MmPdpt
[PdeIndex
].u
.Hard
.Valid
= 1;
666 MmPdpt
[PdeIndex
].u
.Hard
.Write
= 1;
667 MmPdpt
[PdeIndex
].u
.Hard
.PageFrameNumber
= (ULONG_PTR
)MmPdpt
>> PAGE_SHIFT
;
668 MmArchReferencePage
[PdeIndex
]++;
670 /* Remove PTE_BASE from free virtual memory */
671 Status
= MmMdRemoveRegionFromMdlEx(&MmMdlFreeVirtual
,
672 BL_MM_REMOVE_VIRTUAL_REGION_FLAG
,
673 PTE_BASE
>> PAGE_SHIFT
,
674 (4 * 1024 * 1024) >> PAGE_SHIFT
,
676 if (!NT_SUCCESS(Status
))
681 /* Remove HAL_HEAP from free virtual memory */
682 Status
= MmMdRemoveRegionFromMdlEx(&MmMdlFreeVirtual
,
683 BL_MM_REMOVE_VIRTUAL_REGION_FLAG
,
684 MM_HAL_VA_START
>> PAGE_SHIFT
,
685 (4 * 1024 * 1024) >> PAGE_SHIFT
,
687 if (!NT_SUCCESS(Status
))
692 /* Initialize the virtual->physical memory mappings */
693 Status
= Mmx86InitializeMemoryMap(1, MemoryData
);
694 if (!NT_SUCCESS(Status
))
699 EfiPrintf(L
"Ready to turn on motherfucking paging, brah!\r\n");
700 Status
= STATUS_NOT_IMPLEMENTED
;
703 /* Free reference page if we allocated it */
704 if (MmArchReferencePage
)
706 PhysicalAddress
.QuadPart
= (ULONG_PTR
)MmArchReferencePage
;
707 BlMmFreePhysicalPages(PhysicalAddress
);
710 /* Free page directory if we allocated it */
713 PhysicalAddress
.QuadPart
= (ULONG_PTR
)MmPdpt
;
714 BlMmFreePhysicalPages(PhysicalAddress
);
717 /* Free the self map if we allocated it */
718 if (Mmx86SelfMapBase
.QuadPart
)
720 MmPaReleaseSelfMapPages(Mmx86SelfMapBase
);
730 _In_ PBL_MEMORY_DATA MemoryData
,
731 _In_ BL_TRANSLATION_TYPE TranslationType
,
732 _In_ BL_TRANSLATION_TYPE RequestedTranslationType
736 ULONGLONG IncreaseUserVa
, PerfCounter
, CpuRandom
;
739 /* For phase 2, just map deferred regions */
742 return Mmx86pMapMemoryRegions(2, MemoryData
);
745 /* What translation type are we switching to? */
746 switch (RequestedTranslationType
)
748 /* Physical memory */
751 /* Initialize everything to default/null values */
752 MmArchLargePageSize
= 1;
755 MmArchKsegAddressRange
.Minimum
= 0;
756 MmArchKsegAddressRange
.Maximum
= (ULONGLONG
)~0;
757 MmArchTopOfApplicationAddressSpace
= 0;
758 Mmx86SelfMapBase
.QuadPart
= 0;
760 /* Set stub functions */
761 BlMmRelocateSelfMap
= MmArchNullFunction
;
762 BlMmFlushTlb
= MmArchNullFunction
;
765 Status
= STATUS_SUCCESS
;
770 /* Set the large page size to 1024 pages (4MB) */
771 MmArchLargePageSize
= (4 * 1024 * 1024) / PAGE_SIZE
;
773 /* Check if /USERVA option was used */
774 Status
= BlGetBootOptionInteger(BlpApplicationEntry
.BcdData
,
775 BcdOSLoaderInteger_IncreaseUserVa
,
777 if (NT_SUCCESS(Status
) && (IncreaseUserVa
))
779 /* Yes -- load the kernel at 0xE0000000 instead */
780 MmArchKsegBase
= 0xE0000000;
784 /* Nope, load at the standard 2GB split */
785 MmArchKsegBase
= 0x80000000;
788 /* Check if CPUID 01h is supported */
790 if (BlArchIsCpuIdFunctionSupported(1))
793 BlArchCpuId(1, 0, CpuInfo
);
795 /* Check if RDRAND is supported */
796 if (CpuInfo
[2] & 0x40000000)
798 EfiPrintf(L
"Your CPU can do RDRAND! Good for you!\r\n");
804 PerfCounter
= BlArchGetPerformanceCounter();
806 _rotl16(PerfCounter
, 5);
808 /* Set the address range */
809 MmArchKsegAddressRange
.Minimum
= 0;
810 MmArchKsegAddressRange
.Maximum
= (ULONGLONG
)~0;
812 /* Set the KASLR bias */
813 MmArchKsegBias
= ((PerfCounter
^ CpuRandom
) & 0xFFF) << 12;
815 MmArchKsegBase
+= MmArchKsegBias
;
817 /* Set the kernel range */
818 MmArchKsegAddressRange
.Minimum
= MmArchKsegBase
;
819 MmArchKsegAddressRange
.Maximum
= (ULONGLONG
)~0;
821 /* Set the boot application top maximum */
822 MmArchTopOfApplicationAddressSpace
= 0x70000000;
824 /* Initialize virtual address space translation */
825 Status
= MmDefInitializeTranslation(MemoryData
, TranslationType
);
826 if (NT_SUCCESS(Status
))
828 /* Set stub functions */
829 BlMmRelocateSelfMap
= MmDefRelocateSelfMap
;
830 BlMmFlushTlb
= Mmx86FlushTlb
;
831 BlMmMoveVirtualAddressRange
= MmDefMoveVirtualAddressRange
;
832 BlMmZeroVirtualAddressRange
= MmDefZeroVirtualAddressRange
;
838 Status
= STATUS_NOT_SUPPORTED
;
842 Status
= STATUS_INVALID_PARAMETER
;