2010-03-31 15:11:20 +00:00
/*
2015-05-05 20:35:27 +00:00
* kernel internal memory management definitions for amd64
2010-03-31 15:11:20 +00:00
*/
# pragma once
2019-01-18 21:11:43 +00:00
# define _MI_PAGING_LEVELS 4
# define _MI_HAS_NO_EXECUTE 1
2015-05-05 20:35:27 +00:00
2018-01-28 16:45:41 +00:00
/* Memory layout base addresses (This is based on Vista!) */
2011-09-24 08:52:26 +00:00
# define MI_USER_PROBE_ADDRESS (PVOID)0x000007FFFFFF0000ULL
# define MI_DEFAULT_SYSTEM_RANGE_START (PVOID)0xFFFF080000000000ULL
2012-02-04 10:40:27 +00:00
# define MI_REAL_SYSTEM_RANGE_START 0xFFFF800000000000ULL
2018-01-28 16:45:41 +00:00
//#define MI_PAGE_TABLE_BASE 0xFFFFF68000000000ULL // 512 GB page tables
# define HYPER_SPACE 0xFFFFF70000000000ULL // 512 GB hyper space [MiVaProcessSpace]
2010-03-31 15:11:20 +00:00
# define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL
2018-01-28 16:45:41 +00:00
//#define MI_SHARED_SYSTEM_PAGE 0xFFFFF78000000000ULL
# define MI_SYSTEM_CACHE_WS_START 0xFFFFF78000001000ULL // 512 GB - 4 KB system cache working set
//#define MI_LOADER_MAPPINGS 0xFFFFF80000000000ULL // 512 GB loader mappings aka KSEG0_BASE (NDK) [MiVaBootLoaded]
# define MM_SYSTEM_SPACE_START 0xFFFFF88000000000ULL // 128 GB system PTEs [MiVaSystemPtes]
# define MI_DEBUG_MAPPING (PVOID)0xFFFFF89FFFFFF000ULL // FIXME should be allocated from System PTEs
# define MI_PAGED_POOL_START (PVOID)0xFFFFF8A000000000ULL // 128 GB paged pool [MiVaPagedPool]
//#define MI_PAGED_POOL_END 0xFFFFF8BFFFFFFFFFULL
//#define MI_SESSION_SPACE_START 0xFFFFF90000000000ULL // 512 GB session space [MiVaSessionSpace]
2012-02-04 10:40:27 +00:00
# define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL
# define MI_SESSION_SPACE_END 0xFFFFF97FFFFFFFFFULL
2018-01-28 16:45:41 +00:00
# define MI_SYSTEM_CACHE_START 0xFFFFF98000000000ULL // 1 TB system cache (on Vista+ this is dynamic VA space) [MiVaSystemCache,MiVaSpecialPoolPaged,MiVaSpecialPoolNonPaged]
# define MI_SYSTEM_CACHE_END 0xFFFFFA7FFFFFFFFFULL
# define MI_PFN_DATABASE 0xFFFFFA8000000000ULL // up to 5.5 TB PFN database followed by non paged pool [MiVaPfnDatabase/MiVaNonPagedPool]
2015-05-05 20:35:27 +00:00
# define MI_NONPAGED_POOL_END (PVOID)0xFFFFFFFFFFBFFFFFULL
2018-01-28 16:45:41 +00:00
//#define MM_HAL_VA_START 0xFFFFFFFFFFC00000ULL // 4 MB HAL mappings, defined in NDK [MiVaHal]
2010-03-31 15:11:20 +00:00
# define MI_HIGHEST_SYSTEM_ADDRESS (PVOID)0xFFFFFFFFFFFFFFFFULL
2015-05-05 20:36:07 +00:00
# define MmSystemRangeStart ((PVOID)MI_REAL_SYSTEM_RANGE_START)
2010-03-31 15:11:20 +00:00
2012-02-04 10:40:27 +00:00
/* WOW64 address definitions */
2011-09-24 14:22:13 +00:00
# define MM_HIGHEST_USER_ADDRESS_WOW64 0x7FFEFFFF
# define MM_SYSTEM_RANGE_START_WOW64 0x80000000
2015-05-05 20:36:07 +00:00
/* Misc address definitions */
//#define MI_NON_PAGED_SYSTEM_START_MIN MM_SYSTEM_SPACE_START // FIXME
//#define MI_SYSTEM_PTE_START MM_SYSTEM_SPACE_START
//#define MI_SYSTEM_PTE_END (MI_SYSTEM_PTE_START + MI_NUMBER_SYSTEM_PTES * PAGE_SIZE - 1)
2010-07-22 23:22:57 +00:00
# define MI_SYSTEM_PTE_BASE (PVOID)MiAddressToPte(KSEG0_BASE)
2011-09-24 14:22:13 +00:00
# define MM_HIGHEST_VAD_ADDRESS (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
2012-02-04 10:40:27 +00:00
# define MI_MAPPING_RANGE_START HYPER_SPACE
2011-09-24 14:22:13 +00:00
# define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + MI_HYPERSPACE_PTES * PAGE_SIZE)
2012-02-04 10:40:27 +00:00
# define MI_DUMMY_PTE (MI_MAPPING_RANGE_END + PAGE_SIZE)
# define MI_VAD_BITMAP (MI_DUMMY_PTE + PAGE_SIZE)
# define MI_WORKING_SET_LIST (MI_VAD_BITMAP + PAGE_SIZE)
2010-07-22 23:22:57 +00:00
2010-03-31 15:11:20 +00:00
/* Memory sizes */
2015-05-05 20:36:07 +00:00
# define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255 * _1MB) >> PAGE_SHIFT)
# define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19 * _1MB) >> PAGE_SHIFT)
# define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32 * _1MB) >> PAGE_SHIFT)
# define MI_MIN_PAGES_FOR_SYSPTE_BOOST_BOOST ((256 * _1MB) >> PAGE_SHIFT)
# define MI_MIN_INIT_PAGED_POOLSIZE (32 * _1MB)
# define MI_MAX_INIT_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024)
# define MI_MAX_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024)
# define MI_SYSTEM_VIEW_SIZE (16 * _1MB)
# define MI_SESSION_VIEW_SIZE (20 * _1MB)
# define MI_SESSION_POOL_SIZE (16 * _1MB)
# define MI_SESSION_IMAGE_SIZE (8 * _1MB)
# define MI_SESSION_WORKING_SET_SIZE (4 * _1MB)
# define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \
MI_SESSION_POOL_SIZE + \
MI_SESSION_IMAGE_SIZE + \
MI_SESSION_WORKING_SET_SIZE )
# define MI_MIN_ALLOCATION_FRAGMENT (4 * _1KB)
# define MI_ALLOCATION_FRAGMENT (64 * _1KB)
# define MI_MAX_ALLOCATION_FRAGMENT (2 * _1MB)
2012-02-04 10:40:27 +00:00
2011-09-24 14:22:13 +00:00
/* Misc constants */
2015-05-05 20:36:07 +00:00
# define MM_PTE_SOFTWARE_PROTECTION_BITS 5
# define MI_MIN_SECONDARY_COLORS 8
# define MI_SECONDARY_COLORS 64
# define MI_MAX_SECONDARY_COLORS 1024
# define MI_NUMBER_SYSTEM_PTES 22000
# define MI_MAX_FREE_PAGE_LISTS 4
# define MI_HYPERSPACE_PTES (256 - 1)
# define MI_ZERO_PTES (32)
# define MI_MAX_ZERO_BITS 53
# define SESSION_POOL_LOOKASIDES 21
2012-02-04 10:40:27 +00:00
2011-09-26 21:57:40 +00:00
/* MMPTE related defines */
# define MM_EMPTY_PTE_LIST ((ULONG64)0xFFFFFFFF)
# define MM_EMPTY_LIST ((ULONG_PTR)-1)
2011-09-24 14:22:13 +00:00
/* Easy accessing PFN in PTE */
# define PFN_FROM_PTE(v) ((v)->u.Hard.PageFrameNumber)
2011-09-30 09:30:52 +00:00
# define PFN_FROM_PDE(v) ((v)->u.Hard.PageFrameNumber)
# define PFN_FROM_PPE(v) ((v)->u.Hard.PageFrameNumber)
# define PFN_FROM_PXE(v) ((v)->u.Hard.PageFrameNumber)
2010-03-31 15:11:20 +00:00
2015-05-05 20:36:07 +00:00
/* Macros for portable PTE modification */
2011-09-24 14:22:13 +00:00
# define MI_MAKE_DIRTY_PAGE(x) ((x)->u.Hard.Dirty = 1)
2015-05-10 19:35:24 +00:00
# define MI_MAKE_CLEAN_PAGE(x) ((x)->u.Hard.Dirty = 0)
2011-09-24 14:22:13 +00:00
# define MI_MAKE_ACCESSED_PAGE(x) ((x)->u.Hard.Accessed = 1)
# define MI_PAGE_DISABLE_CACHE(x) ((x)->u.Hard.CacheDisable = 1)
# define MI_PAGE_WRITE_THROUGH(x) ((x)->u.Hard.WriteThrough = 1)
# define MI_PAGE_WRITE_COMBINED(x) ((x)->u.Hard.WriteThrough = 0)
# define MI_IS_PAGE_LARGE(x) ((x)->u.Hard.LargePage == 1)
# if !defined(CONFIG_SMP)
# define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Write == 1)
# else
# define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Writable == 1)
# endif
# define MI_IS_PAGE_COPY_ON_WRITE(x)((x)->u.Hard.CopyOnWrite == 1)
2018-01-02 10:22:22 +00:00
# define MI_IS_PAGE_EXECUTABLE(x) ((x)->u.Hard.NoExecute == 0)
2011-09-24 14:22:13 +00:00
# define MI_IS_PAGE_DIRTY(x) ((x)->u.Hard.Dirty == 1)
# define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
# if !defined(CONFIG_SMP)
# define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Write = 1)
# else
# define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Writable = 1)
# endif
2010-07-16 00:03:03 +00:00
2018-01-01 14:25:45 +00:00
/* Macros to identify the page fault reason from the error code */
# define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x1)
2018-01-01 22:03:56 +00:00
# define MI_IS_WRITE_ACCESS(FaultCode) BooleanFlagOn(FaultCode, 0x2)
2018-01-02 10:22:22 +00:00
# define MI_IS_INSTRUCTION_FETCH(FaultCode) BooleanFlagOn(FaultCode, 0x10)
2018-01-01 14:25:45 +00:00
2014-05-18 16:25:40 +00:00
/* On x64, these are the same */
2012-02-04 10:40:27 +00:00
# define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE
# define ValidKernelPpe ValidKernelPde
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
2015-05-05 20:36:07 +00:00
/* Convert an address to a corresponding PTE */
2010-03-31 15:11:20 +00:00
PMMPTE
FORCEINLINE
2015-05-05 20:36:07 +00:00
_MiAddressToPte ( PVOID Address )
2010-03-31 15:11:20 +00:00
{
2015-05-05 20:36:07 +00:00
ULONG64 Offset = ( ULONG64 ) Address > > ( PTI_SHIFT - 3 ) ;
Offset & = 0xFFFFFFFFFULL < < 3 ;
return ( PMMPTE ) ( PTE_BASE + Offset ) ;
2010-03-31 15:11:20 +00:00
}
2015-05-05 20:36:07 +00:00
# define MiAddressToPte(x) _MiAddressToPte((PVOID)(x))
2010-03-31 15:11:20 +00:00
2015-05-05 20:36:07 +00:00
/* Convert an address to a corresponding PDE */
2010-03-31 15:11:20 +00:00
PMMPTE
FORCEINLINE
_MiAddressToPde ( PVOID Address )
{
ULONG64 Offset = ( ULONG64 ) Address > > ( PDI_SHIFT - 3 ) ;
Offset & = 0x7FFFFFF < < 3 ;
return ( PMMPTE ) ( PDE_BASE + Offset ) ;
}
# define MiAddressToPde(x) _MiAddressToPde((PVOID)(x))
2015-05-05 20:36:07 +00:00
/* Convert an address to a corresponding PPE */
2010-03-31 15:11:20 +00:00
PMMPTE
FORCEINLINE
2015-05-05 20:36:07 +00:00
MiAddressToPpe ( PVOID Address )
2010-03-31 15:11:20 +00:00
{
2015-05-05 20:36:07 +00:00
ULONG64 Offset = ( ULONG64 ) Address > > ( PPI_SHIFT - 3 ) ;
Offset & = 0x3FFFF < < 3 ;
return ( PMMPTE ) ( PPE_BASE + Offset ) ;
2010-03-31 15:11:20 +00:00
}
2015-05-05 20:36:07 +00:00
/* Convert an address to a corresponding PXE */
PMMPTE
FORCEINLINE
MiAddressToPxe ( PVOID Address )
{
ULONG64 Offset = ( ULONG64 ) Address > > ( PXI_SHIFT - 3 ) ;
Offset & = PXI_MASK < < 3 ;
return ( PMMPTE ) ( PXE_BASE + Offset ) ;
}
/* Convert an address to a corresponding PTE offset/index */
2010-07-23 23:30:00 +00:00
ULONG
FORCEINLINE
MiAddressToPti ( PVOID Address )
{
2010-07-25 12:00:26 +00:00
return ( ( ( ( ULONG64 ) Address ) > > PTI_SHIFT ) & 0x1FF ) ;
}
# define MiAddressToPteOffset(x) MiAddressToPti(x) // FIXME: bad name
2015-05-05 20:36:07 +00:00
/* Convert an address to a corresponding PDE offset/index */
ULONG
FORCEINLINE
MiAddressToPdi ( PVOID Address )
{
return ( ( ( ( ULONG64 ) Address ) > > PDI_SHIFT ) & 0x1FF ) ;
}
# define MiAddressToPdeOffset(x) MiAddressToPdi(x)
# define MiGetPdeOffset(x) MiAddressToPdi(x)
/* Convert an address to a corresponding PXE offset/index */
2010-07-25 12:00:26 +00:00
ULONG
FORCEINLINE
MiAddressToPxi ( PVOID Address )
{
return ( ( ( ( ULONG64 ) Address ) > > PXI_SHIFT ) & 0x1FF ) ;
2010-07-23 23:30:00 +00:00
}
2010-03-31 15:11:20 +00:00
/* Convert a PTE into a corresponding address */
PVOID
FORCEINLINE
2011-09-30 09:30:52 +00:00
MiPteToAddress ( PMMPTE PointerPte )
2010-03-31 15:11:20 +00:00
{
/* Use signed math */
2011-09-30 09:30:52 +00:00
return ( PVOID ) ( ( ( LONG64 ) PointerPte < < 25 ) > > 16 ) ;
}
2015-05-05 20:36:07 +00:00
/* Convert a PDE into a corresponding address */
2011-09-30 09:30:52 +00:00
PVOID
FORCEINLINE
MiPdeToAddress ( PMMPTE PointerPde )
{
/* Use signed math */
return ( PVOID ) ( ( ( LONG64 ) PointerPde < < 34 ) > > 16 ) ;
}
2015-05-05 20:36:07 +00:00
/* Convert a PPE into a corresponding address */
2011-09-30 09:30:52 +00:00
PVOID
FORCEINLINE
MiPpeToAddress ( PMMPTE PointerPpe )
{
/* Use signed math */
return ( PVOID ) ( ( ( LONG64 ) PointerPpe < < 43 ) > > 16 ) ;
}
2015-05-05 20:36:07 +00:00
/* Convert a PXE into a corresponding address */
2011-09-30 09:30:52 +00:00
PVOID
FORCEINLINE
MiPxeToAddress ( PMMPTE PointerPxe )
{
/* Use signed math */
return ( PVOID ) ( ( ( LONG64 ) PointerPxe < < 52 ) > > 16 ) ;
2010-03-31 15:11:20 +00:00
}
2015-05-05 20:36:07 +00:00
/* Translate between P*Es */
# define MiPdeToPte(_Pde) ((PMMPTE)MiPteToAddress(_Pde))
# define MiPteToPde(_Pte) ((PMMPDE)MiAddressToPte(_Pte))
# define MiPdeToPpe(_Pde) ((PMMPPE)MiAddressToPte(_Pde))
2010-03-31 15:11:20 +00:00
2015-05-05 20:36:07 +00:00
/* Check P*E boundaries */
# define MiIsPteOnPdeBoundary(PointerPte) \
( ( ( ( ULONG_PTR ) PointerPte ) & ( PAGE_SIZE - 1 ) ) = = 0 )
# define MiIsPteOnPpeBoundary(PointerPte) \
( ( ( ( ULONG_PTR ) PointerPte ) & ( PDE_PER_PAGE * PAGE_SIZE - 1 ) ) = = 0 )
# define MiIsPteOnPxeBoundary(PointerPte) \
( ( ( ( ULONG_PTR ) PointerPte ) & ( PPE_PER_PAGE * PDE_PER_PAGE * PAGE_SIZE - 1 ) ) = = 0 )
2012-04-01 15:23:08 +00:00
2015-05-05 20:36:07 +00:00
//
// Decodes a Prototype PTE into the underlying PTE
//
# define MiProtoPteToPte(x) \
( PMMPTE ) ( ( ( LONG64 ) ( x ) - > u . Long ) > > 16 ) /* Sign extend 48 bits */
2011-06-06 19:08:39 +00:00
2013-09-22 21:04:06 +00:00
//
// Decodes a Prototype PTE into the underlying PTE
//
# define MiSubsectionPteToSubsection(x) \
( PMMPTE ) ( ( x ) - > u . Subsect . SubsectionAddress > > 16 )
FORCEINLINE
VOID
2017-12-19 14:16:04 +00:00
MI_MAKE_SUBSECTION_PTE (
_Out_ PMMPTE NewPte ,
_In_ PVOID Segment )
2013-09-22 21:04:06 +00:00
{
2017-12-19 14:16:04 +00:00
/* Mark this as a prototype */
NewPte - > u . Long = 0 ;
NewPte - > u . Subsect . Prototype = 1 ;
/* Store the lower 48 bits of the Segment address */
NewPte - > u . Subsect . SubsectionAddress = ( ( ULONG_PTR ) Segment & 0x0000FFFFFFFFFFFF ) ;
2013-09-22 21:04:06 +00:00
}
2010-10-06 12:16:51 +00:00
FORCEINLINE
VOID
MI_MAKE_PROTOTYPE_PTE ( IN PMMPTE NewPte ,
IN PMMPTE PointerPte )
{
/* Store the Address */
2012-04-01 15:23:08 +00:00
NewPte - > u . Long = ( ULONG64 ) PointerPte < < 16 ;
2010-10-06 12:16:51 +00:00
/* Mark this as a prototype PTE */
NewPte - > u . Proto . Prototype = 1 ;
2012-04-01 15:23:08 +00:00
ASSERT ( MiProtoPteToPte ( NewPte ) = = PointerPte ) ;
}
2010-03-31 15:11:20 +00:00
2013-11-23 22:34:20 +00:00
FORCEINLINE
BOOLEAN
MI_IS_MAPPED_PTE ( PMMPTE PointerPte )
{
/// FIXME
__debugbreak ( ) ;
2014-05-10 14:33:37 +00:00
return ( ( PointerPte - > u . Long & 0xFFFFFC01 ) ! = 0 ) ;
2013-11-23 22:34:20 +00:00
}
2018-12-30 11:19:11 +00:00
INIT_FUNCTION
2010-03-31 15:11:20 +00:00
VOID
FORCEINLINE
MmInitGlobalKernelPageDirectory ( VOID )
{
/* Nothing to do */
}
2015-05-05 20:36:07 +00:00
BOOLEAN
FORCEINLINE
MiIsPdeForAddressValid ( PVOID Address )
{
return ( ( MiAddressToPxe ( Address ) - > u . Hard . Valid ) & &
( MiAddressToPpe ( Address ) - > u . Hard . Valid ) & &
( MiAddressToPde ( Address ) - > u . Hard . Valid ) ) ;
}