1 | 2 | skeleton.sa 3.2 4/26/91 3 | 4 | This file contains code that is system 5 | need to be modified to install the FPS 6 | 7 | Each entry point for exception 'xxxx' 8 | Put any target system specific handlin 9 | before the jump instruction. If there 10 | the 'fpsp_xxxx' handler entry point sh 11 | table so that the 'jmp' can be elimina 12 | exception is one that must be reported 13 | return from the package by a 'jmp real 14 | the machine state will be identical to 15 | the FPSP was entered. In particular, 16 | that caused the exception will still b 17 | package returns. Thus, there will be 18 | to handle the exception. 19 | 20 | If the exception was completely handle 21 | the return will be via a 'jmp fpsp_don 22 | OS specific work to be done (such as h 23 | interrupt) the user program can be res 24 | 25 | In the following skeleton code, some t 26 | code is shown. This code may need to 27 | place in the target system, or rewritt 28 | 29 30 | Copyright (C) Motorola, Inc. 1 31 | All Rights Reserved 32 | 33 | For details on the license for this fi 34 | file, README, in this same directory. 35 36 | 37 | Modified for Linux-1.3.x by Jes Sorens 38 | 39 40 #include <linux/linkage.h> 41 #include <asm/entry.h> 42 #include <asm/asm-offsets.h> 43 44 |SKELETON idnt 2,1 | Motorola 040 Flo 45 46 |section 15 47 | 48 | The following counters are used for st 49 | 50 51 |section 8 52 53 #include "fpsp.h" 54 55 |xref b1238_fix 56 57 | 58 | Divide by Zero exception 59 | 60 | All dz exceptions are 'real', hence no 61 | 62 .global dz 63 .global real_dz 64 dz: 65 real_dz: 66 link %a6,#-LOCAL_SIZE 67 fsave -(%sp) 68 bclrb #E1,E_BYTE(%a6) 69 frestore (%sp)+ 70 unlk %a6 71 72 SAVE_ALL_INT 73 GET_CURRENT(%d0) 74 movel %sp,%sp@- | stac 75 bsrl trap_c 76 addql #4,%sp 77 bral ret_from_exception 78 79 | 80 | Inexact exception 81 | 82 | All inexact exceptions are real, but t 83 | will probably want to clear the pendin 84 | The provided code will clear the E3 ex 85 | otherwise clear the E1 exception. The 86 | necessary for E1 exceptions. 87 | 88 | Code following the 'inex' label is to handle 89 | bug, if an E1 snan, ovfl, or unfl occurred, 90 | swapped out before taking the exception, the 91 | return was inex, rather than the correct exc 92 | and unfl exception to be taken must not have 93 | fix is to check for E1, and the existence of 94 | or unfl bits set in the fpsr. If any of the 95 | to the appropriate handler for the exceptio 96 | that this fix is only for d43b parts, and is 97 | version number is not $40. 98 | 99 | 100 .global real_inex 101 .global inex 102 inex: 103 link %a6,#-LOCAL_SIZE 104 fsave -(%sp) 105 cmpib #VER_40,(%sp) 106 bnes not_fmt40 107 fmovel %fpsr,-(%sp) 108 btstb #E1,E_BYTE(%a6) 109 beqs not_b1232 110 btstb #snan_bit,2(%sp) |test 111 beq inex_ckofl 112 addl #4,%sp 113 frestore (%sp)+ 114 unlk %a6 115 bra snan 116 inex_ckofl: 117 btstb #ovfl_bit,2(%sp) |test 118 beq inex_ckufl 119 addl #4,%sp 120 frestore (%sp)+ 121 unlk %a6 122 bra ovfl 123 inex_ckufl: 124 btstb #unfl_bit,2(%sp) |test 125 beq not_b1232 126 addl #4,%sp 127 frestore (%sp)+ 128 unlk %a6 129 bra unfl 130 131 | 132 | We do not have the bug 1232 case. Clean up 133 | real_inex. 134 | 135 not_b1232: 136 addl #4,%sp 137 frestore (%sp)+ 138 unlk %a6 139 140 real_inex: 141 142 link %a6,#-LOCAL_SIZE 143 fsave -(%sp) 144 not_fmt40: 145 bclrb #E3,E_BYTE(%a6) 146 beqs inex_cke1 147 | 148 | Clear dirty bit on dest resister in the fram 149 | to b1238_fix. 150 | 151 moveml %d0/%d1,USER_DA(%a6) 152 bfextu CMDREG1B(%a6){#6:#3},% 153 bclrb %d0,FPR_DIRTY_BITS(%a6 154 bsrl b1238_fix 155 moveml USER_DA(%a6),%d0/%d1 156 bras inex_done 157 inex_cke1: 158 bclrb #E1,E_BYTE(%a6) 159 inex_done: 160 frestore (%sp)+ 161 unlk %a6 162 163 SAVE_ALL_INT 164 GET_CURRENT(%d0) 165 movel %sp,%sp@- | stac 166 bsrl trap_c 167 addql #4,%sp 168 bral ret_from_exception 169 170 | 171 | Overflow exception 172 | 173 |xref fpsp_ovfl 174 .global real_ovfl 175 .global ovfl 176 ovfl: 177 jmp fpsp_ovfl 178 real_ovfl: 179 180 link %a6,#-LOCAL_SIZE 181 fsave -(%sp) 182 bclrb #E3,E_BYTE(%a6) 183 bnes ovfl_done 184 bclrb #E1,E_BYTE(%a6) 185 ovfl_done: 186 frestore (%sp)+ 187 unlk %a6 188 189 SAVE_ALL_INT 190 GET_CURRENT(%d0) 191 movel %sp,%sp@- | stac 192 bsrl trap_c 193 addql #4,%sp 194 bral ret_from_exception 195 196 | 197 | Underflow exception 198 | 199 |xref fpsp_unfl 200 .global real_unfl 201 .global unfl 202 unfl: 203 jmp fpsp_unfl 204 real_unfl: 205 206 link %a6,#-LOCAL_SIZE 207 fsave -(%sp) 208 bclrb #E3,E_BYTE(%a6) 209 bnes unfl_done 210 bclrb #E1,E_BYTE(%a6) 211 unfl_done: 212 frestore (%sp)+ 213 unlk %a6 214 215 SAVE_ALL_INT 216 GET_CURRENT(%d0) 217 movel %sp,%sp@- | stac 218 bsrl trap_c 219 addql #4,%sp 220 bral ret_from_exception 221 222 | 223 | Signalling NAN exception 224 | 225 |xref fpsp_snan 226 .global real_snan 227 .global snan 228 snan: 229 jmp fpsp_snan 230 real_snan: 231 link %a6,#-LOCAL_SIZE 232 fsave -(%sp) 233 bclrb #E1,E_BYTE(%a6) |snan 234 frestore (%sp)+ 235 unlk %a6 236 237 SAVE_ALL_INT 238 GET_CURRENT(%d0) 239 movel %sp,%sp@- | stac 240 bsrl trap_c 241 addql #4,%sp 242 bral ret_from_exception 243 244 | 245 | Operand Error exception 246 | 247 |xref fpsp_operr 248 .global real_operr 249 .global operr 250 operr: 251 jmp fpsp_operr 252 real_operr: 253 link %a6,#-LOCAL_SIZE 254 fsave -(%sp) 255 bclrb #E1,E_BYTE(%a6) |operr 256 frestore (%sp)+ 257 unlk %a6 258 259 SAVE_ALL_INT 260 GET_CURRENT(%d0) 261 movel %sp,%sp@- | stac 262 bsrl trap_c 263 addql #4,%sp 264 bral ret_from_exception 265 266 267 | 268 | BSUN exception 269 | 270 | This sample handler simply clears the 271 | 272 |xref fpsp_bsun 273 .global real_bsun 274 .global bsun 275 bsun: 276 jmp fpsp_bsun 277 real_bsun: 278 link %a6,#-LOCAL_SIZE 279 fsave -(%sp) 280 bclrb #E1,E_BYTE(%a6) |bsun 281 fmovel %FPSR,-(%sp) 282 bclrb #nan_bit,(%sp) 283 fmovel (%sp)+,%FPSR 284 frestore (%sp)+ 285 unlk %a6 286 287 SAVE_ALL_INT 288 GET_CURRENT(%d0) 289 movel %sp,%sp@- | stac 290 bsrl trap_c 291 addql #4,%sp 292 bral ret_from_exception 293 294 | 295 | F-line exception 296 | 297 | A 'real' F-line exception is one that 298 | handle. E.g. an instruction with a co- 299 | 300 | 301 |xref fpsp_fline 302 .global real_fline 303 .global fline 304 fline: 305 jmp fpsp_fline 306 real_fline: 307 308 SAVE_ALL_INT 309 GET_CURRENT(%d0) 310 movel %sp,%sp@- | stac 311 bsrl trap_c 312 addql #4,%sp 313 bral ret_from_exception 314 315 | 316 | Unsupported data type exception 317 | 318 |xref fpsp_unsupp 319 .global real_unsupp 320 .global unsupp 321 unsupp: 322 jmp fpsp_unsupp 323 real_unsupp: 324 link %a6,#-LOCAL_SIZE 325 fsave -(%sp) 326 bclrb #E1,E_BYTE(%a6) |unsup 327 frestore (%sp)+ 328 unlk %a6 329 330 SAVE_ALL_INT 331 GET_CURRENT(%d0) 332 movel %sp,%sp@- | stac 333 bsrl trap_c 334 addql #4,%sp 335 bral ret_from_exception 336 337 | 338 | Trace exception 339 | 340 .global real_trace 341 real_trace: 342 | 343 bral trap 344 345 | 346 | fpsp_fmt_error --- exit point for fram 347 | 348 | The fpu stack frame does not match the 349 | or planned at the time of this writing 350 | unable to handle frame sizes not in th 351 | version:size pairs: 352 | 353 | {4060, 4160} - busy frame 354 | {4028, 4130} - unimp frame 355 | {4000, 4100} - idle frame 356 | 357 | This entry point simply holds an f-lin 358 | Replace this with a call to your kerne 359 | code to handle future revisions of the 360 | 361 .global fpsp_fmt_error 362 fpsp_fmt_error: 363 364 .long 0xf27f0000 |f-line illega 365 366 | 367 | fpsp_done --- FPSP exit point 368 | 369 | The exception has been handled by the 370 | to return to user mode, but there may 371 | to execute before we do. If there is, 372 | 373 | 374 375 .global fpsp_done 376 fpsp_done: 377 btst #0x5,%sp@ | supe 378 beq .Lnotkern 379 rte 380 .Lnotkern: 381 SAVE_ALL_INT 382 GET_CURRENT(%d0) 383 | deliver signals, reschedule etc.. 384 jra ret_from_exception 385 386 | 387 | mem_write --- write to user or supervi 388 | 389 | Writes to memory while in supervisor mode. 390 | this via a 'moves' instruction. copyout is 391 | If you don't have copyout, use the local cop 392 | 393 | a0 - supervisor source address 394 | a1 - user destination address 395 | d0 - number of bytes to write (maximum 396 | 397 | The supervisor source address is guaranteed 398 | stack. The result is that a UNIX 399 | process is allowed to sleep as a consequence 400 | copyout. The probability of a page fault is 401 | the 68040 always reads the destination addre 402 | faults should have already been handled. 403 | 404 | If the EXC_SR shows that the exception was f 405 | then just do a dumb (and slow) memory move. 406 | there shouldn't be any supervisor mode float 407 | 408 .global mem_write 409 mem_write: 410 btstb #5,EXC_SR(%a6) |check for sup 411 beqs user_write 412 super_write: 413 moveb (%a0)+,(%a1)+ 414 subql #1,%d0 415 bnes super_write 416 rts 417 user_write: 418 movel %d1,-(%sp) |preserve d1 j 419 movel %d0,-(%sp) 420 movel %a1,-(%sp) 421 movel %a0,-(%sp) 422 jsr copyout 423 addw #12,%sp 424 movel (%sp)+,%d1 425 rts 426 | 427 | mem_read --- read from user or supervi 428 | 429 | Reads from memory while in supervisor mode. 430 | this via a 'moves' instruction. copyin is a 431 | If you don't have copyin, use the local copy 432 | 433 | The FPSP calls mem_read to read the original 434 | to extract the data register number when the 435 | used. 436 | 437 |Input: 438 | a0 - user source address 439 | a1 - supervisor destination address 440 | d0 - number of bytes to read (maximum 441 | 442 | Like mem_write, mem_read always reads with a 443 | destination address on the supervisor stack. 444 | the EXC_SR is checked and a simple memory co 445 | from supervisor space is indicated. 446 | 447 .global mem_read 448 mem_read: 449 btstb #5,EXC_SR(%a6) |check for sup 450 beqs user_read 451 super_read: 452 moveb (%a0)+,(%a1)+ 453 subql #1,%d0 454 bnes super_read 455 rts 456 user_read: 457 movel %d1,-(%sp) |preserve d1 j 458 movel %d0,-(%sp) 459 movel %a1,-(%sp) 460 movel %a0,-(%sp) 461 jsr copyin 462 addw #12,%sp 463 movel (%sp)+,%d1 464 rts 465 466 | 467 | Use these routines if your kernel doesn't ha 468 | Assumes that D0/D1/A0/A1 are scratch registe 469 | and copyin overwrites SFC. 470 | 471 copyout: 472 movel 4(%sp),%a0 | source 473 movel 8(%sp),%a1 | destination 474 movel 12(%sp),%d0 | count 475 subl #1,%d0 | dec count by 476 movel #1,%d1 477 478 | DFC is already set 479 | movec %d1,%DFC | set 480 moreout: 481 moveb (%a0)+,%d1 | fetch superv 482 out_ea: 483 movesb %d1,(%a1)+ | write user b 484 dbf %d0,moreout 485 rts 486 487 copyin: 488 movel 4(%sp),%a0 | source 489 movel 8(%sp),%a1 | destination 490 movel 12(%sp),%d0 | count 491 subl #1,%d0 | dec count by 492 movel #1,%d1 493 | SFC is already set 494 | movec %d1,%SFC | set 495 morein: 496 in_ea: 497 movesb (%a0)+,%d1 | fetch user b 498 moveb %d1,(%a1)+ | write superv 499 dbf %d0,morein 500 rts 501 502 .section .fixup,"ax" 503 .even 504 1: 505 jbsr fpsp040_die 506 jbra .Lnotkern 507 508 .section __ex_table,"a" 509 .align 4 510 511 .long in_ea,1b 512 .long out_ea,1b 513 514 |end
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.