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