source: trunk/libs/newlib/src/libgloss/m68k/mvme135-asm.S @ 546

Last change on this file since 546 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 14.5 KB
RevLine 
[444]1/*
2 * mvme135-asm.S -- assembler routines for the MVME stub.
3 *
4 * This code was pulled out of mvme135-stub.c by Ian Taylor so that I
5 * could handle different register and label prefixes in a sensible
6 * way.
7 */
8
9/****************************************************************************
10
11                THIS SOFTWARE IS NOT COPYRIGHTED 
12   
13   HP offers the following for use in the public domain.  HP makes no
14   warranty with regard to the software or it's performance and the
15   user accepts the software "AS IS" with all faults.
16
17   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
18   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20
21****************************************************************************/
22
23#include "asm.h"
24
25        .title "mvme135-asm.S for m68k"
26
27        .globl SYM (registers)
28        .globl SYM (lastFrame)
29        .globl SYM (superStack)
30        .globl SYM (exceptionHook)
31        .globl SYM (_returnFromException)
32        .globl SYM (stackPtr)
33        .globl SYM (handle_exception)
34        .globl SYM (exceptionSize)
35        .globl SYM (exceptionHandler)
36
37.text
38
39
40/*
41 * Create a new exception vector table and populates it. Vectors from the
42 * boot monitor are spliced in so I/O and the abort button will continue
43 * to work. We also use the monitor's generalized vector for anything the
44 * debugger doesn't want.
45 */
46        .global SYM (setup_vectors)
47SYM (setup_vectors):
48        link    fp, IMM (-8)
49        /* copy monitor vector table */
50
51        movecl  vbr, a0
52        lea     SYM (vbr_table), a1
53        movel   0x8(a0), d0             /* get generalized vector */
54        movew   IMM (0x3fc), d1         /* load vector count */
55
56loop:                                   /* fill table to gen. vector */
57        movel   d0, (a1,d1)
58        subqw   IMM (4), d1
59        bne     loop
60
61        movel   0x10(a0), 0x10(a1) /* breakpoint */
62        movel   0x24(a0), 0x24(a1) /* trace */
63        movel   0xbc(a0), 0xbc(a1) /* system call */
64
65        /* add stub vectors to table */
66        movel   SYM (_catchException), 0x8(a1)  /* vector = 2,  Access Fault */
67        movel   SYM (_catchException), 0xc(a1)  /* vector = 3,  Address Error */
68        movel   SYM (_catchException), 0x10(a1) /* vector = 4,  Illegal instruction */
69        movel   SYM (_catchException), 0x14(a1) /* vector = 5,  divide by 0 */
70        movel   SYM (_catchException), 0x18(a1) /* vector = 6,  chk, chk2 instruction */
71        movel   SYM (_catchException), 0x1c(a1) /* vector = 7,  ftrap, trap, trapv ins */
72        movel   SYM (_catchException), 0x20(a1) /* vector = 8,  priviledge violation */
73        movel   SYM (_catchException), 0x24(a1) /* vector = 9,  trace */
74        movel   SYM (_catchException), 0x28(a1) /* vector = 10, Aline opcode */
75        movel   SYM (_catchException), 0x2c(a1) /* vector = 11, fline opcode */
76        movel   SYM (_catchException), 0x30(a1) /* vector = 12, reserved */
77        movel   SYM (_catchException), 0x34(a1) /* vector = 13, coprocessor protocol violation */
78        movel   SYM (_catchException), 0x38(a1) /* vector = 14, format error */
79        movel   SYM (_catchException), 0x3c(a1) /* vector = 15, unitialized interupt */
80       
81        /* unassigned, reserved */
82        movel   SYM (_catchException), 0x40(a1) /* vector = 16 */
83        movel   SYM (_catchException), 0x44(a1) /* vector = 17 */
84        movel   SYM (_catchException), 0x48(a1) /* vector = 18 */
85        movel   SYM (_catchException), 0x4c(a1) /* vector = 19 */
86        movel   SYM (_catchException), 0x50(a1) /* vector = 20 */
87        movel   SYM (_catchException), 0x54(a1) /* vector = 21 */
88        movel   SYM (_catchException), 0x58(a1) /* vector = 22 */
89        movel   SYM (_catchException), 0x5c(a1) /* vector = 23 */
90
91        movel   SYM (_catchException), 0x84(a1) /* vector = 33, breakpoint, trap #1 */
92        movel   SYM (_catchException), 0xa0(a1) /* vector = 40 , trap #8*/
93
94        /* floating point traps */
95        movel   SYM (_catchException), 0xc0(a1) /* vector = 48 */
96        movel   SYM (_catchException), 0xc4(a1) /* vector = 49 */
97        movel   SYM (_catchException), 0xc8(a1) /* vector = 50 */
98        movel   SYM (_catchException), 0xcc(a1) /* vector = 51 */
99        movel   SYM (_catchException), 0xd0(a1) /* vector = 52 */
100        movel   SYM (_catchException), 0xd4(a1) /* vector = 53 */
101        movel   SYM (_catchException), 0xd8(a1) /* vector = 54 */
102        movel   SYM (_catchException), 0xdc(a1) /* vector = 55 */
103        movel   SYM (_catchException), 0xe0(a1) /* vector = 56 */
104        movel   SYM (_catchException), 0xe4(a1) /* vector = 57 */
105        movel   SYM (_catchException), 0xe8(a1) /* vector = 58 */
106
107/***        movel   &__debug_level7, 0x7c(a1) /* level7 interupt vector */
108
109        movecl  a1, vbr         /* change VBR to new table */       
110        unlk    fp
111        rts
112/*
113 * exceptionHandler -- sets up exception vector table.
114 *                     First arg is an integer vector number
115 *                     Second arg is the function pointer for the vector
116 */
117SYM (exceptionHandler):
118#       link    a6, IMM (-8)
119#str1:  .ascii  "Exception Handler Called\n"
120#       moveal  IMM (str1), a0
121#       moveal  IMM (str1+25), a1
122#       jsr     SYM (outln)
123
124#       unlk    a6
125        rts
126
127/* this never gets called */
128        movel   fp@(8), d0              /* get vector number */
129        movel   fp@(12), a0             /* get function address */
130        moveal  &SYM (vbr_table), a1    /* FIXME */
131
132        addl    d0, d0
133        addl    d0, d0
134
135        addal   d0, a1
136        movel   a0, (a1)
137
138        movecl  a1, vbr
139        unlk    a6
140        rts
141
142.globl SYM (return_to_super)
143SYM (return_to_super):
144        movel   SYM (registers)+60,sp /* get new stack pointer */
145        movel   SYM (lastFrame),a0    /* get last frame info  */
146        bra     return_to_any
147
148.globl SYM (return_to_user)
149SYM (return_to_user):
150        movel   SYM (registers)+60,a0   /* get usp */
151        movel   a0,usp           /* set usp */
152        movel   SYM (superStack),sp    /* get original stack pointer */
153
154return_to_any:
155        movel   SYM (lastFrame),a0     /* get last frame info  */
156        movel   a0@+,SYM (lastFrame)   /* link in previous frame     */
157        addql   IMM (8),a0            /* skip over pc, vector#*/             
158        movew   a0@+,d0         /* get # of words in cpu frame */       
159        addw    d0,a0           /* point to end of data        */       
160        addw    d0,a0           /* point to end of data        */       
161        movel   a0,a1
162/* copy the stack frame */
163        subql   IMM (1),d0
164copyUserLoop:                                                               
165        movew   a1@-,sp@-                                               
166        dbf     d0,copyUserLoop                                             
167
168#ifdef __HAVE_68881__
169        fmoveml  SYM (registers)+168,fpcr/fpsr/fpi
170        fmovemx  SYM (registers)+72,fp0-fp7
171        cmpl     IMM (-1),a0@     /* skip frestore flag set ? */
172        beq      skip_frestore
173        frestore a0@+
174skip_frestore:
175#endif
176
177        moveml  SYM (registers),d0-d7/a0-a6
178        rte  /* pop and go! */
179
180
181/* this function is called immediately when a level 7 interrupt occurs */
182/* if the previous interrupt level was 7 then we're already servicing  */
183/* this interrupt and an rte is in order to return to the debugger.    */
184/* For the 68000, the offset for sr is 6 due to the jsr return address */
185.text
186.globl SYM (_debug_level7)
187SYM (_debug_level7):
188        movew   d0,sp@-
189#ifdef mc68020
190        movew   sp@(2),d0
191#else
192        movew   sp@(6),d0
193#endif
194        andiw   IMM (0x700),d0
195        cmpiw   IMM (0x700),d0
196        beq     _already7
197        movew   sp@+,d0
198        bra     SYM (_catchException)
199_already7:
200        movew   sp@+,d0
201#ifndef mc68020
202        lea     sp@(4),sp     /* pull off 68000 return address */
203#endif
204        rte
205
206#ifdef mc68020
207/* This function is called when a 68020 exception occurs.  It saves
208 * all the cpu and fpcp regs in the _registers array, creates a frame on a
209 * linked list of frames which has the cpu and fpcp stack frames needed
210 * to properly restore the context of these processors, and invokes
211 * an exception handler (remcom_handler).
212 *
213 * stack on entry:                       stack on exit:
214 *   N bytes of junk                     exception # MSWord
215 *   Exception Format Word               exception # MSWord
216 *   Program counter LSWord             
217 *   Program counter MSWord             
218 *   Status Register                   
219 *                                       
220 *                                       
221 */
222
223.text
224.globl SYM (_catchException)
225SYM (_catchException):
226
227        oriw   IMM (0x0700),sr  /* Disable interrupts */
228
229        moveml  d0-d7/a0-a6,SYM (registers) /* save registers        */
230        movel   SYM (lastFrame),a0      /* last frame pointer */
231
232#ifdef __HAVE_68881__
233        /* do an fsave, then remember the address to begin a restore from */
234        fsave   a0@-
235        fmovemx fp0-fp7, SYM (registers)+72
236        fmoveml fpcr/fpsr/fpi, SYM (registers)+168
237#endif
238
239        lea     SYM (registers),a5    /* get address of registers     */
240        movew   sp@,d1          /* get status register          */
241        movew   d1,a5@(66)      /* save sr                      */     
242        movel   sp@(2),a4       /* save pc in a4 for later use  */
243        movel   a4,a5@(68)      /* save pc in _regisers[]       */
244
245/* figure out how many bytes in the stack frame */
246        movew   sp@(6),d0       /* get '020 exception format    */
247        movew   d0,d2           /* make a copy of format word   */
248        andiw   IMM (0xf000),d0 /* mask off format type         */
249        rolw    IMM (5),d0           /* rotate into the low byte *2  */
250        lea     SYM (exceptionSize),a1
251        addw    d0,a1          /* index into the table         */
252        movew   a1@,d0         /* get number of words in frame */
253        movew   d0,d3          /* save it                      */
254        subw    d0,a0          /* adjust save pointer          */
255        subw    d0,a0          /* adjust save pointer(bytes)   */
256        movel   a0,a1          /* copy save pointer            */
257        subql   IMM (1),d0     /* predecrement loop counter    */
258
259/* copy the frame */
260
261saveFrameLoop:
262        movew   sp@+,a1@+
263        dbf     d0,saveFrameLoop
264
265/* now that the stack has been clenaed,
266 * save the a7 in use at time of exception
267 */
268        movel   sp,SYM (superStack)  /* save supervisor sp           */
269        andiw   IMM (0x2000),d1      /* were we in supervisor mode ? */
270        beq     userMode       
271        movel   a7,a5@(60)      /* save a7                  */
272        bra     a7saveDone
273userMode: 
274        movel   usp,a1         
275        movel   a1,a5@(60)     /* save user stack pointer       */
276a7saveDone:
277
278
279/* save size of frame */
280        movew   d3,a0@-
281
282/* compute exception number */
283        andl    IMM (0xfff),d2          /* mask off vector offset       */
284        lsrw    IMM (2),d2      /* divide by 4 to get vect num  */
285        movel   d2,a0@-       /* save it                      */
286
287/* save pc causing exception */
288        movel   a4,a0@-
289
290/* save old frame link and set the new value*/
291        movel   SYM (lastFrame),a1      /* last frame pointer */
292        movel   a1,a0@-         /* save pointer to prev frame   */
293        movel   a0,SYM (lastFrame)
294
295        movel   d2,sp@-         /* push exception num           */
296#ifdef TMP_HACK
297        movel   SYM (exceptionHook),a0   /* get address of handler */
298        jbsr    a0@            /* and call it */
299#else
300        jbsr    SYM (remcomHandler)
301#endif
302        clrl    sp@             /* replace exception num parm with frame ptr */
303        jbsr    SYM (_returnFromException)    /* jbsr, but never returns */
304
305#else /* mc68000 */
306
307/* This function is called when an exception occurs.  It translates the
308 * return address found on the stack into an exception vector # which
309 * is then handled by either handle_exception or a system handler.
310 * _catchException provides a front end for both. 
311 *
312 * stack on entry:                       stack on exit:
313 *   Program counter MSWord              exception # MSWord
314 *   Program counter LSWord              exception # MSWord
315 *   Status Register                     
316 *   Return Address  MSWord             
317 *   Return Address  LSWord             
318 */
319.text
320.globl SYM (_catchException)
321SYM (_catchException):
322
323        oriw   IMM (0x0700),sr  /* Disable interrupts */
324
325        moveml d0-d7/a0-a6,SYM (registers)  /* save registers               */
326        movel   SYM (lastFrame),a0      /* last frame pointer */
327
328#ifdef __HAVE_68881__
329        /* do an fsave, then remember the address to begin a restore from */
330        fsave   a0@-
331        fmovemx fp0-fp7, SYM (registers)+72
332        fmoveml fpcr/fpsr/fpi, SYM (registers)+168
333#endif
334
335        lea     SYM (registers),a5    /* get address of registers     */
336        movel   sp@+,d2        /* pop return address           */
337        addl    IMM (1530),d2  /* convert return addr to        */
338        divs    IMM (6),d2     /*  exception number             */
339        extl    d2   
340
341        moveql  IMM (3),d3     /* assume a three word frame     */
342
343        cmpiw   IMM (3),d2     /* bus error or address error ? */
344        bgt     normal         /* if >3 then normal error      */
345        movel   sp@+,a0@-      /* copy error info to frame buff*/
346        movel   sp@+,a0@-      /* these are never used         */
347        moveql  IMM (7),d3     /* this is a 7 word frame       */
348     
349normal:   
350        movew   sp@+,d1        /* pop status register          */
351        movel   sp@+,a4        /* pop program counter          */
352        movew   d1,a5@(66)     /* save sr                       */     
353        movel   a4,a5@(68)     /* save pc in _regisers[]        */
354        movel   a4,a0@-        /* copy pc to frame buffer      */
355        movew   d1,a0@-        /* copy sr to frame buffer      */
356
357        movel   sp,SYM (superStack)   /* save supervisor sp          */
358
359        andiw   IMM (0x2000),d1      /* were we in supervisor mode ? */
360        beq     userMode       
361        movel   a7,a5@(60)      /* save a7                  */
362        bra     saveDone             
363userMode:
364        movel   usp,a1           /* save user stack pointer     */
365        movel   a1,a5@(60)     /* save user stack pointer       */
366saveDone:
367
368        movew   d3,a0@-        /* push frame size in words     */
369        movel   d2,a0@-        /* push vector number           */
370        movel   a4,a0@-        /* push exception pc            */
371
372/* save old frame link and set the new value */
373        movel   SYM (lastFrame),a1       /* last frame pointer */
374        movel   a1,a0@-  /* save pointer to prev frame  */
375        movel   a0,SYM (lastFrame)
376
377        movel   d2,sp@-         /* push exception num           */
378        movel   SYM (exceptionHook),a0   /* get address of handler */
379        jbsr    a0@             /* and call it */
380        clrl    sp@             /* replace exception num parm with frame ptr */
381        jbsr     SYM (_returnFromException)   /* jbsr, but never returns */
382
383#endif /* m68000 */
384
385/*
386 * remcomHandler is a front end for handle_exception.  It moves the
387 * stack pointer into an area reserved for debugger use in case the
388 * breakpoint happened in supervisor mode.
389 */
390.globl SYM (remcomHandler)
391SYM (remcomHandler):
392        addl    IMM (4),sp      /* pop off return address     */
393        movel   sp@+,d0         /* get the exception number   */
394        movel   SYM (stackPtr),sp       /* move to remcom stack area  */
395        movel   d0,sp@-         /* push exception onto stack  */
396        jbsr    SYM (handle_exception)  /* this never returns */
397        rts                     /* return */
Note: See TracBrowser for help on using the repository browser.