Merge tag 'io_uring-5.13-2021-05-14' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / arch / powerpc / kernel / exceptions-64e.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *  Boot code and exception vectors for Book3E processors
4  *
5  *  Copyright (C) 2007 Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
6  */
7
8 #include <linux/threads.h>
9 #include <asm/reg.h>
10 #include <asm/page.h>
11 #include <asm/ppc_asm.h>
12 #include <asm/asm-offsets.h>
13 #include <asm/cputable.h>
14 #include <asm/setup.h>
15 #include <asm/thread_info.h>
16 #include <asm/reg_a2.h>
17 #include <asm/exception-64e.h>
18 #include <asm/bug.h>
19 #include <asm/irqflags.h>
20 #include <asm/ptrace.h>
21 #include <asm/ppc-opcode.h>
22 #include <asm/mmu.h>
23 #include <asm/hw_irq.h>
24 #include <asm/kvm_asm.h>
25 #include <asm/kvm_booke_hv_asm.h>
26 #include <asm/feature-fixups.h>
27 #include <asm/context_tracking.h>
28
29 /* XXX This will ultimately add space for a special exception save
30  *     structure used to save things like SRR0/SRR1, SPRGs, MAS, etc...
31  *     when taking special interrupts. For now we don't support that,
32  *     special interrupts from within a non-standard level will probably
33  *     blow you up
34  */
35 #define SPECIAL_EXC_SRR0        0
36 #define SPECIAL_EXC_SRR1        1
37 #define SPECIAL_EXC_SPRG_GEN    2
38 #define SPECIAL_EXC_SPRG_TLB    3
39 #define SPECIAL_EXC_MAS0        4
40 #define SPECIAL_EXC_MAS1        5
41 #define SPECIAL_EXC_MAS2        6
42 #define SPECIAL_EXC_MAS3        7
43 #define SPECIAL_EXC_MAS6        8
44 #define SPECIAL_EXC_MAS7        9
45 #define SPECIAL_EXC_MAS5        10      /* E.HV only */
46 #define SPECIAL_EXC_MAS8        11      /* E.HV only */
47 #define SPECIAL_EXC_IRQHAPPENED 12
48 #define SPECIAL_EXC_DEAR        13
49 #define SPECIAL_EXC_ESR         14
50 #define SPECIAL_EXC_SOFTE       15
51 #define SPECIAL_EXC_CSRR0       16
52 #define SPECIAL_EXC_CSRR1       17
53 /* must be even to keep 16-byte stack alignment */
54 #define SPECIAL_EXC_END         18
55
56 #define SPECIAL_EXC_FRAME_SIZE  (INT_FRAME_SIZE + SPECIAL_EXC_END * 8)
57 #define SPECIAL_EXC_FRAME_OFFS  (INT_FRAME_SIZE - 288)
58
59 #define SPECIAL_EXC_STORE(reg, name) \
60         std     reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1)
61
62 #define SPECIAL_EXC_LOAD(reg, name) \
63         ld      reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1)
64
65 special_reg_save:
66         /*
67          * We only need (or have stack space) to save this stuff if
68          * we interrupted the kernel.
69          */
70         ld      r3,_MSR(r1)
71         andi.   r3,r3,MSR_PR
72         bnelr
73
74         /*
75          * Advance to the next TLB exception frame for handler
76          * types that don't do it automatically.
77          */
78         LOAD_REG_ADDR(r11,extlb_level_exc)
79         lwz     r12,0(r11)
80         mfspr   r10,SPRN_SPRG_TLB_EXFRAME
81         add     r10,r10,r12
82         mtspr   SPRN_SPRG_TLB_EXFRAME,r10
83
84         /*
85          * Save registers needed to allow nesting of certain exceptions
86          * (such as TLB misses) inside special exception levels
87          */
88         mfspr   r10,SPRN_SRR0
89         SPECIAL_EXC_STORE(r10,SRR0)
90         mfspr   r10,SPRN_SRR1
91         SPECIAL_EXC_STORE(r10,SRR1)
92         mfspr   r10,SPRN_SPRG_GEN_SCRATCH
93         SPECIAL_EXC_STORE(r10,SPRG_GEN)
94         mfspr   r10,SPRN_SPRG_TLB_SCRATCH
95         SPECIAL_EXC_STORE(r10,SPRG_TLB)
96         mfspr   r10,SPRN_MAS0
97         SPECIAL_EXC_STORE(r10,MAS0)
98         mfspr   r10,SPRN_MAS1
99         SPECIAL_EXC_STORE(r10,MAS1)
100         mfspr   r10,SPRN_MAS2
101         SPECIAL_EXC_STORE(r10,MAS2)
102         mfspr   r10,SPRN_MAS3
103         SPECIAL_EXC_STORE(r10,MAS3)
104         mfspr   r10,SPRN_MAS6
105         SPECIAL_EXC_STORE(r10,MAS6)
106         mfspr   r10,SPRN_MAS7
107         SPECIAL_EXC_STORE(r10,MAS7)
108 BEGIN_FTR_SECTION
109         mfspr   r10,SPRN_MAS5
110         SPECIAL_EXC_STORE(r10,MAS5)
111         mfspr   r10,SPRN_MAS8
112         SPECIAL_EXC_STORE(r10,MAS8)
113
114         /* MAS5/8 could have inappropriate values if we interrupted KVM code */
115         li      r10,0
116         mtspr   SPRN_MAS5,r10
117         mtspr   SPRN_MAS8,r10
118 END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
119         mfspr   r10,SPRN_DEAR
120         SPECIAL_EXC_STORE(r10,DEAR)
121         mfspr   r10,SPRN_ESR
122         SPECIAL_EXC_STORE(r10,ESR)
123
124         ld      r10,_NIP(r1)
125         SPECIAL_EXC_STORE(r10,CSRR0)
126         ld      r10,_MSR(r1)
127         SPECIAL_EXC_STORE(r10,CSRR1)
128
129         blr
130
131 ret_from_level_except:
132         ld      r3,_MSR(r1)
133         andi.   r3,r3,MSR_PR
134         beq     1f
135         REST_NVGPRS(r1)
136         b       interrupt_return
137 1:
138
139         LOAD_REG_ADDR(r11,extlb_level_exc)
140         lwz     r12,0(r11)
141         mfspr   r10,SPRN_SPRG_TLB_EXFRAME
142         sub     r10,r10,r12
143         mtspr   SPRN_SPRG_TLB_EXFRAME,r10
144
145         /*
146          * It's possible that the special level exception interrupted a
147          * TLB miss handler, and inserted the same entry that the
148          * interrupted handler was about to insert.  On CPUs without TLB
149          * write conditional, this can result in a duplicate TLB entry.
150          * Wipe all non-bolted entries to be safe.
151          *
152          * Note that this doesn't protect against any TLB misses
153          * we may take accessing the stack from here to the end of
154          * the special level exception.  It's not clear how we can
155          * reasonably protect against that, but only CPUs with
156          * neither TLB write conditional nor bolted kernel memory
157          * are affected.  Do any such CPUs even exist?
158          */
159         PPC_TLBILX_ALL(0,R0)
160
161         REST_NVGPRS(r1)
162
163         SPECIAL_EXC_LOAD(r10,SRR0)
164         mtspr   SPRN_SRR0,r10
165         SPECIAL_EXC_LOAD(r10,SRR1)
166         mtspr   SPRN_SRR1,r10
167         SPECIAL_EXC_LOAD(r10,SPRG_GEN)
168         mtspr   SPRN_SPRG_GEN_SCRATCH,r10
169         SPECIAL_EXC_LOAD(r10,SPRG_TLB)
170         mtspr   SPRN_SPRG_TLB_SCRATCH,r10
171         SPECIAL_EXC_LOAD(r10,MAS0)
172         mtspr   SPRN_MAS0,r10
173         SPECIAL_EXC_LOAD(r10,MAS1)
174         mtspr   SPRN_MAS1,r10
175         SPECIAL_EXC_LOAD(r10,MAS2)
176         mtspr   SPRN_MAS2,r10
177         SPECIAL_EXC_LOAD(r10,MAS3)
178         mtspr   SPRN_MAS3,r10
179         SPECIAL_EXC_LOAD(r10,MAS6)
180         mtspr   SPRN_MAS6,r10
181         SPECIAL_EXC_LOAD(r10,MAS7)
182         mtspr   SPRN_MAS7,r10
183 BEGIN_FTR_SECTION
184         SPECIAL_EXC_LOAD(r10,MAS5)
185         mtspr   SPRN_MAS5,r10
186         SPECIAL_EXC_LOAD(r10,MAS8)
187         mtspr   SPRN_MAS8,r10
188 END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
189
190         SPECIAL_EXC_LOAD(r10,DEAR)
191         mtspr   SPRN_DEAR,r10
192         SPECIAL_EXC_LOAD(r10,ESR)
193         mtspr   SPRN_ESR,r10
194
195         stdcx.  r0,0,r1         /* to clear the reservation */
196
197         REST_4GPRS(2, r1)
198         REST_4GPRS(6, r1)
199
200         ld      r10,_CTR(r1)
201         ld      r11,_XER(r1)
202         mtctr   r10
203         mtxer   r11
204
205         blr
206
207 .macro ret_from_level srr0 srr1 paca_ex scratch
208         bl      ret_from_level_except
209
210         ld      r10,_LINK(r1)
211         ld      r11,_CCR(r1)
212         ld      r0,GPR13(r1)
213         mtlr    r10
214         mtcr    r11
215
216         ld      r10,GPR10(r1)
217         ld      r11,GPR11(r1)
218         ld      r12,GPR12(r1)
219         mtspr   \scratch,r0
220
221         std     r10,\paca_ex+EX_R10(r13);
222         std     r11,\paca_ex+EX_R11(r13);
223         ld      r10,_NIP(r1)
224         ld      r11,_MSR(r1)
225         ld      r0,GPR0(r1)
226         ld      r1,GPR1(r1)
227         mtspr   \srr0,r10
228         mtspr   \srr1,r11
229         ld      r10,\paca_ex+EX_R10(r13)
230         ld      r11,\paca_ex+EX_R11(r13)
231         mfspr   r13,\scratch
232 .endm
233
234 ret_from_crit_except:
235         ret_from_level SPRN_CSRR0 SPRN_CSRR1 PACA_EXCRIT SPRN_SPRG_CRIT_SCRATCH
236         rfci
237
238 ret_from_mc_except:
239         ret_from_level SPRN_MCSRR0 SPRN_MCSRR1 PACA_EXMC SPRN_SPRG_MC_SCRATCH
240         rfmci
241
242 /* Exception prolog code for all exceptions */
243 #define EXCEPTION_PROLOG(n, intnum, type, addition)                         \
244         mtspr   SPRN_SPRG_##type##_SCRATCH,r13; /* get spare registers */   \
245         mfspr   r13,SPRN_SPRG_PACA;     /* get PACA */                      \
246         std     r10,PACA_EX##type+EX_R10(r13);                              \
247         std     r11,PACA_EX##type+EX_R11(r13);                              \
248         mfcr    r10;                    /* save CR */                       \
249         mfspr   r11,SPRN_##type##_SRR1;/* what are we coming from */        \
250         DO_KVM  intnum,SPRN_##type##_SRR1;    /* KVM hook */                \
251         stw     r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \
252         addition;                       /* additional code for that exc. */ \
253         std     r1,PACA_EX##type+EX_R1(r13); /* save old r1 in the PACA */  \
254         type##_SET_KSTACK;              /* get special stack if necessary */\
255         andi.   r10,r11,MSR_PR;         /* save stack pointer */            \
256         beq     1f;                     /* branch around if supervisor */   \
257         ld      r1,PACAKSAVE(r13);      /* get kernel stack coming from usr */\
258 1:      type##_BTB_FLUSH                \
259         cmpdi   cr1,r1,0;               /* check if SP makes sense */       \
260         bge-    cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \
261         mfspr   r10,SPRN_##type##_SRR0; /* read SRR0 before touching stack */
262
263 /* Exception type-specific macros */
264 #define GEN_SET_KSTACK                                                      \
265         subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack */
266 #define SPRN_GEN_SRR0   SPRN_SRR0
267 #define SPRN_GEN_SRR1   SPRN_SRR1
268
269 #define GDBELL_SET_KSTACK       GEN_SET_KSTACK
270 #define SPRN_GDBELL_SRR0        SPRN_GSRR0
271 #define SPRN_GDBELL_SRR1        SPRN_GSRR1
272
273 #define CRIT_SET_KSTACK                                                     \
274         ld      r1,PACA_CRIT_STACK(r13);                                    \
275         subi    r1,r1,SPECIAL_EXC_FRAME_SIZE
276 #define SPRN_CRIT_SRR0  SPRN_CSRR0
277 #define SPRN_CRIT_SRR1  SPRN_CSRR1
278
279 #define DBG_SET_KSTACK                                                      \
280         ld      r1,PACA_DBG_STACK(r13);                                     \
281         subi    r1,r1,SPECIAL_EXC_FRAME_SIZE
282 #define SPRN_DBG_SRR0   SPRN_DSRR0
283 #define SPRN_DBG_SRR1   SPRN_DSRR1
284
285 #define MC_SET_KSTACK                                                       \
286         ld      r1,PACA_MC_STACK(r13);                                      \
287         subi    r1,r1,SPECIAL_EXC_FRAME_SIZE
288 #define SPRN_MC_SRR0    SPRN_MCSRR0
289 #define SPRN_MC_SRR1    SPRN_MCSRR1
290
291 #ifdef CONFIG_PPC_FSL_BOOK3E
292 #define GEN_BTB_FLUSH                   \
293         START_BTB_FLUSH_SECTION         \
294                 beq 1f;                 \
295                 BTB_FLUSH(r10)                  \
296                 1:              \
297         END_BTB_FLUSH_SECTION
298
299 #define CRIT_BTB_FLUSH                  \
300         START_BTB_FLUSH_SECTION         \
301                 BTB_FLUSH(r10)          \
302         END_BTB_FLUSH_SECTION
303
304 #define DBG_BTB_FLUSH CRIT_BTB_FLUSH
305 #define MC_BTB_FLUSH CRIT_BTB_FLUSH
306 #define GDBELL_BTB_FLUSH GEN_BTB_FLUSH
307 #else
308 #define GEN_BTB_FLUSH
309 #define CRIT_BTB_FLUSH
310 #define DBG_BTB_FLUSH
311 #define MC_BTB_FLUSH
312 #define GDBELL_BTB_FLUSH
313 #endif
314
315 #define NORMAL_EXCEPTION_PROLOG(n, intnum, addition)                        \
316         EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n))
317
318 #define CRIT_EXCEPTION_PROLOG(n, intnum, addition)                          \
319         EXCEPTION_PROLOG(n, intnum, CRIT, addition##_CRIT(n))
320
321 #define DBG_EXCEPTION_PROLOG(n, intnum, addition)                           \
322         EXCEPTION_PROLOG(n, intnum, DBG, addition##_DBG(n))
323
324 #define MC_EXCEPTION_PROLOG(n, intnum, addition)                            \
325         EXCEPTION_PROLOG(n, intnum, MC, addition##_MC(n))
326
327 #define GDBELL_EXCEPTION_PROLOG(n, intnum, addition)                        \
328         EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n))
329
330 /* Variants of the "addition" argument for the prolog
331  */
332 #define PROLOG_ADDITION_NONE_GEN(n)
333 #define PROLOG_ADDITION_NONE_GDBELL(n)
334 #define PROLOG_ADDITION_NONE_CRIT(n)
335 #define PROLOG_ADDITION_NONE_DBG(n)
336 #define PROLOG_ADDITION_NONE_MC(n)
337
338 #define PROLOG_ADDITION_MASKABLE_GEN(n)                                     \
339         lbz     r10,PACAIRQSOFTMASK(r13);       /* are irqs soft-masked? */ \
340         andi.   r10,r10,IRQS_DISABLED;  /* yes -> go out of line */ \
341         bne     masked_interrupt_book3e_##n
342
343 #define PROLOG_ADDITION_2REGS_GEN(n)                                        \
344         std     r14,PACA_EXGEN+EX_R14(r13);                                 \
345         std     r15,PACA_EXGEN+EX_R15(r13)
346
347 #define PROLOG_ADDITION_1REG_GEN(n)                                         \
348         std     r14,PACA_EXGEN+EX_R14(r13);
349
350 #define PROLOG_ADDITION_2REGS_CRIT(n)                                       \
351         std     r14,PACA_EXCRIT+EX_R14(r13);                                \
352         std     r15,PACA_EXCRIT+EX_R15(r13)
353
354 #define PROLOG_ADDITION_2REGS_DBG(n)                                        \
355         std     r14,PACA_EXDBG+EX_R14(r13);                                 \
356         std     r15,PACA_EXDBG+EX_R15(r13)
357
358 #define PROLOG_ADDITION_2REGS_MC(n)                                         \
359         std     r14,PACA_EXMC+EX_R14(r13);                                  \
360         std     r15,PACA_EXMC+EX_R15(r13)
361
362
363 /* Core exception code for all exceptions except TLB misses. */
364 #define EXCEPTION_COMMON_LVL(n, scratch, excf)                              \
365 exc_##n##_common:                                                           \
366         std     r0,GPR0(r1);            /* save r0 in stackframe */         \
367         std     r2,GPR2(r1);            /* save r2 in stackframe */         \
368         SAVE_4GPRS(3, r1);              /* save r3 - r6 in stackframe */    \
369         SAVE_2GPRS(7, r1);              /* save r7, r8 in stackframe */     \
370         std     r9,GPR9(r1);            /* save r9 in stackframe */         \
371         std     r10,_NIP(r1);           /* save SRR0 to stackframe */       \
372         std     r11,_MSR(r1);           /* save SRR1 to stackframe */       \
373         beq     2f;                     /* if from kernel mode */           \
374 2:      ld      r3,excf+EX_R10(r13);    /* get back r10 */                  \
375         ld      r4,excf+EX_R11(r13);    /* get back r11 */                  \
376         mfspr   r5,scratch;             /* get back r13 */                  \
377         std     r12,GPR12(r1);          /* save r12 in stackframe */        \
378         ld      r2,PACATOC(r13);        /* get kernel TOC into r2 */        \
379         mflr    r6;                     /* save LR in stackframe */         \
380         mfctr   r7;                     /* save CTR in stackframe */        \
381         mfspr   r8,SPRN_XER;            /* save XER in stackframe */        \
382         ld      r9,excf+EX_R1(r13);     /* load orig r1 back from PACA */   \
383         lwz     r10,excf+EX_CR(r13);    /* load orig CR back from PACA  */  \
384         lbz     r11,PACAIRQSOFTMASK(r13); /* get current IRQ softe */       \
385         ld      r12,exception_marker@toc(r2);                               \
386         li      r0,0;                                                       \
387         std     r3,GPR10(r1);           /* save r10 to stackframe */        \
388         std     r4,GPR11(r1);           /* save r11 to stackframe */        \
389         std     r5,GPR13(r1);           /* save it to stackframe */         \
390         std     r6,_LINK(r1);                                               \
391         std     r7,_CTR(r1);                                                \
392         std     r8,_XER(r1);                                                \
393         li      r3,(n);                 /* regs.trap vector */              \
394         std     r9,0(r1);               /* store stack frame back link */   \
395         std     r10,_CCR(r1);           /* store orig CR in stackframe */   \
396         std     r9,GPR1(r1);            /* store stack frame back link */   \
397         std     r11,SOFTE(r1);          /* and save it to stackframe */     \
398         std     r12,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */       \
399         std     r3,_TRAP(r1);           /* set trap number              */  \
400         std     r0,RESULT(r1);          /* clear regs->result */            \
401         SAVE_NVGPRS(r1);
402
403 #define EXCEPTION_COMMON(n) \
404         EXCEPTION_COMMON_LVL(n, SPRN_SPRG_GEN_SCRATCH, PACA_EXGEN)
405 #define EXCEPTION_COMMON_CRIT(n) \
406         EXCEPTION_COMMON_LVL(n, SPRN_SPRG_CRIT_SCRATCH, PACA_EXCRIT)
407 #define EXCEPTION_COMMON_MC(n) \
408         EXCEPTION_COMMON_LVL(n, SPRN_SPRG_MC_SCRATCH, PACA_EXMC)
409 #define EXCEPTION_COMMON_DBG(n) \
410         EXCEPTION_COMMON_LVL(n, SPRN_SPRG_DBG_SCRATCH, PACA_EXDBG)
411
412 /* XXX FIXME: Restore r14/r15 when necessary */
413 #define BAD_STACK_TRAMPOLINE(n)                                             \
414 exc_##n##_bad_stack:                                                        \
415         li      r1,(n);                 /* get exception number */          \
416         sth     r1,PACA_TRAP_SAVE(r13); /* store trap */                    \
417         b       bad_stack_book3e;       /* bad stack error */
418
419 /* WARNING: If you change the layout of this stub, make sure you check
420         *   the debug exception handler which handles single stepping
421         *   into exceptions from userspace, and the MM code in
422         *   arch/powerpc/mm/tlb_nohash.c which patches the branch here
423         *   and would need to be updated if that branch is moved
424         */
425 #define EXCEPTION_STUB(loc, label)                                      \
426         . = interrupt_base_book3e + loc;                                \
427         nop;    /* To make debug interrupts happy */                    \
428         b       exc_##label##_book3e;
429
430 #define ACK_NONE(r)
431 #define ACK_DEC(r)                                                      \
432         lis     r,TSR_DIS@h;                                            \
433         mtspr   SPRN_TSR,r
434 #define ACK_FIT(r)                                                      \
435         lis     r,TSR_FIS@h;                                            \
436         mtspr   SPRN_TSR,r
437
438 /* Used by asynchronous interrupt that may happen in the idle loop.
439  *
440  * This check if the thread was in the idle loop, and if yes, returns
441  * to the caller rather than the PC. This is to avoid a race if
442  * interrupts happen before the wait instruction.
443  */
444 #define CHECK_NAPPING()                                                 \
445         ld      r11, PACA_THREAD_INFO(r13);                             \
446         ld      r10,TI_LOCAL_FLAGS(r11);                                \
447         andi.   r9,r10,_TLF_NAPPING;                                    \
448         beq+    1f;                                                     \
449         ld      r8,_LINK(r1);                                           \
450         rlwinm  r7,r10,0,~_TLF_NAPPING;                                 \
451         std     r8,_NIP(r1);                                            \
452         std     r7,TI_LOCAL_FLAGS(r11);                                 \
453 1:
454
455
456 #define MASKABLE_EXCEPTION(trapnum, intnum, label, hdlr, ack)           \
457         START_EXCEPTION(label);                                         \
458         NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
459         EXCEPTION_COMMON(trapnum)                                       \
460         ack(r8);                                                        \
461         CHECK_NAPPING();                                                \
462         addi    r3,r1,STACK_FRAME_OVERHEAD;                             \
463         bl      hdlr;                                                   \
464         b       interrupt_return
465
466 /* This value is used to mark exception frames on the stack. */
467         .section        ".toc","aw"
468 exception_marker:
469         .tc     ID_EXC_MARKER[TC],STACK_FRAME_REGS_MARKER
470
471
472 /*
473  * And here we have the exception vectors !
474  */
475
476         .text
477         .balign 0x1000
478         .globl interrupt_base_book3e
479 interrupt_base_book3e:                                  /* fake trap */
480         EXCEPTION_STUB(0x000, machine_check)
481         EXCEPTION_STUB(0x020, critical_input)           /* 0x0100 */
482         EXCEPTION_STUB(0x040, debug_crit)               /* 0x0d00 */
483         EXCEPTION_STUB(0x060, data_storage)             /* 0x0300 */
484         EXCEPTION_STUB(0x080, instruction_storage)      /* 0x0400 */
485         EXCEPTION_STUB(0x0a0, external_input)           /* 0x0500 */
486         EXCEPTION_STUB(0x0c0, alignment)                /* 0x0600 */
487         EXCEPTION_STUB(0x0e0, program)                  /* 0x0700 */
488         EXCEPTION_STUB(0x100, fp_unavailable)           /* 0x0800 */
489         EXCEPTION_STUB(0x120, system_call)              /* 0x0c00 */
490         EXCEPTION_STUB(0x140, ap_unavailable)           /* 0x0f20 */
491         EXCEPTION_STUB(0x160, decrementer)              /* 0x0900 */
492         EXCEPTION_STUB(0x180, fixed_interval)           /* 0x0980 */
493         EXCEPTION_STUB(0x1a0, watchdog)                 /* 0x09f0 */
494         EXCEPTION_STUB(0x1c0, data_tlb_miss)
495         EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
496         EXCEPTION_STUB(0x200, altivec_unavailable)
497         EXCEPTION_STUB(0x220, altivec_assist)
498         EXCEPTION_STUB(0x260, perfmon)
499         EXCEPTION_STUB(0x280, doorbell)
500         EXCEPTION_STUB(0x2a0, doorbell_crit)
501         EXCEPTION_STUB(0x2c0, guest_doorbell)
502         EXCEPTION_STUB(0x2e0, guest_doorbell_crit)
503         EXCEPTION_STUB(0x300, hypercall)
504         EXCEPTION_STUB(0x320, ehpriv)
505         EXCEPTION_STUB(0x340, lrat_error)
506
507         .globl __end_interrupts
508 __end_interrupts:
509
510 /* Critical Input Interrupt */
511         START_EXCEPTION(critical_input);
512         CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL,
513                               PROLOG_ADDITION_NONE)
514         EXCEPTION_COMMON_CRIT(0x100)
515         bl      special_reg_save
516         CHECK_NAPPING();
517         addi    r3,r1,STACK_FRAME_OVERHEAD
518         bl      unknown_nmi_exception
519         b       ret_from_crit_except
520
521 /* Machine Check Interrupt */
522         START_EXCEPTION(machine_check);
523         MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK,
524                             PROLOG_ADDITION_NONE)
525         EXCEPTION_COMMON_MC(0x000)
526         bl      special_reg_save
527         CHECK_NAPPING();
528         addi    r3,r1,STACK_FRAME_OVERHEAD
529         bl      machine_check_exception
530         b       ret_from_mc_except
531
532 /* Data Storage Interrupt */
533         START_EXCEPTION(data_storage)
534         NORMAL_EXCEPTION_PROLOG(0x300, BOOKE_INTERRUPT_DATA_STORAGE,
535                                 PROLOG_ADDITION_2REGS)
536         mfspr   r14,SPRN_DEAR
537         mfspr   r15,SPRN_ESR
538         EXCEPTION_COMMON(0x300)
539         b       storage_fault_common
540
541 /* Instruction Storage Interrupt */
542         START_EXCEPTION(instruction_storage);
543         NORMAL_EXCEPTION_PROLOG(0x400, BOOKE_INTERRUPT_INST_STORAGE,
544                                 PROLOG_ADDITION_2REGS)
545         li      r15,0
546         mr      r14,r10
547         EXCEPTION_COMMON(0x400)
548         b       storage_fault_common
549
550 /* External Input Interrupt */
551         MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL,
552                            external_input, do_IRQ, ACK_NONE)
553
554 /* Alignment */
555         START_EXCEPTION(alignment);
556         NORMAL_EXCEPTION_PROLOG(0x600, BOOKE_INTERRUPT_ALIGNMENT,
557                                 PROLOG_ADDITION_2REGS)
558         mfspr   r14,SPRN_DEAR
559         mfspr   r15,SPRN_ESR
560         EXCEPTION_COMMON(0x600)
561         b       alignment_more  /* no room, go out of line */
562
563 /* Program Interrupt */
564         START_EXCEPTION(program);
565         NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM,
566                                 PROLOG_ADDITION_1REG)
567         mfspr   r14,SPRN_ESR
568         EXCEPTION_COMMON(0x700)
569         std     r14,_DSISR(r1)
570         addi    r3,r1,STACK_FRAME_OVERHEAD
571         ld      r14,PACA_EXGEN+EX_R14(r13)
572         bl      program_check_exception
573         REST_NVGPRS(r1)
574         b       interrupt_return
575
576 /* Floating Point Unavailable Interrupt */
577         START_EXCEPTION(fp_unavailable);
578         NORMAL_EXCEPTION_PROLOG(0x800, BOOKE_INTERRUPT_FP_UNAVAIL,
579                                 PROLOG_ADDITION_NONE)
580         /* we can probably do a shorter exception entry for that one... */
581         EXCEPTION_COMMON(0x800)
582         ld      r12,_MSR(r1)
583         andi.   r0,r12,MSR_PR;
584         beq-    1f
585         bl      load_up_fpu
586         b       fast_interrupt_return
587 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
588         bl      kernel_fp_unavailable_exception
589         b       interrupt_return
590
591 /* Altivec Unavailable Interrupt */
592         START_EXCEPTION(altivec_unavailable);
593         NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL,
594                                 PROLOG_ADDITION_NONE)
595         /* we can probably do a shorter exception entry for that one... */
596         EXCEPTION_COMMON(0x200)
597 #ifdef CONFIG_ALTIVEC
598 BEGIN_FTR_SECTION
599         ld      r12,_MSR(r1)
600         andi.   r0,r12,MSR_PR;
601         beq-    1f
602         bl      load_up_altivec
603         b       fast_interrupt_return
604 1:
605 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
606 #endif
607         addi    r3,r1,STACK_FRAME_OVERHEAD
608         bl      altivec_unavailable_exception
609         b       interrupt_return
610
611 /* AltiVec Assist */
612         START_EXCEPTION(altivec_assist);
613         NORMAL_EXCEPTION_PROLOG(0x220,
614                                 BOOKE_INTERRUPT_ALTIVEC_ASSIST,
615                                 PROLOG_ADDITION_NONE)
616         EXCEPTION_COMMON(0x220)
617         addi    r3,r1,STACK_FRAME_OVERHEAD
618 #ifdef CONFIG_ALTIVEC
619 BEGIN_FTR_SECTION
620         bl      altivec_assist_exception
621 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
622         REST_NVGPRS(r1)
623 #else
624         bl      unknown_exception
625 #endif
626         b       interrupt_return
627
628
629 /* Decrementer Interrupt */
630         MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER,
631                            decrementer, timer_interrupt, ACK_DEC)
632
633 /* Fixed Interval Timer Interrupt */
634         MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT,
635                            fixed_interval, unknown_exception, ACK_FIT)
636
637 /* Watchdog Timer Interrupt */
638         START_EXCEPTION(watchdog);
639         CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG,
640                               PROLOG_ADDITION_NONE)
641         EXCEPTION_COMMON_CRIT(0x9f0)
642         bl      special_reg_save
643         CHECK_NAPPING();
644         addi    r3,r1,STACK_FRAME_OVERHEAD
645 #ifdef CONFIG_BOOKE_WDT
646         bl      WatchdogException
647 #else
648         bl      unknown_nmi_exception
649 #endif
650         b       ret_from_crit_except
651
652 /* System Call Interrupt */
653         START_EXCEPTION(system_call)
654         mr      r9,r13                  /* keep a copy of userland r13 */
655         mfspr   r11,SPRN_SRR0           /* get return address */
656         mfspr   r12,SPRN_SRR1           /* get previous MSR */
657         mfspr   r13,SPRN_SPRG_PACA      /* get our PACA */
658         b       system_call_common
659
660 /* Auxiliary Processor Unavailable Interrupt */
661         START_EXCEPTION(ap_unavailable);
662         NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
663                                 PROLOG_ADDITION_NONE)
664         EXCEPTION_COMMON(0xf20)
665         addi    r3,r1,STACK_FRAME_OVERHEAD
666         bl      unknown_exception
667         b       interrupt_return
668
669 /* Debug exception as a critical interrupt*/
670         START_EXCEPTION(debug_crit);
671         CRIT_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG,
672                               PROLOG_ADDITION_2REGS)
673
674         /*
675          * If there is a single step or branch-taken exception in an
676          * exception entry sequence, it was probably meant to apply to
677          * the code where the exception occurred (since exception entry
678          * doesn't turn off DE automatically).  We simulate the effect
679          * of turning off DE on entry to an exception handler by turning
680          * off DE in the CSRR1 value and clearing the debug status.
681          */
682
683         mfspr   r14,SPRN_DBSR           /* check single-step/branch taken */
684         andis.  r15,r14,(DBSR_IC|DBSR_BT)@h
685         beq+    1f
686
687 #ifdef CONFIG_RELOCATABLE
688         ld      r15,PACATOC(r13)
689         ld      r14,interrupt_base_book3e@got(r15)
690         ld      r15,__end_interrupts@got(r15)
691         cmpld   cr0,r10,r14
692         cmpld   cr1,r10,r15
693 #else
694         LOAD_REG_IMMEDIATE_SYM(r14, r15, interrupt_base_book3e)
695         cmpld   cr0, r10, r14
696         LOAD_REG_IMMEDIATE_SYM(r14, r15, __end_interrupts)
697         cmpld   cr1, r10, r14
698 #endif
699         blt+    cr0,1f
700         bge+    cr1,1f
701
702         /* here it looks like we got an inappropriate debug exception. */
703         lis     r14,(DBSR_IC|DBSR_BT)@h         /* clear the event */
704         rlwinm  r11,r11,0,~MSR_DE       /* clear DE in the CSRR1 value */
705         mtspr   SPRN_DBSR,r14
706         mtspr   SPRN_CSRR1,r11
707         lwz     r10,PACA_EXCRIT+EX_CR(r13)      /* restore registers */
708         ld      r1,PACA_EXCRIT+EX_R1(r13)
709         ld      r14,PACA_EXCRIT+EX_R14(r13)
710         ld      r15,PACA_EXCRIT+EX_R15(r13)
711         mtcr    r10
712         ld      r10,PACA_EXCRIT+EX_R10(r13)     /* restore registers */
713         ld      r11,PACA_EXCRIT+EX_R11(r13)
714         mfspr   r13,SPRN_SPRG_CRIT_SCRATCH
715         rfci
716
717         /* Normal debug exception */
718         /* XXX We only handle coming from userspace for now since we can't
719          *     quite save properly an interrupted kernel state yet
720          */
721 1:      andi.   r14,r11,MSR_PR;         /* check for userspace again */
722         beq     kernel_dbg_exc;         /* if from kernel mode */
723
724         /* Now we mash up things to make it look like we are coming on a
725          * normal exception
726          */
727         mfspr   r14,SPRN_DBSR
728         EXCEPTION_COMMON_CRIT(0xd00)
729         std     r14,_DSISR(r1)
730         addi    r3,r1,STACK_FRAME_OVERHEAD
731         ld      r14,PACA_EXCRIT+EX_R14(r13)
732         ld      r15,PACA_EXCRIT+EX_R15(r13)
733         bl      DebugException
734         REST_NVGPRS(r1)
735         b       interrupt_return
736
737 kernel_dbg_exc:
738         b       .       /* NYI */
739
740 /* Debug exception as a debug interrupt*/
741         START_EXCEPTION(debug_debug);
742         DBG_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG,
743                                                  PROLOG_ADDITION_2REGS)
744
745         /*
746          * If there is a single step or branch-taken exception in an
747          * exception entry sequence, it was probably meant to apply to
748          * the code where the exception occurred (since exception entry
749          * doesn't turn off DE automatically).  We simulate the effect
750          * of turning off DE on entry to an exception handler by turning
751          * off DE in the DSRR1 value and clearing the debug status.
752          */
753
754         mfspr   r14,SPRN_DBSR           /* check single-step/branch taken */
755         andis.  r15,r14,(DBSR_IC|DBSR_BT)@h
756         beq+    1f
757
758 #ifdef CONFIG_RELOCATABLE
759         ld      r15,PACATOC(r13)
760         ld      r14,interrupt_base_book3e@got(r15)
761         ld      r15,__end_interrupts@got(r15)
762         cmpld   cr0,r10,r14
763         cmpld   cr1,r10,r15
764 #else
765         LOAD_REG_IMMEDIATE_SYM(r14, r15, interrupt_base_book3e)
766         cmpld   cr0, r10, r14
767         LOAD_REG_IMMEDIATE_SYM(r14, r15,__end_interrupts)
768         cmpld   cr1, r10, r14
769 #endif
770         blt+    cr0,1f
771         bge+    cr1,1f
772
773         /* here it looks like we got an inappropriate debug exception. */
774         lis     r14,(DBSR_IC|DBSR_BT)@h         /* clear the event */
775         rlwinm  r11,r11,0,~MSR_DE       /* clear DE in the DSRR1 value */
776         mtspr   SPRN_DBSR,r14
777         mtspr   SPRN_DSRR1,r11
778         lwz     r10,PACA_EXDBG+EX_CR(r13)       /* restore registers */
779         ld      r1,PACA_EXDBG+EX_R1(r13)
780         ld      r14,PACA_EXDBG+EX_R14(r13)
781         ld      r15,PACA_EXDBG+EX_R15(r13)
782         mtcr    r10
783         ld      r10,PACA_EXDBG+EX_R10(r13)      /* restore registers */
784         ld      r11,PACA_EXDBG+EX_R11(r13)
785         mfspr   r13,SPRN_SPRG_DBG_SCRATCH
786         rfdi
787
788         /* Normal debug exception */
789         /* XXX We only handle coming from userspace for now since we can't
790          *     quite save properly an interrupted kernel state yet
791          */
792 1:      andi.   r14,r11,MSR_PR;         /* check for userspace again */
793         beq     kernel_dbg_exc;         /* if from kernel mode */
794
795         /* Now we mash up things to make it look like we are coming on a
796          * normal exception
797          */
798         mfspr   r14,SPRN_DBSR
799         EXCEPTION_COMMON_DBG(0xd08)
800         std     r14,_DSISR(r1)
801         addi    r3,r1,STACK_FRAME_OVERHEAD
802         ld      r14,PACA_EXDBG+EX_R14(r13)
803         ld      r15,PACA_EXDBG+EX_R15(r13)
804         bl      DebugException
805         REST_NVGPRS(r1)
806         b       interrupt_return
807
808         START_EXCEPTION(perfmon);
809         NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
810                                 PROLOG_ADDITION_NONE)
811         EXCEPTION_COMMON(0x260)
812         CHECK_NAPPING()
813         addi    r3,r1,STACK_FRAME_OVERHEAD
814         bl      performance_monitor_exception
815         b       interrupt_return
816
817 /* Doorbell interrupt */
818         MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL,
819                            doorbell, doorbell_exception, ACK_NONE)
820
821 /* Doorbell critical Interrupt */
822         START_EXCEPTION(doorbell_crit);
823         CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL,
824                               PROLOG_ADDITION_NONE)
825         EXCEPTION_COMMON_CRIT(0x2a0)
826         bl      special_reg_save
827         CHECK_NAPPING();
828         addi    r3,r1,STACK_FRAME_OVERHEAD
829         bl      unknown_nmi_exception
830         b       ret_from_crit_except
831
832 /*
833  *      Guest doorbell interrupt
834  *      This general exception use GSRRx save/restore registers
835  */
836         START_EXCEPTION(guest_doorbell);
837         GDBELL_EXCEPTION_PROLOG(0x2c0, BOOKE_INTERRUPT_GUEST_DBELL,
838                                 PROLOG_ADDITION_NONE)
839         EXCEPTION_COMMON(0x2c0)
840         addi    r3,r1,STACK_FRAME_OVERHEAD
841         bl      unknown_exception
842         b       interrupt_return
843
844 /* Guest Doorbell critical Interrupt */
845         START_EXCEPTION(guest_doorbell_crit);
846         CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT,
847                               PROLOG_ADDITION_NONE)
848         EXCEPTION_COMMON_CRIT(0x2e0)
849         bl      special_reg_save
850         CHECK_NAPPING();
851         addi    r3,r1,STACK_FRAME_OVERHEAD
852         bl      unknown_nmi_exception
853         b       ret_from_crit_except
854
855 /* Hypervisor call */
856         START_EXCEPTION(hypercall);
857         NORMAL_EXCEPTION_PROLOG(0x310, BOOKE_INTERRUPT_HV_SYSCALL,
858                                 PROLOG_ADDITION_NONE)
859         EXCEPTION_COMMON(0x310)
860         addi    r3,r1,STACK_FRAME_OVERHEAD
861         bl      unknown_exception
862         b       interrupt_return
863
864 /* Embedded Hypervisor priviledged  */
865         START_EXCEPTION(ehpriv);
866         NORMAL_EXCEPTION_PROLOG(0x320, BOOKE_INTERRUPT_HV_PRIV,
867                                 PROLOG_ADDITION_NONE)
868         EXCEPTION_COMMON(0x320)
869         addi    r3,r1,STACK_FRAME_OVERHEAD
870         bl      unknown_exception
871         b       interrupt_return
872
873 /* LRAT Error interrupt */
874         START_EXCEPTION(lrat_error);
875         NORMAL_EXCEPTION_PROLOG(0x340, BOOKE_INTERRUPT_LRAT_ERROR,
876                                 PROLOG_ADDITION_NONE)
877         EXCEPTION_COMMON(0x340)
878         addi    r3,r1,STACK_FRAME_OVERHEAD
879         bl      unknown_exception
880         b       interrupt_return
881
882 /*
883  * An interrupt came in while soft-disabled; We mark paca->irq_happened
884  * accordingly and if the interrupt is level sensitive, we hard disable
885  * hard disable (full_mask) corresponds to PACA_IRQ_MUST_HARD_MASK, so
886  * keep these in synch.
887  */
888
889 .macro masked_interrupt_book3e paca_irq full_mask
890         lbz     r10,PACAIRQHAPPENED(r13)
891         .if \full_mask == 1
892         ori     r10,r10,\paca_irq | PACA_IRQ_HARD_DIS
893         .else
894         ori     r10,r10,\paca_irq
895         .endif
896         stb     r10,PACAIRQHAPPENED(r13)
897
898         .if \full_mask == 1
899         rldicl  r10,r11,48,1            /* clear MSR_EE */
900         rotldi  r11,r10,16
901         mtspr   SPRN_SRR1,r11
902         .endif
903
904         lwz     r11,PACA_EXGEN+EX_CR(r13)
905         mtcr    r11
906         ld      r10,PACA_EXGEN+EX_R10(r13)
907         ld      r11,PACA_EXGEN+EX_R11(r13)
908         mfspr   r13,SPRN_SPRG_GEN_SCRATCH
909         rfi
910         b       .
911 .endm
912
913 masked_interrupt_book3e_0x500:
914         masked_interrupt_book3e PACA_IRQ_EE 1
915
916 masked_interrupt_book3e_0x900:
917         ACK_DEC(r10);
918         masked_interrupt_book3e PACA_IRQ_DEC 0
919
920 masked_interrupt_book3e_0x980:
921         ACK_FIT(r10);
922         masked_interrupt_book3e PACA_IRQ_DEC 0
923
924 masked_interrupt_book3e_0x280:
925 masked_interrupt_book3e_0x2c0:
926         masked_interrupt_book3e PACA_IRQ_DBELL 0
927
928 /*
929  * This is called from 0x300 and 0x400 handlers after the prologs with
930  * r14 and r15 containing the fault address and error code, with the
931  * original values stashed away in the PACA
932  */
933 storage_fault_common:
934         std     r14,_DAR(r1)
935         std     r15,_DSISR(r1)
936         addi    r3,r1,STACK_FRAME_OVERHEAD
937         ld      r14,PACA_EXGEN+EX_R14(r13)
938         ld      r15,PACA_EXGEN+EX_R15(r13)
939         bl      do_page_fault
940         b       interrupt_return
941
942 /*
943  * Alignment exception doesn't fit entirely in the 0x100 bytes so it
944  * continues here.
945  */
946 alignment_more:
947         std     r14,_DAR(r1)
948         std     r15,_DSISR(r1)
949         addi    r3,r1,STACK_FRAME_OVERHEAD
950         ld      r14,PACA_EXGEN+EX_R14(r13)
951         ld      r15,PACA_EXGEN+EX_R15(r13)
952         bl      alignment_exception
953         REST_NVGPRS(r1)
954         b       interrupt_return
955
956 /*
957  * Trampolines used when spotting a bad kernel stack pointer in
958  * the exception entry code.
959  *
960  * TODO: move some bits like SRR0 read to trampoline, pass PACA
961  * index around, etc... to handle crit & mcheck
962  */
963 BAD_STACK_TRAMPOLINE(0x000)
964 BAD_STACK_TRAMPOLINE(0x100)
965 BAD_STACK_TRAMPOLINE(0x200)
966 BAD_STACK_TRAMPOLINE(0x220)
967 BAD_STACK_TRAMPOLINE(0x260)
968 BAD_STACK_TRAMPOLINE(0x280)
969 BAD_STACK_TRAMPOLINE(0x2a0)
970 BAD_STACK_TRAMPOLINE(0x2c0)
971 BAD_STACK_TRAMPOLINE(0x2e0)
972 BAD_STACK_TRAMPOLINE(0x300)
973 BAD_STACK_TRAMPOLINE(0x310)
974 BAD_STACK_TRAMPOLINE(0x320)
975 BAD_STACK_TRAMPOLINE(0x340)
976 BAD_STACK_TRAMPOLINE(0x400)
977 BAD_STACK_TRAMPOLINE(0x500)
978 BAD_STACK_TRAMPOLINE(0x600)
979 BAD_STACK_TRAMPOLINE(0x700)
980 BAD_STACK_TRAMPOLINE(0x800)
981 BAD_STACK_TRAMPOLINE(0x900)
982 BAD_STACK_TRAMPOLINE(0x980)
983 BAD_STACK_TRAMPOLINE(0x9f0)
984 BAD_STACK_TRAMPOLINE(0xa00)
985 BAD_STACK_TRAMPOLINE(0xb00)
986 BAD_STACK_TRAMPOLINE(0xc00)
987 BAD_STACK_TRAMPOLINE(0xd00)
988 BAD_STACK_TRAMPOLINE(0xd08)
989 BAD_STACK_TRAMPOLINE(0xe00)
990 BAD_STACK_TRAMPOLINE(0xf00)
991 BAD_STACK_TRAMPOLINE(0xf20)
992
993         .globl  bad_stack_book3e
994 bad_stack_book3e:
995         /* XXX: Needs to make SPRN_SPRG_GEN depend on exception type */
996         mfspr   r10,SPRN_SRR0;            /* read SRR0 before touching stack */
997         ld      r1,PACAEMERGSP(r13)
998         subi    r1,r1,64+INT_FRAME_SIZE
999         std     r10,_NIP(r1)
1000         std     r11,_MSR(r1)
1001         ld      r10,PACA_EXGEN+EX_R1(r13) /* FIXME for crit & mcheck */
1002         lwz     r11,PACA_EXGEN+EX_CR(r13) /* FIXME for crit & mcheck */
1003         std     r10,GPR1(r1)
1004         std     r11,_CCR(r1)
1005         mfspr   r10,SPRN_DEAR
1006         mfspr   r11,SPRN_ESR
1007         std     r10,_DAR(r1)
1008         std     r11,_DSISR(r1)
1009         std     r0,GPR0(r1);            /* save r0 in stackframe */         \
1010         std     r2,GPR2(r1);            /* save r2 in stackframe */         \
1011         SAVE_4GPRS(3, r1);              /* save r3 - r6 in stackframe */    \
1012         SAVE_2GPRS(7, r1);              /* save r7, r8 in stackframe */     \
1013         std     r9,GPR9(r1);            /* save r9 in stackframe */         \
1014         ld      r3,PACA_EXGEN+EX_R10(r13);/* get back r10 */                \
1015         ld      r4,PACA_EXGEN+EX_R11(r13);/* get back r11 */                \
1016         mfspr   r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 XXX can be wrong */ \
1017         std     r3,GPR10(r1);           /* save r10 to stackframe */        \
1018         std     r4,GPR11(r1);           /* save r11 to stackframe */        \
1019         std     r12,GPR12(r1);          /* save r12 in stackframe */        \
1020         std     r5,GPR13(r1);           /* save it to stackframe */         \
1021         mflr    r10
1022         mfctr   r11
1023         mfxer   r12
1024         std     r10,_LINK(r1)
1025         std     r11,_CTR(r1)
1026         std     r12,_XER(r1)
1027         SAVE_10GPRS(14,r1)
1028         SAVE_8GPRS(24,r1)
1029         lhz     r12,PACA_TRAP_SAVE(r13)
1030         std     r12,_TRAP(r1)
1031         addi    r11,r1,INT_FRAME_SIZE
1032         std     r11,0(r1)
1033         li      r12,0
1034         std     r12,0(r11)
1035         ld      r2,PACATOC(r13)
1036 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
1037         bl      kernel_bad_stack
1038         b       1b
1039
1040 /*
1041  * Setup the initial TLB for a core. This current implementation
1042  * assume that whatever we are running off will not conflict with
1043  * the new mapping at PAGE_OFFSET.
1044  */
1045 _GLOBAL(initial_tlb_book3e)
1046
1047         /* Look for the first TLB with IPROT set */
1048         mfspr   r4,SPRN_TLB0CFG
1049         andi.   r3,r4,TLBnCFG_IPROT
1050         lis     r3,MAS0_TLBSEL(0)@h
1051         bne     found_iprot
1052
1053         mfspr   r4,SPRN_TLB1CFG
1054         andi.   r3,r4,TLBnCFG_IPROT
1055         lis     r3,MAS0_TLBSEL(1)@h
1056         bne     found_iprot
1057
1058         mfspr   r4,SPRN_TLB2CFG
1059         andi.   r3,r4,TLBnCFG_IPROT
1060         lis     r3,MAS0_TLBSEL(2)@h
1061         bne     found_iprot
1062
1063         lis     r3,MAS0_TLBSEL(3)@h
1064         mfspr   r4,SPRN_TLB3CFG
1065         /* fall through */
1066
1067 found_iprot:
1068         andi.   r5,r4,TLBnCFG_HES
1069         bne     have_hes
1070
1071         mflr    r8                              /* save LR */
1072 /* 1. Find the index of the entry we're executing in
1073  *
1074  * r3 = MAS0_TLBSEL (for the iprot array)
1075  * r4 = SPRN_TLBnCFG
1076  */
1077         bl      invstr                          /* Find our address */
1078 invstr: mflr    r6                              /* Make it accessible */
1079         mfmsr   r7
1080         rlwinm  r5,r7,27,31,31                  /* extract MSR[IS] */
1081         mfspr   r7,SPRN_PID
1082         slwi    r7,r7,16
1083         or      r7,r7,r5
1084         mtspr   SPRN_MAS6,r7
1085         tlbsx   0,r6                            /* search MSR[IS], SPID=PID */
1086
1087         mfspr   r3,SPRN_MAS0
1088         rlwinm  r5,r3,16,20,31                  /* Extract MAS0(Entry) */
1089
1090         mfspr   r7,SPRN_MAS1                    /* Insure IPROT set */
1091         oris    r7,r7,MAS1_IPROT@h
1092         mtspr   SPRN_MAS1,r7
1093         tlbwe
1094
1095 /* 2. Invalidate all entries except the entry we're executing in
1096  *
1097  * r3 = MAS0 w/TLBSEL & ESEL for the entry we are running in
1098  * r4 = SPRN_TLBnCFG
1099  * r5 = ESEL of entry we are running in
1100  */
1101         andi.   r4,r4,TLBnCFG_N_ENTRY           /* Extract # entries */
1102         li      r6,0                            /* Set Entry counter to 0 */
1103 1:      mr      r7,r3                           /* Set MAS0(TLBSEL) */
1104         rlwimi  r7,r6,16,4,15                   /* Setup MAS0 = TLBSEL | ESEL(r6) */
1105         mtspr   SPRN_MAS0,r7
1106         tlbre
1107         mfspr   r7,SPRN_MAS1
1108         rlwinm  r7,r7,0,2,31                    /* Clear MAS1 Valid and IPROT */
1109         cmpw    r5,r6
1110         beq     skpinv                          /* Dont update the current execution TLB */
1111         mtspr   SPRN_MAS1,r7
1112         tlbwe
1113         isync
1114 skpinv: addi    r6,r6,1                         /* Increment */
1115         cmpw    r6,r4                           /* Are we done? */
1116         bne     1b                              /* If not, repeat */
1117
1118         /* Invalidate all TLBs */
1119         PPC_TLBILX_ALL(0,R0)
1120         sync
1121         isync
1122
1123 /* 3. Setup a temp mapping and jump to it
1124  *
1125  * r3 = MAS0 w/TLBSEL & ESEL for the entry we are running in
1126  * r5 = ESEL of entry we are running in
1127  */
1128         andi.   r7,r5,0x1       /* Find an entry not used and is non-zero */
1129         addi    r7,r7,0x1
1130         mr      r4,r3           /* Set MAS0(TLBSEL) = 1 */
1131         mtspr   SPRN_MAS0,r4
1132         tlbre
1133
1134         rlwimi  r4,r7,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r7) */
1135         mtspr   SPRN_MAS0,r4
1136
1137         mfspr   r7,SPRN_MAS1
1138         xori    r6,r7,MAS1_TS           /* Setup TMP mapping in the other Address space */
1139         mtspr   SPRN_MAS1,r6
1140
1141         tlbwe
1142
1143         mfmsr   r6
1144         xori    r6,r6,MSR_IS
1145         mtspr   SPRN_SRR1,r6
1146         bl      1f              /* Find our address */
1147 1:      mflr    r6
1148         addi    r6,r6,(2f - 1b)
1149         mtspr   SPRN_SRR0,r6
1150         rfi
1151 2:
1152
1153 /* 4. Clear out PIDs & Search info
1154  *
1155  * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
1156  * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
1157  * r5 = MAS3
1158  */
1159         li      r6,0
1160         mtspr   SPRN_MAS6,r6
1161         mtspr   SPRN_PID,r6
1162
1163 /* 5. Invalidate mapping we started in
1164  *
1165  * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
1166  * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
1167  * r5 = MAS3
1168  */
1169         mtspr   SPRN_MAS0,r3
1170         tlbre
1171         mfspr   r6,SPRN_MAS1
1172         rlwinm  r6,r6,0,2,31    /* clear IPROT and VALID */
1173         mtspr   SPRN_MAS1,r6
1174         tlbwe
1175         sync
1176         isync
1177
1178 /* 6. Setup KERNELBASE mapping in TLB[0]
1179  *
1180  * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
1181  * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
1182  * r5 = MAS3
1183  */
1184         rlwinm  r3,r3,0,16,3    /* clear ESEL */
1185         mtspr   SPRN_MAS0,r3
1186         lis     r6,(MAS1_VALID|MAS1_IPROT)@h
1187         ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l
1188         mtspr   SPRN_MAS1,r6
1189
1190         LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | MAS2_M_IF_NEEDED)
1191         mtspr   SPRN_MAS2,r6
1192
1193         rlwinm  r5,r5,0,0,25
1194         ori     r5,r5,MAS3_SR | MAS3_SW | MAS3_SX
1195         mtspr   SPRN_MAS3,r5
1196         li      r5,-1
1197         rlwinm  r5,r5,0,0,25
1198
1199         tlbwe
1200
1201 /* 7. Jump to KERNELBASE mapping
1202  *
1203  * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
1204  */
1205         /* Now we branch the new virtual address mapped by this entry */
1206         bl      1f              /* Find our address */
1207 1:      mflr    r6
1208         addi    r6,r6,(2f - 1b)
1209         tovirt(r6,r6)
1210         lis     r7,MSR_KERNEL@h
1211         ori     r7,r7,MSR_KERNEL@l
1212         mtspr   SPRN_SRR0,r6
1213         mtspr   SPRN_SRR1,r7
1214         rfi                             /* start execution out of TLB1[0] entry */
1215 2:
1216
1217 /* 8. Clear out the temp mapping
1218  *
1219  * r4 = MAS0 w/TLBSEL & ESEL for the entry we are running in
1220  */
1221         mtspr   SPRN_MAS0,r4
1222         tlbre
1223         mfspr   r5,SPRN_MAS1
1224         rlwinm  r5,r5,0,2,31    /* clear IPROT and VALID */
1225         mtspr   SPRN_MAS1,r5
1226         tlbwe
1227         sync
1228         isync
1229
1230         /* We translate LR and return */
1231         tovirt(r8,r8)
1232         mtlr    r8
1233         blr
1234
1235 have_hes:
1236         /* Setup MAS 0,1,2,3 and 7 for tlbwe of a 1G entry that maps the
1237          * kernel linear mapping. We also set MAS8 once for all here though
1238          * that will have to be made dependent on whether we are running under
1239          * a hypervisor I suppose.
1240          */
1241
1242         /* BEWARE, MAGIC
1243          * This code is called as an ordinary function on the boot CPU. But to
1244          * avoid duplication, this code is also used in SCOM bringup of
1245          * secondary CPUs. We read the code between the initial_tlb_code_start
1246          * and initial_tlb_code_end labels one instruction at a time and RAM it
1247          * into the new core via SCOM. That doesn't process branches, so there
1248          * must be none between those two labels. It also means if this code
1249          * ever takes any parameters, the SCOM code must also be updated to
1250          * provide them.
1251          */
1252         .globl a2_tlbinit_code_start
1253 a2_tlbinit_code_start:
1254
1255         ori     r11,r3,MAS0_WQ_ALLWAYS
1256         oris    r11,r11,MAS0_ESEL(3)@h /* Use way 3: workaround A2 erratum 376 */
1257         mtspr   SPRN_MAS0,r11
1258         lis     r3,(MAS1_VALID | MAS1_IPROT)@h
1259         ori     r3,r3,BOOK3E_PAGESZ_1GB << MAS1_TSIZE_SHIFT
1260         mtspr   SPRN_MAS1,r3
1261         LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET | MAS2_M)
1262         mtspr   SPRN_MAS2,r3
1263         li      r3,MAS3_SR | MAS3_SW | MAS3_SX
1264         mtspr   SPRN_MAS7_MAS3,r3
1265         li      r3,0
1266         mtspr   SPRN_MAS8,r3
1267
1268         /* Write the TLB entry */
1269         tlbwe
1270
1271         .globl a2_tlbinit_after_linear_map
1272 a2_tlbinit_after_linear_map:
1273
1274         /* Now we branch the new virtual address mapped by this entry */
1275         LOAD_REG_IMMEDIATE_SYM(r3, r5, 1f)
1276         mtctr   r3
1277         bctr
1278
1279 1:      /* We are now running at PAGE_OFFSET, clean the TLB of everything
1280          * else (including IPROTed things left by firmware)
1281          * r4 = TLBnCFG
1282          * r3 = current address (more or less)
1283          */
1284
1285         li      r5,0
1286         mtspr   SPRN_MAS6,r5
1287         tlbsx   0,r3
1288
1289         rlwinm  r9,r4,0,TLBnCFG_N_ENTRY
1290         rlwinm  r10,r4,8,0xff
1291         addi    r10,r10,-1      /* Get inner loop mask */
1292
1293         li      r3,1
1294
1295         mfspr   r5,SPRN_MAS1
1296         rlwinm  r5,r5,0,(~(MAS1_VALID|MAS1_IPROT))
1297
1298         mfspr   r6,SPRN_MAS2
1299         rldicr  r6,r6,0,51              /* Extract EPN */
1300
1301         mfspr   r7,SPRN_MAS0
1302         rlwinm  r7,r7,0,0xffff0fff      /* Clear HES and WQ */
1303
1304         rlwinm  r8,r7,16,0xfff          /* Extract ESEL */
1305
1306 2:      add     r4,r3,r8
1307         and     r4,r4,r10
1308
1309         rlwimi  r7,r4,16,MAS0_ESEL_MASK
1310
1311         mtspr   SPRN_MAS0,r7
1312         mtspr   SPRN_MAS1,r5
1313         mtspr   SPRN_MAS2,r6
1314         tlbwe
1315
1316         addi    r3,r3,1
1317         and.    r4,r3,r10
1318
1319         bne     3f
1320         addis   r6,r6,(1<<30)@h
1321 3:
1322         cmpw    r3,r9
1323         blt     2b
1324
1325         .globl  a2_tlbinit_after_iprot_flush
1326 a2_tlbinit_after_iprot_flush:
1327
1328         PPC_TLBILX(0,0,R0)
1329         sync
1330         isync
1331
1332         .globl a2_tlbinit_code_end
1333 a2_tlbinit_code_end:
1334
1335         /* We translate LR and return */
1336         mflr    r3
1337         tovirt(r3,r3)
1338         mtlr    r3
1339         blr
1340
1341 /*
1342  * Main entry (boot CPU, thread 0)
1343  *
1344  * We enter here from head_64.S, possibly after the prom_init trampoline
1345  * with r3 and r4 already saved to r31 and 30 respectively and in 64 bits
1346  * mode. Anything else is as it was left by the bootloader
1347  *
1348  * Initial requirements of this port:
1349  *
1350  * - Kernel loaded at 0 physical
1351  * - A good lump of memory mapped 0:0 by UTLB entry 0
1352  * - MSR:IS & MSR:DS set to 0
1353  *
1354  * Note that some of the above requirements will be relaxed in the future
1355  * as the kernel becomes smarter at dealing with different initial conditions
1356  * but for now you have to be careful
1357  */
1358 _GLOBAL(start_initialization_book3e)
1359         mflr    r28
1360
1361         /* First, we need to setup some initial TLBs to map the kernel
1362          * text, data and bss at PAGE_OFFSET. We don't have a real mode
1363          * and always use AS 0, so we just set it up to match our link
1364          * address and never use 0 based addresses.
1365          */
1366         bl      initial_tlb_book3e
1367
1368         /* Init global core bits */
1369         bl      init_core_book3e
1370
1371         /* Init per-thread bits */
1372         bl      init_thread_book3e
1373
1374         /* Return to common init code */
1375         tovirt(r28,r28)
1376         mtlr    r28
1377         blr
1378
1379
1380 /*
1381  * Secondary core/processor entry
1382  *
1383  * This is entered for thread 0 of a secondary core, all other threads
1384  * are expected to be stopped. It's similar to start_initialization_book3e
1385  * except that it's generally entered from the holding loop in head_64.S
1386  * after CPUs have been gathered by Open Firmware.
1387  *
1388  * We assume we are in 32 bits mode running with whatever TLB entry was
1389  * set for us by the firmware or POR engine.
1390  */
1391 _GLOBAL(book3e_secondary_core_init_tlb_set)
1392         li      r4,1
1393         b       generic_secondary_smp_init
1394
1395 _GLOBAL(book3e_secondary_core_init)
1396         mflr    r28
1397
1398         /* Do we need to setup initial TLB entry ? */
1399         cmplwi  r4,0
1400         bne     2f
1401
1402         /* Setup TLB for this core */
1403         bl      initial_tlb_book3e
1404
1405         /* We can return from the above running at a different
1406          * address, so recalculate r2 (TOC)
1407          */
1408         bl      relative_toc
1409
1410         /* Init global core bits */
1411 2:      bl      init_core_book3e
1412
1413         /* Init per-thread bits */
1414 3:      bl      init_thread_book3e
1415
1416         /* Return to common init code at proper virtual address.
1417          *
1418          * Due to various previous assumptions, we know we entered this
1419          * function at either the final PAGE_OFFSET mapping or using a
1420          * 1:1 mapping at 0, so we don't bother doing a complicated check
1421          * here, we just ensure the return address has the right top bits.
1422          *
1423          * Note that if we ever want to be smarter about where we can be
1424          * started from, we have to be careful that by the time we reach
1425          * the code below we may already be running at a different location
1426          * than the one we were called from since initial_tlb_book3e can
1427          * have moved us already.
1428          */
1429         cmpdi   cr0,r28,0
1430         blt     1f
1431         lis     r3,PAGE_OFFSET@highest
1432         sldi    r3,r3,32
1433         or      r28,r28,r3
1434 1:      mtlr    r28
1435         blr
1436
1437 _GLOBAL(book3e_secondary_thread_init)
1438         mflr    r28
1439         b       3b
1440
1441         .globl init_core_book3e
1442 init_core_book3e:
1443         /* Establish the interrupt vector base */
1444         tovirt(r2,r2)
1445         LOAD_REG_ADDR(r3, interrupt_base_book3e)
1446         mtspr   SPRN_IVPR,r3
1447         sync
1448         blr
1449
1450 init_thread_book3e:
1451         lis     r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h
1452         mtspr   SPRN_EPCR,r3
1453
1454         /* Make sure interrupts are off */
1455         wrteei  0
1456
1457         /* disable all timers and clear out status */
1458         li      r3,0
1459         mtspr   SPRN_TCR,r3
1460         mfspr   r3,SPRN_TSR
1461         mtspr   SPRN_TSR,r3
1462
1463         blr
1464
1465 _GLOBAL(__setup_base_ivors)
1466         SET_IVOR(0, 0x020) /* Critical Input */
1467         SET_IVOR(1, 0x000) /* Machine Check */
1468         SET_IVOR(2, 0x060) /* Data Storage */ 
1469         SET_IVOR(3, 0x080) /* Instruction Storage */
1470         SET_IVOR(4, 0x0a0) /* External Input */ 
1471         SET_IVOR(5, 0x0c0) /* Alignment */ 
1472         SET_IVOR(6, 0x0e0) /* Program */ 
1473         SET_IVOR(7, 0x100) /* FP Unavailable */ 
1474         SET_IVOR(8, 0x120) /* System Call */ 
1475         SET_IVOR(9, 0x140) /* Auxiliary Processor Unavailable */ 
1476         SET_IVOR(10, 0x160) /* Decrementer */ 
1477         SET_IVOR(11, 0x180) /* Fixed Interval Timer */ 
1478         SET_IVOR(12, 0x1a0) /* Watchdog Timer */ 
1479         SET_IVOR(13, 0x1c0) /* Data TLB Error */ 
1480         SET_IVOR(14, 0x1e0) /* Instruction TLB Error */
1481         SET_IVOR(15, 0x040) /* Debug */
1482
1483         sync
1484
1485         blr
1486
1487 _GLOBAL(setup_altivec_ivors)
1488         SET_IVOR(32, 0x200) /* AltiVec Unavailable */
1489         SET_IVOR(33, 0x220) /* AltiVec Assist */
1490         blr
1491
1492 _GLOBAL(setup_perfmon_ivor)
1493         SET_IVOR(35, 0x260) /* Performance Monitor */
1494         blr
1495
1496 _GLOBAL(setup_doorbell_ivors)
1497         SET_IVOR(36, 0x280) /* Processor Doorbell */
1498         SET_IVOR(37, 0x2a0) /* Processor Doorbell Crit */
1499         blr
1500
1501 _GLOBAL(setup_ehv_ivors)
1502         SET_IVOR(40, 0x300) /* Embedded Hypervisor System Call */
1503         SET_IVOR(41, 0x320) /* Embedded Hypervisor Privilege */
1504         SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */
1505         SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */
1506         blr
1507
1508 _GLOBAL(setup_lrat_ivor)
1509         SET_IVOR(42, 0x340) /* LRAT Error */
1510         blr