aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/head_64.S
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-12-05 16:49:00 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:52:25 -0500
commit758438a7b8da593c9116e95cc7fdff6e9e0b0c40 (patch)
tree5343d8ec40016294902278c27a9f5647bd061890 /arch/powerpc/kernel/head_64.S
parent0cc4746cadda16826a1b3214c042a2f75445b71c (diff)
[PATCH] powerpc: Fixups for kernel linked at 32 MB
There's a few places where we need to fix things up for the kernel to work if it's linked at 32MB: - platforms/powermac/smp.c To start secondary cpus on pmac we patch the reset vector, which is fine. Except if we're above 32MB we don't have enough bits for an absolute branch, it needs to relative. - kernel/head_64.s - A few branches in the cpu hold code need to load the full target address and do a bctr. - after_prom_start needs to load PHYSICAL_START as the dest address, not 0. - The exception prolog needs to load the low word of the target adddress, not just the low halfword. - Fixup handling of the initial stab address. - kernel/setup_64.c smp_release_cpus() needs to write 1 to the spinloop flag near 0, not 32 MB. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r--arch/powerpc/kernel/head_64.S30
1 files changed, 24 insertions, 6 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 */