ARM: Check for RAM size in FDT
We skip the check when we already have ranges inserted, like from the raspberry Pi start code, and we fall back to 32MB at SDRAM_BASE is not found.
This commit is contained in:
@@ -2,6 +2,7 @@ SubDir HAIKU_TOP src system boot arch arm ;
|
||||
|
||||
#XXX: should not be needed here
|
||||
UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ;
|
||||
UseLibraryHeaders [ FDirName libfdt ] ;
|
||||
|
||||
{
|
||||
local defines = _BOOT_MODE ;
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#include <libfdt_env.h>
|
||||
};
|
||||
|
||||
|
||||
//#define TRACE_MMU
|
||||
#ifdef TRACE_MMU
|
||||
@@ -37,6 +43,8 @@
|
||||
// You also need to define ENABLE_SERIAL in serial.cpp
|
||||
// for output to work.
|
||||
|
||||
extern void *gFDT;
|
||||
|
||||
|
||||
/*
|
||||
TODO:
|
||||
@@ -551,11 +559,113 @@ 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;
|
||||
|
||||
// Memory base addresses are provided in 32 or 64 bit flavors
|
||||
// #address-cells and #size-cells matches the number of 32-bit 'cells'
|
||||
// representing the length of the base address and size fields
|
||||
int root = fdt_path_offset(gFDT, "/");
|
||||
int32 regAddressCells = 1;
|
||||
int32 regSizeCells = 1;
|
||||
prop = fdt_getprop(gFDT, root, "#address-cells", &len);
|
||||
if (prop && len == sizeof(uint32))
|
||||
regAddressCells = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
prop = fdt_getprop(gFDT, root, "#size-cells", &len);
|
||||
if (prop && len == sizeof(uint32))
|
||||
regSizeCells = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
|
||||
|
||||
// NOTE : Size Cells of 2 is possible in theory... but I haven't seen it yet.
|
||||
if (regAddressCells > 2 || regSizeCells > 1) {
|
||||
panic("%s: Unsupported FDT cell count detected.\n"
|
||||
"Address Cells: %" B_PRId32 "; Size Cells: %" B_PRId32
|
||||
" (CPU > 64bit?).\n", __func__, regAddressCells, regSizeCells);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
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 += regAddressCells;
|
||||
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)
|
||||
{
|
||||
TRACE(("mmu_init\n"));
|
||||
|
||||
// skip RAM check if already done (rPi)
|
||||
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");
|
||||
|
||||
#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;
|
||||
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
|
||||
if (mmu_read_C1() & (1 << 23))
|
||||
sSmallPageType = ARM_MMU_L2_TYPE_SMALLNEW;
|
||||
|
||||
@@ -277,10 +277,6 @@ start_gen(int argc, const char **argv, struct image_header *uimage, void *fdt)
|
||||
args.platform.boot_tgz_size);
|
||||
}
|
||||
|
||||
// specify available physical memory, using 32MB for now, since our
|
||||
// ARMv5 targets have very little by default. TODO get from FDT!
|
||||
insert_physical_memory_range(SDRAM_BASE, 32 * 1024 * 1024);
|
||||
|
||||
// save the size of the FDT so we can map it easily after mmu_init
|
||||
size_t fdtSize = gFDT ? fdt_totalsize(gFDT) : 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user