This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / ppc64 / kernel / head.S
1 /*
2  *  arch/ppc64/kernel/head.S
3  *
4  *  PowerPC version
5  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6  *
7  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
8  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
9  *  Adapted for Power Macintosh by Paul Mackerras.
10  *  Low-level exception handlers and MMU support
11  *  rewritten by Paul Mackerras.
12  *    Copyright (C) 1996 Paul Mackerras.
13  *
14  *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
15  *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
16  *
17  *  This file contains the low-level support and setup for the
18  *  PowerPC-64 platform, including trap and interrupt dispatch.
19  *
20  *  This program is free software; you can redistribute it and/or
21  *  modify it under the terms of the GNU General Public License
22  *  as published by the Free Software Foundation; either version
23  *  2 of the License, or (at your option) any later version.
24  */
25
26 #define SECONDARY_PROCESSORS
27
28 #include <linux/config.h>
29 #include <asm/processor.h>
30 #include <asm/page.h>
31 #include <asm/mmu.h>
32 #include <asm/naca.h>
33 #include <asm/systemcfg.h>
34 #include <asm/ppc_asm.h>
35 #include <asm/offsets.h>
36 #include <asm/bug.h>
37 #include <asm/cputable.h>
38 #include <asm/setup.h>
39
40 #ifdef CONFIG_PPC_ISERIES
41 #define DO_SOFT_DISABLE
42 #endif
43
44 /*
45  * hcall interface to pSeries LPAR
46  */
47 #define HVSC            .long 0x44000022
48 #define H_SET_ASR       0x30
49
50 /*
51  * We layout physical memory as follows:
52  * 0x0000 - 0x00ff : Secondary processor spin code
53  * 0x0100 - 0x2fff : pSeries Interrupt prologs
54  * 0x3000 - 0x3fff : Interrupt support
55  * 0x4000 - 0x4fff : NACA
56  * 0x5000 - 0x5fff : SystemCfg
57  * 0x6000          : iSeries and common interrupt prologs
58  * 0x9000 - 0x9fff : Initial segment table
59  */
60
61 /*
62  *   SPRG Usage
63  *
64  *   Register   Definition
65  *
66  *   SPRG0      reserved for hypervisor
67  *   SPRG1      temp - used to save gpr
68  *   SPRG2      temp - used to save gpr
69  *   SPRG3      virt addr of paca
70  */
71
72 /*
73  * Entering into this code we make the following assumptions:
74  *  For pSeries:
75  *   1. The MMU is off & open firmware is running in real mode.
76  *   2. The kernel is entered at __start
77  *
78  *  For iSeries:
79  *   1. The MMU is on (as it always is for iSeries)
80  *   2. The kernel is entered at SystemReset_Iseries
81  */
82
83         .text
84         .globl  _stext
85 _stext:
86 #ifdef CONFIG_PPC_PSERIES
87 _STATIC(__start)
88         /* NOP this out unconditionally */
89 BEGIN_FTR_SECTION
90         b .__start_initialization_pSeries
91 END_FTR_SECTION(0, 1)
92 #endif
93         /* Catch branch to 0 in real mode */
94         trap
95 #ifdef CONFIG_PPC_ISERIES
96         /*
97          * At offset 0x20, there is a pointer to iSeries LPAR data.
98          * This is required by the hypervisor
99          */
100         . = 0x20
101         .llong hvReleaseData-KERNELBASE
102
103         /*
104          * At offset 0x28 and 0x30 are offsets to the msChunks
105          * array (used by the iSeries LPAR debugger to do translation
106          * between physical addresses and absolute addresses) and
107          * to the pidhash table (also used by the debugger)
108          */
109         .llong msChunks-KERNELBASE
110         .llong 0        /* pidhash-KERNELBASE SFRXXX */
111
112         /* Offset 0x38 - Pointer to start of embedded System.map */
113         .globl  embedded_sysmap_start
114 embedded_sysmap_start:
115         .llong  0
116         /* Offset 0x40 - Pointer to end of embedded System.map */
117         .globl  embedded_sysmap_end
118 embedded_sysmap_end:
119         .llong  0
120 #else
121
122         /* Secondary processors spin on this value until it goes to 1. */
123         .globl  __secondary_hold_spinloop
124 __secondary_hold_spinloop:
125         .llong  0x0
126
127         /* Secondary processors write this value with their cpu # */
128         /* after they enter the spin loop immediately below.      */
129         .globl  __secondary_hold_acknowledge
130 __secondary_hold_acknowledge:
131         .llong  0x0
132
133         . = 0x60
134 /*
135  * The following code is used on pSeries to hold secondary processors
136  * in a spin loop after they have been freed from OpenFirmware, but
137  * before the bulk of the kernel has been relocated.  This code
138  * is relocated to physical address 0x60 before prom_init is run.
139  * All of it must fit below the first exception vector at 0x100.
140  */
141 _GLOBAL(__secondary_hold)
142         mfmsr   r24
143         ori     r24,r24,MSR_RI
144         mtmsrd  r24                     /* RI on */
145
146         /* Grab our linux cpu number */
147         mr      r24,r3
148
149         /* Tell the master cpu we're here */
150         /* Relocation is off & we are located at an address less */
151         /* than 0x100, so only need to grab low order offset.    */
152         std     r24,__secondary_hold_acknowledge@l(0)
153         sync
154
155         /* All secondary cpu's wait here until told to start. */
156 100:    ld      r4,__secondary_hold_spinloop@l(0)
157         cmpdi   0,r4,1
158         bne     100b
159
160 #ifdef CONFIG_HMT
161         b       .hmt_init
162 #else
163 #ifdef CONFIG_SMP
164         mr      r3,r24
165         b       .pseries_secondary_smp_init
166 #else
167         BUG_OPCODE
168 #endif
169 #endif
170 #endif
171
172 /* This value is used to mark exception frames on the stack. */
173         .section ".toc","aw"
174 exception_marker:
175         .tc     ID_72656773_68657265[TC],0x7265677368657265
176         .text
177
178 /*
179  * The following macros define the code that appears as
180  * the prologue to each of the exception handlers.  They
181  * are split into two parts to allow a single kernel binary
182  * to be used for pSeries and iSeries.
183  * LOL.  One day... - paulus
184  */
185
186 /*
187  * We make as much of the exception code common between native
188  * exception handlers (including pSeries LPAR) and iSeries LPAR
189  * implementations as possible.
190  */
191
192 /*
193  * This is the start of the interrupt handlers for pSeries
194  * This code runs with relocation off.
195  */
196 #define EX_R9           0
197 #define EX_R10          8
198 #define EX_R11          16
199 #define EX_R12          24
200 #define EX_R13          32
201 #define EX_SRR0         40
202 #define EX_DAR          48
203 #define EX_DSISR        56
204 #define EX_CCR          60
205
206 #define EXCEPTION_PROLOG_PSERIES(area, label)                           \
207         mfspr   r13,SPRG3;              /* get paca address into r13 */ \
208         std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
209         std     r10,area+EX_R10(r13);                                   \
210         std     r11,area+EX_R11(r13);                                   \
211         std     r12,area+EX_R12(r13);                                   \
212         mfspr   r9,SPRG1;                                               \
213         std     r9,area+EX_R13(r13);                                    \
214         mfcr    r9;                                                     \
215         clrrdi  r12,r13,32;             /* get high part of &label */   \
216         mfmsr   r10;                                                    \
217         mfspr   r11,SRR0;               /* save SRR0 */                 \
218         ori     r12,r12,(label)@l;      /* virt addr of handler */      \
219         ori     r10,r10,MSR_IR|MSR_DR|MSR_RI;                           \
220         mtspr   SRR0,r12;                                               \
221         mfspr   r12,SRR1;               /* and SRR1 */                  \
222         mtspr   SRR1,r10;                                               \
223         rfid
224
225 /*
226  * This is the start of the interrupt handlers for iSeries
227  * This code runs with relocation on.
228  */
229 #define EXCEPTION_PROLOG_ISERIES_1(area)                                \
230         mfspr   r13,SPRG3;              /* get paca address into r13 */ \
231         std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
232         std     r10,area+EX_R10(r13);                                   \
233         std     r11,area+EX_R11(r13);                                   \
234         std     r12,area+EX_R12(r13);                                   \
235         mfspr   r9,SPRG1;                                               \
236         std     r9,area+EX_R13(r13);                                    \
237         mfcr    r9
238
239 #define EXCEPTION_PROLOG_ISERIES_2                                      \
240         mfmsr   r10;                                                    \
241         ld      r11,PACALPPACA+LPPACASRR0(r13);                         \
242         ld      r12,PACALPPACA+LPPACASRR1(r13);                         \
243         ori     r10,r10,MSR_RI;                                         \
244         mtmsrd  r10,1
245
246 /*
247  * The common exception prolog is used for all except a few exceptions
248  * such as a segment miss on a kernel address.  We have to be prepared
249  * to take another exception from the point where we first touch the
250  * kernel stack onwards.
251  *
252  * On entry r13 points to the paca, r9-r13 are saved in the paca,
253  * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
254  * SRR1, and relocation is on.
255  */
256 #define EXCEPTION_PROLOG_COMMON(n, area)                                   \
257         andi.   r10,r12,MSR_PR;         /* See if coming from user      */ \
258         mr      r10,r1;                 /* Save r1                      */ \
259         subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack  */ \
260         beq-    1f;                                                        \
261         ld      r1,PACAKSAVE(r13);      /* kernel stack to use          */ \
262 1:      cmpdi   cr1,r1,0;               /* check if r1 is in userspace  */ \
263         bge-    cr1,bad_stack;          /* abort if it is               */ \
264         std     r9,_CCR(r1);            /* save CR in stackframe        */ \
265         std     r11,_NIP(r1);           /* save SRR0 in stackframe      */ \
266         std     r12,_MSR(r1);           /* save SRR1 in stackframe      */ \
267         std     r10,0(r1);              /* make stack chain pointer     */ \
268         std     r0,GPR0(r1);            /* save r0 in stackframe        */ \
269         std     r10,GPR1(r1);           /* save r1 in stackframe        */ \
270         std     r2,GPR2(r1);            /* save r2 in stackframe        */ \
271         SAVE_4GPRS(3, r1);              /* save r3 - r6 in stackframe   */ \
272         SAVE_2GPRS(7, r1);              /* save r7, r8 in stackframe    */ \
273         ld      r9,area+EX_R9(r13);     /* move r9, r10 to stackframe   */ \
274         ld      r10,area+EX_R10(r13);                                      \
275         std     r9,GPR9(r1);                                               \
276         std     r10,GPR10(r1);                                             \
277         ld      r9,area+EX_R11(r13);    /* move r11 - r13 to stackframe */ \
278         ld      r10,area+EX_R12(r13);                                      \
279         ld      r11,area+EX_R13(r13);                                      \
280         std     r9,GPR11(r1);                                              \
281         std     r10,GPR12(r1);                                             \
282         std     r11,GPR13(r1);                                             \
283         ld      r2,PACATOC(r13);        /* get kernel TOC into r2       */ \
284         mflr    r9;                     /* save LR in stackframe        */ \
285         std     r9,_LINK(r1);                                              \
286         mfctr   r10;                    /* save CTR in stackframe       */ \
287         std     r10,_CTR(r1);                                              \
288         mfspr   r11,XER;                /* save XER in stackframe       */ \
289         std     r11,_XER(r1);                                              \
290         li      r9,(n)+1;                                                  \
291         std     r9,_TRAP(r1);           /* set trap number              */ \
292         li      r10,0;                                                     \
293         ld      r11,exception_marker@toc(r2);                              \
294         std     r10,RESULT(r1);         /* clear regs->result           */ \
295         std     r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame      */
296
297 /*
298  * Exception vectors.
299  */
300 #define STD_EXCEPTION_PSERIES(n, label)                 \
301         . = n;                                          \
302         .globl label##_Pseries;                         \
303 label##_Pseries:                                        \
304         mtspr   SPRG1,r13;              /* save r13 */  \
305         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
306
307 #define STD_EXCEPTION_ISERIES(n, label, area)           \
308         .globl label##_Iseries;                         \
309 label##_Iseries:                                        \
310         mtspr   SPRG1,r13;              /* save r13 */  \
311         EXCEPTION_PROLOG_ISERIES_1(area);               \
312         EXCEPTION_PROLOG_ISERIES_2;                     \
313         b       label##_common
314
315 #define MASKABLE_EXCEPTION_ISERIES(n, label)                            \
316         .globl label##_Iseries;                                         \
317 label##_Iseries:                                                        \
318         mtspr   SPRG1,r13;              /* save r13 */                  \
319         EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);                         \
320         lbz     r10,PACAPROFENABLED(r13);                               \
321         cmpwi   r10,0;                                                  \
322         bne-    label##_Iseries_profile;                                \
323 label##_Iseries_prof_ret:                                               \
324         lbz     r10,PACAPROCENABLED(r13);                               \
325         cmpwi   0,r10,0;                                                \
326         beq-    label##_Iseries_masked;                                 \
327         EXCEPTION_PROLOG_ISERIES_2;                                     \
328         b       label##_common;                                         \
329 label##_Iseries_profile:                                                \
330         ld      r12,PACALPPACA+LPPACASRR1(r13);                         \
331         andi.   r12,r12,MSR_PR;         /* Test if in kernel */         \
332         bne     label##_Iseries_prof_ret;                               \
333         ld      r11,PACALPPACA+LPPACASRR0(r13);                         \
334         ld      r12,PACAPROFSTEXT(r13); /* _stext */                    \
335         subf    r11,r12,r11;            /* offset into kernel */        \
336         lwz     r12,PACAPROFSHIFT(r13);                                 \
337         srd     r11,r11,r12;                                            \
338         lwz     r12,PACAPROFLEN(r13);   /* profile table length - 1 */  \
339         cmpd    r11,r12;                /* off end? */                  \
340         ble     1f;                                                     \
341         mr      r11,r12;                /* force into last entry */     \
342 1:      sldi    r11,r11,2;              /* convert to offset */         \
343         ld      r12,PACAPROFBUFFER(r13);/* profile buffer */            \
344         add     r12,r12,r11;                                            \
345 2:      lwarx   r11,0,r12;              /* atomically increment */      \
346         addi    r11,r11,1;                                              \
347         stwcx.  r11,0,r12;                                              \
348         bne-    2b;                                                     \
349         b       label##_Iseries_prof_ret
350
351 #ifdef DO_SOFT_DISABLE
352 #define DISABLE_INTS                            \
353         lbz     r10,PACAPROCENABLED(r13);       \
354         li      r11,0;                          \
355         std     r10,SOFTE(r1);                  \
356         mfmsr   r10;                            \
357         stb     r11,PACAPROCENABLED(r13);       \
358         ori     r10,r10,MSR_EE;                 \
359         mtmsrd  r10,1
360
361 #define ENABLE_INTS                             \
362         lbz     r10,PACAPROCENABLED(r13);       \
363         mfmsr   r11;                            \
364         std     r10,SOFTE(r1);                  \
365         ori     r11,r11,MSR_EE;                 \
366         mtmsrd  r11,1
367
368 #else   /* hard enable/disable interrupts */
369 #define DISABLE_INTS
370
371 #define ENABLE_INTS                             \
372         ld      r12,_MSR(r1);                   \
373         mfmsr   r11;                            \
374         rlwimi  r11,r12,0,MSR_EE;               \
375         mtmsrd  r11,1
376
377 #endif
378
379 #define STD_EXCEPTION_COMMON(trap, label, hdlr)         \
380         .align  7;                                      \
381         .globl label##_common;                          \
382 label##_common:                                         \
383         EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);      \
384         DISABLE_INTS;                                   \
385         bl      .save_nvgprs;                           \
386         addi    r3,r1,STACK_FRAME_OVERHEAD;             \
387         bl      hdlr;                                   \
388         b       .ret_from_except
389
390 #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr)    \
391         .align  7;                                      \
392         .globl label##_common;                          \
393 label##_common:                                         \
394         EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);      \
395         DISABLE_INTS;                                   \
396         addi    r3,r1,STACK_FRAME_OVERHEAD;             \
397         bl      hdlr;                                   \
398         b       .ret_from_except_lite
399
400 /*
401  * Start of pSeries system interrupt routines
402  */
403         . = 0x100
404         .globl __start_interrupts
405 __start_interrupts:
406
407         STD_EXCEPTION_PSERIES(0x100, SystemReset)
408
409         . = 0x200
410 _MachineCheckPseries:
411         mtspr   SPRG1,r13               /* save r13 */
412         EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
413
414         . = 0x300
415         .globl DataAccess_Pseries
416 DataAccess_Pseries:
417         mtspr   SPRG1,r13
418 BEGIN_FTR_SECTION
419         mtspr   SPRG2,r12
420         mfspr   r13,DAR
421         mfspr   r12,DSISR
422         srdi    r13,r13,60
423         rlwimi  r13,r12,16,0x20
424         mfcr    r12
425         cmpwi   r13,0x2c
426         beq     .do_stab_bolted_Pseries
427         mtcrf   0x80,r12
428         mfspr   r12,SPRG2
429 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
430         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccess_common)
431
432         . = 0x380
433         .globl DataAccessSLB_Pseries
434 DataAccessSLB_Pseries:
435         mtspr   SPRG1,r13
436         mtspr   SPRG2,r12
437         mfspr   r13,DAR
438         mfcr    r12
439         srdi    r13,r13,60
440         cmpdi   r13,0xc
441         beq     .do_slb_bolted_Pseries
442         mtcrf   0x80,r12
443         mfspr   r12,SPRG2
444         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccessSLB_common)
445
446         STD_EXCEPTION_PSERIES(0x400, InstructionAccess)
447         STD_EXCEPTION_PSERIES(0x480, InstructionAccessSLB)
448         STD_EXCEPTION_PSERIES(0x500, HardwareInterrupt)
449         STD_EXCEPTION_PSERIES(0x600, Alignment)
450         STD_EXCEPTION_PSERIES(0x700, ProgramCheck)
451         STD_EXCEPTION_PSERIES(0x800, FPUnavailable)
452         STD_EXCEPTION_PSERIES(0x900, Decrementer)
453         STD_EXCEPTION_PSERIES(0xa00, Trap_0a)
454         STD_EXCEPTION_PSERIES(0xb00, Trap_0b)
455
456         . = 0xc00
457         .globl  SystemCall_Pseries
458 SystemCall_Pseries:
459         mr      r9,r13
460         mfmsr   r10
461         mfspr   r13,SPRG3
462         mfspr   r11,SRR0
463         clrrdi  r12,r13,32
464         oris    r12,r12,SystemCall_common@h
465         ori     r12,r12,SystemCall_common@l
466         mtspr   SRR0,r12
467         ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
468         mfspr   r12,SRR1
469         mtspr   SRR1,r10
470         rfid
471
472         STD_EXCEPTION_PSERIES(0xd00, SingleStep)
473         STD_EXCEPTION_PSERIES(0xe00, Trap_0e)
474
475         /* We need to deal with the Altivec unavailable exception
476          * here which is at 0xf20, thus in the middle of the
477          * prolog code of the PerformanceMonitor one. A little
478          * trickery is thus necessary
479          */
480         . = 0xf00
481         b       PerformanceMonitor_Pseries
482
483         STD_EXCEPTION_PSERIES(0xf20, AltivecUnavailable)
484
485         STD_EXCEPTION_PSERIES(0x1300, InstructionBreakpoint)
486         STD_EXCEPTION_PSERIES(0x1700, AltivecAssist)
487
488         /* moved from 0xf00 */
489         STD_EXCEPTION_PSERIES(0x3000, PerformanceMonitor)
490
491         . = 0x3100
492 _GLOBAL(do_stab_bolted_Pseries)
493         mtcrf   0x80,r12
494         mfspr   r12,SPRG2
495         EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
496
497 _GLOBAL(do_slb_bolted_Pseries)
498         mtcrf   0x80,r12
499         mfspr   r12,SPRG2
500         EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_slb_bolted)
501
502         
503         /* Space for the naca.  Architected to be located at real address
504          * NACA_PHYS_ADDR.  Various tools rely on this location being fixed.
505          * The first dword of the naca is required by iSeries LPAR to
506          * point to itVpdAreas.  On pSeries native, this value is not used.
507          */
508         . = NACA_PHYS_ADDR
509         .globl __end_interrupts
510         .globl __start_naca
511 __end_interrupts:
512 __start_naca:
513 #ifdef CONFIG_PPC_ISERIES
514         .llong itVpdAreas
515 #else
516         .llong 0x0
517 #endif
518         .llong 0x0
519         .llong 0x0
520         .llong paca
521
522         . = SYSTEMCFG_PHYS_ADDR
523         .globl __end_naca
524         .globl __start_systemcfg
525 __end_naca:
526 __start_systemcfg:
527         . = (SYSTEMCFG_PHYS_ADDR + PAGE_SIZE)
528         .globl __end_systemcfg
529 __end_systemcfg:
530
531 #ifdef CONFIG_PPC_ISERIES
532         /*
533          * The iSeries LPAR map is at this fixed address
534          * so that the HvReleaseData structure can address
535          * it with a 32-bit offset.
536          *
537          * The VSID values below are dependent on the
538          * VSID generation algorithm.  See include/asm/mmu_context.h.
539          */
540
541         .llong  1               /* # ESIDs to be mapped by hypervisor    */
542         .llong  1               /* # memory ranges to be mapped by hypervisor */
543         .llong  STAB0_PAGE      /* Page # of segment table within load area     */
544         .llong  0               /* Reserved */
545         .llong  0               /* Reserved */
546         .llong  0               /* Reserved */
547         .llong  0               /* Reserved */
548         .llong  0               /* Reserved */
549         .llong  0x0c00000000    /* ESID to map (Kernel at EA = 0xC000000000000000) */
550         .llong  0x06a99b4b14    /* VSID to map (Kernel at VA = 0x6a99b4b140000000) */
551         .llong  8192            /* # pages to map (32 MB) */
552         .llong  0               /* Offset from start of loadarea to start of map */
553         .llong  0x0006a99b4b140000      /* VPN of first page to map */
554
555         . = 0x6100
556
557 /***  ISeries-LPAR interrupt handlers ***/
558
559         STD_EXCEPTION_ISERIES(0x200, MachineCheck, PACA_EXMC)
560
561         .globl DataAccess_Iseries
562 DataAccess_Iseries:
563         mtspr   SPRG1,r13
564 BEGIN_FTR_SECTION
565         mtspr   SPRG2,r12
566         mfspr   r13,DAR
567         mfspr   r12,DSISR
568         srdi    r13,r13,60
569         rlwimi  r13,r12,16,0x20
570         mfcr    r12
571         cmpwi   r13,0x2c
572         beq     .do_stab_bolted_Iseries
573         mtcrf   0x80,r12
574         mfspr   r12,SPRG2
575 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
576         EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
577         EXCEPTION_PROLOG_ISERIES_2
578         b       DataAccess_common
579
580 .do_stab_bolted_Iseries:
581         mtcrf   0x80,r12
582         mfspr   r12,SPRG2
583         EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
584         EXCEPTION_PROLOG_ISERIES_2
585         b       .do_stab_bolted
586
587         .globl  DataAccessSLB_Iseries
588 DataAccessSLB_Iseries:
589         mtspr   SPRG1,r13               /* save r13 */
590         mtspr   SPRG2,r12
591         mfspr   r13,DAR
592         mfcr    r12
593         srdi    r13,r13,60
594         cmpdi   r13,0xc
595         beq     .do_slb_bolted_Iseries
596         mtcrf   0x80,r12
597         mfspr   r12,SPRG2
598         EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
599         EXCEPTION_PROLOG_ISERIES_2
600         b       DataAccessSLB_common
601
602 .do_slb_bolted_Iseries:
603         mtcrf   0x80,r12
604         mfspr   r12,SPRG2
605         EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
606         EXCEPTION_PROLOG_ISERIES_2
607         b       .do_slb_bolted
608
609         STD_EXCEPTION_ISERIES(0x400, InstructionAccess, PACA_EXGEN)
610         STD_EXCEPTION_ISERIES(0x480, InstructionAccessSLB, PACA_EXGEN)
611         MASKABLE_EXCEPTION_ISERIES(0x500, HardwareInterrupt)
612         STD_EXCEPTION_ISERIES(0x600, Alignment, PACA_EXGEN)
613         STD_EXCEPTION_ISERIES(0x700, ProgramCheck, PACA_EXGEN)
614         STD_EXCEPTION_ISERIES(0x800, FPUnavailable, PACA_EXGEN)
615         MASKABLE_EXCEPTION_ISERIES(0x900, Decrementer)
616         STD_EXCEPTION_ISERIES(0xa00, Trap_0a, PACA_EXGEN)
617         STD_EXCEPTION_ISERIES(0xb00, Trap_0b, PACA_EXGEN)
618
619         .globl  SystemCall_Iseries
620 SystemCall_Iseries:
621         mr      r9,r13
622         mfspr   r13,SPRG3
623         EXCEPTION_PROLOG_ISERIES_2
624         b       SystemCall_common
625
626         STD_EXCEPTION_ISERIES( 0xd00, SingleStep, PACA_EXGEN)
627         STD_EXCEPTION_ISERIES( 0xe00, Trap_0e, PACA_EXGEN)
628         STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor, PACA_EXGEN)
629
630         .globl SystemReset_Iseries
631 SystemReset_Iseries:
632         mfspr   r13,SPRG3               /* Get paca address */
633         mfmsr   r24
634         ori     r24,r24,MSR_RI
635         mtmsrd  r24                     /* RI on */
636         lhz     r24,PACAPACAINDEX(r13)  /* Get processor # */
637         cmpwi   0,r24,0                 /* Are we processor 0? */
638         beq     .__start_initialization_iSeries /* Start up the first processor */
639         mfspr   r4,CTRLF
640         li      r5,RUNLATCH             /* Turn off the run light */
641         andc    r4,r4,r5
642         mtspr   CTRLT,r4
643
644 1:
645         HMT_LOW
646 #ifdef CONFIG_SMP
647         lbz     r23,PACAPROCSTART(r13)  /* Test if this processor
648                                          * should start */
649         sync
650         LOADADDR(r3,current_set)
651         sldi    r28,r24,3               /* get current_set[cpu#] */
652         ldx     r3,r3,r28
653         addi    r1,r3,THREAD_SIZE
654         subi    r1,r1,STACK_FRAME_OVERHEAD
655
656         cmpwi   0,r23,0
657         beq     iseries_secondary_smp_loop      /* Loop until told to go */
658 #ifdef SECONDARY_PROCESSORS
659         bne     .__secondary_start              /* Loop until told to go */
660 #endif
661 iseries_secondary_smp_loop:
662         /* Let the Hypervisor know we are alive */
663         /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
664         lis     r3,0x8002
665         rldicr  r3,r3,32,15             /* r0 = (r3 << 32) & 0xffff000000000000 */
666 #else /* CONFIG_SMP */
667         /* Yield the processor.  This is required for non-SMP kernels
668                 which are running on multi-threaded machines. */
669         lis     r3,0x8000
670         rldicr  r3,r3,32,15             /* r3 = (r3 << 32) & 0xffff000000000000 */
671         addi    r3,r3,18                /* r3 = 0x8000000000000012 which is "yield" */
672         li      r4,0                    /* "yield timed" */
673         li      r5,-1                   /* "yield forever" */
674 #endif /* CONFIG_SMP */
675         li      r0,-1                   /* r0=-1 indicates a Hypervisor call */
676         sc                              /* Invoke the hypervisor via a system call */
677         mfspr   r13,SPRG3               /* Put r13 back ???? */
678         b       1b                      /* If SMP not configured, secondaries
679                                          * loop forever */
680
681         .globl Decrementer_Iseries_masked
682 Decrementer_Iseries_masked:
683         li      r11,1
684         stb     r11,PACALPPACA+LPPACADECRINT(r13)
685         lwz     r12,PACADEFAULTDECR(r13)
686         mtspr   DEC,r12
687         /* fall through */
688
689         .globl HardwareInterrupt_Iseries_masked
690 HardwareInterrupt_Iseries_masked:
691         mtcrf   0x80,r9         /* Restore regs */
692         ld      r11,PACALPPACA+LPPACASRR0(r13)
693         ld      r12,PACALPPACA+LPPACASRR1(r13)
694         mtspr   SRR0,r11
695         mtspr   SRR1,r12
696         ld      r9,PACA_EXGEN+EX_R9(r13)
697         ld      r10,PACA_EXGEN+EX_R10(r13)
698         ld      r11,PACA_EXGEN+EX_R11(r13)
699         ld      r12,PACA_EXGEN+EX_R12(r13)
700         ld      r13,PACA_EXGEN+EX_R13(r13)
701         rfid
702 #endif
703
704 /*
705  * Data area reserved for FWNMI option.
706  */
707         .= 0x7000
708         .globl fwnmi_data_area
709 fwnmi_data_area:
710
711 /*
712  * Vectors for the FWNMI option.  Share common code.
713  */
714         . = 0x8000
715         .globl SystemReset_FWNMI
716 SystemReset_FWNMI:
717         mtspr   SPRG1,r13               /* save r13 */
718         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, SystemReset_common)
719         .globl MachineCheck_FWNMI
720 MachineCheck_FWNMI:
721         mtspr   SPRG1,r13               /* save r13 */
722         EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
723
724         /*
725          * Space for the initial segment table
726          * For LPAR, the hypervisor must fill in at least one entry
727          * before we get control (with relocate on)
728          */
729         . = STAB0_PHYS_ADDR
730         .globl __start_stab
731 __start_stab:
732
733         . = (STAB0_PHYS_ADDR + PAGE_SIZE)
734         .globl __end_stab
735 __end_stab:
736
737
738 /*** Common interrupt handlers ***/
739
740         STD_EXCEPTION_COMMON(0x100, SystemReset, .SystemResetException)
741
742         /*
743          * Machine check is different because we use a different
744          * save area: PACA_EXMC instead of PACA_EXGEN.
745          */
746         .align  7
747         .globl MachineCheck_common
748 MachineCheck_common:
749         EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
750         DISABLE_INTS
751         bl      .save_nvgprs
752         addi    r3,r1,STACK_FRAME_OVERHEAD
753         bl      .MachineCheckException
754         b       .ret_from_except
755
756         STD_EXCEPTION_COMMON_LITE(0x900, Decrementer, .timer_interrupt)
757         STD_EXCEPTION_COMMON(0xa00, Trap_0a, .UnknownException)
758         STD_EXCEPTION_COMMON(0xb00, Trap_0b, .UnknownException)
759         STD_EXCEPTION_COMMON(0xd00, SingleStep, .SingleStepException)
760         STD_EXCEPTION_COMMON(0xe00, Trap_0e, .UnknownException)
761         STD_EXCEPTION_COMMON(0xf00, PerformanceMonitor, .PerformanceMonitorException)
762         STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException)
763 #ifdef CONFIG_ALTIVEC
764         STD_EXCEPTION_COMMON(0x1700, AltivecAssist, .AltivecAssistException)
765 #else
766         STD_EXCEPTION_COMMON(0x1700, AltivecAssist, .UnknownException)
767 #endif
768
769 /*
770  * Here we have detected that the kernel stack pointer is bad.
771  * R9 contains the saved CR, r13 points to the paca,
772  * r10 contains the (bad) kernel stack pointer,
773  * r11 and r12 contain the saved SRR0 and SRR1.
774  * We switch to using the paca guard page as an emergency stack,
775  * save the registers there, and call kernel_bad_stack(), which panics.
776  */
777 bad_stack:
778         ld      r1,PACAEMERGSP(r13)
779         subi    r1,r1,64+INT_FRAME_SIZE
780         std     r9,_CCR(r1)
781         std     r10,GPR1(r1)
782         std     r11,_NIP(r1)
783         std     r12,_MSR(r1)
784         mfspr   r11,DAR
785         mfspr   r12,DSISR
786         std     r11,_DAR(r1)
787         std     r12,_DSISR(r1)
788         mflr    r10
789         mfctr   r11
790         mfxer   r12
791         std     r10,_LINK(r1)
792         std     r11,_CTR(r1)
793         std     r12,_XER(r1)
794         SAVE_GPR(0,r1)
795         SAVE_GPR(2,r1)
796         SAVE_4GPRS(3,r1)
797         SAVE_2GPRS(7,r1)
798         SAVE_10GPRS(12,r1)
799         SAVE_10GPRS(22,r1)
800         addi    r11,r1,INT_FRAME_SIZE
801         std     r11,0(r1)
802         li      r12,0
803         std     r12,0(r11)
804         ld      r2,PACATOC(r13)
805 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
806         bl      .kernel_bad_stack
807         b       1b
808
809 /*
810  * Return from an exception with minimal checks.
811  * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
812  * If interrupts have been enabled, or anything has been
813  * done that might have changed the scheduling status of
814  * any task or sent any task a signal, you should use
815  * ret_from_except or ret_from_except_lite instead of this.
816  */
817 fast_exception_return:
818         ld      r12,_MSR(r1)
819         ld      r11,_NIP(r1)
820         andi.   r3,r12,MSR_RI           /* check if RI is set */
821         beq-    unrecov_fer
822         ld      r3,_CCR(r1)
823         ld      r4,_LINK(r1)
824         ld      r5,_CTR(r1)
825         ld      r6,_XER(r1)
826         mtcr    r3
827         mtlr    r4
828         mtctr   r5
829         mtxer   r6
830         REST_GPR(0, r1)
831         REST_8GPRS(2, r1)
832
833         mfmsr   r10
834         clrrdi  r10,r10,2               /* clear RI (LE is 0 already) */
835         mtmsrd  r10,1
836
837         mtspr   SRR1,r12
838         mtspr   SRR0,r11
839         REST_4GPRS(10, r1)
840         ld      r1,GPR1(r1)
841         rfid
842
843 unrecov_fer:
844         bl      .save_nvgprs
845 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
846         bl      .unrecoverable_exception
847         b       1b
848
849 /*
850  * Here r13 points to the paca, r9 contains the saved CR,
851  * SRR0 and SRR1 are saved in r11 and r12,
852  * r9 - r13 are saved in paca->exgen.
853  */
854         .align  7
855         .globl DataAccess_common
856 DataAccess_common:
857         mfspr   r10,DAR
858         std     r10,PACA_EXGEN+EX_DAR(r13)
859         mfspr   r10,DSISR
860         stw     r10,PACA_EXGEN+EX_DSISR(r13)
861         EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
862         ld      r3,PACA_EXGEN+EX_DAR(r13)
863         lwz     r4,PACA_EXGEN+EX_DSISR(r13)
864         li      r5,0x300
865         b       .do_hash_page           /* Try to handle as hpte fault */
866
867         .align  7
868         .globl DataAccessSLB_common
869 DataAccessSLB_common:
870         mfspr   r10,DAR
871         std     r10,PACA_EXGEN+EX_DAR(r13)
872         EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
873         ld      r3,PACA_EXGEN+EX_DAR(r13)
874         std     r3,_DAR(r1)
875         bl      .slb_allocate
876         cmpdi   r3,0                    /* Check return code */
877         beq     fast_exception_return   /* Return if we succeeded */
878         li      r5,0
879         std     r5,_DSISR(r1)
880         b       .handle_page_fault
881
882         .align  7
883         .globl InstructionAccess_common
884 InstructionAccess_common:
885         EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
886         ld      r3,_NIP(r1)
887         andis.  r4,r12,0x5820
888         li      r5,0x400
889         b       .do_hash_page           /* Try to handle as hpte fault */
890
891         .align  7
892         .globl InstructionAccessSLB_common
893 InstructionAccessSLB_common:
894         EXCEPTION_PROLOG_COMMON(0x480, PACA_EXGEN)
895         ld      r3,_NIP(r1)             /* SRR0 = NIA   */
896         bl      .slb_allocate
897         or.     r3,r3,r3                /* Check return code */
898         beq+    fast_exception_return   /* Return if we succeeded */
899
900         ld      r4,_NIP(r1)
901         li      r5,0
902         std     r4,_DAR(r1)
903         std     r5,_DSISR(r1)
904         b      .handle_page_fault
905
906         .align  7
907         .globl HardwareInterrupt_common
908         .globl HardwareInterrupt_entry
909 HardwareInterrupt_common:
910         EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
911 HardwareInterrupt_entry:
912         DISABLE_INTS
913         addi    r3,r1,STACK_FRAME_OVERHEAD
914         bl      .do_IRQ
915         b       .ret_from_except_lite
916
917         .align  7
918         .globl Alignment_common
919 Alignment_common:
920         mfspr   r10,DAR
921         std     r10,PACA_EXGEN+EX_DAR(r13)
922         mfspr   r10,DSISR
923         stw     r10,PACA_EXGEN+EX_DSISR(r13)
924         EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
925         ld      r3,PACA_EXGEN+EX_DAR(r13)
926         lwz     r4,PACA_EXGEN+EX_DSISR(r13)
927         std     r3,_DAR(r1)
928         std     r4,_DSISR(r1)
929         bl      .save_nvgprs
930         addi    r3,r1,STACK_FRAME_OVERHEAD
931         ENABLE_INTS
932         bl      .AlignmentException
933         b       .ret_from_except
934
935         .align  7
936         .globl ProgramCheck_common
937 ProgramCheck_common:
938         EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
939         bl      .save_nvgprs
940         addi    r3,r1,STACK_FRAME_OVERHEAD
941         ENABLE_INTS
942         bl      .ProgramCheckException
943         b       .ret_from_except
944
945         .align  7
946         .globl FPUnavailable_common
947 FPUnavailable_common:
948         EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
949         bne     .load_up_fpu            /* if from user, just load it up */
950         bl      .save_nvgprs
951         addi    r3,r1,STACK_FRAME_OVERHEAD
952         ENABLE_INTS
953         bl      .KernelFPUnavailableException
954         BUG_OPCODE
955
956         .align  7
957         .globl AltivecUnavailable_common
958 AltivecUnavailable_common:
959         EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
960 #ifdef CONFIG_ALTIVEC
961         bne     .load_up_altivec        /* if from user, just load it up */
962 #endif
963         bl      .save_nvgprs
964         addi    r3,r1,STACK_FRAME_OVERHEAD
965         ENABLE_INTS
966         bl      .AltivecUnavailableException
967         b       .ret_from_except
968
969 /*
970  * Hash table stuff
971  */
972         .align  7
973 _GLOBAL(do_hash_page)
974         std     r3,_DAR(r1)
975         std     r4,_DSISR(r1)
976
977         andis.  r0,r4,0xa450            /* weird error? */
978         bne-    .handle_page_fault      /* if not, try to insert a HPTE */
979 BEGIN_FTR_SECTION
980         andis.  r0,r4,0x0020            /* Is it a segment table fault? */
981         bne-    .do_ste_alloc           /* If so handle it */
982 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
983
984         /*
985          * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
986          * accessing a userspace segment (even from the kernel). We assume
987          * kernel addresses always have the high bit set.
988          */
989         rlwinm  r4,r4,32-23,29,29       /* DSISR_STORE -> _PAGE_RW */
990         rotldi  r0,r3,15                /* Move high bit into MSR_PR posn */
991         orc     r0,r12,r0               /* MSR_PR | ~high_bit */
992         rlwimi  r4,r0,32-13,30,30       /* becomes _PAGE_USER access bit */
993         ori     r4,r4,1                 /* add _PAGE_PRESENT */
994
995         /*
996          * On iSeries, we soft-disable interrupts here, then
997          * hard-enable interrupts so that the hash_page code can spin on
998          * the hash_table_lock without problems on a shared processor.
999          */
1000         DISABLE_INTS
1001
1002         /*
1003          * r3 contains the faulting address
1004          * r4 contains the required access permissions
1005          * r5 contains the trap number
1006          *
1007          * at return r3 = 0 for success
1008          */
1009         bl      .hash_page              /* build HPTE if possible */
1010         cmpdi   r3,0                    /* see if hash_page succeeded */
1011
1012 #ifdef DO_SOFT_DISABLE
1013         /*
1014          * If we had interrupts soft-enabled at the point where the
1015          * DSI/ISI occurred, and an interrupt came in during hash_page,
1016          * handle it now.
1017          * We jump to ret_from_except_lite rather than fast_exception_return
1018          * because ret_from_except_lite will check for and handle pending
1019          * interrupts if necessary.
1020          */
1021         beq     .ret_from_except_lite
1022         /*
1023          * hash_page couldn't handle it, set soft interrupt enable back
1024          * to what it was before the trap.  Note that .local_irq_restore
1025          * handles any interrupts pending at this point.
1026          */
1027         ld      r3,SOFTE(r1)
1028         bl      .local_irq_restore
1029         b       11f
1030 #else
1031         beq+    fast_exception_return   /* Return from exception on success */
1032         /* fall through */
1033 #endif
1034
1035 /* Here we have a page fault that hash_page can't handle. */
1036 _GLOBAL(handle_page_fault)
1037         ENABLE_INTS
1038 11:     ld      r4,_DAR(r1)
1039         ld      r5,_DSISR(r1)
1040         addi    r3,r1,STACK_FRAME_OVERHEAD
1041         bl      .do_page_fault
1042         cmpdi   r3,0
1043         beq+    .ret_from_except_lite
1044         bl      .save_nvgprs
1045         mr      r5,r3
1046         addi    r3,r1,STACK_FRAME_OVERHEAD
1047         lwz     r4,_DAR(r1)
1048         bl      .bad_page_fault
1049         b       .ret_from_except
1050
1051         /* here we have a segment miss */
1052 _GLOBAL(do_ste_alloc)
1053         bl      .ste_allocate           /* try to insert stab entry */
1054         cmpdi   r3,0
1055         beq+    fast_exception_return
1056         b       .handle_page_fault
1057
1058 /*
1059  * r13 points to the PACA, r9 contains the saved CR,
1060  * r11 and r12 contain the saved SRR0 and SRR1.
1061  * r9 - r13 are saved in paca->exslb.
1062  * We assume we aren't going to take any exceptions during this procedure.
1063  * We assume (DAR >> 60) == 0xc.
1064  */
1065         .align  7
1066 _GLOBAL(do_stab_bolted)
1067         stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
1068         std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
1069
1070         /* Hash to the primary group */
1071         ld      r10,PACASTABVIRT(r13)
1072         mfspr   r11,DAR
1073         srdi    r11,r11,28
1074         rldimi  r10,r11,7,52    /* r10 = first ste of the group */
1075
1076         /* Calculate VSID */
1077         /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
1078         rldic   r11,r11,15,36
1079         ori     r11,r11,0xc
1080
1081         /* VSID_RANDOMIZER */
1082         li      r9,9
1083         sldi    r9,r9,32
1084         oris    r9,r9,58231
1085         ori     r9,r9,39831
1086
1087         mulld   r9,r11,r9
1088         rldic   r9,r9,12,16     /* r9 = vsid << 12 */
1089
1090         /* Search the primary group for a free entry */
1091 1:      ld      r11,0(r10)      /* Test valid bit of the current ste    */
1092         andi.   r11,r11,0x80
1093         beq     2f
1094         addi    r10,r10,16
1095         andi.   r11,r10,0x70
1096         bne     1b
1097
1098         /* Stick for only searching the primary group for now.          */
1099         /* At least for now, we use a very simple random castout scheme */
1100         /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
1101         mftb    r11
1102         rldic   r11,r11,4,57    /* r11 = (r11 << 4) & 0x70 */
1103         ori     r11,r11,0x10
1104
1105         /* r10 currently points to an ste one past the group of interest */
1106         /* make it point to the randomly selected entry                 */
1107         subi    r10,r10,128
1108         or      r10,r10,r11     /* r10 is the entry to invalidate       */
1109
1110         isync                   /* mark the entry invalid               */
1111         ld      r11,0(r10)
1112         rldicl  r11,r11,56,1    /* clear the valid bit */
1113         rotldi  r11,r11,8
1114         std     r11,0(r10)
1115         sync
1116
1117         clrrdi  r11,r11,28      /* Get the esid part of the ste         */
1118         slbie   r11
1119
1120 2:      std     r9,8(r10)       /* Store the vsid part of the ste       */
1121         eieio
1122
1123         mfspr   r11,DAR         /* Get the new esid                     */
1124         clrrdi  r11,r11,28      /* Permits a full 32b of ESID           */
1125         ori     r11,r11,0x90    /* Turn on valid and kp                 */
1126         std     r11,0(r10)      /* Put new entry back into the stab     */
1127
1128         sync
1129
1130         /* All done -- return from exception. */
1131         lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
1132         ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
1133
1134         andi.   r10,r12,MSR_RI
1135         beq-    unrecov_slb
1136
1137         mtcrf   0x80,r9                 /* restore CR */
1138
1139         mfmsr   r10
1140         clrrdi  r10,r10,2
1141         mtmsrd  r10,1
1142
1143         mtspr   SRR0,r11
1144         mtspr   SRR1,r12
1145         ld      r9,PACA_EXSLB+EX_R9(r13)
1146         ld      r10,PACA_EXSLB+EX_R10(r13)
1147         ld      r11,PACA_EXSLB+EX_R11(r13)
1148         ld      r12,PACA_EXSLB+EX_R12(r13)
1149         ld      r13,PACA_EXSLB+EX_R13(r13)
1150         rfid
1151
1152 /*
1153  * r13 points to the PACA, r9 contains the saved CR,
1154  * r11 and r12 contain the saved SRR0 and SRR1.
1155  * r9 - r13 are saved in paca->exslb.
1156  * We assume we aren't going to take any exceptions during this procedure.
1157  */
1158 /* XXX note fix masking in get_kernel_vsid to match */
1159 _GLOBAL(do_slb_bolted)
1160         stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
1161         std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
1162
1163         /*
1164          * We take the next entry, round robin. Previously we tried
1165          * to find a free slot first but that took too long. Unfortunately
1166          * we dont have any LRU information to help us choose a slot.
1167          */
1168
1169         /* r13 = paca */
1170 1:      ld      r10,PACASTABRR(r13)
1171         addi    r9,r10,1
1172         cmpdi   r9,SLB_NUM_ENTRIES
1173         blt+    2f
1174         li      r9,2                    /* dont touch slot 0 or 1 */
1175 2:      std     r9,PACASTABRR(r13)
1176
1177         /* r13 = paca, r10 = entry */
1178
1179         /* 
1180          * Never cast out the segment for our kernel stack. Since we
1181          * dont invalidate the ERAT we could have a valid translation
1182          * for the kernel stack during the first part of exception exit 
1183          * which gets invalidated due to a tlbie from another cpu at a
1184          * non recoverable point (after setting srr0/1) - Anton
1185          */
1186         slbmfee r9,r10
1187         srdi    r9,r9,27
1188         /*
1189          * Use paca->ksave as the value of the kernel stack pointer,
1190          * because this is valid at all times.
1191          * The >> 27 (rather than >> 28) is so that the LSB is the
1192          * valid bit - this way we check valid and ESID in one compare.
1193          * In order to completely close the tiny race in the context
1194          * switch (between updating r1 and updating paca->ksave),
1195          * we check against both r1 and paca->ksave.
1196          */
1197         srdi    r11,r1,27
1198         ori     r11,r11,1
1199         cmpd    r11,r9
1200         beq-    1b
1201         ld      r11,PACAKSAVE(r13)
1202         srdi    r11,r11,27
1203         ori     r11,r11,1
1204         cmpd    r11,r9
1205         beq-    1b
1206
1207         /* r13 = paca, r10 = entry */
1208
1209         /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
1210         mfspr   r9,DAR
1211         rldicl  r11,r9,36,51
1212         sldi    r11,r11,15
1213         srdi    r9,r9,60
1214         or      r11,r11,r9
1215
1216         /* VSID_RANDOMIZER */
1217         li      r9,9
1218         sldi    r9,r9,32
1219         oris    r9,r9,58231
1220         ori     r9,r9,39831
1221
1222         /* vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK */
1223         mulld   r11,r11,r9
1224         clrldi  r11,r11,28
1225
1226         /* r13 = paca, r10 = entry, r11 = vsid */
1227
1228         /* Put together slb word1 */
1229         sldi    r11,r11,12
1230
1231 BEGIN_FTR_SECTION
1232         /* set kp and c bits */
1233         ori     r11,r11,0x480
1234 END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
1235 BEGIN_FTR_SECTION
1236         /* set kp, l and c bits */
1237         ori     r11,r11,0x580
1238 END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
1239
1240         /* r13 = paca, r10 = entry, r11 = slb word1 */
1241
1242         /* Put together slb word0 */
1243         mfspr   r9,DAR
1244         clrrdi  r9,r9,28        /* get the new esid */
1245         oris    r9,r9,0x800     /* set valid bit */
1246         rldimi  r9,r10,0,52     /* insert entry */
1247
1248         /* r13 = paca, r9 = slb word0, r11 = slb word1 */
1249
1250         /* 
1251          * No need for an isync before or after this slbmte. The exception
1252          * we enter with and the rfid we exit with are context synchronizing .
1253          */
1254         slbmte  r11,r9
1255
1256         /* All done -- return from exception. */
1257         lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
1258         ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
1259
1260         andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
1261         beq-    unrecov_slb
1262
1263         /*
1264          * Until everyone updates binutils hardwire the POWER4 optimised
1265          * single field mtcrf
1266          */
1267 #if 0
1268         .machine        push
1269         .machine        "power4"
1270         mtcrf   0x80,r9
1271         .machine        pop
1272 #else
1273         .long 0x7d380120
1274 #endif
1275
1276         mfmsr   r10
1277         clrrdi  r10,r10,2
1278         mtmsrd  r10,1
1279
1280         mtspr   SRR0,r11
1281         mtspr   SRR1,r12
1282         ld      r9,PACA_EXSLB+EX_R9(r13)
1283         ld      r10,PACA_EXSLB+EX_R10(r13)
1284         ld      r11,PACA_EXSLB+EX_R11(r13)
1285         ld      r12,PACA_EXSLB+EX_R12(r13)
1286         ld      r13,PACA_EXSLB+EX_R13(r13)
1287         rfid
1288
1289 unrecov_slb:
1290         EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
1291         DISABLE_INTS
1292         bl      .save_nvgprs
1293 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
1294         bl      .unrecoverable_exception
1295         b       1b
1296
1297
1298 /*
1299  * On pSeries, secondary processors spin in the following code.
1300  * At entry, r3 = this processor's number (in Linux terms, not hardware).
1301  */
1302 _GLOBAL(pseries_secondary_smp_init)
1303         /* turn on 64-bit mode */
1304         bl      .enable_64b_mode
1305         isync
1306
1307         /* Set up a paca value for this processor. */
1308         LOADADDR(r24, paca)             /* Get base vaddr of paca array  */
1309         mulli   r13,r3,PACA_SIZE        /* Calculate vaddr of right paca */
1310         add     r13,r13,r24             /* for this processor.           */
1311
1312         mtspr   SPRG3,r13               /* Save vaddr of paca in SPRG3   */
1313         mr      r24,r3                  /* __secondary_start needs cpu#  */
1314
1315 1:
1316         HMT_LOW
1317         lbz     r23,PACAPROCSTART(r13)  /* Test if this processor should */
1318                                         /* start.                        */
1319         sync
1320
1321         /* Create a temp kernel stack for use before relocation is on.  */
1322         ld      r1,PACAEMERGSP(r13)
1323         subi    r1,r1,STACK_FRAME_OVERHEAD
1324
1325         cmpwi   0,r23,0
1326 #ifdef CONFIG_SMP
1327 #ifdef SECONDARY_PROCESSORS
1328         bne     .__secondary_start
1329 #endif
1330 #endif
1331         b       1b                      /* Loop until told to go         */
1332 #ifdef CONFIG_PPC_ISERIES
1333 _GLOBAL(__start_initialization_iSeries)
1334         /* Clear out the BSS */
1335         LOADADDR(r11,__bss_stop)
1336
1337         LOADADDR(r8,__bss_start)
1338
1339         sub     r11,r11,r8              /* bss size                     */
1340         addi    r11,r11,7               /* round up to an even double word */
1341         rldicl. r11,r11,61,3            /* shift right by 3             */
1342         beq     4f
1343         addi    r8,r8,-8
1344         li      r0,0
1345         mtctr   r11                     /* zero this many doublewords   */
1346 3:      stdu    r0,8(r8)
1347         bdnz    3b
1348 4:
1349         LOADADDR(r1,init_thread_union)
1350         addi    r1,r1,THREAD_SIZE
1351         li      r0,0
1352         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
1353
1354         LOADADDR(r3,cpu_specs)
1355         LOADADDR(r4,cur_cpu_spec)
1356         li      r5,0
1357         bl      .identify_cpu
1358
1359         LOADADDR(r2,__toc_start)
1360         addi    r2,r2,0x4000
1361         addi    r2,r2,0x4000
1362
1363         LOADADDR(r9,systemcfg)
1364         SET_REG_TO_CONST(r4, SYSTEMCFG_VIRT_ADDR)
1365         std     r4,0(r9)                /* set the systemcfg pointer */
1366
1367         LOADADDR(r9,naca)
1368         SET_REG_TO_CONST(r4, NACA_VIRT_ADDR)
1369         std     r4,0(r9)                /* set the naca pointer */
1370
1371         /* Get the pointer to the segment table */
1372         ld      r6,PACA(r4)             /* Get the base paca pointer    */
1373         ld      r4,PACASTABVIRT(r6)
1374
1375         bl      .iSeries_fixup_klimit
1376
1377         /* relocation is on at this point */
1378
1379         b       .start_here_common
1380 #endif
1381
1382 #ifdef CONFIG_PPC_PSERIES
1383
1384 _STATIC(mmu_off)
1385         mfmsr   r3
1386         andi.   r0,r3,MSR_IR|MSR_DR
1387         beqlr
1388         andc    r3,r3,r0
1389         mtspr   SRR0,r4
1390         mtspr   SRR1,r3
1391         sync
1392         rfid
1393 _GLOBAL(__start_initialization_pSeries)
1394         mr      r31,r3                  /* save parameters */
1395         mr      r30,r4
1396         mr      r29,r5
1397         mr      r28,r6
1398         mr      r27,r7
1399
1400         bl      .enable_64b_mode
1401
1402         /* put a relocation offset into r3 */
1403         bl      .reloc_offset
1404
1405         LOADADDR(r2,__toc_start)
1406         addi    r2,r2,0x4000
1407         addi    r2,r2,0x4000
1408
1409         /* Relocate the TOC from a virt addr to a real addr */
1410         sub     r2,r2,r3
1411
1412         /* Save parameters */
1413         mr      r3,r31
1414         mr      r4,r30
1415         mr      r5,r29
1416         mr      r6,r28
1417         mr      r7,r27
1418
1419         /* Do all of the interaction with OF client interface */
1420         bl      .prom_init
1421         mr      r23,r3                  /* Save phys address we are running at */
1422
1423         /* Setup some critical 970 SPRs before switching MMU off */
1424         bl      .__970_cpu_preinit
1425
1426         li      r24,0                   /* cpu # */
1427
1428         /* Switch off MMU if not already */
1429         LOADADDR(r4, .__after_prom_start - KERNELBASE)
1430         add     r4,r4,r23
1431         bl      .mmu_off        
1432
1433 /*
1434  * At this point, r3 contains the physical address we are running at,
1435  * returned by prom_init()
1436  */
1437 _STATIC(__after_prom_start)
1438
1439 /*
1440  * We need to run with __start at physical address 0.
1441  * This will leave some code in the first 256B of
1442  * real memory, which are reserved for software use.
1443  * The remainder of the first page is loaded with the fixed
1444  * interrupt vectors.  The next two pages are filled with
1445  * unknown exception placeholders.
1446  *
1447  * Note: This process overwrites the OF exception vectors.
1448  *      r26 == relocation offset
1449  *      r27 == KERNELBASE
1450  */
1451         bl      .reloc_offset
1452         mr      r26,r3
1453         SET_REG_TO_CONST(r27,KERNELBASE)
1454
1455         li      r3,0                    /* target addr */
1456
1457         // XXX FIXME: Use phys returned by OF (r23)
1458         sub     r4,r27,r26              /* source addr                   */
1459                                         /* current address of _start     */
1460                                         /*   i.e. where we are running   */
1461                                         /*      the source addr          */
1462
1463         LOADADDR(r5,copy_to_here)       /* # bytes of memory to copy     */
1464         sub     r5,r5,r27
1465
1466         li      r6,0x100                /* Start offset, the first 0x100 */
1467                                         /* bytes were copied earlier.    */
1468
1469         bl      .copy_and_flush         /* copy the first n bytes        */
1470                                         /* this includes the code being  */
1471                                         /* executed here.                */
1472
1473         LOADADDR(r0, 4f)                /* Jump to the copy of this code */
1474         mtctr   r0                      /* that we just made/relocated   */
1475         bctr
1476
1477 4:      LOADADDR(r5,klimit)
1478         sub     r5,r5,r26
1479         ld      r5,0(r5)                /* get the value of klimit */
1480         sub     r5,r5,r27
1481         bl      .copy_and_flush         /* copy the rest */
1482         b       .start_here_pSeries
1483 #endif
1484
1485 /*
1486  * Copy routine used to copy the kernel to start at physical address 0
1487  * and flush and invalidate the caches as needed.
1488  * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
1489  * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
1490  *
1491  * Note: this routine *only* clobbers r0, r6 and lr
1492  */
1493 _GLOBAL(copy_and_flush)
1494         addi    r5,r5,-8
1495         addi    r6,r6,-8
1496 4:      li      r0,16                   /* Use the least common         */
1497                                         /* denominator cache line       */
1498                                         /* size.  This results in       */
1499                                         /* extra cache line flushes     */
1500                                         /* but operation is correct.    */
1501                                         /* Can't get cache line size    */
1502                                         /* from NACA as it is being     */
1503                                         /* moved too.                   */
1504
1505         mtctr   r0                      /* put # words/line in ctr      */
1506 3:      addi    r6,r6,8                 /* copy a cache line            */
1507         ldx     r0,r6,r4
1508         stdx    r0,r6,r3
1509         bdnz    3b
1510         dcbst   r6,r3                   /* write it to memory           */
1511         sync
1512         icbi    r6,r3                   /* flush the icache line        */
1513         cmpld   0,r6,r5
1514         blt     4b
1515         sync
1516         addi    r5,r5,8
1517         addi    r6,r6,8
1518         blr
1519
1520 .align 8
1521 copy_to_here:
1522
1523 /*
1524  * load_up_fpu(unused, unused, tsk)
1525  * Disable FP for the task which had the FPU previously,
1526  * and save its floating-point registers in its thread_struct.
1527  * Enables the FPU for use in the kernel on return.
1528  * On SMP we know the fpu is free, since we give it up every
1529  * switch (ie, no lazy save of the FP registers).
1530  * On entry: r13 == 'current' && last_task_used_math != 'current'
1531  */
1532 _STATIC(load_up_fpu)
1533         mfmsr   r5                      /* grab the current MSR */
1534         ori     r5,r5,MSR_FP
1535         mtmsrd  r5                      /* enable use of fpu now */
1536         isync
1537 /*
1538  * For SMP, we don't do lazy FPU switching because it just gets too
1539  * horrendously complex, especially when a task switches from one CPU
1540  * to another.  Instead we call giveup_fpu in switch_to.
1541  *
1542  */
1543 #ifndef CONFIG_SMP
1544         ld      r3,last_task_used_math@got(r2)
1545         ld      r4,0(r3)
1546         cmpdi   0,r4,0
1547         beq     1f
1548         /* Save FP state to last_task_used_math's THREAD struct */
1549         addi    r4,r4,THREAD
1550         SAVE_32FPRS(0, r4)
1551         mffs    fr0
1552         stfd    fr0,THREAD_FPSCR(r4)
1553         /* Disable FP for last_task_used_math */
1554         ld      r5,PT_REGS(r4)
1555         ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1556         li      r6,MSR_FP|MSR_FE0|MSR_FE1
1557         andc    r4,r4,r6
1558         std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1559 1:
1560 #endif /* CONFIG_SMP */
1561         /* enable use of FP after return */
1562         ld      r4,PACACURRENT(r13)
1563         addi    r5,r4,THREAD            /* Get THREAD */
1564         ld      r4,THREAD_FPEXC_MODE(r5)
1565         ori     r12,r12,MSR_FP
1566         or      r12,r12,r4
1567         std     r12,_MSR(r1)
1568         lfd     fr0,THREAD_FPSCR(r5)
1569         mtfsf   0xff,fr0
1570         REST_32FPRS(0, r5)
1571 #ifndef CONFIG_SMP
1572         /* Update last_task_used_math to 'current' */
1573         subi    r4,r5,THREAD            /* Back to 'current' */
1574         std     r4,0(r3)
1575 #endif /* CONFIG_SMP */
1576         /* restore registers and return */
1577         b       fast_exception_return
1578
1579 /*
1580  * disable_kernel_fp()
1581  * Disable the FPU.
1582  */
1583 _GLOBAL(disable_kernel_fp)
1584         mfmsr   r3
1585         rldicl  r0,r3,(63-MSR_FP_LG),1
1586         rldicl  r3,r0,(MSR_FP_LG+1),0
1587         mtmsrd  r3                      /* disable use of fpu now */
1588         isync
1589         blr
1590
1591 /*
1592  * giveup_fpu(tsk)
1593  * Disable FP for the task given as the argument,
1594  * and save the floating-point registers in its thread_struct.
1595  * Enables the FPU for use in the kernel on return.
1596  */
1597 _GLOBAL(giveup_fpu)
1598         mfmsr   r5
1599         ori     r5,r5,MSR_FP
1600         mtmsrd  r5                      /* enable use of fpu now */
1601         isync
1602         cmpdi   0,r3,0
1603         beqlr-                          /* if no previous owner, done */
1604         addi    r3,r3,THREAD            /* want THREAD of task */
1605         ld      r5,PT_REGS(r3)
1606         cmpdi   0,r5,0
1607         SAVE_32FPRS(0, r3)
1608         mffs    fr0
1609         stfd    fr0,THREAD_FPSCR(r3)
1610         beq     1f
1611         ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1612         li      r3,MSR_FP|MSR_FE0|MSR_FE1
1613         andc    r4,r4,r3                /* disable FP for previous task */
1614         std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1615 1:
1616 #ifndef CONFIG_SMP
1617         li      r5,0
1618         ld      r4,last_task_used_math@got(r2)
1619         std     r5,0(r4)
1620 #endif /* CONFIG_SMP */
1621         blr
1622
1623
1624 #ifdef CONFIG_ALTIVEC
1625                 
1626 /*
1627  * load_up_altivec(unused, unused, tsk)
1628  * Disable VMX for the task which had it previously,
1629  * and save its vector registers in its thread_struct.
1630  * Enables the VMX for use in the kernel on return.
1631  * On SMP we know the VMX is free, since we give it up every
1632  * switch (ie, no lazy save of the vector registers).
1633  * On entry: r13 == 'current' && last_task_used_altivec != 'current'
1634  */
1635 _STATIC(load_up_altivec)
1636         mfmsr   r5                      /* grab the current MSR */
1637         oris    r5,r5,MSR_VEC@h
1638         mtmsrd  r5                      /* enable use of VMX now */
1639         isync
1640         
1641 /*
1642  * For SMP, we don't do lazy VMX switching because it just gets too
1643  * horrendously complex, especially when a task switches from one CPU
1644  * to another.  Instead we call giveup_altvec in switch_to.
1645  * VRSAVE isn't dealt with here, that is done in the normal context
1646  * switch code. Note that we could rely on vrsave value to eventually
1647  * avoid saving all of the VREGs here...
1648  */
1649 #ifndef CONFIG_SMP
1650         ld      r3,last_task_used_altivec@got(r2)
1651         ld      r4,0(r3)
1652         cmpdi   0,r4,0
1653         beq     1f
1654         /* Save VMX state to last_task_used_altivec's THREAD struct */
1655         addi    r4,r4,THREAD
1656         SAVE_32VRS(0,r5,r4)
1657         mfvscr  vr0
1658         li      r10,THREAD_VSCR
1659         stvx    vr0,r10,r4
1660         /* Disable VMX for last_task_used_altivec */
1661         ld      r5,PT_REGS(r4)
1662         ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1663         lis     r6,MSR_VEC@h
1664         andc    r4,r4,r6
1665         std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1666 1:
1667 #endif /* CONFIG_SMP */
1668         /* Hack: if we get an altivec unavailable trap with VRSAVE
1669          * set to all zeros, we assume this is a broken application
1670          * that fails to set it properly, and thus we switch it to
1671          * all 1's
1672          */
1673         mfspr   r4,SPRN_VRSAVE
1674         cmpdi   0,r4,0
1675         bne+    1f
1676         li      r4,-1
1677         mtspr   SPRN_VRSAVE,r4
1678 1:
1679         /* enable use of VMX after return */
1680         ld      r4,PACACURRENT(r13)
1681         addi    r5,r4,THREAD            /* Get THREAD */
1682         oris    r12,r12,MSR_VEC@h
1683         std     r12,_MSR(r1)
1684         li      r4,1
1685         li      r10,THREAD_VSCR
1686         stw     r4,THREAD_USED_VR(r5)
1687         lvx     vr0,r10,r5
1688         REST_32VRS(0,r4,r5)
1689 #ifndef CONFIG_SMP
1690         /* Update last_task_used_math to 'current' */
1691         subi    r4,r5,THREAD            /* Back to 'current' */
1692         std     r4,0(r3)
1693 #endif /* CONFIG_SMP */
1694         /* restore registers and return */
1695         b       fast_exception_return
1696
1697 /*
1698  * disable_kernel_altivec()
1699  * Disable the VMX.
1700  */
1701 _GLOBAL(disable_kernel_altivec)
1702         mfmsr   r3
1703         rldicl  r0,r3,(63-MSR_VEC_LG),1
1704         rldicl  r3,r0,(MSR_VEC_LG+1),0
1705         mtmsrd  r3                      /* disable use of VMX now */
1706         isync
1707         blr
1708
1709 /*
1710  * giveup_altivec(tsk)
1711  * Disable VMX for the task given as the argument,
1712  * and save the vector registers in its thread_struct.
1713  * Enables the VMX for use in the kernel on return.
1714  */
1715 _GLOBAL(giveup_altivec)
1716         mfmsr   r5
1717         oris    r5,r5,MSR_VEC@h
1718         mtmsrd  r5                      /* enable use of VMX now */
1719         isync
1720         cmpdi   0,r3,0
1721         beqlr-                          /* if no previous owner, done */
1722         addi    r3,r3,THREAD            /* want THREAD of task */
1723         ld      r5,PT_REGS(r3)
1724         cmpdi   0,r5,0
1725         SAVE_32VRS(0,r4,r3)
1726         mfvscr  vr0
1727         li      r4,THREAD_VSCR
1728         stvx    vr0,r4,r3
1729         beq     1f
1730         ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1731         lis     r3,MSR_VEC@h
1732         andc    r4,r4,r3                /* disable FP for previous task */
1733         std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1734 1:
1735 #ifndef CONFIG_SMP
1736         li      r5,0
1737         ld      r4,last_task_used_altivec@got(r2)
1738         std     r5,0(r4)
1739 #endif /* CONFIG_SMP */
1740         blr
1741
1742 #endif /* CONFIG_ALTIVEC */
1743
1744 #ifdef CONFIG_SMP
1745 #ifdef CONFIG_PPC_PMAC
1746 /*
1747  * On PowerMac, secondary processors starts from the reset vector, which
1748  * is temporarily turned into a call to one of the functions below.
1749  */
1750         .section ".text";
1751         .align 2 ;
1752
1753         .globl  pmac_secondary_start_1  
1754 pmac_secondary_start_1: 
1755         li      r24, 1
1756         b       .pmac_secondary_start
1757         
1758         .globl pmac_secondary_start_2
1759 pmac_secondary_start_2: 
1760         li      r24, 2
1761         b       .pmac_secondary_start
1762         
1763         .globl pmac_secondary_start_3
1764 pmac_secondary_start_3:
1765         li      r24, 3
1766         b       .pmac_secondary_start
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         LOADADDR(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   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
1810         HMT_MEDIUM                      /* Set thread priority to MEDIUM */
1811
1812         ld      r2,PACATOC(r13)
1813         li      r6,0
1814         stb     r6,PACAPROCENABLED(r13)
1815
1816 #ifndef CONFIG_PPC_ISERIES
1817         /* Initialize the page table pointer register. */
1818         LOADADDR(r6,_SDR1)
1819         ld      r6,0(r6)                /* get the value of _SDR1        */
1820         mtspr   SDR1,r6                 /* set the htab location         */
1821 #endif
1822         /* Initialize the first segment table (or SLB) entry             */
1823         ld      r3,PACASTABVIRT(r13)    /* get addr of segment table     */
1824         bl      .stab_initialize
1825
1826         /* Initialize the kernel stack.  Just a repeat for iSeries.      */
1827         LOADADDR(r3,current_set)
1828         sldi    r28,r24,3               /* get current_set[cpu#]         */
1829         ldx     r1,r3,r28
1830         addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
1831         std     r1,PACAKSAVE(r13)
1832
1833         ld      r3,PACASTABREAL(r13)    /* get raddr of segment table    */
1834         ori     r4,r3,1                 /* turn on valid bit             */
1835
1836 #ifdef CONFIG_PPC_ISERIES
1837         li      r0,-1                   /* hypervisor call */
1838         li      r3,1
1839         sldi    r3,r3,63                /* 0x8000000000000000 */
1840         ori     r3,r3,4                 /* 0x8000000000000004 */
1841         sc                              /* HvCall_setASR */
1842 #else
1843         /* set the ASR */
1844         li      r3,SYSTEMCFG_PHYS_ADDR  /* r3 = ptr to systemcfg         */
1845         lwz     r3,PLATFORM(r3)         /* r3 = platform flags           */
1846         cmpldi  r3,PLATFORM_PSERIES_LPAR
1847         bne     98f
1848         mfspr   r3,PVR
1849         srwi    r3,r3,16
1850         cmpwi   r3,0x37                 /* SStar  */
1851         beq     97f
1852         cmpwi   r3,0x36                 /* IStar  */
1853         beq     97f
1854         cmpwi   r3,0x34                 /* Pulsar */
1855         bne     98f
1856 97:     li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
1857         HVSC                            /* Invoking hcall */
1858         b       99f
1859 98:                                     /* !(rpa hypervisor) || !(star)  */
1860         mtasr   r4                      /* set the stab location         */
1861 99:
1862 #endif
1863         li      r7,0
1864         mtlr    r7
1865
1866         /* enable MMU and jump to start_secondary */
1867         LOADADDR(r3,.start_secondary_prolog)
1868         SET_REG_TO_CONST(r4, MSR_KERNEL)
1869 #ifdef DO_SOFT_DISABLE
1870         ori     r4,r4,MSR_EE
1871 #endif
1872         mtspr   SRR0,r3
1873         mtspr   SRR1,r4
1874         rfid
1875
1876 /* 
1877  * Running with relocation on at this point.  All we want to do is
1878  * zero the stack back-chain pointer before going into C code.
1879  */
1880 _GLOBAL(start_secondary_prolog)
1881         li      r3,0
1882         std     r3,0(r1)                /* Zero the stack frame pointer */
1883         bl      .start_secondary
1884 #endif
1885
1886 /*
1887  * This subroutine clobbers r11 and r12
1888  */
1889 _GLOBAL(enable_64b_mode)
1890         mfmsr   r11                     /* grab the current MSR */
1891         li      r12,1
1892         rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
1893         or      r11,r11,r12
1894         li      r12,1
1895         rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
1896         or      r11,r11,r12
1897         mtmsrd  r11
1898         isync
1899         blr
1900
1901 #ifdef CONFIG_PPC_PSERIES
1902 /*
1903  * This is where the main kernel code starts.
1904  */
1905 _STATIC(start_here_pSeries)
1906         /* get a new offset, now that the kernel has moved. */
1907         bl      .reloc_offset
1908         mr      r26,r3
1909
1910         mfmsr   r6
1911         ori     r6,r6,MSR_RI
1912         mtmsrd  r6                      /* RI on */
1913
1914         /* setup the systemcfg pointer which is needed by *tab_initialize       */
1915         LOADADDR(r6,systemcfg)
1916         sub     r6,r6,r26               /* addr of the variable systemcfg */
1917         li      r27,SYSTEMCFG_PHYS_ADDR
1918         std     r27,0(r6)               /* set the value of systemcfg   */
1919
1920         /* setup the naca pointer which is needed by *tab_initialize    */
1921         LOADADDR(r6,naca)
1922         sub     r6,r6,r26               /* addr of the variable naca    */
1923         li      r27,NACA_PHYS_ADDR
1924         std     r27,0(r6)               /* set the value of naca        */
1925
1926 #ifdef CONFIG_HMT
1927         /* Start up the second thread on cpu 0 */
1928         mfspr   r3,PVR
1929         srwi    r3,r3,16
1930         cmpwi   r3,0x34                 /* Pulsar  */
1931         beq     90f
1932         cmpwi   r3,0x36                 /* Icestar */
1933         beq     90f
1934         cmpwi   r3,0x37                 /* SStar   */
1935         beq     90f
1936         b       91f                     /* HMT not supported */
1937 90:     li      r3,0
1938         bl      .hmt_start_secondary
1939 91:
1940 #endif
1941
1942 #ifdef CONFIG_SMP
1943         /* All secondary cpus are now spinning on a common
1944          * spinloop, release them all now so they can start
1945          * to spin on their individual paca spinloops.
1946          * For non SMP kernels, the secondary cpus never
1947          * get out of the common spinloop.
1948          */
1949         li      r3,1
1950         LOADADDR(r5,__secondary_hold_spinloop)
1951         tophys(r4,r5)
1952         std     r3,0(r4)
1953 #endif
1954
1955         /* The following gets the stack and TOC set up with the regs */
1956         /* pointing to the real addr of the kernel stack.  This is   */
1957         /* all done to support the C function call below which sets  */
1958         /* up the htab.  This is done because we have relocated the  */
1959         /* kernel but are still running in real mode. */
1960
1961         LOADADDR(r3,init_thread_union)
1962         sub     r3,r3,r26
1963
1964         /* set up a stack pointer (physical address) */
1965         addi    r1,r3,THREAD_SIZE
1966         li      r0,0
1967         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
1968
1969                 /* set up the TOC (physical address) */
1970         LOADADDR(r2,__toc_start)
1971         addi    r2,r2,0x4000
1972         addi    r2,r2,0x4000
1973         sub     r2,r2,r26
1974
1975         LOADADDR(r3,cpu_specs)
1976         sub     r3,r3,r26
1977         LOADADDR(r4,cur_cpu_spec)
1978         sub     r4,r4,r26
1979         mr      r5,r26
1980         bl      .identify_cpu
1981
1982         /* Get the pointer to the segment table which is used by                */
1983         /* stab_initialize                                               */
1984         LOADADDR(r27, boot_cpuid)
1985         sub     r27,r27,r26
1986         lwz     r27,0(r27)
1987
1988         LOADADDR(r24, paca)             /* Get base vaddr of paca array  */
1989         mulli   r13,r27,PACA_SIZE       /* Calculate vaddr of right paca */
1990         add     r13,r13,r24             /* for this processor.           */
1991         sub     r13,r13,r26             /* convert to physical addr      */
1992
1993         mtspr   SPRG3,r13               /* PPPBBB: Temp... -Peter */
1994         ld      r3,PACASTABREAL(r13)
1995         ori     r4,r3,1                 /* turn on valid bit             */
1996         
1997         /* set the ASR */
1998         li      r3,SYSTEMCFG_PHYS_ADDR  /* r3 = ptr to systemcfg */
1999         lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
2000         cmpldi  r3,PLATFORM_PSERIES_LPAR
2001         bne     98f
2002         mfspr   r3,PVR
2003         srwi    r3,r3,16
2004         cmpwi   r3,0x37                 /* SStar */
2005         beq     97f
2006         cmpwi   r3,0x36                 /* IStar  */
2007         beq     97f
2008         cmpwi   r3,0x34                 /* Pulsar */
2009         bne     98f
2010 97:     li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
2011         HVSC                            /* Invoking hcall */
2012         b       99f
2013 98:                                     /* !(rpa hypervisor) || !(star) */
2014         mtasr   r4                      /* set the stab location        */
2015 99:
2016         mfspr   r6,SPRG3
2017         ld      r3,PACASTABREAL(r6)     /* restore r3 for stab_initialize */
2018
2019         /* Initialize an initial memory mapping and turn on relocation. */
2020         bl      .stab_initialize
2021         bl      .htab_initialize
2022
2023         li      r3,SYSTEMCFG_PHYS_ADDR  /* r3 = ptr to systemcfg */
2024         lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
2025         /* Test if bit 0 is set (LPAR bit) */
2026         andi.   r3,r3,0x1
2027         bne     98f
2028         LOADADDR(r6,_SDR1)              /* Only if NOT LPAR */
2029         sub     r6,r6,r26
2030         ld      r6,0(r6)                /* get the value of _SDR1 */
2031         mtspr   SDR1,r6                 /* set the htab location  */
2032 98: 
2033         LOADADDR(r3,.start_here_common)
2034         SET_REG_TO_CONST(r4, MSR_KERNEL)
2035         mtspr   SRR0,r3
2036         mtspr   SRR1,r4
2037         rfid
2038 #endif /* CONFIG_PPC_PSERIES */
2039         
2040         /* This is where all platforms converge execution */
2041 _STATIC(start_here_common)
2042         /* relocation is on at this point */
2043
2044         /* The following code sets up the SP and TOC now that we are */
2045         /* running with translation enabled. */
2046
2047         LOADADDR(r3,init_thread_union)
2048
2049         /* set up the stack */
2050         addi    r1,r3,THREAD_SIZE
2051         li      r0,0
2052         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
2053
2054         /* Apply the CPUs-specific fixups (nop out sections not relevant
2055          * to this CPU
2056          */
2057         li      r3,0
2058         bl      .do_cpu_ftr_fixups
2059
2060         /* setup the systemcfg pointer */
2061         LOADADDR(r9,systemcfg)
2062         SET_REG_TO_CONST(r8, SYSTEMCFG_VIRT_ADDR)
2063         std     r8,0(r9)
2064
2065         /* setup the naca pointer */
2066         LOADADDR(r9,naca)
2067         SET_REG_TO_CONST(r8, NACA_VIRT_ADDR)
2068         std     r8,0(r9)                /* set the value of the naca ptr */
2069
2070         LOADADDR(r26, boot_cpuid)
2071         lwz     r26,0(r26)
2072
2073         LOADADDR(r24, paca)             /* Get base vaddr of paca array  */
2074         mulli   r13,r26,PACA_SIZE       /* Calculate vaddr of right paca */
2075         add     r13,r13,r24             /* for this processor.           */
2076         mtspr   SPRG3,r13
2077
2078         /* ptr to current */
2079         LOADADDR(r4,init_task)
2080         std     r4,PACACURRENT(r13)
2081
2082         /* Load the TOC */
2083         ld      r2,PACATOC(r13)
2084         std     r1,PACAKSAVE(r13)
2085
2086         /* Restore the parms passed in from the bootloader. */
2087         mr      r3,r31
2088         mr      r4,r30
2089         mr      r5,r29
2090         mr      r6,r28
2091         mr      r7,r27
2092
2093         bl      .setup_system
2094
2095         /* Load up the kernel context */
2096 5:
2097 #ifdef DO_SOFT_DISABLE
2098         li      r5,0
2099         stb     r5,PACAPROCENABLED(r13) /* Soft Disabled */
2100         mfmsr   r5
2101         ori     r5,r5,MSR_EE            /* Hard Enabled */
2102         mtmsrd  r5
2103 #endif
2104
2105         bl .start_kernel
2106
2107 _GLOBAL(__setup_cpu_power3)
2108         blr
2109
2110 _GLOBAL(hmt_init)
2111 #ifdef CONFIG_HMT
2112         LOADADDR(r5, hmt_thread_data)
2113         mfspr   r7,PVR
2114         srwi    r7,r7,16
2115         cmpwi   r7,0x34                 /* Pulsar  */
2116         beq     90f
2117         cmpwi   r7,0x36                 /* Icestar */
2118         beq     91f
2119         cmpwi   r7,0x37                 /* SStar   */
2120         beq     91f
2121         b       101f
2122 90:     mfspr   r6,PIR
2123         andi.   r6,r6,0x1f
2124         b       92f
2125 91:     mfspr   r6,PIR
2126         andi.   r6,r6,0x3ff
2127 92:     sldi    r4,r24,3
2128         stwx    r6,r5,r4
2129         bl      .hmt_start_secondary
2130         b       101f
2131
2132 __hmt_secondary_hold:
2133         LOADADDR(r5, hmt_thread_data)
2134         clrldi  r5,r5,4
2135         li      r7,0
2136         mfspr   r6,PIR
2137         mfspr   r8,PVR
2138         srwi    r8,r8,16
2139         cmpwi   r8,0x34
2140         bne     93f
2141         andi.   r6,r6,0x1f
2142         b       103f
2143 93:     andi.   r6,r6,0x3f
2144
2145 103:    lwzx    r8,r5,r7
2146         cmpw    r8,r6
2147         beq     104f
2148         addi    r7,r7,8
2149         b       103b
2150
2151 104:    addi    r7,r7,4
2152         lwzx    r9,r5,r7
2153         mr      r24,r9
2154 101:
2155 #endif
2156         mr      r3,r24
2157         b       .pseries_secondary_smp_init
2158
2159 #ifdef CONFIG_HMT
2160 _GLOBAL(hmt_start_secondary)
2161         LOADADDR(r4,__hmt_secondary_hold)
2162         clrldi  r4,r4,4
2163         mtspr   NIADORM, r4
2164         mfspr   r4, MSRDORM
2165         li      r5, -65
2166         and     r4, r4, r5
2167         mtspr   MSRDORM, r4
2168         lis     r4,0xffef
2169         ori     r4,r4,0x7403
2170         mtspr   TSC, r4
2171         li      r4,0x1f4
2172         mtspr   TST, r4
2173         mfspr   r4, HID0
2174         ori     r4, r4, 0x1
2175         mtspr   HID0, r4
2176         mfspr   r4, CTRLF
2177         oris    r4, r4, 0x40
2178         mtspr   CTRLT, r4
2179         blr
2180 #endif
2181
2182 /*
2183  * We put a few things here that have to be page-aligned.
2184  * This stuff goes at the beginning of the data segment,
2185  * which is page-aligned.
2186  */
2187         .data
2188         .align  12
2189         .globl  sdata
2190 sdata:
2191         .globl  empty_zero_page
2192 empty_zero_page:
2193         .space  4096
2194
2195         .globl  swapper_pg_dir
2196 swapper_pg_dir:
2197         .space  4096
2198
2199         .globl  ioremap_dir
2200 ioremap_dir:
2201         .space  4096
2202
2203 /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */
2204         .globl  stab_array
2205 stab_array:
2206         .space  4096 * 48
2207         
2208 /*
2209  * This space gets a copy of optional info passed to us by the bootstrap
2210  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
2211  */
2212         .globl  cmd_line
2213 cmd_line:
2214         .space  COMMAND_LINE_SIZE