diff options
-rw-r--r-- | arch/powerpc/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kexec.h | 13 | ||||
-rw-r--r-- | arch/powerpc/kernel/crash.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/fsl_booke_entry_mapping.S | 37 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_fsl_booke.S | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_32.S | 17 |
6 files changed, 74 insertions, 1 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c4c4549c22bb..5887cff16785 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -351,7 +351,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE | |||
351 | 351 | ||
352 | config KEXEC | 352 | config KEXEC |
353 | bool "kexec system call (EXPERIMENTAL)" | 353 | bool "kexec system call (EXPERIMENTAL)" |
354 | depends on PPC_BOOK3S && EXPERIMENTAL | 354 | depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL |
355 | help | 355 | help |
356 | kexec is a system call that implements the ability to shutdown your | 356 | kexec is a system call that implements the ability to shutdown your |
357 | current kernel, and to start another kernel. It is like a reboot | 357 | current kernel, and to start another kernel. It is like a reboot |
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index a6ca6da1430b..2a9cd74a841e 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h | |||
@@ -2,6 +2,18 @@ | |||
2 | #define _ASM_POWERPC_KEXEC_H | 2 | #define _ASM_POWERPC_KEXEC_H |
3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
4 | 4 | ||
5 | #ifdef CONFIG_FSL_BOOKE | ||
6 | |||
7 | /* | ||
8 | * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory | ||
9 | * and therefore we can only deal with memory within this range | ||
10 | */ | ||
11 | #define KEXEC_SOURCE_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) | ||
12 | #define KEXEC_DESTINATION_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) | ||
13 | #define KEXEC_CONTROL_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) | ||
14 | |||
15 | #else | ||
16 | |||
5 | /* | 17 | /* |
6 | * Maximum page that is mapped directly into kernel memory. | 18 | * Maximum page that is mapped directly into kernel memory. |
7 | * XXX: Since we copy virt we can use any page we allocate | 19 | * XXX: Since we copy virt we can use any page we allocate |
@@ -21,6 +33,7 @@ | |||
21 | /* TASK_SIZE, probably left over from use_mm ?? */ | 33 | /* TASK_SIZE, probably left over from use_mm ?? */ |
22 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE | 34 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE |
23 | #endif | 35 | #endif |
36 | #endif | ||
24 | 37 | ||
25 | #define KEXEC_CONTROL_PAGE_SIZE 4096 | 38 | #define KEXEC_CONTROL_PAGE_SIZE 4096 |
26 | 39 | ||
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 8c066d6a8e4b..b46f2e09bd81 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -163,6 +163,7 @@ static void crash_kexec_prepare_cpus(int cpu) | |||
163 | } | 163 | } |
164 | 164 | ||
165 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ | 165 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ |
166 | #ifdef CONFIG_PPC_STD_MMU_64 | ||
166 | static void crash_kexec_wait_realmode(int cpu) | 167 | static void crash_kexec_wait_realmode(int cpu) |
167 | { | 168 | { |
168 | unsigned int msecs; | 169 | unsigned int msecs; |
@@ -187,6 +188,7 @@ static void crash_kexec_wait_realmode(int cpu) | |||
187 | } | 188 | } |
188 | mb(); | 189 | mb(); |
189 | } | 190 | } |
191 | #endif | ||
190 | 192 | ||
191 | /* | 193 | /* |
192 | * This function will be called by secondary cpus or by kexec cpu | 194 | * This function will be called by secondary cpus or by kexec cpu |
@@ -445,7 +447,9 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
445 | crash_kexec_prepare_cpus(crashing_cpu); | 447 | crash_kexec_prepare_cpus(crashing_cpu); |
446 | cpu_set(crashing_cpu, cpus_in_crash); | 448 | cpu_set(crashing_cpu, cpus_in_crash); |
447 | crash_kexec_stop_spus(); | 449 | crash_kexec_stop_spus(); |
450 | #ifdef CONFIG_PPC_STD_MMU_64 | ||
448 | crash_kexec_wait_realmode(crashing_cpu); | 451 | crash_kexec_wait_realmode(crashing_cpu); |
452 | #endif | ||
449 | if (ppc_md.kexec_cpu_down) | 453 | if (ppc_md.kexec_cpu_down) |
450 | ppc_md.kexec_cpu_down(1, 0); | 454 | ppc_md.kexec_cpu_down(1, 0); |
451 | } | 455 | } |
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S index cdb1296f972d..beb4d78a2304 100644 --- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S +++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S | |||
@@ -159,6 +159,8 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
159 | #define M_IF_SMP 0 | 159 | #define M_IF_SMP 0 |
160 | #endif | 160 | #endif |
161 | 161 | ||
162 | #if defined(ENTRY_MAPPING_BOOT_SETUP) | ||
163 | |||
162 | /* 6. Setup KERNELBASE mapping in TLB1[0] */ | 164 | /* 6. Setup KERNELBASE mapping in TLB1[0] */ |
163 | lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ | 165 | lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ |
164 | mtspr SPRN_MAS0,r6 | 166 | mtspr SPRN_MAS0,r6 |
@@ -174,6 +176,41 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
174 | /* 7. Jump to KERNELBASE mapping */ | 176 | /* 7. Jump to KERNELBASE mapping */ |
175 | lis r6,(KERNELBASE & ~0xfff)@h | 177 | lis r6,(KERNELBASE & ~0xfff)@h |
176 | ori r6,r6,(KERNELBASE & ~0xfff)@l | 178 | ori r6,r6,(KERNELBASE & ~0xfff)@l |
179 | |||
180 | #elif defined(ENTRY_MAPPING_KEXEC_SETUP) | ||
181 | /* | ||
182 | * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp | ||
183 | * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This | ||
184 | * will cover the first 2GiB of memory. | ||
185 | */ | ||
186 | |||
187 | lis r10, (MAS1_VALID|MAS1_IPROT)@h | ||
188 | ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l | ||
189 | li r11, 0 | ||
190 | li r0, 8 | ||
191 | mtctr r0 | ||
192 | |||
193 | next_tlb_setup: | ||
194 | addi r0, r11, 3 | ||
195 | rlwinm r0, r0, 16, 4, 15 // Compute esel | ||
196 | rlwinm r9, r11, 28, 0, 3 // Compute [ER]PN | ||
197 | oris r0, r0, (MAS0_TLBSEL(1))@h | ||
198 | mtspr SPRN_MAS0,r0 | ||
199 | mtspr SPRN_MAS1,r10 | ||
200 | mtspr SPRN_MAS2,r9 | ||
201 | ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR) | ||
202 | mtspr SPRN_MAS3,r9 | ||
203 | tlbwe | ||
204 | addi r11, r11, 1 | ||
205 | bdnz+ next_tlb_setup | ||
206 | |||
207 | /* 7. Jump to our 1:1 mapping */ | ||
208 | li r6, 0 | ||
209 | |||
210 | #else | ||
211 | #error You need to specify the mapping or not use this at all. | ||
212 | #endif | ||
213 | |||
177 | lis r7,MSR_KERNEL@h | 214 | lis r7,MSR_KERNEL@h |
178 | ori r7,r7,MSR_KERNEL@l | 215 | ori r7,r7,MSR_KERNEL@l |
179 | bl 1f /* Find our address */ | 216 | bl 1f /* Find our address */ |
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 6b5b1f3b6112..4faeba247854 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -95,7 +95,9 @@ _ENTRY(_start); | |||
95 | 95 | ||
96 | _ENTRY(__early_start) | 96 | _ENTRY(__early_start) |
97 | 97 | ||
98 | #define ENTRY_MAPPING_BOOT_SETUP | ||
98 | #include "fsl_booke_entry_mapping.S" | 99 | #include "fsl_booke_entry_mapping.S" |
100 | #undef ENTRY_MAPPING_BOOT_SETUP | ||
99 | 101 | ||
100 | /* Establish the interrupt vector offsets */ | 102 | /* Establish the interrupt vector offsets */ |
101 | SET_IVOR(0, CriticalInput); | 103 | SET_IVOR(0, CriticalInput); |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 8043d1b73cf0..dc66d52dcff5 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -711,6 +711,22 @@ relocate_new_kernel: | |||
711 | /* r4 = reboot_code_buffer */ | 711 | /* r4 = reboot_code_buffer */ |
712 | /* r5 = start_address */ | 712 | /* r5 = start_address */ |
713 | 713 | ||
714 | #ifdef CONFIG_FSL_BOOKE | ||
715 | |||
716 | mr r29, r3 | ||
717 | mr r30, r4 | ||
718 | mr r31, r5 | ||
719 | |||
720 | #define ENTRY_MAPPING_KEXEC_SETUP | ||
721 | #include "fsl_booke_entry_mapping.S" | ||
722 | #undef ENTRY_MAPPING_KEXEC_SETUP | ||
723 | |||
724 | mr r3, r29 | ||
725 | mr r4, r30 | ||
726 | mr r5, r31 | ||
727 | |||
728 | li r0, 0 | ||
729 | #else | ||
714 | li r0, 0 | 730 | li r0, 0 |
715 | 731 | ||
716 | /* | 732 | /* |
@@ -727,6 +743,7 @@ relocate_new_kernel: | |||
727 | rfi | 743 | rfi |
728 | 744 | ||
729 | 1: | 745 | 1: |
746 | #endif | ||
730 | /* from this point address translation is turned off */ | 747 | /* from this point address translation is turned off */ |
731 | /* and interrupts are disabled */ | 748 | /* and interrupts are disabled */ |
732 | 749 | ||