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