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