aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/head_64.S30
-rw-r--r--arch/powerpc/kernel/setup_64.c5
-rw-r--r--arch/powerpc/platforms/powermac/smp.c16
-rw-r--r--include/asm-powerpc/mmu.h3
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
1353initial_stab: 1371initial_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)
322void smp_release_cpus(void) 322void 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)
753static void __devinit smp_core99_kick_cpu(int nr) 753static 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__
39extern char initial_stab[]; 40extern char initial_stab[];