/[pcsx2_0.9.7]/trunk/fps2bios/kernel/iopload/excepman/excepman.c
ViewVC logotype

Contents of /trunk/fps2bios/kernel/iopload/excepman/excepman.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (show annotations) (download)
Mon Sep 6 11:40:06 2010 UTC (9 years, 5 months ago) by william
File MIME type: text/plain
File size: 8472 byte(s)
exported r3113 from ./upstream/trunk
1 /*
2 * The IOP exception manager module.
3 */
4
5
6 #include <tamtypes.h>
7
8 #include "err.h"
9 #include "kexcepman.h"
10 #include "kloadcore.h"
11 #include "iopdebug.h"
12
13 #define _dprintf(fmt, args...) \
14 __printf("excepman: " fmt, ## args)
15
16 int _start();
17 int excepman_reinit();
18 int excepman_deinit();
19 void *GetExHandlersTable();
20 int RegisterExceptionHandler(int code, struct exHandler *handler);
21 int RegisterPriorityExceptionHandler(int code, int priority, struct exHandler *handler);
22 int RegisterDefaultExceptionHandler(struct exHandler *handler);
23 int ReleaseExceptionHandler(int code, struct exHandler *handler);
24 int ReleaseDefaultExceptionHandler(struct exHandler *handler);
25
26 struct export excepman_stub __attribute__((section(".text"))) ={
27 0x41C00000,
28 0,
29 VER(1, 1), // 1.1 => 0x101
30 0,
31 "excepman",
32 (func)_start, // entrypoint
33 (func)excepman_reinit,
34 (func)excepman_deinit,
35 (func)GetExHandlersTable,
36 (func)RegisterExceptionHandler,
37 (func)RegisterPriorityExceptionHandler,
38 (func)RegisterDefaultExceptionHandler,
39 (func)ReleaseExceptionHandler,
40 (func)ReleaseDefaultExceptionHandler,
41 0
42 };
43
44 void* *extable;
45 struct exHandler *handlers[16];
46 void *defhandler;
47
48 void iopException();
49
50 extern void defaultEH();
51
52 void defaultEHfunc()
53 {
54 __printf("panic: excepman: %s\n", __FUNCTION__);
55 __printf("EPC=0x%x, cause: %x\n", *(u32*)0x404, *(u32*)0x40C);
56 __printf("EXECUTION HALTED\n");
57 for (;;);
58 }
59
60 ///////////////////////////////////////////////////////////////////////
61 void registerEH() {
62 int i;
63
64 _dprintf("%s\n", __FUNCTION__);
65
66 // Set up the chain of exception handlers, making sure that each used one is terminated by the
67 // default exception handler.
68 for (i=0; i<16; i++) {
69 if (handlers[i]) {
70 struct exHandler *eh = handlers[i];
71 while(eh->next){
72 struct exHandler *p_handler = (struct exHandler *)(eh->info & ~3);
73 struct exHandler *p_next_handler = (struct exHandler *)(((struct exHandler *)(eh->next))->info & ~3);
74 p_handler->next = (void*)p_next_handler + 8;
75 eh = eh->next;
76 }
77 {
78 struct exHandler *p_handler = (struct exHandler *)(eh->info & ~3);
79 p_handler->next = defhandler;
80 }
81 }
82 }
83
84 for (i=0; i<16; i++) {
85 if (handlers[i]){
86 extable[i]=(void*)((handlers[i]->info & ~3) + 8);
87 } else {
88 extable[i]=defhandler;
89 }
90 }
91 }
92
93 //////////////////////////////entrypoint///////////////////////////////[00]
94 void Kputc(u8 c) {
95 *((u8*)0x1f80380c) = c;
96 }
97
98 void Kprintnum(unsigned int n)
99 {
100 int i = 0;
101 while(i < 8) {
102 u32 a = n>>28;
103 if( a < 10 ) Kputc('0'+a);
104 else Kputc('a'+(a-10));
105 n <<= 4;
106 ++i;
107 }
108 }
109
110 int _start() {
111 int *src, *dst;
112 int i;
113
114 _dprintf("%s\n", __FUNCTION__);
115
116 for (i=0; i<16; i++){
117 handlers[i] = NULL;
118 }
119 defhandler=NULL;
120 extable = (void*)0x440;
121
122 // Install the exception handler to address 0
123 for (src=(int*)iopException, dst=0; (u32)dst<0x100; src++, dst++){
124 *dst = *src;
125 }
126
127 RegisterDefaultExceptionHandler((struct exHandler *)&defaultEH);
128 RegisterLibraryEntries(&excepman_stub);
129
130 return 0;
131 }
132
133 ///////////////////////////////////////////////////////////////////////[02]
134 int excepman_deinit(){
135 return 0;
136 }
137
138 ///////////////////////////////////////////////////////////////////////[01]
139 int excepman_reinit() {
140 excepman_deinit();
141 return _start();
142 }
143
144 ///////////////////////////////////////////////////////////////////////[04]
145 int RegisterExceptionHandler(int code, struct exHandler *handler)
146 {
147 return RegisterPriorityExceptionHandler(code, 2, handler);
148 }
149
150 // This is a pool of containers. They form a linked list. The info member of each points
151 // to a registered handler.
152 struct exHandler _list[32];
153 struct exHandler *list = NULL;
154
155
156 void link(struct exHandler *e) {
157 e->next = list;
158 list = e;
159 }
160
161 struct exHandler *unlink() {
162 struct exHandler *e;
163 if (list == NULL) {
164 int i;
165
166 list = _list;
167 for (i=0; i<31; i++) {
168 list[i].next = &list[i+1];
169 }
170 list[i].next = 0;
171 }
172 e = list;
173 list = e->next;
174 return e;
175 }
176
177 ///////////////////////////////////////////////////////////////////////[05]
178 int RegisterPriorityExceptionHandler(int code, int priority, struct exHandler *handler)
179 {
180 struct exHandler *n, *p, *p_prev;
181
182 _dprintf("%s: code = %d, pri = %d, (handler=%x)\n", __FUNCTION__, code, priority, handler);
183 if (code >= 16){
184 _dprintf("%s ERROR_BAD_EXCODE\n", __FUNCTION__);
185 return ERROR_BAD_EXCODE;
186 }
187 if (handler->next){
188 _dprintf("%s ERROR_USED_EXCODE\n", __FUNCTION__);
189 return ERROR_USED_EXCODE;
190 }
191
192 n = unlink();
193
194 priority &= 3;
195 n->info = ((u32)handler & ~3) | priority;
196 n->next = NULL;
197
198 p = handlers[code]; p_prev = NULL;
199 // walk along the chain starting at the handlers[code] root to find our place in the queue
200 while(p && ((p->info & 3) < priority)){
201 p_prev = p; p = p->next;
202 }
203 n->next = p;
204 if (p_prev == NULL){
205 handlers[code] = n;
206 } else {
207 p_prev->next = n;
208 }
209
210 registerEH();
211 return 0;
212 }
213
214 ///////////////////////////////////////////////////////////////////////[06]
215 int RegisterDefaultExceptionHandler(struct exHandler *handler)
216 {
217 _dprintf("%s\n", __FUNCTION__);
218 if (handler->next){
219 _dprintf("%s ERROR_USED_EXCODE\n", __FUNCTION__);
220 return ERROR_USED_EXCODE;
221 }
222
223 handler->next = defhandler;
224 defhandler = &handler->funccode;
225
226 registerEH();
227 return 0;
228 }
229
230 ///////////////////////////////////////////////////////////////////////[07]
231 int ReleaseExceptionHandler(int code, struct exHandler *handler)
232 {
233 struct exHandler *p, *p_prev;
234
235 _dprintf("%s: %d\n", __FUNCTION__, code);
236 if (code>=16) return ERROR_BAD_EXCODE;
237
238 p_prev = NULL;
239 for (p=handlers[code]; p != NULL; p_prev = p, p=p->next) {
240 if ((struct exHandler *)(p->info & ~3) == handler) {
241 // found it
242 // Mark the handler as no longer used
243 ((struct exHandler *)(p->info & ~3))->next = NULL;
244
245 if (p == handlers[code]){
246 // special case, no more list
247 handlers[code] = NULL;
248 } else {
249 // Remove container p from the list
250 p_prev->next = p->next;
251 }
252
253 link(p); // Add the container back to the pool
254 registerEH();
255 return 0;
256 }
257 }
258 return ERROR_EXCODE_NOTFOUND;
259 }
260
261 ///////////////////////////////////////////////////////////////////////[08]
262 int ReleaseDefaultExceptionHandler(struct exHandler *handler)
263 {
264 struct exHandler *p;
265
266 _dprintf("%s\n", __FUNCTION__);
267 for (p=defhandler; p->next; p=p->next-8) {
268 if (p->next == handler->funccode) {
269 p->next = handler->next;
270 handler->next = 0;
271 registerEH();
272 return 0;
273 }
274 }
275 return ERROR_EXCODE_NOTFOUND;
276 }
277
278 ///////////////////////////////////////////////////////////////////////[03]
279 void *GetExHandlersTable()
280 {
281 return extable;
282 }
283
284 // 256 bytes of this code are copied to memory address 0 in order to install the exception handling code.
285 // Take careful note of the alignment of the code at 0x40 and 0x80 if you change it at all.
286 void iopException() {
287 __asm__ (
288 ".set noat\n"
289 "nop\nnop\nnop\nnop\n"
290 "nop\nnop\nnop\nnop\n"
291 "nop\nnop\nnop\nnop\n"
292 "nop\nnop\nnop\nnop\n"
293
294 /* 0x0040 */
295 /* This the breakpoint exception vector location. */
296
297 "sw $26, 0x0420($0)\n"
298 "mfc0 $27, $14\n"
299 "mfc0 $26, $13\n"
300 "sw $27, 0x0424($0)\n"
301 "sw $26, 0x0428($0)\n"
302 "mfc0 $27, $12\n"
303 "mfc0 $26, $7\n"
304 "sw $27, 0x042C($0)\n"
305 "sw $26, 0x0430($0)\n"
306 "lw $27, 0x047C($0)\n"
307 "mtc0 $0, $7\n"
308 "jr $27\n"
309 "nop\n"
310 "nop\n"
311 "nop\n"
312 "nop\n"
313
314 /* 0x0080 */
315 /* This is the general exception vector location. */
316 "sw $1, 0x0400($0)\n" /* $1 saved at 0x400 */
317 "sw $26, 0x0410($0)\n" /* $26 saved at 0x410 */
318 "mfc0 $1, $14\n"
319 "mfc0 $26, $12\n"
320 "sw $1 , 0x0404($0)\n" /* EPC -> 0x404 */
321 "sw $26, 0x0408($0)\n" /* STATUS -> 0x408 */
322 "mfc0 $1, $13\n"
323 "sw $1, 0x040C($0)\n" /* CAUSE -> 0x40C */
324 "andi $1, 0x3C\n" /* Isolate EXECODE */
325 "lw $1, 0x0440($1)\n"
326 "jr $1\n" /* jump via EXECODE table at 0x440 */
327 "nop\n"
328 "nop\n"
329 "nop\n"
330 "nop\n"
331 "nop\n"
332
333 "nop\nnop\nnop\nnop\n"
334 "nop\nnop\nnop\nnop\n"
335 "nop\nnop\nnop\nnop\n"
336 "nop\nnop\nnop\nnop\n"
337 ".set at\n"
338 );
339 }

  ViewVC Help
Powered by ViewVC 1.1.22