Files
exectos/xtoskrnl/mm/paging.cc
Aiken Harris 1150b9ecdb
Todas las comprobaciones han sido exitosas
Builds / ExectOS (amd64, debug) (push) Successful in 31s
Builds / ExectOS (amd64, release) (push) Successful in 30s
Builds / ExectOS (i686, debug) (push) Successful in 28s
Builds / ExectOS (i686, release) (push) Successful in 27s
Add PTE management routines
2025-10-30 22:03:25 +01:00

416 líneas
8.8 KiB
C++

/**
* 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 <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/**
* Advances a PTE pointer by a given number of entries, considering the actual PTE size.
*
* @param Pte
* The PTE pointer to advance.
*
* @param Count
* The number of PTE entries to advance by.
*
* @return The advanced PTE pointer.
*
* @since XT 1.0
*/
XTAPI
PMMPTE
MM::Paging::AdvancePte(PMMPTE Pte,
ULONG Count)
{
/* Return advanced PTE pointer */
return PmlRoutines->AdvancePte(Pte, Count);
}
/**
* 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)
{
/* Clear PTE */
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 value representing an empty PTE list.
*
* @return This routine returns the value representing an empty PTE list.
*
* @since XT 1.0
*/
XTAPI
ULONG_PTR
MM::Paging::GetEmptyPteList(VOID)
{
/* Return empty PTE list mask */
return (ULONG_PTR)PmlRoutines->GetEmptyPteList();
}
/**
* Gets the next entry in a PTE list.
*
* @param Pte
* The PTE pointer to get the next entry from.
*
* @return This routine returns the next entry in the PTE list.
*
* @since XT 1.0
*/
XTAPI
ULONG_PTR
MM::Paging::GetNextEntry(PMMPTE Pte)
{
/* Return next entry in PTE list */
return PmlRoutines->GetNextEntry(Pte);
}
/**
* Advances a PTE pointer, considering the actual PTE size.
*
* @param Pte
* The PTE pointer to advance.
*
* @return The advanced PTE pointer.
*
* @since XT 1.0
*/
XTAPI
PMMPTE
MM::Paging::GetNextPte(PMMPTE Pte)
{
/* Return advanced PTE pointer */
return PmlRoutines->GetNextPte(Pte);
}
/**
* Checks if a PTE list contains only one entry.
*
* @param Pte
* The PTE pointer to check.
*
* @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
MM::Paging::GetOneEntry(PMMPTE Pte)
{
/* Return one entry status */
return PmlRoutines->GetOneEntry(Pte);
}
/**
* 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 non-XPA page map routines */
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 XPA page map routines */
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 PDE 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 PPE 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 PTE address */
return PmlRoutines->GetPteAddress(Address);
}
/**
* Gets the size of a PTE.
*
* @return This routine returns the size of a PTE.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::Paging::GetPteSize(VOID)
{
/* Return the size of MMPTE */
return PmlRoutines->GetPteSize();
}
/**
* 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)
{
/* Check if PTE is valid */
return PmlRoutines->PteValid(PtePointer);
}
/**
* Sets the next entry in a PTE list.
*
* @param Pte
* The PTE pointer to modify.
*
* @param Value
* The value to set as the next entry.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Paging::SetNextEntry(PMMPTE Pte,
ULONG_PTR Value)
{
/* Set next entry in PTE list */
PmlRoutines->SetNextEntry(Pte, Value);
}
/**
* Sets the flag indicating whether a PTE list contains only one entry.
*
* @param Pte
* The PTE pointer to modify.
*
* @param Value
* The value to set. TRUE if the list has only one entry, FALSE otherwise.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Paging::SetOneEntry(PMMPTE Pte,
BOOLEAN Value)
{
/* Set one entry status */
PmlRoutines->SetOneEntry(Pte, Value);
}
/**
* 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)
{
/* Set PTE */
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)
{
/* Set caching attributes */
PmlRoutines->SetPteCaching(PtePointer, CacheDisable, WriteThrough);
}