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