PS2SDK
PS2 Homebrew Libraries
iop_debug.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2001-2009, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
17 #include <tamtypes.h>
18 #include <excepman.h>
19 #include <iop_cop0_defs.h>
20 #include <ps2_debug.h>
21 
22 #include "iopdebug.h"
23 #include "iopdebug_priv.h"
24 #include "iopdebug_defs.h"
25 
26 u32 _iop_ex_def_stack[_EX_DEF_STACK_SIZE / 4];
27 u32 _iop_ex_dbg_stack[_EX_DBG_STACK_SIZE / 4];
28 
29 IOP_RegFrame _iop_ex_def_frame;
30 IOP_RegFrame _iop_ex_dbg_frame;
31 
32 static int _is_iop_dbg_installed = 0;
33 
34 static void *orig_iop_def_ex_handler = NULL;
35 static void *orig_iop_break_ex_handler = NULL;
36 static void *orig_iop_dbg_ex_handler = NULL;
37 
38 static IOP_ExceptionHandler *iop_exception_handlers[16];
39 
40 IOP_ExceptionHandler *iop_dbg_get_handler(int cause)
41 {
42  if((cause < 0) || (cause > 15)) { return(NULL); }
43 
44  return(iop_exception_handlers[cause]);
45 }
46 
47 IOP_ExceptionHandler *iop_dbg_set_handler(int cause, IOP_ExceptionHandler *handler)
48 {
49  IOP_ExceptionHandler *old_handler;
50  u32 old_state;
51 
52  if((cause < 0) || (cause > 15)) { return(NULL); }
53 
54  EnterCritical(&old_state);
55 
56  old_handler = iop_exception_handlers[cause];
57  iop_exception_handlers[cause] = handler;
58 
59  ExitCritical(old_state);
60 
61  return(old_handler);
62 }
63 
64 // this is called by the IOP debug/exception handlers
65 void iop_exception_dispatcher(IOP_RegFrame *frame)
66 {
67  int excode = M_IOP_GET_CAUSE_EXCODE(frame->cause);
68  IOP_ExceptionHandler *handler = iop_exception_handlers[excode];
69 
70  if(handler)
71  {
72  handler(frame);
73  }
74 }
75 
76 extern void _iop_dbg_set_bpda(u32 addr, u32 mask, u32 user_mask);
77 extern void _iop_dbg_set_bpx(u32 addr, u32 mask, u32 user_mask);
78 
79 // ex: iop_dbg_set_bpr(&var, 0xFFFFFFFF, (IOP_DCIC_UD | IOP_DCIC_KD));
80 void iop_dbg_set_bpr(u32 addr, u32 mask, u32 user_mask) { _iop_dbg_set_bpda(addr, mask, IOP_DCIC_DR | user_mask); }
81 
82 // ex: iop_dbg_set_bpw(&var, 0xFFFFFFFF, (IOP_DCIC_UD | IOP_DCIC_KD));
83 void iop_dbg_set_bpw(u32 addr, u32 mask, u32 user_mask) { _iop_dbg_set_bpda(addr, mask, IOP_DCIC_DW | user_mask); }
84 
85 // ex: iop_dbg_set_bpx(&func, 0xFFFFFFFF, (IOP_DCIC_UD | IOP_DCIC_KD));
86 void iop_dbg_set_bpx(u32 addr, u32 mask, u32 user_mask) { _iop_dbg_set_bpx(addr, mask, user_mask); }
87 
88 void iop_dbg_clr_bpda(void)
89 {
90  u32 dcic = iop_dbg_get_dcic();
91  dcic &= ~(IOP_DCIC_DW | IOP_DCIC_DR | IOP_DCIC_DAE);
92  if(!(dcic & IOP_DCIC_PCE)) { dcic = 0; }
93  iop_dbg_set_dcic(dcic);
94 }
95 
96 void iop_dbg_clr_bpx(void)
97 {
98  u32 dcic = iop_dbg_get_dcic();
99  dcic &= ~(IOP_DCIC_PCE);
100  if(!(dcic & IOP_DCIC_DAE)) { dcic = 0; }
101  iop_dbg_set_dcic(dcic);
102 }
103 
104 void iop_dbg_clr_bps(void)
105 {
106  iop_dbg_set_dcic(0);
107  iop_dbg_set_bda(0);
108  iop_dbg_set_bdam(0);
109  iop_dbg_set_bpc(0);
110  iop_dbg_set_bpcm(0);
111 }
112 
113 extern void _iop_ex_def_handler(void);
114 extern void _iop_ex_dbg_handler(void);
115 extern void _iop_ex_break_handler(void);
116 
117 int iop_dbg_install(void)
118 {
119  int i;
120 
121  // if already installed, return with an error.
122  if(_is_iop_dbg_installed) { return(-1); }
123 
124  // initialize our exception handler pointers.
125  for(i = 0; i < 16; i++)
126  {
127  iop_exception_handlers[i] = NULL;
128  }
129 
130  // todo: preserve original exception handlers here!
131  // This will require using "EXCEPMAN" export 3..
132 
133  // register our "default" exception handler.
134  if(RegisterDefaultExceptionHandler((exception_handler_t) _iop_ex_def_handler) < 0)
135  {
136  orig_iop_def_ex_handler = NULL;
137  return(-2);
138  }
139 
140  // register our "BREAK" instruction exception handler.
141  if(RegisterPriorityExceptionHandler(IOP_EXCEPTION_BP, 0, (exception_handler_t) _iop_ex_break_handler) < 0)
142  {
143  RegisterDefaultExceptionHandler((exception_handler_t) orig_iop_def_ex_handler);
144  orig_iop_def_ex_handler = NULL;
145  orig_iop_break_ex_handler = NULL;
146  return(-3);
147  }
148 
149  // register our "Hardware DeBug"(aka "Hardware BreakPoint") exception handler.
150  if(RegisterPriorityExceptionHandler(IOP_EXCEPTION_HDB, 0, (exception_handler_t) _iop_ex_dbg_handler) < 0)
151  {
152  RegisterDefaultExceptionHandler((exception_handler_t) orig_iop_def_ex_handler);
153  orig_iop_def_ex_handler = NULL;
154 
155  RegisterPriorityExceptionHandler(IOP_EXCEPTION_BP, 0, (exception_handler_t) orig_iop_break_ex_handler);
156  orig_iop_break_ex_handler = NULL;
157 
158  orig_iop_dbg_ex_handler = NULL;
159  return(-4);
160  }
161 
162  _is_iop_dbg_installed = 1;
163  return(0);
164 }
165 
166 int iop_dbg_remove(void)
167 {
168  // if not installed, return with an error.
169  if(!_is_iop_dbg_installed) { return(-1); }
170 
171  if(orig_iop_def_ex_handler)
172  {
173  RegisterDefaultExceptionHandler((exception_handler_t) orig_iop_def_ex_handler);
174  orig_iop_def_ex_handler = NULL;
175  }
176 
177  if(orig_iop_break_ex_handler)
178  {
179  RegisterPriorityExceptionHandler(IOP_EXCEPTION_BP, 0, (exception_handler_t) orig_iop_break_ex_handler);
180  orig_iop_break_ex_handler = NULL;
181  }
182 
183  if(orig_iop_dbg_ex_handler)
184  {
185  RegisterPriorityExceptionHandler(IOP_EXCEPTION_HDB, 0, (exception_handler_t) orig_iop_dbg_ex_handler);
186  orig_iop_dbg_ex_handler = NULL;
187  }
188 
189  _is_iop_dbg_installed = 0;
190  return(0);
191 }
192 
193 void iop_dbg_get_reg_frames(IOP_RegFrame **def_frame_ptr, IOP_RegFrame **dbg_frame_ptr)
194 {
195  if(def_frame_ptr) { *def_frame_ptr = &_iop_ex_def_frame; }
196  if(dbg_frame_ptr) { *dbg_frame_ptr = &_iop_ex_dbg_frame; }
197 }
198 
_EX_DBG_STACK_SIZE
#define _EX_DBG_STACK_SIZE
Definition: iopdebug_defs.h:24
IOP_DCIC_DAE
#define IOP_DCIC_DAE
Definition: iop_cop0_defs.h:44
IOP_DCIC_DR
#define IOP_DCIC_DR
Definition: iop_cop0_defs.h:42
excepman.h
st_IOP_RegFrame
Definition: ps2_debug.h:11
ExitCritical
static void ExitCritical(u32 old_state)
Definition: iopdebug_priv.h:31
_EX_DEF_STACK_SIZE
#define _EX_DEF_STACK_SIZE
Definition: iopdebug_defs.h:21
iopdebug_defs.h
_exception_handler_struct_t
Definition: excepman.h:60
tamtypes.h
iopdebug_priv.h
iop_cop0_defs.h
IOP_DCIC_DW
#define IOP_DCIC_DW
Definition: iop_cop0_defs.h:40
ps2_debug.h
IOP_DCIC_PCE
#define IOP_DCIC_PCE
Definition: iop_cop0_defs.h:46
EnterCritical
static void EnterCritical(u32 *old_state)
Definition: iopdebug_priv.h:28
iopdebug.h
IOP_EXCEPTION_HDB
#define IOP_EXCEPTION_HDB
Definition: excepman.h:58
IOP_EXCEPTION_BP
#define IOP_EXCEPTION_BP
Definition: excepman.h:46