2 * Copyright (C) 2006-2009 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3 * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com>
4 * Copyright (C) 2006 Juniper Networks, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
33 * Copyright (C) 1995, 1996 TooLs GmbH.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by TooLs GmbH.
47 * 4. The name of TooLs GmbH may not be used to endorse or promote products
48 * derived from this software without specific prior written permission.
50 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
51 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
52 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
55 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
56 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
57 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
58 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
59 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 * from: $NetBSD: trap_subr.S,v 1.20 2002/04/22 23:20:08 kleink Exp $
65 * NOTICE: This is not a standalone file. to use it, #include it in
66 * your port's locore.S, like so:
68 * #include <powerpc/booke/trap_subr.S>
74 * SPRG0 - pcpu pointer
75 * SPRG1 - all interrupts except TLB miss, critical, machine check
77 * SPRG3 - machine check
82 /* Get the per-CPU data structure */
83 #define GET_CPUINFO(r) mfsprg0 r
85 #define RES_GRANULE 32
86 #define RES_LOCK 0 /* offset to the 'lock' word */
87 #define RES_RECURSE 4 /* offset to the 'recurse' word */
90 * Standard interrupt prolog
92 * sprg_sp - SPRG{1-3} reg used to temporarily store the SP
93 * savearea - temp save area (pc_{tempsave, disisave, critsave, mchksave})
94 * isrr0-1 - save restore registers with CPU state at interrupt time (may be
95 * SRR0-1, CSRR0-1, MCSRR0-1
97 * 1. saves in the given savearea:
104 * 3. switches to kstack if needed
107 * - R31 can be used as scratch register until a new frame is layed on
108 * the stack with FRAME_SETUP
110 * - potential TLB miss: NO. Saveareas are always acessible via TLB1
111 * permanent entries, and within this prolog we do not dereference any
112 * locations potentially not in the TLB
114 #define STANDARD_PROLOG(sprg_sp, savearea, isrr0, isrr1) \
115 mtspr sprg_sp, %r1; /* Save SP */ \
116 GET_CPUINFO(%r1); /* Per-cpu structure */ \
117 stw %r30, (savearea+CPUSAVE_R30)(%r1); \
118 stw %r31, (savearea+CPUSAVE_R31)(%r1); \
121 stw %r30, (savearea+CPUSAVE_BOOKE_DEAR)(%r1); \
122 stw %r31, (savearea+CPUSAVE_BOOKE_ESR)(%r1); \
124 mfspr %r31, isrr1; /* MSR at interrupt time */ \
125 stw %r30, (savearea+CPUSAVE_SRR0)(%r1); \
126 stw %r31, (savearea+CPUSAVE_SRR1)(%r1); \
128 mfspr %r1, sprg_sp; /* Restore SP */ \
129 mfcr %r30; /* Save CR */ \
130 /* switch to per-thread kstack if intr taken in user mode */ \
131 mtcr %r31; /* MSR at interrupt time */ \
133 GET_CPUINFO(%r1); /* Per-cpu structure */ \
134 lwz %r1, PC_CURPCB(%r1); /* Per-thread kernel stack */ \
137 #define STANDARD_CRIT_PROLOG(sprg_sp, savearea, isrr0, isrr1) \
138 mtspr sprg_sp, %r1; /* Save SP */ \
139 GET_CPUINFO(%r1); /* Per-cpu structure */ \
140 stw %r30, (savearea+CPUSAVE_R30)(%r1); \
141 stw %r31, (savearea+CPUSAVE_R31)(%r1); \
144 stw %r30, (savearea+CPUSAVE_BOOKE_DEAR)(%r1); \
145 stw %r31, (savearea+CPUSAVE_BOOKE_ESR)(%r1); \
147 mfspr %r31, isrr1; /* MSR at interrupt time */ \
148 stw %r30, (savearea+CPUSAVE_SRR0)(%r1); \
149 stw %r31, (savearea+CPUSAVE_SRR1)(%r1); \
150 mfspr %r30, SPR_SRR0; \
151 mfspr %r31, SPR_SRR1; /* MSR at interrupt time */ \
152 stw %r30, (savearea+CPUSAVE_SRR0+8)(%r1); \
153 stw %r31, (savearea+CPUSAVE_SRR1+8)(%r1); \
155 mfspr %r1, sprg_sp; /* Restore SP */ \
156 mfcr %r30; /* Save CR */ \
157 /* switch to per-thread kstack if intr taken in user mode */ \
158 mtcr %r31; /* MSR at interrupt time */ \
160 GET_CPUINFO(%r1); /* Per-cpu structure */ \
161 lwz %r1, PC_CURPCB(%r1); /* Per-thread kernel stack */ \
165 * FRAME_SETUP assumes:
166 * SPRG{1-3} SP at the time interrupt occured
167 * savearea r30-r31, DEAR, ESR, xSRR0-1
172 * sprg_sp - SPRG reg containing SP at the time interrupt occured
173 * savearea - temp save
174 * exc - exception number (EXC_xxx)
176 * 1. sets a new frame
177 * 2. saves in the frame:
178 * - R0, R1 (SP at the time of interrupt), R2, LR, CR
179 * - R3-31 (R30-31 first restored from savearea)
180 * - XER, CTR, DEAR, ESR (from savearea), xSRR0-1
183 * - potential TLB miss: YES, since we make dereferences to kstack, which
184 * can happen not covered (we can have up to two DTLB misses if fortunate
185 * enough i.e. when kstack crosses page boundary and both pages are
188 #define FRAME_SETUP(sprg_sp, savearea, exc) \
189 mfspr %r31, sprg_sp; /* get saved SP */ \
190 /* establish a new stack frame and put everything on it */ \
191 stwu %r31, -FRAMELEN(%r1); \
192 stw %r0, FRAME_0+8(%r1); /* save r0 in the trapframe */ \
193 stw %r31, FRAME_1+8(%r1); /* save SP " " */ \
194 stw %r2, FRAME_2+8(%r1); /* save r2 " " */ \
196 stw %r31, FRAME_LR+8(%r1); /* save LR " " */ \
197 stw %r30, FRAME_CR+8(%r1); /* save CR " " */ \
199 lwz %r30, (savearea+CPUSAVE_R30)(%r2); /* get saved r30 */ \
200 lwz %r31, (savearea+CPUSAVE_R31)(%r2); /* get saved r31 */ \
202 stmw %r3, FRAME_3+8(%r1) ; \
203 /* save DEAR, ESR */ \
204 lwz %r28, (savearea+CPUSAVE_BOOKE_DEAR)(%r2); \
205 lwz %r29, (savearea+CPUSAVE_BOOKE_ESR)(%r2); \
206 stw %r28, FRAME_BOOKE_DEAR+8(%r1); \
207 stw %r29, FRAME_BOOKE_ESR+8(%r1); \
208 /* save XER, CTR, exc number */ \
211 stw %r3, FRAME_XER+8(%r1); \
212 stw %r4, FRAME_CTR+8(%r1); \
214 stw %r5, FRAME_EXC+8(%r1); \
216 mfspr %r3, SPR_DBCR0; \
217 stw %r3, FRAME_BOOKE_DBCR0+8(%r1); \
219 lwz %r30, (savearea+CPUSAVE_SRR0)(%r2); \
220 lwz %r31, (savearea+CPUSAVE_SRR1)(%r2); \
221 stw %r30, FRAME_SRR0+8(%r1); \
222 stw %r31, FRAME_SRR1+8(%r1)
226 * isrr0-1 - save restore registers to restore CPU state to (may be
227 * SRR0-1, CSRR0-1, MCSRR0-1
230 * - potential TLB miss: YES. The deref'd kstack may be not covered
232 #define FRAME_LEAVE(isrr0, isrr1) \
233 /* restore CTR, XER, LR, CR */ \
234 lwz %r4, FRAME_CTR+8(%r1); \
235 lwz %r5, FRAME_XER+8(%r1); \
236 lwz %r6, FRAME_LR+8(%r1); \
237 lwz %r7, FRAME_CR+8(%r1); \
242 /* restore DBCR0 */ \
243 lwz %r4, FRAME_BOOKE_DBCR0+8(%r1); \
244 mtspr SPR_DBCR0, %r4; \
245 /* restore xSRR0-1 */ \
246 lwz %r30, FRAME_SRR0+8(%r1); \
247 lwz %r31, FRAME_SRR1+8(%r1); \
250 /* restore R2-31, SP */ \
251 lmw %r2, FRAME_2+8(%r1) ; \
252 lwz %r0, FRAME_0+8(%r1); \
253 lwz %r1, FRAME_1+8(%r1); \
259 * saves LR, CR, SRR0-1, R20-31 in the TLBSAVE area
262 * - potential TLB miss: NO. It is crucial that we do not generate a TLB
263 * miss within the TLB prolog itself!
264 * - TLBSAVE is always translated
267 mtsprg4 %r1; /* Save SP */ \
270 /* calculate TLB nesting level and TLBSAVE instance address */ \
271 GET_CPUINFO(%r1); /* Per-cpu structure */ \
272 lwz %r28, PC_BOOKE_TLB_LEVEL(%r1); \
273 rlwinm %r29, %r28, 6, 23, 25; /* 4 x TLBSAVE_LEN */ \
274 addi %r28, %r28, 1; \
275 stw %r28, PC_BOOKE_TLB_LEVEL(%r1); \
276 addi %r29, %r29, PC_BOOKE_TLBSAVE@l; \
277 add %r1, %r1, %r29; /* current TLBSAVE ptr */ \
282 stmw %r20, (TLBSAVE_BOOKE_R20)(%r1); \
286 stw %r30, (TLBSAVE_BOOKE_LR)(%r1); \
287 stw %r31, (TLBSAVE_BOOKE_CR)(%r1); \
289 mfsrr0 %r30; /* execution addr at interrupt time */ \
290 mfsrr1 %r31; /* MSR at interrupt time*/ \
291 stw %r30, (TLBSAVE_BOOKE_SRR0)(%r1); /* save SRR0 */ \
292 stw %r31, (TLBSAVE_BOOKE_SRR1)(%r1); /* save SRR1 */ \
297 * restores LR, CR, SRR0-1, R20-31 from the TLBSAVE area
299 * same notes as for the TLB_PROLOG
301 #define TLB_RESTORE \
302 mtsprg4 %r1; /* Save SP */ \
303 GET_CPUINFO(%r1); /* Per-cpu structure */ \
304 /* calculate TLB nesting level and TLBSAVE instance addr */ \
305 lwz %r28, PC_BOOKE_TLB_LEVEL(%r1); \
306 subi %r28, %r28, 1; \
307 stw %r28, PC_BOOKE_TLB_LEVEL(%r1); \
308 rlwinm %r29, %r28, 6, 23, 25; /* 4 x TLBSAVE_LEN */ \
309 addi %r29, %r29, PC_BOOKE_TLBSAVE@l; \
310 add %r1, %r1, %r29; \
312 /* restore LR, CR */ \
313 lwz %r30, (TLBSAVE_BOOKE_LR)(%r1); \
314 lwz %r31, (TLBSAVE_BOOKE_CR)(%r1); \
317 /* restore SRR0-1 */ \
318 lwz %r30, (TLBSAVE_BOOKE_SRR0)(%r1); \
319 lwz %r31, (TLBSAVE_BOOKE_SRR1)(%r1); \
322 /* restore R20-31 */ \
323 lmw %r20, (TLBSAVE_BOOKE_R20)(%r1); \
329 lwz %r21, PC_CURTHREAD(%r20); \
330 lwz %r22, PC_BOOKE_TLB_LOCK(%r20); \
332 1: lwarx %r23, 0, %r22; \
333 cmpwi %r23, MTX_UNOWNED; \
336 /* check if this is recursion */ \
337 cmplw cr0, %r21, %r23; \
340 2: /* try to acquire lock */ \
341 stwcx. %r21, 0, %r22; \
344 /* got it, update recursion counter */ \
345 lwz %r21, RES_RECURSE(%r22); \
346 addi %r21, %r21, 1; \
347 stw %r21, RES_RECURSE(%r22); \
353 lwz %r21, PC_CURTHREAD(%r20); \
354 lwz %r22, PC_BOOKE_TLB_LOCK(%r20); \
356 /* update recursion counter */ \
357 lwz %r23, RES_RECURSE(%r22); \
358 subi %r23, %r23, 1; \
359 stw %r23, RES_RECURSE(%r22); \
366 /* release the lock */ \
367 li %r23, MTX_UNOWNED; \
376 #define INTERRUPT(label) \
382 * Interrupt handling routines in BookE can be flexibly placed and do not have
383 * to live in pre-defined vectors location. Note they need to be TLB-mapped at
384 * all times in order to be able to handle exceptions. We thus arrange for
385 * them to be part of kernel text which is always TLB-accessible.
387 * The interrupt handling routines have to be 16 bytes aligned: we align them
388 * to 32 bytes (cache line length) which supposedly performs better.
392 .globl CNAME(interrupt_vector_base)
394 interrupt_vector_base:
396 /*****************************************************************************
397 * Critical input interrupt
398 ****************************************************************************/
399 INTERRUPT(int_critical_input)
400 STANDARD_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1)
401 FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_CRIT)
403 bl CNAME(powerpc_crit_interrupt)
404 FRAME_LEAVE(SPR_CSRR0, SPR_CSRR1)
408 /*****************************************************************************
409 * Machine check interrupt
410 ****************************************************************************/
411 INTERRUPT(int_machine_check)
412 STANDARD_PROLOG(SPR_SPRG3, PC_BOOKE_MCHKSAVE, SPR_MCSRR0, SPR_MCSRR1)
413 FRAME_SETUP(SPR_SPRG3, PC_BOOKE_MCHKSAVE, EXC_MCHK)
415 bl CNAME(powerpc_mchk_interrupt)
416 FRAME_LEAVE(SPR_MCSRR0, SPR_MCSRR1)
420 /*****************************************************************************
421 * Data storage interrupt
422 ****************************************************************************/
423 INTERRUPT(int_data_storage)
424 STANDARD_PROLOG(SPR_SPRG1, PC_DISISAVE, SPR_SRR0, SPR_SRR1)
425 FRAME_SETUP(SPR_SPRG1, PC_DISISAVE, EXC_DSI)
429 /*****************************************************************************
430 * Instruction storage interrupt
431 ****************************************************************************/
432 INTERRUPT(int_instr_storage)
433 STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
434 FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_ISI)
438 /*****************************************************************************
439 * External input interrupt
440 ****************************************************************************/
441 INTERRUPT(int_external_input)
442 STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
443 FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_EXI)
444 bl CNAME(powerpc_extr_interrupt)
448 INTERRUPT(int_alignment)
449 STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
450 FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_ALI)
454 INTERRUPT(int_program)
455 STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
456 FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_PGM)
460 /*****************************************************************************
462 ****************************************************************************/
463 INTERRUPT(int_syscall)
464 STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
465 FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_SC)
469 /*****************************************************************************
470 * Decrementer interrupt
471 ****************************************************************************/
472 INTERRUPT(int_decrementer)
473 STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
474 FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_DECR)
476 bl CNAME(powerpc_decr_interrupt)
480 /*****************************************************************************
481 * Fixed interval timer
482 ****************************************************************************/
483 INTERRUPT(int_fixed_interval_timer)
484 STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
485 FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_FIT)
489 /*****************************************************************************
491 ****************************************************************************/
492 INTERRUPT(int_watchdog)
493 STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
494 FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_WDOG)
498 /*****************************************************************************
499 * Data TLB miss interrupt
501 * There can be nested TLB misses - while handling a TLB miss we reference
502 * data structures that may be not covered by translations. We support up to
503 * TLB_NESTED_MAX-1 nested misses.
514 * r20:r23 - scratch registers
515 ****************************************************************************/
516 INTERRUPT(int_data_tlb_error)
523 * Save MAS0-MAS2 registers. There might be another tlb miss during
524 * pte lookup overwriting current contents (which was hw filled).
530 /* Check faulting address. */
531 lis %r21, VM_MAXUSER_ADDRESS@h
532 ori %r21, %r21, VM_MAXUSER_ADDRESS@l
533 cmplw cr0, %r31, %r21
536 /* If it's kernel address, allow only supervisor mode misses. */
539 bt 17, search_failed /* check MSR[PR] */
542 /* Load r26 with kernel_pmap address */
543 lis %r26, kernel_pmap_store@h
544 ori %r26, %r26, kernel_pmap_store@l
546 /* Force kernel tid, set TID to 0 in MAS1. */
548 rlwimi %r28, %r21, 0, 8, 15 /* clear TID bits */
551 /* This may result in nested tlb miss. */
552 bl pte_lookup /* returns PTE address in R25 */
554 cmpwi %r25, 0 /* pte found? */
557 /* Finish up, write TLB entry. */
566 /* Load r26 with current user space process pmap */
568 lwz %r26, PC_CURPMAP(%r26)
574 * Whenever we don't find a TLB mapping in PT, set a TLB0 entry with
575 * the faulting virtual address anyway, but put a fake RPN and no
576 * access rights. This should cause a following {D,I}SI exception.
578 lis %r23, 0xffff0000@h /* revoke all permissions */
580 /* Load MAS registers. */
595 /*****************************************************************************
597 * Return pte address that corresponds to given pmap/va. If there is no valid
602 * output: r25 - pte address
604 * scratch regs used: r21
606 ****************************************************************************/
609 beq 1f /* fail quickly if pmap is invalid */
611 srwi %r21, %r31, PDIR_SHIFT /* pdir offset */
612 slwi %r21, %r21, PDIR_ENTRY_SHIFT /* multiply by pdir entry size */
614 addi %r25, %r26, PM_PDIR /* pmap pm_dir[] address */
615 add %r25, %r25, %r21 /* offset within pm_pdir[] table */
617 * Get ptbl address, i.e. pmap->pm_pdir[pdir_idx]
618 * This load may cause a Data TLB miss for non-kernel pmap!
624 lis %r21, PTBL_MASK@h
625 ori %r21, %r21, PTBL_MASK@l
628 /* ptbl offset, multiply by ptbl entry size */
629 srwi %r21, %r21, (PTBL_SHIFT - PTBL_ENTRY_SHIFT)
631 add %r25, %r25, %r21 /* address of pte entry */
634 * This load may cause a Data TLB miss for non-kernel pmap!
636 lwz %r21, PTE_FLAGS(%r25)
637 andis. %r21, %r21, PTE_VALID@h
644 /*****************************************************************************
646 * Load MAS1-MAS3 registers with data, write TLB entry
656 * scratch regs: r21-r23
658 ****************************************************************************/
661 * Update PTE flags: we have to do it atomically, as pmap_protect()
662 * running on other CPUs could attempt to update the flags at the same
667 lwarx %r21, %r23, %r25 /* get pte->flags */
668 oris %r21, %r21, PTE_REFERENCED@h /* set referenced bit */
670 andi. %r22, %r21, (PTE_UW | PTE_UW)@l /* check if writable */
672 oris %r21, %r21, PTE_MODIFIED@h /* set modified bit */
674 stwcx. %r21, %r23, %r25 /* write it back */
678 rlwimi %r27, %r21, 0, 27, 30 /* insert WIMG bits from pte */
680 /* Setup MAS3 value in r23. */
681 lwz %r23, PTE_RPN(%r25) /* get pte->rpn */
683 rlwimi %r23, %r21, 24, 26, 31 /* insert protection bits from pte */
685 /* Load MAS registers. */
700 /*****************************************************************************
701 * Instruction TLB miss interrupt
703 * Same notes as for the Data TLB miss
704 ****************************************************************************/
705 INTERRUPT(int_inst_tlb_error)
709 mfsrr0 %r31 /* faulting address */
712 * Save MAS0-MAS2 registers. There might be another tlb miss during pte
713 * lookup overwriting current contents (which was hw filled).
723 bt 17, search_user_pmap
727 .globl interrupt_vector_top
728 interrupt_vector_top:
730 /*****************************************************************************
732 ****************************************************************************/
734 STANDARD_CRIT_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1)
735 FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_DEBUG)
736 lwz %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0)(%r2);
737 lis %r4, interrupt_vector_base@ha
738 addi %r4, %r4, interrupt_vector_base@l
741 lis %r4, interrupt_vector_top@ha
742 addi %r4, %r4, interrupt_vector_top@l
745 /* Disable single-stepping for the interrupt handlers. */
746 lwz %r3, FRAME_SRR1+8(%r1);
747 rlwinm %r3, %r3, 0, 23, 21
748 stw %r3, FRAME_SRR1+8(%r1);
749 /* Restore srr0 and srr1 as they could have been clobbered. */
750 lwz %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0+8)(%r2);
752 lwz %r4, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR1+8)(%r2);
759 * Handle ASTs, needed for proper support of single-stepping.
760 * We actually need to return to the process with an rfi.
764 FRAME_LEAVE(SPR_CSRR0, SPR_CSRR1)
768 /*****************************************************************************
770 ****************************************************************************/
772 /* Call C trap dispatcher */
776 .globl CNAME(trapexit) /* exported for db_backtrace use */
778 /* disable interrupts */
781 /* Test AST pending - makes sense for user process only */
782 lwz %r5, FRAME_SRR1+8(%r1)
787 lwz %r4, PC_CURTHREAD(%r3)
788 lwz %r4, TD_FLAGS(%r4)
789 lis %r5, (TDF_ASTPENDING | TDF_NEEDRESCHED)@h
790 ori %r5, %r5, (TDF_ASTPENDING | TDF_NEEDRESCHED)@l
794 /* re-enable interrupts before calling ast() */
799 .globl CNAME(asttrapexit) /* db_backtrace code sentinel #2 */
801 b trapexit /* test ast ret value ? */
803 FRAME_LEAVE(SPR_SRR0, SPR_SRR1)
809 * Deliberate entry to dbtrap
811 .globl CNAME(breakpoint)
816 andi. %r3, %r3, ~(PSL_EE | PSL_ME)@l
817 mtmsr %r3 /* disable interrupts */
820 stw %r30, (PC_DBSAVE+CPUSAVE_R30)(%r3)
821 stw %r31, (PC_DBSAVE+CPUSAVE_R31)(%r3)
828 stw %r30, (PC_DBSAVE+CPUSAVE_BOOKE_DEAR)(%r3)
829 stw %r31, (PC_DBSAVE+CPUSAVE_BOOKE_ESR)(%r3)
833 stw %r30, (PC_DBSAVE+CPUSAVE_SRR0)(%r3)
834 stw %r31, (PC_DBSAVE+CPUSAVE_SRR1)(%r3)
840 * Now the kdb trap catching code.
843 FRAME_SETUP(SPR_SPRG1, PC_DBSAVE, EXC_DEBUG)
844 /* Call C trap code: */
846 bl CNAME(db_trap_glue)
849 /* This wasn't for KDB, so switch to real trap: */
853 FRAME_LEAVE(SPR_SRR0, SPR_SRR1)
860 lwz %r5, PC_CURTHREAD(%r5)
862 cmpwi %r4, MTX_UNOWNED
879 * TLB miss spin locks. For each CPU we have a reservation granule (32 bytes);
880 * only a single word from this granule will actually be used as a spin lock
881 * for mutual exclusion between TLB miss handler and pmap layer that
882 * manipulates page table contents.
886 GLOBAL(tlb0_miss_locks)
887 .space RES_GRANULE * MAXCPU