|
@@ -523,6 +523,20 @@ static int __init early_init_dt_scan_memory_ppc(unsigned long node,
|
|
return early_init_dt_scan_memory(node, uname, depth, data);
|
|
return early_init_dt_scan_memory(node, uname, depth, data);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * For a relocatable kernel, we need to get the memstart_addr first,
|
|
|
|
+ * then use it to calculate the virtual kernel start address. This has
|
|
|
|
+ * to happen at a very early stage (before machine_init). In this case,
|
|
|
|
+ * we just want to get the memstart_address and would not like to mess the
|
|
|
|
+ * memblock at this stage. So introduce a variable to skip the memblock_add()
|
|
|
|
+ * for this reason.
|
|
|
|
+ */
|
|
|
|
+#ifdef CONFIG_RELOCATABLE
|
|
|
|
+static int add_mem_to_memblock = 1;
|
|
|
|
+#else
|
|
|
|
+#define add_mem_to_memblock 1
|
|
|
|
+#endif
|
|
|
|
+
|
|
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
|
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
|
{
|
|
{
|
|
#ifdef CONFIG_PPC64
|
|
#ifdef CONFIG_PPC64
|
|
@@ -543,7 +557,8 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
|
}
|
|
}
|
|
|
|
|
|
/* Add the chunk to the MEMBLOCK list */
|
|
/* Add the chunk to the MEMBLOCK list */
|
|
- memblock_add(base, size);
|
|
|
|
|
|
+ if (add_mem_to_memblock)
|
|
|
|
+ memblock_add(base, size);
|
|
}
|
|
}
|
|
|
|
|
|
static void __init early_reserve_mem_dt(void)
|
|
static void __init early_reserve_mem_dt(void)
|
|
@@ -740,6 +755,30 @@ void __init early_init_devtree(void *params)
|
|
DBG(" <- early_init_devtree()\n");
|
|
DBG(" <- early_init_devtree()\n");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_RELOCATABLE
|
|
|
|
+/*
|
|
|
|
+ * This function run before early_init_devtree, so we have to init
|
|
|
|
+ * initial_boot_params.
|
|
|
|
+ */
|
|
|
|
+void __init early_get_first_memblock_info(void *params, phys_addr_t *size)
|
|
|
|
+{
|
|
|
|
+ /* Setup flat device-tree pointer */
|
|
|
|
+ initial_boot_params = params;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Scan the memory nodes and set add_mem_to_memblock to 0 to avoid
|
|
|
|
+ * mess the memblock.
|
|
|
|
+ */
|
|
|
|
+ add_mem_to_memblock = 0;
|
|
|
|
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
|
|
|
|
+ of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
|
|
|
|
+ add_mem_to_memblock = 1;
|
|
|
|
+
|
|
|
|
+ if (size)
|
|
|
|
+ *size = first_memblock_size;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
/*******
|
|
/*******
|
|
*
|
|
*
|
|
* New implementation of the OF "find" APIs, return a refcounted
|
|
* New implementation of the OF "find" APIs, return a refcounted
|