Moved X86PagingStructures32Bit into its own source/header pair.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37061 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2010-06-08 15:39:47 +00:00
parent 1b3e83adde
commit f0675bf757
7 changed files with 190 additions and 138 deletions

View File

@ -51,6 +51,7 @@ KernelMergeObject kernel_arch_x86.o :
# paging/32bit
X86PagingMethod32Bit.cpp
X86PagingStructures32Bit.cpp
x86_apic.cpp
x86_hpet.cpp

View File

@ -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 X86PhysicalPageMapper* sPhysicalPageMapper;
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 -
@ -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<X86PagingStructures32Bit*>(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

View File

@ -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();

View File

@ -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 <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;
}

View File

@ -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

View File

@ -13,6 +13,7 @@
#include <SupportDefs.h>
#include <int.h>
#include <kernel.h>
#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

View File

@ -9,7 +9,8 @@
X86PagingStructures::X86PagingStructures()
:
ref_count(1)
ref_count(1),
active_on_cpus(0)
{
}