powerpc: Remaining 64-bit Book3E support
[pandora-kernel.git] / arch / powerpc / kernel / exceptions-64s.S
1 /*
2  * This file contains the 64-bit "server" PowerPC variant
3  * of the low level exception handling including exception
4  * vectors, exception return, part of the slb and stab
5  * handling and other fixed offset specific things.
6  *
7  * This file is meant to be #included from head_64.S due to
8  * position dependant assembly.
9  *
10  * Most of this originates from head_64.S and thus has the same
11  * copyright history.
12  *
13  */
14
15 #include <asm/exception-64s.h>
16
17 /*
18  * We layout physical memory as follows:
19  * 0x0000 - 0x00ff : Secondary processor spin code
20  * 0x0100 - 0x2fff : pSeries Interrupt prologs
21  * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
22  * 0x6000 - 0x6fff : Initial (CPU0) segment table
23  * 0x7000 - 0x7fff : FWNMI data area
24  * 0x8000 -        : Early init and support code
25  */
26
27 /*
28  * This is the start of the interrupt handlers for pSeries
29  * This code runs with relocation off.
30  * Code from here to __end_interrupts gets copied down to real
31  * address 0x100 when we are running a relocatable kernel.
32  * Therefore any relative branches in this section must only
33  * branch to labels in this section.
34  */
35         . = 0x100
36         .globl __start_interrupts
37 __start_interrupts:
38
39         STD_EXCEPTION_PSERIES(0x100, system_reset)
40
41         . = 0x200
42 _machine_check_pSeries:
43         HMT_MEDIUM
44         mtspr   SPRN_SPRG_SCRATCH0,r13          /* save r13 */
45         EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
46
47         . = 0x300
48         .globl data_access_pSeries
49 data_access_pSeries:
50         HMT_MEDIUM
51         mtspr   SPRN_SPRG_SCRATCH0,r13
52 BEGIN_FTR_SECTION
53         mfspr   r13,SPRN_SPRG_PACA
54         std     r9,PACA_EXSLB+EX_R9(r13)
55         std     r10,PACA_EXSLB+EX_R10(r13)
56         mfspr   r10,SPRN_DAR
57         mfspr   r9,SPRN_DSISR
58         srdi    r10,r10,60
59         rlwimi  r10,r9,16,0x20
60         mfcr    r9
61         cmpwi   r10,0x2c
62         beq     do_stab_bolted_pSeries
63         ld      r10,PACA_EXSLB+EX_R10(r13)
64         std     r11,PACA_EXGEN+EX_R11(r13)
65         ld      r11,PACA_EXSLB+EX_R9(r13)
66         std     r12,PACA_EXGEN+EX_R12(r13)
67         mfspr   r12,SPRN_SPRG_SCRATCH0
68         std     r10,PACA_EXGEN+EX_R10(r13)
69         std     r11,PACA_EXGEN+EX_R9(r13)
70         std     r12,PACA_EXGEN+EX_R13(r13)
71         EXCEPTION_PROLOG_PSERIES_1(data_access_common)
72 FTR_SECTION_ELSE
73         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
74 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
75
76         . = 0x380
77         .globl data_access_slb_pSeries
78 data_access_slb_pSeries:
79         HMT_MEDIUM
80         mtspr   SPRN_SPRG_SCRATCH0,r13
81         mfspr   r13,SPRN_SPRG_PACA              /* get paca address into r13 */
82         std     r3,PACA_EXSLB+EX_R3(r13)
83         mfspr   r3,SPRN_DAR
84         std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
85         mfcr    r9
86 #ifdef __DISABLED__
87         /* Keep that around for when we re-implement dynamic VSIDs */
88         cmpdi   r3,0
89         bge     slb_miss_user_pseries
90 #endif /* __DISABLED__ */
91         std     r10,PACA_EXSLB+EX_R10(r13)
92         std     r11,PACA_EXSLB+EX_R11(r13)
93         std     r12,PACA_EXSLB+EX_R12(r13)
94         mfspr   r10,SPRN_SPRG_SCRATCH0
95         std     r10,PACA_EXSLB+EX_R13(r13)
96         mfspr   r12,SPRN_SRR1           /* and SRR1 */
97 #ifndef CONFIG_RELOCATABLE
98         b       .slb_miss_realmode
99 #else
100         /*
101          * We can't just use a direct branch to .slb_miss_realmode
102          * because the distance from here to there depends on where
103          * the kernel ends up being put.
104          */
105         mfctr   r11
106         ld      r10,PACAKBASE(r13)
107         LOAD_HANDLER(r10, .slb_miss_realmode)
108         mtctr   r10
109         bctr
110 #endif
111
112         STD_EXCEPTION_PSERIES(0x400, instruction_access)
113
114         . = 0x480
115         .globl instruction_access_slb_pSeries
116 instruction_access_slb_pSeries:
117         HMT_MEDIUM
118         mtspr   SPRN_SPRG_SCRATCH0,r13
119         mfspr   r13,SPRN_SPRG_PACA              /* get paca address into r13 */
120         std     r3,PACA_EXSLB+EX_R3(r13)
121         mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
122         std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
123         mfcr    r9
124 #ifdef __DISABLED__
125         /* Keep that around for when we re-implement dynamic VSIDs */
126         cmpdi   r3,0
127         bge     slb_miss_user_pseries
128 #endif /* __DISABLED__ */
129         std     r10,PACA_EXSLB+EX_R10(r13)
130         std     r11,PACA_EXSLB+EX_R11(r13)
131         std     r12,PACA_EXSLB+EX_R12(r13)
132         mfspr   r10,SPRN_SPRG_SCRATCH0
133         std     r10,PACA_EXSLB+EX_R13(r13)
134         mfspr   r12,SPRN_SRR1           /* and SRR1 */
135 #ifndef CONFIG_RELOCATABLE
136         b       .slb_miss_realmode
137 #else
138         mfctr   r11
139         ld      r10,PACAKBASE(r13)
140         LOAD_HANDLER(r10, .slb_miss_realmode)
141         mtctr   r10
142         bctr
143 #endif
144
145         MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
146         STD_EXCEPTION_PSERIES(0x600, alignment)
147         STD_EXCEPTION_PSERIES(0x700, program_check)
148         STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
149         MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
150         STD_EXCEPTION_PSERIES(0xa00, trap_0a)
151         STD_EXCEPTION_PSERIES(0xb00, trap_0b)
152
153         . = 0xc00
154         .globl  system_call_pSeries
155 system_call_pSeries:
156         HMT_MEDIUM
157 BEGIN_FTR_SECTION
158         cmpdi   r0,0x1ebe
159         beq-    1f
160 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
161         mr      r9,r13
162         mfspr   r13,SPRN_SPRG_PACA
163         mfspr   r11,SPRN_SRR0
164         ld      r12,PACAKBASE(r13)
165         ld      r10,PACAKMSR(r13)
166         LOAD_HANDLER(r12, system_call_entry)
167         mtspr   SPRN_SRR0,r12
168         mfspr   r12,SPRN_SRR1
169         mtspr   SPRN_SRR1,r10
170         rfid
171         b       .       /* prevent speculative execution */
172
173 /* Fast LE/BE switch system call */
174 1:      mfspr   r12,SPRN_SRR1
175         xori    r12,r12,MSR_LE
176         mtspr   SPRN_SRR1,r12
177         rfid            /* return to userspace */
178         b       .
179
180         STD_EXCEPTION_PSERIES(0xd00, single_step)
181         STD_EXCEPTION_PSERIES(0xe00, trap_0e)
182
183         /* We need to deal with the Altivec unavailable exception
184          * here which is at 0xf20, thus in the middle of the
185          * prolog code of the PerformanceMonitor one. A little
186          * trickery is thus necessary
187          */
188         . = 0xf00
189         b       performance_monitor_pSeries
190
191         . = 0xf20
192         b       altivec_unavailable_pSeries
193
194         . = 0xf40
195         b       vsx_unavailable_pSeries
196
197 #ifdef CONFIG_CBE_RAS
198         HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error)
199 #endif /* CONFIG_CBE_RAS */
200         STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
201 #ifdef CONFIG_CBE_RAS
202         HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance)
203 #endif /* CONFIG_CBE_RAS */
204         STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
205 #ifdef CONFIG_CBE_RAS
206         HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal)
207 #endif /* CONFIG_CBE_RAS */
208
209         . = 0x3000
210
211 /*** pSeries interrupt support ***/
212
213         /* moved from 0xf00 */
214         STD_EXCEPTION_PSERIES(., performance_monitor)
215         STD_EXCEPTION_PSERIES(., altivec_unavailable)
216         STD_EXCEPTION_PSERIES(., vsx_unavailable)
217
218 /*
219  * An interrupt came in while soft-disabled; clear EE in SRR1,
220  * clear paca->hard_enabled and return.
221  */
222 masked_interrupt:
223         stb     r10,PACAHARDIRQEN(r13)
224         mtcrf   0x80,r9
225         ld      r9,PACA_EXGEN+EX_R9(r13)
226         mfspr   r10,SPRN_SRR1
227         rldicl  r10,r10,48,1            /* clear MSR_EE */
228         rotldi  r10,r10,16
229         mtspr   SPRN_SRR1,r10
230         ld      r10,PACA_EXGEN+EX_R10(r13)
231         mfspr   r13,SPRN_SPRG_SCRATCH0
232         rfid
233         b       .
234
235         .align  7
236 do_stab_bolted_pSeries:
237         std     r11,PACA_EXSLB+EX_R11(r13)
238         std     r12,PACA_EXSLB+EX_R12(r13)
239         mfspr   r10,SPRN_SPRG_SCRATCH0
240         std     r10,PACA_EXSLB+EX_R13(r13)
241         EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted)
242
243 #ifdef CONFIG_PPC_PSERIES
244 /*
245  * Vectors for the FWNMI option.  Share common code.
246  */
247         .globl system_reset_fwnmi
248       .align 7
249 system_reset_fwnmi:
250         HMT_MEDIUM
251         mtspr   SPRN_SPRG_SCRATCH0,r13          /* save r13 */
252         EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
253
254         .globl machine_check_fwnmi
255       .align 7
256 machine_check_fwnmi:
257         HMT_MEDIUM
258         mtspr   SPRN_SPRG_SCRATCH0,r13          /* save r13 */
259         EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
260
261 #endif /* CONFIG_PPC_PSERIES */
262
263 #ifdef __DISABLED__
264 /*
265  * This is used for when the SLB miss handler has to go virtual,
266  * which doesn't happen for now anymore but will once we re-implement
267  * dynamic VSIDs for shared page tables
268  */
269 slb_miss_user_pseries:
270         std     r10,PACA_EXGEN+EX_R10(r13)
271         std     r11,PACA_EXGEN+EX_R11(r13)
272         std     r12,PACA_EXGEN+EX_R12(r13)
273         mfspr   r10,SPRG_SCRATCH0
274         ld      r11,PACA_EXSLB+EX_R9(r13)
275         ld      r12,PACA_EXSLB+EX_R3(r13)
276         std     r10,PACA_EXGEN+EX_R13(r13)
277         std     r11,PACA_EXGEN+EX_R9(r13)
278         std     r12,PACA_EXGEN+EX_R3(r13)
279         clrrdi  r12,r13,32
280         mfmsr   r10
281         mfspr   r11,SRR0                        /* save SRR0 */
282         ori     r12,r12,slb_miss_user_common@l  /* virt addr of handler */
283         ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
284         mtspr   SRR0,r12
285         mfspr   r12,SRR1                        /* and SRR1 */
286         mtspr   SRR1,r10
287         rfid
288         b       .                               /* prevent spec. execution */
289 #endif /* __DISABLED__ */
290
291         .align  7
292         .globl  __end_interrupts
293 __end_interrupts:
294
295 /*
296  * Code from here down to __end_handlers is invoked from the
297  * exception prologs above.  Because the prologs assemble the
298  * addresses of these handlers using the LOAD_HANDLER macro,
299  * which uses an addi instruction, these handlers must be in
300  * the first 32k of the kernel image.
301  */
302
303 /*** Common interrupt handlers ***/
304
305         STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
306
307         /*
308          * Machine check is different because we use a different
309          * save area: PACA_EXMC instead of PACA_EXGEN.
310          */
311         .align  7
312         .globl machine_check_common
313 machine_check_common:
314         EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
315         FINISH_NAP
316         DISABLE_INTS
317         bl      .save_nvgprs
318         addi    r3,r1,STACK_FRAME_OVERHEAD
319         bl      .machine_check_exception
320         b       .ret_from_except
321
322         STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
323         STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
324         STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
325         STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
326         STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
327         STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
328         STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
329 #ifdef CONFIG_ALTIVEC
330         STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
331 #else
332         STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
333 #endif
334 #ifdef CONFIG_CBE_RAS
335         STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception)
336         STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception)
337         STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
338 #endif /* CONFIG_CBE_RAS */
339
340         .align  7
341 system_call_entry:
342         b       system_call_common
343
344 /*
345  * Here we have detected that the kernel stack pointer is bad.
346  * R9 contains the saved CR, r13 points to the paca,
347  * r10 contains the (bad) kernel stack pointer,
348  * r11 and r12 contain the saved SRR0 and SRR1.
349  * We switch to using an emergency stack, save the registers there,
350  * and call kernel_bad_stack(), which panics.
351  */
352 bad_stack:
353         ld      r1,PACAEMERGSP(r13)
354         subi    r1,r1,64+INT_FRAME_SIZE
355         std     r9,_CCR(r1)
356         std     r10,GPR1(r1)
357         std     r11,_NIP(r1)
358         std     r12,_MSR(r1)
359         mfspr   r11,SPRN_DAR
360         mfspr   r12,SPRN_DSISR
361         std     r11,_DAR(r1)
362         std     r12,_DSISR(r1)
363         mflr    r10
364         mfctr   r11
365         mfxer   r12
366         std     r10,_LINK(r1)
367         std     r11,_CTR(r1)
368         std     r12,_XER(r1)
369         SAVE_GPR(0,r1)
370         SAVE_GPR(2,r1)
371         SAVE_4GPRS(3,r1)
372         SAVE_2GPRS(7,r1)
373         SAVE_10GPRS(12,r1)
374         SAVE_10GPRS(22,r1)
375         lhz     r12,PACA_TRAP_SAVE(r13)
376         std     r12,_TRAP(r1)
377         addi    r11,r1,INT_FRAME_SIZE
378         std     r11,0(r1)
379         li      r12,0
380         std     r12,0(r11)
381         ld      r2,PACATOC(r13)
382 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
383         bl      .kernel_bad_stack
384         b       1b
385
386 /*
387  * Here r13 points to the paca, r9 contains the saved CR,
388  * SRR0 and SRR1 are saved in r11 and r12,
389  * r9 - r13 are saved in paca->exgen.
390  */
391         .align  7
392         .globl data_access_common
393 data_access_common:
394         mfspr   r10,SPRN_DAR
395         std     r10,PACA_EXGEN+EX_DAR(r13)
396         mfspr   r10,SPRN_DSISR
397         stw     r10,PACA_EXGEN+EX_DSISR(r13)
398         EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
399         ld      r3,PACA_EXGEN+EX_DAR(r13)
400         lwz     r4,PACA_EXGEN+EX_DSISR(r13)
401         li      r5,0x300
402         b       .do_hash_page           /* Try to handle as hpte fault */
403
404         .align  7
405         .globl instruction_access_common
406 instruction_access_common:
407         EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
408         ld      r3,_NIP(r1)
409         andis.  r4,r12,0x5820
410         li      r5,0x400
411         b       .do_hash_page           /* Try to handle as hpte fault */
412
413 /*
414  * Here is the common SLB miss user that is used when going to virtual
415  * mode for SLB misses, that is currently not used
416  */
417 #ifdef __DISABLED__
418         .align  7
419         .globl  slb_miss_user_common
420 slb_miss_user_common:
421         mflr    r10
422         std     r3,PACA_EXGEN+EX_DAR(r13)
423         stw     r9,PACA_EXGEN+EX_CCR(r13)
424         std     r10,PACA_EXGEN+EX_LR(r13)
425         std     r11,PACA_EXGEN+EX_SRR0(r13)
426         bl      .slb_allocate_user
427
428         ld      r10,PACA_EXGEN+EX_LR(r13)
429         ld      r3,PACA_EXGEN+EX_R3(r13)
430         lwz     r9,PACA_EXGEN+EX_CCR(r13)
431         ld      r11,PACA_EXGEN+EX_SRR0(r13)
432         mtlr    r10
433         beq-    slb_miss_fault
434
435         andi.   r10,r12,MSR_RI          /* check for unrecoverable exception */
436         beq-    unrecov_user_slb
437         mfmsr   r10
438
439 .machine push
440 .machine "power4"
441         mtcrf   0x80,r9
442 .machine pop
443
444         clrrdi  r10,r10,2               /* clear RI before setting SRR0/1 */
445         mtmsrd  r10,1
446
447         mtspr   SRR0,r11
448         mtspr   SRR1,r12
449
450         ld      r9,PACA_EXGEN+EX_R9(r13)
451         ld      r10,PACA_EXGEN+EX_R10(r13)
452         ld      r11,PACA_EXGEN+EX_R11(r13)
453         ld      r12,PACA_EXGEN+EX_R12(r13)
454         ld      r13,PACA_EXGEN+EX_R13(r13)
455         rfid
456         b       .
457
458 slb_miss_fault:
459         EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
460         ld      r4,PACA_EXGEN+EX_DAR(r13)
461         li      r5,0
462         std     r4,_DAR(r1)
463         std     r5,_DSISR(r1)
464         b       handle_page_fault
465
466 unrecov_user_slb:
467         EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
468         DISABLE_INTS
469         bl      .save_nvgprs
470 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
471         bl      .unrecoverable_exception
472         b       1b
473
474 #endif /* __DISABLED__ */
475
476
477 /*
478  * r13 points to the PACA, r9 contains the saved CR,
479  * r12 contain the saved SRR1, SRR0 is still ready for return
480  * r3 has the faulting address
481  * r9 - r13 are saved in paca->exslb.
482  * r3 is saved in paca->slb_r3
483  * We assume we aren't going to take any exceptions during this procedure.
484  */
485 _GLOBAL(slb_miss_realmode)
486         mflr    r10
487 #ifdef CONFIG_RELOCATABLE
488         mtctr   r11
489 #endif
490
491         stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
492         std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
493
494         bl      .slb_allocate_realmode
495
496         /* All done -- return from exception. */
497
498         ld      r10,PACA_EXSLB+EX_LR(r13)
499         ld      r3,PACA_EXSLB+EX_R3(r13)
500         lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
501 #ifdef CONFIG_PPC_ISERIES
502 BEGIN_FW_FTR_SECTION
503         ld      r11,PACALPPACAPTR(r13)
504         ld      r11,LPPACASRR0(r11)             /* get SRR0 value */
505 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
506 #endif /* CONFIG_PPC_ISERIES */
507
508         mtlr    r10
509
510         andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
511         beq-    2f
512
513 .machine        push
514 .machine        "power4"
515         mtcrf   0x80,r9
516         mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
517 .machine        pop
518
519 #ifdef CONFIG_PPC_ISERIES
520 BEGIN_FW_FTR_SECTION
521         mtspr   SPRN_SRR0,r11
522         mtspr   SPRN_SRR1,r12
523 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
524 #endif /* CONFIG_PPC_ISERIES */
525         ld      r9,PACA_EXSLB+EX_R9(r13)
526         ld      r10,PACA_EXSLB+EX_R10(r13)
527         ld      r11,PACA_EXSLB+EX_R11(r13)
528         ld      r12,PACA_EXSLB+EX_R12(r13)
529         ld      r13,PACA_EXSLB+EX_R13(r13)
530         rfid
531         b       .       /* prevent speculative execution */
532
533 2:
534 #ifdef CONFIG_PPC_ISERIES
535 BEGIN_FW_FTR_SECTION
536         b       unrecov_slb
537 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
538 #endif /* CONFIG_PPC_ISERIES */
539         mfspr   r11,SPRN_SRR0
540         ld      r10,PACAKBASE(r13)
541         LOAD_HANDLER(r10,unrecov_slb)
542         mtspr   SPRN_SRR0,r10
543         ld      r10,PACAKMSR(r13)
544         mtspr   SPRN_SRR1,r10
545         rfid
546         b       .
547
548 unrecov_slb:
549         EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
550         DISABLE_INTS
551         bl      .save_nvgprs
552 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
553         bl      .unrecoverable_exception
554         b       1b
555
556         .align  7
557         .globl hardware_interrupt_common
558         .globl hardware_interrupt_entry
559 hardware_interrupt_common:
560         EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
561         FINISH_NAP
562 hardware_interrupt_entry:
563         DISABLE_INTS
564 BEGIN_FTR_SECTION
565         bl      .ppc64_runlatch_on
566 END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
567         addi    r3,r1,STACK_FRAME_OVERHEAD
568         bl      .do_IRQ
569         b       .ret_from_except_lite
570
571 #ifdef CONFIG_PPC_970_NAP
572 power4_fixup_nap:
573         andc    r9,r9,r10
574         std     r9,TI_LOCAL_FLAGS(r11)
575         ld      r10,_LINK(r1)           /* make idle task do the */
576         std     r10,_NIP(r1)            /* equivalent of a blr */
577         blr
578 #endif
579
580         .align  7
581         .globl alignment_common
582 alignment_common:
583         mfspr   r10,SPRN_DAR
584         std     r10,PACA_EXGEN+EX_DAR(r13)
585         mfspr   r10,SPRN_DSISR
586         stw     r10,PACA_EXGEN+EX_DSISR(r13)
587         EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
588         ld      r3,PACA_EXGEN+EX_DAR(r13)
589         lwz     r4,PACA_EXGEN+EX_DSISR(r13)
590         std     r3,_DAR(r1)
591         std     r4,_DSISR(r1)
592         bl      .save_nvgprs
593         addi    r3,r1,STACK_FRAME_OVERHEAD
594         ENABLE_INTS
595         bl      .alignment_exception
596         b       .ret_from_except
597
598         .align  7
599         .globl program_check_common
600 program_check_common:
601         EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
602         bl      .save_nvgprs
603         addi    r3,r1,STACK_FRAME_OVERHEAD
604         ENABLE_INTS
605         bl      .program_check_exception
606         b       .ret_from_except
607
608         .align  7
609         .globl fp_unavailable_common
610 fp_unavailable_common:
611         EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
612         bne     1f                      /* if from user, just load it up */
613         bl      .save_nvgprs
614         addi    r3,r1,STACK_FRAME_OVERHEAD
615         ENABLE_INTS
616         bl      .kernel_fp_unavailable_exception
617         BUG_OPCODE
618 1:      bl      .load_up_fpu
619         b       fast_exception_return
620
621         .align  7
622         .globl altivec_unavailable_common
623 altivec_unavailable_common:
624         EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
625 #ifdef CONFIG_ALTIVEC
626 BEGIN_FTR_SECTION
627         beq     1f
628         bl      .load_up_altivec
629         b       fast_exception_return
630 1:
631 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
632 #endif
633         bl      .save_nvgprs
634         addi    r3,r1,STACK_FRAME_OVERHEAD
635         ENABLE_INTS
636         bl      .altivec_unavailable_exception
637         b       .ret_from_except
638
639         .align  7
640         .globl vsx_unavailable_common
641 vsx_unavailable_common:
642         EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
643 #ifdef CONFIG_VSX
644 BEGIN_FTR_SECTION
645         bne     .load_up_vsx
646 1:
647 END_FTR_SECTION_IFSET(CPU_FTR_VSX)
648 #endif
649         bl      .save_nvgprs
650         addi    r3,r1,STACK_FRAME_OVERHEAD
651         ENABLE_INTS
652         bl      .vsx_unavailable_exception
653         b       .ret_from_except
654
655         .align  7
656         .globl  __end_handlers
657 __end_handlers:
658
659 /*
660  * Return from an exception with minimal checks.
661  * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
662  * If interrupts have been enabled, or anything has been
663  * done that might have changed the scheduling status of
664  * any task or sent any task a signal, you should use
665  * ret_from_except or ret_from_except_lite instead of this.
666  */
667 fast_exc_return_irq:                    /* restores irq state too */
668         ld      r3,SOFTE(r1)
669         TRACE_AND_RESTORE_IRQ(r3);
670         ld      r12,_MSR(r1)
671         rldicl  r4,r12,49,63            /* get MSR_EE to LSB */
672         stb     r4,PACAHARDIRQEN(r13)   /* restore paca->hard_enabled */
673         b       1f
674
675         .globl  fast_exception_return
676 fast_exception_return:
677         ld      r12,_MSR(r1)
678 1:      ld      r11,_NIP(r1)
679         andi.   r3,r12,MSR_RI           /* check if RI is set */
680         beq-    unrecov_fer
681
682 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
683         andi.   r3,r12,MSR_PR
684         beq     2f
685         ACCOUNT_CPU_USER_EXIT(r3, r4)
686 2:
687 #endif
688
689         ld      r3,_CCR(r1)
690         ld      r4,_LINK(r1)
691         ld      r5,_CTR(r1)
692         ld      r6,_XER(r1)
693         mtcr    r3
694         mtlr    r4
695         mtctr   r5
696         mtxer   r6
697         REST_GPR(0, r1)
698         REST_8GPRS(2, r1)
699
700         mfmsr   r10
701         rldicl  r10,r10,48,1            /* clear EE */
702         rldicr  r10,r10,16,61           /* clear RI (LE is 0 already) */
703         mtmsrd  r10,1
704
705         mtspr   SPRN_SRR1,r12
706         mtspr   SPRN_SRR0,r11
707         REST_4GPRS(10, r1)
708         ld      r1,GPR1(r1)
709         rfid
710         b       .       /* prevent speculative execution */
711
712 unrecov_fer:
713         bl      .save_nvgprs
714 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
715         bl      .unrecoverable_exception
716         b       1b
717
718
719 /*
720  * Hash table stuff
721  */
722         .align  7
723 _STATIC(do_hash_page)
724         std     r3,_DAR(r1)
725         std     r4,_DSISR(r1)
726
727         andis.  r0,r4,0xa450            /* weird error? */
728         bne-    handle_page_fault       /* if not, try to insert a HPTE */
729 BEGIN_FTR_SECTION
730         andis.  r0,r4,0x0020            /* Is it a segment table fault? */
731         bne-    do_ste_alloc            /* If so handle it */
732 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
733
734         /*
735          * On iSeries, we soft-disable interrupts here, then
736          * hard-enable interrupts so that the hash_page code can spin on
737          * the hash_table_lock without problems on a shared processor.
738          */
739         DISABLE_INTS
740
741         /*
742          * Currently, trace_hardirqs_off() will be called by DISABLE_INTS
743          * and will clobber volatile registers when irq tracing is enabled
744          * so we need to reload them. It may be possible to be smarter here
745          * and move the irq tracing elsewhere but let's keep it simple for
746          * now
747          */
748 #ifdef CONFIG_TRACE_IRQFLAGS
749         ld      r3,_DAR(r1)
750         ld      r4,_DSISR(r1)
751         ld      r5,_TRAP(r1)
752         ld      r12,_MSR(r1)
753         clrrdi  r5,r5,4
754 #endif /* CONFIG_TRACE_IRQFLAGS */
755         /*
756          * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
757          * accessing a userspace segment (even from the kernel). We assume
758          * kernel addresses always have the high bit set.
759          */
760         rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
761         rotldi  r0,r3,15                /* Move high bit into MSR_PR posn */
762         orc     r0,r12,r0               /* MSR_PR | ~high_bit */
763         rlwimi  r4,r0,32-13,30,30       /* becomes _PAGE_USER access bit */
764         ori     r4,r4,1                 /* add _PAGE_PRESENT */
765         rlwimi  r4,r5,22+2,31-2,31-2    /* Set _PAGE_EXEC if trap is 0x400 */
766
767         /*
768          * r3 contains the faulting address
769          * r4 contains the required access permissions
770          * r5 contains the trap number
771          *
772          * at return r3 = 0 for success
773          */
774         bl      .hash_page              /* build HPTE if possible */
775         cmpdi   r3,0                    /* see if hash_page succeeded */
776
777 BEGIN_FW_FTR_SECTION
778         /*
779          * If we had interrupts soft-enabled at the point where the
780          * DSI/ISI occurred, and an interrupt came in during hash_page,
781          * handle it now.
782          * We jump to ret_from_except_lite rather than fast_exception_return
783          * because ret_from_except_lite will check for and handle pending
784          * interrupts if necessary.
785          */
786         beq     13f
787 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
788
789 BEGIN_FW_FTR_SECTION
790         /*
791          * Here we have interrupts hard-disabled, so it is sufficient
792          * to restore paca->{soft,hard}_enable and get out.
793          */
794         beq     fast_exc_return_irq     /* Return from exception on success */
795 END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
796
797         /* For a hash failure, we don't bother re-enabling interrupts */
798         ble-    12f
799
800         /*
801          * hash_page couldn't handle it, set soft interrupt enable back
802          * to what it was before the trap.  Note that .raw_local_irq_restore
803          * handles any interrupts pending at this point.
804          */
805         ld      r3,SOFTE(r1)
806         TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
807         bl      .raw_local_irq_restore
808         b       11f
809
810 /* Here we have a page fault that hash_page can't handle. */
811 handle_page_fault:
812         ENABLE_INTS
813 11:     ld      r4,_DAR(r1)
814         ld      r5,_DSISR(r1)
815         addi    r3,r1,STACK_FRAME_OVERHEAD
816         bl      .do_page_fault
817         cmpdi   r3,0
818         beq+    13f
819         bl      .save_nvgprs
820         mr      r5,r3
821         addi    r3,r1,STACK_FRAME_OVERHEAD
822         lwz     r4,_DAR(r1)
823         bl      .bad_page_fault
824         b       .ret_from_except
825
826 13:     b       .ret_from_except_lite
827
828 /* We have a page fault that hash_page could handle but HV refused
829  * the PTE insertion
830  */
831 12:     bl      .save_nvgprs
832         mr      r5,r3
833         addi    r3,r1,STACK_FRAME_OVERHEAD
834         ld      r4,_DAR(r1)
835         bl      .low_hash_fault
836         b       .ret_from_except
837
838         /* here we have a segment miss */
839 do_ste_alloc:
840         bl      .ste_allocate           /* try to insert stab entry */
841         cmpdi   r3,0
842         bne-    handle_page_fault
843         b       fast_exception_return
844
845 /*
846  * r13 points to the PACA, r9 contains the saved CR,
847  * r11 and r12 contain the saved SRR0 and SRR1.
848  * r9 - r13 are saved in paca->exslb.
849  * We assume we aren't going to take any exceptions during this procedure.
850  * We assume (DAR >> 60) == 0xc.
851  */
852         .align  7
853 _GLOBAL(do_stab_bolted)
854         stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
855         std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
856
857         /* Hash to the primary group */
858         ld      r10,PACASTABVIRT(r13)
859         mfspr   r11,SPRN_DAR
860         srdi    r11,r11,28
861         rldimi  r10,r11,7,52    /* r10 = first ste of the group */
862
863         /* Calculate VSID */
864         /* This is a kernel address, so protovsid = ESID */
865         ASM_VSID_SCRAMBLE(r11, r9, 256M)
866         rldic   r9,r11,12,16    /* r9 = vsid << 12 */
867
868         /* Search the primary group for a free entry */
869 1:      ld      r11,0(r10)      /* Test valid bit of the current ste    */
870         andi.   r11,r11,0x80
871         beq     2f
872         addi    r10,r10,16
873         andi.   r11,r10,0x70
874         bne     1b
875
876         /* Stick for only searching the primary group for now.          */
877         /* At least for now, we use a very simple random castout scheme */
878         /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
879         mftb    r11
880         rldic   r11,r11,4,57    /* r11 = (r11 << 4) & 0x70 */
881         ori     r11,r11,0x10
882
883         /* r10 currently points to an ste one past the group of interest */
884         /* make it point to the randomly selected entry                 */
885         subi    r10,r10,128
886         or      r10,r10,r11     /* r10 is the entry to invalidate       */
887
888         isync                   /* mark the entry invalid               */
889         ld      r11,0(r10)
890         rldicl  r11,r11,56,1    /* clear the valid bit */
891         rotldi  r11,r11,8
892         std     r11,0(r10)
893         sync
894
895         clrrdi  r11,r11,28      /* Get the esid part of the ste         */
896         slbie   r11
897
898 2:      std     r9,8(r10)       /* Store the vsid part of the ste       */
899         eieio
900
901         mfspr   r11,SPRN_DAR            /* Get the new esid                     */
902         clrrdi  r11,r11,28      /* Permits a full 32b of ESID           */
903         ori     r11,r11,0x90    /* Turn on valid and kp                 */
904         std     r11,0(r10)      /* Put new entry back into the stab     */
905
906         sync
907
908         /* All done -- return from exception. */
909         lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
910         ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
911
912         andi.   r10,r12,MSR_RI
913         beq-    unrecov_slb
914
915         mtcrf   0x80,r9                 /* restore CR */
916
917         mfmsr   r10
918         clrrdi  r10,r10,2
919         mtmsrd  r10,1
920
921         mtspr   SPRN_SRR0,r11
922         mtspr   SPRN_SRR1,r12
923         ld      r9,PACA_EXSLB+EX_R9(r13)
924         ld      r10,PACA_EXSLB+EX_R10(r13)
925         ld      r11,PACA_EXSLB+EX_R11(r13)
926         ld      r12,PACA_EXSLB+EX_R12(r13)
927         ld      r13,PACA_EXSLB+EX_R13(r13)
928         rfid
929         b       .       /* prevent speculative execution */
930
931 /*
932  * Space for CPU0's segment table.
933  *
934  * On iSeries, the hypervisor must fill in at least one entry before
935  * we get control (with relocate on).  The address is given to the hv
936  * as a page number (see xLparMap below), so this must be at a
937  * fixed address (the linker can't compute (u64)&initial_stab >>
938  * PAGE_SHIFT).
939  */
940         . = STAB0_OFFSET        /* 0x6000 */
941         .globl initial_stab
942 initial_stab:
943         .space  4096
944
945 #ifdef CONFIG_PPC_PSERIES
946 /*
947  * Data area reserved for FWNMI option.
948  * This address (0x7000) is fixed by the RPA.
949  */
950         .= 0x7000
951         .globl fwnmi_data_area
952 fwnmi_data_area:
953 #endif /* CONFIG_PPC_PSERIES */
954
955         /* iSeries does not use the FWNMI stuff, so it is safe to put
956          * this here, even if we later allow kernels that will boot on
957          * both pSeries and iSeries */
958 #ifdef CONFIG_PPC_ISERIES
959         . = LPARMAP_PHYS
960         .globl xLparMap
961 xLparMap:
962         .quad   HvEsidsToMap            /* xNumberEsids */
963         .quad   HvRangesToMap           /* xNumberRanges */
964         .quad   STAB0_PAGE              /* xSegmentTableOffs */
965         .zero   40                      /* xRsvd */
966         /* xEsids (HvEsidsToMap entries of 2 quads) */
967         .quad   PAGE_OFFSET_ESID        /* xKernelEsid */
968         .quad   PAGE_OFFSET_VSID        /* xKernelVsid */
969         .quad   VMALLOC_START_ESID      /* xKernelEsid */
970         .quad   VMALLOC_START_VSID      /* xKernelVsid */
971         /* xRanges (HvRangesToMap entries of 3 quads) */
972         .quad   HvPagesToMap            /* xPages */
973         .quad   0                       /* xOffset */
974         .quad   PAGE_OFFSET_VSID << (SID_SHIFT - HW_PAGE_SHIFT) /* xVPN */
975
976 #endif /* CONFIG_PPC_ISERIES */
977
978 #ifdef CONFIG_PPC_PSERIES
979         . = 0x8000
980 #endif /* CONFIG_PPC_PSERIES */