From f0675bf7571235ecdedb5cf4fda90ade6b4598f6 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 8 Jun 2010 15:39:47 +0000 Subject: [PATCH] Moved X86PagingStructures32Bit into its own source/header pair. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37061 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/arch/x86/Jamfile | 1 + .../x86/paging/32bit/X86PagingMethod32Bit.cpp | 142 ++---------------- .../x86/paging/32bit/X86PagingMethod32Bit.h | 10 -- .../paging/32bit/X86PagingStructures32Bit.cpp | 133 ++++++++++++++++ .../paging/32bit/X86PagingStructures32Bit.h | 31 ++++ .../kernel/arch/x86/paging/32bit/paging.h | 8 +- .../arch/x86/paging/X86PagingStructures.cpp | 3 +- 7 files changed, 190 insertions(+), 138 deletions(-) create mode 100644 src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp create mode 100644 src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.h diff --git a/src/system/kernel/arch/x86/Jamfile b/src/system/kernel/arch/x86/Jamfile index 46046b3dfe..a15d462252 100644 --- a/src/system/kernel/arch/x86/Jamfile +++ b/src/system/kernel/arch/x86/Jamfile @@ -51,6 +51,7 @@ KernelMergeObject kernel_arch_x86.o : # paging/32bit X86PagingMethod32Bit.cpp + X86PagingStructures32Bit.cpp x86_apic.cpp x86_hpet.cpp diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp index cc596243c0..fb4af5b177 100644 --- a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp +++ b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include +#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 X86PhysicalPageMapper* sPhysicalPageMapper; static TranslationMapPhysicalPageMapper* sKernelPhysicalPageMapper; -// Accessor class to reuse the SinglyLinkedListLink of DeferredDeletable for -// X86PagingStructures32Bit. -struct PagingStructuresGetLink { -private: - typedef SinglyLinkedListLink 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 - 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 - @@ -211,22 +138,6 @@ put_page_table_entry_in_pgtable(page_table_entry* entry, // #pragma mark - -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 @@ X86VMTranslationMap32Bit::Init(bool kernel) if (fPagingStructures == NULL) return B_NO_MEMORY; - fPagingStructures->active_on_cpus = 0; - if (!kernel) { // user // allocate a physical page mapper @@ -329,46 +238,27 @@ X86VMTranslationMap32Bit::Init(bool kernel) 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; - } - - // 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(fPagingStructures)); - - release_spinlock(&sPagingStructuresListLock); - restore_interrupts(state); + fPagingStructures->Init(sKernelVirtualPageDirectory, + sKernelPhysicalPageDirectory, NULL); } return B_OK; @@ -429,8 +319,9 @@ X86VMTranslationMap32Bit::Map(addr_t va, phys_addr_t pa, uint32 attributes, // 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 @@ X86PagingMethod32Bit::PhysicalPageSlotPool::AllocatePool( = &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 @@ X86PagingMethod32Bit::Init(kernel_args* args, sKernelVirtualPageDirectory, sKernelPhysicalPageDirectory); #endif - B_INITIALIZE_SPINLOCK(&sPagingStructuresListLock); - new (&sPagingStructuresList) PagingStructuresList; + X86PagingStructures32Bit::StaticInit(); // create the initial pool for the physical page mapper PhysicalPageSlotPool* pool diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h index 521f310e56..dcdeffda80 100644 --- a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h +++ b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h @@ -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(); diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp new file mode 100644 index 0000000000..4b86a85611 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. 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 + +#include +#include + + +// Accessor class to reuse the SinglyLinkedListLink of DeferredDeletable for +// X86PagingStructures32Bit. +struct PagingStructuresGetLink { +private: + typedef SinglyLinkedListLink 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 + 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; +} diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.h b/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.h new file mode 100644 index 0000000000..12c5f96b9e --- /dev/null +++ b/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.h @@ -0,0 +1,31 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * 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 diff --git a/src/system/kernel/arch/x86/paging/32bit/paging.h b/src/system/kernel/arch/x86/paging/32bit/paging.h index a7f335109e..0991e61c21 100644 --- a/src/system/kernel/arch/x86/paging/32bit/paging.h +++ b/src/system/kernel/arch/x86/paging/32bit/paging.h @@ -13,6 +13,7 @@ #include #include +#include #define VADDR_TO_PDENT(va) (((va) / B_PAGE_SIZE) / 1024) @@ -52,6 +53,12 @@ #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 @@ void x86_early_prepare_page_tables(page_table_entry* pageTables, addr_t address, 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 diff --git a/src/system/kernel/arch/x86/paging/X86PagingStructures.cpp b/src/system/kernel/arch/x86/paging/X86PagingStructures.cpp index 2844391341..4a2d9ee9ad 100644 --- a/src/system/kernel/arch/x86/paging/X86PagingStructures.cpp +++ b/src/system/kernel/arch/x86/paging/X86PagingStructures.cpp @@ -9,7 +9,8 @@ X86PagingStructures::X86PagingStructures() : - ref_count(1) + ref_count(1), + active_on_cpus(0) { }