hrev52228 adds 1 changeset to branch 'master'
old head: ab39ceb10cd46f91f7c2443e133e2ba7e66121d9
new head: a6cb002e99924f51b179bf0d8f19e2b872712573
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=a6cb002e9992+%5Eab39ceb10cd4
----------------------------------------------------------------------------
a6cb002e9992: 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
[ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev52228
Commit: a6cb002e99924f51b179bf0d8f19e2b872712573
URL: https://git.haiku-os.org/haiku/commit/?id=a6cb002e9992
Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date: Tue Aug 14 21:15:58 2018 UTC
----------------------------------------------------------------------------
1 file changed, 61 insertions(+), 95 deletions(-)
src/system/boot/arch/arm/arch_mmu.cpp | 156 ++++++++++++------------------
----------------------------------------------------------------------------
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!"));
- return B_ERROR;
- }
+ dprintf("checking FDT for %s...\n", path);
+ node = fdt_path_offset(gFDT, path);
+
+ total = 0;
- // determine the MMIO address
- regs_start = fdt_get_device_reg(gFDT, node, false);
+ int32 regAddressCells = 1;
+ int32 regSizeCells = 1;
+ fdt_get_cell_count(gFDT, node, 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");
+ prop = fdt_getprop(gFDT, node, "reg", &len);
+ if (prop == NULL) {
+ dprintf("Unable to locate %s in FDT!\n", path);
return B_ERROR;
}
- // TODO: Obvious hack is obvious
- regs_end = regs_start + 0x01000000;
+ 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);
- TRACE(("BLOCK: %s START: %lx END %lx\n", name, regs_start, regs_end));
- ASSERT((regs_start & ~ARM_PTE_ADDRESS_MASK) == 0);
+ 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;
+ }
+ }
- 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