arch/m68k-amiga: Helper routines for M68K exceptions
[AROS.git] / arch / m68k-amiga / boot / m68k_exception.c
blobddb3033667a525712be22322a6b81110bf5f0bf9
1 /*
2 copyright © 1995-2010, the aros development team. all rights reserved.
3 $id$
5 desc: m68k-amiga bootstrap to exec.
6 lang: english
7 */
9 #include <aros/kernel.h>
10 #include <exec/resident.h>
11 #include <exec/execbase.h>
12 #include <exec/memory.h>
14 #include "exec_intern.h"
16 #include "m68k_exception.h"
18 /* Here's how it's all laid out on the Amiga
19 * M68K Exception
20 * 0 Reset: Initial SP
21 * 1 Reset: Initial PC (NOTE: Really is SysBase!)
22 * 2 Bus Error
23 * 3 Address Error
24 * 4 Illegal Instruction
25 * 5 Divide by Zero
26 * 6 CHK Instruction
27 * 7 TRAPV Instruction
28 * 8 Privileged Instruction
29 * 9 Trace
30 * 10 Line 1010 Emulator
31 * 11 Line 1111 Emulator
32 * 12 -
33 * 13 -
34 * 14 Format Error
35 * 15 Uninitilaized Interrupt Vector
36 * 16 -
37 * ..
38 * 23 -
39 * 24 Spurious Interrupt
40 * 25 Level 1 Interrupt
41 * Paula 0: Serial TX
42 * Paula 1: Disk DMA done
43 * Paula 2: Software Int
44 * 26 Level 2 Interrupt
45 * Paula 3: CIA
46 * 27 Level 3 Interrupt
47 * Paula 4: Copper
48 * Paula 5: Vert Blank
49 * Paula 6: Blitter
50 * 28 Level 4 Interrupt
51 * Paula 7: Audio 0
52 * Paula 8: Audio 1
53 * Paula 9: Audio 2
54 * Paula 10: Audio 3
55 * 29 Level 5 Interrupt
56 * Paula 11: Serial RX
57 * Paula 12: Disk Sync
58 * 30 Level 6 Interrupt
59 * Paula 13: External
60 * Paula 14: Copper (special)
61 * 31 Level 7 Interrupt
62 * Paula 15: NMI
63 * 32 TRAP #0
64 * ..
65 * 47 TRAP #15
66 * 48 -
67 * ..
68 * 63 -
69 * 64 User 1
70 * ..
71 * 255 User 191
74 /* The stack frame here:
75 * Return PC +(0 + 2 + 4)
76 * Return SP +(0 + 2)
77 * Exception struct * +(0)
78 * SP ->
80 * When we call M68KExceptionAction:
81 * D0-D1/A0-A1/A6 (5 * 4) <= NO TOUCHING!
82 * SysBase (4) A6
83 * SP (4) D1
84 * Exception struct * (4) D0
86 * When we come back:
87 * Drop SysBase, SP, and Exception args
88 * Restore D0-D1/A0-A1/A6
89 * Drop the Exception # word
90 * RTE
92 extern void M68KExceptionHelper(void);
93 asm (
94 " .text\n"
95 " .globl M68KExceptionHelper\n"
96 "M68KExceptionHelper:\n"
97 " movem.l %d0-%d1/%a0-%a1/%a6,%sp@-\n" // What we destory
98 " move.l %sp@(5*4),%d0\n" // Exception *
99 " clr.l %d1\n"
100 " move.w %sp@(5*4+4),%d1\n" // SR
101 " move.l 4, %a6\n" // Global SysBase
102 " move.l %a6, %sp@-\n" // Push SysBase
103 " move.l %d1, %sp@-\n" // Push SR
104 " move.l %d0, %sp@-\n" // Push Exception *
105 " jsr M68KExceptionAction\n"
106 " lea %sp@(12),%sp\n" // Drop all stack args
107 " movem.l %sp@+,%d0-%d1/%a0-%a1/%a6\n" // Restore
108 " addq.l #4, %sp\n" // Remove Exception *
109 " rte\n" // And return
112 #undef kprintf
114 void M68KExceptionAction(struct M68KException *Exception, UWORD SRReg, struct ExecBase *SysBase)
116 if (Exception->Handler == NULL) {
117 kprintf("-- Exception %d\n", Exception->Id);
118 Alert(AN_BogusExcpt);
119 for (;;);
122 Exception->Handler(Exception->Id, SRReg, SysBase);
125 /* We assume that the caller has already set up
126 * the exceptions to a 'reasonable' default. These
127 * are only the overrides for AROS.
129 void M68KExceptionInit(const struct M68KException *Table, struct ExecBase *SysBase)
131 IPTR *exception = (IPTR *)0; /* Exception base is at 0 */
132 UWORD *jmptab;
133 int i;
134 int size;
136 for (size = 0; Table[size].Id > 0; size++);
138 /* A little explanation. jmptab will be
139 * constructed as follows:
140 * move.l &Table[i], %sp@+
141 * 0x2f3c (&Table[i] >> 16) (&Table[i] & 0xffff)
142 * jmp %pc@(((size - 1) - i) * (5 * sizeof(UWORD)) + 2)
143 * 0x4efa (((size - 1) - i) * (5 * sizeof(UWORD)) + 2)
144 * ...
145 * ...
146 * jmp M68KExceptionHelper
147 * 0x4ef9 (M68KExceptionHelper >> 16) (M68KExceptionHelper & 0xffff)
149 * NOTICE: jmptab will never be freed! */
150 jmptab = AllocMem(size * (5 * sizeof(UWORD)) + 3 * sizeof(UWORD), 0);
152 for (i = 0; i < size; i++, jmptab += 5) {
153 jmptab[0] = 0x2f3c; // movel #...,%sp@-
154 jmptab[1] = ((IPTR)(&Table[i]) >> 16) & 0xffff;
155 jmptab[2] = ((IPTR)(&Table[i]) >> 0) & 0xffff;
156 jmptab[3] = 0x4efa; // jmp %pc@...
157 jmptab[4] = ((size - 1) - i) * (5 * sizeof(UWORD)) + 2;
158 exception[Table[i].Id] = (IPTR)(&jmptab[0]);
160 jmptab[0] = 0x4ef9; // jmp ....
161 jmptab[1] = ((IPTR)(M68KExceptionHelper) >> 16) & 0xffff;
162 jmptab[2] = ((IPTR)(M68KExceptionHelper) >> 0) & 0xffff;
164 /* We're all set up now! */