diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-07-23 19:15:59 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-08-19 20:25:11 -0400 |
commit | 2d27cfd3286966c04d4192a9db5a6c7ea60eebf1 (patch) | |
tree | a9e3feb764da5a2be1a6ef9b3a0bf694e874a424 /arch/powerpc/kernel/head_64.S | |
parent | 32a74949b7337726e76d69f51c48715431126c6c (diff) |
powerpc: Remaining 64-bit Book3E support
This contains all the bits that didn't fit in previous patches :-) This
includes the actual exception handlers assembly, the changes to the
kernel entry, other misc bits and wiring it all up in Kconfig.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 0552f01041ab..c38afdb45d7b 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -121,10 +121,11 @@ __run_at_load: | |||
121 | */ | 121 | */ |
122 | .globl __secondary_hold | 122 | .globl __secondary_hold |
123 | __secondary_hold: | 123 | __secondary_hold: |
124 | #ifndef CONFIG_PPC_BOOK3E | ||
124 | mfmsr r24 | 125 | mfmsr r24 |
125 | ori r24,r24,MSR_RI | 126 | ori r24,r24,MSR_RI |
126 | mtmsrd r24 /* RI on */ | 127 | mtmsrd r24 /* RI on */ |
127 | 128 | #endif | |
128 | /* Grab our physical cpu number */ | 129 | /* Grab our physical cpu number */ |
129 | mr r24,r3 | 130 | mr r24,r3 |
130 | 131 | ||
@@ -143,6 +144,7 @@ __secondary_hold: | |||
143 | ld r4,0(r4) /* deref function descriptor */ | 144 | ld r4,0(r4) /* deref function descriptor */ |
144 | mtctr r4 | 145 | mtctr r4 |
145 | mr r3,r24 | 146 | mr r3,r24 |
147 | li r4,0 | ||
146 | bctr | 148 | bctr |
147 | #else | 149 | #else |
148 | BUG_OPCODE | 150 | BUG_OPCODE |
@@ -163,21 +165,49 @@ exception_marker: | |||
163 | #include "exceptions-64s.S" | 165 | #include "exceptions-64s.S" |
164 | #endif | 166 | #endif |
165 | 167 | ||
168 | _GLOBAL(generic_secondary_thread_init) | ||
169 | mr r24,r3 | ||
170 | |||
171 | /* turn on 64-bit mode */ | ||
172 | bl .enable_64b_mode | ||
173 | |||
174 | /* get a valid TOC pointer, wherever we're mapped at */ | ||
175 | bl .relative_toc | ||
176 | |||
177 | #ifdef CONFIG_PPC_BOOK3E | ||
178 | /* Book3E initialization */ | ||
179 | mr r3,r24 | ||
180 | bl .book3e_secondary_thread_init | ||
181 | #endif | ||
182 | b generic_secondary_common_init | ||
166 | 183 | ||
167 | /* | 184 | /* |
168 | * On pSeries and most other platforms, secondary processors spin | 185 | * On pSeries and most other platforms, secondary processors spin |
169 | * in the following code. | 186 | * in the following code. |
170 | * At entry, r3 = this processor's number (physical cpu id) | 187 | * At entry, r3 = this processor's number (physical cpu id) |
188 | * | ||
189 | * On Book3E, r4 = 1 to indicate that the initial TLB entry for | ||
190 | * this core already exists (setup via some other mechanism such | ||
191 | * as SCOM before entry). | ||
171 | */ | 192 | */ |
172 | _GLOBAL(generic_secondary_smp_init) | 193 | _GLOBAL(generic_secondary_smp_init) |
173 | mr r24,r3 | 194 | mr r24,r3 |
174 | 195 | mr r25,r4 | |
196 | |||
175 | /* turn on 64-bit mode */ | 197 | /* turn on 64-bit mode */ |
176 | bl .enable_64b_mode | 198 | bl .enable_64b_mode |
177 | 199 | ||
178 | /* get the TOC pointer (real address) */ | 200 | /* get a valid TOC pointer, wherever we're mapped at */ |
179 | bl .relative_toc | 201 | bl .relative_toc |
180 | 202 | ||
203 | #ifdef CONFIG_PPC_BOOK3E | ||
204 | /* Book3E initialization */ | ||
205 | mr r3,r24 | ||
206 | mr r4,r25 | ||
207 | bl .book3e_secondary_core_init | ||
208 | #endif | ||
209 | |||
210 | generic_secondary_common_init: | ||
181 | /* Set up a paca value for this processor. Since we have the | 211 | /* Set up a paca value for this processor. Since we have the |
182 | * physical cpu id in r24, we need to search the pacas to find | 212 | * physical cpu id in r24, we need to search the pacas to find |
183 | * which logical id maps to our physical one. | 213 | * which logical id maps to our physical one. |
@@ -196,6 +226,11 @@ _GLOBAL(generic_secondary_smp_init) | |||
196 | b .kexec_wait /* next kernel might do better */ | 226 | b .kexec_wait /* next kernel might do better */ |
197 | 227 | ||
198 | 2: mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG */ | 228 | 2: mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG */ |
229 | #ifdef CONFIG_PPC_BOOK3E | ||
230 | addi r12,r13,PACA_EXTLB /* and TLB exc frame in another */ | ||
231 | mtspr SPRN_SPRG_TLB_EXFRAME,r12 | ||
232 | #endif | ||
233 | |||
199 | /* From now on, r24 is expected to be logical cpuid */ | 234 | /* From now on, r24 is expected to be logical cpuid */ |
200 | mr r24,r5 | 235 | mr r24,r5 |
201 | 3: HMT_LOW | 236 | 3: HMT_LOW |
@@ -231,6 +266,7 @@ _GLOBAL(generic_secondary_smp_init) | |||
231 | * Turn the MMU off. | 266 | * Turn the MMU off. |
232 | * Assumes we're mapped EA == RA if the MMU is on. | 267 | * Assumes we're mapped EA == RA if the MMU is on. |
233 | */ | 268 | */ |
269 | #ifdef CONFIG_PPC_BOOK3S | ||
234 | _STATIC(__mmu_off) | 270 | _STATIC(__mmu_off) |
235 | mfmsr r3 | 271 | mfmsr r3 |
236 | andi. r0,r3,MSR_IR|MSR_DR | 272 | andi. r0,r3,MSR_IR|MSR_DR |
@@ -242,6 +278,7 @@ _STATIC(__mmu_off) | |||
242 | sync | 278 | sync |
243 | rfid | 279 | rfid |
244 | b . /* prevent speculative execution */ | 280 | b . /* prevent speculative execution */ |
281 | #endif | ||
245 | 282 | ||
246 | 283 | ||
247 | /* | 284 | /* |
@@ -279,6 +316,10 @@ _GLOBAL(__start_initialization_multiplatform) | |||
279 | mr r31,r3 | 316 | mr r31,r3 |
280 | mr r30,r4 | 317 | mr r30,r4 |
281 | 318 | ||
319 | #ifdef CONFIG_PPC_BOOK3E | ||
320 | bl .start_initialization_book3e | ||
321 | b .__after_prom_start | ||
322 | #else | ||
282 | /* Setup some critical 970 SPRs before switching MMU off */ | 323 | /* Setup some critical 970 SPRs before switching MMU off */ |
283 | mfspr r0,SPRN_PVR | 324 | mfspr r0,SPRN_PVR |
284 | srwi r0,r0,16 | 325 | srwi r0,r0,16 |
@@ -296,6 +337,7 @@ _GLOBAL(__start_initialization_multiplatform) | |||
296 | /* Switch off MMU if not already off */ | 337 | /* Switch off MMU if not already off */ |
297 | bl .__mmu_off | 338 | bl .__mmu_off |
298 | b .__after_prom_start | 339 | b .__after_prom_start |
340 | #endif /* CONFIG_PPC_BOOK3E */ | ||
299 | 341 | ||
300 | _INIT_STATIC(__boot_from_prom) | 342 | _INIT_STATIC(__boot_from_prom) |
301 | #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE | 343 | #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE |
@@ -358,10 +400,16 @@ _STATIC(__after_prom_start) | |||
358 | * Note: This process overwrites the OF exception vectors. | 400 | * Note: This process overwrites the OF exception vectors. |
359 | */ | 401 | */ |
360 | li r3,0 /* target addr */ | 402 | li r3,0 /* target addr */ |
403 | #ifdef CONFIG_PPC_BOOK3E | ||
404 | tovirt(r3,r3) /* on booke, we already run at PAGE_OFFSET */ | ||
405 | #endif | ||
361 | mr. r4,r26 /* In some cases the loader may */ | 406 | mr. r4,r26 /* In some cases the loader may */ |
362 | beq 9f /* have already put us at zero */ | 407 | beq 9f /* have already put us at zero */ |
363 | li r6,0x100 /* Start offset, the first 0x100 */ | 408 | li r6,0x100 /* Start offset, the first 0x100 */ |
364 | /* bytes were copied earlier. */ | 409 | /* bytes were copied earlier. */ |
410 | #ifdef CONFIG_PPC_BOOK3E | ||
411 | tovirt(r6,r6) /* on booke, we already run at PAGE_OFFSET */ | ||
412 | #endif | ||
365 | 413 | ||
366 | #ifdef CONFIG_CRASH_DUMP | 414 | #ifdef CONFIG_CRASH_DUMP |
367 | /* | 415 | /* |
@@ -507,6 +555,9 @@ _GLOBAL(pmac_secondary_start) | |||
507 | * r13 = paca virtual address | 555 | * r13 = paca virtual address |
508 | * SPRG_PACA = paca virtual address | 556 | * SPRG_PACA = paca virtual address |
509 | */ | 557 | */ |
558 | .section ".text"; | ||
559 | .align 2 ; | ||
560 | |||
510 | .globl __secondary_start | 561 | .globl __secondary_start |
511 | __secondary_start: | 562 | __secondary_start: |
512 | /* Set thread priority to MEDIUM */ | 563 | /* Set thread priority to MEDIUM */ |
@@ -543,7 +594,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | |||
543 | 594 | ||
544 | mtspr SPRN_SRR0,r3 | 595 | mtspr SPRN_SRR0,r3 |
545 | mtspr SPRN_SRR1,r4 | 596 | mtspr SPRN_SRR1,r4 |
546 | rfid | 597 | RFI |
547 | b . /* prevent speculative execution */ | 598 | b . /* prevent speculative execution */ |
548 | 599 | ||
549 | /* | 600 | /* |
@@ -564,11 +615,16 @@ _GLOBAL(start_secondary_prolog) | |||
564 | */ | 615 | */ |
565 | _GLOBAL(enable_64b_mode) | 616 | _GLOBAL(enable_64b_mode) |
566 | mfmsr r11 /* grab the current MSR */ | 617 | mfmsr r11 /* grab the current MSR */ |
618 | #ifdef CONFIG_PPC_BOOK3E | ||
619 | oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */ | ||
620 | mtmsr r11 | ||
621 | #else /* CONFIG_PPC_BOOK3E */ | ||
567 | li r12,(MSR_SF | MSR_ISF)@highest | 622 | li r12,(MSR_SF | MSR_ISF)@highest |
568 | sldi r12,r12,48 | 623 | sldi r12,r12,48 |
569 | or r11,r11,r12 | 624 | or r11,r11,r12 |
570 | mtmsrd r11 | 625 | mtmsrd r11 |
571 | isync | 626 | isync |
627 | #endif | ||
572 | blr | 628 | blr |
573 | 629 | ||
574 | /* | 630 | /* |
@@ -612,9 +668,11 @@ _INIT_STATIC(start_here_multiplatform) | |||
612 | bdnz 3b | 668 | bdnz 3b |
613 | 4: | 669 | 4: |
614 | 670 | ||
671 | #ifndef CONFIG_PPC_BOOK3E | ||
615 | mfmsr r6 | 672 | mfmsr r6 |
616 | ori r6,r6,MSR_RI | 673 | ori r6,r6,MSR_RI |
617 | mtmsrd r6 /* RI on */ | 674 | mtmsrd r6 /* RI on */ |
675 | #endif | ||
618 | 676 | ||
619 | #ifdef CONFIG_RELOCATABLE | 677 | #ifdef CONFIG_RELOCATABLE |
620 | /* Save the physical address we're running at in kernstart_addr */ | 678 | /* Save the physical address we're running at in kernstart_addr */ |
@@ -647,7 +705,7 @@ _INIT_STATIC(start_here_multiplatform) | |||
647 | ld r4,PACAKMSR(r13) | 705 | ld r4,PACAKMSR(r13) |
648 | mtspr SPRN_SRR0,r3 | 706 | mtspr SPRN_SRR0,r3 |
649 | mtspr SPRN_SRR1,r4 | 707 | mtspr SPRN_SRR1,r4 |
650 | rfid | 708 | RFI |
651 | b . /* prevent speculative execution */ | 709 | b . /* prevent speculative execution */ |
652 | 710 | ||
653 | /* This is where all platforms converge execution */ | 711 | /* This is where all platforms converge execution */ |