From 48ac51f8866a5e44e1789f0df8e589e0eb19131d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 27 Oct 2004 16:44:04 +0000 Subject: [PATCH] Added support to map more than 4 MB in the kernel space. This became necessary to be able to have more than 1280x1024x8 resolutions. The best solution, however, would be to map the graphics memory outside of the kernel space, anyway. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9537 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/boot/platform/bios_ia32/mmu.cpp | 47 ++++++++++++++++------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/src/kernel/boot/platform/bios_ia32/mmu.cpp b/src/kernel/boot/platform/bios_ia32/mmu.cpp index c714b3fea7..7bdc367502 100644 --- a/src/kernel/boot/platform/bios_ia32/mmu.cpp +++ b/src/kernel/boot/platform/bios_ia32/mmu.cpp @@ -102,6 +102,28 @@ get_next_physical_page() } +/** Adds a new page table for the specified base address and makes + * it current, ie. sets sPageTable to point to the new table. + */ + +static void +add_page_table(addr_t base) +{ + // Get new page table and clear it out + sPageTable = (uint32 *)get_next_physical_page(); + if (sPageTable > (uint32 *)(8 * 1024 * 1024)) + panic("tried to add page table beyond the indentity mapped 8 MB region\n"); + + gKernelArgs.arch_args.pgtables[gKernelArgs.arch_args.num_pgtables++] = (uint32)sPageTable; + + for (int32 i = 0; i < 1024; i++) + sPageTable[i] = 0; + + // put the new page table into the page directory + sPageDirectory[base/(4*1024*1024)] = (uint32)sPageTable | kDefaultPageFlags; +} + + /** Creates an entry to map the specified virtualAddress to the given * physicalAddress. * Note, it can only map the 4 meg region right after KERNEL_BASE; this @@ -114,9 +136,19 @@ map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags) { TRACE(("map_page: vaddr 0x%lx, paddr 0x%lx\n", virtualAddress, physicalAddress)); - if (virtualAddress < KERNEL_BASE || virtualAddress >= sMaxVirtualAddress) + if (virtualAddress < KERNEL_BASE) panic("map_page: asked to map invalid page %p!\n", (void *)virtualAddress); + if (virtualAddress >= sMaxVirtualAddress) { + // we need to add a new page table + + add_page_table(sMaxVirtualAddress); + sMaxVirtualAddress += B_PAGE_SIZE * 1024; + + if (virtualAddress >= sMaxVirtualAddress) + panic("map_page: asked to map a page to %p\n", (void *)virtualAddress); + } + physicalAddress &= ~(B_PAGE_SIZE - 1); TRACE(("paddr 0x%lx @ index %ld\n", physicalAddress, @@ -214,17 +246,8 @@ init_page_directory() sPageDirectory[1] = (uint32)pgtable | kDefaultPageFlags; - // Get new page table and clear it out - sPageTable = (uint32 *)get_next_physical_page(); - gKernelArgs.arch_args.pgtables[0] = (uint32)sPageTable; - gKernelArgs.arch_args.num_pgtables = 1; - - for (int32 i = 0; i < 1024; i++) - sPageTable[i] = 0; - - // put the new page table into the page directory - // this maps the kernel at KERNEL_BASE - sPageDirectory[KERNEL_BASE/(4*1024*1024)] = (uint32)sPageTable | kDefaultPageFlags; + gKernelArgs.arch_args.num_pgtables = 0; + add_page_table(KERNEL_BASE); // switch to the new pgdir and enable paging asm("movl %0, %%eax;"