Line 76... |
Line 76... |
static int gdb_read(void*,int);
|
static int gdb_read(void*,int);
|
static int gdb_write(void*,int);
|
static int gdb_write(void*,int);
|
void BlockJTAG(void);
|
void BlockJTAG(void);
|
|
|
#ifndef DEBUGMOD_OFF
|
#ifndef DEBUGMOD_OFF
|
int NewStyleExceptions = 1; /* Start off with the new style exception handlers */
|
|
/* This means GDB will expect the PC at 0xD00 when a
|
|
a breakpoint occurs, and will intercept AFTER the
|
|
exception vector is taken. */
|
|
int GlobalMode = 0; /* Start off in the orginal mode */
|
int GlobalMode = 0; /* Start off in the orginal mode */
|
#else /* no DEBUGMOD_OFF */
|
#else /* no DEBUGMOD_OFF */
|
#define GlobalMode 0
|
#define GlobalMode 0
|
#endif /* no DEBUGMOD_OFF */
|
#endif /* no DEBUGMOD_OFF */
|
|
|
/* CVS revision number. */
|
/* CVS revision number. */
|
const char rcsrev[] = "$Revision: 1.25 $";
|
const char rcsrev[] = "$Revision: 1.26 $";
|
|
|
/* Continuos run versus single step tracing switch. */
|
/* Continuos run versus single step tracing switch. */
|
int cont_run;
|
int cont_run;
|
|
|
/* History of execution */
|
/* History of execution */
|
Line 237... |
Line 233... |
char *redirstr;
|
char *redirstr;
|
int hush;
|
int hush;
|
unsigned long endaddr = 0xFFFFFFFF;
|
unsigned long endaddr = 0xFFFFFFFF;
|
int first_prompt = 1;
|
int first_prompt = 1;
|
int trace_fd = 0;
|
int trace_fd = 0;
|
unsigned char trace_reg[32];
|
|
|
|
memset(trace_reg,'\0',sizeof(trace_reg));
|
|
srand(getpid());
|
srand(getpid());
|
init_defconfig();
|
init_defconfig();
|
if (parse_args(argc, argv)) {
|
if (parse_args(argc, argv)) {
|
printf("Usage: %s [options] <filename>\n", argv[0]);
|
printf("Usage: %s [options] <filename>\n", argv[0]);
|
printf("Options:\n");
|
printf("Options:\n");
|
Line 287... |
Line 281... |
printf("Problems opening profile file. Profiling disabled. \n");
|
printf("Problems opening profile file. Profiling disabled. \n");
|
} else
|
} else
|
fprintf(config.fprof, "+00000000 FFFFFFFF FFFFFFFF main\n");
|
fprintf(config.fprof, "+00000000 FFFFFFFF FFFFFFFF main\n");
|
}
|
}
|
|
|
|
/* Initialize memory table. */
|
|
|
|
|
|
sim_read_memory_table ("sim_memory_table");
|
print_config();
|
print_config();
|
signal(SIGINT, ctrl_c);
|
signal(SIGINT, ctrl_c);
|
initstats();
|
initstats();
|
build_automata();
|
build_automata();
|
|
|
Line 302... |
Line 300... |
a real CPU would. This should maximize the reality of
|
a real CPU would. This should maximize the reality of
|
the capabilities. In this mode, we will expect that
|
the capabilities. In this mode, we will expect that
|
someone will attach to us over the JTAG Proxy interface
|
someone will attach to us over the JTAG Proxy interface
|
and begin debugging that way. */
|
and begin debugging that way. */
|
|
|
if(config.filename)
|
if(config.filename) {
|
{
|
endaddr = loadcode(config.filename, 0, 0); /* MM170901 always load at address zero. */
|
endaddr = loadcode(config.filename, MEMORY_START, 0);
|
|
if (endaddr == -1) {
|
if (endaddr == -1) {
|
printf("Problems loading boot code.\n");
|
printf("Problems loading boot code.\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
}
|
} else {
|
else
|
extern struct dev_memarea *dev_list;
|
{
|
int i;
|
if(config.random_mem)
|
if(config.random_mem) {
|
{
|
|
int n = 0;
|
|
int len = sizeof(mem);
|
|
unsigned int* mptr = (unsigned int*)mem;
|
|
unsigned int val = 0;
|
unsigned int val = 0;
|
int seed = time(NULL);
|
int seed = time(NULL);
|
|
|
srandom(seed);
|
srandom(seed);
|
/* Print out the seed just in case we ever need to debug */
|
/* Print out the seed just in case we ever need to debug */
|
printf("Seeding random generator with value %d\n",seed);
|
printf("Seeding random generator with value %d\n",seed);
|
|
|
for(n=0;n<len;n+=sizeof(unsigned int))
|
for (cur_area = dev_list; cur_area; cur_area = cur_area->next)
|
{
|
for(i = 0; i < cur_area->size; i++) {
|
val = random();
|
val = random();
|
if(random() > RAND_MAX/2)
|
if(random() > RAND_MAX/2)
|
val |= 0x80000000;
|
val |= 0x80000000;
|
*mptr++ = val;
|
cur_area->writefunc(i + cur_area->start, val);
|
}
|
|
}
|
}
|
else if(config.pattern_mem)
|
} else if(config.pattern_mem) {
|
{
|
for (cur_area = dev_list; cur_area; cur_area = cur_area->next)
|
int n = 0;
|
for(i = 0; i < cur_area->size; i++)
|
int len = sizeof(mem);
|
cur_area->writefunc(i + cur_area->start, config.pattern_mem);
|
unsigned int* mptr = (unsigned int*)mem;
|
} else {
|
|
for (cur_area = dev_list; cur_area; cur_area = cur_area->next)
|
for(n=0;n<len;n+=sizeof(unsigned int))
|
for(i = 0; i < cur_area->size; i++)
|
*mptr++ = config.pattern_mem;
|
cur_area->writefunc(i + cur_area->start, 0);
|
}
|
}
|
else
|
|
memset(mem,0,sizeof(mem));
|
|
|
|
if(config.memory)
|
if(config.memory) {
|
{
|
|
MemoryBlock* block = config.memory;
|
MemoryBlock* block = config.memory;
|
|
|
while(block)
|
while(block) {
|
{
|
|
int fd = open(block->file,O_RDONLY);
|
int fd = open(block->file,O_RDONLY);
|
int len,i;
|
int len, i, j, mptr = 0;
|
struct stat buf;
|
struct stat buf;
|
char *mptr = (char*)mem;
|
|
char buffer[8192];
|
char buffer[8192];
|
|
|
if(fd < 0)
|
if(fd < 0)
|
{
|
{
|
perror(block->file);
|
perror(block->file);
|
Line 394... |
Line 381... |
case 0:
|
case 0:
|
fprintf(stderr,"File \"%s\": premature end of file.\n",
|
fprintf(stderr,"File \"%s\": premature end of file.\n",
|
block->file);
|
block->file);
|
exit(1);
|
exit(1);
|
default:
|
default:
|
memcpy(mptr,buffer,n);
|
for (j = 0; j < n; j++)
|
|
setsim_mem8(mptr++,buffer[j]);
|
i+= n;
|
i+= n;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
close(fd);
|
close(fd);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
#ifndef DEBUGMOD_OFF
|
#ifndef DEBUGMOD_OFF
|
GlobalMode = config.filename == NULL; /* Old mode = 0, New mode = 1 */
|
GlobalMode = config.filename == NULL; /* Old mode = 0, New mode = 1 */
|
#endif
|
#endif
|
|
|
uart_reset();
|
uart_reset();
|
dma_reset();
|
dma_reset();
|
tick_reset();
|
tick_reset();
|
pm_reset();
|
pm_reset();
|
pic_reset();
|
pic_reset();
|
mtspr(2,0x20); /* We are emulating a 32 bit processor/no FP */
|
|
reset();
|
reset();
|
if(!GlobalMode) /* Only in old mode */
|
if(!GlobalMode) /* Only in old mode */
|
set_reg32(3, endaddr);
|
set_reg32(3, endaddr);
|
|
|
while(1) {
|
while(1) {
|
Line 633... |
Line 621... |
cont_run = -1;
|
cont_run = -1;
|
hush = 1;
|
hush = 1;
|
} else
|
} else
|
if (!strcmp(item1, "trace")) { /* Added by CZ 210801 */
|
if (!strcmp(item1, "trace")) { /* Added by CZ 210801 */
|
char item2[256];
|
char item2[256];
|
char item3[256];
|
|
char *s,*q;
|
|
|
|
strtoken(linestr, item2, 2);
|
strtoken(linestr, item2, 2);
|
strtoken(linestr, item3, 3);
|
|
if(trace_fd)
|
if(trace_fd)
|
{
|
{
|
close(trace_fd);
|
close(trace_fd);
|
trace_fd = 0;
|
trace_fd = 0;
|
memset(trace_reg,'\0',sizeof(trace_reg));
|
|
}
|
}
|
if(strcmp(item2,"off")) /* if we're not being turned off */
|
if(strcmp(item2,"off")) /* if we're not being turned off */
|
{
|
{
|
if(item2[0])
|
if(item2[0])
|
trace_fd = open(item2,O_CREAT | O_NOCTTY |
|
trace_fd = open(item2,O_CREAT | O_NOCTTY |
|
Line 657... |
Line 641... |
{
|
{
|
perror(item2[0]?item2:"stdout");
|
perror(item2[0]?item2:"stdout");
|
trace_fd = 0;
|
trace_fd = 0;
|
}
|
}
|
}
|
}
|
if(!trace_fd && strlen(item3))
|
|
printf("Syntax error on trace: \"%s\" unexpected\n",item3);
|
|
else
|
|
for(s = item3;s && *s; s = q)
|
|
{
|
|
if(q = strchr(s,','))
|
|
*q++ = '\0';
|
|
|
|
if(strlen(s) < 4 && (s[0] == 'r' || s[0] == 'R') &&
|
|
isdigit(s[1]) && (isdigit(s[2]) || !s[2]))
|
|
trace_reg[atoi(&s[1])] = 1;
|
|
else
|
|
printf("Syntax error in format: \"%s\" not a valid register\n",s);
|
|
}
|
|
|
|
} else
|
} else
|
if (strcmp(item1, "stats") == 0) { /* stats */
|
if (strcmp(item1, "stats") == 0) { /* stats */
|
char item2[20];
|
char item2[20];
|
int i = 0;
|
int i = 0;
|
|
|
Line 731... |
Line 700... |
decode_execute(&iqueue[0],trace_fd);
|
decode_execute(&iqueue[0],trace_fd);
|
if(trace_fd)
|
if(trace_fd)
|
{
|
{
|
char sTemp[256];
|
char sTemp[256];
|
char sTemp2[256];
|
char sTemp2[256];
|
char reg_value[16];
|
|
unsigned long value;
|
unsigned long value;
|
int first_register = 1;
|
|
int i;
|
|
extern char *disassembled;
|
extern char *disassembled;
|
extern unsigned long reg[];
|
extern unsigned long reg[];
|
|
|
value = (mem[0x0c].data << 24) +
|
/* The objects passed to the
|
(mem[0x0d].data << 16) +
|
trace command should not be
|
(mem[0x0e].data << 8)
|
hardcoded like this...instead
|
+ mem[0x0f].data;
|
what to dump should be passed
|
|
on the command line.
|
|
|
|
FIX THIS LATER...
|
|
*/
|
|
value = (evalsim_mem8(0x306bc) << 24) +
|
|
(evalsim_mem8(0x306bd) << 16) +
|
|
(evalsim_mem8(0x306be) << 8)
|
|
+ evalsim_mem8(0x306bf);
|
|
|
#if 0
|
|
sprintf(sTemp,"0x%06x: %s",addr,disassembled);
|
sprintf(sTemp,"0x%06x: %s",addr,disassembled);
|
memset(sTemp2,' ',80);
|
memset(sTemp2,' ',sizeof(sTemp2));
|
strncpy(sTemp2,sTemp,strlen(sTemp));
|
strncpy(sTemp2,sTemp,strlen(sTemp));
|
|
sprintf(&sTemp2[40],"<0x%08x,0x%08x> [0x%08x]\n",
|
sTemp[0] = '\0';
|
reg[3],reg[4],value);
|
sTemp2[78] = '\0';
|
|
for(i=0;i<32;i++)
|
|
if(trace_reg[i])
|
|
{
|
|
sprintf(reg_value,"%c0x%08x",first_register?'<':',',
|
|
reg[i]);
|
|
strcat(sTemp,reg_value);
|
|
first_register = 0;
|
|
}
|
|
if(!first_register)
|
|
sprintf(&sTemp2[40],"%s>\n",sTemp);
|
|
#endif
|
|
sprintf(sTemp2,"0x%06x: %s <0x%08x>\n",addr,disassembled,value);
|
|
write(trace_fd,sTemp2,strlen(sTemp2));
|
write(trace_fd,sTemp2,strlen(sTemp2));
|
}
|
}
|
update_pc();
|
update_pc();
|
analysis();
|
analysis();
|
if (!hush)
|
if (!hush)
|
Line 910... |
Line 870... |
extern char *disassembled;
|
extern char *disassembled;
|
void debugmem() {
|
void debugmem() {
|
int i;
|
int i;
|
printf("starting to dump mem...\n");
|
printf("starting to dump mem...\n");
|
for(i=0; i<500; i++) {
|
for(i=0; i<500; i++) {
|
printf("i=%x :: ", i);
|
struct mem_entry *entry;
|
if (mem[i].label)
|
|
printf("label: %s |", mem[i].label->name);
|
|
{
|
|
unsigned int _insn;
|
unsigned int _insn;
|
_insn = ((unsigned long)mem[i].data << 24);
|
printf("i=%x :: ", i);
|
_insn |= ((unsigned long)mem[i + 1].data << 16);
|
if (verify_memoryarea(i) && cur_area->getentry && (entry = cur_area->getentry(i)) && entry->label)
|
_insn |= ((unsigned long)mem[i + 2].data << 8);
|
printf("label: %s |", entry->label->name);
|
_insn |= ((unsigned long)mem[i + 3].data);
|
|
|
iqueue[0].insn = _insn = evalsim_mem32(i);
|
iqueue[0].insn_index = insn_decode(_insn);
|
iqueue[0].insn_index = insn_decode(_insn);
|
iqueue[0].insn = _insn;
|
|
disassemble_insn (_insn);
|
disassemble_insn (_insn);
|
printf("%s\n", disassembled);
|
printf("%08x %s\n", _insn, disassembled);
|
}
|
|
}
|
}
|
}
|
}
|
|
|
static int tcp_level = 0;
|
static int tcp_level = 0;
|
|
|
Line 1332... |
Line 1288... |
}
|
}
|
msg_bwrite->address = ntohl(msg_bwrite->address);
|
msg_bwrite->address = ntohl(msg_bwrite->address);
|
msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
|
msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
|
for(i=0;i<msg_bwrite->nRegisters;i++)
|
for(i=0;i<msg_bwrite->nRegisters;i++)
|
{
|
{
|
int t_err;
|
int t_err = 0;
|
|
|
msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
|
msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
|
t_err = DebugSetRegister(msg_bwrite->address+i,msg_bwrite->data[i]);
|
t_err = DebugSetRegister(msg_bwrite->address+i,msg_bwrite->data[i]);
|
err = err ? err : t_err;
|
err = err ? err : t_err;
|
}
|
}
|
Line 1402... |
Line 1358... |
free(buf);
|
free(buf);
|
return;
|
return;
|
}
|
}
|
free(buf);
|
free(buf);
|
buf = NULL;
|
buf = NULL;
|
buf = NULL;
|
resp_bread = NULL;
|
break;
|
break;
|
case JTAG_COMMAND_CHAIN:
|
case JTAG_COMMAND_CHAIN:
|
if(length != sizeof(msg_chain) - 8)
|
if(length != sizeof(msg_chain) - 8)
|
{
|
{
|
ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
|
ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
|