Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[pandora-kernel.git] / arch / powerpc / kernel / head_64.S
1 /*
2  *  PowerPC version
3  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4  *
5  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
6  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
7  *  Adapted for Power Macintosh by Paul Mackerras.
8  *  Low-level exception handlers and MMU support
9  *  rewritten by Paul Mackerras.
10  *    Copyright (C) 1996 Paul Mackerras.
11  *
12  *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
13  *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
14  *
15  *  This file contains the low-level support and setup for the
16  *  PowerPC-64 platform, including trap and interrupt dispatch.
17  *
18  *  This program is free software; you can redistribute it and/or
19  *  modify it under the terms of the GNU General Public License
20  *  as published by the Free Software Foundation; either version
21  *  2 of the License, or (at your option) any later version.
22  */
23
24 #include <linux/config.h>
25 #include <linux/threads.h>
26 #include <asm/reg.h>
27 #include <asm/page.h>
28 #include <asm/mmu.h>
29 #include <asm/ppc_asm.h>
30 #include <asm/asm-offsets.h>
31 #include <asm/bug.h>
32 #include <asm/cputable.h>
33 #include <asm/setup.h>
34 #include <asm/hvcall.h>
35 #include <asm/iseries/lpar_map.h>
36 #include <asm/thread_info.h>
37
38 #ifdef CONFIG_PPC_ISERIES
39 #define DO_SOFT_DISABLE
40 #endif
41
42 /*
43  * We layout physical memory as follows:
44  * 0x0000 - 0x00ff : Secondary processor spin code
45  * 0x0100 - 0x2fff : pSeries Interrupt prologs
46  * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
47  * 0x6000 - 0x6fff : Initial (CPU0) segment table
48  * 0x7000 - 0x7fff : FWNMI data area
49  * 0x8000 -        : Early init and support code
50  */
51
52 /*
53  *   SPRG Usage
54  *
55  *   Register   Definition
56  *
57  *   SPRG0      reserved for hypervisor
58  *   SPRG1      temp - used to save gpr
59  *   SPRG2      temp - used to save gpr
60  *   SPRG3      virt addr of paca
61  */
62
63 /*
64  * Entering into this code we make the following assumptions:
65  *  For pSeries:
66  *   1. The MMU is off & open firmware is running in real mode.
67  *   2. The kernel is entered at __start
68  *
69  *  For iSeries:
70  *   1. The MMU is on (as it always is for iSeries)
71  *   2. The kernel is entered at system_reset_iSeries
72  */
73
74         .text
75         .globl  _stext
76 _stext:
77 #ifdef CONFIG_PPC_MULTIPLATFORM
78 _GLOBAL(__start)
79         /* NOP this out unconditionally */
80 BEGIN_FTR_SECTION
81         b       .__start_initialization_multiplatform
82 END_FTR_SECTION(0, 1)
83 #endif /* CONFIG_PPC_MULTIPLATFORM */
84
85         /* Catch branch to 0 in real mode */
86         trap
87
88 #ifdef CONFIG_PPC_ISERIES
89         /*
90          * At offset 0x20, there is a pointer to iSeries LPAR data.
91          * This is required by the hypervisor
92          */
93         . = 0x20
94         .llong hvReleaseData-KERNELBASE
95
96         /*
97          * At offset 0x28 and 0x30 are offsets to the mschunks_map
98          * array (used by the iSeries LPAR debugger to do translation
99          * between physical addresses and absolute addresses) and
100          * to the pidhash table (also used by the debugger)
101          */
102         .llong mschunks_map-KERNELBASE
103         .llong 0        /* pidhash-KERNELBASE SFRXXX */
104
105         /* Offset 0x38 - Pointer to start of embedded System.map */
106         .globl  embedded_sysmap_start
107 embedded_sysmap_start:
108         .llong  0
109         /* Offset 0x40 - Pointer to end of embedded System.map */
110         .globl  embedded_sysmap_end
111 embedded_sysmap_end:
112         .llong  0
113
114 #endif /* CONFIG_PPC_ISERIES */
115
116         /* Secondary processors spin on this value until it goes to 1. */
117         .globl  __secondary_hold_spinloop
118 __secondary_hold_spinloop:
119         .llong  0x0
120
121         /* Secondary processors write this value with their cpu # */
122         /* after they enter the spin loop immediately below.      */
123         .globl  __secondary_hold_acknowledge
124 __secondary_hold_acknowledge:
125         .llong  0x0
126
127         . = 0x60
128 /*
129  * The following code is used on pSeries to hold secondary processors
130  * in a spin loop after they have been freed from OpenFirmware, but
131  * before the bulk of the kernel has been relocated.  This code
132  * is relocated to physical address 0x60 before prom_init is run.
133  * All of it must fit below the first exception vector at 0x100.
134  */
135 _GLOBAL(__secondary_hold)
136         mfmsr   r24
137         ori     r24,r24,MSR_RI
138         mtmsrd  r24                     /* RI on */
139
140         /* Grab our physical cpu number */
141         mr      r24,r3
142
143         /* Tell the master cpu we're here */
144         /* Relocation is off & we are located at an address less */
145         /* than 0x100, so only need to grab low order offset.    */
146         std     r24,__secondary_hold_acknowledge@l(0)
147         sync
148
149         /* All secondary cpus wait here until told to start. */
150 100:    ld      r4,__secondary_hold_spinloop@l(0)
151         cmpdi   0,r4,1
152         bne     100b
153
154 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
155         LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init)
156         mtctr   r4
157         mr      r3,r24
158         bctr
159 #else
160         BUG_OPCODE
161 #endif
162
163 /* This value is used to mark exception frames on the stack. */
164         .section ".toc","aw"
165 exception_marker:
166         .tc     ID_72656773_68657265[TC],0x7265677368657265
167         .text
168
169 /*
170  * The following macros define the code that appears as
171  * the prologue to each of the exception handlers.  They
172  * are split into two parts to allow a single kernel binary
173  * to be used for pSeries and iSeries.
174  * LOL.  One day... - paulus
175  */
176
177 /*
178  * We make as much of the exception code common between native
179  * exception handlers (including pSeries LPAR) and iSeries LPAR
180  * implementations as possible.
181  */
182
183 /*
184  * This is the start of the interrupt handlers for pSeries
185  * This code runs with relocation off.
186  */
187 #define EX_R9           0
188 #define EX_R10          8
189 #define EX_R11          16
190 #define EX_R12          24
191 #define EX_R13          32
192 #define EX_SRR0         40
193 #define EX_DAR          48
194 #define EX_DSISR        56
195 #define EX_CCR          60
196 #define EX_R3           64
197 #define EX_LR           72
198
199 /*
200  * We're short on space and time in the exception prolog, so we can't
201  * use the normal SET_REG_IMMEDIATE macro. Normally we just need the
202  * low halfword of the address, but for Kdump we need the whole low
203  * word.
204  */
205 #ifdef CONFIG_CRASH_DUMP
206 #define LOAD_HANDLER(reg, label)                                        \
207         oris    reg,reg,(label)@h;      /* virt addr of handler ... */  \
208         ori     reg,reg,(label)@l;      /* .. and the rest */
209 #else
210 #define LOAD_HANDLER(reg, label)                                        \
211         ori     reg,reg,(label)@l;      /* virt addr of handler ... */
212 #endif
213
214 #define EXCEPTION_PROLOG_PSERIES(area, label)                           \
215         mfspr   r13,SPRN_SPRG3;         /* get paca address into r13 */ \
216         std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
217         std     r10,area+EX_R10(r13);                                   \
218         std     r11,area+EX_R11(r13);                                   \
219         std     r12,area+EX_R12(r13);                                   \
220         mfspr   r9,SPRN_SPRG1;                                          \
221         std     r9,area+EX_R13(r13);                                    \
222         mfcr    r9;                                                     \
223         clrrdi  r12,r13,32;             /* get high part of &label */   \
224         mfmsr   r10;                                                    \
225         mfspr   r11,SPRN_SRR0;          /* save SRR0 */                 \
226         LOAD_HANDLER(r12,label)                                         \
227         ori     r10,r10,MSR_IR|MSR_DR|MSR_RI;                           \
228         mtspr   SPRN_SRR0,r12;                                          \
229         mfspr   r12,SPRN_SRR1;          /* and SRR1 */                  \
230         mtspr   SPRN_SRR1,r10;                                          \
231         rfid;                                                           \
232         b       .       /* prevent speculative execution */
233
234 /*
235  * This is the start of the interrupt handlers for iSeries
236  * This code runs with relocation on.
237  */
238 #define EXCEPTION_PROLOG_ISERIES_1(area)                                \
239         mfspr   r13,SPRN_SPRG3;         /* get paca address into r13 */ \
240         std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
241         std     r10,area+EX_R10(r13);                                   \
242         std     r11,area+EX_R11(r13);                                   \
243         std     r12,area+EX_R12(r13);                                   \
244         mfspr   r9,SPRN_SPRG1;                                          \
245         std     r9,area+EX_R13(r13);                                    \
246         mfcr    r9
247
248 #define EXCEPTION_PROLOG_ISERIES_2                                      \
249         mfmsr   r10;                                                    \
250         ld      r12,PACALPPACAPTR(r13);                                 \
251         ld      r11,LPPACASRR0(r12);                                    \
252         ld      r12,LPPACASRR1(r12);                                    \
253         ori     r10,r10,MSR_RI;                                         \
254         mtmsrd  r10,1
255
256 /*
257  * The common exception prolog is used for all except a few exceptions
258  * such as a segment miss on a kernel address.  We have to be prepared
259  * to take another exception from the point where we first touch the
260  * kernel stack onwards.
261  *
262  * On entry r13 points to the paca, r9-r13 are saved in the paca,
263  * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
264  * SRR1, and relocation is on.
265  */
266 #define EXCEPTION_PROLOG_COMMON(n, area)                                   \
267         andi.   r10,r12,MSR_PR;         /* See if coming from user      */ \
268         mr      r10,r1;                 /* Save r1                      */ \
269         subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack  */ \
270         beq-    1f;                                                        \
271         ld      r1,PACAKSAVE(r13);      /* kernel stack to use          */ \
272 1:      cmpdi   cr1,r1,0;               /* check if r1 is in userspace  */ \
273         bge-    cr1,bad_stack;          /* abort if it is               */ \
274         std     r9,_CCR(r1);            /* save CR in stackframe        */ \
275         std     r11,_NIP(r1);           /* save SRR0 in stackframe      */ \
276         std     r12,_MSR(r1);           /* save SRR1 in stackframe      */ \
277         std     r10,0(r1);              /* make stack chain pointer     */ \
278         std     r0,GPR0(r1);            /* save r0 in stackframe        */ \
279         std     r10,GPR1(r1);           /* save r1 in stackframe        */ \
280         ACCOUNT_CPU_USER_ENTRY(r9, r10);                                   \
281         std     r2,GPR2(r1);            /* save r2 in stackframe        */ \
282         SAVE_4GPRS(3, r1);              /* save r3 - r6 in stackframe   */ \
283         SAVE_2GPRS(7, r1);              /* save r7, r8 in stackframe    */ \
284         ld      r9,area+EX_R9(r13);     /* move r9, r10 to stackframe   */ \
285         ld      r10,area+EX_R10(r13);                                      \
286         std     r9,GPR9(r1);                                               \
287         std     r10,GPR10(r1);                                             \
288         ld      r9,area+EX_R11(r13);    /* move r11 - r13 to stackframe */ \
289         ld      r10,area+EX_R12(r13);                                      \
290         ld      r11,area+EX_R13(r13);                                      \
291         std     r9,GPR11(r1);                                              \
292         std     r10,GPR12(r1);                                             \
293         std     r11,GPR13(r1);                                             \
294         ld      r2,PACATOC(r13);        /* get kernel TOC into r2       */ \
295         mflr    r9;                     /* save LR in stackframe        */ \
296         std     r9,_LINK(r1);                                              \
297         mfctr   r10;                    /* save CTR in stackframe       */ \
298         std     r10,_CTR(r1);                                              \
299         mfspr   r11,SPRN_XER;           /* save XER in stackframe       */ \
300         std     r11,_XER(r1);                                              \
301         li      r9,(n)+1;                                                  \
302         std     r9,_TRAP(r1);           /* set trap number              */ \
303         li      r10,0;                                                     \
304         ld      r11,exception_marker@toc(r2);                              \
305         std     r10,RESULT(r1);         /* clear regs->result           */ \
306         std     r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame      */
307
308 /*
309  * Exception vectors.
310  */
311 #define STD_EXCEPTION_PSERIES(n, label)                 \
312         . = n;                                          \
313         .globl label##_pSeries;                         \
314 label##_pSeries:                                        \
315         HMT_MEDIUM;                                     \
316         mtspr   SPRN_SPRG1,r13;         /* save r13 */  \
317         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
318
319 #define HSTD_EXCEPTION_PSERIES(n, label)                \
320         . = n;                                          \
321         .globl label##_pSeries;                         \
322 label##_pSeries:                                        \
323         HMT_MEDIUM;                                     \
324         mtspr   SPRN_SPRG1,r20;         /* save r20 */  \
325         mfspr   r20,SPRN_HSRR0;         /* copy HSRR0 to SRR0 */ \
326         mtspr   SPRN_SRR0,r20;                          \
327         mfspr   r20,SPRN_HSRR1;         /* copy HSRR0 to SRR0 */ \
328         mtspr   SPRN_SRR1,r20;                          \
329         mfspr   r20,SPRN_SPRG1;         /* restore r20 */ \
330         mtspr   SPRN_SPRG1,r13;         /* save r13 */  \
331         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
332
333
334 #define STD_EXCEPTION_ISERIES(n, label, area)           \
335         .globl label##_iSeries;                         \
336 label##_iSeries:                                        \
337         HMT_MEDIUM;                                     \
338         mtspr   SPRN_SPRG1,r13;         /* save r13 */  \
339         EXCEPTION_PROLOG_ISERIES_1(area);               \
340         EXCEPTION_PROLOG_ISERIES_2;                     \
341         b       label##_common
342
343 #define MASKABLE_EXCEPTION_ISERIES(n, label)                            \
344         .globl label##_iSeries;                                         \
345 label##_iSeries:                                                        \
346         HMT_MEDIUM;                                                     \
347         mtspr   SPRN_SPRG1,r13;         /* save r13 */                  \
348         EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);                         \
349         lbz     r10,PACAPROCENABLED(r13);                               \
350         cmpwi   0,r10,0;                                                \
351         beq-    label##_iSeries_masked;                                 \
352         EXCEPTION_PROLOG_ISERIES_2;                                     \
353         b       label##_common;                                         \
354
355 #ifdef DO_SOFT_DISABLE
356 #define DISABLE_INTS                            \
357         lbz     r10,PACAPROCENABLED(r13);       \
358         li      r11,0;                          \
359         std     r10,SOFTE(r1);                  \
360         mfmsr   r10;                            \
361         stb     r11,PACAPROCENABLED(r13);       \
362         ori     r10,r10,MSR_EE;                 \
363         mtmsrd  r10,1
364
365 #define ENABLE_INTS                             \
366         lbz     r10,PACAPROCENABLED(r13);       \
367         mfmsr   r11;                            \
368         std     r10,SOFTE(r1);                  \
369         ori     r11,r11,MSR_EE;                 \
370         mtmsrd  r11,1
371
372 #else   /* hard enable/disable interrupts */
373 #define DISABLE_INTS
374
375 #define ENABLE_INTS                             \
376         ld      r12,_MSR(r1);                   \
377         mfmsr   r11;                            \
378         rlwimi  r11,r12,0,MSR_EE;               \
379         mtmsrd  r11,1
380
381 #endif
382
383 #define STD_EXCEPTION_COMMON(trap, label, hdlr)         \
384         .align  7;                                      \
385         .globl label##_common;                          \
386 label##_common:                                         \
387         EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);      \
388         DISABLE_INTS;                                   \
389         bl      .save_nvgprs;                           \
390         addi    r3,r1,STACK_FRAME_OVERHEAD;             \
391         bl      hdlr;                                   \
392         b       .ret_from_except
393
394 /*
395  * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
396  * in the idle task and therefore need the special idle handling.
397  */
398 #define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr)    \
399         .align  7;                                      \
400         .globl label##_common;                          \
401 label##_common:                                         \
402         EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);      \
403         FINISH_NAP;                                     \
404         DISABLE_INTS;                                   \
405         bl      .save_nvgprs;                           \
406         addi    r3,r1,STACK_FRAME_OVERHEAD;             \
407         bl      hdlr;                                   \
408         b       .ret_from_except
409
410 #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr)    \
411         .align  7;                                      \
412         .globl label##_common;                          \
413 label##_common:                                         \
414         EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);      \
415         FINISH_NAP;                                     \
416         DISABLE_INTS;                                   \
417         bl      .ppc64_runlatch_on;                     \
418         addi    r3,r1,STACK_FRAME_OVERHEAD;             \
419         bl      hdlr;                                   \
420         b       .ret_from_except_lite
421
422 /*
423  * When the idle code in power4_idle puts the CPU into NAP mode,
424  * it has to do so in a loop, and relies on the external interrupt
425  * and decrementer interrupt entry code to get it out of the loop.
426  * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags
427  * to signal that it is in the loop and needs help to get out.
428  */
429 #ifdef CONFIG_PPC_970_NAP
430 #define FINISH_NAP                              \
431 BEGIN_FTR_SECTION                               \
432         clrrdi  r11,r1,THREAD_SHIFT;            \
433         ld      r9,TI_LOCAL_FLAGS(r11);         \
434         andi.   r10,r9,_TLF_NAPPING;            \
435         bnel    power4_fixup_nap;               \
436 END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
437 #else
438 #define FINISH_NAP
439 #endif
440
441 /*
442  * Start of pSeries system interrupt routines
443  */
444         . = 0x100
445         .globl __start_interrupts
446 __start_interrupts:
447
448         STD_EXCEPTION_PSERIES(0x100, system_reset)
449
450         . = 0x200
451 _machine_check_pSeries:
452         HMT_MEDIUM
453         mtspr   SPRN_SPRG1,r13          /* save r13 */
454         EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
455
456         . = 0x300
457         .globl data_access_pSeries
458 data_access_pSeries:
459         HMT_MEDIUM
460         mtspr   SPRN_SPRG1,r13
461 BEGIN_FTR_SECTION
462         mtspr   SPRN_SPRG2,r12
463         mfspr   r13,SPRN_DAR
464         mfspr   r12,SPRN_DSISR
465         srdi    r13,r13,60
466         rlwimi  r13,r12,16,0x20
467         mfcr    r12
468         cmpwi   r13,0x2c
469         beq     .do_stab_bolted_pSeries
470         mtcrf   0x80,r12
471         mfspr   r12,SPRN_SPRG2
472 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
473         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
474
475         . = 0x380
476         .globl data_access_slb_pSeries
477 data_access_slb_pSeries:
478         HMT_MEDIUM
479         mtspr   SPRN_SPRG1,r13
480         mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
481         std     r3,PACA_EXSLB+EX_R3(r13)
482         mfspr   r3,SPRN_DAR
483         std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
484         mfcr    r9
485 #ifdef __DISABLED__
486         /* Keep that around for when we re-implement dynamic VSIDs */
487         cmpdi   r3,0
488         bge     slb_miss_user_pseries
489 #endif /* __DISABLED__ */
490         std     r10,PACA_EXSLB+EX_R10(r13)
491         std     r11,PACA_EXSLB+EX_R11(r13)
492         std     r12,PACA_EXSLB+EX_R12(r13)
493         mfspr   r10,SPRN_SPRG1
494         std     r10,PACA_EXSLB+EX_R13(r13)
495         mfspr   r12,SPRN_SRR1           /* and SRR1 */
496         b       .slb_miss_realmode      /* Rel. branch works in real mode */
497
498         STD_EXCEPTION_PSERIES(0x400, instruction_access)
499
500         . = 0x480
501         .globl instruction_access_slb_pSeries
502 instruction_access_slb_pSeries:
503         HMT_MEDIUM
504         mtspr   SPRN_SPRG1,r13
505         mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
506         std     r3,PACA_EXSLB+EX_R3(r13)
507         mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
508         std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
509         mfcr    r9
510 #ifdef __DISABLED__
511         /* Keep that around for when we re-implement dynamic VSIDs */
512         cmpdi   r3,0
513         bge     slb_miss_user_pseries
514 #endif /* __DISABLED__ */
515         std     r10,PACA_EXSLB+EX_R10(r13)
516         std     r11,PACA_EXSLB+EX_R11(r13)
517         std     r12,PACA_EXSLB+EX_R12(r13)
518         mfspr   r10,SPRN_SPRG1
519         std     r10,PACA_EXSLB+EX_R13(r13)
520         mfspr   r12,SPRN_SRR1           /* and SRR1 */
521         b       .slb_miss_realmode      /* Rel. branch works in real mode */
522
523         STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
524         STD_EXCEPTION_PSERIES(0x600, alignment)
525         STD_EXCEPTION_PSERIES(0x700, program_check)
526         STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
527         STD_EXCEPTION_PSERIES(0x900, decrementer)
528         STD_EXCEPTION_PSERIES(0xa00, trap_0a)
529         STD_EXCEPTION_PSERIES(0xb00, trap_0b)
530
531         . = 0xc00
532         .globl  system_call_pSeries
533 system_call_pSeries:
534         HMT_MEDIUM
535         mr      r9,r13
536         mfmsr   r10
537         mfspr   r13,SPRN_SPRG3
538         mfspr   r11,SPRN_SRR0
539         clrrdi  r12,r13,32
540         oris    r12,r12,system_call_common@h
541         ori     r12,r12,system_call_common@l
542         mtspr   SPRN_SRR0,r12
543         ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
544         mfspr   r12,SPRN_SRR1
545         mtspr   SPRN_SRR1,r10
546         rfid
547         b       .       /* prevent speculative execution */
548
549         STD_EXCEPTION_PSERIES(0xd00, single_step)
550         STD_EXCEPTION_PSERIES(0xe00, trap_0e)
551
552         /* We need to deal with the Altivec unavailable exception
553          * here which is at 0xf20, thus in the middle of the
554          * prolog code of the PerformanceMonitor one. A little
555          * trickery is thus necessary
556          */
557         . = 0xf00
558         b       performance_monitor_pSeries
559
560         STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
561
562 #ifdef CONFIG_CBE_RAS
563         HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error)
564 #endif /* CONFIG_CBE_RAS */
565         STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
566 #ifdef CONFIG_CBE_RAS
567         HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance)
568 #endif /* CONFIG_CBE_RAS */
569         STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
570 #ifdef CONFIG_CBE_RAS
571         HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal)
572 #endif /* CONFIG_CBE_RAS */
573
574         . = 0x3000
575
576 /*** pSeries interrupt support ***/
577
578         /* moved from 0xf00 */
579         STD_EXCEPTION_PSERIES(., performance_monitor)
580
581         .align  7
582 _GLOBAL(do_stab_bolted_pSeries)
583         mtcrf   0x80,r12
584         mfspr   r12,SPRN_SPRG2
585         EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
586
587 /*
588  * We have some room here  we use that to put
589  * the peries slb miss user trampoline code so it's reasonably
590  * away from slb_miss_user_common to avoid problems with rfid
591  *
592  * This is used for when the SLB miss handler has to go virtual,
593  * which doesn't happen for now anymore but will once we re-implement
594  * dynamic VSIDs for shared page tables
595  */
596 #ifdef __DISABLED__
597 slb_miss_user_pseries:
598         std     r10,PACA_EXGEN+EX_R10(r13)
599         std     r11,PACA_EXGEN+EX_R11(r13)
600         std     r12,PACA_EXGEN+EX_R12(r13)
601         mfspr   r10,SPRG1
602         ld      r11,PACA_EXSLB+EX_R9(r13)
603         ld      r12,PACA_EXSLB+EX_R3(r13)
604         std     r10,PACA_EXGEN+EX_R13(r13)
605         std     r11,PACA_EXGEN+EX_R9(r13)
606         std     r12,PACA_EXGEN+EX_R3(r13)
607         clrrdi  r12,r13,32
608         mfmsr   r10
609         mfspr   r11,SRR0                        /* save SRR0 */
610         ori     r12,r12,slb_miss_user_common@l  /* virt addr of handler */
611         ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
612         mtspr   SRR0,r12
613         mfspr   r12,SRR1                        /* and SRR1 */
614         mtspr   SRR1,r10
615         rfid
616         b       .                               /* prevent spec. execution */
617 #endif /* __DISABLED__ */
618
619 /*
620  * Vectors for the FWNMI option.  Share common code.
621  */
622         .globl system_reset_fwnmi
623       .align 7
624 system_reset_fwnmi:
625         HMT_MEDIUM
626         mtspr   SPRN_SPRG1,r13          /* save r13 */
627         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
628
629         .globl machine_check_fwnmi
630       .align 7
631 machine_check_fwnmi:
632         HMT_MEDIUM
633         mtspr   SPRN_SPRG1,r13          /* save r13 */
634         EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
635
636 #ifdef CONFIG_PPC_ISERIES
637 /***  ISeries-LPAR interrupt handlers ***/
638
639         STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
640
641         .globl data_access_iSeries
642 data_access_iSeries:
643         mtspr   SPRN_SPRG1,r13
644 BEGIN_FTR_SECTION
645         mtspr   SPRN_SPRG2,r12
646         mfspr   r13,SPRN_DAR
647         mfspr   r12,SPRN_DSISR
648         srdi    r13,r13,60
649         rlwimi  r13,r12,16,0x20
650         mfcr    r12
651         cmpwi   r13,0x2c
652         beq     .do_stab_bolted_iSeries
653         mtcrf   0x80,r12
654         mfspr   r12,SPRN_SPRG2
655 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
656         EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
657         EXCEPTION_PROLOG_ISERIES_2
658         b       data_access_common
659
660 .do_stab_bolted_iSeries:
661         mtcrf   0x80,r12
662         mfspr   r12,SPRN_SPRG2
663         EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
664         EXCEPTION_PROLOG_ISERIES_2
665         b       .do_stab_bolted
666
667         .globl  data_access_slb_iSeries
668 data_access_slb_iSeries:
669         mtspr   SPRN_SPRG1,r13          /* save r13 */
670         mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
671         std     r3,PACA_EXSLB+EX_R3(r13)
672         mfspr   r3,SPRN_DAR
673         std     r9,PACA_EXSLB+EX_R9(r13)
674         mfcr    r9
675 #ifdef __DISABLED__
676         cmpdi   r3,0
677         bge     slb_miss_user_iseries
678 #endif
679         std     r10,PACA_EXSLB+EX_R10(r13)
680         std     r11,PACA_EXSLB+EX_R11(r13)
681         std     r12,PACA_EXSLB+EX_R12(r13)
682         mfspr   r10,SPRN_SPRG1
683         std     r10,PACA_EXSLB+EX_R13(r13)
684         ld      r12,PACALPPACAPTR(r13)
685         ld      r12,LPPACASRR1(r12)
686         b       .slb_miss_realmode
687
688         STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
689
690         .globl  instruction_access_slb_iSeries
691 instruction_access_slb_iSeries:
692         mtspr   SPRN_SPRG1,r13          /* save r13 */
693         mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
694         std     r3,PACA_EXSLB+EX_R3(r13)
695         ld      r3,PACALPPACAPTR(r13)
696         ld      r3,LPPACASRR0(r3)       /* get SRR0 value */
697         std     r9,PACA_EXSLB+EX_R9(r13)
698         mfcr    r9
699 #ifdef __DISABLED__
700         cmpdi   r3,0
701         bge     .slb_miss_user_iseries
702 #endif
703         std     r10,PACA_EXSLB+EX_R10(r13)
704         std     r11,PACA_EXSLB+EX_R11(r13)
705         std     r12,PACA_EXSLB+EX_R12(r13)
706         mfspr   r10,SPRN_SPRG1
707         std     r10,PACA_EXSLB+EX_R13(r13)
708         ld      r12,PACALPPACAPTR(r13)
709         ld      r12,LPPACASRR1(r12)
710         b       .slb_miss_realmode
711
712 #ifdef __DISABLED__
713 slb_miss_user_iseries:
714         std     r10,PACA_EXGEN+EX_R10(r13)
715         std     r11,PACA_EXGEN+EX_R11(r13)
716         std     r12,PACA_EXGEN+EX_R12(r13)
717         mfspr   r10,SPRG1
718         ld      r11,PACA_EXSLB+EX_R9(r13)
719         ld      r12,PACA_EXSLB+EX_R3(r13)
720         std     r10,PACA_EXGEN+EX_R13(r13)
721         std     r11,PACA_EXGEN+EX_R9(r13)
722         std     r12,PACA_EXGEN+EX_R3(r13)
723         EXCEPTION_PROLOG_ISERIES_2
724         b       slb_miss_user_common
725 #endif
726
727         MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
728         STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
729         STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
730         STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
731         MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
732         STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
733         STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
734
735         .globl  system_call_iSeries
736 system_call_iSeries:
737         mr      r9,r13
738         mfspr   r13,SPRN_SPRG3
739         EXCEPTION_PROLOG_ISERIES_2
740         b       system_call_common
741
742         STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
743         STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
744         STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
745
746         .globl system_reset_iSeries
747 system_reset_iSeries:
748         mfspr   r13,SPRN_SPRG3          /* Get paca address */
749         mfmsr   r24
750         ori     r24,r24,MSR_RI
751         mtmsrd  r24                     /* RI on */
752         lhz     r24,PACAPACAINDEX(r13)  /* Get processor # */
753         cmpwi   0,r24,0                 /* Are we processor 0? */
754         beq     .__start_initialization_iSeries /* Start up the first processor */
755         mfspr   r4,SPRN_CTRLF
756         li      r5,CTRL_RUNLATCH        /* Turn off the run light */
757         andc    r4,r4,r5
758         mtspr   SPRN_CTRLT,r4
759
760 1:
761         HMT_LOW
762 #ifdef CONFIG_SMP
763         lbz     r23,PACAPROCSTART(r13)  /* Test if this processor
764                                          * should start */
765         sync
766         LOAD_REG_IMMEDIATE(r3,current_set)
767         sldi    r28,r24,3               /* get current_set[cpu#] */
768         ldx     r3,r3,r28
769         addi    r1,r3,THREAD_SIZE
770         subi    r1,r1,STACK_FRAME_OVERHEAD
771
772         cmpwi   0,r23,0
773         beq     iSeries_secondary_smp_loop      /* Loop until told to go */
774         bne     .__secondary_start              /* Loop until told to go */
775 iSeries_secondary_smp_loop:
776         /* Let the Hypervisor know we are alive */
777         /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
778         lis     r3,0x8002
779         rldicr  r3,r3,32,15             /* r0 = (r3 << 32) & 0xffff000000000000 */
780 #else /* CONFIG_SMP */
781         /* Yield the processor.  This is required for non-SMP kernels
782                 which are running on multi-threaded machines. */
783         lis     r3,0x8000
784         rldicr  r3,r3,32,15             /* r3 = (r3 << 32) & 0xffff000000000000 */
785         addi    r3,r3,18                /* r3 = 0x8000000000000012 which is "yield" */
786         li      r4,0                    /* "yield timed" */
787         li      r5,-1                   /* "yield forever" */
788 #endif /* CONFIG_SMP */
789         li      r0,-1                   /* r0=-1 indicates a Hypervisor call */
790         sc                              /* Invoke the hypervisor via a system call */
791         mfspr   r13,SPRN_SPRG3          /* Put r13 back ???? */
792         b       1b                      /* If SMP not configured, secondaries
793                                          * loop forever */
794
795         .globl decrementer_iSeries_masked
796 decrementer_iSeries_masked:
797         /* We may not have a valid TOC pointer in here. */
798         li      r11,1
799         ld      r12,PACALPPACAPTR(r13)
800         stb     r11,LPPACADECRINT(r12)
801         LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy)
802         lwz     r12,0(r12)
803         mtspr   SPRN_DEC,r12
804         /* fall through */
805
806         .globl hardware_interrupt_iSeries_masked
807 hardware_interrupt_iSeries_masked:
808         mtcrf   0x80,r9         /* Restore regs */
809         ld      r12,PACALPPACAPTR(r13)
810         ld      r11,LPPACASRR0(r12)
811         ld      r12,LPPACASRR1(r12)
812         mtspr   SPRN_SRR0,r11
813         mtspr   SPRN_SRR1,r12
814         ld      r9,PACA_EXGEN+EX_R9(r13)
815         ld      r10,PACA_EXGEN+EX_R10(r13)
816         ld      r11,PACA_EXGEN+EX_R11(r13)
817         ld      r12,PACA_EXGEN+EX_R12(r13)
818         ld      r13,PACA_EXGEN+EX_R13(r13)
819         rfid
820         b       .       /* prevent speculative execution */
821 #endif /* CONFIG_PPC_ISERIES */
822
823 /*** Common interrupt handlers ***/
824
825         STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
826
827         /*
828          * Machine check is different because we use a different
829          * save area: PACA_EXMC instead of PACA_EXGEN.
830          */
831         .align  7
832         .globl machine_check_common
833 machine_check_common:
834         EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
835         FINISH_NAP
836         DISABLE_INTS
837         bl      .save_nvgprs
838         addi    r3,r1,STACK_FRAME_OVERHEAD
839         bl      .machine_check_exception
840         b       .ret_from_except
841
842         STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
843         STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
844         STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
845         STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
846         STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
847         STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
848         STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
849 #ifdef CONFIG_ALTIVEC
850         STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
851 #else
852         STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
853 #endif
854 #ifdef CONFIG_CBE_RAS
855         STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception)
856         STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception)
857         STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
858 #endif /* CONFIG_CBE_RAS */
859
860 /*
861  * Here we have detected that the kernel stack pointer is bad.
862  * R9 contains the saved CR, r13 points to the paca,
863  * r10 contains the (bad) kernel stack pointer,
864  * r11 and r12 contain the saved SRR0 and SRR1.
865  * We switch to using an emergency stack, save the registers there,
866  * and call kernel_bad_stack(), which panics.
867  */
868 bad_stack:
869         ld      r1,PACAEMERGSP(r13)
870         subi    r1,r1,64+INT_FRAME_SIZE
871         std     r9,_CCR(r1)
872         std     r10,GPR1(r1)
873         std     r11,_NIP(r1)
874         std     r12,_MSR(r1)
875         mfspr   r11,SPRN_DAR
876         mfspr   r12,SPRN_DSISR
877         std     r11,_DAR(r1)
878         std     r12,_DSISR(r1)
879         mflr    r10
880         mfctr   r11
881         mfxer   r12
882         std     r10,_LINK(r1)
883         std     r11,_CTR(r1)
884         std     r12,_XER(r1)
885         SAVE_GPR(0,r1)
886         SAVE_GPR(2,r1)
887         SAVE_4GPRS(3,r1)
888         SAVE_2GPRS(7,r1)
889         SAVE_10GPRS(12,r1)
890         SAVE_10GPRS(22,r1)
891         addi    r11,r1,INT_FRAME_SIZE
892         std     r11,0(r1)
893         li      r12,0
894         std     r12,0(r11)
895         ld      r2,PACATOC(r13)
896 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
897         bl      .kernel_bad_stack
898         b       1b
899
900 /*
901  * Return from an exception with minimal checks.
902  * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
903  * If interrupts have been enabled, or anything has been
904  * done that might have changed the scheduling status of
905  * any task or sent any task a signal, you should use
906  * ret_from_except or ret_from_except_lite instead of this.
907  */
908         .globl  fast_exception_return
909 fast_exception_return:
910         ld      r12,_MSR(r1)
911         ld      r11,_NIP(r1)
912         andi.   r3,r12,MSR_RI           /* check if RI is set */
913         beq-    unrecov_fer
914
915 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
916         andi.   r3,r12,MSR_PR
917         beq     2f
918         ACCOUNT_CPU_USER_EXIT(r3, r4)
919 2:
920 #endif
921
922         ld      r3,_CCR(r1)
923         ld      r4,_LINK(r1)
924         ld      r5,_CTR(r1)
925         ld      r6,_XER(r1)
926         mtcr    r3
927         mtlr    r4
928         mtctr   r5
929         mtxer   r6
930         REST_GPR(0, r1)
931         REST_8GPRS(2, r1)
932
933         mfmsr   r10
934         clrrdi  r10,r10,2               /* clear RI (LE is 0 already) */
935         mtmsrd  r10,1
936
937         mtspr   SPRN_SRR1,r12
938         mtspr   SPRN_SRR0,r11
939         REST_4GPRS(10, r1)
940         ld      r1,GPR1(r1)
941         rfid
942         b       .       /* prevent speculative execution */
943
944 unrecov_fer:
945         bl      .save_nvgprs
946 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
947         bl      .unrecoverable_exception
948         b       1b
949
950 /*
951  * Here r13 points to the paca, r9 contains the saved CR,
952  * SRR0 and SRR1 are saved in r11 and r12,
953  * r9 - r13 are saved in paca->exgen.
954  */
955         .align  7
956         .globl data_access_common
957 data_access_common:
958         mfspr   r10,SPRN_DAR
959         std     r10,PACA_EXGEN+EX_DAR(r13)
960         mfspr   r10,SPRN_DSISR
961         stw     r10,PACA_EXGEN+EX_DSISR(r13)
962         EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
963         ld      r3,PACA_EXGEN+EX_DAR(r13)
964         lwz     r4,PACA_EXGEN+EX_DSISR(r13)
965         li      r5,0x300
966         b       .do_hash_page           /* Try to handle as hpte fault */
967
968         .align  7
969         .globl instruction_access_common
970 instruction_access_common:
971         EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
972         ld      r3,_NIP(r1)
973         andis.  r4,r12,0x5820
974         li      r5,0x400
975         b       .do_hash_page           /* Try to handle as hpte fault */
976
977 /*
978  * Here is the common SLB miss user that is used when going to virtual
979  * mode for SLB misses, that is currently not used
980  */
981 #ifdef __DISABLED__
982         .align  7
983         .globl  slb_miss_user_common
984 slb_miss_user_common:
985         mflr    r10
986         std     r3,PACA_EXGEN+EX_DAR(r13)
987         stw     r9,PACA_EXGEN+EX_CCR(r13)
988         std     r10,PACA_EXGEN+EX_LR(r13)
989         std     r11,PACA_EXGEN+EX_SRR0(r13)
990         bl      .slb_allocate_user
991
992         ld      r10,PACA_EXGEN+EX_LR(r13)
993         ld      r3,PACA_EXGEN+EX_R3(r13)
994         lwz     r9,PACA_EXGEN+EX_CCR(r13)
995         ld      r11,PACA_EXGEN+EX_SRR0(r13)
996         mtlr    r10
997         beq-    slb_miss_fault
998
999         andi.   r10,r12,MSR_RI          /* check for unrecoverable exception */
1000         beq-    unrecov_user_slb
1001         mfmsr   r10
1002
1003 .machine push
1004 .machine "power4"
1005         mtcrf   0x80,r9
1006 .machine pop
1007
1008         clrrdi  r10,r10,2               /* clear RI before setting SRR0/1 */
1009         mtmsrd  r10,1
1010
1011         mtspr   SRR0,r11
1012         mtspr   SRR1,r12
1013
1014         ld      r9,PACA_EXGEN+EX_R9(r13)
1015         ld      r10,PACA_EXGEN+EX_R10(r13)
1016         ld      r11,PACA_EXGEN+EX_R11(r13)
1017         ld      r12,PACA_EXGEN+EX_R12(r13)
1018         ld      r13,PACA_EXGEN+EX_R13(r13)
1019         rfid
1020         b       .
1021
1022 slb_miss_fault:
1023         EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
1024         ld      r4,PACA_EXGEN+EX_DAR(r13)
1025         li      r5,0
1026         std     r4,_DAR(r1)
1027         std     r5,_DSISR(r1)
1028         b       .handle_page_fault
1029
1030 unrecov_user_slb:
1031         EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
1032         DISABLE_INTS
1033         bl      .save_nvgprs
1034 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
1035         bl      .unrecoverable_exception
1036         b       1b
1037
1038 #endif /* __DISABLED__ */
1039
1040
1041 /*
1042  * r13 points to the PACA, r9 contains the saved CR,
1043  * r12 contain the saved SRR1, SRR0 is still ready for return
1044  * r3 has the faulting address
1045  * r9 - r13 are saved in paca->exslb.
1046  * r3 is saved in paca->slb_r3
1047  * We assume we aren't going to take any exceptions during this procedure.
1048  */
1049 _GLOBAL(slb_miss_realmode)
1050         mflr    r10
1051
1052         stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
1053         std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
1054
1055         bl      .slb_allocate_realmode
1056
1057         /* All done -- return from exception. */
1058
1059         ld      r10,PACA_EXSLB+EX_LR(r13)
1060         ld      r3,PACA_EXSLB+EX_R3(r13)
1061         lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
1062 #ifdef CONFIG_PPC_ISERIES
1063         ld      r11,PACALPPACAPTR(r13)
1064         ld      r11,LPPACASRR0(r11)             /* get SRR0 value */
1065 #endif /* CONFIG_PPC_ISERIES */
1066
1067         mtlr    r10
1068
1069         andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
1070         beq-    unrecov_slb
1071
1072 .machine        push
1073 .machine        "power4"
1074         mtcrf   0x80,r9
1075         mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
1076 .machine        pop
1077
1078 #ifdef CONFIG_PPC_ISERIES
1079         mtspr   SPRN_SRR0,r11
1080         mtspr   SPRN_SRR1,r12
1081 #endif /* CONFIG_PPC_ISERIES */
1082         ld      r9,PACA_EXSLB+EX_R9(r13)
1083         ld      r10,PACA_EXSLB+EX_R10(r13)
1084         ld      r11,PACA_EXSLB+EX_R11(r13)
1085         ld      r12,PACA_EXSLB+EX_R12(r13)
1086         ld      r13,PACA_EXSLB+EX_R13(r13)
1087         rfid
1088         b       .       /* prevent speculative execution */
1089
1090 unrecov_slb:
1091         EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
1092         DISABLE_INTS
1093         bl      .save_nvgprs
1094 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
1095         bl      .unrecoverable_exception
1096         b       1b
1097
1098         .align  7
1099         .globl hardware_interrupt_common
1100         .globl hardware_interrupt_entry
1101 hardware_interrupt_common:
1102         EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
1103         FINISH_NAP
1104 hardware_interrupt_entry:
1105         DISABLE_INTS
1106         bl      .ppc64_runlatch_on
1107         addi    r3,r1,STACK_FRAME_OVERHEAD
1108         bl      .do_IRQ
1109         b       .ret_from_except_lite
1110
1111 #ifdef CONFIG_PPC_970_NAP
1112 power4_fixup_nap:
1113         andc    r9,r9,r10
1114         std     r9,TI_LOCAL_FLAGS(r11)
1115         ld      r10,_LINK(r1)           /* make idle task do the */
1116         std     r10,_NIP(r1)            /* equivalent of a blr */
1117         blr
1118 #endif
1119
1120         .align  7
1121         .globl alignment_common
1122 alignment_common:
1123         mfspr   r10,SPRN_DAR
1124         std     r10,PACA_EXGEN+EX_DAR(r13)
1125         mfspr   r10,SPRN_DSISR
1126         stw     r10,PACA_EXGEN+EX_DSISR(r13)
1127         EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
1128         ld      r3,PACA_EXGEN+EX_DAR(r13)
1129         lwz     r4,PACA_EXGEN+EX_DSISR(r13)
1130         std     r3,_DAR(r1)
1131         std     r4,_DSISR(r1)
1132         bl      .save_nvgprs
1133         addi    r3,r1,STACK_FRAME_OVERHEAD
1134         ENABLE_INTS
1135         bl      .alignment_exception
1136         b       .ret_from_except
1137
1138         .align  7
1139         .globl program_check_common
1140 program_check_common:
1141         EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
1142         bl      .save_nvgprs
1143         addi    r3,r1,STACK_FRAME_OVERHEAD
1144         ENABLE_INTS
1145         bl      .program_check_exception
1146         b       .ret_from_except
1147
1148         .align  7
1149         .globl fp_unavailable_common
1150 fp_unavailable_common:
1151         EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
1152         bne     .load_up_fpu            /* if from user, just load it up */
1153         bl      .save_nvgprs
1154         addi    r3,r1,STACK_FRAME_OVERHEAD
1155         ENABLE_INTS
1156         bl      .kernel_fp_unavailable_exception
1157         BUG_OPCODE
1158
1159         .align  7
1160         .globl altivec_unavailable_common
1161 altivec_unavailable_common:
1162         EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
1163 #ifdef CONFIG_ALTIVEC
1164 BEGIN_FTR_SECTION
1165         bne     .load_up_altivec        /* if from user, just load it up */
1166 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1167 #endif
1168         bl      .save_nvgprs
1169         addi    r3,r1,STACK_FRAME_OVERHEAD
1170         ENABLE_INTS
1171         bl      .altivec_unavailable_exception
1172         b       .ret_from_except
1173
1174 #ifdef CONFIG_ALTIVEC
1175 /*
1176  * load_up_altivec(unused, unused, tsk)
1177  * Disable VMX for the task which had it previously,
1178  * and save its vector registers in its thread_struct.
1179  * Enables the VMX for use in the kernel on return.
1180  * On SMP we know the VMX is free, since we give it up every
1181  * switch (ie, no lazy save of the vector registers).
1182  * On entry: r13 == 'current' && last_task_used_altivec != 'current'
1183  */
1184 _STATIC(load_up_altivec)
1185         mfmsr   r5                      /* grab the current MSR */
1186         oris    r5,r5,MSR_VEC@h
1187         mtmsrd  r5                      /* enable use of VMX now */
1188         isync
1189
1190 /*
1191  * For SMP, we don't do lazy VMX switching because it just gets too
1192  * horrendously complex, especially when a task switches from one CPU
1193  * to another.  Instead we call giveup_altvec in switch_to.
1194  * VRSAVE isn't dealt with here, that is done in the normal context
1195  * switch code. Note that we could rely on vrsave value to eventually
1196  * avoid saving all of the VREGs here...
1197  */
1198 #ifndef CONFIG_SMP
1199         ld      r3,last_task_used_altivec@got(r2)
1200         ld      r4,0(r3)
1201         cmpdi   0,r4,0
1202         beq     1f
1203         /* Save VMX state to last_task_used_altivec's THREAD struct */
1204         addi    r4,r4,THREAD
1205         SAVE_32VRS(0,r5,r4)
1206         mfvscr  vr0
1207         li      r10,THREAD_VSCR
1208         stvx    vr0,r10,r4
1209         /* Disable VMX for last_task_used_altivec */
1210         ld      r5,PT_REGS(r4)
1211         ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1212         lis     r6,MSR_VEC@h
1213         andc    r4,r4,r6
1214         std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1215 1:
1216 #endif /* CONFIG_SMP */
1217         /* Hack: if we get an altivec unavailable trap with VRSAVE
1218          * set to all zeros, we assume this is a broken application
1219          * that fails to set it properly, and thus we switch it to
1220          * all 1's
1221          */
1222         mfspr   r4,SPRN_VRSAVE
1223         cmpdi   0,r4,0
1224         bne+    1f
1225         li      r4,-1
1226         mtspr   SPRN_VRSAVE,r4
1227 1:
1228         /* enable use of VMX after return */
1229         ld      r4,PACACURRENT(r13)
1230         addi    r5,r4,THREAD            /* Get THREAD */
1231         oris    r12,r12,MSR_VEC@h
1232         std     r12,_MSR(r1)
1233         li      r4,1
1234         li      r10,THREAD_VSCR
1235         stw     r4,THREAD_USED_VR(r5)
1236         lvx     vr0,r10,r5
1237         mtvscr  vr0
1238         REST_32VRS(0,r4,r5)
1239 #ifndef CONFIG_SMP
1240         /* Update last_task_used_math to 'current' */
1241         subi    r4,r5,THREAD            /* Back to 'current' */
1242         std     r4,0(r3)
1243 #endif /* CONFIG_SMP */
1244         /* restore registers and return */
1245         b       fast_exception_return
1246 #endif /* CONFIG_ALTIVEC */
1247
1248 /*
1249  * Hash table stuff
1250  */
1251         .align  7
1252 _GLOBAL(do_hash_page)
1253         std     r3,_DAR(r1)
1254         std     r4,_DSISR(r1)
1255
1256         andis.  r0,r4,0xa450            /* weird error? */
1257         bne-    .handle_page_fault      /* if not, try to insert a HPTE */
1258 BEGIN_FTR_SECTION
1259         andis.  r0,r4,0x0020            /* Is it a segment table fault? */
1260         bne-    .do_ste_alloc           /* If so handle it */
1261 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
1262
1263         /*
1264          * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
1265          * accessing a userspace segment (even from the kernel). We assume
1266          * kernel addresses always have the high bit set.
1267          */
1268         rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
1269         rotldi  r0,r3,15                /* Move high bit into MSR_PR posn */
1270         orc     r0,r12,r0               /* MSR_PR | ~high_bit */
1271         rlwimi  r4,r0,32-13,30,30       /* becomes _PAGE_USER access bit */
1272         ori     r4,r4,1                 /* add _PAGE_PRESENT */
1273         rlwimi  r4,r5,22+2,31-2,31-2    /* Set _PAGE_EXEC if trap is 0x400 */
1274
1275         /*
1276          * On iSeries, we soft-disable interrupts here, then
1277          * hard-enable interrupts so that the hash_page code can spin on
1278          * the hash_table_lock without problems on a shared processor.
1279          */
1280         DISABLE_INTS
1281
1282         /*
1283          * r3 contains the faulting address
1284          * r4 contains the required access permissions
1285          * r5 contains the trap number
1286          *
1287          * at return r3 = 0 for success
1288          */
1289         bl      .hash_page              /* build HPTE if possible */
1290         cmpdi   r3,0                    /* see if hash_page succeeded */
1291
1292 #ifdef DO_SOFT_DISABLE
1293         /*
1294          * If we had interrupts soft-enabled at the point where the
1295          * DSI/ISI occurred, and an interrupt came in during hash_page,
1296          * handle it now.
1297          * We jump to ret_from_except_lite rather than fast_exception_return
1298          * because ret_from_except_lite will check for and handle pending
1299          * interrupts if necessary.
1300          */
1301         beq     .ret_from_except_lite
1302         /* For a hash failure, we don't bother re-enabling interrupts */
1303         ble-    12f
1304
1305         /*
1306          * hash_page couldn't handle it, set soft interrupt enable back
1307          * to what it was before the trap.  Note that .local_irq_restore
1308          * handles any interrupts pending at this point.
1309          */
1310         ld      r3,SOFTE(r1)
1311         bl      .local_irq_restore
1312         b       11f
1313 #else
1314         beq     fast_exception_return   /* Return from exception on success */
1315         ble-    12f                     /* Failure return from hash_page */
1316
1317         /* fall through */
1318 #endif
1319
1320 /* Here we have a page fault that hash_page can't handle. */
1321 _GLOBAL(handle_page_fault)
1322         ENABLE_INTS
1323 11:     ld      r4,_DAR(r1)
1324         ld      r5,_DSISR(r1)
1325         addi    r3,r1,STACK_FRAME_OVERHEAD
1326         bl      .do_page_fault
1327         cmpdi   r3,0
1328         beq+    .ret_from_except_lite
1329         bl      .save_nvgprs
1330         mr      r5,r3
1331         addi    r3,r1,STACK_FRAME_OVERHEAD
1332         lwz     r4,_DAR(r1)
1333         bl      .bad_page_fault
1334         b       .ret_from_except
1335
1336 /* We have a page fault that hash_page could handle but HV refused
1337  * the PTE insertion
1338  */
1339 12:     bl      .save_nvgprs
1340         addi    r3,r1,STACK_FRAME_OVERHEAD
1341         lwz     r4,_DAR(r1)
1342         bl      .low_hash_fault
1343         b       .ret_from_except
1344
1345         /* here we have a segment miss */
1346 _GLOBAL(do_ste_alloc)
1347         bl      .ste_allocate           /* try to insert stab entry */
1348         cmpdi   r3,0
1349         beq+    fast_exception_return
1350         b       .handle_page_fault
1351
1352 /*
1353  * r13 points to the PACA, r9 contains the saved CR,
1354  * r11 and r12 contain the saved SRR0 and SRR1.
1355  * r9 - r13 are saved in paca->exslb.
1356  * We assume we aren't going to take any exceptions during this procedure.
1357  * We assume (DAR >> 60) == 0xc.
1358  */
1359         .align  7
1360 _GLOBAL(do_stab_bolted)
1361         stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
1362         std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
1363
1364         /* Hash to the primary group */
1365         ld      r10,PACASTABVIRT(r13)
1366         mfspr   r11,SPRN_DAR
1367         srdi    r11,r11,28
1368         rldimi  r10,r11,7,52    /* r10 = first ste of the group */
1369
1370         /* Calculate VSID */
1371         /* This is a kernel address, so protovsid = ESID */
1372         ASM_VSID_SCRAMBLE(r11, r9)
1373         rldic   r9,r11,12,16    /* r9 = vsid << 12 */
1374
1375         /* Search the primary group for a free entry */
1376 1:      ld      r11,0(r10)      /* Test valid bit of the current ste    */
1377         andi.   r11,r11,0x80
1378         beq     2f
1379         addi    r10,r10,16
1380         andi.   r11,r10,0x70
1381         bne     1b
1382
1383         /* Stick for only searching the primary group for now.          */
1384         /* At least for now, we use a very simple random castout scheme */
1385         /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
1386         mftb    r11
1387         rldic   r11,r11,4,57    /* r11 = (r11 << 4) & 0x70 */
1388         ori     r11,r11,0x10
1389
1390         /* r10 currently points to an ste one past the group of interest */
1391         /* make it point to the randomly selected entry                 */
1392         subi    r10,r10,128
1393         or      r10,r10,r11     /* r10 is the entry to invalidate       */
1394
1395         isync                   /* mark the entry invalid               */
1396         ld      r11,0(r10)
1397         rldicl  r11,r11,56,1    /* clear the valid bit */
1398         rotldi  r11,r11,8
1399         std     r11,0(r10)
1400         sync
1401
1402         clrrdi  r11,r11,28      /* Get the esid part of the ste         */
1403         slbie   r11
1404
1405 2:      std     r9,8(r10)       /* Store the vsid part of the ste       */
1406         eieio
1407
1408         mfspr   r11,SPRN_DAR            /* Get the new esid                     */
1409         clrrdi  r11,r11,28      /* Permits a full 32b of ESID           */
1410         ori     r11,r11,0x90    /* Turn on valid and kp                 */
1411         std     r11,0(r10)      /* Put new entry back into the stab     */
1412
1413         sync
1414
1415         /* All done -- return from exception. */
1416         lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
1417         ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
1418
1419         andi.   r10,r12,MSR_RI
1420         beq-    unrecov_slb
1421
1422         mtcrf   0x80,r9                 /* restore CR */
1423
1424         mfmsr   r10
1425         clrrdi  r10,r10,2
1426         mtmsrd  r10,1
1427
1428         mtspr   SPRN_SRR0,r11
1429         mtspr   SPRN_SRR1,r12
1430         ld      r9,PACA_EXSLB+EX_R9(r13)
1431         ld      r10,PACA_EXSLB+EX_R10(r13)
1432         ld      r11,PACA_EXSLB+EX_R11(r13)
1433         ld      r12,PACA_EXSLB+EX_R12(r13)
1434         ld      r13,PACA_EXSLB+EX_R13(r13)
1435         rfid
1436         b       .       /* prevent speculative execution */
1437
1438 /*
1439  * Space for CPU0's segment table.
1440  *
1441  * On iSeries, the hypervisor must fill in at least one entry before
1442  * we get control (with relocate on).  The address is give to the hv
1443  * as a page number (see xLparMap in lpardata.c), so this must be at a
1444  * fixed address (the linker can't compute (u64)&initial_stab >>
1445  * PAGE_SHIFT).
1446  */
1447         . = STAB0_OFFSET        /* 0x6000 */
1448         .globl initial_stab
1449 initial_stab:
1450         .space  4096
1451
1452 /*
1453  * Data area reserved for FWNMI option.
1454  * This address (0x7000) is fixed by the RPA.
1455  */
1456         .= 0x7000
1457         .globl fwnmi_data_area
1458 fwnmi_data_area:
1459
1460         /* iSeries does not use the FWNMI stuff, so it is safe to put
1461          * this here, even if we later allow kernels that will boot on
1462          * both pSeries and iSeries */
1463 #ifdef CONFIG_PPC_ISERIES
1464         . = LPARMAP_PHYS
1465 #include "lparmap.s"
1466 /*
1467  * This ".text" is here for old compilers that generate a trailing
1468  * .note section when compiling .c files to .s
1469  */
1470         .text
1471 #endif /* CONFIG_PPC_ISERIES */
1472
1473         . = 0x8000
1474
1475 /*
1476  * On pSeries, secondary processors spin in the following code.
1477  * At entry, r3 = this processor's number (physical cpu id)
1478  */
1479 _GLOBAL(pSeries_secondary_smp_init)
1480         mr      r24,r3
1481         
1482         /* turn on 64-bit mode */
1483         bl      .enable_64b_mode
1484         isync
1485
1486         /* Copy some CPU settings from CPU 0 */
1487         bl      .__restore_cpu_setup
1488
1489         /* Set up a paca value for this processor. Since we have the
1490          * physical cpu id in r24, we need to search the pacas to find
1491          * which logical id maps to our physical one.
1492          */
1493         LOAD_REG_IMMEDIATE(r13, paca)   /* Get base vaddr of paca array  */
1494         li      r5,0                    /* logical cpu id                */
1495 1:      lhz     r6,PACAHWCPUID(r13)     /* Load HW procid from paca      */
1496         cmpw    r6,r24                  /* Compare to our id             */
1497         beq     2f
1498         addi    r13,r13,PACA_SIZE       /* Loop to next PACA on miss     */
1499         addi    r5,r5,1
1500         cmpwi   r5,NR_CPUS
1501         blt     1b
1502
1503         mr      r3,r24                  /* not found, copy phys to r3    */
1504         b       .kexec_wait             /* next kernel might do better   */
1505
1506 2:      mtspr   SPRN_SPRG3,r13          /* Save vaddr of paca in SPRG3   */
1507         /* From now on, r24 is expected to be logical cpuid */
1508         mr      r24,r5
1509 3:      HMT_LOW
1510         lbz     r23,PACAPROCSTART(r13)  /* Test if this processor should */
1511                                         /* start.                        */
1512         sync
1513
1514         /* Create a temp kernel stack for use before relocation is on.  */
1515         ld      r1,PACAEMERGSP(r13)
1516         subi    r1,r1,STACK_FRAME_OVERHEAD
1517
1518         cmpwi   0,r23,0
1519 #ifdef CONFIG_SMP
1520         bne     .__secondary_start
1521 #endif
1522         b       3b                      /* Loop until told to go         */
1523
1524 #ifdef CONFIG_PPC_ISERIES
1525 _STATIC(__start_initialization_iSeries)
1526         /* Clear out the BSS */
1527         LOAD_REG_IMMEDIATE(r11,__bss_stop)
1528         LOAD_REG_IMMEDIATE(r8,__bss_start)
1529         sub     r11,r11,r8              /* bss size                     */
1530         addi    r11,r11,7               /* round up to an even double word */
1531         rldicl. r11,r11,61,3            /* shift right by 3             */
1532         beq     4f
1533         addi    r8,r8,-8
1534         li      r0,0
1535         mtctr   r11                     /* zero this many doublewords   */
1536 3:      stdu    r0,8(r8)
1537         bdnz    3b
1538 4:
1539         LOAD_REG_IMMEDIATE(r1,init_thread_union)
1540         addi    r1,r1,THREAD_SIZE
1541         li      r0,0
1542         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
1543
1544         LOAD_REG_IMMEDIATE(r3,cpu_specs)
1545         LOAD_REG_IMMEDIATE(r4,cur_cpu_spec)
1546         li      r5,0
1547         bl      .identify_cpu
1548
1549         LOAD_REG_IMMEDIATE(r2,__toc_start)
1550         addi    r2,r2,0x4000
1551         addi    r2,r2,0x4000
1552
1553         bl      .iSeries_early_setup
1554         bl      .early_setup
1555
1556         /* relocation is on at this point */
1557
1558         b       .start_here_common
1559 #endif /* CONFIG_PPC_ISERIES */
1560
1561 #ifdef CONFIG_PPC_MULTIPLATFORM
1562
1563 _STATIC(__mmu_off)
1564         mfmsr   r3
1565         andi.   r0,r3,MSR_IR|MSR_DR
1566         beqlr
1567         andc    r3,r3,r0
1568         mtspr   SPRN_SRR0,r4
1569         mtspr   SPRN_SRR1,r3
1570         sync
1571         rfid
1572         b       .       /* prevent speculative execution */
1573
1574
1575 /*
1576  * Here is our main kernel entry point. We support currently 2 kind of entries
1577  * depending on the value of r5.
1578  *
1579  *   r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
1580  *                 in r3...r7
1581  *   
1582  *   r5 == NULL -> kexec style entry. r3 is a physical pointer to the
1583  *                 DT block, r4 is a physical pointer to the kernel itself
1584  *
1585  */
1586 _GLOBAL(__start_initialization_multiplatform)
1587 #ifdef CONFIG_PPC_MULTIPLATFORM
1588         /*
1589          * Are we booted from a PROM Of-type client-interface ?
1590          */
1591         cmpldi  cr0,r5,0
1592         bne     .__boot_from_prom               /* yes -> prom */
1593 #endif
1594
1595         /* Save parameters */
1596         mr      r31,r3
1597         mr      r30,r4
1598
1599         /* Make sure we are running in 64 bits mode */
1600         bl      .enable_64b_mode
1601
1602         /* Setup some critical 970 SPRs before switching MMU off */
1603         bl      .__970_cpu_preinit
1604
1605         /* cpu # */
1606         li      r24,0
1607
1608         /* Switch off MMU if not already */
1609         LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
1610         add     r4,r4,r30
1611         bl      .__mmu_off
1612         b       .__after_prom_start
1613
1614 #ifdef CONFIG_PPC_MULTIPLATFORM
1615 _STATIC(__boot_from_prom)
1616         /* Save parameters */
1617         mr      r31,r3
1618         mr      r30,r4
1619         mr      r29,r5
1620         mr      r28,r6
1621         mr      r27,r7
1622
1623         /*
1624          * Align the stack to 16-byte boundary
1625          * Depending on the size and layout of the ELF sections in the initial
1626          * boot binary, the stack pointer will be unalignet on PowerMac
1627          */
1628         rldicr  r1,r1,0,59
1629
1630         /* Make sure we are running in 64 bits mode */
1631         bl      .enable_64b_mode
1632
1633         /* put a relocation offset into r3 */
1634         bl      .reloc_offset
1635
1636         LOAD_REG_IMMEDIATE(r2,__toc_start)
1637         addi    r2,r2,0x4000
1638         addi    r2,r2,0x4000
1639
1640         /* Relocate the TOC from a virt addr to a real addr */
1641         add     r2,r2,r3
1642
1643         /* Restore parameters */
1644         mr      r3,r31
1645         mr      r4,r30
1646         mr      r5,r29
1647         mr      r6,r28
1648         mr      r7,r27
1649
1650         /* Do all of the interaction with OF client interface */
1651         bl      .prom_init
1652         /* We never return */
1653         trap
1654 #endif
1655
1656 /*
1657  * At this point, r3 contains the physical address we are running at,
1658  * returned by prom_init()
1659  */
1660 _STATIC(__after_prom_start)
1661
1662 /*
1663  * We need to run with __start at physical address PHYSICAL_START.
1664  * This will leave some code in the first 256B of
1665  * real memory, which are reserved for software use.
1666  * The remainder of the first page is loaded with the fixed
1667  * interrupt vectors.  The next two pages are filled with
1668  * unknown exception placeholders.
1669  *
1670  * Note: This process overwrites the OF exception vectors.
1671  *      r26 == relocation offset
1672  *      r27 == KERNELBASE
1673  */
1674         bl      .reloc_offset
1675         mr      r26,r3
1676         LOAD_REG_IMMEDIATE(r27, KERNELBASE)
1677
1678         LOAD_REG_IMMEDIATE(r3, PHYSICAL_START)  /* target addr */
1679
1680         // XXX FIXME: Use phys returned by OF (r30)
1681         add     r4,r27,r26              /* source addr                   */
1682                                         /* current address of _start     */
1683                                         /*   i.e. where we are running   */
1684                                         /*      the source addr          */
1685
1686         LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */
1687         sub     r5,r5,r27
1688
1689         li      r6,0x100                /* Start offset, the first 0x100 */
1690                                         /* bytes were copied earlier.    */
1691
1692         bl      .copy_and_flush         /* copy the first n bytes        */
1693                                         /* this includes the code being  */
1694                                         /* executed here.                */
1695
1696         LOAD_REG_IMMEDIATE(r0, 4f)      /* Jump to the copy of this code */
1697         mtctr   r0                      /* that we just made/relocated   */
1698         bctr
1699
1700 4:      LOAD_REG_IMMEDIATE(r5,klimit)
1701         add     r5,r5,r26
1702         ld      r5,0(r5)                /* get the value of klimit */
1703         sub     r5,r5,r27
1704         bl      .copy_and_flush         /* copy the rest */
1705         b       .start_here_multiplatform
1706
1707 #endif /* CONFIG_PPC_MULTIPLATFORM */
1708
1709 /*
1710  * Copy routine used to copy the kernel to start at physical address 0
1711  * and flush and invalidate the caches as needed.
1712  * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
1713  * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
1714  *
1715  * Note: this routine *only* clobbers r0, r6 and lr
1716  */
1717 _GLOBAL(copy_and_flush)
1718         addi    r5,r5,-8
1719         addi    r6,r6,-8
1720 4:      li      r0,16                   /* Use the least common         */
1721                                         /* denominator cache line       */
1722                                         /* size.  This results in       */
1723                                         /* extra cache line flushes     */
1724                                         /* but operation is correct.    */
1725                                         /* Can't get cache line size    */
1726                                         /* from NACA as it is being     */
1727                                         /* moved too.                   */
1728
1729         mtctr   r0                      /* put # words/line in ctr      */
1730 3:      addi    r6,r6,8                 /* copy a cache line            */
1731         ldx     r0,r6,r4
1732         stdx    r0,r6,r3
1733         bdnz    3b
1734         dcbst   r6,r3                   /* write it to memory           */
1735         sync
1736         icbi    r6,r3                   /* flush the icache line        */
1737         cmpld   0,r6,r5
1738         blt     4b
1739         sync
1740         addi    r5,r5,8
1741         addi    r6,r6,8
1742         blr
1743
1744 .align 8
1745 copy_to_here:
1746
1747 #ifdef CONFIG_SMP
1748 #ifdef CONFIG_PPC_PMAC
1749 /*
1750  * On PowerMac, secondary processors starts from the reset vector, which
1751  * is temporarily turned into a call to one of the functions below.
1752  */
1753         .section ".text";
1754         .align 2 ;
1755
1756         .globl  __secondary_start_pmac_0
1757 __secondary_start_pmac_0:
1758         /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
1759         li      r24,0
1760         b       1f
1761         li      r24,1
1762         b       1f
1763         li      r24,2
1764         b       1f
1765         li      r24,3
1766 1:
1767         
1768 _GLOBAL(pmac_secondary_start)
1769         /* turn on 64-bit mode */
1770         bl      .enable_64b_mode
1771         isync
1772
1773         /* Copy some CPU settings from CPU 0 */
1774         bl      .__restore_cpu_setup
1775
1776         /* pSeries do that early though I don't think we really need it */
1777         mfmsr   r3
1778         ori     r3,r3,MSR_RI
1779         mtmsrd  r3                      /* RI on */
1780
1781         /* Set up a paca value for this processor. */
1782         LOAD_REG_IMMEDIATE(r4, paca)    /* Get base vaddr of paca array */
1783         mulli   r13,r24,PACA_SIZE        /* Calculate vaddr of right paca */
1784         add     r13,r13,r4              /* for this processor.          */
1785         mtspr   SPRN_SPRG3,r13           /* Save vaddr of paca in SPRG3 */
1786
1787         /* Create a temp kernel stack for use before relocation is on.  */
1788         ld      r1,PACAEMERGSP(r13)
1789         subi    r1,r1,STACK_FRAME_OVERHEAD
1790
1791         b       .__secondary_start
1792
1793 #endif /* CONFIG_PPC_PMAC */
1794
1795 /*
1796  * This function is called after the master CPU has released the
1797  * secondary processors.  The execution environment is relocation off.
1798  * The paca for this processor has the following fields initialized at
1799  * this point:
1800  *   1. Processor number
1801  *   2. Segment table pointer (virtual address)
1802  * On entry the following are set:
1803  *   r1 = stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
1804  *   r24   = cpu# (in Linux terms)
1805  *   r13   = paca virtual address
1806  *   SPRG3 = paca virtual address
1807  */
1808 _GLOBAL(__secondary_start)
1809         /* Set thread priority to MEDIUM */
1810         HMT_MEDIUM
1811
1812         /* Load TOC */
1813         ld      r2,PACATOC(r13)
1814
1815         /* Do early setup for that CPU (stab, slb, hash table pointer) */
1816         bl      .early_setup_secondary
1817
1818         /* Initialize the kernel stack.  Just a repeat for iSeries.      */
1819         LOAD_REG_ADDR(r3, current_set)
1820         sldi    r28,r24,3               /* get current_set[cpu#]         */
1821         ldx     r1,r3,r28
1822         addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
1823         std     r1,PACAKSAVE(r13)
1824
1825         /* Clear backchain so we get nice backtraces */
1826         li      r7,0
1827         mtlr    r7
1828
1829         /* enable MMU and jump to start_secondary */
1830         LOAD_REG_ADDR(r3, .start_secondary_prolog)
1831         LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
1832 #ifdef DO_SOFT_DISABLE
1833         ori     r4,r4,MSR_EE
1834 #endif
1835         mtspr   SPRN_SRR0,r3
1836         mtspr   SPRN_SRR1,r4
1837         rfid
1838         b       .       /* prevent speculative execution */
1839
1840 /* 
1841  * Running with relocation on at this point.  All we want to do is
1842  * zero the stack back-chain pointer before going into C code.
1843  */
1844 _GLOBAL(start_secondary_prolog)
1845         li      r3,0
1846         std     r3,0(r1)                /* Zero the stack frame pointer */
1847         bl      .start_secondary
1848         b       .
1849 #endif
1850
1851 /*
1852  * This subroutine clobbers r11 and r12
1853  */
1854 _GLOBAL(enable_64b_mode)
1855         mfmsr   r11                     /* grab the current MSR */
1856         li      r12,1
1857         rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
1858         or      r11,r11,r12
1859         li      r12,1
1860         rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
1861         or      r11,r11,r12
1862         mtmsrd  r11
1863         isync
1864         blr
1865
1866 #ifdef CONFIG_PPC_MULTIPLATFORM
1867 /*
1868  * This is where the main kernel code starts.
1869  */
1870 _STATIC(start_here_multiplatform)
1871         /* get a new offset, now that the kernel has moved. */
1872         bl      .reloc_offset
1873         mr      r26,r3
1874
1875         /* Clear out the BSS. It may have been done in prom_init,
1876          * already but that's irrelevant since prom_init will soon
1877          * be detached from the kernel completely. Besides, we need
1878          * to clear it now for kexec-style entry.
1879          */
1880         LOAD_REG_IMMEDIATE(r11,__bss_stop)
1881         LOAD_REG_IMMEDIATE(r8,__bss_start)
1882         sub     r11,r11,r8              /* bss size                     */
1883         addi    r11,r11,7               /* round up to an even double word */
1884         rldicl. r11,r11,61,3            /* shift right by 3             */
1885         beq     4f
1886         addi    r8,r8,-8
1887         li      r0,0
1888         mtctr   r11                     /* zero this many doublewords   */
1889 3:      stdu    r0,8(r8)
1890         bdnz    3b
1891 4:
1892
1893         mfmsr   r6
1894         ori     r6,r6,MSR_RI
1895         mtmsrd  r6                      /* RI on */
1896
1897         /* The following gets the stack and TOC set up with the regs */
1898         /* pointing to the real addr of the kernel stack.  This is   */
1899         /* all done to support the C function call below which sets  */
1900         /* up the htab.  This is done because we have relocated the  */
1901         /* kernel but are still running in real mode. */
1902
1903         LOAD_REG_IMMEDIATE(r3,init_thread_union)
1904         add     r3,r3,r26
1905
1906         /* set up a stack pointer (physical address) */
1907         addi    r1,r3,THREAD_SIZE
1908         li      r0,0
1909         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
1910
1911         /* set up the TOC (physical address) */
1912         LOAD_REG_IMMEDIATE(r2,__toc_start)
1913         addi    r2,r2,0x4000
1914         addi    r2,r2,0x4000
1915         add     r2,r2,r26
1916
1917         LOAD_REG_IMMEDIATE(r3, cpu_specs)
1918         add     r3,r3,r26
1919         LOAD_REG_IMMEDIATE(r4,cur_cpu_spec)
1920         add     r4,r4,r26
1921         mr      r5,r26
1922         bl      .identify_cpu
1923
1924         /* Save some low level config HIDs of CPU0 to be copied to
1925          * other CPUs later on, or used for suspend/resume
1926          */
1927         bl      .__save_cpu_setup
1928         sync
1929
1930         /* Do very early kernel initializations, including initial hash table,
1931          * stab and slb setup before we turn on relocation.     */
1932
1933         /* Restore parameters passed from prom_init/kexec */
1934         mr      r3,r31
1935         bl      .early_setup
1936
1937         LOAD_REG_IMMEDIATE(r3, .start_here_common)
1938         LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
1939         mtspr   SPRN_SRR0,r3
1940         mtspr   SPRN_SRR1,r4
1941         rfid
1942         b       .       /* prevent speculative execution */
1943 #endif /* CONFIG_PPC_MULTIPLATFORM */
1944         
1945         /* This is where all platforms converge execution */
1946 _STATIC(start_here_common)
1947         /* relocation is on at this point */
1948
1949         /* The following code sets up the SP and TOC now that we are */
1950         /* running with translation enabled. */
1951
1952         LOAD_REG_IMMEDIATE(r3,init_thread_union)
1953
1954         /* set up the stack */
1955         addi    r1,r3,THREAD_SIZE
1956         li      r0,0
1957         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
1958
1959         /* Apply the CPUs-specific fixups (nop out sections not relevant
1960          * to this CPU
1961          */
1962         li      r3,0
1963         bl      .do_cpu_ftr_fixups
1964
1965         LOAD_REG_IMMEDIATE(r26, boot_cpuid)
1966         lwz     r26,0(r26)
1967
1968         LOAD_REG_IMMEDIATE(r24, paca)   /* Get base vaddr of paca array  */
1969         mulli   r13,r26,PACA_SIZE       /* Calculate vaddr of right paca */
1970         add     r13,r13,r24             /* for this processor.           */
1971         mtspr   SPRN_SPRG3,r13
1972
1973         /* ptr to current */
1974         LOAD_REG_IMMEDIATE(r4, init_task)
1975         std     r4,PACACURRENT(r13)
1976
1977         /* Load the TOC */
1978         ld      r2,PACATOC(r13)
1979         std     r1,PACAKSAVE(r13)
1980
1981         bl      .setup_system
1982
1983         /* Load up the kernel context */
1984 5:
1985 #ifdef DO_SOFT_DISABLE
1986         li      r5,0
1987         stb     r5,PACAPROCENABLED(r13) /* Soft Disabled */
1988         mfmsr   r5
1989         ori     r5,r5,MSR_EE            /* Hard Enabled */
1990         mtmsrd  r5
1991 #endif
1992
1993         bl .start_kernel
1994
1995         /* Not reached */
1996         BUG_OPCODE
1997
1998 /* Put the paca pointer into r13 and SPRG3 */
1999 _GLOBAL(setup_boot_paca)
2000         LOAD_REG_IMMEDIATE(r3, boot_cpuid)
2001         lwz     r3,0(r3)
2002         LOAD_REG_IMMEDIATE(r4, paca)    /* Get base vaddr of paca array  */
2003         mulli   r3,r3,PACA_SIZE         /* Calculate vaddr of right paca */
2004         add     r13,r3,r4               /* for this processor.           */
2005         mtspr   SPRN_SPRG3,r13
2006
2007         blr
2008
2009 /*
2010  * We put a few things here that have to be page-aligned.
2011  * This stuff goes at the beginning of the bss, which is page-aligned.
2012  */
2013         .section ".bss"
2014
2015         .align  PAGE_SHIFT
2016
2017         .globl  empty_zero_page
2018 empty_zero_page:
2019         .space  PAGE_SIZE
2020
2021         .globl  swapper_pg_dir
2022 swapper_pg_dir:
2023         .space  PAGE_SIZE
2024
2025 /*
2026  * This space gets a copy of optional info passed to us by the bootstrap
2027  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
2028  */
2029         .globl  cmd_line
2030 cmd_line:
2031         .space  COMMAND_LINE_SIZE