ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
ee_debug.c
Go to the documentation of this file.
1 #include <kernel.h>
2 #include <ee_debug.h>
3 #include <string.h>
4 
5 #include "eedebug_defs.h"
6 
7 // the stacks for the Level 1 and Level 2 exception handlers.
8 u128 __ee_ex_l1_stack[_EX_L1_STACK_SIZE / 16] __attribute__ ((aligned(128)));
9 u128 __ee_ex_l2_stack[_EX_L2_STACK_SIZE / 16] __attribute__ ((aligned(128)));
10 
11 // the register frames used by the Level 1 and Level 2 exception handlers to store the register states.
12 EE_RegFrame __ee_ex_l1_frame __attribute__ ((aligned(128)));
13 EE_RegFrame __ee_ex_l2_frame __attribute__ ((aligned(128)));
14 
15 // used to preserve the original "debug" exception vector.
16 static u32 __saved_dbg_ex_vector[0x80 / 4] = { 0 };
17 
18 // used to preserve the original "Level 1" exception handlers.
19 static void *_old_l1_handlers[16] = { 0 };
20 
21 static int _installed_levels = 0;
22 
25 
27 {
28  while(1);
29 }
30 
32 {
33  int excode = M_EE_GET_CAUSE_EXCODE(frame->cause);
35 
36  if(handler)
37  {
38  handler(frame);
39  }
40 }
41 
43 {
44  int exc2 = M_EE_GET_CAUSE_EXC2(frame->cause);
46 
47  if(handler)
48  {
49  handler(frame);
50  }
51 }
52 
54 {
55  if((cause < 0) || (cause > 13)) { return(NULL); }
56 
57  return(ee_level1_exception_handlers[cause]);
58 }
59 
61 {
62  EE_ExceptionHandler *old_handler;
63  u32 oldintr;
64 
65  if((cause < 0) || (cause > 13)) { return(NULL); }
66 
67  oldintr = DIntr();
68 
69  old_handler = ee_level1_exception_handlers[cause];
70  ee_level1_exception_handlers[cause] = handler;
71 
72  if(oldintr) { EIntr(); }
73 
74  return(old_handler);
75 }
76 
78 {
79  if((cause < 0) || (cause > 3)) { return(NULL); }
80 
81  return(ee_level2_exception_handlers[cause]);
82 }
83 
85 {
86  EE_ExceptionHandler *old_handler;
87  u32 oldintr;
88 
89  if((cause < 0) || (cause > 3)) { return(NULL); }
90 
91  oldintr = DIntr();
92 
93  old_handler = ee_level2_exception_handlers[cause];
94  ee_level2_exception_handlers[cause] = handler;
95 
96  if(oldintr) { EIntr(); }
97 
98  return(old_handler);
99 }
100 
101 extern void _ee_dbg_set_bpda(u32, u32, u32);
102 extern void _ee_dbg_set_bpdv(u32, u32, u32);
103 extern void _ee_dbg_set_bpx(u32, u32, u32);
104 
105 // ex: ee_dbg_set_bpr(&var, 0xFFFFFFFF, (EE_BPC_DUE | EE_BPC_DSE | EE_BPC_DKE | EE_BPC_DXE));
106 void ee_dbg_set_bpr(u32 addr, u32 mask, u32 opmode_mask) { _ee_dbg_set_bpda(addr, mask, EE_BPC_DRE | opmode_mask); }
107 
108 // ex: ee_dbg_set_bpw(&var, 0xFFFFFFFF, (EE_BPC_DUE | EE_BPC_DSE | EE_BPC_DKE | EE_BPC_DXE));
109 void ee_dbg_set_bpw(u32 addr, u32 mask, u32 opmode_mask) { _ee_dbg_set_bpda(addr, mask, EE_BPC_DWE | opmode_mask); }
110 
111 // ex: ee_dbg_set_bprw(&var, 0xFFFFFFFF, (EE_BPC_DUE | EE_BPC_DSE | EE_BPC_DKE | EE_BPC_DXE));
112 void ee_dbg_set_bprw(u32 addr, u32 mask, u32 opmode_mask) { _ee_dbg_set_bpda(addr, mask, EE_BPC_DRE | EE_BPC_DWE | opmode_mask); }
113 
114 // ex: ee_dbg_set_bpv(0xDEADBEEF, 0xFFFFFFFF, (EE_BPC_DUE | EE_BPC_DSE | EE_BPC_DKE | EE_BPC_DXE));
115 void ee_dbg_set_bpv(u32 value, u32 mask, u32 opmode_mask) { _ee_dbg_set_bpdv(value, mask, opmode_mask); }
116 
117 // ex: ee_dbg_set_bpx(&func, 0xFFFFFFFF, (EE_BPC_IUE | EE_BPC_ISE | EE_BPC_IKE | EE_BPC_IXE));
118 void ee_dbg_set_bpx(u32 addr, u32 mask, u32 opmode_mask) { _ee_dbg_set_bpx(addr, mask, opmode_mask); }
119 
120 void ee_dbg_clr_bpda(void)
121 {
122  u32 bpc = ee_dbg_get_bpc();
123 
124  bpc &= ~(EE_BPC_DWE | EE_BPC_DRE);
125 
126  if(!(bpc & (EE_BPC_DVE)))
127  {
128  // if Data Value breakpoint not enabled, disable all Data bp bits.
130  }
131 
132  ee_dbg_set_bpc(bpc);
133 }
134 
135 void ee_dbg_clr_bpdv(void)
136 {
137  u32 bpc = ee_dbg_get_bpc();
138 
139  bpc &= ~(EE_BPC_DVE);
140 
141  if(!(bpc & (EE_BPC_DWE | EE_BPC_DRE)))
142  {
143  // if Data Read or Data Write breakpoints not enabled, disable all Data bp bits.
145  }
146 
147  ee_dbg_set_bpc(bpc);
148 }
149 
150 void ee_dbg_clr_bpx(void)
151 {
152  u32 bpc = ee_dbg_get_bpc();
154  ee_dbg_set_bpc(bpc);
155 }
156 
157 void ee_dbg_clr_bps(void)
158 {
160  ee_dbg_set_iab(0);
161  ee_dbg_set_iabm(0);
162  ee_dbg_set_dab(0);
163  ee_dbg_set_dabm(0);
164  ee_dbg_set_dvb(0);
165  ee_dbg_set_dvbm(0);
166 }
167 
168 extern void __ee_level1_ex_vector(void);
169 extern void __ee_level2_ex_vector(void);
170 
171 int ee_dbg_install(int levels)
172 {
173  u32 oldintr, oldop;
174  int i;
175 
176  if(_installed_levels & levels)
177  {
178  return(-1);
179  }
180 
181  if(levels & 1)
182  {
183  for(i = 0; i < 16; i++) { ee_level1_exception_handlers[i] = NULL; }
184  }
185 
186  if(levels & 2)
187  {
188  for(i = 0; i < 4; i++) { ee_level2_exception_handlers[i] = NULL; }
189 
190  oldintr = DIntr();
191  oldop = ee_set_opmode(0);
192 
193  ee_dbg_clr_bps();
194 
195  // save the original level 2 debug exception vector.
196  memcpy(&__saved_dbg_ex_vector, (void *) (0x80000100), 0x80);
197 
198  // replace the level 2 debug exception vector with our own
199  memcpy((void *) (0x80000100), &__ee_level2_ex_vector, 32);
200 
201  ee_set_opmode(oldop);
202  if(oldintr) { EIntr(); }
203  }
204 
205  if(levels & 1)
206  {
207  // redirect desirable "Level 1" exceptions to our level 1 handler.
208  for(i = 1; i <= 3; i++)
209  {
212  }
213 
214  for(i = 4; i <= 7; i++)
215  {
218  }
219 
220  for(i = 10; i <= 13; i++)
221  {
224  }
225  }
226 
227  FlushCache(0);
228  FlushCache(2);
229 
230  _installed_levels |= levels;
231 
232  return(0);
233 }
234 
235 int ee_dbg_remove(int levels)
236 {
237  u32 oldintr, oldop;
238  int i;
239 
240  if((levels < 1) || (levels > 3)) { return(-1); }
241 
242  if(!(_installed_levels & levels)) { return(-1); }
243 
244  if((levels & _installed_levels) & 2)
245  {
246  oldintr = DIntr();
247  oldop = ee_set_opmode(0);
248 
249  ee_dbg_clr_bps();
250 
251  // restore the original debug exception vector.
252  memcpy((void *) (0x80000100), &__saved_dbg_ex_vector, sizeof(__saved_dbg_ex_vector));
253 
254  ee_set_opmode(oldop);
255  if(oldintr) { EIntr(); }
256 
257  FlushCache(0);
258  FlushCache(2);
259 
260  _installed_levels &= 1;
261  }
262 
263  if((levels & _installed_levels) & 1)
264  {
265  // restore the exception handlers that we previously hooked.
266  for(i = 1; i <= 3; i++)
267  {
268  if(_old_l1_handlers[i] != NULL)
269  {
271  _old_l1_handlers[i] = NULL;
272  }
273  }
274  for(i = 4; i <= 7; i++)
275  {
276  if(_old_l1_handlers[i] != NULL)
277  {
279  _old_l1_handlers[i] = NULL;
280  }
281  }
282  for(i = 10; i <= 13; i++)
283  {
284  if(_old_l1_handlers[i] != NULL)
285  {
287  _old_l1_handlers[i] = NULL;
288  }
289  }
290 
291  FlushCache(0);
292  FlushCache(2);
293 
294  _installed_levels &= 2;
295  }
296 
297  return(0);
298 }
#define EE_BPC_DWE
Definition: ee_cop0_defs.h:69
#define EE_BPC_BED
Definition: ee_cop0_defs.h:105
#define EE_BPC_IUE
Definition: ee_cop0_defs.h:75
#define EE_BPC_DKE
Definition: ee_cop0_defs.h:93
#define M_EE_GET_CAUSE_EXCODE(__cause)
Definition: ee_cop0_defs.h:19
#define EE_BPC_ISE
Definition: ee_cop0_defs.h:78
#define EE_BPC_ITE
Definition: ee_cop0_defs.h:99
#define EE_BPC_IKE
Definition: ee_cop0_defs.h:81
#define M_EE_GET_CAUSE_EXC2(__cause)
Definition: ee_cop0_defs.h:20
#define EE_BPC_DVE
Definition: ee_cop0_defs.h:72
#define EE_BPC_DXE
Definition: ee_cop0_defs.h:96
#define EE_BPC_IXE
Definition: ee_cop0_defs.h:84
#define EE_BPC_DRE
Definition: ee_cop0_defs.h:66
#define EE_BPC_DUE
Definition: ee_cop0_defs.h:87
#define EE_BPC_DSE
Definition: ee_cop0_defs.h:90
#define EE_BPC_DTE
Definition: ee_cop0_defs.h:102
void ee_dbg_set_bprw(u32 addr, u32 mask, u32 opmode_mask)
Definition: ee_debug.c:112
void __ee_level2_ex_vector(void)
void __ee_level1_ex_vector(void)
void ee_dbg_clr_bpda(void)
Definition: ee_debug.c:120
int ee_dbg_remove(int levels)
Definition: ee_debug.c:235
void ee_dbg_set_bpw(u32 addr, u32 mask, u32 opmode_mask)
Definition: ee_debug.c:109
void ee_dbg_clr_bpx(void)
Definition: ee_debug.c:150
void _ee_dbg_set_bpdv(u32, u32, u32)
void _ee_dbg_set_bpda(u32, u32, u32)
static EE_ExceptionHandler * ee_level1_exception_handlers[16]
Definition: ee_debug.c:23
void ee_dbg_set_bpv(u32 value, u32 mask, u32 opmode_mask)
Definition: ee_debug.c:115
void ee_dbg_set_bpx(u32 addr, u32 mask, u32 opmode_mask)
Definition: ee_debug.c:118
EE_ExceptionHandler * ee_dbg_set_level1_handler(int cause, EE_ExceptionHandler *handler)
Definition: ee_debug.c:60
static EE_ExceptionHandler * ee_level2_exception_handlers[4]
Definition: ee_debug.c:24
static u32 __saved_dbg_ex_vector[0x80/4]
Definition: ee_debug.c:16
u128 __ee_ex_l2_stack[_EX_L2_STACK_SIZE/16]
Definition: ee_debug.c:9
int ee_dbg_install(int levels)
Definition: ee_debug.c:171
EE_ExceptionHandler * ee_dbg_get_level2_handler(int cause)
Definition: ee_debug.c:77
EE_RegFrame __ee_ex_l2_frame
Definition: ee_debug.c:13
void _def_ee_ex_handler(EE_RegFrame *frame)
Definition: ee_debug.c:26
void ee_dbg_clr_bps(void)
Definition: ee_debug.c:157
void _ee_dbg_set_bpx(u32, u32, u32)
void ee_dbg_clr_bpdv(void)
Definition: ee_debug.c:135
EE_ExceptionHandler * ee_dbg_get_level1_handler(int cause)
Definition: ee_debug.c:53
u128 __ee_ex_l1_stack[_EX_L1_STACK_SIZE/16]
Definition: ee_debug.c:8
static void * _old_l1_handlers[16]
Definition: ee_debug.c:19
void ee_dbg_set_bpr(u32 addr, u32 mask, u32 opmode_mask)
Definition: ee_debug.c:106
void ee_level2_ex_dispatcher(EE_RegFrame *frame)
Definition: ee_debug.c:42
static int _installed_levels
Definition: ee_debug.c:21
EE_ExceptionHandler * ee_dbg_set_level2_handler(int cause, EE_ExceptionHandler *handler)
Definition: ee_debug.c:84
void ee_level1_ex_dispatcher(EE_RegFrame *frame)
Definition: ee_debug.c:31
EE_RegFrame __ee_ex_l1_frame
Definition: ee_debug.c:12
void ee_dbg_set_iab(u32)
void ee_dbg_set_dvbm(u32)
void ee_dbg_set_dabm(u32)
int() EE_ExceptionHandler(struct st_EE_RegFrame *)
Definition: ee_debug.h:28
u32 ee_dbg_get_bpc(void)
void ee_dbg_set_iabm(u32)
void ee_dbg_set_dvb(u32)
void ee_dbg_set_bpc(u32)
void ee_dbg_set_dab(u32)
#define _EX_L2_STACK_SIZE
Definition: eedebug_defs.h:21
#define _EX_L1_STACK_SIZE
Definition: eedebug_defs.h:20
void SetVCommonHandler(s32 handler_num, void *handler_func)
static int ee_set_opmode(u32 opmode)
Definition: kernel.h:163
void SetVTLBRefillHandler(s32 handler_num, void *handler_func)
void FlushCache(s32 operation)
int DIntr(void)
void * GetExceptionHandler(int except_no)
int EIntr(void)
#define NULL
Definition: tamtypes.h:91
unsigned int u32
Definition: tamtypes.h:30
unsigned int u128
Definition: tamtypes.h:36