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