Simplify the page directory init loops.
Also check and possibly reuse an existing page directory entry. This makes the possible memory maps a little more flexible.
This commit is contained in:
@@ -277,6 +277,33 @@ get_next_page_table(uint32 type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32 *
|
||||||
|
get_or_create_page_table(addr_t address, uint32 type)
|
||||||
|
{
|
||||||
|
uint32 *pageTable = NULL;
|
||||||
|
uint32 pageDirectoryIndex = VADDR_TO_PDENT(address);
|
||||||
|
uint32 pageDirectoryEntry = sPageDirectory[pageDirectoryIndex];
|
||||||
|
|
||||||
|
uint32 entryType = pageDirectoryEntry & ARM_PDE_TYPE_MASK;
|
||||||
|
if (entryType == ARM_MMU_L1_TYPE_FAULT) {
|
||||||
|
// This page directory entry has not been set yet, allocate it.
|
||||||
|
pageTable = get_next_page_table(type);
|
||||||
|
sPageDirectory[pageDirectoryIndex] = (uint32)pageTable | type;
|
||||||
|
return pageTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entryType != type) {
|
||||||
|
// This entry has been allocated with a different type!
|
||||||
|
panic("tried to reuse page directory entry %" B_PRIu32
|
||||||
|
" with different type (entry: %#" B_PRIx32 ", new type: %#" B_PRIx32
|
||||||
|
")\n", pageDirectoryIndex, pageDirectoryEntry, type);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32 *)(pageDirectoryEntry & ARM_PDE_ADDRESS_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init_page_directory()
|
init_page_directory()
|
||||||
{
|
{
|
||||||
@@ -295,33 +322,28 @@ init_page_directory()
|
|||||||
for (uint32 i = 0; i < ARM_MMU_L1_TABLE_ENTRY_COUNT; i++)
|
for (uint32 i = 0; i < ARM_MMU_L1_TABLE_ENTRY_COUNT; i++)
|
||||||
sPageDirectory[i] = 0;
|
sPageDirectory[i] = 0;
|
||||||
|
|
||||||
uint32 *pageTable = NULL;
|
|
||||||
for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP); i++) {
|
for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP); i++) {
|
||||||
|
|
||||||
pageTable = get_next_page_table(ARM_MMU_L1_TYPE_COARSE);
|
|
||||||
TRACE(("BLOCK: %s START: %lx END %lx\n", LOADER_MEMORYMAP[i].name,
|
TRACE(("BLOCK: %s START: %lx END %lx\n", LOADER_MEMORYMAP[i].name,
|
||||||
LOADER_MEMORYMAP[i].start, LOADER_MEMORYMAP[i].end));
|
LOADER_MEMORYMAP[i].start, LOADER_MEMORYMAP[i].end));
|
||||||
addr_t pos = LOADER_MEMORYMAP[i].start;
|
|
||||||
|
|
||||||
int c = 0;
|
addr_t address = LOADER_MEMORYMAP[i].start;
|
||||||
while (pos < LOADER_MEMORYMAP[i].end) {
|
ASSERT((address & ~ARM_PTE_ADDRESS_MASK) == 0);
|
||||||
pageTable[c] = pos | LOADER_MEMORYMAP[i].flags | smallType;
|
|
||||||
|
|
||||||
c++;
|
uint32 *pageTable = NULL;
|
||||||
if (c > 255) { // we filled a pagetable => we need a new one
|
uint32 pageTableIndex = 0;
|
||||||
// there is 1MB per pagetable so:
|
|
||||||
sPageDirectory[VADDR_TO_PDENT(pos)]
|
while (address < LOADER_MEMORYMAP[i].end) {
|
||||||
= (uint32)pageTable | ARM_MMU_L1_TYPE_COARSE;
|
if (pageTable == NULL
|
||||||
pageTable = get_next_page_table(ARM_MMU_L1_TYPE_COARSE);
|
|| pageTableIndex >= ARM_MMU_L2_COARSE_ENTRY_COUNT) {
|
||||||
c = 0;
|
pageTable = get_or_create_page_table(address,
|
||||||
|
ARM_MMU_L1_TYPE_COARSE);
|
||||||
|
pageTableIndex = VADDR_TO_PTENT(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += B_PAGE_SIZE;
|
pageTable[pageTableIndex++]
|
||||||
}
|
= address | LOADER_MEMORYMAP[i].flags | smallType;
|
||||||
|
address += B_PAGE_SIZE;
|
||||||
if (c > 0) {
|
|
||||||
sPageDirectory[VADDR_TO_PDENT(pos)]
|
|
||||||
= (uint32)pageTable | ARM_MMU_L1_TYPE_COARSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user