[PATCH] Restore lparmap.s include for iSeries
[wandboard.git] / arch / ppc64 / kernel / head.S
blobd98a9986c14f02dea86f04f2e6c05f7390083ee2
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  */
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/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>
40 #ifdef CONFIG_PPC_ISERIES
41 #define DO_SOFT_DISABLE
42 #endif
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  */
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  */
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  */
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 */
87         /* Catch branch to 0 in real mode */
88         trap
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
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 */
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
116 #endif /* CONFIG_PPC_ISERIES */
118         /* Secondary processors spin on this value until it goes to 1. */
119         .globl  __secondary_hold_spinloop
120 __secondary_hold_spinloop:
121         .llong  0x0
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
129         . = 0x60
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 */
142         /* Grab our linux cpu number */
143         mr      r24,r3
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
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
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
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
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  */
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  */
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
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 */
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
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
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.
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      */
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)
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
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;                                         \
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
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
347 #else   /* hard enable/disable interrupts */
348 #define DISABLE_INTS
350 #define ENABLE_INTS                             \
351         ld      r12,_MSR(r1);                   \
352         mfmsr   r11;                            \
353         rlwimi  r11,r12,0,MSR_EE;               \
354         mtmsrd  r11,1
356 #endif
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
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
380  * Start of pSeries system interrupt routines
381  */
382         . = 0x100
383         .globl __start_interrupts
384 __start_interrupts:
386         STD_EXCEPTION_PSERIES(0x100, system_reset)
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)
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)
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 */
433         STD_EXCEPTION_PSERIES(0x400, instruction_access)
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 */
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)
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 */
481         STD_EXCEPTION_PSERIES(0xd00, single_step)
482         STD_EXCEPTION_PSERIES(0xe00, trap_0e)
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
492         STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
494         STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
495         STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
497         . = 0x3000
499 /*** pSeries interrupt support ***/
501         /* moved from 0xf00 */
502         STD_EXCEPTION_PSERIES(., performance_monitor)
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)
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)
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)
527 #ifdef CONFIG_PPC_ISERIES
528 /***  ISeries-LPAR interrupt handlers ***/
530         STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
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
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
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
567         STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
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
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)
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
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)
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
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
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 */
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 */
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 */
670 /*** Common interrupt handlers ***/
672         STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
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
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
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
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)
765         mfmsr   r10
766         clrrdi  r10,r10,2               /* clear RI (LE is 0 already) */
767         mtmsrd  r10,1
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 */
776 unrecov_fer:
777         bl      .save_nvgprs
778 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
779         bl      .unrecoverable_exception
780         b       1b
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 */
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 */
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
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
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
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
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
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.
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)
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
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
931 #ifdef CONFIG_ALTIVEC
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
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)
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
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 */
1006  * Hash table stuff
1007  */
1008         .align  7
1009 _GLOBAL(do_hash_page)
1010         std     r3,_DAR(r1)
1011         std     r4,_DSISR(r1)
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)
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 */
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
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 */
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
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 */
1074         /* fall through */
1075 #endif
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
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
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
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 */
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 */
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 */
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
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
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       */
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
1159         clrrdi  r11,r11,28      /* Get the esid part of the ste         */
1160         slbie   r11
1162 2:      std     r9,8(r10)       /* Store the vsid part of the ste       */
1163         eieio
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     */
1170         sync
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 */
1176         andi.   r10,r12,MSR_RI
1177         beq-    unrecov_slb
1179         mtcrf   0x80,r9                 /* restore CR */
1181         mfmsr   r10
1182         clrrdi  r10,r10,2
1183         mtmsrd  r10,1
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 */
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
1206         stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
1207         std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
1209         bl      .slb_allocate                   /* handle it */
1211         /* All done -- return from exception. */
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 */
1220         mtlr    r10
1222         andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
1223         beq-    unrecov_slb
1225 .machine        push
1226 .machine        "power4"
1227         mtcrf   0x80,r9
1228         mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
1229 .machine        pop
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 */
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
1252  * Space for CPU0's segment table.
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
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:
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 #endif /* CONFIG_PPC_ISERIES */
1281         . = 0x8000
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
1294         /* Copy some CPU settings from CPU 0 */
1295         bl      .__restore_cpu_setup
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
1311         mr      r3,r24                  /* not found, copy phys to r3    */
1312         b       .kexec_wait             /* next kernel might do better   */
1314 2:      mtspr   SPRG3,r13               /* Save vaddr of paca in SPRG3   */
1315         /* From now on, r24 is expected to be logical cpuid */
1316         mr      r24,r5
1317 3:      HMT_LOW
1318         lbz     r23,PACAPROCSTART(r13)  /* Test if this processor should */
1319                                         /* start.                        */
1320         sync
1322         /* Create a temp kernel stack for use before relocation is on.  */
1323         ld      r1,PACAEMERGSP(r13)
1324         subi    r1,r1,STACK_FRAME_OVERHEAD
1326         cmpwi   0,r23,0
1327 #ifdef CONFIG_SMP
1328         bne     .__secondary_start
1329 #endif
1330         b       3b                      /* Loop until told to go         */
1332 #ifdef CONFIG_PPC_ISERIES
1333 _STATIC(__start_initialization_iSeries)
1334         /* Clear out the BSS */
1335         LOADADDR(r11,__bss_stop)
1336         LOADADDR(r8,__bss_start)
1337         sub     r11,r11,r8              /* bss size                     */
1338         addi    r11,r11,7               /* round up to an even double word */
1339         rldicl. r11,r11,61,3            /* shift right by 3             */
1340         beq     4f
1341         addi    r8,r8,-8
1342         li      r0,0
1343         mtctr   r11                     /* zero this many doublewords   */
1344 3:      stdu    r0,8(r8)
1345         bdnz    3b
1347         LOADADDR(r1,init_thread_union)
1348         addi    r1,r1,THREAD_SIZE
1349         li      r0,0
1350         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
1352         LOADADDR(r3,cpu_specs)
1353         LOADADDR(r4,cur_cpu_spec)
1354         li      r5,0
1355         bl      .identify_cpu
1357         LOADADDR(r2,__toc_start)
1358         addi    r2,r2,0x4000
1359         addi    r2,r2,0x4000
1361         bl      .iSeries_early_setup
1363         /* relocation is on at this point */
1365         b       .start_here_common
1366 #endif /* CONFIG_PPC_ISERIES */
1368 #ifdef CONFIG_PPC_MULTIPLATFORM
1370 _STATIC(__mmu_off)
1371         mfmsr   r3
1372         andi.   r0,r3,MSR_IR|MSR_DR
1373         beqlr
1374         andc    r3,r3,r0
1375         mtspr   SPRN_SRR0,r4
1376         mtspr   SPRN_SRR1,r3
1377         sync
1378         rfid
1379         b       .       /* prevent speculative execution */
1383  * Here is our main kernel entry point. We support currently 2 kind of entries
1384  * depending on the value of r5.
1386  *   r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
1387  *                 in r3...r7
1388  *   
1389  *   r5 == NULL -> kexec style entry. r3 is a physical pointer to the
1390  *                 DT block, r4 is a physical pointer to the kernel itself
1392  */
1393 _GLOBAL(__start_initialization_multiplatform)
1394         /*
1395          * Are we booted from a PROM Of-type client-interface ?
1396          */
1397         cmpldi  cr0,r5,0
1398         bne     .__boot_from_prom               /* yes -> prom */
1400         /* Save parameters */
1401         mr      r31,r3
1402         mr      r30,r4
1404         /* Make sure we are running in 64 bits mode */
1405         bl      .enable_64b_mode
1407         /* Setup some critical 970 SPRs before switching MMU off */
1408         bl      .__970_cpu_preinit
1410         /* cpu # */
1411         li      r24,0
1413         /* Switch off MMU if not already */
1414         LOADADDR(r4, .__after_prom_start - KERNELBASE)
1415         add     r4,r4,r30
1416         bl      .__mmu_off
1417         b       .__after_prom_start
1419 _STATIC(__boot_from_prom)
1420         /* Save parameters */
1421         mr      r31,r3
1422         mr      r30,r4
1423         mr      r29,r5
1424         mr      r28,r6
1425         mr      r27,r7
1427         /* Make sure we are running in 64 bits mode */
1428         bl      .enable_64b_mode
1430         /* put a relocation offset into r3 */
1431         bl      .reloc_offset
1433         LOADADDR(r2,__toc_start)
1434         addi    r2,r2,0x4000
1435         addi    r2,r2,0x4000
1437         /* Relocate the TOC from a virt addr to a real addr */
1438         sub     r2,r2,r3
1440         /* Restore parameters */
1441         mr      r3,r31
1442         mr      r4,r30
1443         mr      r5,r29
1444         mr      r6,r28
1445         mr      r7,r27
1447         /* Do all of the interaction with OF client interface */
1448         bl      .prom_init
1449         /* We never return */
1450         trap
1453  * At this point, r3 contains the physical address we are running at,
1454  * returned by prom_init()
1455  */
1456 _STATIC(__after_prom_start)
1459  * We need to run with __start at physical address 0.
1460  * This will leave some code in the first 256B of
1461  * real memory, which are reserved for software use.
1462  * The remainder of the first page is loaded with the fixed
1463  * interrupt vectors.  The next two pages are filled with
1464  * unknown exception placeholders.
1466  * Note: This process overwrites the OF exception vectors.
1467  *      r26 == relocation offset
1468  *      r27 == KERNELBASE
1469  */
1470         bl      .reloc_offset
1471         mr      r26,r3
1472         SET_REG_TO_CONST(r27,KERNELBASE)
1474         li      r3,0                    /* target addr */
1476         // XXX FIXME: Use phys returned by OF (r30)
1477         sub     r4,r27,r26              /* source addr                   */
1478                                         /* current address of _start     */
1479                                         /*   i.e. where we are running   */
1480                                         /*      the source addr          */
1482         LOADADDR(r5,copy_to_here)       /* # bytes of memory to copy     */
1483         sub     r5,r5,r27
1485         li      r6,0x100                /* Start offset, the first 0x100 */
1486                                         /* bytes were copied earlier.    */
1488         bl      .copy_and_flush         /* copy the first n bytes        */
1489                                         /* this includes the code being  */
1490                                         /* executed here.                */
1492         LOADADDR(r0, 4f)                /* Jump to the copy of this code */
1493         mtctr   r0                      /* that we just made/relocated   */
1494         bctr
1496 4:      LOADADDR(r5,klimit)
1497         sub     r5,r5,r26
1498         ld      r5,0(r5)                /* get the value of klimit */
1499         sub     r5,r5,r27
1500         bl      .copy_and_flush         /* copy the rest */
1501         b       .start_here_multiplatform
1503 #endif /* CONFIG_PPC_MULTIPLATFORM */
1506  * Copy routine used to copy the kernel to start at physical address 0
1507  * and flush and invalidate the caches as needed.
1508  * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
1509  * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
1511  * Note: this routine *only* clobbers r0, r6 and lr
1512  */
1513 _GLOBAL(copy_and_flush)
1514         addi    r5,r5,-8
1515         addi    r6,r6,-8
1516 4:      li      r0,16                   /* Use the least common         */
1517                                         /* denominator cache line       */
1518                                         /* size.  This results in       */
1519                                         /* extra cache line flushes     */
1520                                         /* but operation is correct.    */
1521                                         /* Can't get cache line size    */
1522                                         /* from NACA as it is being     */
1523                                         /* moved too.                   */
1525         mtctr   r0                      /* put # words/line in ctr      */
1526 3:      addi    r6,r6,8                 /* copy a cache line            */
1527         ldx     r0,r6,r4
1528         stdx    r0,r6,r3
1529         bdnz    3b
1530         dcbst   r6,r3                   /* write it to memory           */
1531         sync
1532         icbi    r6,r3                   /* flush the icache line        */
1533         cmpld   0,r6,r5
1534         blt     4b
1535         sync
1536         addi    r5,r5,8
1537         addi    r6,r6,8
1538         blr
1540 .align 8
1541 copy_to_here:
1543 #ifdef CONFIG_SMP
1544 #ifdef CONFIG_PPC_PMAC
1546  * On PowerMac, secondary processors starts from the reset vector, which
1547  * is temporarily turned into a call to one of the functions below.
1548  */
1549         .section ".text";
1550         .align 2 ;
1552         .globl  pmac_secondary_start_1  
1553 pmac_secondary_start_1: 
1554         li      r24, 1
1555         b       .pmac_secondary_start
1556         
1557         .globl pmac_secondary_start_2
1558 pmac_secondary_start_2: 
1559         li      r24, 2
1560         b       .pmac_secondary_start
1561         
1562         .globl pmac_secondary_start_3
1563 pmac_secondary_start_3:
1564         li      r24, 3
1565         b       .pmac_secondary_start
1566         
1567 _GLOBAL(pmac_secondary_start)
1568         /* turn on 64-bit mode */
1569         bl      .enable_64b_mode
1570         isync
1572         /* Copy some CPU settings from CPU 0 */
1573         bl      .__restore_cpu_setup
1575         /* pSeries do that early though I don't think we really need it */
1576         mfmsr   r3
1577         ori     r3,r3,MSR_RI
1578         mtmsrd  r3                      /* RI on */
1580         /* Set up a paca value for this processor. */
1581         LOADADDR(r4, paca)               /* Get base vaddr of paca array        */
1582         mulli   r13,r24,PACA_SIZE        /* Calculate vaddr of right paca */
1583         add     r13,r13,r4              /* for this processor.          */
1584         mtspr   SPRG3,r13                /* Save vaddr of paca in SPRG3 */
1586         /* Create a temp kernel stack for use before relocation is on.  */
1587         ld      r1,PACAEMERGSP(r13)
1588         subi    r1,r1,STACK_FRAME_OVERHEAD
1590         b       .__secondary_start
1592 #endif /* CONFIG_PPC_PMAC */
1595  * This function is called after the master CPU has released the
1596  * secondary processors.  The execution environment is relocation off.
1597  * The paca for this processor has the following fields initialized at
1598  * this point:
1599  *   1. Processor number
1600  *   2. Segment table pointer (virtual address)
1601  * On entry the following are set:
1602  *   r1 = stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
1603  *   r24   = cpu# (in Linux terms)
1604  *   r13   = paca virtual address
1605  *   SPRG3 = paca virtual address
1606  */
1607 _GLOBAL(__secondary_start)
1609         HMT_MEDIUM                      /* Set thread priority to MEDIUM */
1611         ld      r2,PACATOC(r13)
1612         li      r6,0
1613         stb     r6,PACAPROCENABLED(r13)
1615 #ifndef CONFIG_PPC_ISERIES
1616         /* Initialize the page table pointer register. */
1617         LOADADDR(r6,_SDR1)
1618         ld      r6,0(r6)                /* get the value of _SDR1        */
1619         mtspr   SDR1,r6                 /* set the htab location         */
1620 #endif
1621         /* Initialize the first segment table (or SLB) entry             */
1622         ld      r3,PACASTABVIRT(r13)    /* get addr of segment table     */
1623         bl      .stab_initialize
1625         /* Initialize the kernel stack.  Just a repeat for iSeries.      */
1626         LOADADDR(r3,current_set)
1627         sldi    r28,r24,3               /* get current_set[cpu#]         */
1628         ldx     r1,r3,r28
1629         addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
1630         std     r1,PACAKSAVE(r13)
1632         ld      r3,PACASTABREAL(r13)    /* get raddr of segment table    */
1633         ori     r4,r3,1                 /* turn on valid bit             */
1635 #ifdef CONFIG_PPC_ISERIES
1636         li      r0,-1                   /* hypervisor call */
1637         li      r3,1
1638         sldi    r3,r3,63                /* 0x8000000000000000 */
1639         ori     r3,r3,4                 /* 0x8000000000000004 */
1640         sc                              /* HvCall_setASR */
1641 #else
1642         /* set the ASR */
1643         ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg         */
1644         lwz     r3,PLATFORM(r3)         /* r3 = platform flags           */
1645         cmpldi  r3,PLATFORM_PSERIES_LPAR
1646         bne     98f
1647         mfspr   r3,PVR
1648         srwi    r3,r3,16
1649         cmpwi   r3,0x37                 /* SStar  */
1650         beq     97f
1651         cmpwi   r3,0x36                 /* IStar  */
1652         beq     97f
1653         cmpwi   r3,0x34                 /* Pulsar */
1654         bne     98f
1655 97:     li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
1656         HVSC                            /* Invoking hcall */
1657         b       99f
1658 98:                                     /* !(rpa hypervisor) || !(star)  */
1659         mtasr   r4                      /* set the stab location         */
1661 #endif
1662         li      r7,0
1663         mtlr    r7
1665         /* enable MMU and jump to start_secondary */
1666         LOADADDR(r3,.start_secondary_prolog)
1667         SET_REG_TO_CONST(r4, MSR_KERNEL)
1668 #ifdef DO_SOFT_DISABLE
1669         ori     r4,r4,MSR_EE
1670 #endif
1671         mtspr   SRR0,r3
1672         mtspr   SRR1,r4
1673         rfid
1674         b       .       /* prevent speculative execution */
1676 /* 
1677  * Running with relocation on at this point.  All we want to do is
1678  * zero the stack back-chain pointer before going into C code.
1679  */
1680 _GLOBAL(start_secondary_prolog)
1681         li      r3,0
1682         std     r3,0(r1)                /* Zero the stack frame pointer */
1683         bl      .start_secondary
1684 #endif
1687  * This subroutine clobbers r11 and r12
1688  */
1689 _GLOBAL(enable_64b_mode)
1690         mfmsr   r11                     /* grab the current MSR */
1691         li      r12,1
1692         rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
1693         or      r11,r11,r12
1694         li      r12,1
1695         rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
1696         or      r11,r11,r12
1697         mtmsrd  r11
1698         isync
1699         blr
1701 #ifdef CONFIG_PPC_MULTIPLATFORM
1703  * This is where the main kernel code starts.
1704  */
1705 _STATIC(start_here_multiplatform)
1706         /* get a new offset, now that the kernel has moved. */
1707         bl      .reloc_offset
1708         mr      r26,r3
1710         /* Clear out the BSS. It may have been done in prom_init,
1711          * already but that's irrelevant since prom_init will soon
1712          * be detached from the kernel completely. Besides, we need
1713          * to clear it now for kexec-style entry.
1714          */
1715         LOADADDR(r11,__bss_stop)
1716         LOADADDR(r8,__bss_start)
1717         sub     r11,r11,r8              /* bss size                     */
1718         addi    r11,r11,7               /* round up to an even double word */
1719         rldicl. r11,r11,61,3            /* shift right by 3             */
1720         beq     4f
1721         addi    r8,r8,-8
1722         li      r0,0
1723         mtctr   r11                     /* zero this many doublewords   */
1724 3:      stdu    r0,8(r8)
1725         bdnz    3b
1728         mfmsr   r6
1729         ori     r6,r6,MSR_RI
1730         mtmsrd  r6                      /* RI on */
1732 #ifdef CONFIG_HMT
1733         /* Start up the second thread on cpu 0 */
1734         mfspr   r3,PVR
1735         srwi    r3,r3,16
1736         cmpwi   r3,0x34                 /* Pulsar  */
1737         beq     90f
1738         cmpwi   r3,0x36                 /* Icestar */
1739         beq     90f
1740         cmpwi   r3,0x37                 /* SStar   */
1741         beq     90f
1742         b       91f                     /* HMT not supported */
1743 90:     li      r3,0
1744         bl      .hmt_start_secondary
1746 #endif
1748         /* The following gets the stack and TOC set up with the regs */
1749         /* pointing to the real addr of the kernel stack.  This is   */
1750         /* all done to support the C function call below which sets  */
1751         /* up the htab.  This is done because we have relocated the  */
1752         /* kernel but are still running in real mode. */
1754         LOADADDR(r3,init_thread_union)
1755         sub     r3,r3,r26
1757         /* set up a stack pointer (physical address) */
1758         addi    r1,r3,THREAD_SIZE
1759         li      r0,0
1760         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
1762         /* set up the TOC (physical address) */
1763         LOADADDR(r2,__toc_start)
1764         addi    r2,r2,0x4000
1765         addi    r2,r2,0x4000
1766         sub     r2,r2,r26
1768         LOADADDR(r3,cpu_specs)
1769         sub     r3,r3,r26
1770         LOADADDR(r4,cur_cpu_spec)
1771         sub     r4,r4,r26
1772         mr      r5,r26
1773         bl      .identify_cpu
1775         /* Save some low level config HIDs of CPU0 to be copied to
1776          * other CPUs later on, or used for suspend/resume
1777          */
1778         bl      .__save_cpu_setup
1779         sync
1781         /* Setup a valid physical PACA pointer in SPRG3 for early_setup
1782          * note that boot_cpuid can always be 0 nowadays since there is
1783          * nowhere it can be initialized differently before we reach this
1784          * code
1785          */
1786         LOADADDR(r27, boot_cpuid)
1787         sub     r27,r27,r26
1788         lwz     r27,0(r27)
1790         LOADADDR(r24, paca)             /* Get base vaddr of paca array  */
1791         mulli   r13,r27,PACA_SIZE       /* Calculate vaddr of right paca */
1792         add     r13,r13,r24             /* for this processor.           */
1793         sub     r13,r13,r26             /* convert to physical addr      */
1794         mtspr   SPRG3,r13               /* PPPBBB: Temp... -Peter */
1795         
1796         /* Do very early kernel initializations, including initial hash table,
1797          * stab and slb setup before we turn on relocation.     */
1799         /* Restore parameters passed from prom_init/kexec */
1800         mr      r3,r31
1801         bl      .early_setup
1803         /* set the ASR */
1804         ld      r3,PACASTABREAL(r13)
1805         ori     r4,r3,1                 /* turn on valid bit             */
1806         ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg */
1807         lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
1808         cmpldi  r3,PLATFORM_PSERIES_LPAR
1809         bne     98f
1810         mfspr   r3,PVR
1811         srwi    r3,r3,16
1812         cmpwi   r3,0x37                 /* SStar */
1813         beq     97f
1814         cmpwi   r3,0x36                 /* IStar  */
1815         beq     97f
1816         cmpwi   r3,0x34                 /* Pulsar */
1817         bne     98f
1818 97:     li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
1819         HVSC                            /* Invoking hcall */
1820         b       99f
1821 98:                                     /* !(rpa hypervisor) || !(star) */
1822         mtasr   r4                      /* set the stab location        */
1824         /* Set SDR1 (hash table pointer) */
1825         ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg */
1826         lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
1827         /* Test if bit 0 is set (LPAR bit) */
1828         andi.   r3,r3,0x1
1829         bne     98f
1830         LOADADDR(r6,_SDR1)              /* Only if NOT LPAR */
1831         sub     r6,r6,r26
1832         ld      r6,0(r6)                /* get the value of _SDR1 */
1833         mtspr   SDR1,r6                 /* set the htab location  */
1834 98: 
1835         LOADADDR(r3,.start_here_common)
1836         SET_REG_TO_CONST(r4, MSR_KERNEL)
1837         mtspr   SRR0,r3
1838         mtspr   SRR1,r4
1839         rfid
1840         b       .       /* prevent speculative execution */
1841 #endif /* CONFIG_PPC_MULTIPLATFORM */
1842         
1843         /* This is where all platforms converge execution */
1844 _STATIC(start_here_common)
1845         /* relocation is on at this point */
1847         /* The following code sets up the SP and TOC now that we are */
1848         /* running with translation enabled. */
1850         LOADADDR(r3,init_thread_union)
1852         /* set up the stack */
1853         addi    r1,r3,THREAD_SIZE
1854         li      r0,0
1855         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
1857         /* Apply the CPUs-specific fixups (nop out sections not relevant
1858          * to this CPU
1859          */
1860         li      r3,0
1861         bl      .do_cpu_ftr_fixups
1863         LOADADDR(r26, boot_cpuid)
1864         lwz     r26,0(r26)
1866         LOADADDR(r24, paca)             /* Get base vaddr of paca array  */
1867         mulli   r13,r26,PACA_SIZE       /* Calculate vaddr of right paca */
1868         add     r13,r13,r24             /* for this processor.           */
1869         mtspr   SPRG3,r13
1871         /* ptr to current */
1872         LOADADDR(r4,init_task)
1873         std     r4,PACACURRENT(r13)
1875         /* Load the TOC */
1876         ld      r2,PACATOC(r13)
1877         std     r1,PACAKSAVE(r13)
1879         bl      .setup_system
1881         /* Load up the kernel context */
1883 #ifdef DO_SOFT_DISABLE
1884         li      r5,0
1885         stb     r5,PACAPROCENABLED(r13) /* Soft Disabled */
1886         mfmsr   r5
1887         ori     r5,r5,MSR_EE            /* Hard Enabled */
1888         mtmsrd  r5
1889 #endif
1891         bl .start_kernel
1893 _GLOBAL(hmt_init)
1894 #ifdef CONFIG_HMT
1895         LOADADDR(r5, hmt_thread_data)
1896         mfspr   r7,PVR
1897         srwi    r7,r7,16
1898         cmpwi   r7,0x34                 /* Pulsar  */
1899         beq     90f
1900         cmpwi   r7,0x36                 /* Icestar */
1901         beq     91f
1902         cmpwi   r7,0x37                 /* SStar   */
1903         beq     91f
1904         b       101f
1905 90:     mfspr   r6,PIR
1906         andi.   r6,r6,0x1f
1907         b       92f
1908 91:     mfspr   r6,PIR
1909         andi.   r6,r6,0x3ff
1910 92:     sldi    r4,r24,3
1911         stwx    r6,r5,r4
1912         bl      .hmt_start_secondary
1913         b       101f
1915 __hmt_secondary_hold:
1916         LOADADDR(r5, hmt_thread_data)
1917         clrldi  r5,r5,4
1918         li      r7,0
1919         mfspr   r6,PIR
1920         mfspr   r8,PVR
1921         srwi    r8,r8,16
1922         cmpwi   r8,0x34
1923         bne     93f
1924         andi.   r6,r6,0x1f
1925         b       103f
1926 93:     andi.   r6,r6,0x3f
1928 103:    lwzx    r8,r5,r7
1929         cmpw    r8,r6
1930         beq     104f
1931         addi    r7,r7,8
1932         b       103b
1934 104:    addi    r7,r7,4
1935         lwzx    r9,r5,r7
1936         mr      r24,r9
1937 101:
1938 #endif
1939         mr      r3,r24
1940         b       .pSeries_secondary_smp_init
1942 #ifdef CONFIG_HMT
1943 _GLOBAL(hmt_start_secondary)
1944         LOADADDR(r4,__hmt_secondary_hold)
1945         clrldi  r4,r4,4
1946         mtspr   NIADORM, r4
1947         mfspr   r4, MSRDORM
1948         li      r5, -65
1949         and     r4, r4, r5
1950         mtspr   MSRDORM, r4
1951         lis     r4,0xffef
1952         ori     r4,r4,0x7403
1953         mtspr   TSC, r4
1954         li      r4,0x1f4
1955         mtspr   TST, r4
1956         mfspr   r4, HID0
1957         ori     r4, r4, 0x1
1958         mtspr   HID0, r4
1959         mfspr   r4, SPRN_CTRLF
1960         oris    r4, r4, 0x40
1961         mtspr   SPRN_CTRLT, r4
1962         blr
1963 #endif
1965 #if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES))
1966 _GLOBAL(smp_release_cpus)
1967         /* All secondary cpus are spinning on a common
1968          * spinloop, release them all now so they can start
1969          * to spin on their individual paca spinloops.
1970          * For non SMP kernels, the secondary cpus never
1971          * get out of the common spinloop.
1972          */
1973         li      r3,1
1974         LOADADDR(r5,__secondary_hold_spinloop)
1975         std     r3,0(r5)
1976         sync
1977         blr
1978 #endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */
1982  * We put a few things here that have to be page-aligned.
1983  * This stuff goes at the beginning of the bss, which is page-aligned.
1984  */
1985         .section ".bss"
1987         .align  12
1989         .globl  empty_zero_page
1990 empty_zero_page:
1991         .space  PAGE_SIZE
1993         .globl  swapper_pg_dir
1994 swapper_pg_dir:
1995         .space  PAGE_SIZE
1998  * This space gets a copy of optional info passed to us by the bootstrap
1999  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
2000  */
2001         .globl  cmd_line
2002 cmd_line:
2003         .space  COMMAND_LINE_SIZE