diff options
Diffstat (limited to 'arch/powerpc/kernel/prom_init.c')
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index bcdc209dca85..e381f2fc121c 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -192,6 +192,11 @@ static unsigned long __initdata alloc_bottom; | |||
192 | static unsigned long __initdata rmo_top; | 192 | static unsigned long __initdata rmo_top; |
193 | static unsigned long __initdata ram_top; | 193 | static unsigned long __initdata ram_top; |
194 | 194 | ||
195 | #ifdef CONFIG_KEXEC | ||
196 | static unsigned long __initdata prom_crashk_base; | ||
197 | static unsigned long __initdata prom_crashk_size; | ||
198 | #endif | ||
199 | |||
195 | static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; | 200 | static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; |
196 | static int __initdata mem_reserve_cnt; | 201 | static int __initdata mem_reserve_cnt; |
197 | 202 | ||
@@ -553,7 +558,8 @@ unsigned long prom_memparse(const char *ptr, const char **retptr) | |||
553 | static void __init early_cmdline_parse(void) | 558 | static void __init early_cmdline_parse(void) |
554 | { | 559 | { |
555 | struct prom_t *_prom = &RELOC(prom); | 560 | struct prom_t *_prom = &RELOC(prom); |
556 | char *opt, *p; | 561 | const char *opt; |
562 | char *p; | ||
557 | int l = 0; | 563 | int l = 0; |
558 | 564 | ||
559 | RELOC(prom_cmd_line[0]) = 0; | 565 | RELOC(prom_cmd_line[0]) = 0; |
@@ -590,6 +596,34 @@ static void __init early_cmdline_parse(void) | |||
590 | RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); | 596 | RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); |
591 | #endif | 597 | #endif |
592 | } | 598 | } |
599 | |||
600 | #ifdef CONFIG_KEXEC | ||
601 | /* | ||
602 | * crashkernel=size@addr specifies the location to reserve for | ||
603 | * crash kernel. | ||
604 | */ | ||
605 | opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel=")); | ||
606 | if (opt) { | ||
607 | opt += 12; | ||
608 | RELOC(prom_crashk_size) = prom_memparse(opt, &opt); | ||
609 | |||
610 | if (ALIGN(RELOC(prom_crashk_size), 0x1000000) != | ||
611 | RELOC(prom_crashk_size)) { | ||
612 | prom_printf("Warning: crashkernel size is not " | ||
613 | "aligned to 16MB\n"); | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * At present, the crash kernel always run at 32MB. | ||
618 | * Just ignore whatever user passed. | ||
619 | */ | ||
620 | RELOC(prom_crashk_base) = 0x2000000; | ||
621 | if (*opt == '@') { | ||
622 | prom_printf("Warning: PPC64 kdump kernel always runs " | ||
623 | "at 32 MB\n"); | ||
624 | } | ||
625 | } | ||
626 | #endif | ||
593 | } | 627 | } |
594 | 628 | ||
595 | #ifdef CONFIG_PPC_PSERIES | 629 | #ifdef CONFIG_PPC_PSERIES |
@@ -1011,6 +1045,12 @@ static void __init prom_init_mem(void) | |||
1011 | prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); | 1045 | prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); |
1012 | prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); | 1046 | prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); |
1013 | prom_printf(" ram_top : %x\n", RELOC(ram_top)); | 1047 | prom_printf(" ram_top : %x\n", RELOC(ram_top)); |
1048 | #ifdef CONFIG_KEXEC | ||
1049 | if (RELOC(prom_crashk_base)) { | ||
1050 | prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base)); | ||
1051 | prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size)); | ||
1052 | } | ||
1053 | #endif | ||
1014 | } | 1054 | } |
1015 | 1055 | ||
1016 | 1056 | ||
@@ -1500,6 +1540,8 @@ static int __init prom_find_machine_type(void) | |||
1500 | #ifdef CONFIG_PPC64 | 1540 | #ifdef CONFIG_PPC64 |
1501 | if (strstr(p, RELOC("Momentum,Maple"))) | 1541 | if (strstr(p, RELOC("Momentum,Maple"))) |
1502 | return PLATFORM_MAPLE; | 1542 | return PLATFORM_MAPLE; |
1543 | if (strstr(p, RELOC("IBM,CPB"))) | ||
1544 | return PLATFORM_CELL; | ||
1503 | #endif | 1545 | #endif |
1504 | i += sl + 1; | 1546 | i += sl + 1; |
1505 | } | 1547 | } |
@@ -1994,7 +2036,7 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4) | |||
1994 | if (r3 && r4 && r4 != 0xdeadbeef) { | 2036 | if (r3 && r4 && r4 != 0xdeadbeef) { |
1995 | unsigned long val; | 2037 | unsigned long val; |
1996 | 2038 | ||
1997 | RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; | 2039 | RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3; |
1998 | RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; | 2040 | RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; |
1999 | 2041 | ||
2000 | val = RELOC(prom_initrd_start); | 2042 | val = RELOC(prom_initrd_start); |
@@ -2094,6 +2136,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2094 | */ | 2136 | */ |
2095 | prom_init_mem(); | 2137 | prom_init_mem(); |
2096 | 2138 | ||
2139 | #ifdef CONFIG_KEXEC | ||
2140 | if (RELOC(prom_crashk_base)) | ||
2141 | reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size)); | ||
2142 | #endif | ||
2097 | /* | 2143 | /* |
2098 | * Determine which cpu is actually running right _now_ | 2144 | * Determine which cpu is actually running right _now_ |
2099 | */ | 2145 | */ |
@@ -2150,6 +2196,16 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2150 | } | 2196 | } |
2151 | #endif | 2197 | #endif |
2152 | 2198 | ||
2199 | #ifdef CONFIG_KEXEC | ||
2200 | if (RELOC(prom_crashk_base)) { | ||
2201 | prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base", | ||
2202 | PTRRELOC(&prom_crashk_base), | ||
2203 | sizeof(RELOC(prom_crashk_base))); | ||
2204 | prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size", | ||
2205 | PTRRELOC(&prom_crashk_size), | ||
2206 | sizeof(RELOC(prom_crashk_size))); | ||
2207 | } | ||
2208 | #endif | ||
2153 | /* | 2209 | /* |
2154 | * Fixup any known bugs in the device-tree | 2210 | * Fixup any known bugs in the device-tree |
2155 | */ | 2211 | */ |