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