diff --git a/xtoskrnl/includes/mm/amd64/paging.hh b/xtoskrnl/includes/mm/amd64/paging.hh index 5a39583..6f927bb 100644 --- a/xtoskrnl/includes/mm/amd64/paging.hh +++ b/xtoskrnl/includes/mm/amd64/paging.hh @@ -51,6 +51,9 @@ namespace MM STATIC XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer); STATIC XTAPI BOOLEAN GetXpaStatus(VOID); STATIC XTAPI VOID InitializePageMapSupport(VOID); + STATIC XTAPI XTSTATUS MapVirtualAddress(IN PVOID VirtualAddress, + IN PFN_NUMBER PageFrameNumber, + IN ULONGLONG Attributes); STATIC XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer); STATIC XTAPI VOID SetNextEntry(IN PMMPTE Pte, IN ULONG_PTR Value); diff --git a/xtoskrnl/includes/mm/i686/paging.hh b/xtoskrnl/includes/mm/i686/paging.hh index 7487c06..3924111 100644 --- a/xtoskrnl/includes/mm/i686/paging.hh +++ b/xtoskrnl/includes/mm/i686/paging.hh @@ -47,6 +47,9 @@ namespace MM STATIC XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer); STATIC XTAPI BOOLEAN GetXpaStatus(VOID); STATIC XTAPI VOID InitializePageMapSupport(VOID); + STATIC XTAPI XTSTATUS MapVirtualAddress(IN PVOID VirtualAddress, + IN PFN_NUMBER PageFrameNumber, + IN ULONGLONG Attributes); STATIC XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer); STATIC XTAPI VOID SetNextEntry(IN PMMPTE Pte, IN ULONG_PTR Value); diff --git a/xtoskrnl/mm/amd64/paging.cc b/xtoskrnl/mm/amd64/paging.cc index a04e007..62bfcc8 100644 --- a/xtoskrnl/mm/amd64/paging.cc +++ b/xtoskrnl/mm/amd64/paging.cc @@ -97,6 +97,64 @@ MM::Paging::GetPxeVirtualAddress(IN PMMPXE PxePointer) return PmlRoutines->GetPxeVirtualAddress(PxePointer); } +/** + * Maps a specific virtual address to a specific physical page frame. + * + * @param VirtualAddress + * The virtual address to map. + * + * @param PageFrameNumber + * The physical frame number to back the virtual address. + * + * @param Attributes + * Specifies the attributes (protections, caching) to apply to the PTE. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +MM::Paging::MapVirtualAddress(IN PVOID VirtualAddress, + IN PFN_NUMBER PageFrameNumber, + IN ULONGLONG Attributes) +{ + MMPTE TemplatePte; + PMMPTE PointerPte; + + /* Initialize the template PTE */ + MM::Paging::ClearPte(&TemplatePte); + MM::Paging::SetPte(&TemplatePte, 0, Attributes | MM_PTE_CACHE_ENABLE); + + /* Check if XPA is enabled */ + if(MM::Paging::GetXpaStatus()) + { + /* Map Page 5-level Entry*/ + MM::Pte::MapP5E(VirtualAddress, VirtualAddress, (PMMP5E)&TemplatePte); + } + + /* Map PXE, PPE and PDE for the corresponding virtual address */ + MM::Pte::MapPXE(VirtualAddress, VirtualAddress, (PMMPXE)&TemplatePte); + MM::Pte::MapPPE(VirtualAddress, VirtualAddress, (PMMPPE)&TemplatePte); + MM::Pte::MapPDE(VirtualAddress, VirtualAddress, (PMMPDE)&TemplatePte); + + /* Get PTE address */ + PointerPte = MM::Paging::GetPteAddress(VirtualAddress); + + /* Initialize the template PTE */ + MM::Paging::ClearPte(&TemplatePte); + MM::Paging::SetPte(&TemplatePte, PageFrameNumber, Attributes); + + /* Write the PTE */ + MM::Paging::WritePte(PointerPte, TemplatePte); + + /* Flush the TLB to reflect the changes */ + MM::Paging::FlushTlb(); + + /* Return success */ + return STATUS_SUCCESS; +} + /** * Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way. * diff --git a/xtoskrnl/mm/i686/paging.cc b/xtoskrnl/mm/i686/paging.cc index ed85f18..1be0f18 100644 --- a/xtoskrnl/mm/i686/paging.cc +++ b/xtoskrnl/mm/i686/paging.cc @@ -25,6 +25,62 @@ MM::Paging::GetExtendedPhysicalAddressingStatus(VOID) return ((AR::CpuFunc::ReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE; } +/** + * Maps a specific virtual address to a specific physical page frame (i686 specific). + * + * @param VirtualAddress + * The virtual address to map. + * + * @param PageFrameNumber + * The physical frame number to back the virtual address. + * + * @param Attributes + * Specifies the attributes (protections, caching) to apply to the PTE. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +MM::Paging::MapVirtualAddress(IN PVOID VirtualAddress, + IN PFN_NUMBER PageFrameNumber, + IN ULONGLONG Attributes) +{ + MMPTE TemplatePte; + PMMPTE PointerPte; + + /* Initialize the template PTE */ + MM::Paging::ClearPte(&TemplatePte); + MM::Paging::SetPte(&TemplatePte, 0, Attributes | MM_PTE_CACHE_ENABLE); + + /* Check if XPA is enabled */ + if(MM::Paging::GetXpaStatus()) + { + /* Map Page Directory Pointer Table */ + MM::Pte::MapPPE(VirtualAddress, VirtualAddress, (PMMPPE)&TemplatePte); + } + + /* Map Page Directory Entry */ + MM::Pte::MapPDE(VirtualAddress, VirtualAddress, (PMMPDE)&TemplatePte); + + /* Get PTE address */ + PointerPte = MM::Paging::GetPteAddress(VirtualAddress); + + /* Initialize the template PTE */ + MM::Paging::ClearPte(&TemplatePte); + MM::Paging::SetPte(&TemplatePte, PageFrameNumber, Attributes); + + /* Write the PTE */ + MM::Paging::WritePte(PointerPte, TemplatePte); + + /* Flush the TLB to reflect the changes */ + MM::Paging::FlushTlb(); + + /* Return success */ + return STATUS_SUCCESS; +} + /** * Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way. *