Author: bonefish Date: 2010-06-08 17:39:47 +0200 (Tue, 08 Jun 2010) New Revision: 37061 Changeset: http://dev.haiku-os.org/changeset/37061/haiku Added: haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.h Modified: haiku/trunk/src/system/kernel/arch/x86/Jamfile 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/32bit/paging.h haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingStructures.cpp Log: Moved X86PagingStructures32Bit into its own source/header pair. Modified: haiku/trunk/src/system/kernel/arch/x86/Jamfile =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/Jamfile 2010-06-08 15:00:56 UTC (rev 37060) +++ haiku/trunk/src/system/kernel/arch/x86/Jamfile 2010-06-08 15:39:47 UTC (rev 37061) @@ -51,6 +51,7 @@ # paging/32bit X86PagingMethod32Bit.cpp + X86PagingStructures32Bit.cpp x86_apic.cpp x86_hpet.cpp 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:00:56 UTC (rev 37060) +++ haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp 2010-06-08 15:39:47 UTC (rev 37061) @@ -16,7 +16,6 @@ #include <AutoDeleter.h> #include <arch_system_info.h> -#include <heap.h> #include <int.h> #include <thread.h> #include <slab/Slab.h> @@ -28,6 +27,7 @@ #include <vm/VMAddressSpace.h> #include <vm/VMCache.h> +#include "paging/32bit/X86PagingStructures32Bit.h" #include "paging/32bit/X86VMTranslationMap32Bit.h" #include "paging/x86_physical_page_mapper.h" #include "paging/x86_physical_page_mapper_large_memory.h" @@ -58,79 +58,6 @@ static TranslationMapPhysicalPageMapper* sKernelPhysicalPageMapper; -// Accessor class to reuse the SinglyLinkedListLink of DeferredDeletable for -// X86PagingStructures32Bit. -struct PagingStructuresGetLink { -private: - typedef SinglyLinkedListLink<X86PagingStructures32Bit> Link; - -public: - inline Link* operator()(X86PagingStructures32Bit* element) const - { - return (Link*)element->GetSinglyLinkedListLink(); - } - - inline const Link* operator()( - const X86PagingStructures32Bit* element) const - { - return (const Link*)element->GetSinglyLinkedListLink(); - } -}; - - -typedef SinglyLinkedList<X86PagingStructures32Bit, PagingStructuresGetLink> - PagingStructuresList; - - -static PagingStructuresList sPagingStructuresList; -static spinlock sPagingStructuresListLock; - - -#define FIRST_USER_PGDIR_ENT (VADDR_TO_PDENT(USER_BASE)) -#define NUM_USER_PGDIR_ENTS (VADDR_TO_PDENT(ROUNDUP(USER_SIZE, \ - B_PAGE_SIZE * 1024))) -#define FIRST_KERNEL_PGDIR_ENT (VADDR_TO_PDENT(KERNEL_BASE)) -#define NUM_KERNEL_PGDIR_ENTS (VADDR_TO_PDENT(KERNEL_SIZE)) - - -X86PagingStructures32Bit::X86PagingStructures32Bit() - : - pgdir_virt(NULL) -{ -} - - -X86PagingStructures32Bit::~X86PagingStructures32Bit() -{ - // free the page dir - free(pgdir_virt); -} - - -void -X86PagingStructures32Bit::Delete() -{ - // remove from global list - InterruptsSpinLocker locker(sPagingStructuresListLock); - sPagingStructuresList.Remove(this); - locker.Unlock(); - -#if 0 - // this sanity check can be enabled when corruption due to - // overwriting an active page directory is suspected - uint32 activePageDirectory; - read_cr3(activePageDirectory); - if (activePageDirectory == pgdir_phys) - panic("deleting a still active page directory\n"); -#endif - - if (are_interrupts_enabled()) - delete this; - else - deferred_delete(this); -} - - // #pragma mark - @@ -212,22 +139,6 @@ void -x86_update_all_pgdirs(int index, page_directory_entry e) -{ - unsigned int state = disable_interrupts(); - - acquire_spinlock(&sPagingStructuresListLock); - - PagingStructuresList::Iterator it = sPagingStructuresList.GetIterator(); - while (X86PagingStructures32Bit* info = it.Next()) - info->pgdir_virt[index] = e; - - release_spinlock(&sPagingStructuresListLock); - restore_interrupts(state); -} - - -void x86_put_pgtable_in_pgdir(page_directory_entry *entry, phys_addr_t pgtablePhysical, uint32 attributes) { @@ -319,8 +230,6 @@ if (fPagingStructures == NULL) return B_NO_MEMORY; - fPagingStructures->active_on_cpus = 0; - if (!kernel) { // user // allocate a physical page mapper @@ -329,48 +238,29 @@ if (error != B_OK) return error; - // allocate a pgdir - fPagingStructures->pgdir_virt = (page_directory_entry *)memalign( + // allocate the page directory + page_directory_entry* virtualPageDir = (page_directory_entry*)memalign( B_PAGE_SIZE, B_PAGE_SIZE); - if (fPagingStructures->pgdir_virt == NULL) + if (virtualPageDir == NULL) return B_NO_MEMORY; + // look up the page directory's physical address phys_addr_t physicalPageDir; vm_get_page_mapping(VMAddressSpace::KernelID(), - (addr_t)fPagingStructures->pgdir_virt, - &physicalPageDir); - fPagingStructures->pgdir_phys = physicalPageDir; + (addr_t)virtualPageDir, &physicalPageDir); + + fPagingStructures->Init(virtualPageDir, physicalPageDir, + sKernelVirtualPageDirectory); } else { // kernel // get the physical page mapper fPageMapper = sKernelPhysicalPageMapper; // we already know the kernel pgdir mapping - fPagingStructures->pgdir_virt = sKernelVirtualPageDirectory; - fPagingStructures->pgdir_phys = sKernelPhysicalPageDirectory; + fPagingStructures->Init(sKernelVirtualPageDirectory, + sKernelPhysicalPageDirectory, NULL); } - // zero out the bottom portion of the new pgdir - memset(fPagingStructures->pgdir_virt + FIRST_USER_PGDIR_ENT, 0, - NUM_USER_PGDIR_ENTS * sizeof(page_directory_entry)); - - // insert this new map into the map list - { - int state = disable_interrupts(); - acquire_spinlock(&sPagingStructuresListLock); - - // copy the top portion of the pgdir from the current one - memcpy(fPagingStructures->pgdir_virt + FIRST_KERNEL_PGDIR_ENT, - sKernelVirtualPageDirectory + FIRST_KERNEL_PGDIR_ENT, - NUM_KERNEL_PGDIR_ENTS * sizeof(page_directory_entry)); - - sPagingStructuresList.Add( - static_cast<X86PagingStructures32Bit*>(fPagingStructures)); - - release_spinlock(&sPagingStructuresListLock); - restore_interrupts(state); - } - return B_OK; } @@ -429,8 +319,9 @@ // update any other page directories, if it maps kernel space if (index >= FIRST_KERNEL_PGDIR_ENT - && index < (FIRST_KERNEL_PGDIR_ENT + NUM_KERNEL_PGDIR_ENTS)) - x86_update_all_pgdirs(index, pd[index]); + && index < (FIRST_KERNEL_PGDIR_ENT + NUM_KERNEL_PGDIR_ENTS)) { + X86PagingStructures32Bit::UpdateAllPageDirs(index, pd[index]); + } fMapCount++; } @@ -1378,7 +1269,7 @@ = &map->PagingStructures32Bit()->pgdir_virt[index]; x86_put_pgtable_in_pgdir(entry, physicalTable, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); - x86_update_all_pgdirs(index, *entry); + X86PagingStructures32Bit::UpdateAllPageDirs(index, *entry); // init the pool structure pool->Init(dataArea, data, virtualArea, (addr_t)virtualBase); @@ -1434,8 +1325,7 @@ sKernelVirtualPageDirectory, sKernelPhysicalPageDirectory); #endif - B_INITIALIZE_SPINLOCK(&sPagingStructuresListLock); - new (&sPagingStructuresList) PagingStructuresList; + X86PagingStructures32Bit::StaticInit(); // create the initial pool for the physical page mapper PhysicalPageSlotPool* pool 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:00:56 UTC (rev 37060) +++ haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h 2010-06-08 15:39:47 UTC (rev 37061) @@ -11,16 +11,6 @@ #include "paging/X86PagingStructures.h" -struct X86PagingStructures32Bit : X86PagingStructures { - page_directory_entry* pgdir_virt; - - X86PagingStructures32Bit(); - virtual ~X86PagingStructures32Bit(); - - virtual void Delete(); -}; - - class X86PagingMethod32Bit : public X86PagingMethod { public: X86PagingMethod32Bit(); Added: haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp (rev 0) +++ haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp 2010-06-08 15:39:47 UTC (rev 37061) @@ -0,0 +1,133 @@ +/* + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Copyright 2002-2007, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include "paging/32bit/X86PagingStructures32Bit.h" + +#include <stdlib.h> + +#include <heap.h> +#include <util/AutoLock.h> + + +// Accessor class to reuse the SinglyLinkedListLink of DeferredDeletable for +// X86PagingStructures32Bit. +struct PagingStructuresGetLink { +private: + typedef SinglyLinkedListLink<X86PagingStructures32Bit> Link; + +public: + inline Link* operator()(X86PagingStructures32Bit* element) const + { + return (Link*)element->GetSinglyLinkedListLink(); + } + + inline const Link* operator()( + const X86PagingStructures32Bit* element) const + { + return (const Link*)element->GetSinglyLinkedListLink(); + } +}; + + +typedef SinglyLinkedList<X86PagingStructures32Bit, PagingStructuresGetLink> + PagingStructuresList; + + +static PagingStructuresList sPagingStructuresList; +static spinlock sPagingStructuresListLock; + + +X86PagingStructures32Bit::X86PagingStructures32Bit() + : + pgdir_virt(NULL) +{ +} + + +X86PagingStructures32Bit::~X86PagingStructures32Bit() +{ + // free the page dir + free(pgdir_virt); +} + + +void +X86PagingStructures32Bit::Init(page_directory_entry* virtualPageDir, + phys_addr_t physicalPageDir, page_directory_entry* kernelPageDir) +{ + pgdir_virt = virtualPageDir; + pgdir_phys = physicalPageDir; + + // zero out the bottom portion of the new pgdir + memset(pgdir_virt + FIRST_USER_PGDIR_ENT, 0, + NUM_USER_PGDIR_ENTS * sizeof(page_directory_entry)); + + // insert this new map into the map list + { + int state = disable_interrupts(); + acquire_spinlock(&sPagingStructuresListLock); + + // copy the top portion of the page dir from the kernel page dir + if (kernelPageDir != NULL) { + memcpy(pgdir_virt + FIRST_KERNEL_PGDIR_ENT, + kernelPageDir + FIRST_KERNEL_PGDIR_ENT, + NUM_KERNEL_PGDIR_ENTS * sizeof(page_directory_entry)); + } + + sPagingStructuresList.Add(this); + + release_spinlock(&sPagingStructuresListLock); + restore_interrupts(state); + } +} + + +void +X86PagingStructures32Bit::Delete() +{ + // remove from global list + InterruptsSpinLocker locker(sPagingStructuresListLock); + sPagingStructuresList.Remove(this); + locker.Unlock(); + +#if 0 + // this sanity check can be enabled when corruption due to + // overwriting an active page directory is suspected + uint32 activePageDirectory; + read_cr3(activePageDirectory); + if (activePageDirectory == pgdir_phys) + panic("deleting a still active page directory\n"); +#endif + + if (are_interrupts_enabled()) + delete this; + else + deferred_delete(this); +} + + +/*static*/ void +X86PagingStructures32Bit::StaticInit() +{ + B_INITIALIZE_SPINLOCK(&sPagingStructuresListLock); + new (&sPagingStructuresList) PagingStructuresList; +} + + +/*static*/ void +X86PagingStructures32Bit::UpdateAllPageDirs(int index, + page_directory_entry entry) +{ + InterruptsSpinLocker locker(sPagingStructuresListLock); + + PagingStructuresList::Iterator it = sPagingStructuresList.GetIterator(); + while (X86PagingStructures32Bit* info = it.Next()) + info->pgdir_virt[index] = entry; +} Added: haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.h =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.h (rev 0) +++ haiku/trunk/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.h 2010-06-08 15:39:47 UTC (rev 37061) @@ -0,0 +1,31 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_ARCH_X86_PAGING_32_BIT_X86_PAGING_STRUCTURES_32_BIT_H +#define KERNEL_ARCH_X86_PAGING_32_BIT_X86_PAGING_STRUCTURES_32_BIT_H + + +#include "paging/32bit/paging.h" +#include "paging/X86PagingStructures.h" + + +struct X86PagingStructures32Bit : X86PagingStructures { + page_directory_entry* pgdir_virt; + + X86PagingStructures32Bit(); + virtual ~X86PagingStructures32Bit(); + + void Init(page_directory_entry* virtualPageDir, + phys_addr_t physicalPageDir, + page_directory_entry* kernelPageDir); + + virtual void Delete(); + + static void StaticInit(); + static void UpdateAllPageDirs(int index, + page_directory_entry entry); +}; + + +#endif // KERNEL_ARCH_X86_PAGING_32_BIT_X86_PAGING_STRUCTURES_32_BIT_H Modified: haiku/trunk/src/system/kernel/arch/x86/paging/32bit/paging.h =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/paging/32bit/paging.h 2010-06-08 15:00:56 UTC (rev 37060) +++ haiku/trunk/src/system/kernel/arch/x86/paging/32bit/paging.h 2010-06-08 15:39:47 UTC (rev 37061) @@ -13,6 +13,7 @@ #include <SupportDefs.h> #include <int.h> +#include <kernel.h> #define VADDR_TO_PDENT(va) (((va) / B_PAGE_SIZE) / 1024) @@ -52,7 +53,13 @@ #define X86_PTE_MEMORY_TYPE_MASK (X86_PTE_WRITE_THROUGH \ | X86_PTE_CACHING_DISABLED) +#define FIRST_USER_PGDIR_ENT (VADDR_TO_PDENT(USER_BASE)) +#define NUM_USER_PGDIR_ENTS (VADDR_TO_PDENT(ROUNDUP(USER_SIZE, \ + B_PAGE_SIZE * 1024))) +#define FIRST_KERNEL_PGDIR_ENT (VADDR_TO_PDENT(KERNEL_BASE)) +#define NUM_KERNEL_PGDIR_ENTS (VADDR_TO_PDENT(KERNEL_SIZE)) + typedef uint32 page_table_entry; typedef uint32 page_directory_entry; @@ -61,7 +68,6 @@ size_t size); void x86_put_pgtable_in_pgdir(page_directory_entry* entry, phys_addr_t physicalPageTable, uint32 attributes); -void x86_update_all_pgdirs(int index, page_directory_entry entry); static inline page_table_entry Modified: haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingStructures.cpp =================================================================== --- haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingStructures.cpp 2010-06-08 15:00:56 UTC (rev 37060) +++ haiku/trunk/src/system/kernel/arch/x86/paging/X86PagingStructures.cpp 2010-06-08 15:39:47 UTC (rev 37061) @@ -9,7 +9,8 @@ X86PagingStructures::X86PagingStructures() : - ref_count(1) + ref_count(1), + active_on_cpus(0) { }