00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00155 #include "StdAfx.h"
00156
00157 #if defined(IDB)
00158 #include "TraceEngine.h"
00159 #include "AlphaCPU.h"
00160 #include "System.h"
00161 #include "DPR.h"
00162 #include "Flash.h"
00163 #include "lockstep.h"
00164 #include <signal.h>
00165
00166 CTraceEngine* trc;
00167
00176 inline void write_printable_s(char* dest, const char* org)
00177 {
00178 int cnt = 100;
00179 while(*org && cnt--)
00180 {
00181 *(dest++) = printable(*(org++));
00182 }
00183
00184 *dest = '\0';
00185 }
00186
00192 inline u64 real_address(u64 address, CAlphaCPU* c, bool bIBOX)
00193 {
00194 bool b;
00195 u64 a;
00196
00197 if(bIBOX && (address & 1))
00198 return address & U64(0xfffffffffffffffc);
00199
00200 if(!(c->virt2phys(address, &a, ACCESS_READ | NO_CHECK | FAKE, &b, 0)))
00201 return a & (bIBOX ? U64(0xfffffffffffffffc) : U64(0xffffffffffffffff));
00202
00203 return
00204 ((address & U64(0xfffffffff0000000)) == U64(0x0000000020000000)) ? address -
00205 U64(0x000000001fe00000) :
00206 (
00207 ((address & U64(0xfffffffff0000000)) == U64(0x0000000010000000)) ? address -
00208 U64(0x000000000fffe000) : address
00209 ) & (bIBOX ? U64(0xfffffffffffffffc) : U64(0xffffffffffffffff));
00210 }
00211
00215 CTraceEngine::CTraceEngine(CSystem* sys)
00216 {
00217 int i;
00218 iNumFunctions = 0;
00219 iNumPRBRs = 0;
00220 cSystem = sys;
00221 for(i = 0; i < 4; i++)
00222 {
00223 asCPUs[0].last_prbr = -1;
00224 }
00225
00226 current_trace_file = stdout;
00227 bBreakPoint = false;
00228 }
00229
00233 CTraceEngine::~CTraceEngine(void)
00234 {
00235 int i;
00236 for(i = 0; i < iNumPRBRs; i++)
00237 fclose(asPRBRs[i].f);
00238 }
00239
00251 void CTraceEngine::trace(CAlphaCPU* cpu, u64 f, u64 t, bool down, bool up,
00252 const char* x, int y)
00253 {
00254
00255 if((t == f + 4) || (t == f))
00256 return;
00257
00258
00259 int p = get_prbr(cpu->get_prbr(), cpu->get_hwpcb());
00260
00261
00262 int o = asCPUs[cpu->get_cpuid()].last_prbr;
00263
00264
00265 if(p != o)
00266 {
00267 if(o != -1)
00268 {
00269
00270
00271 fprintf(asPRBRs[o].f, "\n==> Switch to PRBR %08"LL "x %08"LL "x (%s)\n",
00272 asPRBRs[p].prbr, asPRBRs[p].hwpcb, asPRBRs[p].procname);
00273 fprintf(asPRBRs[p].f, " This is PRBR %08"LL "x %08"LL "x (%s)\n",
00274 asPRBRs[p].prbr, asPRBRs[p].hwpcb, asPRBRs[p].procname);
00275 fprintf(asPRBRs[p].f, "<== Switch from PRBR %08"LL "x %08"LL "x (%s)\n\n",
00276 asPRBRs[o].prbr, asPRBRs[o].hwpcb, asPRBRs[o].procname);
00277 }
00278
00279
00280 asCPUs[cpu->get_cpuid()].last_prbr = p;
00281 }
00282
00283
00284 if(asPRBRs[p].trc_waitfor)
00285 {
00286
00287 if((t &~U64(0x3)) == asPRBRs[p].trc_waitfor)
00288 asPRBRs[p].trc_waitfor = 0;
00289
00290
00291 return;
00292 }
00293
00294
00295 u64 pc_f = real_address(f, cpu, true);
00296 u64 pc_t = real_address(f, cpu, true);
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 int oldlvl = asPRBRs[p].trclvl;
00317 int i;
00318 int j;
00319
00320 if(up)
00321 {
00322
00323 for(i = oldlvl - 1; i >= 0; i--)
00324 {
00325
00326 if((asPRBRs[p].trcadd[i] == (pc_t - 4)) || (asPRBRs[p].trcadd[i] == (pc_t)))
00327 {
00328
00329 asPRBRs[p].trclvl = i;
00330
00331 if(asPRBRs[p].trchide > i)
00332 asPRBRs[p].trchide = -1;
00333
00334
00335 if(asPRBRs[p].trchide != -1)
00336 return;
00337
00338
00339 for(j = 0; j < oldlvl; j++)
00340 fprintf(asPRBRs[p].f, " ");
00341
00342
00343 fprintf(asPRBRs[p].f, "%016"LL "x(%08"LL "x) ($r0 = %"LL "x)\n", f,
00344 pc_f, cpu->get_r(0, true));
00345
00346
00347 for(j = 0; j < asPRBRs[p].trclvl; j++)
00348 fprintf(asPRBRs[p].f, " ");
00349
00350
00351 fprintf(asPRBRs[p].f, "%016"LL "x(%08"LL "x) <--\n", t, pc_t);
00352 return;
00353 }
00354 }
00355 }
00356
00357
00358 if(asPRBRs[p].trchide != -1)
00359 return;
00360
00361 if(!down)
00362 {
00363
00364 trace_br(cpu, f, t);
00365 return;
00366 }
00367
00368
00369 if(oldlvl < 700)
00370 asPRBRs[p].trclvl = oldlvl + 1;
00371
00372
00373 asPRBRs[p].trcadd[oldlvl] = pc_f;
00374
00375
00376 if(x)
00377 {
00378
00379 for(i = 0; i < oldlvl; i++)
00380 fprintf(asPRBRs[p].f, " ");
00381
00382
00383 fprintf(asPRBRs[p].f, x, y);
00384 fprintf(asPRBRs[p].f, "\n");
00385 }
00386
00387
00388 for(i = 0; i < oldlvl; i++)
00389 fprintf(asPRBRs[p].f, " ");
00390
00391
00392 fprintf(asPRBRs[p].f, "%016"LL "x(%08"LL "x) -->\n", f, pc_f);
00393
00394
00395 for(i = 0; i < asPRBRs[p].trclvl; i++)
00396 fprintf(asPRBRs[p].f, " ");
00397
00398
00399 for(i = 0; i < iNumFunctions; i++)
00400 {
00401 if(asFunctions[i].address == pc_t)
00402 {
00403
00404
00405
00406 fprintf(asPRBRs[p].f, "%016"LL "x(%s)", t, asFunctions[i].fn_name);
00407
00408
00409 write_arglist(cpu, asPRBRs[p].f, asFunctions[i].fn_arglist);
00410 fprintf(asPRBRs[p].f, "\n");
00411
00412
00413 if(asFunctions[i].step_over)
00414 asPRBRs[p].trchide = asPRBRs[p].trclvl;
00415 return;
00416 }
00417 }
00418
00419
00420
00421
00422 fprintf(asPRBRs[p].f, "%016"LL "x(%08"LL "x)", t, pc_t);
00423
00424
00425 write_arglist(cpu, asPRBRs[p].f, "(%s|16%, %s|17%, %s|18%, %s|19%)");
00426 fprintf(asPRBRs[p].f, "\n");
00427 }
00428
00438 void CTraceEngine::trace_br(CAlphaCPU* cpu, u64 f, u64 t)
00439 {
00440 int p;
00441 int o;
00442
00443
00444 u64 pc_f = real_address(f, cpu, true);
00445 u64 pc_t = real_address(t, cpu, true);
00446
00447
00448 p = get_prbr(cpu->get_prbr(), cpu->get_hwpcb());
00449
00450
00451 o = asCPUs[cpu->get_cpuid()].last_prbr;
00452
00453
00454 if(asPRBRs[p].trc_waitfor)
00455 {
00456
00457 if((t &~U64(0x3)) == asPRBRs[p].trc_waitfor)
00458 asPRBRs[p].trc_waitfor = 0;
00459
00460
00461 return;
00462 }
00463
00464
00465 if(asPRBRs[p].trchide != -1)
00466 return;
00467
00468
00469 if(p != o)
00470 {
00471 if(o != -1)
00472 {
00473
00474
00475 fprintf(asPRBRs[o].f, "\n==> Switch to PRBR %08"LL "x %08"LL "x (%s)\n",
00476 asPRBRs[p].prbr, asPRBRs[p].hwpcb, asPRBRs[p].procname);
00477 fprintf(asPRBRs[p].f, " This is PRBR %08"LL "x %08"LL "x (%s)\n",
00478 asPRBRs[p].prbr, asPRBRs[p].hwpcb, asPRBRs[p].procname);
00479 fprintf(asPRBRs[p].f, "<== Switch from PRBR %08"LL "x %08"LL "x (%s)\n\n",
00480 asPRBRs[o].prbr, asPRBRs[o].hwpcb, asPRBRs[o].procname);
00481 }
00482
00483
00484 asCPUs[cpu->get_cpuid()].last_prbr = p;
00485 }
00486
00487 int i;
00488
00489
00490 if((pc_t > pc_f + 4) || (pc_t < pc_f))
00491 {
00492
00493 for(i = 0; i < asPRBRs[p].trclvl; i++)
00494 fprintf(asPRBRs[p].f, " ");
00495
00496
00497 fprintf(asPRBRs[p].f, "%016"LL "x(%08"LL "x) --+\n", f, pc_f);
00498
00499
00500 for(i = 0; i < asPRBRs[p].trclvl; i++)
00501 fprintf(asPRBRs[p].f, " ");
00502
00503
00504 for(i = 0; i < iNumFunctions; i++)
00505 {
00506 if(asFunctions[i].address == pc_t)
00507 {
00508
00509
00510
00511 fprintf(asPRBRs[p].f, "%016"LL "x(%s)", t, asFunctions[i].fn_name);
00512
00513
00514 write_arglist(cpu, asPRBRs[p].f, asFunctions[i].fn_arglist);
00515 fprintf(asPRBRs[p].f, " <-+\n");
00516
00517
00518 if(asFunctions[i].step_over)
00519 asPRBRs[p].trchide = asPRBRs[p].trclvl;
00520 return;
00521 }
00522 }
00523
00524
00525 fprintf(asPRBRs[p].f, "%016"LL "x(%08"LL "x) <-+\n", t, pc_t);
00526 }
00527 }
00528
00532 void CTraceEngine::add_function(u64 address, const char* fn_name, const char* fn_arglist,
00533 bool step_over)
00534 {
00535 asFunctions[iNumFunctions].address = (u32) address &~3;
00536 asFunctions[iNumFunctions].fn_name = _strdup(fn_name);
00537 asFunctions[iNumFunctions].fn_arglist = _strdup(fn_arglist);
00538 asFunctions[iNumFunctions].step_over = step_over;
00539 iNumFunctions++;
00540 }
00541
00545 void CTraceEngine::set_waitfor(CAlphaCPU* cpu, u64 address)
00546 {
00547 int p;
00548 p = get_prbr(cpu->get_prbr(), cpu->get_hwpcb());
00549
00550 if(asPRBRs[p].trc_waitfor == 0)
00551 asPRBRs[p].trc_waitfor = address &~U64(0x3);
00552 }
00553
00557 bool CTraceEngine::get_fnc_name(CAlphaCPU* c, u64 address, char ** p_fn_name)
00558 {
00559 int i;
00560
00561 u64 a = real_address(address, c, true);
00562
00563 for(i = 0; i < iNumFunctions; i++)
00564 {
00565 if(asFunctions[i].address == a)
00566 {
00567 *p_fn_name = asFunctions[i].fn_name;
00568 return true;
00569 }
00570 }
00571
00572 *p_fn_name = (char*) 0;
00573 return false;
00574 }
00575
00579 int CTraceEngine::get_prbr(u64 prbr, u64 hwpcb)
00580 {
00581 int i;
00582 char filename[100];
00583
00584 for(i = 0; i < iNumPRBRs; i++)
00585 {
00586 if((asPRBRs[i].prbr == prbr) && (asPRBRs[i].hwpcb == hwpcb))
00587 {
00588 if(asPRBRs[i].f == current_trace_file)
00589 return i;
00590 if(!strncmp(asPRBRs[i].procname, cSystem->PtrToMem(prbr + 0x154), 20))
00591 {
00592 current_trace_file = asPRBRs[i].f;
00593 return i;
00594 }
00595
00596 fclose(asPRBRs[i].f);
00597 break;
00598 }
00599 }
00600
00601 if(i == iNumPRBRs)
00602 {
00603 asPRBRs[i].generation = 0;
00604 iNumPRBRs++;
00605 }
00606
00607 asPRBRs[i].generation++;
00608
00609 asPRBRs[i].prbr = prbr;
00610 asPRBRs[i].hwpcb = hwpcb;
00611 if(prbr > 0 && prbr < (U64(0x1) << cSystem->get_memory_bits()))
00612 strncpy(asPRBRs[i].procname, cSystem->PtrToMem(prbr + 0x154), 20);
00613 else
00614 strcpy(asPRBRs[i].procname, "");
00615 sprintf(filename, "trace_%08"LL "x_%08"LL "x_%02d_%s.trc", prbr, hwpcb,
00616 asPRBRs[i].generation, asPRBRs[i].procname);
00617 asPRBRs[i].f = fopen(filename, "w");
00618 if(asPRBRs[i].f == 0)
00619 printf("Failed to open file!!\n");
00620 asPRBRs[i].trclvl = 0;
00621 asPRBRs[i].trchide = -1;
00622 asPRBRs[i].trc_waitfor = 0;
00623 current_trace_file = asPRBRs[i].f;
00624 printf("Add PRBR: %08"LL "x_%08"LL "x\n", prbr, hwpcb);
00625 return i;
00626 }
00627
00632 void CTraceEngine::write_arglist(CAlphaCPU* c, FILE* fl, const char* a)
00633 {
00634 char o[500];
00635 char* op = o;
00636 const char* ap = a;
00637 char f[20];
00638 char* fp;
00639 char* rp;
00640 int r;
00641 u64 value;
00642
00643 while(*ap)
00644 {
00645 if(*ap == '%')
00646 {
00647 ap++;
00648 fp = f;
00649 *(fp++) = '%';
00650 while(*ap != '%')
00651 *(fp++) = *(ap++);
00652 ap++;
00653 *fp = '\0';
00654
00655
00656 rp = strchr(f, '|');
00657 *(rp++) = '\0';
00658
00659
00660 r = atoi(rp);
00661 value = c->get_r(r, true);
00662 if(!strcmp(f, "%s"))
00663 {
00664 sprintf(op, "%"LL "x (", value);
00665 while(*op)
00666 op++;
00667 value = real_address(value, c, false);
00668 if((value > 0) && (value < (U64(0x1) << cSystem->get_memory_bits())))
00669 write_printable_s(op, cSystem->PtrToMem(value));
00670 else
00671 sprintf(op, "INVPTR");
00672 while(*op)
00673 op++;
00674 *(op++) = ')';
00675 *(op) = '\0';
00676 }
00677 else if(!strcmp(f, "%c"))
00678 sprintf(op, "%02"LL "x (%c)", value, printable((char) value));
00679 else if(!strcmp(f, "%d"))
00680 sprintf(op, "%"LL "d", value);
00681 else if(!strcmp(f, "%x"))
00682 sprintf(op, "%"LL "x", value);
00683 else if(!strcmp(f, "%0x"))
00684 sprintf(op, "%016"LL "x", value);
00685 else if(!strcmp(f, "%016x"))
00686 sprintf(op, "%016"LL "x", value);
00687 else if(!strcmp(f, "%08x"))
00688 sprintf(op, "%08"LL "x", value);
00689 else if(!strcmp(f, "%04x"))
00690 sprintf(op, "%04"LL "x", value);
00691 else if(!strcmp(f, "%02x"))
00692 sprintf(op, "%02"LL "x", value);
00693 else
00694 sprintf(op, f, value);
00695 while(*op)
00696 op++;
00697 }
00698 else
00699 {
00700 *(op++) = *(ap++);
00701 }
00702 }
00703
00704 *op = '\0';
00705
00706 fprintf(fl, "%s", o);
00707 }
00708
00713 void CTraceEngine::read_procfile(const char* filename)
00714 {
00715 FILE* f;
00716 u64 address;
00717 char linebuffer[1000];
00718 char* fn_name;
00719 char* fn_args;
00720 char* sov;
00721 int step_over;
00722 int result;
00723 int i = 0;
00724
00725 f = fopen(filename, "r");
00726
00727 if(f)
00728 {
00729 while(fscanf(f, "%[^\n] ", linebuffer) != EOF)
00730 {
00731 address = U64(0x0);
00732 fn_name = strchr(linebuffer, ';');
00733 if(fn_name)
00734 {
00735 *fn_name = '\0';
00736 fn_name++;
00737 result = sscanf(linebuffer, "%"LL "x", &address);
00738 if((result == 1) && address)
00739 {
00740 fn_args = strchr(fn_name, ';');
00741 if(fn_args)
00742 {
00743 *fn_args = '\0';
00744 fn_args++;
00745 sov = strchr(fn_args, ';');
00746 if(sov)
00747 {
00748 *sov = '\0';
00749 sov++;
00750 result = sscanf(sov, "%d", &step_over);
00751 if(result == 1)
00752 {
00753 add_function(address, fn_name, fn_args, step_over ? true : false);
00754 i++;
00755 }
00756 }
00757 }
00758 }
00759 }
00760 }
00761
00762 fclose(f);
00763 printf("%%IDB-I-RDTRC : Read %d entries from trace-file %s\n", i, filename);
00764 }
00765 }
00766
00770 void CTraceEngine::trace_dev(const char* text)
00771 {
00772 fprintf(current_trace_file, "%s", text);
00773 }
00774
00778 FILE* CTraceEngine::trace_file()
00779 {
00780 return current_trace_file;
00781 }
00782
00786 void CTraceEngine::run_script(const char* filename)
00787 {
00788 char s[100][100];
00789 int i;
00790
00791 #if !defined(LS_SLAVE)
00792 char c = '\0';
00793 int j;
00794 FILE* f = NULL;
00795
00796 if(filename)
00797 {
00798 f = fopen(filename, "r");
00799 if(!f)
00800 {
00801 printf("%%IDB-F-NOLOAD: File %s could not be opened.\n", filename);
00802 return;
00803 }
00804 }
00805 else
00806 {
00807 printf("This is the ES40 interactive debugger. To start non-interactively, run es40,\n");
00808 printf("Or run this executable (es40_idb) with a last argument of @<script-file>\n");
00809 f = stdin;
00810 }
00811 #endif
00812 for(;;)
00813 {
00814 #if !defined(LS_SLAVE)
00815 if(filename)
00816 {
00817 if(feof(f))
00818 break;
00819 }
00820 else
00821 {
00822 printf("IDB %016"LL "x %c>", theSystem->get_cpu(0)->get_clean_pc(),
00823 (theSystem->get_cpu(0)->get_pc() & U64(0x1)) ? 'P' : '-');
00824 }
00825 #endif
00826 for(i = 0; i < 100;)
00827 {
00828 #if defined(LS_SLAVE)
00829 lockstep_receive(s[i], 100);
00830 if(!strcmp(s[i], "TERM"))
00831 break;
00832 #else
00833 bool u = false;
00834 for(j = 0; j < 100;)
00835 {
00836 fscanf(f, "%c", &c);
00837 if(c != '\n' && c != '\r' && c != ' ' && c != '\t')
00838 {
00839 s[i][j++] = c;
00840 u = true;
00841 }
00842
00843 if(c == ' ' || c == '\t' || c == '\n')
00844 break;
00845 }
00846
00847 s[i][j] = '\0';
00848
00849 if(u)
00850 #endif
00851 {
00852 #if defined(LS_MASTER)
00853 lockstep_send(s[i]);
00854 #endif
00855 i++;
00856 }
00857
00858 #if !defined(LS_SLAVE)
00859 if(c == '\n')
00860 {
00861 #if defined(LS_MASTER)
00862 lockstep_send("TERM");
00863 #endif
00864 break;
00865 }
00866 #endif
00867 }
00868
00869 s[i][0] = '\0';
00870 if(parse(s))
00871 break;
00872 }
00873
00874 #if !defined(LS_SLAVE)
00875 if(filename)
00876 fclose(f);
00877 #endif
00878 }
00879
00883 int CTraceEngine::parse(char command[100][100])
00884 {
00885 int i = 0;
00886 int numargs;
00887 int result;
00888 int RunCycles;
00889 u64 iFrom;
00890 u64 iTo;
00891 u64 iJump;
00892
00893 for(numargs = 0; command[numargs][0] != '\0'; numargs++);
00894
00895 if((numargs > 0) && (command[0][0] == '#' || command[0][0] == ';'
00896 || command[0][0] == '!' || (command[0][0] == '/' && command[0][1] == '/')))
00897
00898
00899 return 0;
00900 switch(numargs)
00901 {
00902 case 0:
00903
00904
00905 return 0;
00906
00907 case 1:
00908 if(!strncasecmp(command[0], "EXIT", strlen(command[0]))
00909 || !strncasecmp(command[0], "QUIT", strlen(command[0]))) return 1;
00910 if(!strncasecmp(command[0], "HELP", strlen(command[0]))
00911 || !strncasecmp(command[0], "?", strlen(command[0])))
00912 {
00913 printf(" \n");
00914 printf("Available commands: \n");
00915 printf(" HELP | ? \n");
00916 printf(" EXIT | QUIT \n");
00917 printf(" STEP \n");
00918 printf(" TRACE [ ON | OFF ] \n");
00919 printf(" HASHING [ ON | OFF ] \n");
00920 printf(" BREAKPOINT [ OFF | [ > | < | = | INSTRUCTION ] <hex value> ] \n");
00921 printf(" DISASSEMBLE [ON | OFF ] \n");
00922 #if defined(DEBUG_TB)
00923 printf(" TBDEBUG [ON | OFF ] \n");
00924 #endif
00925 printf(" LIST [ ALL |<hex address> - <hex address> ] \n");
00926 printf(" RUN [ <max cycles> ] \n");
00927 printf(" LOAD [ STATE | DPR | FLASH | CSV ] <file> \n");
00928 printf(" SAVE [ STATE | DPR | FLASH ] <file> \n");
00929 printf(" JUMP <hex address> \n");
00930 printf(" PAL [ ON | OFF ] \n");
00931 printf(" DUMPREGS \n");
00932 printf(" LOADREG <register> <value> \n");
00933 printf(" LOADFPREG <register> <value> \n");
00934 printf(" @<script-file> \n");
00935 printf(" # | // | ; | ! <comment> \n");
00936 printf(" \n");
00937 printf("The words of each command can be abbreviated, e.g. B or BRE for \n");
00938 printf("BREAKPOINT; S F for save flash. \n");
00939 printf(" \n");
00940 return 0;
00941 }
00942
00943 if(!strncasecmp(command[0], "STEP", strlen(command[0])))
00944 {
00945 printf("%%IDB-I-SSTEP : Single step.\n");
00946 theSystem->SingleStep();
00947 return 0;
00948 }
00949
00950 if(!strncasecmp(command[0], "DUMPREGS", strlen(command[0])))
00951 {
00952 printf("\n==================== SYSTEM STATE =======================\n");
00953 printf("PC: %"LL "x\n", theSystem->get_cpu(0)->get_pc());
00954 printf("Physical PC: %"LL "x\n",
00955 theSystem->get_cpu(0)->get_current_pc_physical());
00956 printf("Instruction count: %"LL "d\n",
00957 theSystem->get_cpu(0)->get_instruction_count());
00958 printf("\n==================== REGISTER VALUES ====================\n");
00959 for(i = 0; i < 32; i++)
00960 {
00961 if(i < 10)
00962 printf("R");
00963 printf("%d:%016"LL "x", i, theSystem->get_cpu(0)->get_r(i, false));
00964 if(i % 4 == 3)
00965 printf("\n");
00966 else
00967 printf(" ");
00968 }
00969
00970 printf("\n");
00971 for(i = 4; i < 8; i++)
00972 {
00973 if(i < 10)
00974 printf("S");
00975 printf("%d:%016"LL "x", i, theSystem->get_cpu(0)->get_r(i + 32, false));
00976 if(i % 4 == 3)
00977 printf("\n");
00978 else
00979 printf(" ");
00980 }
00981
00982 for(i = 20; i < 24; i++)
00983 {
00984 if(i < 10)
00985 printf("S");
00986 printf("%d:%016"LL "x", i, theSystem->get_cpu(0)->get_r(i + 32, false));
00987 if(i % 4 == 3)
00988 printf("\n");
00989 else
00990 printf(" ");
00991 }
00992
00993 printf("\n");
00994 for(i = 0; i < 32; i++)
00995 {
00996 if(i < 10)
00997 printf("F");
00998 printf("%d:%016"LL "x", i, theSystem->get_cpu(0)->get_f(i));
00999 if(i % 4 == 3)
01000 printf("\n");
01001 else
01002 printf(" ");
01003 }
01004
01005 printf("=========================================================\n");
01006 return 0;
01007 }
01008
01009 if(!strncasecmp(command[0], "RUN", strlen(command[0])))
01010 {
01011 if(!bBreakPoint)
01012 {
01013 printf("%%IDB-F-NOBRKP: No breakpoint set, press Ctrl-C to end run.\n");
01014
01015
01016 extern int got_sigint;
01017 void sigint_handler(int);
01018 signal(SIGINT, &sigint_handler);
01019 while(!got_sigint)
01020 {
01021 theSystem->SingleStep();
01022 }
01023
01024 got_sigint = 0;
01025 return 0;
01026 }
01027
01028 printf("%%IDB-I-RUNBPT: Running until breakpoint found.\n");
01029 switch(iBreakPointMode)
01030 {
01031 case -1:
01032 for(i = 0;; i++)
01033 {
01034 if(theSystem->SingleStep())
01035 {
01036 printf("%%IDB-I-ABORT : Abort run requested (probably from serial port)\n");
01037 break;
01038 }
01039
01040 if(theSystem->get_cpu(0)->get_clean_pc() < iBreakPoint)
01041 {
01042 printf("%%IDB-I-BRKPT : Breakpoint encountered.\n");
01043 break;
01044 }
01045 }
01046 break;
01047
01048 case 0:
01049 for(i = 0;; i++)
01050 {
01051 if(theSystem->SingleStep())
01052 {
01053 printf("%%IDB-I-ABORT : Abort run requested (probably from serial port)\n");
01054 break;
01055 }
01056
01057 if(theSystem->get_cpu(0)->get_clean_pc() == iBreakPoint)
01058 {
01059 printf("%%IDB-I-BRKPT : Breakpoint encountered.\n");
01060 break;
01061 }
01062 }
01063 break;
01064
01065 case 1:
01066 for(i = 0;; i++)
01067 {
01068 if(theSystem->SingleStep())
01069 {
01070 printf("%%IDB-I-ABORT : Abort run requested (probably from serial port)\n");
01071 break;
01072 }
01073
01074 if(theSystem->get_cpu(0)->get_clean_pc() > iBreakPoint)
01075 {
01076 printf("%%IDB-I-BRKPT : Breakpoint encountered.\n");
01077 break;
01078 }
01079 }
01080 break;
01081
01082 case 2:
01083
01084
01085
01086 extern int got_sigint;
01087
01088 void sigint_handler(int);
01089 signal(SIGINT, &sigint_handler);
01090 while(1)
01091 {
01092 theSystem->SingleStep();
01093 if(theSystem->get_cpu(0)->get_last_instruction()
01094 == iBreakPointInstruction || got_sigint)
01095 {
01096 printf("%%IDB-I-BRKPT: Found trapped instruction or control-c\n");
01097 break;
01098 }
01099 }
01100
01101 got_sigint = 0;
01102 break;
01103
01104 default:
01105 break;
01106 }
01107
01108 printf("%%IDB-I-ENDRUN: End of run.\n");
01109 return 0;
01110 }
01111
01112 #if !defined(IDB) || !defined(LS_SLAVE)
01113 if(command[0][0] == '@')
01114 {
01115 run_script(command[0] + 1);
01116 return 0;
01117 }
01118 #endif // !defined(IDB) || !defined(LS_SLAVE)
01119 break;
01120
01121 case 2:
01122 if(!strncasecmp(command[0], "LIST", strlen(command[0]))
01123 && !strncasecmp(command[1], "ALL", strlen(command[1])))
01124 {
01125 list_all();
01126 return 0;
01127 }
01128
01129 if(!strncasecmp(command[0], "TRACE", strlen(command[0])))
01130 {
01131 if(!strcasecmp(command[1], "ON"))
01132 {
01133 printf("%%IDB-I-TRCON : Tracing enabled.\n");
01134 bTrace = true;
01135 return 0;
01136 }
01137
01138 if(!strcasecmp(command[1], "OFF"))
01139 {
01140 printf("%%IDB-I-TRCOFF: Tracing disabled.\n");
01141 bTrace = false;
01142 return 0;
01143 }
01144 }
01145
01146 #if defined(DEBUG_TB)
01147 if(!strncasecmp(command[0], "TBDEBUG", strlen(command[0])))
01148 {
01149 if(!strcasecmp(command[1], "ON"))
01150 {
01151 printf("%%IDB-I-TBDON : Translation Buffer Debugging enabled.\n");
01152 bTB_Debug = true;
01153 return 0;
01154 }
01155
01156 if(!strcasecmp(command[1], "OFF"))
01157 {
01158 printf("%%IDB-I-TBDOFF: Translation Buffer Debugging disabled.\n");
01159 bTB_Debug = false;
01160 return 0;
01161 }
01162 }
01163 #endif
01164 if(!strncasecmp(command[0], "HASHING", strlen(command[0])))
01165 {
01166 if(!strcasecmp(command[1], "ON"))
01167 {
01168 printf("%%IDB-I-HSHON : Hashing enabled.\n");
01169 bHashing = true;
01170 return 0;
01171 }
01172
01173 if(!strcasecmp(command[1], "OFF"))
01174 {
01175 printf("%%IDB-I-HSHOFF: Hashing disabled.\n");
01176 bHashing = false;
01177 return 0;
01178 }
01179 }
01180
01181 if(!strncasecmp(command[0], "PAL", strlen(command[0])))
01182 {
01183 if(!strcasecmp(command[1], "ON"))
01184 {
01185 printf("%%IDB-I-PALON : PALmode enabled.\n");
01186 theSystem->get_cpu(0)->set_pc(theSystem->get_cpu(0)->get_clean_pc() + 1);
01187 return 0;
01188 }
01189
01190 if(!strcasecmp(command[1], "OFF"))
01191 {
01192 printf("%%IDB-I-PALOFF: PALmode disabled.\n");
01193 theSystem->get_cpu(0)->set_pc(theSystem->get_cpu(0)->get_clean_pc());
01194 return 0;
01195 }
01196 }
01197
01198 if(!strncasecmp(command[0], "DISASSEMBLE", strlen(command[0])))
01199 {
01200 if(!strcasecmp(command[1], "ON"))
01201 {
01202 printf("%%IDB-I-DISON : Disassembling enabled.\n");
01203 bDisassemble = true;
01204 return 0;
01205 }
01206
01207 if(!strcasecmp(command[1], "OFF"))
01208 {
01209 printf("%%IDB-I-DISOFF: Disassembling disabled.\n");
01210 bDisassemble = false;
01211 return 0;
01212 }
01213 }
01214
01215 if(!strncasecmp(command[0], "BREAKPOINT", strlen(command[0])))
01216 {
01217 if(!strncasecmp(command[1], "OFF", strlen(command[1])))
01218 {
01219 printf("%%IDB-I-BRKOFF: Breakpoint disabled.\n");
01220 bBreakPoint = false;
01221 return 0;
01222 }
01223 }
01224
01225 if(!strncasecmp(command[0], "RUN", strlen(command[0])))
01226 {
01227 result = sscanf(command[1], "%d", &RunCycles);
01228 if(result != 1)
01229 {
01230 printf("%%IDB-F-INVVAL: Invalid decimal value.\n");
01231 return 0;
01232 }
01233
01234 if(bBreakPoint)
01235 {
01236 printf("%%IDB-I-RUNCBP: Running until breakpoint found or max cycles reached.\n");
01237 switch(iBreakPointMode)
01238 {
01239 case -1:
01240 for(i = 0; i < RunCycles; i++)
01241 {
01242 if(theSystem->SingleStep())
01243 {
01244 printf("%%IDB-I-ABORT : Abort run requested (probably from serial port)\n");
01245 break;
01246 }
01247
01248 if(theSystem->get_cpu(0)->get_clean_pc() < iBreakPoint)
01249 {
01250 printf("%%IDB-I-BRKPT : Breakpoint encountered.\n");
01251 break;
01252 }
01253 }
01254 break;
01255
01256 case 0:
01257 for(i = 0; i < RunCycles; i++)
01258 {
01259 if(theSystem->SingleStep())
01260 {
01261 printf("%%IDB-I-ABORT : Abort run requested (probably from serial port)\n");
01262 break;
01263 }
01264
01265 if(theSystem->get_cpu(0)->get_clean_pc() == iBreakPoint)
01266 {
01267 printf("%%IDB-I-BRKPT : Breakpoint encountered.\n");
01268 break;
01269 }
01270 }
01271 break;
01272
01273 case 1:
01274 for(i = 0; i < RunCycles; i++)
01275 {
01276 if(theSystem->SingleStep())
01277 {
01278 printf("%%IDB-I-ABORT : Abort run requested (probably from serial port)\n");
01279 break;
01280 }
01281
01282 if(theSystem->get_cpu(0)->get_clean_pc() > iBreakPoint)
01283 {
01284 printf("%%IDB-I-BRKPT : Breakpoint encountered.\n");
01285 break;
01286 }
01287 }
01288 break;
01289
01290 case 2:
01291 for(i = 0; i < RunCycles; i++)
01292 {
01293 if(theSystem->SingleStep())
01294 {
01295 printf("%%IDB-I-ABORT : Abort run requested (probably from serial port)\n");
01296 break;
01297 }
01298
01299 if(theSystem->get_cpu(0)->get_last_instruction()
01300 == iBreakPointInstruction)
01301 {
01302 printf("%%IDB-I-BRKPT: Found trapped instruction\n");
01303 break;
01304 }
01305 }
01306 break;
01307
01308 default:
01309 break;
01310 }
01311 }
01312 else
01313 {
01314 printf("%%IDB-I-RUNCYC: Running until max cycles reached.\n");
01315
01316 extern int got_sigint;
01317 void sigint_handler(int);
01318 signal(SIGINT, &sigint_handler);
01319 for(i = 0; i < RunCycles; i++)
01320 {
01321 if(theSystem->SingleStep())
01322 {
01323 printf("%%IDB-I-ABORT : Abort run requested (probably from serial port)\n");
01324 break;
01325 }
01326
01327 if(got_sigint)
01328 break;
01329 }
01330
01331 got_sigint = 0;
01332 }
01333
01334 printf("%%IDB-I-ENDRUN: End of run.\n");
01335 return 0;
01336 }
01337
01338 if(!strncasecmp(command[0], "JUMP", strlen(command[0])))
01339 {
01340 result = sscanf(command[1], "%"LL "x", &iJump);
01341 if(result != 1)
01342 {
01343 printf("%%IDB-F-INVVAL: Invalid hexadecimal value.\n");
01344 return 0;
01345 }
01346
01347 if(iJump & U64(0x3))
01348 {
01349 printf("%%IDB-F-ALGVAL: Value not aligned on a 4-byte bounday.\n");
01350 return 0;
01351 }
01352
01353 printf("%%IDB-I-JUMPTO: Jumping.\n");
01354 theSystem->get_cpu(0)->set_pc(iJump + (theSystem->get_cpu(0)->get_pc() & U64(0x1)));
01355 return 0;
01356 }
01357 break;
01358
01359 case 3:
01360 if(!strncasecmp(command[0], "BREAKPOINT", strlen(command[0])))
01361 {
01362 if(!strcmp(command[1], "=") || !strcmp(command[1], ">")
01363 || !strcmp(command[1], "<"))
01364 {
01365 result = sscanf(command[2], "%"LL "x", &iBreakPoint);
01366 if(result != 1)
01367 {
01368 printf("%%IDB-F-INVVAL: Invalid hexadecimal value.\n");
01369 bBreakPoint = false;
01370 return 0;
01371 }
01372
01373 if(iBreakPoint & U64(0x3))
01374 {
01375 printf("%%IDB-F-ALGVAL: Value not aligned on a 4-byte bounday.\n");
01376 bBreakPoint = false;
01377 return 0;
01378 }
01379
01380 switch(command[1][0])
01381 {
01382 case '=': iBreakPointMode = 0; break;
01383 case '>': iBreakPointMode = 1; break;
01384 case '<': iBreakPointMode = -1; break;
01385 }
01386
01387 printf("%%IDB-I-BRKSET: Breakpoint set when PC %c %016"LL "x.\n",
01388 command[1][0], iBreakPoint);
01389 bBreakPoint = true;
01390 return 0;
01391 }
01392 else
01393 {
01394 if(!strncasecmp(command[1], "INSTRUCTION", strlen(command[1])))
01395 {
01396 result = sscanf(command[2], "%"LL "x", &iBreakPointInstruction);
01397 if(result != 1)
01398 {
01399 printf("%%IDB-F-INVVAL: Invalid hexadecimal value.\n");
01400 bBreakPoint = false;
01401 return 0;
01402 }
01403
01404 printf("%%IDB-I-BRKSET: Breakpoint set when instruction %08x is executed.\n",
01405 iBreakPointInstruction);
01406 bBreakPoint = true;
01407 iBreakPointMode = 2;
01408 return 0;
01409 }
01410 }
01411 }
01412
01413 if(!strncasecmp(command[0], "LOAD", strlen(command[0])))
01414 {
01415 if(!strncasecmp(command[1], "CSV", strlen(command[1])))
01416 {
01417 read_procfile(command[2]);
01418 return 0;
01419 }
01420
01421 if(!strncasecmp(command[1], "STATE", strlen(command[1])))
01422 {
01423 theSystem->RestoreState(command[2]);
01424 return 0;
01425 }
01426
01427 if(!strncasecmp(command[1], "DPR", strlen(command[1])))
01428 {
01429 theDPR->RestoreStateF(command[2]);
01430 return 0;
01431 }
01432
01433 if(!strncasecmp(command[1], "FLASH", strlen(command[1])))
01434 {
01435 theSROM->RestoreStateF(command[2]);
01436 return 0;
01437 }
01438 }
01439
01440 if(!strncasecmp(command[0], "SAVE", strlen(command[0])))
01441 {
01442 if(!strncasecmp(command[1], "STATE", strlen(command[1])))
01443 {
01444 theSystem->SaveState(command[2]);
01445 return 0;
01446 }
01447
01448 if(!strncasecmp(command[1], "DPR", strlen(command[1])))
01449 {
01450 theDPR->SaveStateF(command[2]);
01451 return 0;
01452 }
01453
01454 if(!strncasecmp(command[1], "FLASH", strlen(command[1])))
01455 {
01456 theSROM->SaveStateF(command[2]);
01457 return 0;
01458 }
01459 }
01460
01461 if(!strncasecmp(command[0], "LOADREG", strlen(command[0])))
01462 {
01463 int reg;
01464 u64 value;
01465 result = sscanf(command[1], "%d", ®);
01466 if(result != 1 || reg > 31)
01467 {
01468 printf("%%IDB-F-INVREG: Invalid register number.\n");
01469 return 0;
01470 }
01471
01472 result = sscanf(command[2], "%"LL "x", &value);
01473 if(result != 1)
01474 {
01475 printf("%%IDB-F-INVVAL: Invalid hexadecimal value.\n");
01476 return 0;
01477 }
01478
01479 theSystem->get_cpu(0)->set_r(reg, value);
01480 return 0;
01481 }
01482
01483 if(!strncasecmp(command[0], "LOADFPREG", strlen(command[0])))
01484 {
01485 int reg;
01486 u64 value;
01487 result = sscanf(command[1], "%d", ®);
01488 if(result != 1 || reg > 31)
01489 {
01490 printf("%%IDB-F-INVREG: Invalid register number.\n");
01491 return 0;
01492 }
01493
01494 result = sscanf(command[2], "%"LL "x", &value);
01495 if(result != 1)
01496 {
01497 printf("%%IDB-F-INVVAL: Invalid hexadecimal value.\n");
01498 return 0;
01499 }
01500
01501 theSystem->get_cpu(0)->set_f(reg, value);
01502 return 0;
01503 }
01504 break;
01505
01506 case 4:
01507 if(!strncasecmp(command[0], "LIST", strlen(command[0]))
01508 && !strcmp(command[2], "-"))
01509 {
01510 result = sscanf(command[1], "%"LL "x", &iFrom);
01511 if(result == 1)
01512 result = sscanf(command[3], "%"LL "x", &iTo);
01513 if(result != 1)
01514 {
01515 printf("%%IDB-F-INVVAL: Invalid hexadecimal value.\n");
01516 return 0;
01517 }
01518
01519 if(iFrom & U64(0x3) || iTo & U64(0x3))
01520 {
01521 printf("%%IDB-F-ALGVAL: Value not aligned on a 4-byte bounday.\n");
01522 return 0;
01523 }
01524
01525 if(iFrom > iTo)
01526 {
01527 printf("%%IDB-F-FRLTTO: From value exceeds to value.\n");
01528 return 0;
01529 }
01530
01531 theSystem->get_cpu(0)->listing(iFrom, iTo);
01532 return 0;
01533 }
01534 break;
01535
01536 default:
01537 break;
01538 }
01539
01540 printf("%%IDB-F-SYNTAX: Syntax error. Type \"?\" or \"HELP\" for help.\n");
01541 return 0;
01542 }
01543
01544 struct sRegion
01545 {
01546 u64 from;
01547 u64 to;
01548 struct sRegion* pNext;
01549 };
01550
01554 void CTraceEngine::list_all()
01555 {
01556 struct sRegion* pR = NULL;
01557 struct sRegion ** ppN = &pR;
01558 struct sRegion* p = NULL;
01559 int f = 0;
01560 int t = 0;
01561 int ms = 1 << (theSystem->get_memory_bits() - 3);
01562 u64* pM = (u64*) theSystem->PtrToMem(0);
01563
01564 for(;;)
01565 {
01566 while
01567 (
01568 (!pM[f] || pM[f] == U64(0xefefefefefefefef) || pM[f] == U64(0xffffffffffffffff))
01569 && f < ms
01570 )
01571 {
01572 f++;
01573 if(!(f & 0x1ffff))
01574 printf(".");
01575 }
01576
01577 if(f >= ms)
01578 break;
01579 t = f;
01580 for(;;)
01581 {
01582 while
01583 (
01584 pM[t]
01585 && pM[t] != U64(0xefefefefefefefef)
01586 && pM[t] != U64(0xffffffffffffffff)
01587 && t < ms
01588 )
01589 {
01590 t++;
01591 if(!(t & 0x1ffff))
01592 printf("x");
01593 }
01594
01595 if(t + 3 < ms)
01596 {
01597 if((!pM[t + 1] || pM[t + 1] == U64(0xefefefefefefefef)
01598 || pM[t + 1] == U64(0xffffffffffffffff)) && (!pM[t + 2]
01599 || pM[t + 2] == U64(0xefefefefefefefef)
01600 || pM[t + 2] == U64(0xffffffffffffffff)) && (!pM[t + 3]
01601 || pM[t + 3] == U64(0xefefefefefefefef)
01602 || pM[t + 3] == U64(0xffffffffffffffff)))
01603 break;
01604 }
01605
01606 if(t >= ms)
01607 break;
01608 t++;
01609 if(!(t & 0x1ffff))
01610 printf("x");
01611 }
01612
01613 *ppN = new sRegion;
01614 (*ppN)->from = (u64) f * 8;
01615 (*ppN)->to = (u64) ((t - 1) * 8) + 4;
01616 (*ppN)->pNext = NULL;
01617 ppN = &((*ppN)->pNext);
01618 f = t;
01619 }
01620
01621 printf("\n");
01622
01623 p = pR;
01624
01625 while(p)
01626 {
01627 printf("\n======== DISASSEMBLING %08"LL "x TO %08"LL "x ========\n\n",
01628 p->from, p->to);
01629 theSystem->get_cpu(0)->listing(p->from, p->to);
01630 p = p->pNext;
01631 }
01632 }
01633
01634 bool bTrace = false;
01635 bool bDisassemble = false;
01636 bool bHashing = false;
01637 bool bListing = false;
01638
01639 #if defined(DEBUG_TB)
01640 bool bTB_Debug = false;
01641 #endif
01642 #endif // IDB