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