x86: Allocate as much initial physical page pools as needed
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
#include <arch/smp.h>
|
||||||
#include <arch_system_info.h>
|
#include <arch_system_info.h>
|
||||||
#include <boot/kernel_args.h>
|
#include <boot/kernel_args.h>
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
@@ -36,6 +37,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_INITIAL_POOLS \
|
||||||
|
((SMP_MAX_CPUS * TOTAL_SLOTS_PER_CPU + EXTRA_SLOTS + 1023) / 1024)
|
||||||
|
|
||||||
|
|
||||||
using X86LargePhysicalPageMapper::PhysicalPageSlot;
|
using X86LargePhysicalPageMapper::PhysicalPageSlot;
|
||||||
|
|
||||||
|
|
||||||
@@ -60,7 +65,7 @@ public:
|
|||||||
addr_t virtualAddress);
|
addr_t virtualAddress);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static PhysicalPageSlotPool sInitialPhysicalPagePool;
|
static PhysicalPageSlotPool sInitialPhysicalPagePool[MAX_INITIAL_POOLS];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
area_id fDataArea;
|
area_id fDataArea;
|
||||||
@@ -71,7 +76,8 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
X86PagingMethod32Bit::PhysicalPageSlotPool
|
X86PagingMethod32Bit::PhysicalPageSlotPool
|
||||||
X86PagingMethod32Bit::PhysicalPageSlotPool::sInitialPhysicalPagePool;
|
X86PagingMethod32Bit::PhysicalPageSlotPool::sInitialPhysicalPagePool[
|
||||||
|
MAX_INITIAL_POOLS];
|
||||||
|
|
||||||
|
|
||||||
X86PagingMethod32Bit::PhysicalPageSlotPool::~PhysicalPageSlotPool()
|
X86PagingMethod32Bit::PhysicalPageSlotPool::~PhysicalPageSlotPool()
|
||||||
@@ -287,20 +293,23 @@ X86PagingMethod32Bit::Init(kernel_args* args,
|
|||||||
|
|
||||||
X86PagingStructures32Bit::StaticInit();
|
X86PagingStructures32Bit::StaticInit();
|
||||||
|
|
||||||
// create the initial pool for the physical page mapper
|
// create the initial pools for the physical page mapper
|
||||||
|
int32 poolCount = _GetInitialPoolCount();
|
||||||
PhysicalPageSlotPool* pool
|
PhysicalPageSlotPool* pool
|
||||||
= new(&PhysicalPageSlotPool::sInitialPhysicalPagePool)
|
= new(&PhysicalPageSlotPool::sInitialPhysicalPagePool)
|
||||||
PhysicalPageSlotPool;
|
PhysicalPageSlotPool[poolCount];
|
||||||
status_t error = pool->InitInitial(args);
|
for (int32 i = 0; i < poolCount; i++) {
|
||||||
if (error != B_OK) {
|
status_t error = pool[i].InitInitial(args);
|
||||||
panic("X86PagingMethod32Bit::Init(): Failed to create initial pool "
|
if (error != B_OK) {
|
||||||
"for physical page mapper!");
|
panic("X86PagingMethod32Bit::Init(): Failed to create initial pool "
|
||||||
return error;
|
"for physical page mapper!");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create physical page mapper
|
// create physical page mapper
|
||||||
large_memory_physical_page_ops_init(args, pool, fPhysicalPageMapper,
|
large_memory_physical_page_ops_init(args, pool, poolCount, sizeof(*pool),
|
||||||
fKernelPhysicalPageMapper);
|
fPhysicalPageMapper, fKernelPhysicalPageMapper);
|
||||||
// TODO: Select the best page mapper!
|
// TODO: Select the best page mapper!
|
||||||
|
|
||||||
// enable global page feature if available
|
// enable global page feature if available
|
||||||
@@ -337,10 +346,13 @@ X86PagingMethod32Bit::InitPostArea(kernel_args* args)
|
|||||||
if (area < B_OK)
|
if (area < B_OK)
|
||||||
return area;
|
return area;
|
||||||
|
|
||||||
error = PhysicalPageSlotPool::sInitialPhysicalPagePool
|
int32 poolCount = _GetInitialPoolCount();
|
||||||
.InitInitialPostArea(args);
|
for (int32 i = 0; i < poolCount; i++) {
|
||||||
if (error != B_OK)
|
status_t error = PhysicalPageSlotPool::sInitialPhysicalPagePool[i]
|
||||||
return error;
|
.InitInitialPostArea(args);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -517,6 +529,15 @@ X86PagingMethod32Bit::PutPageTableEntryInTable(page_table_entry* entry,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int32
|
||||||
|
X86PagingMethod32Bit::_GetInitialPoolCount()
|
||||||
|
{
|
||||||
|
int32 requiredSlots = smp_get_num_cpus() * TOTAL_SLOTS_PER_CPU
|
||||||
|
+ EXTRA_SLOTS;
|
||||||
|
return (requiredSlots + 1023) / 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ void
|
/*static*/ void
|
||||||
X86PagingMethod32Bit::_EarlyPreparePageTables(page_table_entry* pageTables,
|
X86PagingMethod32Bit::_EarlyPreparePageTables(page_table_entry* pageTables,
|
||||||
addr_t address, size_t size)
|
addr_t address, size_t size)
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ private:
|
|||||||
friend struct PhysicalPageSlotPool;
|
friend struct PhysicalPageSlotPool;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline int32 _GetInitialPoolCount();
|
||||||
|
|
||||||
static void _EarlyPreparePageTables(
|
static void _EarlyPreparePageTables(
|
||||||
page_table_entry* pageTables,
|
page_table_entry* pageTables,
|
||||||
addr_t address, size_t size);
|
addr_t address, size_t size);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
#include <arch/smp.h>
|
||||||
#include <boot/kernel_args.h>
|
#include <boot/kernel_args.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
@@ -40,6 +41,11 @@
|
|||||||
#if B_HAIKU_PHYSICAL_BITS == 64
|
#if B_HAIKU_PHYSICAL_BITS == 64
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_INITIAL_POOLS \
|
||||||
|
((SMP_MAX_CPUS * TOTAL_SLOTS_PER_CPU + EXTRA_SLOTS \
|
||||||
|
+ kPAEPageTableEntryCount - 1) / kPAEPageTableEntryCount)
|
||||||
|
|
||||||
|
|
||||||
using X86LargePhysicalPageMapper::PhysicalPageSlot;
|
using X86LargePhysicalPageMapper::PhysicalPageSlot;
|
||||||
|
|
||||||
|
|
||||||
@@ -364,7 +370,7 @@ public:
|
|||||||
addr_t virtualAddress);
|
addr_t virtualAddress);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static PhysicalPageSlotPool sInitialPhysicalPagePool;
|
static PhysicalPageSlotPool sInitialPhysicalPagePool[MAX_INITIAL_POOLS];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
area_id fDataArea;
|
area_id fDataArea;
|
||||||
@@ -375,7 +381,8 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
X86PagingMethodPAE::PhysicalPageSlotPool
|
X86PagingMethodPAE::PhysicalPageSlotPool
|
||||||
X86PagingMethodPAE::PhysicalPageSlotPool::sInitialPhysicalPagePool;
|
X86PagingMethodPAE::PhysicalPageSlotPool::sInitialPhysicalPagePool[
|
||||||
|
MAX_INITIAL_POOLS];
|
||||||
|
|
||||||
|
|
||||||
X86PagingMethodPAE::PhysicalPageSlotPool::~PhysicalPageSlotPool()
|
X86PagingMethodPAE::PhysicalPageSlotPool::~PhysicalPageSlotPool()
|
||||||
@@ -585,20 +592,23 @@ X86PagingMethodPAE::Init(kernel_args* args,
|
|||||||
fEarlyPageStructuresSize, fKernelVirtualPageDirs,
|
fEarlyPageStructuresSize, fKernelVirtualPageDirs,
|
||||||
fKernelPhysicalPageDirs, fFreeVirtualSlot, fFreeVirtualSlotPTE);
|
fKernelPhysicalPageDirs, fFreeVirtualSlot, fFreeVirtualSlotPTE);
|
||||||
|
|
||||||
// create the initial pool for the physical page mapper
|
// create the initial pools for the physical page mapper
|
||||||
|
int32 poolCount = _GetInitialPoolCount();
|
||||||
PhysicalPageSlotPool* pool
|
PhysicalPageSlotPool* pool
|
||||||
= new(&PhysicalPageSlotPool::sInitialPhysicalPagePool)
|
= new(&PhysicalPageSlotPool::sInitialPhysicalPagePool)
|
||||||
PhysicalPageSlotPool;
|
PhysicalPageSlotPool[poolCount];
|
||||||
status_t error = pool->InitInitial(this, args);
|
for (int32 i = 0; i < poolCount; i++) {
|
||||||
if (error != B_OK) {
|
status_t error = pool[i].InitInitial(this, args);
|
||||||
panic("X86PagingMethodPAE::Init(): Failed to create initial pool "
|
if (error != B_OK) {
|
||||||
"for physical page mapper!");
|
panic("X86PagingMethodPAE::Init(): Failed to create initial pool "
|
||||||
return error;
|
"for physical page mapper!");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create physical page mapper
|
// create physical page mapper
|
||||||
large_memory_physical_page_ops_init(args, pool, fPhysicalPageMapper,
|
large_memory_physical_page_ops_init(args, pool, poolCount, sizeof(*pool),
|
||||||
fKernelPhysicalPageMapper);
|
fPhysicalPageMapper, fKernelPhysicalPageMapper);
|
||||||
|
|
||||||
*_physicalPageMapper = fPhysicalPageMapper;
|
*_physicalPageMapper = fPhysicalPageMapper;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -615,11 +625,14 @@ X86PagingMethodPAE::InitPostArea(kernel_args* args)
|
|||||||
if (area < B_OK)
|
if (area < B_OK)
|
||||||
return area;
|
return area;
|
||||||
|
|
||||||
// let the initial page pool create areas for its structures
|
// let the initial page pools create areas for its structures
|
||||||
status_t error = PhysicalPageSlotPool::sInitialPhysicalPagePool
|
int32 poolCount = _GetInitialPoolCount();
|
||||||
.InitInitialPostArea(args);
|
for (int32 i = 0; i < poolCount; i++) {
|
||||||
if (error != B_OK)
|
status_t error = PhysicalPageSlotPool::sInitialPhysicalPagePool[i]
|
||||||
return error;
|
.InitInitialPostArea(args);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// The early physical page mapping mechanism is no longer needed. Unmap the
|
// The early physical page mapping mechanism is no longer needed. Unmap the
|
||||||
// slot.
|
// slot.
|
||||||
@@ -884,6 +897,16 @@ X86PagingMethodPAE::Free32BitPage(void* address, phys_addr_t physicalAddress,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int32
|
||||||
|
X86PagingMethodPAE::_GetInitialPoolCount()
|
||||||
|
{
|
||||||
|
int32 requiredSlots = smp_get_num_cpus() * TOTAL_SLOTS_PER_CPU
|
||||||
|
+ EXTRA_SLOTS;
|
||||||
|
return (requiredSlots + kPAEPageTableEntryCount - 1)
|
||||||
|
/ kPAEPageTableEntryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
X86PagingMethodPAE::_EarlyQuery(addr_t virtualAddress,
|
X86PagingMethodPAE::_EarlyQuery(addr_t virtualAddress,
|
||||||
phys_addr_t* _physicalAddress)
|
phys_addr_t* _physicalAddress)
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ private:
|
|||||||
friend struct PhysicalPageSlotPool;
|
friend struct PhysicalPageSlotPool;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline int32 _GetInitialPoolCount();
|
||||||
|
|
||||||
bool _EarlyQuery(addr_t virtualAddress,
|
bool _EarlyQuery(addr_t virtualAddress,
|
||||||
phys_addr_t* _physicalAddress);
|
phys_addr_t* _physicalAddress);
|
||||||
pae_page_table_entry* _EarlyGetPageTable(phys_addr_t address);
|
pae_page_table_entry* _EarlyGetPageTable(phys_addr_t address);
|
||||||
|
|||||||
@@ -48,12 +48,6 @@
|
|||||||
// a little longer, thus avoiding re-mapping.
|
// a little longer, thus avoiding re-mapping.
|
||||||
#define SLOTS_PER_TRANSLATION_MAP 4
|
#define SLOTS_PER_TRANSLATION_MAP 4
|
||||||
|
|
||||||
#define USER_SLOTS_PER_CPU 16
|
|
||||||
#define KERNEL_SLOTS_PER_CPU 16
|
|
||||||
#define TOTAL_SLOTS_PER_CPU (USER_SLOTS_PER_CPU \
|
|
||||||
+ KERNEL_SLOTS_PER_CPU + 1)
|
|
||||||
// one slot is for use in interrupts
|
|
||||||
|
|
||||||
|
|
||||||
using X86LargePhysicalPageMapper::PhysicalPageSlot;
|
using X86LargePhysicalPageMapper::PhysicalPageSlot;
|
||||||
using X86LargePhysicalPageMapper::PhysicalPageSlotPool;
|
using X86LargePhysicalPageMapper::PhysicalPageSlotPool;
|
||||||
@@ -125,9 +119,10 @@ public:
|
|||||||
LargeMemoryPhysicalPageMapper();
|
LargeMemoryPhysicalPageMapper();
|
||||||
|
|
||||||
status_t Init(kernel_args* args,
|
status_t Init(kernel_args* args,
|
||||||
PhysicalPageSlotPool* initialPool,
|
PhysicalPageSlotPool* initialPools,
|
||||||
TranslationMapPhysicalPageMapper*&
|
int32 initalPoolCount, size_t poolSize,
|
||||||
_kernelPageMapper);
|
TranslationMapPhysicalPageMapper*&
|
||||||
|
_kernelPageMapper);
|
||||||
|
|
||||||
virtual status_t CreateTranslationMapPhysicalPageMapper(
|
virtual status_t CreateTranslationMapPhysicalPageMapper(
|
||||||
TranslationMapPhysicalPageMapper** _mapper);
|
TranslationMapPhysicalPageMapper** _mapper);
|
||||||
@@ -428,11 +423,16 @@ LargeMemoryPhysicalPageMapper::LargeMemoryPhysicalPageMapper()
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
LargeMemoryPhysicalPageMapper::Init(kernel_args* args,
|
LargeMemoryPhysicalPageMapper::Init(kernel_args* args,
|
||||||
PhysicalPageSlotPool* initialPool,
|
PhysicalPageSlotPool* initialPools, int32 initialPoolCount, size_t poolSize,
|
||||||
TranslationMapPhysicalPageMapper*& _kernelPageMapper)
|
TranslationMapPhysicalPageMapper*& _kernelPageMapper)
|
||||||
{
|
{
|
||||||
fInitialPool = initialPool;
|
ASSERT(initialPoolCount >= 1);
|
||||||
fNonEmptyPools.Add(fInitialPool);
|
|
||||||
|
fInitialPool = initialPools;
|
||||||
|
for (int32 i = 0; i < initialPoolCount; i++) {
|
||||||
|
uint8* pointer = (uint8*)initialPools + i * poolSize;
|
||||||
|
fNonEmptyPools.Add((PhysicalPageSlotPool*)pointer);
|
||||||
|
}
|
||||||
|
|
||||||
// get the debug slot
|
// get the debug slot
|
||||||
GetSlot(true, fDebugSlot);
|
GetSlot(true, fDebugSlot);
|
||||||
@@ -755,12 +755,14 @@ LargeMemoryPhysicalPageMapper::GetSlotQueue(int32 cpu, bool user)
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
large_memory_physical_page_ops_init(kernel_args* args,
|
large_memory_physical_page_ops_init(kernel_args* args,
|
||||||
X86LargePhysicalPageMapper::PhysicalPageSlotPool* initialPool,
|
X86LargePhysicalPageMapper::PhysicalPageSlotPool* initialPools,
|
||||||
|
int32 initialPoolCount, size_t poolSize,
|
||||||
X86PhysicalPageMapper*& _pageMapper,
|
X86PhysicalPageMapper*& _pageMapper,
|
||||||
TranslationMapPhysicalPageMapper*& _kernelPageMapper)
|
TranslationMapPhysicalPageMapper*& _kernelPageMapper)
|
||||||
{
|
{
|
||||||
new(&sPhysicalPageMapper) LargeMemoryPhysicalPageMapper;
|
new(&sPhysicalPageMapper) LargeMemoryPhysicalPageMapper;
|
||||||
sPhysicalPageMapper.Init(args, initialPool, _kernelPageMapper);
|
sPhysicalPageMapper.Init(args, initialPools, initialPoolCount, poolSize,
|
||||||
|
_kernelPageMapper);
|
||||||
|
|
||||||
_pageMapper = &sPhysicalPageMapper;
|
_pageMapper = &sPhysicalPageMapper;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -11,6 +11,15 @@
|
|||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define USER_SLOTS_PER_CPU 16
|
||||||
|
#define KERNEL_SLOTS_PER_CPU 16
|
||||||
|
#define TOTAL_SLOTS_PER_CPU (USER_SLOTS_PER_CPU \
|
||||||
|
+ KERNEL_SLOTS_PER_CPU + 1)
|
||||||
|
// one slot is for use in interrupts
|
||||||
|
|
||||||
|
#define EXTRA_SLOTS 2
|
||||||
|
|
||||||
|
|
||||||
class TranslationMapPhysicalPageMapper;
|
class TranslationMapPhysicalPageMapper;
|
||||||
class X86PhysicalPageMapper;
|
class X86PhysicalPageMapper;
|
||||||
struct kernel_args;
|
struct kernel_args;
|
||||||
@@ -53,7 +62,8 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
status_t large_memory_physical_page_ops_init(kernel_args* args,
|
status_t large_memory_physical_page_ops_init(kernel_args* args,
|
||||||
X86LargePhysicalPageMapper::PhysicalPageSlotPool* initialPool,
|
X86LargePhysicalPageMapper::PhysicalPageSlotPool* initialPools,
|
||||||
|
int32 initialPoolCount, size_t poolSize,
|
||||||
X86PhysicalPageMapper*& _pageMapper,
|
X86PhysicalPageMapper*& _pageMapper,
|
||||||
TranslationMapPhysicalPageMapper*& _kernelPageMapper);
|
TranslationMapPhysicalPageMapper*& _kernelPageMapper);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user