-
Notifications
You must be signed in to change notification settings - Fork 0
/
exception.c
182 lines (160 loc) · 3.17 KB
/
exception.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include "proto.h"
typedef struct {
uint32_t d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6;
} registers_t;
__attribute__((noreturn))
static void
fatal_exception(const char *kind, registers_t *regs __attribute((unused)))
{
board_status(0);
fmt("fatal: %s\n", kind);
for (;;);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_bus_error(registers_t regs __attribute((unused)))
{
fatal_exception("bus error", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_address_error(registers_t regs __attribute((unused)))
{
fatal_exception("address error", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_illegal_instruction(registers_t regs __attribute((unused)))
{
fatal_exception("illegal instruction", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_zero_divide(registers_t regs __attribute((unused)))
{
fatal_exception("zero divide", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_chk(registers_t regs __attribute((unused)))
{
fatal_exception("chk", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_trapv(registers_t regs __attribute((unused)))
{
fatal_exception("trapv", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_privilege_violation(registers_t regs __attribute((unused)))
{
fatal_exception("privilege violation", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_trace(registers_t regs __attribute((unused)))
{
fatal_exception("trace", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_line_a(registers_t regs __attribute((unused)))
{
fatal_exception("line a", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_line_f(registers_t regs __attribute((unused)))
{
fatal_exception("line f", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_uninitialized_interrupt(registers_t regs __attribute((unused)))
{
fatal_exception("uninitialized interrupt", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_spurious_interrupt(registers_t regs __attribute((unused)))
{
fatal_exception("spurious interrupt", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_64(registers_t regs __attribute((unused)))
{
fatal_exception("vector_64", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_65(registers_t regs __attribute((unused)))
{
fatal_exception("vector_65", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_66(registers_t regs __attribute((unused)))
{
fatal_exception("vector_66", ®s);
}
INTERRUPT_HANDLER
__attribute__((weak))
void
vector_67(registers_t regs __attribute((unused)))
{
fatal_exception("vector_67", ®s);
}
static inline uint16_t
get_sr()
{
uint16_t result;
__asm__ volatile (
"move.w %%sr, %0"
: "=d" (result)
:
: "memory"
);
return result;
}
static inline void
set_sr(uint16_t value)
{
__asm__ volatile (
"move.w %0, %%sr"
:
: "d" (value)
: "memory"
);
}
bool
interrupt_disable()
{
bool state = ((get_sr() & 0x0700) == 0);
set_sr(0x2700);
return state;
}
void
interrupt_enable(bool enable)
{
if (enable) {
set_sr(0x2000);
}
}