Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/m68k/m68k Add a common source of m68k bus error and...



details:   https://anonhg.NetBSD.org/src/rev/19d6cd2b486f
branches:  trunk
changeset: 327711:19d6cd2b486f
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Sat Mar 15 09:22:36 2014 +0000

description:
Add a common source of m68k bus error and address error handlers.

This will be included from each MD locore.s as other common m68k
asm files like trap_subr.s and support.s etc.

diffstat:

 sys/arch/m68k/m68k/busaddrerr.s |  272 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 272 insertions(+), 0 deletions(-)

diffs (276 lines):

diff -r 3b7c76104a66 -r 19d6cd2b486f sys/arch/m68k/m68k/busaddrerr.s
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/m68k/m68k/busaddrerr.s   Sat Mar 15 09:22:36 2014 +0000
@@ -0,0 +1,272 @@
+/*     $NetBSD: busaddrerr.s,v 1.1 2014/03/15 09:22:36 tsutsui Exp $   */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1980, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah $Hdr: locore.s 1.66 92/12/22$
+ *
+ *     @(#)locore.s    8.6 (Berkeley) 5/27/94
+ */
+
+/*
+ * bus error and address error handler routines common to all m68k ports.
+ */
+
+/*
+ * NOTICE: This is not a standalone file.  To use it, #include it in
+ * your port's locore.s, like so:
+ *
+ *     #include <m68k/m68k/busaddrerr.s>
+ */
+
+/* assume M68K_MMU_MOTOROLA is default if none is defined */
+#if !defined(M68K_MMU_MOTOROLA) && !defined(M68K_MMU_HP)
+#define M68K_MMU_MOTOROLA
+#endif
+
+/*
+ * address error handler for 68040/68060
+ */
+#if defined(M68040) || defined(M68060)
+ENTRY_NOPROFILE(addrerr4060)
+       clrl    %sp@-                   | stack adjust count
+       moveml  %d0-%d7/%a0-%a7,%sp@-   | save user registers
+       movl    %usp,%a0                | save the user SP
+       movl    %a0,%sp@(FR_SP)         |   in the savearea
+       movl    %sp@(FR_HW+8),%sp@-
+       clrl    %sp@-                   | dummy code
+       movl    #T_ADDRERR,%sp@-        | mark address error
+       jra     _ASM_LABEL(faultstkadj) | and deal with it
+#endif
+
+/*
+ * bus error handler for 68060
+ */
+#if defined(M68060)
+ENTRY_NOPROFILE(buserr60)
+       clrl    %sp@-                   | stack adjust count
+       moveml  %d0-%d7/%a0-%a7,%sp@-   | save user registers
+       movl    %usp,%a0                | save the user SP
+       movl    %a0,%sp@(FR_SP)         |   in the savearea
+       movel   %sp@(FR_HW+12),%d0      | FSLW
+       btst    #2,%d0                  | branch prediction error?
+       jeq     Lnobpe
+       movc    %cacr,%d2
+       orl     #IC60_CABC,%d2          | clear all branch cache entries
+       movc    %d2,%cacr
+       movl    %d0,%d1
+#if defined(amiga) || defined(atari)
+       addql   #1,L60bpe
+#endif
+       andl    #0x7ffd,%d1             | check other faults
+       jeq     _ASM_LABEL(faultstkadjnotrap2)
+Lnobpe:
+| we need to adjust for misaligned addresses
+       movl    %sp@(FR_HW+8),%d1       | grab VA
+       btst    #27,%d0                 | check for mis-aligned access
+       jeq     Lberr3                  | no, skip
+       addl    #28,%d1                 | yes, get into next page
+                                       | operand case: 3,
+                                       | instruction case: 4+12+12
+                                       | XXX instr. case not done yet
+       andl    #PG_FRAME,%d1           | and truncate
+Lberr3:
+       movl    %d1,%sp@-
+       movl    %d0,%sp@-               | code is FSLW now.
+       andw    #0x1f80,%d0
+       jeq     Lberr60                 | it is a bus error
+       movl    #T_MMUFLT,%sp@-         | show that we are an MMU fault
+       jra     _ASM_LABEL(faultstkadj) | and deal with it
+Lberr60:
+       tstl    _C_LABEL(nofault)       | catch bus error?
+       jeq     Lisberr                 | no, handle as usual
+#ifdef mac68k
+       movl    %a2,_C_LABEL(mac68k_a2_fromfault) | save %a2
+       movl    %sp@(FR_HW+8+8),_C_LABEL(m68k_fault_addr) | save fault addr
+#endif
+       movl    _C_LABEL(nofault),%sp@- | yes,
+       jbsr    _C_LABEL(longjmp)       |  longjmp(nofault)
+       /* NOTREACHED */
+#endif
+
+/*
+ * bus error handler for 68040
+ */
+#if defined(M68040)
+ENTRY_NOPROFILE(buserr40)
+       clrl    %sp@-                   | stack adjust count
+       moveml  %d0-%d7/%a0-%a7,%sp@-   | save user registers
+       movl    %usp,%a0                | save the user SP
+       movl    %a0,%sp@(FR_SP)         |   in the savearea
+       movl    %sp@(FR_HW+20),%d1      | get fault address
+       moveq   #0,%d0
+       movw    %sp@(FR_HW+12),%d0      | get SSW
+       btst    #11,%d0                 | check for mis-aligned
+       jeq     Lbe1stpg                | no skip
+       addl    #3,%d1                  | get into next page
+       andl    #PG_FRAME,%d1           | and truncate
+Lbe1stpg:
+       movl    %d1,%sp@-               | pass fault address.
+       movl    %d0,%sp@-               | pass SSW as code
+       btst    #10,%d0                 | test ATC
+       jeq     Lberr40                 | it is a bus error
+       movl    #T_MMUFLT,%sp@-         | show that we are an MMU fault
+       jra     _ASM_LABEL(faultstkadj) | and deal with it
+Lberr40:
+       tstl    _C_LABEL(nofault)       | catch bus error?
+       jeq     Lisberr                 | no, handle as usual
+#ifdef mac68k
+       movl    %a2,_C_LABEL(mac68k_a2_fromfault) | save %a2
+       movl    %sp@(FR_HW+8+20),_C_LABEL(m68k_fault_addr) | save fault addr
+#endif
+       movl    _C_LABEL(nofault),%sp@- | yes,
+       jbsr    _C_LABEL(longjmp)       |  longjmp(nofault)
+       /* NOTREACHED */
+#endif
+
+/*
+ * bus error and address error handlers for 68020/68030
+ */
+#if defined(M68020) || defined(M68030)
+ENTRY_NOPROFILE(busaddrerr2030)
+       clrl    %sp@-                   | stack adjust count
+       moveml  %d0-%d7/%a0-%a7,%sp@-   | save user registers
+       movl    %usp,%a0                | save the user SP
+       movl    %a0,%sp@(FR_SP)         |   in the savearea
+       moveq   #0,%d0
+       movw    %sp@(FR_HW+10),%d0      | grab SSW for fault processing
+       btst    #12,%d0                 | RB set?
+       jeq     LbeX0                   | no, test RC
+       bset    #14,%d0                 | yes, must set FB
+       movw    %d0,%sp@(FR_HW+10)      | for hardware too
+LbeX0:
+       btst    #13,%d0                 | RC set?
+       jeq     LbeX1                   | no, skip
+       bset    #15,%d0                 | yes, must set FC
+       movw    %d0,%sp@(FR_HW+10)      | for hardware too
+LbeX1:
+       btst    #8,%d0                  | data fault?
+       jeq     Lbe0                    | no, check for hard cases
+       movl    %sp@(FR_HW+16),%d1      | fault address is as given in frame
+       jra     Lbe10                   | thats it
+Lbe0:
+       btst    #4,%sp@(FR_HW+6)        | long (type B) stack frame?
+       jne     Lbe4                    | yes, go handle
+       movl    %sp@(FR_HW+2),%d1       | no, can use save PC
+       btst    #14,%d0                 | FB set?
+       jeq     Lbe3                    | no, try FC
+       addql   #4,%d1                  | yes, adjust address
+       jra     Lbe10                   | done
+Lbe3:
+       btst    #15,%d0                 | FC set?
+       jeq     Lbe10                   | no, done
+       addql   #2,%d1                  | yes, adjust address
+       jra     Lbe10                   | done
+Lbe4:
+       movl    %sp@(FR_HW+36),%d1      | long format, use stage B address
+       btst    #15,%d0                 | FC set?
+       jeq     Lbe10                   | no, all done
+       subql   #2,%d1                  | yes, adjust address
+Lbe10:
+       movl    %d1,%sp@-               | push fault VA
+       movl    %d0,%sp@-               | and padded SSW
+       movw    %sp@(FR_HW+8+6),%d0     | get frame format/vector offset
+       andw    #0x0FFF,%d0             | clear out frame format
+       cmpw    #12,%d0                 | address error vector?
+       jeq     Lisaerr                 | yes, go to it
+#if defined(M68K_MMU_MOTOROLA)
+#if defined(M68K_MMU_HP)
+       tstl    _C_LABEL(mmutype)       | HP MMU?
+       jeq     Lbehpmmu                | yes, different MMU fault handler
+#endif
+       movl    %d1,%a0                 | fault address
+       movl    %sp@,%d0                | function code from ssw
+       btst    #8,%d0                  | data fault?
+       jne     Lbe10a
+       movql   #1,%d0                  | user program access FC
+                                       | (we dont separate data/program)
+       btst    #5,%sp@(FR_HW+8)        | supervisor mode?
+       jeq     Lbe10a                  | if no, done
+       movql   #5,%d0                  | else supervisor program access
+Lbe10a:
+       ptestr  %d0,%a0@,#7             | do a table search
+       pmove   %psr,%sp@               | save result
+       movb    %sp@,%d1
+       btst    #2,%d1                  | invalid (incl. limit viol. and berr)?
+       jeq     Lmightnotbemerr         | no -> wp check
+       btst    #7,%d1                  | is it MMU table berr?
+       jne     Lisberr1                | yes, needs not be fast.
+#endif /* M68K_MMU_MOTOROLA */
+Lismerr:
+       movl    #T_MMUFLT,%sp@-         | show that we are an MMU fault
+       jra     _ASM_LABEL(faultstkadj) | and deal with it
+#if defined(M68K_MMU_MOTOROLA)
+Lmightnotbemerr:
+       btst    #3,%d1                  | write protect bit set?
+       jeq     Lisberr1                | no, must be bus error
+       movl    %sp@,%d0                | ssw into low word of d0
+       andw    #0xc0,%d0               | write protect is set on page:
+       cmpw    #0x40,%d0               | was it read cycle?
+       jne     Lismerr                 | no, was not WPE, must be MMU fault
+       jra     Lisberr1                | real bus err needs not be fast.
+#endif /* M68K_MMU_MOTOROLA */
+#if defined(M68K_MMU_HP)
+Lbehpmmu:
+       MMUADDR(%a0)
+       movl    %a0@(MMUSTAT),%d0       | read MMU status
+        btst   #3,%d0                  | MMU fault?
+       jeq     Lisberr1                | no, just a non-MMU bus error
+       andl    #~MMU_FAULT,%a0@(MMUSTAT)| yes, clear fault bits
+       movw    %d0,%sp@                | pass MMU stat in upper half of code
+       jra     Lismerr                 | and handle it
+#endif
+Lisaerr:
+       movl    #T_ADDRERR,%sp@-        | mark address error
+       jra     _ASM_LABEL(faultstkadj) | and deal with it
+Lisberr1:
+       clrw    %sp@                    | re-clear pad word
+       tstl    _C_LABEL(nofault)       | catch bus error?
+       jeq     Lisberr                 | no, handle as usual
+#ifdef mac68k
+       movl    %a2,_C_LABEL(mac68k_a2_fromfault) | save %a2
+       movl    %sp@(FR_HW+8+16),_C_LABEL(m68k_fault_addr) | save fault addr
+#endif
+       movl    _C_LABEL(nofault),%sp@- | yes,
+       jbsr    _C_LABEL(longjmp)       |  longjmp(nofault)
+       /* NOTREACHED */
+#endif /* M68020 || M68030 */
+
+Lisberr:                               | also used by M68040/60
+       movl    #T_BUSERR,%sp@-         | mark bus error
+       jra     _ASM_LABEL(faultstkadj) | and deal with it
+



Home | Main Index | Thread Index | Old Index