mgh: fix for default HDD DMA mode, that wasn't correctly set
[open-ps2-loader.git] / modules / debug / ioptrap / ioptrap.c
blob62ee1faa6b81884064aae5298385f0611bd7f541
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
10 # $Id: ioptrap.c 1619 2009-10-07 04:54:58Z Herben $
11 # IOP exception handling.
14 #include "types.h"
15 #include "defs.h"
16 #include "irx.h"
18 #include "ioptrap.h"
20 #include "excepman.h"
21 #include "loadcore.h"
22 #include "intrman.h"
23 #include "sifman.h"
24 #include "stdio.h"
25 #include "sysclib.h"
26 #include "thbase.h"
28 IRX_ID("ioptrap_driver", 1, 1);
30 struct irx_export_table _exp_ioptrap;
33 static const char *exception_type_name[] = {
34 "Interrupt",
35 "TLB Modification",
36 "TLB Miss Load",
37 "TLB Miss Store",
38 "Address Error Load",
39 "Address Error Store",
40 "Instruction Bus Error",
41 "Data Bus Error",
42 "Syscall",
43 "Breakpoint",
44 "Reserved Instruction",
45 "Coprocessor Unusable",
46 "Overflow",
47 "Reserved 13",
48 "Reserved 14" /* "Floating point exception" */
51 const char * get_exception_name(exception_type_t type) {
52 return exception_type_name[type];
55 exception_frame_t __trap_frame;
56 extern void def_exc_handler();
57 extern void bp_exc_handler();
59 int dbg_jmp_buf_setup = 0;
60 jmp_buf dbg_jmp_buf;
62 exception_type_t dbg_setjmp() {
63 int v;
64 if(0 == (v = setjmp(dbg_jmp_buf))) {
65 dbg_jmp_buf_setup = 1;
66 } else {
67 dbg_jmp_buf_setup = 0;
69 return v;
72 // from ps2link
74 /* Module info entry. */
75 typedef struct _smod_mod_info {
76 struct _smod_mod_info *next;
77 u8 *name;
78 u16 version;
79 u16 newflags; /* For modload shipped with games. */
80 u16 id;
81 u16 flags; /* I believe this is where flags are kept for BIOS versions. */
82 u32 entry; /* _start */
83 u32 gp;
84 u32 text_start;
85 u32 text_size;
86 u32 data_size;
87 u32 bss_size;
88 u32 unused1;
89 u32 unused2;
90 } smod_mod_info_t;
93 smod_mod_info_t *smod_get_next_mod(smod_mod_info_t *cur_mod)
95 /* If cur_mod is 0, return the head of the list (IOP address 0x800). */
96 if (!cur_mod) {
97 return (smod_mod_info_t *)0x800;
98 } else {
99 if (!cur_mod->next)
100 return 0;
101 else
102 return cur_mod->next;
104 return 0;
107 char* ExceptionGetModuleName(u32 epc, u32* r_epc)
109 smod_mod_info_t *mod_info = 0;
111 while((mod_info = smod_get_next_mod(mod_info)) != 0)
113 if((epc >= mod_info->text_start) && (epc <= (mod_info->text_start+mod_info->text_size)))
115 if(r_epc)
116 *r_epc = epc - mod_info->text_start;
118 return mod_info->name;
122 return 0;
125 #define JUMP_BUF_PC 0
126 #define JUMP_BUF_SP 1
127 #define JUMP_BUF_FP 2
128 #define JUMP_BUF_S0 3
129 #define JUMP_BUF_S1 4
130 #define JUMP_BUF_S2 5
131 #define JUMP_BUF_S3 6
132 #define JUMP_BUF_S4 7
133 #define JUMP_BUF_S5 8
134 #define JUMP_BUF_S6 9
135 #define JUMP_BUF_S7 10
136 #define JUMP_BUF_GP 11
138 // Define this to something else if you want... maybe some ee_sio stuff :P
139 #define TRAP_PRINTF(args...) printf(args)
141 static trap_exception_handler_t handlers[16];
143 trap_exception_handler_t set_exception_handler(exception_type_t type, trap_exception_handler_t handler) {
144 trap_exception_handler_t old_handler = handlers[type];
145 handlers[type] = handler;
146 return old_handler;
149 trap_exception_handler_t get_exception_handler(exception_type_t type) {
150 return handlers[type];
153 void trap(exception_type_t type, struct exception_frame *ex) {
154 u32 i, r_addr;
155 char *module;
156 if(dbg_jmp_buf_setup) {
157 u32 *p = (u32*)dbg_jmp_buf;
158 /* simulate longjmp */
159 ex->epc = p[JUMP_BUF_PC];
160 ex->regs[29] = p[JUMP_BUF_SP];
161 ex->regs[30] = p[JUMP_BUF_FP];
162 ex->regs[16] = p[JUMP_BUF_S0];
163 ex->regs[17] = p[JUMP_BUF_S1];
164 ex->regs[18] = p[JUMP_BUF_S2];
165 ex->regs[19] = p[JUMP_BUF_S3];
166 ex->regs[20] = p[JUMP_BUF_S4];
167 ex->regs[21] = p[JUMP_BUF_S5];
168 ex->regs[22] = p[JUMP_BUF_S6];
169 ex->regs[23] = p[JUMP_BUF_S7];
170 ex->regs[28] = p[JUMP_BUF_GP];
171 ex->regs[2] = type; /* return value from setjmp */
172 return;
174 TRAP_PRINTF("IOP Exception : %s\n", exception_type_name[type]);
175 TRAP_PRINTF("EPC=%08x CAUSE=%08x SR=%08x BADVADDR=%08x DCIC=%08x\n", (int)ex->epc, (int)ex->cause, (int)ex->sr, (int)ex->badvaddr, (int)ex->dcic);
176 if((module = ExceptionGetModuleName(ex->epc, &r_addr)))
177 TRAP_PRINTF("module %s at unreloc offset %08lX\n", module, r_addr);
178 if((module = ExceptionGetModuleName(ex->regs[31], &r_addr)))
179 TRAP_PRINTF("ra module %s at unreloc offset %08lX\n", module, r_addr);
180 for(i = 0; i != 32; i += 4) {
181 TRAP_PRINTF("r[%02d]=%08x r[%02d]=%08x r[%02d]=%08x r[%02d]=%08x\n",
182 (int)i, (int)ex->regs[i], (int)i+1, (int)ex->regs[i+1], (int)i+2, (int)ex->regs[i+2], (int)i+3, (int)ex->regs[i+3]);
185 if (handlers[type]) {
186 handlers[type](type, ex);
189 if(type == EXCEPTION_Bp) {
190 ex->dcic = 0;
191 } else {
192 if(ex->cause & (1<<31)) {
193 ex->cause &= ~(1<<31); /* clear BD */
194 } else {
195 ex->epc += 4;
200 #ifdef TEST_TRAP
201 static void trigger() {
202 u32 v;
203 printf("trigger=%p\n", trigger);
204 printf("badaddr\n");
205 if(0 == (v = setjmp(dbg_jmp_buf))) {
206 dbg_jmp_buf_setup = 1;
207 *(u32*)0xdeadbeef = 0xfeedface;
208 } else {
209 printf("exception occurred in command, v=%08x\n", (int)v);
211 dbg_jmp_buf_setup = 0;
212 printf("done.\n");
215 void main_thread(void *unused) {
216 int i = 0;
218 DelayThread(1000*1000);
220 printf("IOP: about to trap!\n");
221 trigger();
222 printf("IOP: back from trap!\n");
223 while(1) {
224 printf("IOP: still running %d\n", i++);
225 DelayThread(2000*1000);
226 if (i == 10)
227 break;
229 ExitDeleteThread();
232 int create_main_thread(void) {
233 iop_thread_t thread;
235 thread.attr = 0x2000000;
236 thread.option = 0;
237 thread.thread = main_thread;
238 thread.stacksize = 0x8000;
239 thread.priority = 0x18;
240 return CreateThread(&thread);
243 void do_tests() {
244 int thid;
245 thid = create_main_thread();
246 StartThread(thid, NULL);
248 #else
249 #define do_tests()
250 #endif
252 int _start(int argc, char **argv)
254 int rv;
256 if(RegisterLibraryEntries(&_exp_ioptrap) != 0) return 1;
258 memset(handlers, 0, sizeof(trap_exception_handler_t) * 16);
259 printf("ioptrap starts.\n");
260 if((rv = RegisterDefaultExceptionHandler(def_exc_handler)) < 0) {
261 printf("RegisterDefaultExceptionHandler failed, rv=%d\n", rv);
262 return 1;
264 if((rv = RegisterPriorityExceptionHandler(IOP_EXCEPTION_HDB, 0, bp_exc_handler)) < 0) {
265 // shouldn't we release the default exception handler here... ?
266 printf("RegisterDefaultExceptionHandler failed, rv=%d\n", rv);
267 return 1;
269 do_tests();
270 return 0;
273 int shutdown()
275 return 0;