/[pcsx2_0.9.7]/trunk/pcsx2/RDebug/deci2_dbgp.cpp
ViewVC logotype

Contents of /trunk/pcsx2/RDebug/deci2_dbgp.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 5 months ago) by william
File size: 14267 byte(s)
committing r3113 initial commit again...
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16
17 #include "PrecompiledHeader.h"
18
19 #include "IopCommon.h"
20 #include "VUmicro.h"
21 #include "deci2.h"
22
23 using namespace Threading;
24
25 using namespace R5900;
26
27 struct DECI2_DBGP_HEADER{
28 DECI2_HEADER h; //+00
29 u16 id; //+08
30 u8 type, //+0A
31 code, //+0B
32 result, //+0C
33 count; //+0D
34 u16 _pad; //+0E
35 }; //=10
36
37 struct DECI2_DBGP_CONF{
38 u32 major_ver, //+00
39 minor_ver, //+04
40 target_id, //+08
41 _pad, //+0C
42 mem_align, //+10
43 _pad2, //+14
44 reg_size, //+18
45 nreg, //+1C
46 nbrkpt, //+20
47 ncont, //+24
48 nstep, //+28
49 nnext, //+2C
50 mem_limit_align, //+30
51 mem_limit_size, //+34
52 run_stop_state, //+38
53 hdbg_area_addr, //+3C
54 hdbg_area_size; //+40
55 }; //=44
56
57 DECI2_DBGP_CONF
58 cpu={3, 0, PROTO_EDBGP, 0, 0x41F, 1, 7, 32, 32, 1, 0xFF, 0xFF, 0x1F, 0x400, 2, 0x80020c70, 0x100},
59 vu0={3, 0, PROTO_EDBGP, 0, 0x41F, 1, 7, 32, 32, 1, 0xFF, 0xFF, 0x1F, 0x400, 2, 0x80020c70, 0x100},
60 vu1={3, 0, PROTO_EDBGP, 0, 0x41F, 1, 7, 32, 32, 1, 0xFF, 0xFF, 0x1F, 0x400, 2, 0x80020c70, 0x100},
61 iop={3, 0, PROTO_IDBGP, 0, 0x00F, 1, 5, 62, 32, 1, 0x00, 0x00, 0x07, 0x200, 1, 0x0001E670, 0x100};
62 //iop={3, 0, PROTO_IDBGP, 0, 0x00F, 1, 5, 62, 0, 1, 0x00, 0x00, 0x07, 0x200, 0, 0x00006940, 0x100};
63
64 #pragma pack(2)
65 struct DECI2_DBGP_EREG{
66 u8 kind, //+00
67 number; //+01
68 u16 _pad; //+02
69 u64 value[2]; //+04
70 }; //=14
71
72 struct DECI2_DBGP_IREG{
73 u8 kind, //+00
74 number; //+01
75 u16 _pad; //+02
76 u32 value; //+04
77 }; //=08
78
79 struct DECI2_DBGP_MEM{
80 u8 space, //+00
81 align; //+01
82 u16 _pad; //+02
83 u32 address; //+04
84 u32 length; //+08
85 }; //=0C
86
87 struct DECI2_DBGP_RUN{
88 u32 entry, //+00
89 gp, //+04
90 _pad, //+08
91 _pad1, //+0C
92 argc; //+10
93 //u32 argv; //+14
94 }; //=18
95 #pragma pack()
96
97 void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char *ioppc, char *eecy, char *iopcy){
98 const DECI2_DBGP_HEADER *in=(DECI2_DBGP_HEADER*)inbuffer;
99 DECI2_DBGP_HEADER* out=(DECI2_DBGP_HEADER*)outbuffer;
100
101 DECI2_DBGP_EREG *eregs=(DECI2_DBGP_EREG*)&out[1];
102 DECI2_DBGP_IREG *iregs=(DECI2_DBGP_IREG*)&out[1];
103 DECI2_DBGP_MEM *mem =(DECI2_DBGP_MEM*) &out[1];
104 const DECI2_DBGP_RUN*run =(DECI2_DBGP_RUN*) &in[1];
105
106 static char line[1024];
107 int i, s;
108
109 memcpy(outbuffer, inbuffer, 128*1024);//BUFFERSIZE
110 //out->h.length=sizeof(DECI2_DBGP_HEADER);
111 out->type++;
112 out->result=0; //ok
113 exchangeSD((DECI2_HEADER*)out);
114 switch(in->type){
115 case 0x00://ok
116 sprintf(line, "%s/GETCONF", in->id==0?"CPU":in->id==1?"VU0":"VU1");
117
118 if (in->h.destination=='I'){
119 memcpy(&out[1], &iop, sizeof(DECI2_DBGP_CONF));
120 }else
121 switch(in->id){
122 case 0:memcpy(&out[1], &cpu, sizeof(DECI2_DBGP_CONF));break;
123 case 1:memcpy(&out[1], &vu0, sizeof(DECI2_DBGP_CONF));break;
124 case 2:memcpy(&out[1], &vu1, sizeof(DECI2_DBGP_CONF));break;
125 }
126 break;
127 case 0x02://ok
128 sprintf(line, "%s/2", in->id==0?"CPU":in->id==1?"VU0":"VU1");
129 break;
130 case 0x04://ok
131 sprintf(line, "%s/GETREG count=%d kind[0]=%d number[0]=%d",
132 in->id==0?"CPU":in->id==1?"VU0":"VU1", in->count, eregs[0].kind, eregs[0].number);
133 if (in->h.destination=='I'){
134 for (i=0; i<in->count; i++)
135 switch (iregs[i].kind){
136 case 1:switch (iregs[i].number){
137 case 0:iregs[i].value=psxRegs.GPR.n.lo;break;
138 case 1:iregs[i].value=psxRegs.GPR.n.hi;break;
139 }
140 break;
141 case 2:iregs[i].value=psxRegs.GPR.r[iregs[i].number]; break;
142 case 3:
143 if (iregs[i].number==14) psxRegs.CP0.n.EPC=psxRegs.pc;
144 iregs[i].value=psxRegs.CP0.r[iregs[i].number];
145 break;
146 case 6:iregs[i].value=psxRegs.CP2D.r[iregs[i].number]; break;
147 case 7:iregs[i].value=psxRegs.CP2C.r[iregs[i].number]; break;
148 default:
149 iregs[0].value++;//dummy; might be assert(0)
150 }
151 }else
152 for (i=0; i<in->count; i++)
153 switch (eregs[i].kind){
154 case 0:memcpy(eregs[i].value, &cpuRegs.GPR.r[eregs[i].number], 16);break;
155 case 1:
156 switch(eregs[i].number){
157 case 0:memcpy(eregs[i].value, &cpuRegs.HI.UD[0], 8);break;
158 case 1:memcpy(eregs[i].value, &cpuRegs.LO.UD[0], 8);break;
159 case 2:memcpy(eregs[i].value, &cpuRegs.HI.UD[1], 8);break;
160 case 3:memcpy(eregs[i].value, &cpuRegs.LO.UD[1], 8);break;
161 case 4:memcpy(eregs[i].value, &cpuRegs.sa, 4); break;
162 }
163 case 2:
164 if (eregs[i].number==14) cpuRegs.CP0.n.EPC=cpuRegs.pc;
165 memcpy(eregs[i].value, &cpuRegs.CP0.r[eregs[i].number], 4);
166 break;
167 case 3:break;//performance counter 32x3
168 case 4:break;//hw debug reg 32x8
169 case 5:memcpy(eregs[i].value, &fpuRegs.fpr[eregs[i].number], 4);break;
170 case 6:memcpy(eregs[i].value, &fpuRegs.fprc[eregs[i].number], 4);break;
171 case 7:memcpy(eregs[i].value, &VU0.VF[eregs[i].number], 16);break;
172 case 8:memcpy(eregs[i].value, &VU0.VI[eregs[i].number], 4);break;
173 case 9:memcpy(eregs[i].value, &VU1.VF[eregs[i].number], 16);break;
174 case 10:memcpy(eregs[i].value, &VU1.VI[eregs[i].number], 4);break;
175 default:
176 eregs[0].value[0]++;//dummy; might be assert(0)
177 }
178 break;
179 case 0x06://ok
180 sprintf(line, "%s/PUTREG count=%d kind[0]=%d number[0]=%d value=%016I64X_%016I64X",
181 in->id==0?"CPU":in->id==1?"VU0":"VU1", in->count, eregs[0].kind, eregs[0].number, eregs[0].value[1], eregs[0].value[0]);
182 if (in->h.destination=='I'){
183 for (i=0; i<in->count; i++)
184 switch (iregs[i].kind){
185 case 1:switch (iregs[i].number){
186 case 0:psxRegs.GPR.n.lo=iregs[i].value;break;
187 case 1:psxRegs.GPR.n.hi=iregs[i].value;break;
188 }
189 break;
190 case 2:psxRegs.GPR.r[iregs[i].number]=iregs[i].value; break;
191 case 3:
192 psxRegs.CP0.r[iregs[i].number]=iregs[i].value;
193 if (iregs[i].number==14) psxRegs.pc=psxRegs.CP0.n.EPC;
194 break;
195 case 6:psxRegs.CP2D.r[iregs[i].number]=iregs[i].value; break;
196 case 7:psxRegs.CP2C.r[iregs[i].number]=iregs[i].value; break;
197 default:
198 ;//dummy; might be assert(0)
199 }
200 }else
201 for (i=0; i<in->count; i++)
202 switch (eregs[i].kind){
203 case 0:memcpy(&cpuRegs.GPR.r[eregs[i].number], eregs[i].value, 16);break;
204 case 1:
205 switch(eregs[i].number){
206 case 0:memcpy(&cpuRegs.HI.UD[0], eregs[i].value, 8);break;
207 case 1:memcpy(&cpuRegs.LO.UD[0], eregs[i].value, 8);break;
208 case 2:memcpy(&cpuRegs.HI.UD[1], eregs[i].value, 8);break;
209 case 3:memcpy(&cpuRegs.LO.UD[1], eregs[i].value, 8);break;
210 case 4:memcpy(&cpuRegs.sa, eregs[i].value, 4); break;
211 }
212 break;
213 case 2:
214 memcpy(&cpuRegs.CP0.r[eregs[i].number], eregs[i].value, 4);
215 if (eregs[i].number==14) cpuRegs.pc=cpuRegs.CP0.n.EPC;
216 break;
217 case 3:break;//performance counter 32x3
218 case 4:break;//hw debug reg 32x8
219 case 5:memcpy(&fpuRegs.fpr[eregs[i].number], eregs[i].value, 4);break;
220 case 6:memcpy(&fpuRegs.fprc[eregs[i].number], eregs[i].value, 4);break;
221 case 7:memcpy(&VU0.VF[eregs[i].number], eregs[i].value, 16);break;
222 case 8:memcpy(&VU0.VI[eregs[i].number], eregs[i].value, 4);break;
223 case 9:memcpy(&VU1.VF[eregs[i].number], eregs[i].value, 16);break;
224 case 10:memcpy(&VU1.VI[eregs[i].number], eregs[i].value, 4);break;
225 default:
226 ;//dummy; might be assert(0)
227 }
228 break;
229 case 0x08://ok
230 {
231 sprintf(line, "%s/RDMEM %08X/%X",
232 in->id==0?"CPU":in->id==1?"VU0":"VU1", mem->address, mem->length);
233 u8* data =(u8*)out+ //kids: don't try this at home! :D
234 ((sizeof(DECI2_DBGP_HEADER)+sizeof(DECI2_DBGP_MEM)+(1 << mem->align) - 1) & (0xFFFFFFFF << mem->align));
235
236 if ((mem->address & ((1 << mem->align)-1)) ||
237 (mem->length & ((1 << mem->align)-1))){
238 out->result=1;
239 strcat(line, " ALIGN ERROR");
240 break;
241 }
242 if (in->h.destination=='I')
243 if (iopVirtMemR<void>(mem->address & 0x1FFFFFFF))
244 memcpy(data, iopVirtMemR<void>(mem->address & 0x1FFFFFFF), mem->length);
245 else{
246 out->result=0x11;
247 strcat(line, " ADDRESS ERROR");
248 break;
249 }
250 else
251 {
252 switch(mem->space){
253 case 0:
254 if ((mem->address & 0xF0000000) == 0x70000000)
255 memcpy(data, PSM(mem->address), mem->length);
256 else
257 if ((((mem->address & 0x1FFFFFFF)>128*1024*1024) || ((mem->address & 0x1FFFFFFF)<32*1024*1024)) && PSM(mem->address & 0x1FFFFFFF))
258 memcpy(data, PSM(mem->address & 0x1FFFFFFF), mem->length);
259 else{
260 out->result=0x11;
261 strcat(line, " ADDRESS ERROR");
262 }
263 break;
264 case 1:
265 if (in->id==1)
266 memcpy(data, &VU0.Mem[mem->address & 0xFFF], mem->length);
267 else
268 memcpy(data, &VU1.Mem[mem->address & 0x3FFF], mem->length);
269 break;
270 case 2:
271 if (in->id==1)
272 memcpy(data, &VU0.Micro[mem->address & 0xFFF], mem->length);
273 else
274 memcpy(data, &VU1.Micro[mem->address & 0x3FFF], mem->length);
275 break;
276 }
277 }
278 out->h.length=mem->length+data-(u8*)out;
279 break;
280 }
281
282 case 0x0a://ok
283 {
284 sprintf(line, "%s/WRMEM %08X/%X",
285 in->id==0?"CPU":in->id==1?"VU0":"VU1", mem->address, mem->length);
286 const u8* data=(u8*)in+ //kids: don't try this at home! :D
287 ((sizeof(DECI2_DBGP_HEADER)+sizeof(DECI2_DBGP_MEM)+(1 << mem->align) - 1) & (0xFFFFFFFF << mem->align));
288 if (mem->length==4 && *(int*)data==0x0000000D)
289 strcat(line, " BREAKPOINT");
290 if ((mem->address & ((1 << mem->align)-1)) ||
291 (mem->length & ((1 << mem->align)-1))){
292 out->result=1;
293 strcat(line, " ALIGN ERROR");
294 break;
295 }
296 if (in->h.destination=='I')
297 if (iopVirtMemR<void>(mem->address & 0x1FFFFFFF))
298 memcpy( (void*)iopVirtMemR<void>(mem->address & 0x1FFFFFFF), data, mem->length);
299 else{
300 out->result=0x11;
301 strcat(line, " ADDRESS ERROR");
302 break;
303 }
304 else
305 switch(mem->space){
306 case 0:
307 if ((mem->address & 0xF0000000) == 0x70000000)
308 memcpy(PSM(mem->address), data, mem->length);
309 else
310 if (PSM(mem->address & 0x1FFFFFFF))
311 memcpy(PSM(mem->address & 0x1FFFFFFF), data, mem->length);
312 else{
313 out->result=0x11;
314 strcat(line, " ADDRESS ERROR");
315 }
316 break;
317 case 1:
318 if (in->id==1)
319 memcpy(&VU0.Mem[mem->address & 0xFFF], data, mem->length);
320 else
321 memcpy(&VU1.Mem[mem->address & 0x3FFF], data, mem->length);
322 break;
323 case 2:
324 if (in->id==1)
325 memcpy(&VU0.Micro[mem->address & 0xFFF], data, mem->length);
326 else
327 memcpy(&VU1.Micro[mem->address & 0x3FFF], data, mem->length);
328 break;
329 }
330 out->h.length=sizeof(DECI2_DBGP_HEADER)+sizeof(DECI2_DBGP_MEM);
331 break;
332 }
333 case 0x10://ok
334 {
335 sprintf(line, "%s/GETBRKPT count=%d",
336 in->id==0?"CPU":in->id==1?"VU0":"VU1", in->count);
337 if (in->h.destination=='I') memcpy(&out[1], ibrk, out->count=ibrk_count);
338 else memcpy(&out[1], ebrk, out->count=ebrk_count);
339 out->h.length=sizeof(DECI2_DBGP_HEADER)+out->count*sizeof(DECI2_DBGP_BRK);
340 break;
341 }
342 case 0x12://ok [does not break on iop brkpts]
343 sprintf(line, "%s/PUTBRKPT count=%d",
344 in->id==0?"CPU":in->id==1?"VU0":"VU1", in->count);
345 out->h.length=sizeof(DECI2_DBGP_HEADER);
346 if (in->count>32){
347 out->result=1;
348 strcat(line, "TOO MANY");
349 break;
350 }
351 if (in->h.destination=='I') memcpy(ibrk, &out[1], ibrk_count=in->count);
352 else memcpy(ebrk, &out[1], ebrk_count=in->count);
353 out->count=0;
354 break;
355 case 0x14://ok, [w/o iop]
356 sprintf(line, "%s/BREAK count=%d",
357 in->id==0?"CPU":in->id==1?"VU0":"VU1", in->count);
358 if (in->h.destination=='I')
359 ;
360 else{
361 out->result = ( pcsx2_InterlockedExchange(&runStatus, STOP)==STOP ?
362 0x20 : 0x21 );
363 out->code=0xFF;
364 Sleep(50);
365 }
366 break;
367 case 0x16://ok, [w/o iop]
368 sprintf(line, "%s/CONTINUE code=%s count=%d",
369 in->id==0?"CPU":in->id==1?"VU0":"VU1",
370 in->code==0?"CONT":in->code==1?"STEP":"NEXT", in->count);
371 if (in->h.destination=='I')
372 ;
373 else{
374 pcsx2_InterlockedExchange(&runStatus, STOP);
375 Sleep(100);//first get the run thread to Wait state
376 runCount=in->count;
377 runCode=in->code;
378 runEvent->Post();//kick it
379 }
380 break;
381 case 0x18://ok [without argc/argv stuff]
382 {
383 sprintf(line, "%s/RUN code=%d count=%d entry=0x%08X gp=0x%08X argc=%d",
384 in->id==0?"CPU":in->id==1?"VU0":"VU1", in->code, in->count,
385 run->entry, run->gp, run->argc);
386 cpuRegs.CP0.n.EPC=cpuRegs.pc=run->entry;
387 cpuRegs.GPR.n.gp.UL[0]=run->gp;
388 // threads_array[0].argc = run->argc;
389 u32* argv = (u32*)&run[1];
390 for (i=0, s=0; i<(int)run->argc; i++, argv++) s+=argv[i];
391 memcpy(PSM(0), argv, s);
392 // threads_array[0].argstring = 0;
393 pcsx2_InterlockedExchange((volatile long*)&runStatus, (u32)STOP);
394 Sleep(1000);//first get the run thread to Wait state
395 runCount=0;
396 runCode=0xFF;
397 runEvent->Post();
398 out->h.length=sizeof(DECI2_DBGP_HEADER);
399 break;
400 }
401 default:
402 sprintf(line, "type=0x%02X code=%d count=%d [unknown]", in->type, in->code, in->count);
403 }
404 sprintf(message, "[DBGP %c->%c/%04X] %s", in->h.source, in->h.destination, in->h.length, line);
405 sprintf(eepc, "%08X", cpuRegs.pc);
406 sprintf(ioppc, "%08X", psxRegs.pc);
407 sprintf(eecy, "%d", cpuRegs.cycle);
408 sprintf(iopcy, "%d", psxRegs.cycle);
409 writeData(outbuffer);
410 }
411
412 void sendBREAK(u8 source, u16 id, u8 code, u8 result, u8 count){
413 static DECI2_DBGP_HEADER tmp;
414 tmp.h.length =sizeof(DECI2_DBGP_HEADER);
415 tmp.h._pad =0;
416 tmp.h.protocol =( source=='E' ? PROTO_EDBGP : PROTO_IDBGP );
417 tmp.h.source =source;
418 tmp.h.destination='H';
419 tmp.id =id;
420 tmp.type =0x15;
421 tmp.code =code;
422 tmp.result =result;
423 tmp.count =count;
424 tmp._pad =0;
425 writeData((u8*)&tmp);
426 }

  ViewVC Help
Powered by ViewVC 1.1.22