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