From 3e450daa1c856fb979541d9f5a8275ad25d6c0e4 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sun, 7 Sep 2014 00:28:54 +0200 Subject: [PATCH] ARM: remove the loader from the memory map table We have _start/_end symbols to mark our start and end, use those to determine where we are loaded. We're slowly getting closer to a fully dynamic handling of our memory map! --- src/system/boot/arch/arm/arch_mmu.cpp | 79 ++++++++++++++++----------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/src/system/boot/arch/arm/arch_mmu.cpp b/src/system/boot/arch/arm/arch_mmu.cpp index 3bd0ffd5b2..a0f1693653 100644 --- a/src/system/boot/arch/arm/arch_mmu.cpp +++ b/src/system/boot/arch/arm/arch_mmu.cpp @@ -64,6 +64,9 @@ static const size_t kMaxKernelSize = 0x800000; // Base address for loader static const size_t kLoaderBaseAddress = KERNEL_LOAD_BASE + kMaxKernelSize; +// Start and end of ourselfs +extern int _start, _end; + /* *defines a block in memory */ @@ -92,12 +95,6 @@ static struct memblock LOADER_MEMORYMAP[] = { KERNEL_LOAD_BASE + kMaxKernelSize - 1, ARM_MMU_L2_FLAG_C, }, - { - "RAM_loader", // 1MB loader - kLoaderBaseAddress + 0, - kLoaderBaseAddress + 0x0fffff, - ARM_MMU_L2_FLAG_C, - }, { "RAM_pt", // Page Table 1MB kLoaderBaseAddress + 0x100000, @@ -126,12 +123,14 @@ static struct memblock LOADER_MEMORYMAP[] = { // not cached not buffered, R/W static addr_t sNextPhysicalAddress = 0; //will be set by mmu_init -static addr_t sNextVirtualAddress = LOADER_MEMORYMAP[4].start; +static addr_t sNextVirtualAddress = 0; static addr_t sNextPageTableAddress = 0; //the page directory is in front of the pagetable static uint32 kPageTableRegionEnd = 0; +static uint32 sSmallPageType = ARM_MMU_L2_TYPE_SMALLEXT; + // working page directory and page table static uint32 *sPageDirectory = 0 ; //page directory has to be on a multiple of 16MB for @@ -309,17 +308,34 @@ get_or_create_page_table(addr_t address, uint32 type) } +static void +mmu_map_identity(addr_t start, size_t end, int flags) +{ + uint32 *pageTable = NULL; + uint32 pageTableIndex = 0; + + start = ROUNDDOWN(start, B_PAGE_SIZE); + end = ROUNDUP(end, B_PAGE_SIZE); + + TRACE(("mmu_map_identity: [ %" B_PRIxADDR " - %" B_PRIxADDR "]\n", start, end)); + + for (addr_t address = start; address < end; address += B_PAGE_SIZE) { + if (pageTable == NULL + || pageTableIndex >= ARM_MMU_L2_COARSE_ENTRY_COUNT) { + pageTable = get_or_create_page_table(address, + ARM_MMU_L1_TYPE_COARSE); + pageTableIndex = VADDR_TO_PTENT(address); + } + + pageTable[pageTableIndex++] + = address | flags | sSmallPageType; + } +} + void init_page_directory() { TRACE(("init_page_directory\n")); - uint32 smallType; - - // see if subpages are disabled - if (mmu_read_C1() & (1 << 23)) - smallType = ARM_MMU_L2_TYPE_SMALLNEW; - else - smallType = ARM_MMU_L2_TYPE_SMALLEXT; gKernelArgs.arch_args.phys_pgdir = (uint32)sPageDirectory; @@ -327,6 +343,9 @@ init_page_directory() for (uint32 i = 0; i < ARM_MMU_L1_TABLE_ENTRY_COUNT; i++) sPageDirectory[i] = 0; + // map ourselfs first... just to make sure + mmu_map_identity((addr_t)&_start, (addr_t)&_end, ARM_MMU_L2_FLAG_C); + for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP); i++) { TRACE(("BLOCK: %s START: %lx END %lx\n", LOADER_MEMORYMAP[i].name, @@ -335,21 +354,8 @@ init_page_directory() addr_t address = LOADER_MEMORYMAP[i].start; ASSERT((address & ~ARM_PTE_ADDRESS_MASK) == 0); - uint32 *pageTable = NULL; - uint32 pageTableIndex = 0; - - while (address < LOADER_MEMORYMAP[i].end) { - if (pageTable == NULL - || pageTableIndex >= ARM_MMU_L2_COARSE_ENTRY_COUNT) { - pageTable = get_or_create_page_table(address, - ARM_MMU_L1_TYPE_COARSE); - pageTableIndex = VADDR_TO_PTENT(address); - } - - pageTable[pageTableIndex++] - = address | LOADER_MEMORYMAP[i].flags | smallType; - address += B_PAGE_SIZE; - } + mmu_map_identity(LOADER_MEMORYMAP[i].start, LOADER_MEMORYMAP[i].end, + LOADER_MEMORYMAP[i].flags); } // Map the page directory itself. @@ -588,6 +594,10 @@ mmu_init(void) { TRACE(("mmu_init\n")); + // see if subpages are disabled + if (mmu_read_C1() & (1 << 23)) + sSmallPageType = ARM_MMU_L2_TYPE_SMALLNEW; + mmu_write_C1(mmu_read_C1() & ~((1 << 29) | (1 << 28) | (1 << 0))); // access flag disabled, TEX remap disabled, mmu disabled @@ -595,8 +605,10 @@ mmu_init(void) // calculate lowest RAM adress from MEMORYMAP for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP); i++) { - if (strcmp("RAM_free", LOADER_MEMORYMAP[i].name) == 0) + if (strcmp("RAM_free", LOADER_MEMORYMAP[i].name) == 0) { sNextPhysicalAddress = LOADER_MEMORYMAP[i].start; + sNextVirtualAddress = LOADER_MEMORYMAP[i].start; + } if (strcmp("RAM_pt", LOADER_MEMORYMAP[i].name) == 0) { sNextPageTableAddress = LOADER_MEMORYMAP[i].start @@ -611,9 +623,10 @@ mmu_init(void) } } - gKernelArgs.physical_memory_range[0].start = SDRAM_BASE; - gKernelArgs.physical_memory_range[0].size = highestRAMAddress - SDRAM_BASE; - gKernelArgs.num_physical_memory_ranges = 1; + insert_physical_memory_range(SDRAM_BASE, highestRAMAddress - SDRAM_BASE); + + // mark ourselfs as allocated, so init_page_directory doesn't overwrite us + insert_physical_allocated_range((addr_t)&_start, (addr_t)&_end - (addr_t)&_start); init_page_directory();