Cygwin: dirent.h: fix a comment
[newlib-cygwin.git] / libgloss / m68k / mvme135-asm.S
blobea0a29826645eb377781a67fea8cc3c14fc109ae
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  */
9 /****************************************************************************
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 its performance and the
15    user accepts the software "AS IS" with all faults.
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.
21 ****************************************************************************/
23 #include "asm.h"
25         .title "mvme135-asm.S for m68k"
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)
37 .text
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)
47 SYM (setup_vectors):
48         link    fp, IMM (-8)
49         /* copy monitor vector table */
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 */
56 loop:                                   /* fill table to gen. vector */
57         movel   d0, (a1,d1)
58         subqw   IMM (4), d1
59         bne     loop
61         movel   0x10(a0), 0x10(a1) /* breakpoint */
62         movel   0x24(a0), 0x24(a1) /* trace */
63         movel   0xbc(a0), 0xbc(a1) /* system call */
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 */
91         movel   SYM (_catchException), 0x84(a1) /* vector = 33, breakpoint, trap #1 */
92         movel   SYM (_catchException), 0xa0(a1) /* vector = 40 , trap #8*/
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 */
107 /***        movel   &__debug_level7, 0x7c(a1) /* level7 interupt vector */
109         movecl  a1, vbr         /* change VBR to new table */        
110         unlk    fp
111         rts
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  */
117 SYM (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)
124 #       unlk    a6
125         rts
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 */
132         addl    d0, d0
133         addl    d0, d0
135         addal   d0, a1
136         movel   a0, (a1)
138         movecl  a1, vbr
139         unlk    a6
140         rts
142 .globl SYM (return_to_super)
143 SYM (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
148 .globl SYM (return_to_user)
149 SYM (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 */
154 return_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
164 copyUserLoop:                                                               
165         movew   a1@-,sp@-                                               
166         dbf     d0,copyUserLoop                                             
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@+
174 skip_frestore:
175 #endif
177         moveml  SYM (registers),d0-d7/a0-a6
178         rte  /* pop and go! */
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)
187 SYM (_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
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).
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  */
223 .text
224 .globl SYM (_catchException)
225 SYM (_catchException):
227         oriw   IMM (0x0700),sr  /* Disable interrupts */
229         moveml  d0-d7/a0-a6,SYM (registers) /* save registers        */
230         movel   SYM (lastFrame),a0      /* last frame pointer */
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
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[]       */
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    */
259 /* copy the frame */
261 saveFrameLoop:
262         movew   sp@+,a1@+
263         dbf     d0,saveFrameLoop
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
273 userMode:  
274         movel   usp,a1          
275         movel   a1,a5@(60)     /* save user stack pointer       */
276 a7saveDone:
279 /* save size of frame */
280         movew   d3,a0@-
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                      */
287 /* save pc causing exception */
288         movel   a4,a0@-
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)
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 */
305 #else /* mc68000 */
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.  
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)
321 SYM (_catchException):
323         oriw   IMM (0x0700),sr  /* Disable interrupts */
325         moveml d0-d7/a0-a6,SYM (registers)  /* save registers               */
326         movel   SYM (lastFrame),a0      /* last frame pointer */
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
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   
341         moveql  IMM (3),d3     /* assume a three word frame     */
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      
349 normal:   
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      */
357         movel   sp,SYM (superStack)   /* save supervisor sp          */
359         andiw   IMM (0x2000),d1      /* were we in supervisor mode ? */
360         beq     userMode       
361         movel   a7,a5@(60)      /* save a7                  */
362         bra     saveDone             
363 userMode:
364         movel   usp,a1           /* save user stack pointer     */
365         movel   a1,a5@(60)     /* save user stack pointer       */
366 saveDone:
368         movew   d3,a0@-        /* push frame size in words     */
369         movel   d2,a0@-        /* push vector number           */
370         movel   a4,a0@-        /* push exception pc            */
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)
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 */
383 #endif /* m68000 */
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)
391 SYM (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 */