[haiku-commits] r37100 - haiku/trunk/src/system/kernel/arch/x86/paging/pae

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 11 Jun 2010 18:21:13 +0200 (CEST)

Author: bonefish
Date: 2010-06-11 18:21:13 +0200 (Fri, 11 Jun 2010)
New Revision: 37100
Changeset: http://dev.haiku-os.org/changeset/37100/haiku

Modified:
   haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86PagingStructuresPAE.cpp
   haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86PagingStructuresPAE.h
   haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp
Log:
* Implemented X86VMTranslationMapPAE and X86PagingStructuresPAE destruction.
* Implemented X86VMTranslationMapPAE::QueryInterrupt().


Modified: 
haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86PagingStructuresPAE.cpp
===================================================================
--- 
haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86PagingStructuresPAE.cpp    
    2010-06-11 15:35:07 UTC (rev 37099)
+++ 
haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86PagingStructuresPAE.cpp    
    2010-06-11 16:21:13 UTC (rev 37100)
@@ -6,34 +6,46 @@
 
 #include "paging/pae/X86PagingStructuresPAE.h"
 
+#include <stdlib.h>
 #include <string.h>
 
 #include <KernelExport.h>
 
+#include <int.h>
 
+#include "paging/pae/X86PagingMethodPAE.h"
+
+
 #if B_HAIKU_PHYSICAL_BITS == 64
 
 
 X86PagingStructuresPAE::X86PagingStructuresPAE()
 {
+       fVirtualPageDirs[0] = NULL;
 }
 
 
 X86PagingStructuresPAE::~X86PagingStructuresPAE()
 {
-// TODO: Implement!
-       panic("X86PagingStructuresPAE::~X86PagingStructuresPAE(): not 
implemented");
+       // free the user page dirs
+       free(fVirtualPageDirs[0]);
+
+       // free the PDPT page
+       X86PagingMethodPAE::Method()->Free32BitPage(fPageDirPointerTable,
+               pgdir_phys, fPageDirPointerTableHandle);
 }
 
 
 void
 X86PagingStructuresPAE::Init(
        pae_page_directory_pointer_table_entry* virtualPDPT,
-       phys_addr_t physicalPDPT, pae_page_directory_entry* const* 
virtualPageDirs,
+       phys_addr_t physicalPDPT, void* pdptHandle,
+       pae_page_directory_entry* const* virtualPageDirs,
        const phys_addr_t* physicalPageDirs)
 {
        fPageDirPointerTable = virtualPDPT;
        pgdir_phys = physicalPDPT;
+       fPageDirPointerTableHandle = pdptHandle;
        memcpy(fVirtualPageDirs, virtualPageDirs, sizeof(fVirtualPageDirs));
        memcpy(fPhysicalPageDirs, physicalPageDirs, sizeof(fPhysicalPageDirs));
 }
@@ -42,8 +54,10 @@
 void
 X86PagingStructuresPAE::Delete()
 {
-// TODO: Implement!
-       panic("X86PagingStructuresPAE::Delete(): not implemented");
+       if (are_interrupts_enabled())
+               delete this;
+       else
+               deferred_delete(this);
 }
 
 

Modified: 
haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86PagingStructuresPAE.h
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86PagingStructuresPAE.h  
2010-06-11 15:35:07 UTC (rev 37099)
+++ haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86PagingStructuresPAE.h  
2010-06-11 16:21:13 UTC (rev 37100)
@@ -19,7 +19,7 @@
 
                        void                            
Init(pae_page_directory_pointer_table_entry*
                                                                                
virtualPDPT,
-                                                                        
phys_addr_t physicalPDPT,
+                                                                        
phys_addr_t physicalPDPT, void* pdptHandle,
                                                                         
pae_page_directory_entry* const*
                                                                                
virtualPageDirs,
                                                                         const 
phys_addr_t* physicalPageDirs);
@@ -31,6 +31,7 @@
 
 private:
                        pae_page_directory_pointer_table_entry* 
fPageDirPointerTable;
+                       void*                           
fPageDirPointerTableHandle;
                        pae_page_directory_entry* fVirtualPageDirs[4];
                        phys_addr_t                     fPhysicalPageDirs[4];
 };

Modified: 
haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp
===================================================================
--- 
haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp    
    2010-06-11 15:35:07 UTC (rev 37099)
+++ 
haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp    
    2010-06-11 16:21:13 UTC (rev 37100)
@@ -43,7 +43,40 @@
 
 X86VMTranslationMapPAE::~X86VMTranslationMapPAE()
 {
-// TODO: Implement!
+       if (fPagingStructures == NULL)
+               return;
+
+       if (fPageMapper != NULL)
+               fPageMapper->Delete();
+
+       // cycle through and free all of the user space page tables
+
+       STATIC_ASSERT(KERNEL_BASE == 0x80000000 && KERNEL_SIZE == 0x80000000);
+               // assuming 1-1 split of the address space
+
+       for (uint32 k = 0; k < 2; k++) {
+               pae_page_directory_entry* pageDir
+                       = fPagingStructures->VirtualPageDirs()[k];
+               if (pageDir == NULL)
+                       continue;
+
+               for (uint32 i = 0; i < kPAEPageDirEntryCount; i++) {
+                       if ((pageDir[i] & X86_PAE_PDE_PRESENT) != 0) {
+                               phys_addr_t address = pageDir[i] & 
X86_PAE_PDE_ADDRESS_MASK;
+                               vm_page* page = vm_lookup_page(address / 
B_PAGE_SIZE);
+                               if (page == NULL)
+                                       
panic("X86VMTranslationMapPAE::~X86VMTranslationMapPAE: "
+                                               "didn't find page table page: 
page address: %#"
+                                               B_PRIxPHYSADDR ", virtual base: 
%#" B_PRIxADDR "\n",
+                                               address,
+                                               (k * kPAEPageDirEntryCount + i) 
* kPAEPageTableRange);
+                               DEBUG_PAGE_ACCESS_START(page);
+                               vm_page_set_state(page, PAGE_STATE_FREE);
+                       }
+               }
+       }
+
+       fPagingStructures->RemoveReference();
 }
 
 
@@ -67,7 +100,7 @@
 
                // we already know the kernel pgdir mapping
                
fPagingStructures->Init(method->KernelVirtualPageDirPointerTable(),
-                       method->KernelPhysicalPageDirPointerTable(),
+                       method->KernelPhysicalPageDirPointerTable(), NULL,
                        method->KernelVirtualPageDirs(), 
method->KernelPhysicalPageDirs());
        } else {
                // user
@@ -124,7 +157,7 @@
                }
 
                // init the paging structures
-               fPagingStructures->Init(pdpt, physicalPDPT, virtualPageDirs,
+               fPagingStructures->Init(pdpt, physicalPDPT, pdptHandle, 
virtualPageDirs,
                        physicalPageDirs);
        }
 
@@ -455,12 +488,48 @@
 
 
 status_t
-X86VMTranslationMapPAE::QueryInterrupt(addr_t va, phys_addr_t *_physical,
-       uint32 *_flags)
+X86VMTranslationMapPAE::QueryInterrupt(addr_t virtualAddress,
+       phys_addr_t* _physicalAddress, uint32* _flags)
 {
-// TODO: Implement!
-       panic("X86VMTranslationMapPAE::QueryInterrupt(): not implemented");
-       return B_UNSUPPORTED;
+       // default the flags to not present
+       *_flags = 0;
+       *_physicalAddress = 0;
+
+       // get the page directory entry
+       pae_page_directory_entry* pageDirEntry
+               = X86PagingMethodPAE::PageDirEntryForAddress(
+                       fPagingStructures->VirtualPageDirs(), virtualAddress);
+       if ((*pageDirEntry & X86_PAE_PDE_PRESENT) == 0) {
+               // no pagetable here
+               return B_OK;
+       }
+
+       // get the page table entry
+       pae_page_table_entry* pageTable
+               = (pae_page_table_entry*)X86PagingMethodPAE::Method()
+                       ->PhysicalPageMapper()->InterruptGetPageTableAt(
+                               *pageDirEntry & X86_PAE_PDE_ADDRESS_MASK);
+       pae_page_table_entry entry
+               = pageTable[virtualAddress / B_PAGE_SIZE % 
kPAEPageTableEntryCount];
+
+       *_physicalAddress = entry & X86_PAE_PTE_ADDRESS_MASK;
+
+       // translate the page state flags
+       if ((entry & X86_PAE_PTE_USER) != 0) {
+               *_flags |= ((entry & X86_PAE_PTE_WRITABLE) != 0 ? B_WRITE_AREA 
: 0)
+                       | B_READ_AREA;
+       }
+
+       *_flags |= ((entry & X86_PAE_PTE_WRITABLE) != 0 ? B_KERNEL_WRITE_AREA : 
0)
+               | B_KERNEL_READ_AREA
+               | ((entry & X86_PAE_PTE_DIRTY) != 0 ? PAGE_MODIFIED : 0)
+               | ((entry & X86_PAE_PTE_ACCESSED) != 0 ? PAGE_ACCESSED : 0)
+               | ((entry & X86_PAE_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0);
+
+       TRACE("X86VMTranslationMapPAE::Query(%#" B_PRIxADDR ") -> %#"
+               B_PRIxPHYSADDR ":\n", *_physicalAddress, virtualAddress);
+
+       return B_OK;
 }
 
 


Other related posts:

  • » [haiku-commits] r37100 - haiku/trunk/src/system/kernel/arch/x86/paging/pae - ingo_weinhold