|
@@ -26,6 +26,54 @@
|
|
|
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
|
|
|
#include <asm/page.h>
|
|
|
|
|
|
+/*
|
|
|
+ * of_fdt_limit_memory - limit the number of regions in the /memory node
|
|
|
+ * @limit: maximum entries
|
|
|
+ *
|
|
|
+ * Adjust the flattened device tree to have at most 'limit' number of
|
|
|
+ * memory entries in the /memory node. This function may be called
|
|
|
+ * any time after initial_boot_param is set.
|
|
|
+ */
|
|
|
+void of_fdt_limit_memory(int limit)
|
|
|
+{
|
|
|
+ int memory;
|
|
|
+ int len;
|
|
|
+ const void *val;
|
|
|
+ int nr_address_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
|
|
|
+ int nr_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
|
|
|
+ const uint32_t *addr_prop;
|
|
|
+ const uint32_t *size_prop;
|
|
|
+ int root_offset;
|
|
|
+ int cell_size;
|
|
|
+
|
|
|
+ root_offset = fdt_path_offset(initial_boot_params, "/");
|
|
|
+ if (root_offset < 0)
|
|
|
+ return;
|
|
|
+
|
|
|
+ addr_prop = fdt_getprop(initial_boot_params, root_offset,
|
|
|
+ "#address-cells", NULL);
|
|
|
+ if (addr_prop)
|
|
|
+ nr_address_cells = fdt32_to_cpu(*addr_prop);
|
|
|
+
|
|
|
+ size_prop = fdt_getprop(initial_boot_params, root_offset,
|
|
|
+ "#size-cells", NULL);
|
|
|
+ if (size_prop)
|
|
|
+ nr_size_cells = fdt32_to_cpu(*size_prop);
|
|
|
+
|
|
|
+ cell_size = sizeof(uint32_t)*(nr_address_cells + nr_size_cells);
|
|
|
+
|
|
|
+ memory = fdt_path_offset(initial_boot_params, "/memory");
|
|
|
+ if (memory > 0) {
|
|
|
+ val = fdt_getprop(initial_boot_params, memory, "reg", &len);
|
|
|
+ if (len > limit*cell_size) {
|
|
|
+ len = limit*cell_size;
|
|
|
+ pr_debug("Limiting number of entries to %d\n", limit);
|
|
|
+ fdt_setprop(initial_boot_params, memory, "reg", val,
|
|
|
+ len);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* of_fdt_is_compatible - Return true if given node from the given blob has
|
|
|
* compat in its compatible list
|
|
@@ -937,7 +985,7 @@ int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-bool __init early_init_dt_scan(void *params)
|
|
|
+bool __init early_init_dt_verify(void *params)
|
|
|
{
|
|
|
if (!params)
|
|
|
return false;
|
|
@@ -951,6 +999,12 @@ bool __init early_init_dt_scan(void *params)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void __init early_init_dt_scan_nodes(void)
|
|
|
+{
|
|
|
/* Retrieve various information from the /chosen node */
|
|
|
of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
|
|
|
|
|
@@ -959,7 +1013,17 @@ bool __init early_init_dt_scan(void *params)
|
|
|
|
|
|
/* Setup memory, calling early_init_dt_add_memory_arch */
|
|
|
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+bool __init early_init_dt_scan(void *params)
|
|
|
+{
|
|
|
+ bool status;
|
|
|
+
|
|
|
+ status = early_init_dt_verify(params);
|
|
|
+ if (!status)
|
|
|
+ return false;
|
|
|
|
|
|
+ early_init_dt_scan_nodes();
|
|
|
return true;
|
|
|
}
|
|
|
|