From d687d8ac70249aa14a983002e52b643836f76b2d Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Wed, 4 Jul 2012 19:57:48 +0100 Subject: [PATCH] Implementation of VMPhysicalPageMapper for x86_64 using the permanent physical memory mapping. --- src/system/kernel/arch/x86/Jamfile | 2 +- .../x86_physical_page_mapper_mapped.cpp | 228 ++++++++++++++++++ 2 files changed, 229 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/arch/x86/Jamfile b/src/system/kernel/arch/x86/Jamfile index a67e4204f3..c45f2d1f12 100644 --- a/src/system/kernel/arch/x86/Jamfile +++ b/src/system/kernel/arch/x86/Jamfile @@ -26,7 +26,7 @@ if $(TARGET_ARCH) = x86_64 { stubs.cpp # paging - #x86_physical_page_mapper_mapped.cpp + x86_physical_page_mapper_mapped.cpp # paging/64bit X86PagingMethod64Bit.cpp diff --git a/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.cpp b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.cpp index 45f270c10b..d74fb7cd7a 100644 --- a/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.cpp +++ b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -27,3 +28,230 @@ #include "paging/X86PagingStructures.h" #include "paging/X86VMTranslationMap.h" + +// #pragma mark - + + +class MappedTranslationMapPhysicalPageMapper + : public TranslationMapPhysicalPageMapper { +public: + virtual void Delete(); + + virtual void* GetPageTableAt(phys_addr_t physicalAddress); +}; + + +class MappedPhysicalPageMapper : public X86PhysicalPageMapper { +public: + virtual status_t CreateTranslationMapPhysicalPageMapper( + TranslationMapPhysicalPageMapper** _mapper); + + virtual void* InterruptGetPageTableAt( + phys_addr_t physicalAddress); + + virtual status_t GetPage(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle); + virtual status_t PutPage(addr_t virtualAddress, void* handle); + + virtual status_t GetPageCurrentCPU(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle); + virtual status_t PutPageCurrentCPU(addr_t virtualAddress, + void* handle); + + virtual status_t GetPageDebug(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle); + virtual status_t PutPageDebug(addr_t virtualAddress, + void* handle); + + virtual status_t MemsetPhysical(phys_addr_t address, int value, + phys_size_t length); + virtual status_t MemcpyFromPhysical(void* to, phys_addr_t from, + size_t length, bool user); + virtual status_t MemcpyToPhysical(phys_addr_t to, + const void* from, size_t length, bool user); + virtual void MemcpyPhysicalPage(phys_addr_t to, + phys_addr_t from); +}; + + +static MappedPhysicalPageMapper sPhysicalPageMapper; +static MappedTranslationMapPhysicalPageMapper sKernelPageMapper; + + +// #pragma mark - MappedTranslationMapPhysicalPageMapper + + +void +MappedTranslationMapPhysicalPageMapper::Delete() +{ + delete this; +} + + +void* +MappedTranslationMapPhysicalPageMapper::GetPageTableAt( + phys_addr_t physicalAddress) +{ + ASSERT(physicalAddress % B_PAGE_SIZE == 0); + + return (void*)(physicalAddress + KERNEL_PMAP_BASE); +} + + +// #pragma mark - MappedPhysicalPageMapper + + +status_t +MappedPhysicalPageMapper::CreateTranslationMapPhysicalPageMapper( + TranslationMapPhysicalPageMapper** _mapper) +{ + MappedTranslationMapPhysicalPageMapper* mapper + = new(std::nothrow) MappedTranslationMapPhysicalPageMapper; + if (mapper == NULL) + return B_NO_MEMORY; + + *_mapper = mapper; + return B_OK; +} + + +void* +MappedPhysicalPageMapper::InterruptGetPageTableAt( + phys_addr_t physicalAddress) +{ + ASSERT(physicalAddress % B_PAGE_SIZE == 0); + + return (void*)(physicalAddress + KERNEL_PMAP_BASE); +} + + +status_t +MappedPhysicalPageMapper::GetPage(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle) +{ + if (physicalAddress >= KERNEL_PMAP_BASE) + return B_BAD_ADDRESS; + + *virtualAddress = physicalAddress + KERNEL_PMAP_BASE; + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::PutPage(addr_t virtualAddress, void* handle) +{ + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::GetPageCurrentCPU(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle) +{ + if (physicalAddress >= KERNEL_PMAP_BASE) + return B_BAD_ADDRESS; + + *virtualAddress = physicalAddress + KERNEL_PMAP_BASE; + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::PutPageCurrentCPU(addr_t virtualAddress, + void* handle) +{ + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::GetPageDebug(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle) +{ + if (physicalAddress >= KERNEL_PMAP_BASE) + return B_BAD_ADDRESS; + + *virtualAddress = physicalAddress + KERNEL_PMAP_BASE; + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::PutPageDebug(addr_t virtualAddress, void* handle) +{ + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::MemsetPhysical(phys_addr_t address, int value, + phys_size_t length) +{ + if (address >= KERNEL_PMAP_SIZE || address + length > KERNEL_PMAP_SIZE) + return B_BAD_ADDRESS; + + memset((void*)(address + KERNEL_PMAP_BASE), value, length); + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::MemcpyFromPhysical(void* to, phys_addr_t _from, + size_t length, bool user) +{ + if (_from >= KERNEL_PMAP_SIZE || _from + length > KERNEL_PMAP_SIZE) + return B_BAD_ADDRESS; + + void* from = (void*)(_from + KERNEL_PMAP_BASE); + + if (user) + return user_memcpy(to, from, length); + else + memcpy(to, from, length); + + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::MemcpyToPhysical(phys_addr_t _to, const void* from, + size_t length, bool user) +{ + if (_to >= KERNEL_PMAP_SIZE || _to + length > KERNEL_PMAP_SIZE) + return B_BAD_ADDRESS; + + void* to = (void*)(_to + KERNEL_PMAP_BASE); + + if (user) + return user_memcpy(to, from, length); + else + memcpy(to, from, length); + + return B_OK; +} + + +void +MappedPhysicalPageMapper::MemcpyPhysicalPage(phys_addr_t to, + phys_addr_t from) +{ + memcpy((void*)(to + KERNEL_PMAP_BASE), (void*)(from + KERNEL_PMAP_BASE), + B_PAGE_SIZE); +} + + +// #pragma mark - Initialization + + +status_t +mapped_physical_page_ops_init(kernel_args* args, + X86PhysicalPageMapper*& _pageMapper, + TranslationMapPhysicalPageMapper*& _kernelPageMapper) +{ + new(&sPhysicalPageMapper) MappedPhysicalPageMapper; + new(&sKernelPageMapper) MappedTranslationMapPhysicalPageMapper; + + _pageMapper = &sPhysicalPageMapper; + _kernelPageMapper = &sKernelPageMapper; + return B_OK; +}