2 /* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */
5 * Copyright (C) 2001 Benno Rice
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
30 * Copyright (C) 1995, 1996 TooLs GmbH.
31 * All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by TooLs GmbH.
44 * 4. The name of TooLs GmbH may not be used to endorse or promote products
45 * derived from this software without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
52 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
53 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
54 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
55 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
56 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 #include "opt_ipkdb.h"
63 #include <sys/syscall.h>
65 #include <machine/trap.h>
66 #include <machine/param.h>
67 #include <machine/sr.h>
68 #include <machine/psl.h>
69 #include <machine/asm.h>
72 * Some instructions gas doesn't understand (yet?)
74 #define bdneq bdnzf 2,
83 .long 0 /* end of symbol table */
85 .long 0 /* proc0 p_addr */
92 .asciz "irq0", "irq1", "irq2", "irq3"
93 .asciz "irq4", "irq5", "irq6", "irq7"
94 .asciz "irq8", "irq9", "irq10", "irq11"
95 .asciz "irq12", "irq13", "irq14", "irq15"
96 .asciz "irq16", "irq17", "irq18", "irq19"
97 .asciz "irq20", "irq21", "irq22", "irq23"
98 .asciz "irq24", "irq25", "irq26", "irq27"
99 .asciz "irq28", "irq29", "irq30", "irq31"
100 .asciz "irq32", "irq33", "irq34", "irq35"
101 .asciz "irq36", "irq37", "irq38", "irq39"
102 .asciz "irq40", "irq41", "irq42", "irq43"
103 .asciz "irq44", "irq45", "irq46", "irq47"
104 .asciz "irq48", "irq49", "irq50", "irq51"
105 .asciz "irq52", "irq53", "irq54", "irq55"
106 .asciz "irq56", "irq57", "irq58", "irq59"
107 .asciz "irq60", "irq61", "irq62", "irq63"
108 .asciz "clock", "softclock", "softnet", "softserial"
112 .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
113 .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
114 .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
115 .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
120 .long 0 /* msr used in Open Firmware */
126 * File-scope for locore.S
129 .long 0 /* fake uarea during idle after exit */
131 .long 0 /* openfirmware entry point */
133 .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
136 * This symbol is here for the benefit of kvm_mkdb, and is supposed to
137 * mark the start of kernel text.
144 * Startup entry. Note, this must be the first thing in the text
152 andi. 0,0,PSL_IR|PSL_DR
186 lis 8,openfirmware_entry@ha
187 stw 5,openfirmware_entry@l(8) /* save client interface handler */
210 stw 4,proc0paddr@l(9)
211 addi 4,4,USPACE-FRAMELEN
217 addi 3,3,kernel_text@l
226 #if 0 /* XXX: We may switch back to this in the future. */
228 * OpenFirmware entry point
231 mflr 0 /* save return address */
233 stwu 1,-16(1) /* setup stack frame */
235 mfmsr 4 /* save msr */
238 lis 4,openfirmware_entry@ha /* get firmware entry point */
239 lwz 4,openfirmware_entry@l(4)
242 li 0,0 /* clear battable translations */
248 lis 4,ofmsr@ha /* Open Firmware msr */
253 lis 4,srsave@ha /* save old SR */
259 addis 5,5,0x10000000@h
263 lis 4,ofw_pmap@ha /* load OFW SR */
266 cmpwi 0,0 /* pm_sr[KERNEL_SR] == 0? */
267 beq 2f /* then skip (not initialized yet) */
272 addis 5,5,0x10000000@h
276 blrl /* call Open Firmware */
284 lis 4,srsave@ha /* restore saved SR */
290 addis 5,5,0x10000000@h
294 lwz 4,8(1) /* restore msr */
298 lwz 1,0(1) /* and return */
305 * Switch to/from OpenFirmware real mode stack
307 * Note: has to be called as the very first thing in OpenFirmware interface
331 * if (openfirmware(&args) < 0)
338 .comm firmstk,PAGE_SIZE,8
341 mfmsr 8 /* turn off interrupts */
342 andi. 0,8,~(PSL_EE|PSL_RI)@l
344 stw 8,4(1) /* abuse return address slot */
346 lwz 5,0(1) /* get length of stack frame */
349 lis 7,firmstk+PAGE_SIZE-8@ha
350 addi 7,7,firmstk+PAGE_SIZE-8@l
353 subf 4,5,7 /* make room for stack frame on
355 stw 6,-4(7) /* setup return pointer */
383 lwz 1,0(1) /* get callers original stack pointer */
385 lwz 0,4(1) /* get saved msr from abused slot */
388 lwz 1,0(1) /* return */
394 * Data used during primary/secondary traps/interrupts
396 #define tempsave 0x2e0 /* primary save area for trap handling */
397 #define disisave 0x3e0 /* primary save area for dsi/isi traps */
399 #define INTSTK (8*1024) /* 8K interrupt stack */
403 .space INTSTK /* interrupt stack */
406 .long -1 /* in-use marker */
408 #define SPILLSTK 1024 /* 1K spill stack */
410 .comm spillstk,SPILLSTK,8
413 * This code gets copied to all the trap vectors
414 * (except ISI/DSI, ALI, the interrupts, and possibly the debugging
415 * traps when using IPKDB).
418 .globl trapcode,trapsize
420 mtsprg 1,1 /* save SP */
421 stmw 28,tempsave(0) /* free r28-r31 */
422 mflr 28 /* save LR */
423 mfcr 29 /* save CR */
424 /* Test whether we already had PR set */
427 bc 4,17,1f /* branch if PSL_PR is clear */
430 addi 1,1,USPACE /* stack is top of user struct */
433 trapsize = .-trapcode
436 * For ALI: has to save DSISR and DAR
438 .globl alitrap,alisize
440 mtsprg 1,1 /* save SP */
441 stmw 28,tempsave(0) /* free r28-r31 */
444 stmw 30,tempsave+16(0)
445 mflr 28 /* save LR */
446 mfcr 29 /* save CR */
447 /* Test whether we already had PR set */
450 bc 4,17,1f /* branch if PSL_PR is clear */
453 addi 1,1,USPACE /* stack is top of user struct */
459 * Similar to the above for DSI
460 * Has to handle BAT spills
461 * and standard pagetable spills
463 .globl dsitrap,dsisize
465 stmw 28,disisave(0) /* free r28-r31 */
466 mfcr 29 /* save CR */
467 mfxer 30 /* save XER */
468 mtsprg 2,30 /* in SPRG2 */
469 mfsrr1 31 /* test kernel mode */
471 bc 12,17,1f /* branch if PSL_PR is set */
472 mfdar 31 /* get fault address */
473 rlwinm 31,31,7,25,28 /* get segment * 8 */
476 addis 31,31,battable@ha
477 lwz 30,battable@l(31)
479 bc 4,30,1f /* branch if supervisor valid is
482 lwz 31,battable+4@l(31)
483 /* We randomly use the highest two bat registers here */
494 mfsprg 30,2 /* restore XER */
496 mtcr 29 /* restore CR */
497 lmw 28,disisave(0) /* restore r28-r31 */
498 rfi /* return to trapped code */
500 mflr 28 /* save LR */
505 * Similar to the above for ISI
507 .globl isitrap,isisize
509 stmw 28,disisave(0) /* free r28-r31 */
510 mflr 28 /* save LR */
511 mfcr 29 /* save CR */
512 mfsrr1 31 /* test kernel mode */
514 bc 12,17,1f /* branch if PSL_PR is set */
515 mfsrr0 31 /* get fault address */
516 rlwinm 31,31,7,25,28 /* get segment * 8 */
519 addis 31,31,battable@ha
520 lwz 30,battable@l(31)
522 bc 4,30,1f /* branch if supervisor valid is
527 lwz 30,battable+4@l(31)
530 mtcr 29 /* restore CR */
531 lmw 28,disisave(0) /* restore r28-r31 */
532 rfi /* return to trapped code */
538 * This one for the external interrupt handler.
540 .globl extint,extsize
542 mtsprg 1,1 /* save SP */
543 stmw 28,tempsave(0) /* free r28-r31 */
544 mflr 28 /* save LR */
545 mfcr 29 /* save CR */
546 mfxer 30 /* save XER */
547 lis 1,intstk+INTSTK@ha /* get interrupt stack */
548 addi 1,1,intstk+INTSTK@l
549 lwz 31,0(1) /* were we already running on intstk? */
553 mfsprg 1,1 /* yes, get old SP */
559 * And this one for the decrementer interrupt handler.
561 .globl decrint,decrsize
563 mtsprg 1,1 /* save SP */
564 stmw 28,tempsave(0) /* free r28-r31 */
566 lwz 29,decrnest@l(28)
570 stw 29,decrnest@l(28)
571 mflr 28 /* save LR */
572 mfcr 29 /* save CR */
573 mfxer 30 /* save XER */
574 lis 1,intstk+INTSTK@ha /* get interrupt stack */
575 addi 1,1,intstk+INTSTK@l
576 lwz 31,0(1) /* were we already running on intstk? */
580 mfsprg 1,1 /* yes, get old SP */
589 * Now the tlb software load for 603 processors:
590 * (Code essentially from the 603e User Manual, Chapter 5, but
601 .globl tlbimiss,tlbimsize
603 mfspr 2,HASH1 /* get first pointer */
605 mfctr 0 /* save counter */
606 mfspr 3,ICMP /* get first compare value */
607 addi 2,2,-8 /* predec pointer */
609 mtctr 1 /* load counter */
611 lwzu 1,8(2) /* get next pte */
612 cmpl 0,1,3 /* see if found pte */
613 bdneq 2b /* loop if not eq */
614 bne 3f /* not found */
615 lwz 1,4(2) /* load tlb entry lower word */
616 andi. 3,1,8 /* check G-bit */
617 bne 4f /* if guarded, take ISI */
618 mtctr 0 /* restore counter */
619 mfspr 0,IMISS /* get the miss address for the tlbli */
620 mfsrr1 3 /* get the saved cr0 bits */
621 mtcrf 0x80,3 /* and restore */
622 ori 1,1,0x100 /* set the reference bit */
623 mtspr RPA,1 /* set the pte */
624 srwi 1,1,8 /* get byte 7 of pte */
625 tlbli 0 /* load the itlb */
626 stb 1,6(2) /* update page table */
629 3: /* not found in pteg */
630 andi. 1,3,0x40 /* have we already done second hash? */
632 mfspr 2,HASH2 /* get the second pointer */
633 ori 3,3,0x40 /* change the compare value */
635 addi 2,2,-8 /* predec pointer */
639 andi. 2,3,0xffff /* clean upper srr1 */
640 oris 2,2,0x8000000@h /* set srr<4> to flag prot violation */
642 5: /* not found anywhere */
644 andi. 2,3,0xffff /* clean upper srr1 */
645 oris 2,2,0x40000000@h /* set srr1<1> to flag pte not found */
647 mtctr 0 /* restore counter */
650 xoris 0,0,0x20000@h /* flip the msr<tgpr> bit */
651 mtcrf 0x80,3 /* restore cr0 */
652 mtmsr 0 /* now with native gprs */
655 tlbimsize = .-tlbimiss
657 .globl tlbdlmiss,tlbdlmsize
659 mfspr 2,HASH1 /* get first pointer */
661 mfctr 0 /* save counter */
662 mfspr 3,DCMP /* get first compare value */
663 addi 2,2,-8 /* predec pointer */
665 mtctr 1 /* load counter */
667 lwzu 1,8(2) /* get next pte */
668 cmpl 0,1,3 /* see if found pte */
669 bdneq 2b /* loop if not eq */
670 bne 3f /* not found */
671 lwz 1,4(2) /* load tlb entry lower word */
672 mtctr 0 /* restore counter */
673 mfspr 0,DMISS /* get the miss address for the tlbld */
674 mfsrr1 3 /* get the saved cr0 bits */
675 mtcrf 0x80,3 /* and restore */
676 ori 1,1,0x100 /* set the reference bit */
677 mtspr RPA,1 /* set the pte */
678 srwi 1,1,8 /* get byte 7 of pte */
679 tlbld 0 /* load the dtlb */
680 stb 1,6(2) /* update page table */
683 3: /* not found in pteg */
684 andi. 1,3,0x40 /* have we already done second hash? */
686 mfspr 2,HASH2 /* get the second pointer */
687 ori 3,3,0x40 /* change the compare value */
689 addi 2,2,-8 /* predec pointer */
691 5: /* not found anywhere */
693 lis 1,0x40000000@h /* set dsisr<1> to flag pte not found */
694 mtctr 0 /* restore counter */
695 andi. 2,3,0xffff /* clean upper srr1 */
697 mtdsisr 1 /* load the dsisr */
698 mfspr 1,DMISS /* get the miss address */
699 mtdar 1 /* put in dar */
701 xoris 0,0,0x20000@h /* flip the msr<tgpr> bit */
702 mtcrf 0x80,3 /* restore cr0 */
703 mtmsr 0 /* now with native gprs */
706 tlbdlmsize = .-tlbdlmiss
708 .globl tlbdsmiss,tlbdsmsize
710 mfspr 2,HASH1 /* get first pointer */
712 mfctr 0 /* save counter */
713 mfspr 3,DCMP /* get first compare value */
714 addi 2,2,-8 /* predec pointer */
716 mtctr 1 /* load counter */
718 lwzu 1,8(2) /* get next pte */
719 cmpl 0,1,3 /* see if found pte */
720 bdneq 2b /* loop if not eq */
721 bne 3f /* not found */
722 lwz 1,4(2) /* load tlb entry lower word */
723 andi. 3,1,0x80 /* check the C-bit */
726 mtctr 0 /* restore counter */
727 mfspr 0,DMISS /* get the miss address for the tlbld */
728 mfsrr1 3 /* get the saved cr0 bits */
729 mtcrf 0x80,3 /* and restore */
730 mtspr RPA,1 /* set the pte */
731 tlbld 0 /* load the dtlb */
734 3: /* not found in pteg */
735 andi. 1,3,0x40 /* have we already done second hash? */
737 mfspr 2,HASH2 /* get the second pointer */
738 ori 3,3,0x40 /* change the compare value */
740 addi 2,2,-8 /* predec pointer */
742 4: /* found, but C-bit = 0 */
743 rlwinm. 3,1,30,0,1 /* test PP */
747 9: /* found, but protection violation (PP==00)*/
749 lis 1,0xa000000@h /* indicate protection violation
752 7: /* found, PP=1x */
753 mfspr 3,DMISS /* get the miss address */
754 mfsrin 1,3 /* get the segment register */
756 rlwinm 3,3,18,31,31 /* get PR-bit */
757 rlwnm. 2,2,3,1,1 /* get the key */
758 bne- 9b /* protection violation */
759 8: /* found, set reference/change bits */
760 lwz 1,4(2) /* reload tlb entry */
764 5: /* not found anywhere */
766 lis 1,0x42000000@h /* set dsisr<1> to flag pte not found */
767 /* dsisr<6> to flag store */
769 mtctr 0 /* restore counter */
770 andi. 2,3,0xffff /* clean upper srr1 */
772 mtdsisr 1 /* load the dsisr */
773 mfspr 1,DMISS /* get the miss address */
774 mtdar 1 /* put in dar */
776 xoris 0,0,0x20000@h /* flip the msr<tgpr> bit */
777 mtcrf 0x80,3 /* restore cr0 */
778 mtmsr 0 /* now with native gprs */
781 tlbdsmsize = .-tlbdsmiss
784 #define ddbsave 0xde0 /* primary save area for DDB */
786 * In case of DDB we want a separate trap catcher for it
789 .comm ddbstk,INTSTK,8 /* ddb stack */
791 .globl ddblow,ddbsize
793 mtsprg 1,1 /* save SP */
794 stmw 28,ddbsave(0) /* free r28-r31 */
795 mflr 28 /* save LR */
796 mfcr 29 /* save CR */
797 lis 1,ddbstk+INTSTK@ha /* get new SP */
798 addi 1,1,ddbstk+INTSTK@l
804 #define ipkdbsave 0xde0 /* primary save area for IPKDB */
806 * In case of IPKDB we want a separate trap catcher for it
810 .comm ipkdbstk,INTSTK,8 /* ipkdb stack */
812 .globl ipkdblow,ipkdbsize
814 mtsprg 1,1 /* save SP */
815 stmw 28,ipkdbsave(0) /* free r28-r31 */
816 mflr 28 /* save LR */
817 mfcr 29 /* save CR */
818 lis 1,ipkdbstk+INTSTK@ha /* get new SP */
819 addi 1,1,ipkdbstk+INTSTK@l
821 ipkdbsize = .-ipkdblow
825 * FRAME_SETUP assumes:
827 * savearea r28-r31,DAR,DSISR (DAR & DSISR only for DSI traps)
832 * SRR0/1 as at start of trap
834 #define FRAME_SETUP(savearea) \
835 /* Have to enable translation to allow access of kernel stack: */ \
838 stmw 30,savearea+24(0); \
840 ori 30,30,(PSL_DR|PSL_IR); \
844 stwu 31,-FRAMELEN(1); \
845 stw 0,FRAME_0+8(1); \
846 stw 31,FRAME_1+8(1); \
847 stw 28,FRAME_LR+8(1); \
848 stw 29,FRAME_CR+8(1); \
849 lmw 28,savearea(0); \
850 stmw 2,FRAME_2+8(1); \
851 lmw 28,savearea+16(0); \
856 stw 3,FRAME_XER+8(1); \
857 stw 4,FRAME_CTR+8(1); \
858 stw 5,FRAME_EXC+8(1); \
859 stw 28,FRAME_DAR+8(1); \
860 stw 29,FRAME_DSISR+8(1); \
861 stw 30,FRAME_SRR0+8(1); \
862 stw 31,FRAME_SRR1+8(1)
864 #define FRAME_LEAVE(savearea) \
865 /* Now restore regs: */ \
866 lwz 2,FRAME_SRR0+8(1); \
867 lwz 3,FRAME_SRR1+8(1); \
868 lwz 4,FRAME_CTR+8(1); \
869 lwz 5,FRAME_XER+8(1); \
870 lwz 6,FRAME_LR+8(1); \
871 lwz 7,FRAME_CR+8(1); \
873 stw 3,savearea+4(0); \
877 mtsprg 1,7; /* save cr */ \
878 lmw 2,FRAME_2+8(1); \
879 lwz 0,FRAME_0+8(1); \
880 lwz 1,FRAME_1+8(1); \
881 mtsprg 2,2; /* save r2 & r3 */ \
883 /* Disable translation, machine check and recoverability: */ \
885 andi. 2,2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \
888 /* Decide whether we return to user mode: */ \
889 lwz 3,savearea+4(0); \
891 bc 4,17,1f; /* branch if PSL_PR is false */ \
892 /* Restore user & kernel access SR: */ \
893 /* lis 2,curpm@ha; get real address of pmap */ \
894 /* lwz 2,curpm@l(2); */ \
895 /* lwz 3,PM_USRSR(2); */ \
896 /* mtsr USER_SR,3; */ \
897 /* lwz 3,PM_KERNELSR(2); */ \
898 /* mtsr KERNEL_SR,3; */ \
899 1: mfsprg 2,1; /* restore cr */ \
902 lwz 3,savearea+4(0); \
905 mfsprg 2,2; /* restore r2 & r3 */ \
909 * Preamble code for DSI/ISI traps
915 stmw 30,tempsave+8(0)
918 stmw 30,tempsave+16(0)
920 /* Test whether we already had PR set */
923 mfsprg 1,1 /* restore SP (might have been
925 bc 4,17,s_trap /* branch if PSL_PR is false */
928 addi 1,1,USPACE /* stack is top of user struct */
931 * Now the common trap catching code.
934 /* First have to enable KERNEL mapping */
935 lis 31,KERNEL_SEGMENT@h
936 ori 31,31,KERNEL_SEGMENT@l
938 FRAME_SETUP(tempsave)
939 /* Now we can recover interrupts again: */
941 ori 7,7,(PSL_EE|PSL_FP|PSL_ME|PSL_RI)@l
944 /* Call C trap code: */
950 FRAME_LEAVE(tempsave)
954 * DSI second stage fault handler
957 mfdsisr 31 /* test whether this may be a
960 mtsprg 1,1 /* save SP */
961 bc 4,1,disitrap /* branch if table miss is false */
962 lis 1,spillstk+SPILLSTK@ha
963 addi 1,1,spillstk+SPILLSTK@l /* get spill stack */
965 stw 0,48(1) /* save non-volatile registers */
976 mflr 30 /* save trap type */
980 bl pmap_pte_spill /* try a spill */
982 mtctr 31 /* restore CTR */
983 mtlr 30 /* and trap type */
984 mfsprg 31,2 /* get saved XER */
985 mtxer 31 /* restore XER */
986 lwz 12,8(1) /* restore non-volatile registers */
998 mfsprg 1,1 /* restore SP */
999 mtcr 29 /* restore CR */
1000 mtlr 28 /* restore LR */
1001 lmw 28,disisave(0) /* restore r28-r31 */
1002 rfi /* return to trapped code */
1005 * ISI second stage fault handler
1008 mfsrr1 31 /* test whether this may be a
1011 mtsprg 1,1 /* save SP */
1012 bc 4,1,disitrap /* branch if table miss is false */
1013 lis 1,spillstk+SPILLSTK@ha
1014 addi 1,1,spillstk+SPILLSTK@l /* get spill stack */
1016 stw 0,48(1) /* save non-volatile registers */
1027 mfxer 30 /* save XER */
1029 mflr 30 /* save trap type */
1030 mfctr 31 /* & ctr */
1032 b s_pte_spill /* above */
1035 * External interrupt second level handler
1038 /* Save non-volatile registers: */ \
1039 stwu 1,-88(1); /* temporarily */ \
1041 mfsprg 0,1; /* get original SP */ \
1042 stw 0,0(1); /* and store it */ \
1053 stw 28,40(1); /* saved LR */ \
1054 stw 29,36(1); /* saved CR */ \
1055 stw 30,32(1); /* saved XER */ \
1056 lmw 28,tempsave(0); /* restore r28-r31 */ \
1058 lis 5,intr_depth@ha; \
1059 lwz 5,intr_depth@l(5); \
1066 /* interrupts are recoverable here, and enable translation */ \
1067 lis 3,(KERNEL_SEGMENT|SR_KS|SR_KP)@h; \
1068 ori 3,3,(KERNEL_SEGMENT|SR_KS|SR_KP)@l; \
1071 ori 5,5,(PSL_IR|PSL_DR|PSL_RI); \
1079 bl extint_call /* to be filled in later */
1082 /* Disable interrupts (should already be disabled) and MMU here: */
1084 andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l
1087 /* restore possibly overwritten registers: */
1102 /* Returning to user mode? */
1103 mtcr 6 /* saved SRR1 */
1104 bc 4,17,1f /* branch if PSL_PR is false */
1105 mfsprg 3,0 /* get pcpu */
1106 lwz 3,PC_CURPCB(3) /* get curpcb from pcpu */
1107 lwz 3,PCB_PMR(3) /* get pmap real address from curpcb */
1109 /* Setup for entry to realtrap: */
1110 lwz 3,0(1) /* get saved SP */
1115 stmw 28,tempsave(0) /* establish tempsave again */
1117 lwz 28,40(1) /* saved LR */
1118 lwz 29,36(1) /* saved CR */
1124 lis 30,intr_depth@ha /* adjust reentrancy count */
1125 lwz 31,intr_depth@l(30)
1127 stw 31,intr_depth@l(30)
1128 b realtrap /* XXX: should call ast(frame ptr) */
1130 /* Here is the normal exit of extintr: */
1137 lis 3,intr_depth@ha /* adjust reentrancy count */
1138 lwz 4,intr_depth@l(3)
1140 stw 4,intr_depth@l(3)
1148 * Decrementer interrupt second level handler
1152 addi 3,1,8 /* intr frame */
1156 stw 29,decrnest@l(28)
1161 * Deliberate entry to ddbtrap
1168 andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI)@l
1169 mtmsr 3 /* disable interrupts */
1179 * Now the ddb trap catching code.
1182 FRAME_SETUP(ddbsave)
1183 /* Call C trap code: */
1188 /* This wasn't for DDB, so switch to real trap: */
1189 lwz 3,FRAME_EXC+8(1) /* save exception */
1191 FRAME_LEAVE(ddbsave)
1192 mtsprg 1,1 /* prepare for entrance to realtrap */
1200 FRAME_LEAVE(ddbsave)
1206 * Deliberate entry to ipkdbtrap
1213 andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI)@l
1214 mtmsr 3 /* disable interrupts */
1216 stmw 28,ipkdbsave(0)
1224 * Now the ipkdb trap catching code.
1227 FRAME_SETUP(ipkdbsave)
1228 /* Call C trap code: */
1233 /* This wasn't for IPKDB, so switch to real trap: */
1234 lwz 3,FRAME_EXC+8(1) /* save exception */
1235 stw 3,ipkdbsave+8(0)
1236 FRAME_LEAVE(ipkdbsave)
1237 mtsprg 1,1 /* prepare for entrance to realtrap */
1241 lwz 31,ipkdbsave+8(0)
1245 FRAME_LEAVE(ipkdbsave)
1258 * int ipkdbfbyte(unsigned char *p)
1262 li 9,EXC_DSI /* establish new fault routine */
1265 lwz 6,ipkdbfault@l(6)
1267 #ifdef IPKDBUSERHACK
1273 dcbst 0,9 /* flush data... */
1275 icbi 0,9 /* and instruction caches */
1276 lbz 3,0(3) /* fetch data */
1277 stw 5,0(9) /* restore previous fault handler */
1278 dcbst 0,9 /* and flush data... */
1280 icbi 0,9 /* and instruction caches */
1284 * int ipkdbsbyte(unsigned char *p, int c)
1288 li 9,EXC_DSI /* establish new fault routine */
1291 lwz 6,ipkdbfault@l(6)
1293 #ifdef IPKDBUSERHACK
1299 dcbst 0,9 /* flush data... */
1301 icbi 0,9 /* and instruction caches */
1305 dcbst 0,6 /* Now do appropriate flushes
1308 icbi 0,6 /* and instruction caches */
1309 stw 5,0(9) /* restore previous fault handler */
1310 dcbst 0,9 /* and flush data... */
1312 icbi 0,9 /* and instruction caches */
1319 * Similar to setjmp to setup for handling faults on accesses to user memory.
1320 * Any routine using this may only call bcopy, either the form below,
1321 * or the (currently used) C code optimized, so it doesn't use any non-volatile
1330 stw 3,PCB_ONFAULT(4)
1339 * Signal "trampoline" code.
1347 .long esigcode-sigcode