Annotation of sys/arch/m68k/fpsp/netbsd.sa, Revision 1.1
1.1 ! nbrk 1: * $OpenBSD: netbsd.sa,v 1.5 2004/01/27 16:16:27 miod Exp $
! 2: * $NetBSD: netbsd.sa,v 1.3 1997/04/25 02:26:04 thorpej Exp $
! 3:
! 4: * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
! 5: * M68000 Hi-Performance Microprocessor Division
! 6: * M68040 Software Package
! 7: *
! 8: * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
! 9: * All rights reserved.
! 10: *
! 11: * THE SOFTWARE is provided on an "AS IS" basis and without warranty.
! 12: * To the maximum extent permitted by applicable law,
! 13: * MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
! 14: * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
! 15: * PARTICULAR PURPOSE and any warranty against infringement with
! 16: * regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
! 17: * and any accompanying written materials.
! 18: *
! 19: * To the maximum extent permitted by applicable law,
! 20: * IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
! 21: * (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
! 22: * PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
! 23: * OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
! 24: * SOFTWARE. Motorola assumes no responsibility for the maintenance
! 25: * and support of the SOFTWARE.
! 26: *
! 27: * You are hereby granted a copyright license to use, modify, and
! 28: * distribute the SOFTWARE so long as this entire notice is retained
! 29: * without alteration in any modified and/or redistributed versions,
! 30: * and that such modified versions are clearly identified as such.
! 31: * No licenses are granted by implication, estoppel or otherwise
! 32: * under any patents or trademarks of Motorola, Inc.
! 33:
! 34: *
! 35: * skeleton.sa 3.2 4/26/91
! 36: *
! 37: * This file contains code that is system dependent and will
! 38: * need to be modified to install the FPSP.
! 39: *
! 40: * Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'.
! 41: * Put any target system specific handling that must be done immediately
! 42: * before the jump instruction. If there no handling necessary, then
! 43: * the 'fpsp_xxxx' handler entry point should be placed in the exception
! 44: * table so that the 'jmp' can be eliminated. If the FPSP determines that the
! 45: * exception is one that must be reported then there will be a
! 46: * return from the package by a 'jmp real_xxxx'. At that point
! 47: * the machine state will be identical to the state before
! 48: * the FPSP was entered. In particular, whatever condition
! 49: * that caused the exception will still be pending when the FPSP
! 50: * package returns. Thus, there will be system specific code
! 51: * to handle the exception.
! 52: *
! 53: * If the exception was completely handled by the package, then
! 54: * the return will be via a 'jmp fpsp_done'. Unless there is
! 55: * OS specific work to be done (such as handling a context switch or
! 56: * interrupt) the user program can be resumed via 'rte'.
! 57: *
! 58: * In the following skeleton code, some typical 'real_xxxx' handling
! 59: * code is shown. This code may need to be moved to an appropriate
! 60: * place in the target system, or rewritten.
! 61: *
! 62:
! 63: SKELETON IDNT 2,1 Motorola 040 Floating Point Software Package
! 64:
! 65: section 15
! 66: *
! 67: * The following counters are used for standalone testing
! 68: *
! 69:
! 70: section 8
! 71:
! 72: include fpsp.h
! 73:
! 74: *
! 75: * XXX Note, this is NOT valid Motorola syntax, but what else can we do?
! 76: *
! 77: #include "../include/asm.h"
! 78:
! 79: xref b1238_fix
! 80:
! 81: *
! 82: * Divide by Zero exception
! 83: *
! 84: * All dz exceptions are 'real', hence no fpsp_dz entry point.
! 85: *
! 86: xdef dz
! 87: dz:
! 88: link a6,#-LOCAL_SIZE
! 89: fsave -(sp)
! 90: bclr.b #E1,E_BYTE(a6)
! 91: frestore (sp)+
! 92: unlk a6
! 93: jmp _C_LABEL(fpfault)
! 94:
! 95: *
! 96: * Inexact exception
! 97: *
! 98: * All inexact exceptions are real, but the 'real' handler
! 99: * will probably want to clear the pending exception.
! 100: * The provided code will clear the E3 exception (if pending),
! 101: * otherwise clear the E1 exception. The frestore is not really
! 102: * necessary for E1 exceptions.
! 103: *
! 104: * Code following the 'inex' label is to handle bug #1232. In this
! 105: * bug, if an E1 snan, ovfl, or unfl occurred, and the process was
! 106: * swapped out before taking the exception, the exception taken on
! 107: * return was inex, rather than the correct exception. The snan, ovfl,
! 108: * and unfl exception to be taken must not have been enabled. The
! 109: * fix is to check for E1, and the existence of one of snan, ovfl,
! 110: * or unfl bits set in the fpsr. If any of these are set, branch
! 111: * to the appropriate handler for the exception in the fpsr. Note
! 112: * that this fix is only for d43b parts, and is skipped if the
! 113: * version number is not $40.
! 114: *
! 115: *
! 116: xdef real_inex
! 117: xdef inex
! 118: inex:
! 119: link a6,#-LOCAL_SIZE
! 120: fsave -(sp)
! 121: cmpi.b #VER_40,(sp) ;test version number
! 122: bne.b not_fmt40
! 123: fmove.l fpsr,-(sp)
! 124: btst.b #E1,E_BYTE(a6) ;test for E1 set
! 125: beq.b not_b1232
! 126: btst.b #snan_bit,2(sp) ;test for snan
! 127: beq inex_ckofl
! 128: addq.l #4,sp
! 129: frestore (sp)+
! 130: unlk a6
! 131: bra fpsp_snan
! 132: inex_ckofl:
! 133: btst.b #ovfl_bit,2(sp) ;test for ovfl
! 134: beq inex_ckufl
! 135: addq.l #4,sp
! 136: frestore (sp)+
! 137: unlk a6
! 138: bra fpsp_ovfl
! 139: inex_ckufl:
! 140: btst.b #unfl_bit,2(sp) ;test for unfl
! 141: beq not_b1232
! 142: addq.l #4,sp
! 143: frestore (sp)+
! 144: unlk a6
! 145: bra fpsp_unfl
! 146:
! 147: *
! 148: * We do not have the bug 1232 case. Clean up the stack and call
! 149: * real_inex.
! 150: *
! 151: not_b1232:
! 152: addq.l #4,sp
! 153: frestore (sp)+
! 154: unlk a6
! 155:
! 156: real_inex:
! 157: link a6,#-LOCAL_SIZE
! 158: fsave -(sp)
! 159: not_fmt40:
! 160: bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
! 161: beq.b inex_cke1
! 162: *
! 163: * Clear dirty bit on dest resister in the frame before branching
! 164: * to b1238_fix.
! 165: *
! 166: movem.l d0/d1,USER_DA(a6)
! 167: bfextu CMDREG1B(a6){6:3},d0 ;get dest reg no
! 168: bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
! 169: bsr.l b1238_fix ;test for bug1238 case
! 170: movem.l USER_DA(a6),d0/d1
! 171: bra.b inex_done
! 172: inex_cke1:
! 173: bclr.b #E1,E_BYTE(a6)
! 174: inex_done:
! 175: frestore (sp)+
! 176: unlk a6
! 177: jmp _C_LABEL(fpfault)
! 178:
! 179: *
! 180: * Overflow exception
! 181: *
! 182: xdef real_ovfl
! 183: real_ovfl:
! 184: link a6,#-LOCAL_SIZE
! 185: fsave -(sp)
! 186: bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
! 187: bne.b ovfl_done
! 188: bclr.b #E1,E_BYTE(a6)
! 189: ovfl_done:
! 190: frestore (sp)+
! 191: unlk a6
! 192: jmp _C_LABEL(fpfault)
! 193:
! 194: *
! 195: * Underflow exception
! 196: *
! 197: xdef real_unfl
! 198: real_unfl:
! 199: link a6,#-LOCAL_SIZE
! 200: fsave -(sp)
! 201: bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
! 202: bne.b unfl_done
! 203: bclr.b #E1,E_BYTE(a6)
! 204: unfl_done:
! 205: frestore (sp)+
! 206: unlk a6
! 207: jmp _C_LABEL(fpfault)
! 208:
! 209: *
! 210: * Signalling NAN exception
! 211: *
! 212: xdef real_snan
! 213: real_snan:
! 214: link a6,#-LOCAL_SIZE
! 215: fsave -(sp)
! 216: bclr.b #E1,E_BYTE(a6) ;snan is always an E1 exception
! 217: frestore (sp)+
! 218: unlk a6
! 219: jmp _C_LABEL(fpfault)
! 220:
! 221: *
! 222: * Operand Error exception
! 223: *
! 224: xdef real_operr
! 225: real_operr:
! 226: link a6,#-LOCAL_SIZE
! 227: fsave -(sp)
! 228: bclr.b #E1,E_BYTE(a6) ;operr is always an E1 exception
! 229: frestore (sp)+
! 230: unlk a6
! 231: jmp _C_LABEL(fpfault)
! 232:
! 233: *
! 234: * BSUN exception
! 235: *
! 236: * This sample handler simply clears the nan bit in the FPSR.
! 237: *
! 238: xdef real_bsun
! 239: real_bsun:
! 240: link a6,#-LOCAL_SIZE
! 241: fsave -(sp)
! 242: bclr.b #E1,E_BYTE(a6) ;bsun is always an E1 exception
! 243: fmove.l FPSR,-(sp)
! 244: bclr.b #nan_bit,(sp)
! 245: fmove.l (sp)+,FPSR
! 246: frestore (sp)+
! 247: unlk a6
! 248: jmp _C_LABEL(fpfault)
! 249:
! 250: *
! 251: * F-line exception
! 252: *
! 253: * A 'real' F-line exception is one that the FPSP isn't supposed to
! 254: * handle. E.g. an instruction with a co-processor ID that is not 1.
! 255: *
! 256: *
! 257: xdef real_fline
! 258: real_fline:
! 259: jmp _C_LABEL(fpfault)
! 260:
! 261: *
! 262: * Unsupported data type exception
! 263: *
! 264: xdef real_unsupp
! 265: real_unsupp:
! 266: link a6,#-LOCAL_SIZE
! 267: fsave -(sp)
! 268: bclr.b #E1,E_BYTE(a6) ;unsupp is always an E1 exception
! 269: frestore (sp)+
! 270: unlk a6
! 271: jmp _C_LABEL(fpfault)
! 272:
! 273: *
! 274: * Trace exception
! 275: *
! 276: xdef real_trace
! 277: real_trace:
! 278: rte
! 279:
! 280: *
! 281: * fpsp_fmt_error --- exit point for frame format error
! 282: *
! 283: * The fpu stack frame does not match the frames existing
! 284: * or planned at the time of this writing. The fpsp is
! 285: * unable to handle frame sizes not in the following
! 286: * version:size pairs:
! 287: *
! 288: * {4060, 4160} - busy frame
! 289: * {4028, 4130} - unimp frame
! 290: * {4000, 4100} - idle frame
! 291: *
! 292: * This entry point simply holds an f-line illegal value.
! 293: * Replace this with a call to your kernel panic code or
! 294: * code to handle future revisions of the fpu.
! 295: *
! 296: xdef fpsp_fmt_error
! 297: fpsp_fmt_error:
! 298: pea 1f
! 299: jsr _C_LABEL(panic)
! 300: dc.l $f27f0000 ;f-line illegal
! 301: 1:
! 302: .asciz "bad floating point stack frame"
! 303: .even
! 304:
! 305: *
! 306: * fpsp_done --- FPSP exit point
! 307: *
! 308: * The exception has been handled by the package and we are ready
! 309: * to return to user mode, but there may be OS specific code
! 310: * to execute before we do. If there is, do it now.
! 311: *
! 312: *
! 313: xref _ASM_LABEL(rei)
! 314: xdef fpsp_done
! 315: fpsp_done:
! 316: jmp _ASM_LABEL(rei)
! 317:
! 318: *
! 319: * mem_write --- write to user or supervisor address space
! 320: *
! 321: * Writes to memory while in supervisor mode. copyout accomplishes
! 322: * this via a 'moves' instruction. copyout is a UNIX SVR3 (and later) function.
! 323: * If you don't have copyout, use the local copy of the function below.
! 324: *
! 325: * a0 - supervisor source address
! 326: * a1 - user destination address
! 327: * d0 - number of bytes to write (maximum count is 12)
! 328: *
! 329: * The supervisor source address is guaranteed to point into the supervisor
! 330: * stack. The result is that a UNIX
! 331: * process is allowed to sleep as a consequence of a page fault during
! 332: * copyout. The probability of a page fault is exceedingly small because
! 333: * the 68040 always reads the destination address and thus the page
! 334: * faults should have already been handled.
! 335: *
! 336: * If the EXC_SR shows that the exception was from supervisor space,
! 337: * then just do a dumb (and slow) memory move. In a UNIX environment
! 338: * there shouldn't be any supervisor mode floating point exceptions.
! 339: *
! 340: xdef mem_write
! 341: mem_write:
! 342: btst.b #5,EXC_SR(a6) ;check for supervisor state
! 343: beq.b user_write
! 344: super_write:
! 345: move.b (a0)+,(a1)+
! 346: subq.l #1,d0
! 347: bne.b super_write
! 348: rts
! 349: user_write:
! 350: move.l d1,-(sp) ;preserve d1 just in case
! 351: move.l d0,-(sp)
! 352: move.l a1,-(sp)
! 353: move.l a0,-(sp)
! 354: jsr _C_LABEL(copyout)
! 355: add.l #12,sp
! 356: move.l (sp)+,d1
! 357: rts
! 358:
! 359: *
! 360: * mem_read --- read from user or supervisor address space
! 361: *
! 362: * Reads from memory while in supervisor mode. copyin accomplishes
! 363: * this via a 'moves' instruction. copyin is a UNIX SVR3 (and later) function.
! 364: * If you don't have copyin, use the local copy of the function below.
! 365: *
! 366: * The FPSP calls mem_read to read the original F-line instruction in order
! 367: * to extract the data register number when the 'Dn' addressing mode is
! 368: * used.
! 369: *
! 370: *Input:
! 371: * a0 - user source address
! 372: * a1 - supervisor destination address
! 373: * d0 - number of bytes to read (maximum count is 12)
! 374: *
! 375: * Like mem_write, mem_read always reads with a supervisor
! 376: * destination address on the supervisor stack. Also like mem_write,
! 377: * the EXC_SR is checked and a simple memory copy is done if reading
! 378: * from supervisor space is indicated.
! 379: *
! 380: xdef mem_read
! 381: mem_read:
! 382: btst.b #5,EXC_SR(a6) ;check for supervisor state
! 383: beq.b user_read
! 384: super_read:
! 385: move.b (a0)+,(a1)+
! 386: subq.l #1,d0
! 387: bne.b super_read
! 388: rts
! 389: user_read:
! 390: move.l d1,-(sp) ;preserve d1 just in case
! 391: move.l d0,-(sp)
! 392: move.l a1,-(sp)
! 393: move.l a0,-(sp)
! 394: jsr _C_LABEL(copyin)
! 395: add.l #12,sp
! 396: move.l (sp)+,d1
! 397: rts
! 398:
! 399: end
CVSweb