aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorKevin Hao <haokexin@gmail.com>2013-12-24 02:12:08 -0500
committerScott Wood <scottwood@freescale.com>2014-01-09 18:52:17 -0500
commitb27652dd2174df1a7e0a7c5f00d1c8e3ed9287a7 (patch)
treea93bf5700c442d52a2ed86de8d2203f05e78cf23 /arch/powerpc
parent78a235efdc42ff363de81fdbc171385e8b86b69b (diff)
powerpc: introduce early_get_first_memblock_info
For a relocatable kernel since it can be loaded at any place, there is no any relation between the kernel start addr and the memstart_addr. So we can't calculate the memstart_addr from kernel start addr. And also we can't wait to do the relocation after we get the real memstart_addr from device tree because it is so late. So introduce a new function we can use to get the first memblock address and size in a very early stage (before machine_init). Signed-off-by: Kevin Hao <haokexin@gmail.com> Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/prom.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fa0ad8aafbcc..f58c0d3aaeb4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -523,6 +523,20 @@ static int __init early_init_dt_scan_memory_ppc(unsigned long node,
523 return early_init_dt_scan_memory(node, uname, depth, data); 523 return early_init_dt_scan_memory(node, uname, depth, data);
524} 524}
525 525
526/*
527 * For a relocatable kernel, we need to get the memstart_addr first,
528 * then use it to calculate the virtual kernel start address. This has
529 * to happen at a very early stage (before machine_init). In this case,
530 * we just want to get the memstart_address and would not like to mess the
531 * memblock at this stage. So introduce a variable to skip the memblock_add()
532 * for this reason.
533 */
534#ifdef CONFIG_RELOCATABLE
535static int add_mem_to_memblock = 1;
536#else
537#define add_mem_to_memblock 1
538#endif
539
526void __init early_init_dt_add_memory_arch(u64 base, u64 size) 540void __init early_init_dt_add_memory_arch(u64 base, u64 size)
527{ 541{
528#ifdef CONFIG_PPC64 542#ifdef CONFIG_PPC64
@@ -543,7 +557,8 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
543 } 557 }
544 558
545 /* Add the chunk to the MEMBLOCK list */ 559 /* Add the chunk to the MEMBLOCK list */
546 memblock_add(base, size); 560 if (add_mem_to_memblock)
561 memblock_add(base, size);
547} 562}
548 563
549static void __init early_reserve_mem_dt(void) 564static void __init early_reserve_mem_dt(void)
@@ -740,6 +755,30 @@ void __init early_init_devtree(void *params)
740 DBG(" <- early_init_devtree()\n"); 755 DBG(" <- early_init_devtree()\n");
741} 756}
742 757
758#ifdef CONFIG_RELOCATABLE
759/*
760 * This function run before early_init_devtree, so we have to init
761 * initial_boot_params.
762 */
763void __init early_get_first_memblock_info(void *params, phys_addr_t *size)
764{
765 /* Setup flat device-tree pointer */
766 initial_boot_params = params;
767
768 /*
769 * Scan the memory nodes and set add_mem_to_memblock to 0 to avoid
770 * mess the memblock.
771 */
772 add_mem_to_memblock = 0;
773 of_scan_flat_dt(early_init_dt_scan_root, NULL);
774 of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
775 add_mem_to_memblock = 1;
776
777 if (size)
778 *size = first_memblock_size;
779}
780#endif
781
743/******* 782/*******
744 * 783 *
745 * New implementation of the OF "find" APIs, return a refcounted 784 * New implementation of the OF "find" APIs, return a refcounted