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