aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/head_64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r--arch/powerpc/kernel/head_64.S71
1 files changed, 55 insertions, 16 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 27935d1ab6a..97bb6e6f67b 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -82,7 +82,11 @@ END_FTR_SECTION(0, 1)
82 /* Catch branch to 0 in real mode */ 82 /* Catch branch to 0 in real mode */
83 trap 83 trap
84 84
85 /* Secondary processors spin on this value until it goes to 1. */ 85 /* Secondary processors spin on this value until it becomes nonzero.
86 * When it does it contains the real address of the descriptor
87 * of the function that the cpu should jump to to continue
88 * initialization.
89 */
86 .globl __secondary_hold_spinloop 90 .globl __secondary_hold_spinloop
87__secondary_hold_spinloop: 91__secondary_hold_spinloop:
88 .llong 0x0 92 .llong 0x0
@@ -109,8 +113,11 @@ __secondary_hold_acknowledge:
109 * before the bulk of the kernel has been relocated. This code 113 * before the bulk of the kernel has been relocated. This code
110 * is relocated to physical address 0x60 before prom_init is run. 114 * is relocated to physical address 0x60 before prom_init is run.
111 * All of it must fit below the first exception vector at 0x100. 115 * All of it must fit below the first exception vector at 0x100.
116 * Use .globl here not _GLOBAL because we want __secondary_hold
117 * to be the actual text address, not a descriptor.
112 */ 118 */
113_GLOBAL(__secondary_hold) 119 .globl __secondary_hold
120__secondary_hold:
114 mfmsr r24 121 mfmsr r24
115 ori r24,r24,MSR_RI 122 ori r24,r24,MSR_RI
116 mtmsrd r24 /* RI on */ 123 mtmsrd r24 /* RI on */
@@ -126,11 +133,11 @@ _GLOBAL(__secondary_hold)
126 133
127 /* All secondary cpus wait here until told to start. */ 134 /* All secondary cpus wait here until told to start. */
128100: ld r4,__secondary_hold_spinloop@l(0) 135100: ld r4,__secondary_hold_spinloop@l(0)
129 cmpdi 0,r4,1 136 cmpdi 0,r4,0
130 bne 100b 137 beq 100b
131 138
132#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) 139#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
133 LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init) 140 ld r4,0(r4) /* deref function descriptor */
134 mtctr r4 141 mtctr r4
135 mr r3,r24 142 mr r3,r24
136 bctr 143 bctr
@@ -147,6 +154,10 @@ exception_marker:
147/* 154/*
148 * This is the start of the interrupt handlers for pSeries 155 * This is the start of the interrupt handlers for pSeries
149 * This code runs with relocation off. 156 * This code runs with relocation off.
157 * Code from here to __end_interrupts gets copied down to real
158 * address 0x100 when we are running a relocatable kernel.
159 * Therefore any relative branches in this section must only
160 * branch to labels in this section.
150 */ 161 */
151 . = 0x100 162 . = 0x100
152 .globl __start_interrupts 163 .globl __start_interrupts
@@ -200,7 +211,20 @@ data_access_slb_pSeries:
200 mfspr r10,SPRN_SPRG1 211 mfspr r10,SPRN_SPRG1
201 std r10,PACA_EXSLB+EX_R13(r13) 212 std r10,PACA_EXSLB+EX_R13(r13)
202 mfspr r12,SPRN_SRR1 /* and SRR1 */ 213 mfspr r12,SPRN_SRR1 /* and SRR1 */
203 b .slb_miss_realmode /* Rel. branch works in real mode */ 214#ifndef CONFIG_RELOCATABLE
215 b .slb_miss_realmode
216#else
217 /*
218 * We can't just use a direct branch to .slb_miss_realmode
219 * because the distance from here to there depends on where
220 * the kernel ends up being put.
221 */
222 mfctr r11
223 ld r10,PACAKBASE(r13)
224 LOAD_HANDLER(r10, .slb_miss_realmode)
225 mtctr r10
226 bctr
227#endif
204 228
205 STD_EXCEPTION_PSERIES(0x400, instruction_access) 229 STD_EXCEPTION_PSERIES(0x400, instruction_access)
206 230
@@ -225,7 +249,15 @@ instruction_access_slb_pSeries:
225 mfspr r10,SPRN_SPRG1 249 mfspr r10,SPRN_SPRG1
226 std r10,PACA_EXSLB+EX_R13(r13) 250 std r10,PACA_EXSLB+EX_R13(r13)
227 mfspr r12,SPRN_SRR1 /* and SRR1 */ 251 mfspr r12,SPRN_SRR1 /* and SRR1 */
228 b .slb_miss_realmode /* Rel. branch works in real mode */ 252#ifndef CONFIG_RELOCATABLE
253 b .slb_miss_realmode
254#else
255 mfctr r11
256 ld r10,PACAKBASE(r13)
257 LOAD_HANDLER(r10, .slb_miss_realmode)
258 mtctr r10
259 bctr
260#endif
229 261
230 MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt) 262 MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
231 STD_EXCEPTION_PSERIES(0x600, alignment) 263 STD_EXCEPTION_PSERIES(0x600, alignment)
@@ -244,14 +276,12 @@ BEGIN_FTR_SECTION
244 beq- 1f 276 beq- 1f
245END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) 277END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
246 mr r9,r13 278 mr r9,r13
247 mfmsr r10
248 mfspr r13,SPRN_SPRG3 279 mfspr r13,SPRN_SPRG3
249 mfspr r11,SPRN_SRR0 280 mfspr r11,SPRN_SRR0
250 clrrdi r12,r13,32 281 ld r12,PACAKBASE(r13)
251 oris r12,r12,system_call_common@h 282 ld r10,PACAKMSR(r13)
252 ori r12,r12,system_call_common@l 283 LOAD_HANDLER(r12, system_call_entry)
253 mtspr SPRN_SRR0,r12 284 mtspr SPRN_SRR0,r12
254 ori r10,r10,MSR_IR|MSR_DR|MSR_RI
255 mfspr r12,SPRN_SRR1 285 mfspr r12,SPRN_SRR1
256 mtspr SPRN_SRR1,r10 286 mtspr SPRN_SRR1,r10
257 rfid 287 rfid
@@ -379,7 +409,10 @@ __end_interrupts:
379 409
380/* 410/*
381 * Code from here down to __end_handlers is invoked from the 411 * Code from here down to __end_handlers is invoked from the
382 * exception prologs above. 412 * exception prologs above. Because the prologs assemble the
413 * addresses of these handlers using the LOAD_HANDLER macro,
414 * which uses an addi instruction, these handlers must be in
415 * the first 32k of the kernel image.
383 */ 416 */
384 417
385/*** Common interrupt handlers ***/ 418/*** Common interrupt handlers ***/
@@ -419,6 +452,10 @@ machine_check_common:
419 STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception) 452 STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
420#endif /* CONFIG_CBE_RAS */ 453#endif /* CONFIG_CBE_RAS */
421 454
455 .align 7
456system_call_entry:
457 b system_call_common
458
422/* 459/*
423 * Here we have detected that the kernel stack pointer is bad. 460 * Here we have detected that the kernel stack pointer is bad.
424 * R9 contains the saved CR, r13 points to the paca, 461 * R9 contains the saved CR, r13 points to the paca,
@@ -562,6 +599,9 @@ unrecov_user_slb:
562 */ 599 */
563_GLOBAL(slb_miss_realmode) 600_GLOBAL(slb_miss_realmode)
564 mflr r10 601 mflr r10
602#ifdef CONFIG_RELOCATABLE
603 mtctr r11
604#endif
565 605
566 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ 606 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
567 std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ 607 std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
@@ -612,11 +652,10 @@ BEGIN_FW_FTR_SECTION
612END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 652END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
613#endif /* CONFIG_PPC_ISERIES */ 653#endif /* CONFIG_PPC_ISERIES */
614 mfspr r11,SPRN_SRR0 654 mfspr r11,SPRN_SRR0
615 clrrdi r10,r13,32 655 ld r10,PACAKBASE(r13)
616 LOAD_HANDLER(r10,unrecov_slb) 656 LOAD_HANDLER(r10,unrecov_slb)
617 mtspr SPRN_SRR0,r10 657 mtspr SPRN_SRR0,r10
618 mfmsr r10 658 ld r10,PACAKMSR(r13)
619 ori r10,r10,MSR_IR|MSR_DR|MSR_RI
620 mtspr SPRN_SRR1,r10 659 mtspr SPRN_SRR1,r10
621 rfid 660 rfid
622 b . 661 b .