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