diff options
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 30 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/smp.c | 16 | ||||
-rw-r--r-- | include/asm-powerpc/mmu.h | 3 |
4 files changed, 37 insertions, 17 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index f4194f5fd2e5..0763dd632b78 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -154,11 +154,15 @@ _GLOBAL(__secondary_hold) | |||
154 | bne 100b | 154 | bne 100b |
155 | 155 | ||
156 | #ifdef CONFIG_HMT | 156 | #ifdef CONFIG_HMT |
157 | b .hmt_init | 157 | LOADADDR(r4, .hmt_init) |
158 | mtctr r4 | ||
159 | bctr | ||
158 | #else | 160 | #else |
159 | #ifdef CONFIG_SMP | 161 | #ifdef CONFIG_SMP |
162 | LOADADDR(r4, .pSeries_secondary_smp_init) | ||
163 | mtctr r4 | ||
160 | mr r3,r24 | 164 | mr r3,r24 |
161 | b .pSeries_secondary_smp_init | 165 | bctr |
162 | #else | 166 | #else |
163 | BUG_OPCODE | 167 | BUG_OPCODE |
164 | #endif | 168 | #endif |
@@ -200,6 +204,20 @@ exception_marker: | |||
200 | #define EX_R3 64 | 204 | #define EX_R3 64 |
201 | #define EX_LR 72 | 205 | #define EX_LR 72 |
202 | 206 | ||
207 | /* | ||
208 | * We're short on space and time in the exception prolog, so we can't use | ||
209 | * the normal LOADADDR macro. Normally we just need the low halfword of the | ||
210 | * address, but for Kdump we need the whole low word. | ||
211 | */ | ||
212 | #ifdef CONFIG_CRASH_DUMP | ||
213 | #define LOAD_HANDLER(reg, label) \ | ||
214 | oris reg,reg,(label)@h; /* virt addr of handler ... */ \ | ||
215 | ori reg,reg,(label)@l; /* .. and the rest */ | ||
216 | #else | ||
217 | #define LOAD_HANDLER(reg, label) \ | ||
218 | ori reg,reg,(label)@l; /* virt addr of handler ... */ | ||
219 | #endif | ||
220 | |||
203 | #define EXCEPTION_PROLOG_PSERIES(area, label) \ | 221 | #define EXCEPTION_PROLOG_PSERIES(area, label) \ |
204 | mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ | 222 | mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ |
205 | std r9,area+EX_R9(r13); /* save r9 - r12 */ \ | 223 | std r9,area+EX_R9(r13); /* save r9 - r12 */ \ |
@@ -212,7 +230,7 @@ exception_marker: | |||
212 | clrrdi r12,r13,32; /* get high part of &label */ \ | 230 | clrrdi r12,r13,32; /* get high part of &label */ \ |
213 | mfmsr r10; \ | 231 | mfmsr r10; \ |
214 | mfspr r11,SPRN_SRR0; /* save SRR0 */ \ | 232 | mfspr r11,SPRN_SRR0; /* save SRR0 */ \ |
215 | ori r12,r12,(label)@l; /* virt addr of handler */ \ | 233 | LOAD_HANDLER(r12,label) \ |
216 | ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ | 234 | ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ |
217 | mtspr SPRN_SRR0,r12; \ | 235 | mtspr SPRN_SRR0,r12; \ |
218 | mfspr r12,SPRN_SRR1; /* and SRR1 */ \ | 236 | mfspr r12,SPRN_SRR1; /* and SRR1 */ \ |
@@ -1348,7 +1366,7 @@ _GLOBAL(do_stab_bolted) | |||
1348 | * fixed address (the linker can't compute (u64)&initial_stab >> | 1366 | * fixed address (the linker can't compute (u64)&initial_stab >> |
1349 | * PAGE_SHIFT). | 1367 | * PAGE_SHIFT). |
1350 | */ | 1368 | */ |
1351 | . = STAB0_PHYS_ADDR /* 0x6000 */ | 1369 | . = STAB0_OFFSET /* 0x6000 */ |
1352 | .globl initial_stab | 1370 | .globl initial_stab |
1353 | initial_stab: | 1371 | initial_stab: |
1354 | .space 4096 | 1372 | .space 4096 |
@@ -1553,7 +1571,7 @@ _STATIC(__boot_from_prom) | |||
1553 | _STATIC(__after_prom_start) | 1571 | _STATIC(__after_prom_start) |
1554 | 1572 | ||
1555 | /* | 1573 | /* |
1556 | * We need to run with __start at physical address 0. | 1574 | * We need to run with __start at physical address PHYSICAL_START. |
1557 | * This will leave some code in the first 256B of | 1575 | * This will leave some code in the first 256B of |
1558 | * real memory, which are reserved for software use. | 1576 | * real memory, which are reserved for software use. |
1559 | * The remainder of the first page is loaded with the fixed | 1577 | * The remainder of the first page is loaded with the fixed |
@@ -1568,7 +1586,7 @@ _STATIC(__after_prom_start) | |||
1568 | mr r26,r3 | 1586 | mr r26,r3 |
1569 | SET_REG_TO_CONST(r27,KERNELBASE) | 1587 | SET_REG_TO_CONST(r27,KERNELBASE) |
1570 | 1588 | ||
1571 | li r3,0 /* target addr */ | 1589 | LOADADDR(r3, PHYSICAL_START) /* target addr */ |
1572 | 1590 | ||
1573 | // XXX FIXME: Use phys returned by OF (r30) | 1591 | // XXX FIXME: Use phys returned by OF (r30) |
1574 | add r4,r27,r26 /* source addr */ | 1592 | add r4,r27,r26 /* source addr */ |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index e67120e34652..419e0b974b96 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -322,6 +322,7 @@ void early_setup_secondary(void) | |||
322 | void smp_release_cpus(void) | 322 | void smp_release_cpus(void) |
323 | { | 323 | { |
324 | extern unsigned long __secondary_hold_spinloop; | 324 | extern unsigned long __secondary_hold_spinloop; |
325 | unsigned long *ptr; | ||
325 | 326 | ||
326 | DBG(" -> smp_release_cpus()\n"); | 327 | DBG(" -> smp_release_cpus()\n"); |
327 | 328 | ||
@@ -332,7 +333,9 @@ void smp_release_cpus(void) | |||
332 | * This is useless but harmless on iSeries, secondaries are already | 333 | * This is useless but harmless on iSeries, secondaries are already |
333 | * waiting on their paca spinloops. */ | 334 | * waiting on their paca spinloops. */ |
334 | 335 | ||
335 | __secondary_hold_spinloop = 1; | 336 | ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop |
337 | - PHYSICAL_START); | ||
338 | *ptr = 1; | ||
336 | mb(); | 339 | mb(); |
337 | 340 | ||
338 | DBG(" <- smp_release_cpus()\n"); | 341 | DBG(" <- smp_release_cpus()\n"); |
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index fb2a7c798e82..862f1e985c19 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c | |||
@@ -753,14 +753,15 @@ static int __init smp_core99_probe(void) | |||
753 | static void __devinit smp_core99_kick_cpu(int nr) | 753 | static void __devinit smp_core99_kick_cpu(int nr) |
754 | { | 754 | { |
755 | unsigned int save_vector; | 755 | unsigned int save_vector; |
756 | unsigned long new_vector; | 756 | unsigned long target, flags; |
757 | unsigned long flags; | ||
758 | volatile unsigned int *vector | 757 | volatile unsigned int *vector |
759 | = ((volatile unsigned int *)(KERNELBASE+0x100)); | 758 | = ((volatile unsigned int *)(KERNELBASE+0x100)); |
760 | 759 | ||
761 | if (nr < 0 || nr > 3) | 760 | if (nr < 0 || nr > 3) |
762 | return; | 761 | return; |
763 | if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); | 762 | |
763 | if (ppc_md.progress) | ||
764 | ppc_md.progress("smp_core99_kick_cpu", 0x346); | ||
764 | 765 | ||
765 | local_irq_save(flags); | 766 | local_irq_save(flags); |
766 | local_irq_disable(); | 767 | local_irq_disable(); |
@@ -768,14 +769,11 @@ static void __devinit smp_core99_kick_cpu(int nr) | |||
768 | /* Save reset vector */ | 769 | /* Save reset vector */ |
769 | save_vector = *vector; | 770 | save_vector = *vector; |
770 | 771 | ||
771 | /* Setup fake reset vector that does | 772 | /* Setup fake reset vector that does |
772 | * b __secondary_start_pmac_0 + nr*8 - KERNELBASE | 773 | * b __secondary_start_pmac_0 + nr*8 - KERNELBASE |
773 | */ | 774 | */ |
774 | new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8; | 775 | target = (unsigned long) __secondary_start_pmac_0 + nr * 8; |
775 | *vector = 0x48000002 + new_vector - KERNELBASE; | 776 | create_branch((unsigned long)vector, target, BRANCH_SET_LINK); |
776 | |||
777 | /* flush data cache and inval instruction cache */ | ||
778 | flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); | ||
779 | 777 | ||
780 | /* Put some life in our friend */ | 778 | /* Put some life in our friend */ |
781 | pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); | 779 | pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); |
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h index 29613500c2c2..0a7323f0083b 100644 --- a/include/asm-powerpc/mmu.h +++ b/include/asm-powerpc/mmu.h | |||
@@ -33,7 +33,8 @@ | |||
33 | 33 | ||
34 | /* Location of cpu0's segment table */ | 34 | /* Location of cpu0's segment table */ |
35 | #define STAB0_PAGE 0x6 | 35 | #define STAB0_PAGE 0x6 |
36 | #define STAB0_PHYS_ADDR (STAB0_PAGE<<12) | 36 | #define STAB0_OFFSET (STAB0_PAGE << 12) |
37 | #define STAB0_PHYS_ADDR (STAB0_OFFSET + PHYSICAL_START) | ||
37 | 38 | ||
38 | #ifndef __ASSEMBLY__ | 39 | #ifndef __ASSEMBLY__ |
39 | extern char initial_stab[]; | 40 | extern char initial_stab[]; |