diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 41 |
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 | ||
535 | static int add_mem_to_memblock = 1; | ||
536 | #else | ||
537 | #define add_mem_to_memblock 1 | ||
538 | #endif | ||
539 | |||
526 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | 540 | void __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 | ||
549 | static void __init early_reserve_mem_dt(void) | 564 | static 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 | */ | ||
763 | void __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 |