diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /sys/arch/m68k/fpsp/skeleton.sa |
initial import of NetBSD tree
Diffstat (limited to 'sys/arch/m68k/fpsp/skeleton.sa')
-rw-r--r-- | sys/arch/m68k/fpsp/skeleton.sa | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/sys/arch/m68k/fpsp/skeleton.sa b/sys/arch/m68k/fpsp/skeleton.sa new file mode 100644 index 00000000000..4ed506d77c7 --- /dev/null +++ b/sys/arch/m68k/fpsp/skeleton.sa @@ -0,0 +1,482 @@ +* $NetBSD: skeleton.sa,v 1.3 1994/10/26 07:49:50 cgd Exp $ + +* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP +* M68000 Hi-Performance Microprocessor Division +* M68040 Software Package +* +* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. +* All rights reserved. +* +* THE SOFTWARE is provided on an "AS IS" basis and without warranty. +* To the maximum extent permitted by applicable law, +* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, +* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A +* PARTICULAR PURPOSE and any warranty against infringement with +* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) +* and any accompanying written materials. +* +* To the maximum extent permitted by applicable law, +* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER +* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS +* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR +* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE +* SOFTWARE. Motorola assumes no responsibility for the maintenance +* and support of the SOFTWARE. +* +* You are hereby granted a copyright license to use, modify, and +* distribute the SOFTWARE so long as this entire notice is retained +* without alteration in any modified and/or redistributed versions, +* and that such modified versions are clearly identified as such. +* No licenses are granted by implication, estoppel or otherwise +* under any patents or trademarks of Motorola, Inc. + +* +* skeleton.sa 3.2 4/26/91 +* +* This file contains code that is system dependent and will +* need to be modified to install the FPSP. +* +* Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'. +* Put any target system specific handling that must be done immediately +* before the jump instruction. If there no handling necessary, then +* the 'fpsp_xxxx' handler entry point should be placed in the exception +* table so that the 'jmp' can be eliminated. If the FPSP determines that the +* exception is one that must be reported then there will be a +* return from the package by a 'jmp real_xxxx'. At that point +* the machine state will be identical to the state before +* the FPSP was entered. In particular, whatever condition +* that caused the exception will still be pending when the FPSP +* package returns. Thus, there will be system specific code +* to handle the exception. +* +* If the exception was completely handled by the package, then +* the return will be via a 'jmp fpsp_done'. Unless there is +* OS specific work to be done (such as handling a context switch or +* interrupt) the user program can be resumed via 'rte'. +* +* In the following skeleton code, some typical 'real_xxxx' handling +* code is shown. This code may need to be moved to an appropriate +* place in the target system, or rewritten. +* + +SKELETON IDNT 2,1 Motorola 040 Floating Point Software Package + + section 15 +* +* The following counters are used for standalone testing +* +sigunimp dc.l 0 +sigbsun dc.l 0 +siginex dc.l 0 +sigdz dc.l 0 +sigunfl dc.l 0 +sigovfl dc.l 0 +sigoperr dc.l 0 +sigsnan dc.l 0 +sigunsupp dc.l 0 + + section 8 + + include fpsp.h + + xref b1238_fix + +* +* Divide by Zero exception +* +* All dz exceptions are 'real', hence no fpsp_dz entry point. +* + xdef dz + xdef real_dz +dz: +real_dz: + link a6,#-LOCAL_SIZE + fsave -(sp) + bclr.b #E1,E_BYTE(a6) + frestore (sp)+ + unlk a6 + + add.l #1,sigdz ;for standalone testing + + rte +* +* Inexact exception +* +* All inexact exceptions are real, but the 'real' handler +* will probably want to clear the pending exception. +* The provided code will clear the E3 exception (if pending), +* otherwise clear the E1 exception. The frestore is not really +* necessary for E1 exceptions. +* +* Code following the 'inex' label is to handle bug #1232. In this +* bug, if an E1 snan, ovfl, or unfl occured, and the process was +* swapped out before taking the exception, the exception taken on +* return was inex, rather than the correct exception. The snan, ovfl, +* and unfl exception to be taken must not have been enabled. The +* fix is to check for E1, and the existence of one of snan, ovfl, +* or unfl bits set in the fpsr. If any of these are set, branch +* to the appropriate handler for the exception in the fpsr. Note +* that this fix is only for d43b parts, and is skipped if the +* version number is not $40. +* +* + xdef real_inex + xdef inex +inex: + link a6,#-LOCAL_SIZE + fsave -(sp) + cmpi.b #VER_40,(sp) ;test version number + bne.b not_fmt40 + fmove.l fpsr,-(sp) + btst.b #E1,E_BYTE(a6) ;test for E1 set + beq.b not_b1232 + btst.b #snan_bit,2(sp) ;test for snan + beq inex_ckofl + add.l #4,sp + frestore (sp)+ + unlk a6 + bra snan +inex_ckofl: + btst.b #ovfl_bit,2(sp) ;test for ovfl + beq inex_ckufl + add.l #4,sp + frestore (sp)+ + unlk a6 + bra ovfl +inex_ckufl: + btst.b #unfl_bit,2(sp) ;test for unfl + beq not_b1232 + add.l #4,sp + frestore (sp)+ + unlk a6 + bra unfl + +* +* We do not have the bug 1232 case. Clean up the stack and call +* real_inex. +* +not_b1232: + add.l #4,sp + frestore (sp)+ + unlk a6 + +real_inex: + + add.l #1,siginex ;for standalone testing + + link a6,#-LOCAL_SIZE + fsave -(sp) +not_fmt40: + bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag + beq.b inex_cke1 +* +* Clear dirty bit on dest resister in the frame before branching +* to b1238_fix. +* + movem.l d0/d1,USER_DA(a6) + bfextu CMDREG1B(a6){6:3},d0 ;get dest reg no + bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit + bsr.l b1238_fix ;test for bug1238 case + movem.l USER_DA(a6),d0/d1 + bra.b inex_done +inex_cke1: + bclr.b #E1,E_BYTE(a6) +inex_done: + frestore (sp)+ + unlk a6 + rte + +* +* Overflow exception +* + xref fpsp_ovfl + xdef real_ovfl + xdef ovfl +ovfl: + jmp fpsp_ovfl +real_ovfl: + + add.l #1,sigovfl ;for standalone testing + + link a6,#-LOCAL_SIZE + fsave -(sp) + bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag + bne.b ovfl_done + bclr.b #E1,E_BYTE(a6) +ovfl_done: + frestore (sp)+ + unlk a6 + rte + +* +* Underflow exception +* + xref fpsp_unfl + xdef real_unfl + xdef unfl +unfl: + jmp fpsp_unfl +real_unfl: + + add.l #1,sigunfl ;for standalone testing + + link a6,#-LOCAL_SIZE + fsave -(sp) + bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag + bne.b unfl_done + bclr.b #E1,E_BYTE(a6) +unfl_done: + frestore (sp)+ + unlk a6 + rte + +* +* Signalling NAN exception +* + xref fpsp_snan + xdef real_snan + xdef snan +snan: + jmp fpsp_snan +real_snan: + link a6,#-LOCAL_SIZE + fsave -(sp) + bclr.b #E1,E_BYTE(a6) ;snan is always an E1 exception + frestore (sp)+ + unlk a6 + + add.l #1,sigsnan ;for standalone testing + rte + +* +* Operand Error exception +* + xref fpsp_operr + xdef real_operr + xdef operr +operr: + jmp fpsp_operr +real_operr: + link a6,#-LOCAL_SIZE + fsave -(sp) + bclr.b #E1,E_BYTE(a6) ;operr is always an E1 exception + frestore (sp)+ + unlk a6 + + add.l #1,sigoperr ;for standalone testing + + rte + +* +* BSUN exception +* +* This sample handler simply clears the nan bit in the FPSR. +* + xref fpsp_bsun + xdef real_bsun + xdef bsun +bsun: + jmp fpsp_bsun +real_bsun: + link a6,#-LOCAL_SIZE + fsave -(sp) + bclr.b #E1,E_BYTE(a6) ;bsun is always an E1 exception + fmove.l FPSR,-(sp) + bclr.b #nan_bit,(sp) + fmove.l (sp)+,FPSR + frestore (sp)+ + unlk a6 + + add.l #1,sigbsun ;for standalone testing + + rte + +* +* F-line exception +* +* A 'real' F-line exception is one that the FPSP isn't supposed to +* handle. E.g. an instruction with a co-processor ID that is not 1. +* +* + xref fpsp_fline + xdef real_fline + xdef fline +fline: + jmp fpsp_fline +real_fline: + + add.l #1,sigunimp ;for standalone testing + + rte + +* +* Unsupported data type exception +* + xref fpsp_unsupp + xdef real_unsupp + xdef unsupp +unsupp: + jmp fpsp_unsupp +real_unsupp: + link a6,#-LOCAL_SIZE + fsave -(sp) + bclr.b #E1,E_BYTE(a6) ;unsupp is always an E1 exception + frestore (sp)+ + unlk a6 + + add.l #1,sigunsupp ;for standalone testing + + rte + +* +* Trace exception +* + xdef real_trace +real_trace: + rte + +* +* fpsp_fmt_error --- exit point for frame format error +* +* The fpu stack frame does not match the frames existing +* or planned at the time of this writing. The fpsp is +* unable to handle frame sizes not in the following +* version:size pairs: +* +* {4060, 4160} - busy frame +* {4028, 4130} - unimp frame +* {4000, 4100} - idle frame +* +* This entry point simply holds an f-line illegal value. +* Replace this with a call to your kernel panic code or +* code to handle future revisions of the fpu. +* + xdef fpsp_fmt_error +fpsp_fmt_error: + + dc.l $f27f0000 ;f-line illegal + +* +* fpsp_done --- FPSP exit point +* +* The exception has been handled by the package and we are ready +* to return to user mode, but there may be OS specific code +* to execute before we do. If there is, do it now. +* +* + xdef fpsp_done +fpsp_done: + rte + +* +* mem_write --- write to user or supervisor address space +* +* Writes to memory while in supervisor mode. copyout accomplishes +* this via a 'moves' instruction. copyout is a UNIX SVR3 (and later) function. +* If you don't have copyout, use the local copy of the function below. +* +* a0 - supervisor source address +* a1 - user destination address +* d0 - number of bytes to write (maximum count is 12) +* +* The supervisor source address is guaranteed to point into the supervisor +* stack. The result is that a UNIX +* process is allowed to sleep as a consequence of a page fault during +* copyout. The probability of a page fault is exceedingly small because +* the 68040 always reads the destination address and thus the page +* faults should have already been handled. +* +* If the EXC_SR shows that the exception was from supervisor space, +* then just do a dumb (and slow) memory move. In a UNIX environment +* there shouldn't be any supervisor mode floating point exceptions. +* + xdef mem_write +mem_write: + btst.b #5,EXC_SR(a6) ;check for supervisor state + beq.b user_write +super_write: + move.b (a0)+,(a1)+ + subq.l #1,d0 + bne.b super_write + rts +user_write: + move.l d1,-(sp) ;preserve d1 just in case + move.l d0,-(sp) + move.l a1,-(sp) + move.l a0,-(sp) + jsr copyout + add.l #12,sp + move.l (sp)+,d1 + rts +* +* mem_read --- read from user or supervisor address space +* +* Reads from memory while in supervisor mode. copyin accomplishes +* this via a 'moves' instruction. copyin is a UNIX SVR3 (and later) function. +* If you don't have copyin, use the local copy of the function below. +* +* The FPSP calls mem_read to read the original F-line instruction in order +* to extract the data register number when the 'Dn' addressing mode is +* used. +* +*Input: +* a0 - user source address +* a1 - supervisor destination address +* d0 - number of bytes to read (maximum count is 12) +* +* Like mem_write, mem_read always reads with a supervisor +* destination address on the supervisor stack. Also like mem_write, +* the EXC_SR is checked and a simple memory copy is done if reading +* from supervisor space is indicated. +* + xdef mem_read +mem_read: + btst.b #5,EXC_SR(a6) ;check for supervisor state + beq.b user_read +super_read: + move.b (a0)+,(a1)+ + subq.l #1,d0 + bne.b super_read + rts +user_read: + move.l d1,-(sp) ;preserve d1 just in case + move.l d0,-(sp) + move.l a1,-(sp) + move.l a0,-(sp) + jsr copyin + add.l #12,sp + move.l (sp)+,d1 + rts + +* +* Use these routines if your kernel doesn't have copyout/copyin equivalents. +* Assumes that D0/D1/A0/A1 are scratch registers. copyout overwrites DFC, +* and copyin overwrites SFC. +* +copyout: + move.l 4(sp),a0 ; source + move.l 8(sp),a1 ; destination + move.l 12(sp),d0 ; count + sub.l #1,d0 ; dec count by 1 for dbra + move.l #1,d1 + movec d1,DFC ; set dfc for user data space +moreout: + move.b (a0)+,d1 ; fetch supervisor byte + moves.b d1,(a1)+ ; write user byte + dbf.w d0,moreout + rts + +copyin: + move.l 4(sp),a0 ; source + move.l 8(sp),a1 ; destination + move.l 12(sp),d0 ; count + sub.l #1,d0 ; dec count by 1 for dbra + move.l #1,d1 + movec d1,SFC ; set sfc for user space +morein: + moves.b (a0)+,d1 ; fetch user byte + move.b d1,(a1)+ ; write supervisor byte + dbf.w d0,morein + rts + + end |