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