[BACK]Return to skeleton.sa CVS log [TXT][DIR] Up to [local] / sys / arch / m68k / fpsp

File: [local] / sys / arch / m68k / fpsp / skeleton.sa (download)

Revision 1.1, Tue Mar 4 16:07:07 2008 UTC (16 years, 2 months ago) by nbrk
Branch point for: MAIN

Initial revision

*	$OpenBSD: skeleton.sa,v 1.3 2001/09/20 17:02:30 mpech Exp $
*	$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 occurred, 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