diff options
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 71 |
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. */ |
128 | 100: ld r4,__secondary_hold_spinloop@l(0) | 135 | 100: 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 |
245 | END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) | 277 | END_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 | ||
456 | system_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 | |||
612 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | 652 | END_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 . |