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

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 10 Jun 2010 19:45:38 +0200 (CEST)

Author: bonefish
Date: 2010-06-10 19:45:38 +0200 (Thu, 10 Jun 2010)
New Revision: 37090
Changeset: http://dev.haiku-os.org/changeset/37090/haiku

Modified:
   haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp
Log:
X86VMTranslationMapPAE::Init(): Implemented the initialization for userland
maps. Now we can at least fully boot in qemu with one CPU. A few things
still need to be implemented, though.


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-10 17:40:19 UTC (rev 37089)
+++ 
haiku/trunk/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp    
    2010-06-10 17:45:38 UTC (rev 37090)
@@ -70,8 +70,6 @@
                        method->KernelPhysicalPageDirPointerTable(),
                        method->KernelVirtualPageDirs(), 
method->KernelPhysicalPageDirs());
        } else {
-panic("X86VMTranslationMapPAE::Init(): user init not implemented");
-#if 0
                // user
                // allocate a physical page mapper
                status_t error = method->PhysicalPageMapper()
@@ -79,20 +77,55 @@
                if (error != B_OK)
                        return error;
 
-               // allocate the page directory
-               page_directory_entry* virtualPageDir = 
(page_directory_entry*)memalign(
-                       B_PAGE_SIZE, B_PAGE_SIZE);
-               if (virtualPageDir == NULL)
+               // The following code assumes that the kernel address space 
occupies the
+               // upper half of the virtual address space. This simplifies 
things a
+               // lot, since it allows us to just use the upper two page 
directories
+               // of the kernel and create two new lower page directories for 
the
+               // userland.
+               STATIC_ASSERT(KERNEL_BASE == 0x80000000 && KERNEL_SIZE == 
0x80000000);
+
+               // allocate the page directories (both at once)
+               pae_page_directory_entry* virtualPageDirs[4];
+               phys_addr_t physicalPageDirs[4];
+               virtualPageDirs[0] = 
(pae_page_directory_entry*)memalign(B_PAGE_SIZE,
+                       2 * B_PAGE_SIZE);
+               if (virtualPageDirs[0] == NULL)
                        return B_NO_MEMORY;
+               virtualPageDirs[1] = virtualPageDirs[0] + 
kPAEPageTableEntryCount;
 
-               // look up the page directory's physical address
-               phys_addr_t physicalPageDir;
-               vm_get_page_mapping(VMAddressSpace::KernelID(),
-                       (addr_t)virtualPageDir, &physicalPageDir);
+               // clear the userland page directories
+               memset(virtualPageDirs[0], 0, 2 * B_PAGE_SIZE);
 
-               fPagingStructures->Init(virtualPageDir, physicalPageDir,
-                       method->KernelVirtualPageDirectory());
-#endif
+               // use the upper two kernel page directories
+               for (int32 i = 2; i < 4; i++) {
+                       virtualPageDirs[i] = method->KernelVirtualPageDirs()[i];
+                       physicalPageDirs[i] = 
method->KernelPhysicalPageDirs()[i];
+               }
+
+               // look up the page directories' physical addresses
+               for (int32 i = 0; i < 2; i++) {
+                       vm_get_page_mapping(VMAddressSpace::KernelID(),
+                               (addr_t)virtualPageDirs[i], 
&physicalPageDirs[i]);
+               }
+
+               // allocate the PDPT -- needs to have a 32 bit physical address
+               phys_addr_t physicalPDPT;
+               void* pdptHandle;
+               pae_page_directory_pointer_table_entry* pdpt
+                       = (pae_page_directory_pointer_table_entry*)
+                               method->Allocate32BitPage(physicalPDPT, 
pdptHandle);
+               if (pdpt == NULL)
+                       free(virtualPageDirs[0]);
+
+               // init the PDPT entries
+               for (int32 i = 0; i < 4; i++) {
+                       pdpt[i] = (physicalPageDirs[i] & 
X86_PAE_PDPTE_ADDRESS_MASK)
+                               | X86_PAE_PDPTE_PRESENT;
+               }
+
+               // init the paging structures
+               fPagingStructures->Init(pdpt, physicalPDPT, virtualPageDirs,
+                       physicalPageDirs);
        }
 
        return B_OK;


Other related posts:

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