Author: bonefish Date: 2010-06-08 18:18:57 +0200 (Tue, 08 Jun 2010) New Revision: 37062 Changeset: http://dev.haiku-os.org/changeset/37062/haiku Modified: haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingMethod.cpp haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingMethod.h Log: * Introduced global variable gX86PagingMethod, so the paging method can be accessed from anywhere. Added static X86PagingMethod32Bit::Method() returning it as the subtype pointer -- to be used in the code related to that method only, of course. * Made a bunch of static variables non-static members of X86PagingMethod32Bit and added accessors for them. This makes them accessible in other source files (allowing for more refactoring) and saves memory, when we actually have another paging method implementation. Modified: haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp 2010-06-08 15:39:47 UTC (rev 37061) +++ haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp 2010-06-08 16:18:57 UTC (rev 37062) @@ -21,7 +21,10 @@ #endif -static X86PagingMethod* sPagingMethod; +static union { + uint64 align; + char thirty_two[sizeof(X86PagingMethod32Bit)]; +} sPagingMethodBuffer; // #pragma mark - VM API @@ -30,7 +33,7 @@ status_t arch_vm_translation_map_create_map(bool kernel, VMTranslationMap** _map) { - return sPagingMethod->CreateTranslationMap(kernel, _map); + return gX86PagingMethod->CreateTranslationMap(kernel, _map); } @@ -65,9 +68,9 @@ } #endif - sPagingMethod = X86PagingMethod32Bit::Create(); + gX86PagingMethod = new(&sPagingMethodBuffer) X86PagingMethod32Bit; - return sPagingMethod->Init(args, _physicalPageMapper); + return gX86PagingMethod->Init(args, _physicalPageMapper); } @@ -83,7 +86,7 @@ { TRACE("vm_translation_map_init_post_area: entry\n"); - return sPagingMethod->InitPostArea(args); + return gX86PagingMethod->InitPostArea(args); } @@ -93,7 +96,7 @@ { TRACE("early_tmap: entry pa 0x%lx va 0x%lx\n", pa, va); - return sPagingMethod->MapEarly(args, va, pa, attributes, get_free_page); + return gX86PagingMethod->MapEarly(args, va, pa, attributes, get_free_page); } @@ -113,5 +116,5 @@ arch_vm_translation_map_is_kernel_page_accessible(addr_t virtualAddress, uint32 protection) { - return sPagingMethod->IsKernelPageAccessible(virtualAddress, protection); + return gX86PagingMethod->IsKernelPageAccessible(virtualAddress, protection); } Modified: haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp 2010-06-08 15:39:47 UTC (rev 37061) +++ haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp 2010-06-08 16:18:57 UTC (rev 37062) @@ -47,17 +47,6 @@ static const size_t kPageTableAlignment = 1024 * B_PAGE_SIZE; -static X86PagingMethod32Bit sMethod; - -static page_table_entry *sPageHole = NULL; -static page_directory_entry *sPageHolePageDir = NULL; -static uint32 sKernelPhysicalPageDirectory = 0; -static page_directory_entry *sKernelVirtualPageDirectory = NULL; - -static X86PhysicalPageMapper* sPhysicalPageMapper; -static TranslationMapPhysicalPageMapper* sKernelPhysicalPageMapper; - - // #pragma mark - @@ -65,12 +54,14 @@ static status_t early_query(addr_t va, phys_addr_t *_physicalAddress) { - if ((sPageHolePageDir[VADDR_TO_PDENT(va)] & X86_PDE_PRESENT) == 0) { + X86PagingMethod32Bit* method = X86PagingMethod32Bit::Method(); + if ((method->PageHolePageDir()[VADDR_TO_PDENT(va)] & X86_PDE_PRESENT) + == 0) { // no pagetable here return B_ERROR; } - page_table_entry* pentry = sPageHole + va / B_PAGE_SIZE; + page_table_entry* pentry = method->PageHole() + va / B_PAGE_SIZE; if ((*pentry & X86_PTE_PRESENT) == 0) { // page mapping not valid return B_ERROR; @@ -168,11 +159,14 @@ { addr_t virtualTable = (addr_t)pageTables; + page_directory_entry* pageHolePageDir + = X86PagingMethod32Bit::Method()->PageHolePageDir(); + for (size_t i = 0; i < (size / (B_PAGE_SIZE * 1024)); i++, virtualTable += B_PAGE_SIZE) { phys_addr_t physicalTable = 0; early_query(virtualTable, &physicalTable); - page_directory_entry* entry = &sPageHolePageDir[ + page_directory_entry* entry = &pageHolePageDir[ (address / (B_PAGE_SIZE * 1024)) + i]; x86_put_pgtable_in_pgdir(entry, physicalTable, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); @@ -230,10 +224,12 @@ if (fPagingStructures == NULL) return B_NO_MEMORY; + X86PagingMethod32Bit* method = X86PagingMethod32Bit::Method(); + if (!kernel) { // user // allocate a physical page mapper - status_t error = sPhysicalPageMapper + status_t error = method->PhysicalPageMapper() ->CreateTranslationMapPhysicalPageMapper(&fPageMapper); if (error != B_OK) return error; @@ -250,15 +246,15 @@ (addr_t)virtualPageDir, &physicalPageDir); fPagingStructures->Init(virtualPageDir, physicalPageDir, - sKernelVirtualPageDirectory); + method->KernelVirtualPageDirectory()); } else { // kernel // get the physical page mapper - fPageMapper = sKernelPhysicalPageMapper; + fPageMapper = method->KernelPhysicalPageMapper(); // we already know the kernel pgdir mapping - fPagingStructures->Init(sKernelVirtualPageDirectory, - sKernelPhysicalPageDirectory, NULL); + fPagingStructures->Init(method->KernelVirtualPageDirectory(), + method->KernelPhysicalPageDirectory(), NULL); } return B_OK; @@ -813,8 +809,8 @@ } // map page table entry - page_table_entry* pt - = (page_table_entry*)sPhysicalPageMapper->InterruptGetPageTableAt( + page_table_entry* pt = (page_table_entry*)X86PagingMethod32Bit::Method() + ->PhysicalPageMapper()->InterruptGetPageTableAt( pd[index] & X86_PDE_ADDRESS_MASK); page_table_entry entry = pt[VADDR_TO_PTENT(va)]; @@ -1283,6 +1279,13 @@ X86PagingMethod32Bit::X86PagingMethod32Bit() + : + fPageHole(NULL), + fPageHolePageDir(NULL), + fKernelPhysicalPageDirectory(0), + fKernelVirtualPageDirectory(NULL), + fPhysicalPageMapper(NULL), + fKernelPhysicalPageMapper(NULL) { } @@ -1292,13 +1295,6 @@ } -/*static*/ X86PagingMethod* -X86PagingMethod32Bit::Create() -{ - return new(&sMethod) X86PagingMethod32Bit; -} - - status_t X86PagingMethod32Bit::Init(kernel_args* args, VMPhysicalPageMapper** _physicalPageMapper) @@ -1306,23 +1302,23 @@ TRACE("vm_translation_map_init: entry\n"); // page hole set up in stage2 - sPageHole = (page_table_entry *)args->arch_args.page_hole; + fPageHole = (page_table_entry*)args->arch_args.page_hole; // calculate where the pgdir would be - sPageHolePageDir = (page_directory_entry*) + fPageHolePageDir = (page_directory_entry*) (((addr_t)args->arch_args.page_hole) + (B_PAGE_SIZE * 1024 - B_PAGE_SIZE)); // clear out the bottom 2 GB, unmap everything - memset(sPageHolePageDir + FIRST_USER_PGDIR_ENT, 0, + memset(fPageHolePageDir + FIRST_USER_PGDIR_ENT, 0, sizeof(page_directory_entry) * NUM_USER_PGDIR_ENTS); - sKernelPhysicalPageDirectory = args->arch_args.phys_pgdir; - sKernelVirtualPageDirectory = (page_directory_entry*) + fKernelPhysicalPageDirectory = args->arch_args.phys_pgdir; + fKernelVirtualPageDirectory = (page_directory_entry*) args->arch_args.vir_pgdir; #ifdef TRACE_X86_PAGING_METHOD_32_BIT - TRACE("page hole: %p, page dir: %p\n", sPageHole, sPageHolePageDir); + TRACE("page hole: %p, page dir: %p\n", fPageHole, fPageHolePageDir); TRACE("page dir: %p (physical: %#" B_PRIx32 ")\n", - sKernelVirtualPageDirectory, sKernelPhysicalPageDirectory); + fKernelVirtualPageDirectory, fKernelPhysicalPageDirectory); #endif X86PagingStructures32Bit::StaticInit(); @@ -1339,8 +1335,8 @@ } // create physical page mapper - large_memory_physical_page_ops_init(args, pool, sPhysicalPageMapper, - sKernelPhysicalPageMapper); + large_memory_physical_page_ops_init(args, pool, fPhysicalPageMapper, + fKernelPhysicalPageMapper); // TODO: Select the best page mapper! // enable global page feature if available @@ -1352,7 +1348,7 @@ TRACE("vm_translation_map_init: done\n"); - *_physicalPageMapper = sPhysicalPageMapper; + *_physicalPageMapper = fPhysicalPageMapper; return B_OK; } @@ -1367,11 +1363,11 @@ area_id area; // unmap the page hole hack we were using before - sKernelVirtualPageDirectory[1023] = 0; - sPageHolePageDir = NULL; - sPageHole = NULL; + fKernelVirtualPageDirectory[1023] = 0; + fPageHolePageDir = NULL; + fPageHole = NULL; - temp = (void *)sKernelVirtualPageDirectory; + temp = (void*)fKernelVirtualPageDirectory; area = create_area("kernel_pgdir", &temp, B_EXACT_ADDRESS, B_PAGE_SIZE, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (area < B_OK) @@ -1418,7 +1414,7 @@ // check to see if a page table exists for this range int index = VADDR_TO_PDENT(virtualAddress); - if ((sPageHolePageDir[index] & X86_PDE_PRESENT) == 0) { + if ((fPageHolePageDir[index] & X86_PDE_PRESENT) == 0) { phys_addr_t pgtable; page_directory_entry *e; // we need to allocate a pgtable @@ -1430,23 +1426,23 @@ "pgtable. %#" B_PRIxPHYSADDR "\n", pgtable); // put it in the pgdir - e = &sPageHolePageDir[index]; + e = &fPageHolePageDir[index]; x86_put_pgtable_in_pgdir(e, pgtable, attributes); // zero it out in it's new mapping - memset((unsigned int*)((addr_t)sPageHole + memset((unsigned int*)((addr_t)fPageHole + (virtualAddress / B_PAGE_SIZE / 1024) * B_PAGE_SIZE), 0, B_PAGE_SIZE); } ASSERT_PRINT( - (sPageHole[virtualAddress / B_PAGE_SIZE] & X86_PTE_PRESENT) == 0, + (fPageHole[virtualAddress / B_PAGE_SIZE] & X86_PTE_PRESENT) == 0, "virtual address: %#" B_PRIxADDR ", pde: %#" B_PRIx32 - ", existing pte: %#" B_PRIx32, virtualAddress, sPageHolePageDir[index], - sPageHole[virtualAddress / B_PAGE_SIZE]); + ", existing pte: %#" B_PRIx32, virtualAddress, fPageHolePageDir[index], + fPageHole[virtualAddress / B_PAGE_SIZE]); // now, fill in the pentry - put_page_table_entry_in_pgtable(sPageHole + virtualAddress / B_PAGE_SIZE, + put_page_table_entry_in_pgtable(fPageHole + virtualAddress / B_PAGE_SIZE, physicalAddress, attributes, 0, IS_KERNEL_ADDRESS(virtualAddress)); return B_OK; @@ -1461,25 +1457,24 @@ // Always set it to make sure the TLBs don't contain obsolete data. uint32 physicalPageDirectory; read_cr3(physicalPageDirectory); - write_cr3(sKernelPhysicalPageDirectory); + write_cr3(fKernelPhysicalPageDirectory); // get the page directory entry for the address page_directory_entry pageDirectoryEntry; uint32 index = VADDR_TO_PDENT(virtualAddress); - if (physicalPageDirectory == sKernelPhysicalPageDirectory) { - pageDirectoryEntry = sKernelVirtualPageDirectory[index]; - } else if (sPhysicalPageMapper != NULL) { + if (physicalPageDirectory == fKernelPhysicalPageDirectory) { + pageDirectoryEntry = fKernelVirtualPageDirectory[index]; + } else if (fPhysicalPageMapper != NULL) { // map the original page directory and get the entry void* handle; addr_t virtualPageDirectory; - status_t error = sPhysicalPageMapper->GetPageDebug( + status_t error = fPhysicalPageMapper->GetPageDebug( physicalPageDirectory, &virtualPageDirectory, &handle); if (error == B_OK) { pageDirectoryEntry = ((page_directory_entry*)virtualPageDirectory)[index]; - sPhysicalPageMapper->PutPageDebug(virtualPageDirectory, - handle); + fPhysicalPageMapper->PutPageDebug(virtualPageDirectory, handle); } else pageDirectoryEntry = 0; } else @@ -1490,22 +1485,22 @@ index = VADDR_TO_PTENT(virtualAddress); if ((pageDirectoryEntry & X86_PDE_PRESENT) != 0 - && sPhysicalPageMapper != NULL) { + && fPhysicalPageMapper != NULL) { void* handle; addr_t virtualPageTable; - status_t error = sPhysicalPageMapper->GetPageDebug( + status_t error = fPhysicalPageMapper->GetPageDebug( pageDirectoryEntry & X86_PDE_ADDRESS_MASK, &virtualPageTable, &handle); if (error == B_OK) { pageTableEntry = ((page_table_entry*)virtualPageTable)[index]; - sPhysicalPageMapper->PutPageDebug(virtualPageTable, handle); + fPhysicalPageMapper->PutPageDebug(virtualPageTable, handle); } else pageTableEntry = 0; } else pageTableEntry = 0; // switch back to the original page directory - if (physicalPageDirectory != sKernelPhysicalPageDirectory) + if (physicalPageDirectory != fKernelPhysicalPageDirectory) write_cr3(physicalPageDirectory); if ((pageTableEntry & X86_PTE_PRESENT) == 0) Modified: haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h 2010-06-08 15:39:47 UTC (rev 37061) +++ haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h 2010-06-08 16:18:57 UTC (rev 37062) @@ -11,13 +11,15 @@ #include "paging/X86PagingStructures.h" +class TranslationMapPhysicalPageMapper; +class X86PhysicalPageMapper; + + class X86PagingMethod32Bit : public X86PagingMethod { public: X86PagingMethod32Bit(); virtual ~X86PagingMethod32Bit(); - static X86PagingMethod* Create(); - virtual status_t Init(kernel_args* args, VMPhysicalPageMapper** _physicalPageMapper); virtual status_t InitPostArea(kernel_args* args); @@ -34,9 +36,40 @@ virtual bool IsKernelPageAccessible(addr_t virtualAddress, uint32 protection); + inline page_table_entry* PageHole() const + { return fPageHole; } + inline page_directory_entry* PageHolePageDir() const + { return fPageHolePageDir; } + inline uint32 KernelPhysicalPageDirectory() const + { return fKernelPhysicalPageDirectory; } + inline page_directory_entry* KernelVirtualPageDirectory() const + { return fKernelVirtualPageDirectory; } + inline X86PhysicalPageMapper* PhysicalPageMapper() const + { return fPhysicalPageMapper; } + inline TranslationMapPhysicalPageMapper* KernelPhysicalPageMapper() const + { return fKernelPhysicalPageMapper; } + + static X86PagingMethod32Bit* Method(); + private: struct PhysicalPageSlotPool; + +private: + page_table_entry* fPageHole; + page_directory_entry* fPageHolePageDir; + uint32 fKernelPhysicalPageDirectory; + page_directory_entry* fKernelVirtualPageDirectory; + + X86PhysicalPageMapper* fPhysicalPageMapper; + TranslationMapPhysicalPageMapper* fKernelPhysicalPageMapper; }; +/*static*/ inline X86PagingMethod32Bit* +X86PagingMethod32Bit::Method() +{ + return static_cast<X86PagingMethod32Bit*>(gX86PagingMethod); +} + + #endif // KERNEL_ARCH_X86_PAGING_32_BIT_X86_PAGING_METHOD_32_BIT_H Modified: haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingMethod.cpp =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingMethod.cpp 2010-06-08 15:39:47 UTC (rev 37061) +++ haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingMethod.cpp 2010-06-08 16:18:57 UTC (rev 37062) @@ -7,6 +7,9 @@ #include "paging/X86PagingMethod.h" +X86PagingMethod* gX86PagingMethod; + + X86PagingMethod::~X86PagingMethod() { } Modified: haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingMethod.h =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingMethod.h 2010-06-08 15:39:47 UTC (rev 37061) +++ haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingMethod.h 2010-06-08 16:18:57 UTC (rev 37062) @@ -38,4 +38,7 @@ }; +extern X86PagingMethod* gX86PagingMethod; + + #endif // KERNEL_ARCH_X86_PAGING_X86_PAGING_METHOD_H