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.S604
1 files changed, 32 insertions, 572 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 171800002ede..97c5857faf00 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -34,6 +34,8 @@
34#include <asm/iseries/lpar_map.h> 34#include <asm/iseries/lpar_map.h>
35#include <asm/thread_info.h> 35#include <asm/thread_info.h>
36#include <asm/firmware.h> 36#include <asm/firmware.h>
37#include <asm/page_64.h>
38#include <asm/exception.h>
37 39
38#define DO_SOFT_DISABLE 40#define DO_SOFT_DISABLE
39 41
@@ -144,344 +146,9 @@ exception_marker:
144 .text 146 .text
145 147
146/* 148/*
147 * The following macros define the code that appears as
148 * the prologue to each of the exception handlers. They
149 * are split into two parts to allow a single kernel binary
150 * to be used for pSeries and iSeries.
151 * LOL. One day... - paulus
152 */
153
154/*
155 * We make as much of the exception code common between native
156 * exception handlers (including pSeries LPAR) and iSeries LPAR
157 * implementations as possible.
158 */
159
160/*
161 * This is the start of the interrupt handlers for pSeries 149 * This is the start of the interrupt handlers for pSeries
162 * This code runs with relocation off. 150 * This code runs with relocation off.
163 */ 151 */
164#define EX_R9 0
165#define EX_R10 8
166#define EX_R11 16
167#define EX_R12 24
168#define EX_R13 32
169#define EX_SRR0 40
170#define EX_DAR 48
171#define EX_DSISR 56
172#define EX_CCR 60
173#define EX_R3 64
174#define EX_LR 72
175
176/*
177 * We're short on space and time in the exception prolog, so we can't
178 * use the normal SET_REG_IMMEDIATE macro. Normally we just need the
179 * low halfword of the address, but for Kdump we need the whole low
180 * word.
181 */
182#ifdef CONFIG_CRASH_DUMP
183#define LOAD_HANDLER(reg, label) \
184 oris reg,reg,(label)@h; /* virt addr of handler ... */ \
185 ori reg,reg,(label)@l; /* .. and the rest */
186#else
187#define LOAD_HANDLER(reg, label) \
188 ori reg,reg,(label)@l; /* virt addr of handler ... */
189#endif
190
191/*
192 * Equal to EXCEPTION_PROLOG_PSERIES, except that it forces 64bit mode.
193 * The firmware calls the registered system_reset_fwnmi and
194 * machine_check_fwnmi handlers in 32bit mode if the cpu happens to run
195 * a 32bit application at the time of the event.
196 * This firmware bug is present on POWER4 and JS20.
197 */
198#define EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(area, label) \
199 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
200 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
201 std r10,area+EX_R10(r13); \
202 std r11,area+EX_R11(r13); \
203 std r12,area+EX_R12(r13); \
204 mfspr r9,SPRN_SPRG1; \
205 std r9,area+EX_R13(r13); \
206 mfcr r9; \
207 clrrdi r12,r13,32; /* get high part of &label */ \
208 mfmsr r10; \
209 /* force 64bit mode */ \
210 li r11,5; /* MSR_SF_LG|MSR_ISF_LG */ \
211 rldimi r10,r11,61,0; /* insert into top 3 bits */ \
212 /* done 64bit mode */ \
213 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
214 LOAD_HANDLER(r12,label) \
215 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
216 mtspr SPRN_SRR0,r12; \
217 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
218 mtspr SPRN_SRR1,r10; \
219 rfid; \
220 b . /* prevent speculative execution */
221
222#define EXCEPTION_PROLOG_PSERIES(area, label) \
223 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
224 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
225 std r10,area+EX_R10(r13); \
226 std r11,area+EX_R11(r13); \
227 std r12,area+EX_R12(r13); \
228 mfspr r9,SPRN_SPRG1; \
229 std r9,area+EX_R13(r13); \
230 mfcr r9; \
231 clrrdi r12,r13,32; /* get high part of &label */ \
232 mfmsr r10; \
233 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
234 LOAD_HANDLER(r12,label) \
235 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
236 mtspr SPRN_SRR0,r12; \
237 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
238 mtspr SPRN_SRR1,r10; \
239 rfid; \
240 b . /* prevent speculative execution */
241
242/*
243 * This is the start of the interrupt handlers for iSeries
244 * This code runs with relocation on.
245 */
246#define EXCEPTION_PROLOG_ISERIES_1(area) \
247 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
248 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
249 std r10,area+EX_R10(r13); \
250 std r11,area+EX_R11(r13); \
251 std r12,area+EX_R12(r13); \
252 mfspr r9,SPRN_SPRG1; \
253 std r9,area+EX_R13(r13); \
254 mfcr r9
255
256#define EXCEPTION_PROLOG_ISERIES_2 \
257 mfmsr r10; \
258 ld r12,PACALPPACAPTR(r13); \
259 ld r11,LPPACASRR0(r12); \
260 ld r12,LPPACASRR1(r12); \
261 ori r10,r10,MSR_RI; \
262 mtmsrd r10,1
263
264/*
265 * The common exception prolog is used for all except a few exceptions
266 * such as a segment miss on a kernel address. We have to be prepared
267 * to take another exception from the point where we first touch the
268 * kernel stack onwards.
269 *
270 * On entry r13 points to the paca, r9-r13 are saved in the paca,
271 * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
272 * SRR1, and relocation is on.
273 */
274#define EXCEPTION_PROLOG_COMMON(n, area) \
275 andi. r10,r12,MSR_PR; /* See if coming from user */ \
276 mr r10,r1; /* Save r1 */ \
277 subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
278 beq- 1f; \
279 ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
2801: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
281 bge- cr1,2f; /* abort if it is */ \
282 b 3f; \
2832: li r1,(n); /* will be reloaded later */ \
284 sth r1,PACA_TRAP_SAVE(r13); \
285 b bad_stack; \
2863: std r9,_CCR(r1); /* save CR in stackframe */ \
287 std r11,_NIP(r1); /* save SRR0 in stackframe */ \
288 std r12,_MSR(r1); /* save SRR1 in stackframe */ \
289 std r10,0(r1); /* make stack chain pointer */ \
290 std r0,GPR0(r1); /* save r0 in stackframe */ \
291 std r10,GPR1(r1); /* save r1 in stackframe */ \
292 ACCOUNT_CPU_USER_ENTRY(r9, r10); \
293 std r2,GPR2(r1); /* save r2 in stackframe */ \
294 SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
295 SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
296 ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
297 ld r10,area+EX_R10(r13); \
298 std r9,GPR9(r1); \
299 std r10,GPR10(r1); \
300 ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \
301 ld r10,area+EX_R12(r13); \
302 ld r11,area+EX_R13(r13); \
303 std r9,GPR11(r1); \
304 std r10,GPR12(r1); \
305 std r11,GPR13(r1); \
306 ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
307 mflr r9; /* save LR in stackframe */ \
308 std r9,_LINK(r1); \
309 mfctr r10; /* save CTR in stackframe */ \
310 std r10,_CTR(r1); \
311 lbz r10,PACASOFTIRQEN(r13); \
312 mfspr r11,SPRN_XER; /* save XER in stackframe */ \
313 std r10,SOFTE(r1); \
314 std r11,_XER(r1); \
315 li r9,(n)+1; \
316 std r9,_TRAP(r1); /* set trap number */ \
317 li r10,0; \
318 ld r11,exception_marker@toc(r2); \
319 std r10,RESULT(r1); /* clear regs->result */ \
320 std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */
321
322/*
323 * Exception vectors.
324 */
325#define STD_EXCEPTION_PSERIES(n, label) \
326 . = n; \
327 .globl label##_pSeries; \
328label##_pSeries: \
329 HMT_MEDIUM; \
330 mtspr SPRN_SPRG1,r13; /* save r13 */ \
331 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
332
333#define HSTD_EXCEPTION_PSERIES(n, label) \
334 . = n; \
335 .globl label##_pSeries; \
336label##_pSeries: \
337 HMT_MEDIUM; \
338 mtspr SPRN_SPRG1,r20; /* save r20 */ \
339 mfspr r20,SPRN_HSRR0; /* copy HSRR0 to SRR0 */ \
340 mtspr SPRN_SRR0,r20; \
341 mfspr r20,SPRN_HSRR1; /* copy HSRR0 to SRR0 */ \
342 mtspr SPRN_SRR1,r20; \
343 mfspr r20,SPRN_SPRG1; /* restore r20 */ \
344 mtspr SPRN_SPRG1,r13; /* save r13 */ \
345 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
346
347
348#define MASKABLE_EXCEPTION_PSERIES(n, label) \
349 . = n; \
350 .globl label##_pSeries; \
351label##_pSeries: \
352 HMT_MEDIUM; \
353 mtspr SPRN_SPRG1,r13; /* save r13 */ \
354 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
355 std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
356 std r10,PACA_EXGEN+EX_R10(r13); \
357 lbz r10,PACASOFTIRQEN(r13); \
358 mfcr r9; \
359 cmpwi r10,0; \
360 beq masked_interrupt; \
361 mfspr r10,SPRN_SPRG1; \
362 std r10,PACA_EXGEN+EX_R13(r13); \
363 std r11,PACA_EXGEN+EX_R11(r13); \
364 std r12,PACA_EXGEN+EX_R12(r13); \
365 clrrdi r12,r13,32; /* get high part of &label */ \
366 mfmsr r10; \
367 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
368 LOAD_HANDLER(r12,label##_common) \
369 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
370 mtspr SPRN_SRR0,r12; \
371 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
372 mtspr SPRN_SRR1,r10; \
373 rfid; \
374 b . /* prevent speculative execution */
375
376#define STD_EXCEPTION_ISERIES(n, label, area) \
377 .globl label##_iSeries; \
378label##_iSeries: \
379 HMT_MEDIUM; \
380 mtspr SPRN_SPRG1,r13; /* save r13 */ \
381 EXCEPTION_PROLOG_ISERIES_1(area); \
382 EXCEPTION_PROLOG_ISERIES_2; \
383 b label##_common
384
385#define MASKABLE_EXCEPTION_ISERIES(n, label) \
386 .globl label##_iSeries; \
387label##_iSeries: \
388 HMT_MEDIUM; \
389 mtspr SPRN_SPRG1,r13; /* save r13 */ \
390 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
391 lbz r10,PACASOFTIRQEN(r13); \
392 cmpwi 0,r10,0; \
393 beq- label##_iSeries_masked; \
394 EXCEPTION_PROLOG_ISERIES_2; \
395 b label##_common; \
396
397#ifdef CONFIG_PPC_ISERIES
398#define DISABLE_INTS \
399 li r11,0; \
400 stb r11,PACASOFTIRQEN(r13); \
401BEGIN_FW_FTR_SECTION; \
402 stb r11,PACAHARDIRQEN(r13); \
403END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
404BEGIN_FW_FTR_SECTION; \
405 mfmsr r10; \
406 ori r10,r10,MSR_EE; \
407 mtmsrd r10,1; \
408END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
409
410#else
411#define DISABLE_INTS \
412 li r11,0; \
413 stb r11,PACASOFTIRQEN(r13); \
414 stb r11,PACAHARDIRQEN(r13)
415
416#endif /* CONFIG_PPC_ISERIES */
417
418#define ENABLE_INTS \
419 ld r12,_MSR(r1); \
420 mfmsr r11; \
421 rlwimi r11,r12,0,MSR_EE; \
422 mtmsrd r11,1
423
424#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
425 .align 7; \
426 .globl label##_common; \
427label##_common: \
428 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
429 DISABLE_INTS; \
430 bl .save_nvgprs; \
431 addi r3,r1,STACK_FRAME_OVERHEAD; \
432 bl hdlr; \
433 b .ret_from_except
434
435/*
436 * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
437 * in the idle task and therefore need the special idle handling.
438 */
439#define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr) \
440 .align 7; \
441 .globl label##_common; \
442label##_common: \
443 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
444 FINISH_NAP; \
445 DISABLE_INTS; \
446 bl .save_nvgprs; \
447 addi r3,r1,STACK_FRAME_OVERHEAD; \
448 bl hdlr; \
449 b .ret_from_except
450
451#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \
452 .align 7; \
453 .globl label##_common; \
454label##_common: \
455 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
456 FINISH_NAP; \
457 DISABLE_INTS; \
458 bl .ppc64_runlatch_on; \
459 addi r3,r1,STACK_FRAME_OVERHEAD; \
460 bl hdlr; \
461 b .ret_from_except_lite
462
463/*
464 * When the idle code in power4_idle puts the CPU into NAP mode,
465 * it has to do so in a loop, and relies on the external interrupt
466 * and decrementer interrupt entry code to get it out of the loop.
467 * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags
468 * to signal that it is in the loop and needs help to get out.
469 */
470#ifdef CONFIG_PPC_970_NAP
471#define FINISH_NAP \
472BEGIN_FTR_SECTION \
473 clrrdi r11,r1,THREAD_SHIFT; \
474 ld r9,TI_LOCAL_FLAGS(r11); \
475 andi. r10,r9,_TLF_NAPPING; \
476 bnel power4_fixup_nap; \
477END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
478#else
479#define FINISH_NAP
480#endif
481
482/*
483 * Start of pSeries system interrupt routines
484 */
485 . = 0x100 152 . = 0x100
486 .globl __start_interrupts 153 .globl __start_interrupts
487__start_interrupts: 154__start_interrupts:
@@ -674,6 +341,7 @@ slb_miss_user_pseries:
674 b . /* prevent spec. execution */ 341 b . /* prevent spec. execution */
675#endif /* __DISABLED__ */ 342#endif /* __DISABLED__ */
676 343
344#ifdef CONFIG_PPC_PSERIES
677/* 345/*
678 * Vectors for the FWNMI option. Share common code. 346 * Vectors for the FWNMI option. Share common code.
679 */ 347 */
@@ -691,191 +359,7 @@ machine_check_fwnmi:
691 mtspr SPRN_SPRG1,r13 /* save r13 */ 359 mtspr SPRN_SPRG1,r13 /* save r13 */
692 EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXMC, machine_check_common) 360 EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXMC, machine_check_common)
693 361
694#ifdef CONFIG_PPC_ISERIES 362#endif /* CONFIG_PPC_PSERIES */
695/*** ISeries-LPAR interrupt handlers ***/
696
697 STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
698
699 .globl data_access_iSeries
700data_access_iSeries:
701 mtspr SPRN_SPRG1,r13
702BEGIN_FTR_SECTION
703 mtspr SPRN_SPRG2,r12
704 mfspr r13,SPRN_DAR
705 mfspr r12,SPRN_DSISR
706 srdi r13,r13,60
707 rlwimi r13,r12,16,0x20
708 mfcr r12
709 cmpwi r13,0x2c
710 beq .do_stab_bolted_iSeries
711 mtcrf 0x80,r12
712 mfspr r12,SPRN_SPRG2
713END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
714 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
715 EXCEPTION_PROLOG_ISERIES_2
716 b data_access_common
717
718.do_stab_bolted_iSeries:
719 mtcrf 0x80,r12
720 mfspr r12,SPRN_SPRG2
721 EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
722 EXCEPTION_PROLOG_ISERIES_2
723 b .do_stab_bolted
724
725 .globl data_access_slb_iSeries
726data_access_slb_iSeries:
727 mtspr SPRN_SPRG1,r13 /* save r13 */
728 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
729 std r3,PACA_EXSLB+EX_R3(r13)
730 mfspr r3,SPRN_DAR
731 std r9,PACA_EXSLB+EX_R9(r13)
732 mfcr r9
733#ifdef __DISABLED__
734 cmpdi r3,0
735 bge slb_miss_user_iseries
736#endif
737 std r10,PACA_EXSLB+EX_R10(r13)
738 std r11,PACA_EXSLB+EX_R11(r13)
739 std r12,PACA_EXSLB+EX_R12(r13)
740 mfspr r10,SPRN_SPRG1
741 std r10,PACA_EXSLB+EX_R13(r13)
742 ld r12,PACALPPACAPTR(r13)
743 ld r12,LPPACASRR1(r12)
744 b .slb_miss_realmode
745
746 STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
747
748 .globl instruction_access_slb_iSeries
749instruction_access_slb_iSeries:
750 mtspr SPRN_SPRG1,r13 /* save r13 */
751 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
752 std r3,PACA_EXSLB+EX_R3(r13)
753 ld r3,PACALPPACAPTR(r13)
754 ld r3,LPPACASRR0(r3) /* get SRR0 value */
755 std r9,PACA_EXSLB+EX_R9(r13)
756 mfcr r9
757#ifdef __DISABLED__
758 cmpdi r3,0
759 bge .slb_miss_user_iseries
760#endif
761 std r10,PACA_EXSLB+EX_R10(r13)
762 std r11,PACA_EXSLB+EX_R11(r13)
763 std r12,PACA_EXSLB+EX_R12(r13)
764 mfspr r10,SPRN_SPRG1
765 std r10,PACA_EXSLB+EX_R13(r13)
766 ld r12,PACALPPACAPTR(r13)
767 ld r12,LPPACASRR1(r12)
768 b .slb_miss_realmode
769
770#ifdef __DISABLED__
771slb_miss_user_iseries:
772 std r10,PACA_EXGEN+EX_R10(r13)
773 std r11,PACA_EXGEN+EX_R11(r13)
774 std r12,PACA_EXGEN+EX_R12(r13)
775 mfspr r10,SPRG1
776 ld r11,PACA_EXSLB+EX_R9(r13)
777 ld r12,PACA_EXSLB+EX_R3(r13)
778 std r10,PACA_EXGEN+EX_R13(r13)
779 std r11,PACA_EXGEN+EX_R9(r13)
780 std r12,PACA_EXGEN+EX_R3(r13)
781 EXCEPTION_PROLOG_ISERIES_2
782 b slb_miss_user_common
783#endif
784
785 MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
786 STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
787 STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
788 STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
789 MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
790 STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
791 STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
792
793 .globl system_call_iSeries
794system_call_iSeries:
795 mr r9,r13
796 mfspr r13,SPRN_SPRG3
797 EXCEPTION_PROLOG_ISERIES_2
798 b system_call_common
799
800 STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
801 STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
802 STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
803
804 .globl system_reset_iSeries
805system_reset_iSeries:
806 mfspr r13,SPRN_SPRG3 /* Get paca address */
807 mfmsr r24
808 ori r24,r24,MSR_RI
809 mtmsrd r24 /* RI on */
810 lhz r24,PACAPACAINDEX(r13) /* Get processor # */
811 cmpwi 0,r24,0 /* Are we processor 0? */
812 bne 1f
813 b .__start_initialization_iSeries /* Start up the first processor */
8141: mfspr r4,SPRN_CTRLF
815 li r5,CTRL_RUNLATCH /* Turn off the run light */
816 andc r4,r4,r5
817 mtspr SPRN_CTRLT,r4
818
8191:
820 HMT_LOW
821#ifdef CONFIG_SMP
822 lbz r23,PACAPROCSTART(r13) /* Test if this processor
823 * should start */
824 sync
825 LOAD_REG_IMMEDIATE(r3,current_set)
826 sldi r28,r24,3 /* get current_set[cpu#] */
827 ldx r3,r3,r28
828 addi r1,r3,THREAD_SIZE
829 subi r1,r1,STACK_FRAME_OVERHEAD
830
831 cmpwi 0,r23,0
832 beq iSeries_secondary_smp_loop /* Loop until told to go */
833 bne __secondary_start /* Loop until told to go */
834iSeries_secondary_smp_loop:
835 /* Let the Hypervisor know we are alive */
836 /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
837 lis r3,0x8002
838 rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
839#else /* CONFIG_SMP */
840 /* Yield the processor. This is required for non-SMP kernels
841 which are running on multi-threaded machines. */
842 lis r3,0x8000
843 rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */
844 addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */
845 li r4,0 /* "yield timed" */
846 li r5,-1 /* "yield forever" */
847#endif /* CONFIG_SMP */
848 li r0,-1 /* r0=-1 indicates a Hypervisor call */
849 sc /* Invoke the hypervisor via a system call */
850 mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */
851 b 1b /* If SMP not configured, secondaries
852 * loop forever */
853
854decrementer_iSeries_masked:
855 /* We may not have a valid TOC pointer in here. */
856 li r11,1
857 ld r12,PACALPPACAPTR(r13)
858 stb r11,LPPACADECRINT(r12)
859 LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy)
860 lwz r12,0(r12)
861 mtspr SPRN_DEC,r12
862 /* fall through */
863
864hardware_interrupt_iSeries_masked:
865 mtcrf 0x80,r9 /* Restore regs */
866 ld r12,PACALPPACAPTR(r13)
867 ld r11,LPPACASRR0(r12)
868 ld r12,LPPACASRR1(r12)
869 mtspr SPRN_SRR0,r11
870 mtspr SPRN_SRR1,r12
871 ld r9,PACA_EXGEN+EX_R9(r13)
872 ld r10,PACA_EXGEN+EX_R10(r13)
873 ld r11,PACA_EXGEN+EX_R11(r13)
874 ld r12,PACA_EXGEN+EX_R12(r13)
875 ld r13,PACA_EXGEN+EX_R13(r13)
876 rfid
877 b . /* prevent speculative execution */
878#endif /* CONFIG_PPC_ISERIES */
879 363
880/*** Common interrupt handlers ***/ 364/*** Common interrupt handlers ***/
881 365
@@ -1175,7 +659,9 @@ hardware_interrupt_common:
1175 FINISH_NAP 659 FINISH_NAP
1176hardware_interrupt_entry: 660hardware_interrupt_entry:
1177 DISABLE_INTS 661 DISABLE_INTS
662BEGIN_FTR_SECTION
1178 bl .ppc64_runlatch_on 663 bl .ppc64_runlatch_on
664END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
1179 addi r3,r1,STACK_FRAME_OVERHEAD 665 addi r3,r1,STACK_FRAME_OVERHEAD
1180 bl .do_IRQ 666 bl .do_IRQ
1181 b .ret_from_except_lite 667 b .ret_from_except_lite
@@ -1449,7 +935,7 @@ _GLOBAL(do_stab_bolted)
1449 935
1450 /* Calculate VSID */ 936 /* Calculate VSID */
1451 /* This is a kernel address, so protovsid = ESID */ 937 /* This is a kernel address, so protovsid = ESID */
1452 ASM_VSID_SCRAMBLE(r11, r9) 938 ASM_VSID_SCRAMBLE(r11, r9, 256M)
1453 rldic r9,r11,12,16 /* r9 = vsid << 12 */ 939 rldic r9,r11,12,16 /* r9 = vsid << 12 */
1454 940
1455 /* Search the primary group for a free entry */ 941 /* Search the primary group for a free entry */
@@ -1519,8 +1005,8 @@ _GLOBAL(do_stab_bolted)
1519 * Space for CPU0's segment table. 1005 * Space for CPU0's segment table.
1520 * 1006 *
1521 * On iSeries, the hypervisor must fill in at least one entry before 1007 * On iSeries, the hypervisor must fill in at least one entry before
1522 * we get control (with relocate on). The address is give to the hv 1008 * we get control (with relocate on). The address is given to the hv
1523 * as a page number (see xLparMap in lpardata.c), so this must be at a 1009 * as a page number (see xLparMap below), so this must be at a
1524 * fixed address (the linker can't compute (u64)&initial_stab >> 1010 * fixed address (the linker can't compute (u64)&initial_stab >>
1525 * PAGE_SHIFT). 1011 * PAGE_SHIFT).
1526 */ 1012 */
@@ -1529,6 +1015,7 @@ _GLOBAL(do_stab_bolted)
1529initial_stab: 1015initial_stab:
1530 .space 4096 1016 .space 4096
1531 1017
1018#ifdef CONFIG_PPC_PSERIES
1532/* 1019/*
1533 * Data area reserved for FWNMI option. 1020 * Data area reserved for FWNMI option.
1534 * This address (0x7000) is fixed by the RPA. 1021 * This address (0x7000) is fixed by the RPA.
@@ -1536,21 +1023,34 @@ initial_stab:
1536 .= 0x7000 1023 .= 0x7000
1537 .globl fwnmi_data_area 1024 .globl fwnmi_data_area
1538fwnmi_data_area: 1025fwnmi_data_area:
1026#endif /* CONFIG_PPC_PSERIES */
1539 1027
1540 /* iSeries does not use the FWNMI stuff, so it is safe to put 1028 /* iSeries does not use the FWNMI stuff, so it is safe to put
1541 * this here, even if we later allow kernels that will boot on 1029 * this here, even if we later allow kernels that will boot on
1542 * both pSeries and iSeries */ 1030 * both pSeries and iSeries */
1543#ifdef CONFIG_PPC_ISERIES 1031#ifdef CONFIG_PPC_ISERIES
1544 . = LPARMAP_PHYS 1032 . = LPARMAP_PHYS
1545#include "lparmap.s" 1033 .globl xLparMap
1546/* 1034xLparMap:
1547 * This ".text" is here for old compilers that generate a trailing 1035 .quad HvEsidsToMap /* xNumberEsids */
1548 * .note section when compiling .c files to .s 1036 .quad HvRangesToMap /* xNumberRanges */
1549 */ 1037 .quad STAB0_PAGE /* xSegmentTableOffs */
1550 .text 1038 .zero 40 /* xRsvd */
1039 /* xEsids (HvEsidsToMap entries of 2 quads) */
1040 .quad PAGE_OFFSET_ESID /* xKernelEsid */
1041 .quad PAGE_OFFSET_VSID /* xKernelVsid */
1042 .quad VMALLOC_START_ESID /* xKernelEsid */
1043 .quad VMALLOC_START_VSID /* xKernelVsid */
1044 /* xRanges (HvRangesToMap entries of 3 quads) */
1045 .quad HvPagesToMap /* xPages */
1046 .quad 0 /* xOffset */
1047 .quad PAGE_OFFSET_VSID << (SID_SHIFT - HW_PAGE_SHIFT) /* xVPN */
1048
1551#endif /* CONFIG_PPC_ISERIES */ 1049#endif /* CONFIG_PPC_ISERIES */
1552 1050
1051#ifdef CONFIG_PPC_PSERIES
1553 . = 0x8000 1052 . = 0x8000
1053#endif /* CONFIG_PPC_PSERIES */
1554 1054
1555/* 1055/*
1556 * On pSeries and most other platforms, secondary processors spin 1056 * On pSeries and most other platforms, secondary processors spin
@@ -1611,39 +1111,6 @@ _GLOBAL(generic_secondary_smp_init)
1611 b __secondary_start 1111 b __secondary_start
1612#endif 1112#endif
1613 1113
1614#ifdef CONFIG_PPC_ISERIES
1615_INIT_STATIC(__start_initialization_iSeries)
1616 /* Clear out the BSS */
1617 LOAD_REG_IMMEDIATE(r11,__bss_stop)
1618 LOAD_REG_IMMEDIATE(r8,__bss_start)
1619 sub r11,r11,r8 /* bss size */
1620 addi r11,r11,7 /* round up to an even double word */
1621 rldicl. r11,r11,61,3 /* shift right by 3 */
1622 beq 4f
1623 addi r8,r8,-8
1624 li r0,0
1625 mtctr r11 /* zero this many doublewords */
16263: stdu r0,8(r8)
1627 bdnz 3b
16284:
1629 LOAD_REG_IMMEDIATE(r1,init_thread_union)
1630 addi r1,r1,THREAD_SIZE
1631 li r0,0
1632 stdu r0,-STACK_FRAME_OVERHEAD(r1)
1633
1634 LOAD_REG_IMMEDIATE(r2,__toc_start)
1635 addi r2,r2,0x4000
1636 addi r2,r2,0x4000
1637
1638 bl .iSeries_early_setup
1639 bl .early_setup
1640
1641 /* relocation is on at this point */
1642
1643 b .start_here_common
1644#endif /* CONFIG_PPC_ISERIES */
1645
1646
1647_STATIC(__mmu_off) 1114_STATIC(__mmu_off)
1648 mfmsr r3 1115 mfmsr r3
1649 andi. r0,r3,MSR_IR|MSR_DR 1116 andi. r0,r3,MSR_IR|MSR_DR
@@ -1891,6 +1358,7 @@ _GLOBAL(pmac_secondary_start)
1891 * r13 = paca virtual address 1358 * r13 = paca virtual address
1892 * SPRG3 = paca virtual address 1359 * SPRG3 = paca virtual address
1893 */ 1360 */
1361 .globl __secondary_start
1894__secondary_start: 1362__secondary_start:
1895 /* Set thread priority to MEDIUM */ 1363 /* Set thread priority to MEDIUM */
1896 HMT_MEDIUM 1364 HMT_MEDIUM
@@ -2021,7 +1489,7 @@ _INIT_STATIC(start_here_multiplatform)
2021 b . /* prevent speculative execution */ 1489 b . /* prevent speculative execution */
2022 1490
2023 /* This is where all platforms converge execution */ 1491 /* This is where all platforms converge execution */
2024_INIT_STATIC(start_here_common) 1492_INIT_GLOBAL(start_here_common)
2025 /* relocation is on at this point */ 1493 /* relocation is on at this point */
2026 1494
2027 /* The following code sets up the SP and TOC now that we are */ 1495 /* The following code sets up the SP and TOC now that we are */
@@ -2078,12 +1546,4 @@ empty_zero_page:
2078 1546
2079 .globl swapper_pg_dir 1547 .globl swapper_pg_dir
2080swapper_pg_dir: 1548swapper_pg_dir:
2081 .space PAGE_SIZE 1549 .space PGD_TABLE_SIZE
2082
2083/*
2084 * This space gets a copy of optional info passed to us by the bootstrap
2085 * Used to pass parameters into the kernel like root=/dev/sda1, etc.
2086 */
2087 .globl cmd_line
2088cmd_line:
2089 .space COMMAND_LINE_SIZE