|
@@ -22,6 +22,73 @@
|
|
|
|
|
|
static unsigned char fdt_buf[16 << 10] __initdata;
|
|
|
|
|
|
+static int append_memory(void *fdt)
|
|
|
+{
|
|
|
+ unsigned long phys_memsize, memsize;
|
|
|
+ __be32 mem_array[2];
|
|
|
+ int err, mem_off;
|
|
|
+ char *var;
|
|
|
+
|
|
|
+ /* find memory size from the bootloader environment */
|
|
|
+ var = fw_getenv("memsize");
|
|
|
+ if (var) {
|
|
|
+ err = kstrtoul(var, 0, &phys_memsize);
|
|
|
+ if (err) {
|
|
|
+ pr_err("Failed to read memsize env variable '%s'\n",
|
|
|
+ var);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n");
|
|
|
+ phys_memsize = 32 << 20;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* default to using all available RAM */
|
|
|
+ memsize = phys_memsize;
|
|
|
+
|
|
|
+ /* allow the user to override the usable memory */
|
|
|
+ var = strstr(arcs_cmdline, "memsize=");
|
|
|
+ if (var)
|
|
|
+ memsize = memparse(var + strlen("memsize="), NULL);
|
|
|
+
|
|
|
+ /* if the user says there's more RAM than we thought, believe them */
|
|
|
+ phys_memsize = max_t(unsigned long, phys_memsize, memsize);
|
|
|
+
|
|
|
+ /* find or add a memory node */
|
|
|
+ mem_off = fdt_path_offset(fdt, "/memory");
|
|
|
+ if (mem_off == -FDT_ERR_NOTFOUND)
|
|
|
+ mem_off = fdt_add_subnode(fdt, 0, "memory");
|
|
|
+ if (mem_off < 0) {
|
|
|
+ pr_err("Unable to find or add memory DT node: %d\n", mem_off);
|
|
|
+ return mem_off;
|
|
|
+ }
|
|
|
+
|
|
|
+ err = fdt_setprop_string(fdt, mem_off, "device_type", "memory");
|
|
|
+ if (err) {
|
|
|
+ pr_err("Unable to set memory node device_type: %d\n", err);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+
|
|
|
+ mem_array[0] = 0;
|
|
|
+ mem_array[1] = cpu_to_be32(phys_memsize);
|
|
|
+ err = fdt_setprop(fdt, mem_off, "reg", mem_array, sizeof(mem_array));
|
|
|
+ if (err) {
|
|
|
+ pr_err("Unable to set memory regs property: %d\n", err);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+
|
|
|
+ mem_array[0] = 0;
|
|
|
+ mem_array[1] = cpu_to_be32(memsize);
|
|
|
+ err = fdt_setprop(fdt, mem_off, "linux,usable-memory",
|
|
|
+ mem_array, sizeof(mem_array));
|
|
|
+ if (err) {
|
|
|
+ pr_err("Unable to set linux,usable-memory property: %d\n", err);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int remove_gic(void *fdt)
|
|
|
{
|
|
|
const unsigned int cpu_ehci_int = 2;
|
|
@@ -205,6 +272,10 @@ void __init *sead3_dt_shim(void *fdt)
|
|
|
if (err)
|
|
|
panic("Unable to open FDT: %d", err);
|
|
|
|
|
|
+ err = append_memory(fdt_buf);
|
|
|
+ if (err)
|
|
|
+ panic("Unable to patch FDT: %d", err);
|
|
|
+
|
|
|
err = remove_gic(fdt_buf);
|
|
|
if (err)
|
|
|
panic("Unable to patch FDT: %d", err);
|