diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index b933448..07f9468 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -51,15 +51,14 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc ${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc ${XTOSKRNL_SOURCE_DIR}/ke/timer.cc - ${XTOSKRNL_SOURCE_DIR}/mm/globals.c - ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.c - ${XTOSKRNL_SOURCE_DIR}/mm/init.c - ${XTOSKRNL_SOURCE_DIR}/mm/kpools.c - ${XTOSKRNL_SOURCE_DIR}/mm/pages.c - ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/globals.c - ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.c - ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pages.c - ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pmap.c + ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.cc + ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc + ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc + ${XTOSKRNL_SOURCE_DIR}/mm/data.cc + ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc + ${XTOSKRNL_SOURCE_DIR}/mm/init.cc + ${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc + ${XTOSKRNL_SOURCE_DIR}/mm/paging.cc ${XTOSKRNL_SOURCE_DIR}/po/idle.cc ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc diff --git a/xtoskrnl/includes/mm.hh b/xtoskrnl/includes/mm.hh new file mode 100644 index 0000000..8dbdfb5 --- /dev/null +++ b/xtoskrnl/includes/mm.hh @@ -0,0 +1,21 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm.hh + * DESCRIPTION: Memory Manager + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_HH +#define __XTOSKRNL_MM_HH + +#include + +#include XTOS_ARCH_HEADER(mm, pagemap.hh) + +#include +#include +#include +#include + +#endif /* __XTOSKRNL_MM_HH */ diff --git a/xtoskrnl/includes/mm/amd64/pagemap.hh b/xtoskrnl/includes/mm/amd64/pagemap.hh new file mode 100644 index 0000000..79a4418 --- /dev/null +++ b/xtoskrnl/includes/mm/amd64/pagemap.hh @@ -0,0 +1,53 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/pagemap.hh + * DESCRIPTION: Low-level support for page map manipulation + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_PAGEMAP_HH +#define __XTOSKRNL_MM_PAGEMAP_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + typedef class PageMap + { + protected: + MMPAGEMAP_INFO PageMapInfo; + + public: + XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer); + XTAPI PMMP5E GetP5eAddress(PVOID Address); + XTAPI PMMPDE GetPdeAddress(PVOID Address); + XTAPI PMMPPE GetPpeAddress(PVOID Address); + XTAPI PMMPTE GetPteAddress(PVOID Address); + XTAPI PMMPXE GetPxeAddress(PVOID Address); + virtual XTAPI VOID InitializePageMapInfo(VOID) = 0; + XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer); + XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + } PAGEMAP, *PPAGEMAP; + + class PageMapBasic final : public PageMap + { + public: + XTAPI VOID InitializePageMapInfo(VOID); + }; + + class PageMapXpa final : public PageMap + { + public: + XTAPI VOID InitializePageMapInfo(VOID); + }; +} + +#endif /* __XTOSKRNL_MM_PAGEMAP_HH */ diff --git a/xtoskrnl/includes/mm/hlpool.hh b/xtoskrnl/includes/mm/hlpool.hh new file mode 100644 index 0000000..5a9a9e3 --- /dev/null +++ b/xtoskrnl/includes/mm/hlpool.hh @@ -0,0 +1,39 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/hlpool.hh + * DESCRIPTION: Hardware layer pool memory management + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_HLPOOL_HH +#define __XTOSKRNL_MM_HLPOOL_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class HardwarePool + { + public: + STATIC XTAPI XTSTATUS AllocateHardwareMemory(IN PFN_NUMBER PageCount, + IN BOOLEAN Aligned, + OUT PPHYSICAL_ADDRESS Buffer); + STATIC XTAPI XTSTATUS MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, + IN PFN_NUMBER PageCount, + IN BOOLEAN FlushTlb, + OUT PVOID *VirtualAddress); + STATIC XTAPI VOID MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, + IN PFN_NUMBER PageCount); + STATIC XTAPI VOID RemapHardwareMemory(IN PVOID VirtualAddress, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN BOOLEAN FlushTlb); + STATIC XTAPI XTSTATUS UnmapHardwareMemory(IN PVOID VirtualAddress, + IN PFN_NUMBER PageCount, + IN BOOLEAN FlushTlb); + }; +} + +#endif /* __XTOSKRNL_MM_HLPOOL_HH */ diff --git a/xtoskrnl/includes/mm/i686/pagemap.hh b/xtoskrnl/includes/mm/i686/pagemap.hh new file mode 100644 index 0000000..0ca1616 --- /dev/null +++ b/xtoskrnl/includes/mm/i686/pagemap.hh @@ -0,0 +1,65 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/pagemap.hh + * DESCRIPTION: Low-level support for page map manipulation + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_PAGEMAP_HH +#define __XTOSKRNL_MM_PAGEMAP_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + typedef class PageMap + { + protected: + MMPAGEMAP_INFO PageMapInfo; + + public: + XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer); + XTAPI PMMPDE GetPdeAddress(PVOID Address); + XTAPI PMMPPE GetPpeAddress(PVOID Address); + XTAPI PMMPTE GetPteAddress(PVOID Address); + virtual XTAPI VOID InitializePageMapInfo(VOID) = 0; + virtual XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer) = 0; + virtual XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) = 0; + virtual XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) = 0; + } PAGEMAP, *PPAGEMAP; + + class PageMapBasic final : public PageMap + { + public: + XTAPI VOID InitializePageMapInfo(VOID); + XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer); + XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + }; + + class PageMapXpa final : public PageMap + { + public: + XTAPI VOID InitializePageMapInfo(VOID); + XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer); + XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + }; +} + +#endif /* __XTOSKRNL_MM_PAGEMAP_HH */ diff --git a/xtoskrnl/includes/mm/init.hh b/xtoskrnl/includes/mm/init.hh new file mode 100644 index 0000000..1810e46 --- /dev/null +++ b/xtoskrnl/includes/mm/init.hh @@ -0,0 +1,32 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/init.hh + * DESCRIPTION: Memory Manager initialization + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_INIT_HH +#define __XTOSKRNL_MM_INIT_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class Init + { + public: + STATIC XTAPI VOID InitializeMemoryManager(VOID); + STATIC XTAPI VOID InitializePageMapSupport(VOID); + STATIC XTAPI VOID ScanMemoryDescriptors(VOID); + + private: + STATIC XTAPI VOID InitializeArchitecture(VOID); + STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType); + STATIC XTAPI BOOLEAN VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType); + }; +} + +#endif /* __XTOSKRNL_MM_INIT_HH */ diff --git a/xtoskrnl/includes/mm/kpool.hh b/xtoskrnl/includes/mm/kpool.hh new file mode 100644 index 0000000..f61681e --- /dev/null +++ b/xtoskrnl/includes/mm/kpool.hh @@ -0,0 +1,32 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/hlpool.hh + * DESCRIPTION: Kernel pool memory management + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_KPOOL_HH +#define __XTOSKRNL_MM_KPOOL_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class KernelPool + { + public: + STATIC XTAPI XTSTATUS AllocateKernelStack(IN PVOID *Stack, + IN BOOLEAN LargeStack, + IN UCHAR SystemNode); + STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber, + OUT PVOID *StructuresData); + STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack, + IN BOOLEAN LargeStack); + STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData); + }; +} + +#endif /* __XTOSKRNL_MM_KPOOL_HH */ diff --git a/xtoskrnl/includes/mm/paging.hh b/xtoskrnl/includes/mm/paging.hh new file mode 100644 index 0000000..2f261f3 --- /dev/null +++ b/xtoskrnl/includes/mm/paging.hh @@ -0,0 +1,47 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/paging.hh + * DESCRIPTION: Low level page management support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_PAGING_HH +#define __XTOSKRNL_MM_PAGING_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class Paging + { + private: + STATIC PPAGEMAP PmlRoutines; + + public: + STATIC XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer); + STATIC XTAPI VOID FlushTlb(VOID); + STATIC XTAPI PMMPDE GetPdeAddress(PVOID Address); + STATIC XTAPI PMMPPE GetPpeAddress(PVOID Address); + STATIC XTAPI PMMPTE GetPteAddress(PVOID Address); + STATIC XTAPI VOID InitializePageMapSupport(VOID); + STATIC XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer); + STATIC XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + STATIC XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address, + IN ULONG Size); + + private: + STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID); + STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID); + STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID); + }; +} + +#endif /* __XTOSKRNL_MM_PAGING_HH */ diff --git a/xtoskrnl/includes/xtos.hh b/xtoskrnl/includes/xtos.hh index 3a28f57..4d05229 100644 --- a/xtoskrnl/includes/xtos.hh +++ b/xtoskrnl/includes/xtos.hh @@ -31,5 +31,6 @@ extern "C" { #include #include #include +#include #include #include diff --git a/xtoskrnl/mm/amd64/globals.c b/xtoskrnl/mm/amd64/globals.c deleted file mode 100644 index f5959a1..0000000 --- a/xtoskrnl/mm/amd64/globals.c +++ /dev/null @@ -1,26 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/amd64/globals.c - * DESCRIPTION: AMD64-specific global variables for the Memory Manager - * DEVELOPERS: Aiken Harris - */ - -#include - - -/* Page mapping routines for systems using 4-level paging (PML4) */ -CMMPAGEMAP_ROUTINES MmpPml4Routines = { - .ClearPte = MmpClearPte, - .PteValid = MmpPteValid, - .SetPteCaching = MmpSetPteCaching, - .SetPte = MmpSetPte, -}; - -/* Page mapping routines for systems using 5-level paging (PML5) */ -CMMPAGEMAP_ROUTINES MmpPml5Routines = { - .ClearPte = MmpClearPte, - .PteValid = MmpPteValid, - .SetPteCaching = MmpSetPteCaching, - .SetPte = MmpSetPte, -}; diff --git a/xtoskrnl/mm/amd64/init.c b/xtoskrnl/mm/amd64/init.c deleted file mode 100644 index 31483d4..0000000 --- a/xtoskrnl/mm/amd64/init.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/amd64/init.c - * DESCRIPTION: Architecture specific Memory Manager initialization routines - * DEVELOPERS: Rafal Kupiec - * Aiken Harris - */ - -#include - - -/** - * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmInitializePageMapSupport(VOID) -{ - /* Check if XPA is enabled */ - if(MmpGetExtendedPhysicalAddressingStatus()) - { - /* XPA enabled, use LA57 paging (PML5) */ - MmpPageMapRoutines = &MmpPml5Routines; - - /* Set PML5 page map information */ - MmpPageMapInfo.Xpa = TRUE; - - /* Set PML5 base addresses */ - MmpPageMapInfo.PteBase = MM_PTE_LA57_BASE; - MmpPageMapInfo.PdeBase = MM_PDE_LA57_BASE; - MmpPageMapInfo.PpeBase = MM_PPE_LA57_BASE; - MmpPageMapInfo.PxeBase = MM_PXE_LA57_BASE; - MmpPageMapInfo.P5eBase = MM_P5E_LA57_BASE; - - /* PML5 use 57-bit virtual addresses */ - MmpPageMapInfo.VaBits = 57; - } - else - { - /* XPA disabled, use LA48 paging (PML4) */ - MmpPageMapRoutines = &MmpPml4Routines; - - /* Set PML4 page map information */ - MmpPageMapInfo.Xpa = FALSE; - - /* Set PML4 base addresses */ - MmpPageMapInfo.PteBase = MM_PTE_BASE; - MmpPageMapInfo.PdeBase = MM_PDE_BASE; - MmpPageMapInfo.PpeBase = MM_PPE_BASE; - MmpPageMapInfo.PxeBase = MM_PXE_BASE; - MmpPageMapInfo.P5eBase = 0x0; - - /* PML use 48-bit virtual addresses */ - MmpPageMapInfo.VaBits = 48; - } -} - -/** - * Performs architecture specific initialization of the XTOS Memory Manager. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmpInitializeArchitecture(VOID) -{ - UNIMPLEMENTED; -} diff --git a/xtoskrnl/mm/amd64/init.cc b/xtoskrnl/mm/amd64/init.cc new file mode 100644 index 0000000..7e7a9d8 --- /dev/null +++ b/xtoskrnl/mm/amd64/init.cc @@ -0,0 +1,25 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/amd64/init.cc + * DESCRIPTION: Architecture specific Memory Manager initialization routines + * DEVELOPERS: Rafal Kupiec + * Aiken Harris + */ + +#include + + +/** + * Performs architecture specific initialization of the XTOS Memory Manager. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Init::InitializeArchitecture(VOID) +{ + UNIMPLEMENTED; +} diff --git a/xtoskrnl/mm/amd64/pmap.c b/xtoskrnl/mm/amd64/pagemap.cc similarity index 51% rename from xtoskrnl/mm/amd64/pmap.c rename to xtoskrnl/mm/amd64/pagemap.cc index bc29a75..ea7343b 100644 --- a/xtoskrnl/mm/amd64/pmap.c +++ b/xtoskrnl/mm/amd64/pagemap.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/amd64/pmap.c - * DESCRIPTION: Low-level support for AMD64 page map manipulation + * FILE: xtoskrnl/mm/i686/pagemap.cc + * DESCRIPTION: Low-level support for i686 page map manipulation * DEVELOPERS: Aiken Harris */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTAPI VOID -MmpClearPte(PHARDWARE_PTE PtePointer) +MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer) { PtePointer->CacheDisable = 0; PtePointer->PageFrameNumber = 0; @@ -30,21 +30,6 @@ MmpClearPte(PHARDWARE_PTE PtePointer) PtePointer->WriteThrough = 0; } -/** - * Checks if eXtended Physical Addressing (XPA) is enabled. - * - * @return This routine returns TRUE if LA57 is enabled, or FALSE otherwise. - * - * @since XT 1.0 - */ -XTAPI -BOOLEAN -MmpGetExtendedPhysicalAddressingStatus(VOID) -{ - /* Check if LA57 is enabled */ - return ((ArReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE; -} - /** * Gets the address of the P5E (Page Map Level 5 Entry), that maps given address. * @@ -57,12 +42,13 @@ MmpGetExtendedPhysicalAddressingStatus(VOID) */ XTAPI PMMP5E -MmpGetP5eAddress(PVOID Address) +MM::PageMap::GetP5eAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_P5I_SHIFT) << MM_PTE_SHIFT); - return (PMMP5E)((MmpPageMapInfo.P5eBase + Offset) * MmpPageMapInfo.Xpa); + /* Calculate offset and return P5E address */ + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_P5I_SHIFT) << MM_PTE_SHIFT); + return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa); } /** @@ -77,19 +63,20 @@ MmpGetP5eAddress(PVOID Address) */ XTAPI PMMPDE -MmpGetPdeAddress(PVOID Address) +MM::PageMap::GetPdeAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PDI_SHIFT) << MM_PTE_SHIFT); - return (PMMPDE)(MmpPageMapInfo.PdeBase + Offset); + /* Calculate offset and return PDE address */ + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PDI_SHIFT) << MM_PTE_SHIFT); + return (PMMPDE)(PageMapInfo.PdeBase + Offset); } /** * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address. * * @param Address - * Specifies the virtual address for which to retrieve the corresponding PPE. + * Specifies the virtual address for which to retrieve the corresponding PDE. * * @return This routine returns the address of the PPE. * @@ -97,12 +84,13 @@ MmpGetPdeAddress(PVOID Address) */ XTAPI PMMPPE -MmpGetPpeAddress(PVOID Address) +MM::PageMap::GetPpeAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PPI_SHIFT) << MM_PTE_SHIFT); - return (PMMPPE)(MmpPageMapInfo.PpeBase + Offset); + /* Calculate offset and return PPE address */ + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PPI_SHIFT) << MM_PTE_SHIFT); + return (PMMPPE)(PageMapInfo.PpeBase + Offset); } /** @@ -117,12 +105,13 @@ MmpGetPpeAddress(PVOID Address) */ XTAPI PMMPTE -MmpGetPteAddress(PVOID Address) +MM::PageMap::GetPteAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PTI_SHIFT) << MM_PTE_SHIFT); - return (PMMPTE)(MmpPageMapInfo.PteBase + Offset); + /* Calculate offset and return PTE address */ + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PTI_SHIFT) << MM_PTE_SHIFT); + return (PMMPTE)(PageMapInfo.PteBase + Offset); } /** @@ -137,16 +126,16 @@ MmpGetPteAddress(PVOID Address) */ XTAPI PMMPXE -MmpGetPxeAddress(PVOID Address) +MM::PageMap::GetPxeAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT); - return (PMMPXE)(MmpPageMapInfo.PxeBase + Offset); + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT); + return (PMMPXE)(PageMapInfo.PxeBase + Offset); } /** - * Checks whether the given page table entry (PTE) is valid. + * Checks whether the given PML2 page table entry (PTE) is valid. * * @param PtePointer * Pointer to the page table entry (PTE) to check. @@ -157,13 +146,13 @@ MmpGetPxeAddress(PVOID Address) */ XTAPI BOOLEAN -MmpPteValid(PHARDWARE_PTE PtePointer) +MM::PageMap::PteValid(PHARDWARE_PTE PtePointer) { return (BOOLEAN)PtePointer->Valid; } /** - * Sets a page table entry (PTE) with the specified physical page and access flags. + * Sets a PML2 page table entry (PTE) with the specified physical page and access flags. * * @param PtePointer * Pointer to the page table entry (PTE) to set. @@ -180,9 +169,9 @@ MmpPteValid(PHARDWARE_PTE PtePointer) */ XTAPI VOID -MmpSetPte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable) +MM::PageMap::SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) { PtePointer->PageFrameNumber = PageFrameNumber; PtePointer->Valid = 1; @@ -190,7 +179,7 @@ MmpSetPte(PHARDWARE_PTE PtePointer, } /** - * Sets caching attributes for a page table entry (PTE). + * Sets caching attributes for a PML2 page table entry (PTE). * * @param PtePointer * Pointer to the page table entry (PTE) to modify. @@ -207,10 +196,60 @@ MmpSetPte(PHARDWARE_PTE PtePointer, */ XTAPI VOID -MmpSetPteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough) +MM::PageMap::SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) { PtePointer->CacheDisable = CacheDisable; PtePointer->WriteThrough = WriteThrough; } + +/** + * Initializes page map information for basic paging (PML4). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapBasic::InitializePageMapInfo(VOID) +{ + /* Set PML4 page map information */ + PageMapInfo.Xpa = FALSE; + + /* Set PML4 base addresses */ + PageMapInfo.PteBase = MM_PTE_BASE; + PageMapInfo.PdeBase = MM_PDE_BASE; + PageMapInfo.PpeBase = MM_PPE_BASE; + PageMapInfo.PxeBase = MM_PXE_BASE; + PageMapInfo.P5eBase = 0x0; + + /* PML use 48-bit virtual addresses */ + PageMapInfo.VaBits = 48; +} + +/** + * Initializes page map information for XPA paging (PML5). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapXpa::InitializePageMapInfo(VOID) +{ + /* Set PML5 page map information */ + PageMapInfo.Xpa = TRUE; + + /* Set PML5 base addresses */ + PageMapInfo.PteBase = MM_PTE_LA57_BASE; + PageMapInfo.PdeBase = MM_PDE_LA57_BASE; + PageMapInfo.PpeBase = MM_PPE_LA57_BASE; + PageMapInfo.PxeBase = MM_PXE_LA57_BASE; + PageMapInfo.P5eBase = MM_P5E_LA57_BASE; + + /* PML5 use 57-bit virtual addresses */ + PageMapInfo.VaBits = 57; +} diff --git a/xtoskrnl/mm/amd64/pages.c b/xtoskrnl/mm/amd64/paging.cc similarity index 64% rename from xtoskrnl/mm/amd64/pages.c rename to xtoskrnl/mm/amd64/paging.cc index 7471ec5..0ab73ef 100644 --- a/xtoskrnl/mm/amd64/pages.c +++ b/xtoskrnl/mm/amd64/paging.cc @@ -1,14 +1,30 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/amd64/pages.c + * FILE: xtoskrnl/mm/amd64/paging.cc * DESCRIPTION: Architecture dependent paging support * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ -#include +#include +/** + * Checks if eXtended Physical Addressing (XPA) is enabled. + * + * @return This routine returns TRUE if LA57 is enabled, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::Paging::GetExtendedPhysicalAddressingStatus(VOID) +{ + /* Check if LA57 is enabled */ + return ((AR::CpuFunc::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE; +} + /** * Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way. * @@ -24,8 +40,8 @@ */ XTFASTCALL VOID -MmZeroPages(IN PVOID Address, - IN ULONG Size) +MM::Paging::ZeroPages(IN PVOID Address, + IN ULONG Size) { __asm__ volatile("xor %%rax, %%rax\n" "mov %0, %%rdi\n" diff --git a/xtoskrnl/mm/data.cc b/xtoskrnl/mm/data.cc new file mode 100644 index 0000000..7869827 --- /dev/null +++ b/xtoskrnl/mm/data.cc @@ -0,0 +1,40 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/data.cc + * DESCRIPTION: Memory Manager global and static data + * DEVELOPERS: Aiken Harris + */ + +#include + + +/* Allocation descriptors dedicated for hardware layer */ +LOADER_MEMORY_DESCRIPTOR MM::HardwarePool::HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS]; + +/* Live address of kernel's hardware heap */ +PVOID MM::HardwarePool::HardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS; + +/* Number of used hardware allocation descriptors */ +ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0; + +/* Biggest free memory descriptor */ +PLOADER_MEMORY_DESCRIPTOR MM::Init::FreeDescriptor; + +/* Highest physical page number */ +ULONG_PTR MM::Init::HighestPhysicalPage; + +/* Lowest physical page number */ +ULONG_PTR MM::Init::LowestPhysicalPage = -1; + +/* Number of physical pages */ +ULONG MM::Init::NumberOfPhysicalPages; + +/* Old biggest free memory descriptor */ +LOADER_MEMORY_DESCRIPTOR MM::Init::OldFreeDescriptor; + +/* Processor structures data (THIS IS A TEMPORARY HACK) */ +UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}}; + +/* Instance of the page map routines for the current PML level */ +MM::PPAGEMAP MM::Paging::PmlRoutines; diff --git a/xtoskrnl/mm/globals.c b/xtoskrnl/mm/globals.c deleted file mode 100644 index f3e0878..0000000 --- a/xtoskrnl/mm/globals.c +++ /dev/null @@ -1,43 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/globals.c - * DESCRIPTION: Memory Manager initialization routines - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* Biggest free memory descriptor */ -PLOADER_MEMORY_DESCRIPTOR MmFreeDescriptor; - -/* Highest physical page number */ -ULONG_PTR MmHighestPhysicalPage; - -/* Lowest physical page number */ -ULONG_PTR MmLowestPhysicalPage = -1; - -/* Number of physical pages */ -ULONG MmNumberOfPhysicalPages; - -/* Old biggest free memory descriptor */ -LOADER_MEMORY_DESCRIPTOR MmOldFreeDescriptor; - -/* Processor structures data (THIS IS A TEMPORARY HACK) */ -UCHAR MmProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {0}; - -/* Allocation descriptors dedicated for hardware layer */ -LOADER_MEMORY_DESCRIPTOR MmpHardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS]; - -/* Live address of kernel's hardware heap */ -PVOID MmpHardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS; - -/* Information about the current page map */ -MMPAGEMAP_INFO MmpPageMapInfo; - -/* Pointers to page map routines for the current paging mode */ -PCMMPAGEMAP_ROUTINES MmpPageMapRoutines; - -/* Number of used hardware allocation descriptors */ -ULONG MmpUsedHardwareAllocationDescriptors = 0; diff --git a/xtoskrnl/mm/hlpool.c b/xtoskrnl/mm/hlpool.cc similarity index 74% rename from xtoskrnl/mm/hlpool.c rename to xtoskrnl/mm/hlpool.cc index a5302b9..ececddb 100644 --- a/xtoskrnl/mm/hlpool.c +++ b/xtoskrnl/mm/hlpool.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/hlpool.c + * FILE: xtoskrnl/mm/hlpool.cc * DESCRIPTION: Hardware layer pool memory management * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -27,9 +27,9 @@ */ XTAPI XTSTATUS -MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, - IN BOOLEAN Aligned, - OUT PPHYSICAL_ADDRESS Buffer) +MM::HardwarePool::AllocateHardwareMemory(IN PFN_NUMBER PageCount, + IN BOOLEAN Aligned, + OUT PPHYSICAL_ADDRESS Buffer) { PLOADER_MEMORY_DESCRIPTOR Descriptor, ExtraDescriptor, HardwareDescriptor; PFN_NUMBER Alignment, MaxPage; @@ -43,7 +43,7 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, MaxPage = MM_MAXIMUM_PHYSICAL_ADDRESS >> MM_PAGE_SHIFT; /* Make sure there are at least 2 descriptors available */ - if((MmpUsedHardwareAllocationDescriptors + 2) > MM_HARDWARE_ALLOCATION_DESCRIPTORS) + if((UsedHardwareAllocationDescriptors + 2) > MM_HARDWARE_ALLOCATION_DESCRIPTORS) { /* Not enough descriptors, return error */ return STATUS_INSUFFICIENT_RESOURCES; @@ -84,13 +84,13 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, } /* Allocate new descriptor */ - HardwareDescriptor = &MmpHardwareAllocationDescriptors[MmpUsedHardwareAllocationDescriptors]; + HardwareDescriptor = &HardwareAllocationDescriptors[UsedHardwareAllocationDescriptors]; HardwareDescriptor->BasePage = Descriptor->BasePage + Alignment; HardwareDescriptor->MemoryType = LoaderHardwareCachedMemory; HardwareDescriptor->PageCount = PageCount; /* Update hardware allocation descriptors count */ - MmpUsedHardwareAllocationDescriptors++; + UsedHardwareAllocationDescriptors++; /* Check if alignment was done */ if(Alignment) @@ -99,23 +99,23 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, if(Descriptor->PageCount > (PageCount + Alignment)) { /* Initialize extra descriptor */ - ExtraDescriptor = &MmpHardwareAllocationDescriptors[MmpUsedHardwareAllocationDescriptors]; + ExtraDescriptor = &HardwareAllocationDescriptors[UsedHardwareAllocationDescriptors]; ExtraDescriptor->BasePage = Descriptor->BasePage + Alignment + (ULONG)PageCount; ExtraDescriptor->MemoryType = LoaderFree; ExtraDescriptor->PageCount = Descriptor->PageCount - (Alignment + (ULONG)PageCount); /* Update hardware allocation descriptors count */ - MmpUsedHardwareAllocationDescriptors++; + UsedHardwareAllocationDescriptors++; /* Insert extra descriptor in the list */ - RtlInsertHeadList(&Descriptor->ListEntry, &ExtraDescriptor->ListEntry); + RTL::LinkedList::InsertHeadList(&Descriptor->ListEntry, &ExtraDescriptor->ListEntry); } /* Trim source descriptor to the alignment */ Descriptor->PageCount = Alignment; /* Insert new descriptor in the list */ - RtlInsertHeadList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry); + RTL::LinkedList::InsertHeadList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry); } else { @@ -124,13 +124,13 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, Descriptor->PageCount -= (ULONG)PageCount; /* Insert new descriptor in the list */ - RtlInsertTailList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry); + RTL::LinkedList::InsertTailList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry); /* Check if source descriptor is fully consumed */ if(Descriptor->PageCount == 0) { /* Remove descriptor from the list */ - RtlRemoveEntryList(&Descriptor->ListEntry); + RTL::LinkedList::RemoveEntryList(&Descriptor->ListEntry); } } @@ -160,17 +160,17 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, */ XTAPI XTSTATUS -MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, - IN PFN_NUMBER PageCount, - IN BOOLEAN FlushTlb, - OUT PVOID *VirtualAddress) +MM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, + IN PFN_NUMBER PageCount, + IN BOOLEAN FlushTlb, + OUT PVOID *VirtualAddress) { PVOID BaseAddress, ReturnAddress; PFN_NUMBER MappedPages; PHARDWARE_PTE PtePointer; /* Initialize variables */ - BaseAddress = MmpHardwareHeapStart; + BaseAddress = HardwareHeapStart; MappedPages = 0; ReturnAddress = BaseAddress; *VirtualAddress = NULL; @@ -186,11 +186,11 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, } /* Get PTE pointer and advance to next page */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(ReturnAddress); - ReturnAddress = (PVOID)(ULONG_PTR)ReturnAddress + MM_PAGE_SIZE; + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(ReturnAddress); + ReturnAddress = (PVOID)((ULONG_PTR)ReturnAddress + MM_PAGE_SIZE); /* Check if PTE is valid */ - if(MmpPageMapRoutines->PteValid(PtePointer)) + if(MM::Paging::PteValid(PtePointer)) { /* PTE is not available, go to the next one */ BaseAddress = ReturnAddress; @@ -203,23 +203,23 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, } /* Take the actual base address with an offset */ - ReturnAddress = (PVOID)(ULONG_PTR)(BaseAddress + PAGE_OFFSET(PhysicalAddress.LowPart)); + ReturnAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_OFFSET(PhysicalAddress.LowPart)); /* Check if base address starts at the beginning of the heap */ - if(BaseAddress == MmpHardwareHeapStart) + if(BaseAddress == HardwareHeapStart) { /* Move heap beyond base address */ - MmpHardwareHeapStart = (PVOID)((ULONG_PTR)BaseAddress + ((ULONG_PTR)PageCount << MM_PAGE_SHIFT)); + HardwareHeapStart = (PVOID)((ULONG_PTR)BaseAddress + ((ULONG_PTR)PageCount << MM_PAGE_SHIFT)); } /* Iterate through mapped pages */ while(MappedPages--) { /* Get PTE pointer */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(BaseAddress); + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(BaseAddress); /* Fill the PTE */ - MmpPageMapRoutines->SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); + MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); /* Advance to the next address */ PhysicalAddress.QuadPart += MM_PAGE_SIZE; @@ -230,7 +230,7 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, if(FlushTlb) { /* Flush the TLB */ - MmFlushTlb(); + MM::Paging::FlushTlb(); } /* Return virtual address */ @@ -253,20 +253,20 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, */ XTAPI VOID -MmMarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, - IN PFN_NUMBER PageCount) +MM::HardwarePool::MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, + IN PFN_NUMBER PageCount) { PHARDWARE_PTE PtePointer; PFN_NUMBER Page; /* Get PTE address from virtual address */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(VirtualAddress); + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress); /* Iterate through mapped pages */ for(Page = 0; Page < PageCount; Page++) { /* Mark pages as CD/WT */ - MmpPageMapRoutines->SetPteCaching(PtePointer, TRUE, TRUE); + MM::Paging::SetPteCaching(PtePointer, TRUE, TRUE); PtePointer++; } } @@ -289,23 +289,23 @@ MmMarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, */ XTAPI VOID -MmRemapHardwareMemory(IN PVOID VirtualAddress, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN BOOLEAN FlushTlb) +MM::HardwarePool::RemapHardwareMemory(IN PVOID VirtualAddress, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN BOOLEAN FlushTlb) { PHARDWARE_PTE PtePointer; /* Get PTE address from virtual address */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(VirtualAddress); + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress); /* Remap the PTE */ - MmpPageMapRoutines->SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); + MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); /* Check if TLB needs to be flushed */ if(FlushTlb) { /* Flush the TLB */ - MmFlushTlb(); + MM::Paging::FlushTlb(); } } @@ -327,9 +327,9 @@ MmRemapHardwareMemory(IN PVOID VirtualAddress, */ XTAPI XTSTATUS -MmUnmapHardwareMemory(IN PVOID VirtualAddress, - IN PFN_NUMBER PageCount, - IN BOOLEAN FlushTlb) +MM::HardwarePool::UnmapHardwareMemory(IN PVOID VirtualAddress, + IN PFN_NUMBER PageCount, + IN BOOLEAN FlushTlb) { PHARDWARE_PTE PtePointer; PFN_NUMBER Page; @@ -345,13 +345,13 @@ MmUnmapHardwareMemory(IN PVOID VirtualAddress, VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(MM_PAGE_SIZE - 1)); /* Get PTE address from virtual address */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(VirtualAddress); + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress); /* Iterate through mapped pages */ for(Page = 0; Page < PageCount; Page++) { /* Unmap the PTE and get the next one */ - MmpPageMapRoutines->ClearPte(PtePointer); + MM::Paging::ClearPte(PtePointer); PtePointer++; } @@ -359,14 +359,14 @@ MmUnmapHardwareMemory(IN PVOID VirtualAddress, if(FlushTlb) { /* Flush the TLB */ - MmFlushTlb(); + MM::Paging::FlushTlb(); } /* Check if heap can be reused */ - if(MmpHardwareHeapStart > VirtualAddress) + if(HardwareHeapStart > VirtualAddress) { /* Free VA space */ - MmpHardwareHeapStart = VirtualAddress; + HardwareHeapStart = VirtualAddress; } /* Return success */ diff --git a/xtoskrnl/mm/i686/globals.c b/xtoskrnl/mm/i686/globals.c deleted file mode 100644 index 97db43e..0000000 --- a/xtoskrnl/mm/i686/globals.c +++ /dev/null @@ -1,26 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/i686/globals.c - * DESCRIPTION: i686-specific global variables for the Memory Manager - * DEVELOPERS: Aiken Harris - */ - -#include - - -/* Page mapping routines for systems using 2-level paging (PML2) */ -CMMPAGEMAP_ROUTINES MmpPml2Routines = { - .ClearPte = MmpClearPte, - .PteValid = MmpPml2PteValid, - .SetPteCaching = MmpSetPml2PteCaching, - .SetPte = MmpSetPml2Pte, -}; - -/* Page mapping routines for systems using 3-level paging (PML3) */ -CMMPAGEMAP_ROUTINES MmpPml3Routines = { - .ClearPte = MmpClearPte, - .PteValid = MmpPml3PteValid, - .SetPteCaching = MmpSetPml3PteCaching, - .SetPte = MmpSetPml3Pte, -}; diff --git a/xtoskrnl/mm/i686/init.c b/xtoskrnl/mm/i686/init.c deleted file mode 100644 index a473449..0000000 --- a/xtoskrnl/mm/i686/init.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/i686/init.c - * DESCRIPTION: Architecture specific Memory Manager initialization routines - * DEVELOPERS: Rafal Kupiec - * Aiken Harris - */ - -#include - - -/** - * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmInitializePageMapSupport(VOID) -{ - /* Check if XPA is enabled */ - if(MmpGetExtendedPhysicalAddressingStatus()) - { - /* XPA enabled, use modern PAE paging (PML3) */ - MmpPageMapRoutines = &MmpPml3Routines; - - /* Set PML3 page map information */ - MmpPageMapInfo.Xpa = TRUE; - - /* Set PML3 base addresses */ - MmpPageMapInfo.PteBase = MM_PTE_BASE; - MmpPageMapInfo.PdeBase = MM_PDE_BASE; - - /* Set PML3 shift values */ - MmpPageMapInfo.PdiShift = MM_PDI_SHIFT; - MmpPageMapInfo.PteShift = MM_PTE_SHIFT; - } - else - { - /* XPA disabled, use legacy i386 paging (PML2) */ - MmpPageMapRoutines = &MmpPml2Routines; - - /* Set PML2 page map information */ - MmpPageMapInfo.Xpa = FALSE; - - /* Set PML2 base addresses */ - MmpPageMapInfo.PteBase = MM_PTE_BASE; - MmpPageMapInfo.PdeBase = MM_PDE_LEGACY_BASE; - - /* Set PML2 shift values */ - MmpPageMapInfo.PdiShift = MM_PDI_LEGACY_SHIFT; - MmpPageMapInfo.PteShift = MM_PTE_LEGACY_SHIFT; - } -} - -/** - * Performs architecture specific initialization of the XTOS Memory Manager. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmpInitializeArchitecture(VOID) -{ - UNIMPLEMENTED; -} diff --git a/xtoskrnl/mm/i686/init.cc b/xtoskrnl/mm/i686/init.cc new file mode 100644 index 0000000..ab1892d --- /dev/null +++ b/xtoskrnl/mm/i686/init.cc @@ -0,0 +1,25 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/i686/init.cc + * DESCRIPTION: Architecture specific Memory Manager initialization routines + * DEVELOPERS: Rafal Kupiec + * Aiken Harris + */ + +#include + + +/** + * Performs architecture specific initialization of the XTOS Memory Manager. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Init::InitializeArchitecture(VOID) +{ + UNIMPLEMENTED; +} diff --git a/xtoskrnl/mm/i686/pmap.c b/xtoskrnl/mm/i686/pagemap.cc similarity index 65% rename from xtoskrnl/mm/i686/pmap.c rename to xtoskrnl/mm/i686/pagemap.cc index 4decaba..2ff1ed9 100644 --- a/xtoskrnl/mm/i686/pmap.c +++ b/xtoskrnl/mm/i686/pagemap.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/i686/pmap.c + * FILE: xtoskrnl/mm/i686/pagemap.cc * DESCRIPTION: Low-level support for i686 page map manipulation * DEVELOPERS: Aiken Harris */ -#include +#include /** @@ -21,26 +21,11 @@ */ XTAPI VOID -MmpClearPte(PHARDWARE_PTE PtePointer) +MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer) { PtePointer->Long = 0; } -/** - * Checks if eXtended Physical Addressing (XPA) is enabled. - * - * @return This routine returns TRUE if PAE is enabled, or FALSE otherwise. - * - * @since XT 1.0 - */ -XTAPI -BOOLEAN -MmpGetExtendedPhysicalAddressingStatus(VOID) -{ - /* Check if PAE is enabled */ - return ((ArReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE; -} - /** * Gets the address of the PDE (Page Directory Entry), that maps given address. * @@ -53,13 +38,13 @@ MmpGetExtendedPhysicalAddressingStatus(VOID) */ XTAPI PMMPDE -MmpGetPdeAddress(PVOID Address) +MM::PageMap::GetPdeAddress(PVOID Address) { ULONG Offset; - /* Calculate offset and return PTE address */ - Offset = ((((ULONG)(Address)) >> MmpPageMapInfo.PdiShift) << MmpPageMapInfo.PteShift); - return (PMMPTE)(MmpPageMapInfo.PdeBase + Offset); + /* Calculate offset and return PDE address */ + Offset = ((((ULONG_PTR)(Address)) >> PageMapInfo.PdiShift) << PageMapInfo.PteShift); + return (PMMPDE)(PageMapInfo.PdeBase + Offset); } /** @@ -74,10 +59,10 @@ MmpGetPdeAddress(PVOID Address) */ XTAPI PMMPPE -MmpGetPpeAddress(PVOID Address) +MM::PageMap::GetPpeAddress(PVOID Address) { /* Return zero */ - return 0; + return (PMMPPE)0; } /** @@ -92,15 +77,38 @@ MmpGetPpeAddress(PVOID Address) */ XTAPI PMMPTE -MmpGetPteAddress(PVOID Address) +MM::PageMap::GetPteAddress(PVOID Address) { ULONG Offset; /* Calculate offset and return PTE address */ - Offset = ((((ULONG)(Address)) >> MM_PTI_SHIFT) << MmpPageMapInfo.PteShift); + Offset = ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) << PageMapInfo.PteShift); return (PMMPTE)(MM_PTE_BASE + Offset); } +/** + * Initializes page map information for basic paging (PML2). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapBasic::InitializePageMapInfo(VOID) +{ + /* Set PML2 page map information */ + PageMapInfo.Xpa = FALSE; + + /* Set PML2 base addresses */ + PageMapInfo.PteBase = MM_PTE_BASE; + PageMapInfo.PdeBase = MM_PDE_LEGACY_BASE; + + /* Set PML2 shift values */ + PageMapInfo.PdiShift = MM_PDI_LEGACY_SHIFT; + PageMapInfo.PteShift = MM_PTE_LEGACY_SHIFT; +} + /** * Checks whether the given PML2 page table entry (PTE) is valid. * @@ -113,7 +121,7 @@ MmpGetPteAddress(PVOID Address) */ XTAPI BOOLEAN -MmpPml2PteValid(PHARDWARE_PTE PtePointer) +MM::PageMapBasic::PteValid(PHARDWARE_PTE PtePointer) { return (BOOLEAN)PtePointer->Pml2.Valid; } @@ -136,9 +144,9 @@ MmpPml2PteValid(PHARDWARE_PTE PtePointer) */ XTAPI VOID -MmpSetPml2Pte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable) +MM::PageMapBasic::SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) { PtePointer->Pml2.PageFrameNumber = PageFrameNumber; PtePointer->Pml2.Valid = 1; @@ -163,14 +171,37 @@ MmpSetPml2Pte(PHARDWARE_PTE PtePointer, */ XTAPI VOID -MmpSetPml2PteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough) +MM::PageMapBasic::SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) { PtePointer->Pml2.CacheDisable = CacheDisable; PtePointer->Pml2.WriteThrough = WriteThrough; } +/** + * Initializes page map information for basic paging (PML3). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapXpa::InitializePageMapInfo(VOID) +{ + /* Set PML2 page map information */ + PageMapInfo.Xpa = TRUE; + + /* Set PML2 base addresses */ + PageMapInfo.PteBase = MM_PTE_BASE; + PageMapInfo.PdeBase = MM_PDE_BASE; + + /* Set PML2 shift values */ + PageMapInfo.PdiShift = MM_PDI_SHIFT; + PageMapInfo.PteShift = MM_PTE_SHIFT; +} + /** * Checks whether the given PML3 page table entry (PTE) is valid. * @@ -183,9 +214,9 @@ MmpSetPml2PteCaching(PHARDWARE_PTE PtePointer, */ XTAPI BOOLEAN -MmpPml3PteValid(PHARDWARE_PTE PtePointer) +MM::PageMapXpa::PteValid(PHARDWARE_PTE PtePointer) { - return PtePointer->Pml3.Valid; + return (BOOLEAN)PtePointer->Pml3.Valid; } /** @@ -206,9 +237,9 @@ MmpPml3PteValid(PHARDWARE_PTE PtePointer) */ XTAPI VOID -MmpSetPml3Pte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable) +MM::PageMapXpa::SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) { PtePointer->Pml3.PageFrameNumber = PageFrameNumber; PtePointer->Pml3.Valid = 1; @@ -233,9 +264,9 @@ MmpSetPml3Pte(PHARDWARE_PTE PtePointer, */ XTAPI VOID -MmpSetPml3PteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough) +MM::PageMapXpa::SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) { PtePointer->Pml3.CacheDisable = CacheDisable; PtePointer->Pml3.WriteThrough = WriteThrough; diff --git a/xtoskrnl/mm/i686/pages.c b/xtoskrnl/mm/i686/paging.cc similarity index 61% rename from xtoskrnl/mm/i686/pages.c rename to xtoskrnl/mm/i686/paging.cc index b0b4fe9..ed85f18 100644 --- a/xtoskrnl/mm/i686/pages.c +++ b/xtoskrnl/mm/i686/paging.cc @@ -1,14 +1,30 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/i686/pages.c + * FILE: xtoskrnl/mm/i686/paging.cc * DESCRIPTION: Architecture dependent paging support * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ -#include +#include +/** + * Checks if eXtended Physical Addressing (XPA) is enabled. + * + * @return This routine returns TRUE if PAE is enabled, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::Paging::GetExtendedPhysicalAddressingStatus(VOID) +{ + /* Check if PAE is enabled */ + return ((AR::CpuFunc::ReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE; +} + /** * Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way. * @@ -24,8 +40,8 @@ */ XTFASTCALL VOID -MmZeroPages(IN PVOID Address, - IN ULONG Size) +MM::Paging::ZeroPages(IN PVOID Address, + IN ULONG Size) { __asm__ volatile("xor %%eax, %%eax\n" "rep stosb" diff --git a/xtoskrnl/mm/init.c b/xtoskrnl/mm/init.cc similarity index 70% rename from xtoskrnl/mm/init.c rename to xtoskrnl/mm/init.cc index 3225c16..dfe54b3 100644 --- a/xtoskrnl/mm/init.c +++ b/xtoskrnl/mm/init.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/init.c + * FILE: xtoskrnl/mm/init.cc * DESCRIPTION: Memory Manager initialization routines * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,13 +18,13 @@ */ XTAPI VOID -MmInitializeMemoryManager(VOID) +MM::Init::InitializeMemoryManager(VOID) { /* Scan memory descriptors provided by the boot loader */ - MmpScanMemoryDescriptors(); + ScanMemoryDescriptors(); /* Check if there are enough physical pages */ - if(MmNumberOfPhysicalPages < MM_MINIMUM_PHYSICAL_PAGES) + if(NumberOfPhysicalPages < MM_MINIMUM_PHYSICAL_PAGES) { /* Insufficient physical pages, kernel panic */ DebugPrint(L"Insufficient physical pages! Install additional memory\n"); @@ -32,7 +32,7 @@ MmInitializeMemoryManager(VOID) } /* Proceed with architecture specific initialization */ - MmpInitializeArchitecture(); + InitializeArchitecture(); } /** @@ -44,7 +44,7 @@ MmInitializeMemoryManager(VOID) */ XTAPI VOID -MmpScanMemoryDescriptors(VOID) +MM::Init::ScanMemoryDescriptors(VOID) { PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor; PLIST_ENTRY MemoryMappings; @@ -61,7 +61,7 @@ MmpScanMemoryDescriptors(VOID) MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry); /* Check if memory type is invisible or cached */ - if(MmpVerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType) || + if(VerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType) || (MemoryDescriptor->MemoryType == LoaderHardwareCachedMemory)) { /* Skip this mapping */ @@ -73,32 +73,32 @@ MmpScanMemoryDescriptors(VOID) if(MemoryDescriptor->MemoryType != LoaderBad) { /* Increment number of physical pages */ - MmNumberOfPhysicalPages += MemoryDescriptor->PageCount; + NumberOfPhysicalPages += MemoryDescriptor->PageCount; } /* Find lowest physical page */ - if(MemoryDescriptor->BasePage < MmLowestPhysicalPage) + if(MemoryDescriptor->BasePage < LowestPhysicalPage) { /* Update lowest physical page */ - MmLowestPhysicalPage = MemoryDescriptor->BasePage; + LowestPhysicalPage = MemoryDescriptor->BasePage; } /* Find highest physical page */ - if(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > MmHighestPhysicalPage) + if(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > HighestPhysicalPage) { /* Update highest physical page */ - MmHighestPhysicalPage = (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) - 1; + HighestPhysicalPage = (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) - 1; } /* Check if memory type should be considered as free */ - if(MmpVerifyMemoryTypeFree(MemoryDescriptor->MemoryType)) + if(VerifyMemoryTypeFree(MemoryDescriptor->MemoryType)) { /* Check if this descriptor contains more free pages */ if(MemoryDescriptor->PageCount >= FreePages) { /* Update free descriptor */ FreePages = MemoryDescriptor->PageCount; - MmFreeDescriptor = MemoryDescriptor; + FreeDescriptor = MemoryDescriptor; } } @@ -107,7 +107,7 @@ MmpScanMemoryDescriptors(VOID) } /* Store original free descriptor */ - RtlCopyMemory(&MmOldFreeDescriptor, MmFreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR)); + RTL::Memory::CopyMemory(&OldFreeDescriptor, FreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR)); } /** Checks whether the specified memory type should be considered as free. @@ -121,10 +121,10 @@ MmpScanMemoryDescriptors(VOID) */ XTAPI BOOLEAN -MmpVerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType) +MM::Init::VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType) { - return (MemoryType == LoaderFree) || (MemoryType == LoaderFirmwareTemporary) || - (MemoryType == LoaderLoadedProgram) || (MemoryType == LoaderOsloaderStack); + return (BOOLEAN)((MemoryType == LoaderFree) || (MemoryType == LoaderFirmwareTemporary) || + (MemoryType == LoaderLoadedProgram) || (MemoryType == LoaderOsloaderStack)); } /** @@ -139,9 +139,9 @@ MmpVerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType) */ XTAPI BOOLEAN -MmpVerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType) +MM::Init::VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType) { - return (MemoryType == LoaderFirmwarePermanent) || - (MemoryType == LoaderSpecialMemory) || - (MemoryType == LoaderBBTMemory); + return (BOOLEAN)((MemoryType == LoaderFirmwarePermanent) || + (MemoryType == LoaderSpecialMemory) || + (MemoryType == LoaderBBTMemory)); } diff --git a/xtoskrnl/mm/kpools.c b/xtoskrnl/mm/kpool.cc similarity index 78% rename from xtoskrnl/mm/kpools.c rename to xtoskrnl/mm/kpool.cc index 5acea49..f72b74e 100644 --- a/xtoskrnl/mm/kpools.c +++ b/xtoskrnl/mm/kpool.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/kpools.c + * FILE: xtoskrnl/mm/kpool.cc * DESCRIPTION: Kernel pool memory management * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -27,9 +27,9 @@ */ XTAPI XTSTATUS -MmAllocateKernelStack(IN PVOID *Stack, - IN BOOLEAN LargeStack, - IN UCHAR SystemNode) +MM::KernelPool::AllocateKernelStack(IN PVOID *Stack, + IN BOOLEAN LargeStack, + IN UCHAR SystemNode) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; @@ -50,8 +50,8 @@ MmAllocateKernelStack(IN PVOID *Stack, */ XTAPI XTSTATUS -MmAllocateProcessorStructures(IN ULONG CpuNumber, - OUT PVOID *StructuresData) +MM::KernelPool::AllocateProcessorStructures(IN ULONG CpuNumber, + OUT PVOID *StructuresData) { PKPROCESSOR_BLOCK ProcessorBlock; PVOID ProcessorStructures; @@ -61,10 +61,10 @@ MmAllocateProcessorStructures(IN ULONG CpuNumber, UNIMPLEMENTED; /* Assign memory for processor structures from preallocated buffer */ - ProcessorStructures = &MmProcessorStructuresData[CpuNumber - 1]; + ProcessorStructures = &ProcessorStructuresData[CpuNumber - 1]; /* Make sure all structures are zeroed */ - RtlZeroMemory(ProcessorStructures, KPROCESSOR_STRUCTURES_SIZE); + RTL::Memory::ZeroMemory(ProcessorStructures, KPROCESSOR_STRUCTURES_SIZE); /* Align address to page size boundary and find a space for processor block */ Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE); @@ -95,8 +95,8 @@ MmAllocateProcessorStructures(IN ULONG CpuNumber, */ XTAPI VOID -MmFreeKernelStack(IN PVOID Stack, - IN BOOLEAN LargeStack) +MM::KernelPool::FreeKernelStack(IN PVOID Stack, + IN BOOLEAN LargeStack) { UNIMPLEMENTED; } @@ -113,7 +113,7 @@ MmFreeKernelStack(IN PVOID Stack, */ XTAPI VOID -MmFreeProcessorStructures(IN PVOID StructuresData) +MM::KernelPool::FreeProcessorStructures(IN PVOID StructuresData) { UNIMPLEMENTED; } diff --git a/xtoskrnl/mm/pages.c b/xtoskrnl/mm/pages.c deleted file mode 100644 index 13bbd58..0000000 --- a/xtoskrnl/mm/pages.c +++ /dev/null @@ -1,62 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/pages.c - * DESCRIPTION: Low level page management support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Flushes current Translation Lookaside Buffer (TLB) - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmFlushTlb(VOID) -{ - CPUID_REGISTERS CpuRegisters; - BOOLEAN Interrupts; - ULONG_PTR Cr4; - - /* Save interrupts state and disable them */ - Interrupts = ArInterruptsEnabled(); - ArClearInterruptFlag(); - - /* Get CPU features */ - CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; - ArCpuId(&CpuRegisters); - - /* Check if Paging Global Extensions (PGE) is supported */ - if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) - { - /* Read CR4 */ - Cr4 = ArReadControlRegister(4); - - /* Disable PGE */ - ArWriteControlRegister(4, Cr4 & ~CR4_PGE); - - /* Flush the TLB */ - ArFlushTlb(); - - /* Restore CR4 */ - ArWriteControlRegister(4, Cr4); - } - else - { - /* Simply flush the TLB */ - ArFlushTlb(); - } - - /* Check if interrupts should be enabled */ - if(Interrupts) - { - /* Re-enable interrupts */ - ArSetInterruptFlag(); - } -} diff --git a/xtoskrnl/mm/paging.cc b/xtoskrnl/mm/paging.cc new file mode 100644 index 0000000..58833b1 --- /dev/null +++ b/xtoskrnl/mm/paging.cc @@ -0,0 +1,254 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/paging.cc + * DESCRIPTION: Low level page management support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Clears the contents of a page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to be cleared. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::ClearPte(PHARDWARE_PTE PtePointer) +{ + PmlRoutines->ClearPte(PtePointer); +} + +/** + * Flushes current Translation Lookaside Buffer (TLB) + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::FlushTlb(VOID) +{ + CPUID_REGISTERS CpuRegisters; + BOOLEAN Interrupts; + ULONG_PTR Cr4; + + /* Save interrupts state and disable them */ + Interrupts = AR::CpuFunc::InterruptsEnabled(); + AR::CpuFunc::ClearInterruptFlag(); + + /* Get CPU features */ + CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; + AR::CpuFunc::CpuId(&CpuRegisters); + + /* Check if Paging Global Extensions (PGE) is supported */ + if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) + { + /* Read CR4 */ + Cr4 = AR::CpuFunc::ReadControlRegister(4); + + /* Disable PGE */ + AR::CpuFunc::WriteControlRegister(4, Cr4 & ~CR4_PGE); + + /* Flush the TLB */ + AR::CpuFunc::FlushTlb(); + + /* Restore CR4 */ + AR::CpuFunc::WriteControlRegister(4, Cr4); + } + else + { + /* Simply flush the TLB */ + AR::CpuFunc::FlushTlb(); + } + + /* Check if interrupts should be enabled */ + if(Interrupts) + { + /* Re-enable interrupts */ + AR::CpuFunc::SetInterruptFlag(); + } +} + +/** + * Gets the page map routines for basic paging mode (non-XPA). + * + * @return This routine returns the address of the object containing non-XPA page map routines. + * + * @since XT 1.0 + */ +XTAPI +MM::PPAGEMAP +MM::Paging::GetPageMapBasicRoutines(VOID) +{ + static MM::PageMapBasic PageMapBasicRoutines; + return &PageMapBasicRoutines; +} + +/** + * Gets the page map routines for eXtended Physical Addressing (XPA) mode. + * + * @return This routine returns the address of the object containing XPA page map routines. + * + * @since XT 1.0 + */ +XTAPI +MM::PPAGEMAP +MM::Paging::GetPageMapXpaRoutines(VOID) +{ + static MM::PageMapXpa PageMapXpaRoutines; + return &PageMapXpaRoutines; +} + +/** + * Gets the address of the PDE (Page Directory Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PDE. + * + * @return This routine returns the address of the PDE. + * + * @since XT 1.0 + */ +XTAPI +PMMPDE +MM::Paging::GetPdeAddress(PVOID Address) +{ + return PmlRoutines->GetPdeAddress(Address); +} + +/** + * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PDE. + * + * @return This routine returns the address of the PPE. + * + * @since XT 1.0 + */ +XTAPI +PMMPPE +MM::Paging::GetPpeAddress(PVOID Address) +{ + return PmlRoutines->GetPpeAddress(Address); +} + +/** + * Gets the address of the PTE (Page Table Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PTE. + * + * @return This routine returns the address of the PTE. + * + * @since XT 1.0 + */ +XTAPI +PMMPTE +MM::Paging::GetPteAddress(PVOID Address) +{ + return PmlRoutines->GetPteAddress(Address); +} + +/** + * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::InitializePageMapSupport(VOID) +{ + /* Check if XPA is enabled */ + if(GetExtendedPhysicalAddressingStatus()) + { + /* XPA enabled, use modern paging (PAE / LA57) */ + PmlRoutines = GetPageMapXpaRoutines(); + } + else + { + /* XPA disabled, use basic paging (PML2 / PML4) */ + PmlRoutines = GetPageMapBasicRoutines(); + } + + /* Set page map information */ + PmlRoutines->InitializePageMapInfo(); +} + +/** + * Checks whether the given PML2 page table entry (PTE) is valid. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to check. + * + * @return Returns TRUE if the entry is valid, FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::Paging::PteValid(PHARDWARE_PTE PtePointer) +{ + return PmlRoutines->PteValid(PtePointer); +} + +/** + * Sets a PML2 page table entry (PTE) with the specified physical page and access flags. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param PageFrameNumber + * Physical frame number to map. + * + * @param Writable + * Indicates whether the page should be writable. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) +{ + PmlRoutines->SetPte(PtePointer, PageFrameNumber, Writable); +} + +/** + * Sets caching attributes for a PML2 page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to modify. + * + * @param CacheDisable + * Indicates whether caching should be disabled for this page. + * + * @param WriteThrough + * Indicates whether write-through caching should be enabled. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) +{ + PmlRoutines->SetPteCaching(PtePointer, CacheDisable, WriteThrough); +}