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