diff options
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 83 |
1 files changed, 70 insertions, 13 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 012505ebd9f9..c38afdb45d7b 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <asm/thread_info.h> | 36 | #include <asm/thread_info.h> |
37 | #include <asm/firmware.h> | 37 | #include <asm/firmware.h> |
38 | #include <asm/page_64.h> | 38 | #include <asm/page_64.h> |
39 | #include <asm/exception.h> | ||
40 | #include <asm/irqflags.h> | 39 | #include <asm/irqflags.h> |
41 | 40 | ||
42 | /* The physical memory is layed out such that the secondary processor | 41 | /* The physical memory is layed out such that the secondary processor |
@@ -122,10 +121,11 @@ __run_at_load: | |||
122 | */ | 121 | */ |
123 | .globl __secondary_hold | 122 | .globl __secondary_hold |
124 | __secondary_hold: | 123 | __secondary_hold: |
124 | #ifndef CONFIG_PPC_BOOK3E | ||
125 | mfmsr r24 | 125 | mfmsr r24 |
126 | ori r24,r24,MSR_RI | 126 | ori r24,r24,MSR_RI |
127 | mtmsrd r24 /* RI on */ | 127 | mtmsrd r24 /* RI on */ |
128 | 128 | #endif | |
129 | /* Grab our physical cpu number */ | 129 | /* Grab our physical cpu number */ |
130 | mr r24,r3 | 130 | mr r24,r3 |
131 | 131 | ||
@@ -144,6 +144,7 @@ __secondary_hold: | |||
144 | ld r4,0(r4) /* deref function descriptor */ | 144 | ld r4,0(r4) /* deref function descriptor */ |
145 | mtctr r4 | 145 | mtctr r4 |
146 | mr r3,r24 | 146 | mr r3,r24 |
147 | li r4,0 | ||
147 | bctr | 148 | bctr |
148 | #else | 149 | #else |
149 | BUG_OPCODE | 150 | BUG_OPCODE |
@@ -164,21 +165,49 @@ exception_marker: | |||
164 | #include "exceptions-64s.S" | 165 | #include "exceptions-64s.S" |
165 | #endif | 166 | #endif |
166 | 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 | ||
167 | 183 | ||
168 | /* | 184 | /* |
169 | * On pSeries and most other platforms, secondary processors spin | 185 | * On pSeries and most other platforms, secondary processors spin |
170 | * in the following code. | 186 | * in the following code. |
171 | * 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). | ||
172 | */ | 192 | */ |
173 | _GLOBAL(generic_secondary_smp_init) | 193 | _GLOBAL(generic_secondary_smp_init) |
174 | mr r24,r3 | 194 | mr r24,r3 |
175 | 195 | mr r25,r4 | |
196 | |||
176 | /* turn on 64-bit mode */ | 197 | /* turn on 64-bit mode */ |
177 | bl .enable_64b_mode | 198 | bl .enable_64b_mode |
178 | 199 | ||
179 | /* get the TOC pointer (real address) */ | 200 | /* get a valid TOC pointer, wherever we're mapped at */ |
180 | bl .relative_toc | 201 | bl .relative_toc |
181 | 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: | ||
182 | /* 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 |
183 | * 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 |
184 | * which logical id maps to our physical one. | 213 | * which logical id maps to our physical one. |
@@ -196,7 +225,12 @@ _GLOBAL(generic_secondary_smp_init) | |||
196 | mr r3,r24 /* not found, copy phys to r3 */ | 225 | mr r3,r24 /* not found, copy phys to r3 */ |
197 | b .kexec_wait /* next kernel might do better */ | 226 | b .kexec_wait /* next kernel might do better */ |
198 | 227 | ||
199 | 2: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ | 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 | |||
200 | /* From now on, r24 is expected to be logical cpuid */ | 234 | /* From now on, r24 is expected to be logical cpuid */ |
201 | mr r24,r5 | 235 | mr r24,r5 |
202 | 3: HMT_LOW | 236 | 3: HMT_LOW |
@@ -232,6 +266,7 @@ _GLOBAL(generic_secondary_smp_init) | |||
232 | * Turn the MMU off. | 266 | * Turn the MMU off. |
233 | * Assumes we're mapped EA == RA if the MMU is on. | 267 | * Assumes we're mapped EA == RA if the MMU is on. |
234 | */ | 268 | */ |
269 | #ifdef CONFIG_PPC_BOOK3S | ||
235 | _STATIC(__mmu_off) | 270 | _STATIC(__mmu_off) |
236 | mfmsr r3 | 271 | mfmsr r3 |
237 | andi. r0,r3,MSR_IR|MSR_DR | 272 | andi. r0,r3,MSR_IR|MSR_DR |
@@ -243,6 +278,7 @@ _STATIC(__mmu_off) | |||
243 | sync | 278 | sync |
244 | rfid | 279 | rfid |
245 | b . /* prevent speculative execution */ | 280 | b . /* prevent speculative execution */ |
281 | #endif | ||
246 | 282 | ||
247 | 283 | ||
248 | /* | 284 | /* |
@@ -280,6 +316,10 @@ _GLOBAL(__start_initialization_multiplatform) | |||
280 | mr r31,r3 | 316 | mr r31,r3 |
281 | mr r30,r4 | 317 | mr r30,r4 |
282 | 318 | ||
319 | #ifdef CONFIG_PPC_BOOK3E | ||
320 | bl .start_initialization_book3e | ||
321 | b .__after_prom_start | ||
322 | #else | ||
283 | /* Setup some critical 970 SPRs before switching MMU off */ | 323 | /* Setup some critical 970 SPRs before switching MMU off */ |
284 | mfspr r0,SPRN_PVR | 324 | mfspr r0,SPRN_PVR |
285 | srwi r0,r0,16 | 325 | srwi r0,r0,16 |
@@ -297,6 +337,7 @@ _GLOBAL(__start_initialization_multiplatform) | |||
297 | /* Switch off MMU if not already off */ | 337 | /* Switch off MMU if not already off */ |
298 | bl .__mmu_off | 338 | bl .__mmu_off |
299 | b .__after_prom_start | 339 | b .__after_prom_start |
340 | #endif /* CONFIG_PPC_BOOK3E */ | ||
300 | 341 | ||
301 | _INIT_STATIC(__boot_from_prom) | 342 | _INIT_STATIC(__boot_from_prom) |
302 | #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE | 343 | #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE |
@@ -359,10 +400,16 @@ _STATIC(__after_prom_start) | |||
359 | * Note: This process overwrites the OF exception vectors. | 400 | * Note: This process overwrites the OF exception vectors. |
360 | */ | 401 | */ |
361 | 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 | ||
362 | mr. r4,r26 /* In some cases the loader may */ | 406 | mr. r4,r26 /* In some cases the loader may */ |
363 | beq 9f /* have already put us at zero */ | 407 | beq 9f /* have already put us at zero */ |
364 | li r6,0x100 /* Start offset, the first 0x100 */ | 408 | li r6,0x100 /* Start offset, the first 0x100 */ |
365 | /* 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 | ||
366 | 413 | ||
367 | #ifdef CONFIG_CRASH_DUMP | 414 | #ifdef CONFIG_CRASH_DUMP |
368 | /* | 415 | /* |
@@ -485,7 +532,7 @@ _GLOBAL(pmac_secondary_start) | |||
485 | LOAD_REG_ADDR(r4,paca) /* Get base vaddr of paca array */ | 532 | LOAD_REG_ADDR(r4,paca) /* Get base vaddr of paca array */ |
486 | mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ | 533 | mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ |
487 | add r13,r13,r4 /* for this processor. */ | 534 | add r13,r13,r4 /* for this processor. */ |
488 | mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ | 535 | mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/ |
489 | 536 | ||
490 | /* Create a temp kernel stack for use before relocation is on. */ | 537 | /* Create a temp kernel stack for use before relocation is on. */ |
491 | ld r1,PACAEMERGSP(r13) | 538 | ld r1,PACAEMERGSP(r13) |
@@ -503,11 +550,14 @@ _GLOBAL(pmac_secondary_start) | |||
503 | * 1. Processor number | 550 | * 1. Processor number |
504 | * 2. Segment table pointer (virtual address) | 551 | * 2. Segment table pointer (virtual address) |
505 | * On entry the following are set: | 552 | * On entry the following are set: |
506 | * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries | 553 | * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries |
507 | * r24 = cpu# (in Linux terms) | 554 | * r24 = cpu# (in Linux terms) |
508 | * r13 = paca virtual address | 555 | * r13 = paca virtual address |
509 | * SPRG3 = paca virtual address | 556 | * SPRG_PACA = paca virtual address |
510 | */ | 557 | */ |
558 | .section ".text"; | ||
559 | .align 2 ; | ||
560 | |||
511 | .globl __secondary_start | 561 | .globl __secondary_start |
512 | __secondary_start: | 562 | __secondary_start: |
513 | /* Set thread priority to MEDIUM */ | 563 | /* Set thread priority to MEDIUM */ |
@@ -544,7 +594,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | |||
544 | 594 | ||
545 | mtspr SPRN_SRR0,r3 | 595 | mtspr SPRN_SRR0,r3 |
546 | mtspr SPRN_SRR1,r4 | 596 | mtspr SPRN_SRR1,r4 |
547 | rfid | 597 | RFI |
548 | b . /* prevent speculative execution */ | 598 | b . /* prevent speculative execution */ |
549 | 599 | ||
550 | /* | 600 | /* |
@@ -565,11 +615,16 @@ _GLOBAL(start_secondary_prolog) | |||
565 | */ | 615 | */ |
566 | _GLOBAL(enable_64b_mode) | 616 | _GLOBAL(enable_64b_mode) |
567 | 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 */ | ||
568 | li r12,(MSR_SF | MSR_ISF)@highest | 622 | li r12,(MSR_SF | MSR_ISF)@highest |
569 | sldi r12,r12,48 | 623 | sldi r12,r12,48 |
570 | or r11,r11,r12 | 624 | or r11,r11,r12 |
571 | mtmsrd r11 | 625 | mtmsrd r11 |
572 | isync | 626 | isync |
627 | #endif | ||
573 | blr | 628 | blr |
574 | 629 | ||
575 | /* | 630 | /* |
@@ -613,9 +668,11 @@ _INIT_STATIC(start_here_multiplatform) | |||
613 | bdnz 3b | 668 | bdnz 3b |
614 | 4: | 669 | 4: |
615 | 670 | ||
671 | #ifndef CONFIG_PPC_BOOK3E | ||
616 | mfmsr r6 | 672 | mfmsr r6 |
617 | ori r6,r6,MSR_RI | 673 | ori r6,r6,MSR_RI |
618 | mtmsrd r6 /* RI on */ | 674 | mtmsrd r6 /* RI on */ |
675 | #endif | ||
619 | 676 | ||
620 | #ifdef CONFIG_RELOCATABLE | 677 | #ifdef CONFIG_RELOCATABLE |
621 | /* Save the physical address we're running at in kernstart_addr */ | 678 | /* Save the physical address we're running at in kernstart_addr */ |
@@ -642,13 +699,13 @@ _INIT_STATIC(start_here_multiplatform) | |||
642 | 699 | ||
643 | /* Restore parameters passed from prom_init/kexec */ | 700 | /* Restore parameters passed from prom_init/kexec */ |
644 | mr r3,r31 | 701 | mr r3,r31 |
645 | bl .early_setup /* also sets r13 and SPRG3 */ | 702 | bl .early_setup /* also sets r13 and SPRG_PACA */ |
646 | 703 | ||
647 | LOAD_REG_ADDR(r3, .start_here_common) | 704 | LOAD_REG_ADDR(r3, .start_here_common) |
648 | ld r4,PACAKMSR(r13) | 705 | ld r4,PACAKMSR(r13) |
649 | mtspr SPRN_SRR0,r3 | 706 | mtspr SPRN_SRR0,r3 |
650 | mtspr SPRN_SRR1,r4 | 707 | mtspr SPRN_SRR1,r4 |
651 | rfid | 708 | RFI |
652 | b . /* prevent speculative execution */ | 709 | b . /* prevent speculative execution */ |
653 | 710 | ||
654 | /* This is where all platforms converge execution */ | 711 | /* This is where all platforms converge execution */ |