2 * mvme135-asm.S -- assembler routines for the MVME stub.
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
9 /****************************************************************************
11 THIS SOFTWARE IS NOT COPYRIGHTED
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.
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 ****************************************************************************/
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)
33 .globl SYM (handle_exception)
34 .globl SYM (exceptionSize)
35 .globl SYM (exceptionHandler)
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.
46 .global SYM (setup_vectors)
49 /* copy monitor vector table */
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 */
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 */
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 */
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
117 SYM (exceptionHandler):
119 #str1: .ascii "Exception Handler Called\n"
120 # moveal IMM (str1), a0
121 # moveal IMM (str1+25), a1
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 */
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 */
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 */
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 */
162 /* copy the stack frame */
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 ? */
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 */
186 .globl SYM (_debug_level7)
198 bra SYM (_catchException)
202 lea sp@(4),sp /* pull off 68000 return address */
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
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 */
235 fmovemx fp0-fp7, SYM (registers)+72
236 fmoveml fpcr/fpsr/fpi, SYM (registers)+168
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 */
265 /* now that the stack has been clenaed,
266 * save the a7 in use at time of exception
268 movel sp,SYM (superStack) /* save supervisor sp */
269 andiw IMM (0x2000),d1 /* were we in supervisor mode ? */
271 movel a7,a5@(60) /* save a7 */
275 movel a1,a5@(60) /* save user stack pointer */
279 /* save size of frame */
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 */
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 */
297 movel SYM (exceptionHook),a0 /* get address of handler */
298 jbsr a0@ /* and call it */
300 jbsr SYM (remcomHandler)
302 clrl sp@ /* replace exception num parm with frame ptr */
303 jbsr SYM (_returnFromException) /* jbsr, but never returns */
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
316 * Return Address MSWord
317 * Return Address LSWord
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 */
331 fmovemx fp0-fp7, SYM (registers)+72
332 fmoveml fpcr/fpsr/fpi, SYM (registers)+168
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 */
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 */
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 ? */
361 movel a7,a5@(60) /* save a7 */
364 movel usp,a1 /* save user stack pointer */
365 movel a1,a5@(60) /* save user stack pointer */
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 */
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.
390 .globl 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 */