summaryrefslogtreecommitdiff
path: root/sys/arch/m68k/fpsp/skeleton.sa
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /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.sa482
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