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