From a6cb002e99924f51b179bf0d8f19e2b872712573 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Tue, 14 Aug 2018 16:15:58 -0500 Subject: [PATCH] boot/mmu: Consolidate some fdt mapping functions * Realized we already had a function which iterates over an fdt node and maps it's memory regs. Make it work for physical mappings or identity mappings. Change-Id: I0e3e323798bc2dfcead1accc1d403b30a8ab188f --- src/system/boot/arch/arm/arch_mmu.cpp | 158 ++++++++++---------------- 1 file changed, 62 insertions(+), 96 deletions(-) diff --git a/src/system/boot/arch/arm/arch_mmu.cpp b/src/system/boot/arch/arm/arch_mmu.cpp index b35f59e066..d49de968cd 100644 --- a/src/system/boot/arch/arm/arch_mmu.cpp +++ b/src/system/boot/arch/arm/arch_mmu.cpp @@ -352,38 +352,71 @@ map_pages_loader() } +//TODO:move this to generic/ ? static status_t -map_pages_peripherals() +fdt_map_memory_ranges(const char* path, bool physical = false) { int node; - phys_addr_t regs_start; - phys_addr_t regs_end; - const char* name = "/axi"; + const void *prop; + int len; + uint64 total; - node = fdt_path_offset(gFDT, name); - if (node < 0) { - TRACE(("Unable to locate path offset for simple-bus!")); + dprintf("checking FDT for %s...\n", path); + node = fdt_path_offset(gFDT, path); + + total = 0; + + int32 regAddressCells = 1; + int32 regSizeCells = 1; + fdt_get_cell_count(gFDT, node, regAddressCells, regSizeCells); + + prop = fdt_getprop(gFDT, node, "reg", &len); + if (prop == NULL) { + dprintf("Unable to locate %s in FDT!\n", path); return B_ERROR; } - // determine the MMIO address - regs_start = fdt_get_device_reg(gFDT, node, false); + const uint32 *p = (const uint32 *)prop; + for (int32 i = 0; len; i++) { + uint64 base; + uint64 size; + if (regAddressCells == 2) + base = fdt64_to_cpu(*(uint64_t *)p); + else + base = fdt32_to_cpu(*(uint32_t *)p); + p += regAddressCells; + if (regSizeCells == 2) + size = fdt64_to_cpu(*(uint64_t *)p); + else + size = fdt32_to_cpu(*(uint32_t *)p); + p += regSizeCells; + len -= sizeof(uint32) * (regAddressCells + regSizeCells); - #warning TODO: This MMU code is overly simplistic. - if (regs_start == 0) { - // TODO: FDT's like am335x have peripherals at various - // locations. We should map *each* item within simple-bus. - panic("No reg for simple-bus. See TODO"); - return B_ERROR; + if (size <= 0) { + dprintf("%ld: empty region\n", i); + continue; + } + dprintf("%" B_PRIu32 ": base = %" B_PRIu64 "," + "size = %" B_PRIu64 "\n", i, base, size); + + total += size; + + if (physical) { + if (insert_physical_memory_range(base, size) != B_OK) { + dprintf("cannot map physical memory range " + "(num ranges = %" B_PRIu32 ")!\n", + gKernelArgs.num_physical_memory_ranges); + return B_ERROR; + } + } else { + if (mmu_map_identity(base, base + size, ARM_MMU_L2_FLAG_B)) { + dprintf("cannot identity map memory range!"); + return B_ERROR; + } } - // TODO: Obvious hack is obvious - regs_end = regs_start + 0x01000000; - - TRACE(("BLOCK: %s START: %lx END %lx\n", name, regs_start, regs_end)); - ASSERT((regs_start & ~ARM_PTE_ADDRESS_MASK) == 0); - - mmu_map_identity(regs_start, regs_end, ARM_MMU_L2_FLAG_B); + dprintf("total '%s' physical memory = %" B_PRId64 "MB\n", path, + total / (1024 * 1024)); return B_OK; } @@ -410,11 +443,10 @@ init_page_directory() // map our well known / static pages map_pages_loader(); - // map peripheral devices from fdt - if (map_pages_peripherals() != B_OK) { - // This is a panic since we still have serial access. - panic("%s: unable to map peripherals! Check FDT.\n", __func__); - } + // map peripheral devices (such as uart) from fdt + // TODO: Iterate over for "simple-bus" compatible devices! + // this assumes /axi which is broadcom! + fdt_map_memory_ranges("/axi"); mmu_flush_TLB(); @@ -662,69 +694,6 @@ mmu_init_for_kernel(void) } -//TODO:move this to generic/ ? -static status_t -find_physical_memory_ranges(uint64 &total) -{ - int node; - const void *prop; - int len; - - dprintf("checking for memory...\n"); - // let's just skip the OF way (prop memory on /chosen) - //node = fdt_path_offset(gFDT, "/chosen"); - node = fdt_path_offset(gFDT, "/memory"); - // TODO: check devicetype=="memory" ? - - total = 0; - - int32 regAddressCells = 1; - int32 regSizeCells = 1; - fdt_get_cell_count(gFDT, node, regAddressCells, regSizeCells); - - prop = fdt_getprop(gFDT, node, "reg", &len); - if (prop == NULL) { - panic("FDT /memory reg property not set"); - return B_ERROR; - } - - const uint32 *p = (const uint32 *)prop; - for (int32 i = 0; len; i++) { - uint64 base; - uint64 size; - if (regAddressCells == 2) - base = fdt64_to_cpu(*(uint64_t *)p); - else - base = fdt32_to_cpu(*(uint32_t *)p); - p += regAddressCells; - if (regSizeCells == 2) - size = fdt64_to_cpu(*(uint64_t *)p); - else - size = fdt32_to_cpu(*(uint32_t *)p); - p += regSizeCells; - len -= sizeof(uint32) * (regAddressCells + regSizeCells); - - if (size <= 0) { - dprintf("%ld: empty region\n", i); - continue; - } - dprintf("%" B_PRIu32 ": base = %" B_PRIu64 "," - "size = %" B_PRIu64 "\n", i, base, size); - - total += size; - - if (insert_physical_memory_range(base, size) != B_OK) { - dprintf("cannot map physical memory range " - "(num ranges = %" B_PRIu32 ")!\n", - gKernelArgs.num_physical_memory_ranges); - return B_ERROR; - } - } - - return B_OK; -} - - extern "C" void mmu_init(void) { @@ -734,22 +703,19 @@ mmu_init(void) if (gKernelArgs.num_physical_memory_ranges == 0) { // get map of physical memory (fill in kernel_args structure) - uint64 total; - if (find_physical_memory_ranges(total) != B_OK) { - dprintf("Error: could not find physical memory ranges!\n"); + if (fdt_map_memory_ranges("/memory", true) != B_OK) { + panic("Error: could not find physical memory ranges from FDT!\n"); #ifdef SDRAM_BASE dprintf("Defaulting to 32MB at %" B_PRIx64 "\n", (uint64)SDRAM_BASE); // specify available physical memory, using 32MB for now, since our // ARMv5 targets have very little by default. - total = 32 * 1024 * 1024; + uint64 total = 32 * 1024 * 1024; insert_physical_memory_range(SDRAM_BASE, total); #else return /*B_ERROR*/; #endif } - dprintf("total physical memory = %" B_PRId64 "MB\n", - total / (1024 * 1024)); } // see if subpages are disabled