Annotation of sys/arch/m68k/fpsp/skeleton.sa, Revision 1.1
1.1 ! nbrk 1: * $OpenBSD: skeleton.sa,v 1.3 2001/09/20 17:02:30 mpech Exp $
! 2: * $NetBSD: skeleton.sa,v 1.3 1994/10/26 07:49:50 cgd 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: sigunimp dc.l 0
! 70: sigbsun dc.l 0
! 71: siginex dc.l 0
! 72: sigdz dc.l 0
! 73: sigunfl dc.l 0
! 74: sigovfl dc.l 0
! 75: sigoperr dc.l 0
! 76: sigsnan dc.l 0
! 77: sigunsupp dc.l 0
! 78:
! 79: section 8
! 80:
! 81: include fpsp.h
! 82:
! 83: xref b1238_fix
! 84:
! 85: *
! 86: * Divide by Zero exception
! 87: *
! 88: * All dz exceptions are 'real', hence no fpsp_dz entry point.
! 89: *
! 90: xdef dz
! 91: xdef real_dz
! 92: dz:
! 93: real_dz:
! 94: link a6,#-LOCAL_SIZE
! 95: fsave -(sp)
! 96: bclr.b #E1,E_BYTE(a6)
! 97: frestore (sp)+
! 98: unlk a6
! 99:
! 100: add.l #1,sigdz ;for standalone testing
! 101:
! 102: rte
! 103: *
! 104: * Inexact exception
! 105: *
! 106: * All inexact exceptions are real, but the 'real' handler
! 107: * will probably want to clear the pending exception.
! 108: * The provided code will clear the E3 exception (if pending),
! 109: * otherwise clear the E1 exception. The frestore is not really
! 110: * necessary for E1 exceptions.
! 111: *
! 112: * Code following the 'inex' label is to handle bug #1232. In this
! 113: * bug, if an E1 snan, ovfl, or unfl occurred, and the process was
! 114: * swapped out before taking the exception, the exception taken on
! 115: * return was inex, rather than the correct exception. The snan, ovfl,
! 116: * and unfl exception to be taken must not have been enabled. The
! 117: * fix is to check for E1, and the existence of one of snan, ovfl,
! 118: * or unfl bits set in the fpsr. If any of these are set, branch
! 119: * to the appropriate handler for the exception in the fpsr. Note
! 120: * that this fix is only for d43b parts, and is skipped if the
! 121: * version number is not $40.
! 122: *
! 123: *
! 124: xdef real_inex
! 125: xdef inex
! 126: inex:
! 127: link a6,#-LOCAL_SIZE
! 128: fsave -(sp)
! 129: cmpi.b #VER_40,(sp) ;test version number
! 130: bne.b not_fmt40
! 131: fmove.l fpsr,-(sp)
! 132: btst.b #E1,E_BYTE(a6) ;test for E1 set
! 133: beq.b not_b1232
! 134: btst.b #snan_bit,2(sp) ;test for snan
! 135: beq inex_ckofl
! 136: add.l #4,sp
! 137: frestore (sp)+
! 138: unlk a6
! 139: bra snan
! 140: inex_ckofl:
! 141: btst.b #ovfl_bit,2(sp) ;test for ovfl
! 142: beq inex_ckufl
! 143: add.l #4,sp
! 144: frestore (sp)+
! 145: unlk a6
! 146: bra ovfl
! 147: inex_ckufl:
! 148: btst.b #unfl_bit,2(sp) ;test for unfl
! 149: beq not_b1232
! 150: add.l #4,sp
! 151: frestore (sp)+
! 152: unlk a6
! 153: bra unfl
! 154:
! 155: *
! 156: * We do not have the bug 1232 case. Clean up the stack and call
! 157: * real_inex.
! 158: *
! 159: not_b1232:
! 160: add.l #4,sp
! 161: frestore (sp)+
! 162: unlk a6
! 163:
! 164: real_inex:
! 165:
! 166: add.l #1,siginex ;for standalone testing
! 167:
! 168: link a6,#-LOCAL_SIZE
! 169: fsave -(sp)
! 170: not_fmt40:
! 171: bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
! 172: beq.b inex_cke1
! 173: *
! 174: * Clear dirty bit on dest resister in the frame before branching
! 175: * to b1238_fix.
! 176: *
! 177: movem.l d0/d1,USER_DA(a6)
! 178: bfextu CMDREG1B(a6){6:3},d0 ;get dest reg no
! 179: bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
! 180: bsr.l b1238_fix ;test for bug1238 case
! 181: movem.l USER_DA(a6),d0/d1
! 182: bra.b inex_done
! 183: inex_cke1:
! 184: bclr.b #E1,E_BYTE(a6)
! 185: inex_done:
! 186: frestore (sp)+
! 187: unlk a6
! 188: rte
! 189:
! 190: *
! 191: * Overflow exception
! 192: *
! 193: xref fpsp_ovfl
! 194: xdef real_ovfl
! 195: xdef ovfl
! 196: ovfl:
! 197: jmp fpsp_ovfl
! 198: real_ovfl:
! 199:
! 200: add.l #1,sigovfl ;for standalone testing
! 201:
! 202: link a6,#-LOCAL_SIZE
! 203: fsave -(sp)
! 204: bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
! 205: bne.b ovfl_done
! 206: bclr.b #E1,E_BYTE(a6)
! 207: ovfl_done:
! 208: frestore (sp)+
! 209: unlk a6
! 210: rte
! 211:
! 212: *
! 213: * Underflow exception
! 214: *
! 215: xref fpsp_unfl
! 216: xdef real_unfl
! 217: xdef unfl
! 218: unfl:
! 219: jmp fpsp_unfl
! 220: real_unfl:
! 221:
! 222: add.l #1,sigunfl ;for standalone testing
! 223:
! 224: link a6,#-LOCAL_SIZE
! 225: fsave -(sp)
! 226: bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
! 227: bne.b unfl_done
! 228: bclr.b #E1,E_BYTE(a6)
! 229: unfl_done:
! 230: frestore (sp)+
! 231: unlk a6
! 232: rte
! 233:
! 234: *
! 235: * Signalling NAN exception
! 236: *
! 237: xref fpsp_snan
! 238: xdef real_snan
! 239: xdef snan
! 240: snan:
! 241: jmp fpsp_snan
! 242: real_snan:
! 243: link a6,#-LOCAL_SIZE
! 244: fsave -(sp)
! 245: bclr.b #E1,E_BYTE(a6) ;snan is always an E1 exception
! 246: frestore (sp)+
! 247: unlk a6
! 248:
! 249: add.l #1,sigsnan ;for standalone testing
! 250: rte
! 251:
! 252: *
! 253: * Operand Error exception
! 254: *
! 255: xref fpsp_operr
! 256: xdef real_operr
! 257: xdef operr
! 258: operr:
! 259: jmp fpsp_operr
! 260: real_operr:
! 261: link a6,#-LOCAL_SIZE
! 262: fsave -(sp)
! 263: bclr.b #E1,E_BYTE(a6) ;operr is always an E1 exception
! 264: frestore (sp)+
! 265: unlk a6
! 266:
! 267: add.l #1,sigoperr ;for standalone testing
! 268:
! 269: rte
! 270:
! 271: *
! 272: * BSUN exception
! 273: *
! 274: * This sample handler simply clears the nan bit in the FPSR.
! 275: *
! 276: xref fpsp_bsun
! 277: xdef real_bsun
! 278: xdef bsun
! 279: bsun:
! 280: jmp fpsp_bsun
! 281: real_bsun:
! 282: link a6,#-LOCAL_SIZE
! 283: fsave -(sp)
! 284: bclr.b #E1,E_BYTE(a6) ;bsun is always an E1 exception
! 285: fmove.l FPSR,-(sp)
! 286: bclr.b #nan_bit,(sp)
! 287: fmove.l (sp)+,FPSR
! 288: frestore (sp)+
! 289: unlk a6
! 290:
! 291: add.l #1,sigbsun ;for standalone testing
! 292:
! 293: rte
! 294:
! 295: *
! 296: * F-line exception
! 297: *
! 298: * A 'real' F-line exception is one that the FPSP isn't supposed to
! 299: * handle. E.g. an instruction with a co-processor ID that is not 1.
! 300: *
! 301: *
! 302: xref fpsp_fline
! 303: xdef real_fline
! 304: xdef fline
! 305: fline:
! 306: jmp fpsp_fline
! 307: real_fline:
! 308:
! 309: add.l #1,sigunimp ;for standalone testing
! 310:
! 311: rte
! 312:
! 313: *
! 314: * Unsupported data type exception
! 315: *
! 316: xref fpsp_unsupp
! 317: xdef real_unsupp
! 318: xdef unsupp
! 319: unsupp:
! 320: jmp fpsp_unsupp
! 321: real_unsupp:
! 322: link a6,#-LOCAL_SIZE
! 323: fsave -(sp)
! 324: bclr.b #E1,E_BYTE(a6) ;unsupp is always an E1 exception
! 325: frestore (sp)+
! 326: unlk a6
! 327:
! 328: add.l #1,sigunsupp ;for standalone testing
! 329:
! 330: rte
! 331:
! 332: *
! 333: * Trace exception
! 334: *
! 335: xdef real_trace
! 336: real_trace:
! 337: rte
! 338:
! 339: *
! 340: * fpsp_fmt_error --- exit point for frame format error
! 341: *
! 342: * The fpu stack frame does not match the frames existing
! 343: * or planned at the time of this writing. The fpsp is
! 344: * unable to handle frame sizes not in the following
! 345: * version:size pairs:
! 346: *
! 347: * {4060, 4160} - busy frame
! 348: * {4028, 4130} - unimp frame
! 349: * {4000, 4100} - idle frame
! 350: *
! 351: * This entry point simply holds an f-line illegal value.
! 352: * Replace this with a call to your kernel panic code or
! 353: * code to handle future revisions of the fpu.
! 354: *
! 355: xdef fpsp_fmt_error
! 356: fpsp_fmt_error:
! 357:
! 358: dc.l $f27f0000 ;f-line illegal
! 359:
! 360: *
! 361: * fpsp_done --- FPSP exit point
! 362: *
! 363: * The exception has been handled by the package and we are ready
! 364: * to return to user mode, but there may be OS specific code
! 365: * to execute before we do. If there is, do it now.
! 366: *
! 367: *
! 368: xdef fpsp_done
! 369: fpsp_done:
! 370: rte
! 371:
! 372: *
! 373: * mem_write --- write to user or supervisor address space
! 374: *
! 375: * Writes to memory while in supervisor mode. copyout accomplishes
! 376: * this via a 'moves' instruction. copyout is a UNIX SVR3 (and later) function.
! 377: * If you don't have copyout, use the local copy of the function below.
! 378: *
! 379: * a0 - supervisor source address
! 380: * a1 - user destination address
! 381: * d0 - number of bytes to write (maximum count is 12)
! 382: *
! 383: * The supervisor source address is guaranteed to point into the supervisor
! 384: * stack. The result is that a UNIX
! 385: * process is allowed to sleep as a consequence of a page fault during
! 386: * copyout. The probability of a page fault is exceedingly small because
! 387: * the 68040 always reads the destination address and thus the page
! 388: * faults should have already been handled.
! 389: *
! 390: * If the EXC_SR shows that the exception was from supervisor space,
! 391: * then just do a dumb (and slow) memory move. In a UNIX environment
! 392: * there shouldn't be any supervisor mode floating point exceptions.
! 393: *
! 394: xdef mem_write
! 395: mem_write:
! 396: btst.b #5,EXC_SR(a6) ;check for supervisor state
! 397: beq.b user_write
! 398: super_write:
! 399: move.b (a0)+,(a1)+
! 400: subq.l #1,d0
! 401: bne.b super_write
! 402: rts
! 403: user_write:
! 404: move.l d1,-(sp) ;preserve d1 just in case
! 405: move.l d0,-(sp)
! 406: move.l a1,-(sp)
! 407: move.l a0,-(sp)
! 408: jsr copyout
! 409: add.l #12,sp
! 410: move.l (sp)+,d1
! 411: rts
! 412: *
! 413: * mem_read --- read from user or supervisor address space
! 414: *
! 415: * Reads from memory while in supervisor mode. copyin accomplishes
! 416: * this via a 'moves' instruction. copyin is a UNIX SVR3 (and later) function.
! 417: * If you don't have copyin, use the local copy of the function below.
! 418: *
! 419: * The FPSP calls mem_read to read the original F-line instruction in order
! 420: * to extract the data register number when the 'Dn' addressing mode is
! 421: * used.
! 422: *
! 423: *Input:
! 424: * a0 - user source address
! 425: * a1 - supervisor destination address
! 426: * d0 - number of bytes to read (maximum count is 12)
! 427: *
! 428: * Like mem_write, mem_read always reads with a supervisor
! 429: * destination address on the supervisor stack. Also like mem_write,
! 430: * the EXC_SR is checked and a simple memory copy is done if reading
! 431: * from supervisor space is indicated.
! 432: *
! 433: xdef mem_read
! 434: mem_read:
! 435: btst.b #5,EXC_SR(a6) ;check for supervisor state
! 436: beq.b user_read
! 437: super_read:
! 438: move.b (a0)+,(a1)+
! 439: subq.l #1,d0
! 440: bne.b super_read
! 441: rts
! 442: user_read:
! 443: move.l d1,-(sp) ;preserve d1 just in case
! 444: move.l d0,-(sp)
! 445: move.l a1,-(sp)
! 446: move.l a0,-(sp)
! 447: jsr copyin
! 448: add.l #12,sp
! 449: move.l (sp)+,d1
! 450: rts
! 451:
! 452: *
! 453: * Use these routines if your kernel doesn't have copyout/copyin equivalents.
! 454: * Assumes that D0/D1/A0/A1 are scratch registers. copyout overwrites DFC,
! 455: * and copyin overwrites SFC.
! 456: *
! 457: copyout:
! 458: move.l 4(sp),a0 ; source
! 459: move.l 8(sp),a1 ; destination
! 460: move.l 12(sp),d0 ; count
! 461: sub.l #1,d0 ; dec count by 1 for dbra
! 462: move.l #1,d1
! 463: movec d1,DFC ; set dfc for user data space
! 464: moreout:
! 465: move.b (a0)+,d1 ; fetch supervisor byte
! 466: moves.b d1,(a1)+ ; write user byte
! 467: dbf.w d0,moreout
! 468: rts
! 469:
! 470: copyin:
! 471: move.l 4(sp),a0 ; source
! 472: move.l 8(sp),a1 ; destination
! 473: move.l 12(sp),d0 ; count
! 474: sub.l #1,d0 ; dec count by 1 for dbra
! 475: move.l #1,d1
! 476: movec d1,SFC ; set sfc for user space
! 477: morein:
! 478: moves.b (a0)+,d1 ; fetch user byte
! 479: move.b d1,(a1)+ ; write supervisor byte
! 480: dbf.w d0,morein
! 481: rts
! 482:
! 483: end
CVSweb