Line 367... |
Line 367... |
|
|
/*---- Local functions -------------------------------------------------------*/
|
/*---- Local functions -------------------------------------------------------*/
|
|
|
/** Log to file a memory read operation (not including target reg change) */
|
/** Log to file a memory read operation (not including target reg change) */
|
void log_read(t_state *s, int full_address, int word_value, int size, int log){
|
void log_read(t_state *s, int full_address, int word_value, int size, int log){
|
if(log_enabled(s) && log!=0){
|
/* if bit CP0.16==1, this is a D-Cache line invalidation access and
|
|
the HW will not read any actual data, so skip the log (@note1) */
|
|
if(log_enabled(s) && log!=0 && !(s->status & 0x00010000)){
|
fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD\n",
|
fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD\n",
|
s->op_addr, full_address, word_value);
|
s->op_addr, full_address, word_value);
|
}
|
}
|
}
|
}
|
|
|
Line 419... |
Line 421... |
break;
|
break;
|
}
|
}
|
}
|
}
|
if(!ptr){
|
if(!ptr){
|
/* address out of mapped blocks: log and return zero */
|
/* address out of mapped blocks: log and return zero */
|
if(log_enabled(s) && log!=0){
|
/* if bit CP0.16==1, this is a D-Cache line invalidation access and
|
|
the HW will not read any actual data, so skip the log (@note1) */
|
|
if(log_enabled(s) && log!=0 && !(s->status & (1<<16))){
|
fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD UNMAPPED\n",
|
fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD UNMAPPED\n",
|
s->pc, full_address, 0);
|
s->pc, full_address, 0);
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
Line 519... |
Line 523... |
printf("BUG: mem write size invalid (%08x)\n", s->pc);
|
printf("BUG: mem write size invalid (%08x)\n", s->pc);
|
exit(2);
|
exit(2);
|
}
|
}
|
|
|
fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR\n",
|
fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR\n",
|
s->op_addr, address&0xfffffffc, mask, dvalue);
|
//s->op_addr, address&0xfffffffc, mask, dvalue);
|
|
s->op_addr, address, mask, dvalue);
|
}
|
}
|
|
|
if((address&0xffff0000)==DBG_REGS){
|
if((address&0xffff0000)==DBG_REGS){
|
printf("[%04x]=%08x\n", address & 0xffff, value);
|
printf("[%04x]=%08x\n", address & 0xffff, value);
|
}
|
}
|
Line 831... |
Line 836... |
case 0x09:/*JALR*/ delay_slot=1;
|
case 0x09:/*JALR*/ delay_slot=1;
|
r[rd]=s->pc_next;
|
r[rd]=s->pc_next;
|
s->pc_next=r[rs]; break;
|
s->pc_next=r[rs]; break;
|
case 0x0a:/*MOVZ*/ if(!r[rt]) r[rd]=r[rs]; break; /*IV*/
|
case 0x0a:/*MOVZ*/ if(!r[rt]) r[rd]=r[rs]; break; /*IV*/
|
case 0x0b:/*MOVN*/ if(r[rt]) r[rd]=r[rs]; break; /*IV*/
|
case 0x0b:/*MOVN*/ if(r[rt]) r[rd]=r[rs]; break; /*IV*/
|
case 0x0c:/*SYSCALL*/ //trap_cause = 8;
|
case 0x0c:/*SYSCALL*/ trap_cause = 8;
|
//s->exceptionId=1;
|
s->exceptionId=1;
|
/*
|
/*
|
FIXME enable when running uClinux
|
FIXME enable when running uClinux
|
printf("SYSCALL (%08x)\n", s->pc);
|
printf("SYSCALL (%08x)\n", s->pc);
|
*/
|
*/
|
break;
|
break;
|
case 0x0d:/*BREAK*/ //trap_cause = 9;
|
case 0x0d:/*BREAK*/ trap_cause = 9;
|
//s->exceptionId=1;
|
s->exceptionId=1;
|
/*
|
/*
|
FIXME enable when running uClinux
|
FIXME enable when running uClinux
|
printf("BREAK (%08x)\n", s->pc);
|
printf("BREAK (%08x)\n", s->pc);
|
*/
|
*/
|
break;
|
break;
|
Line 905... |
Line 910... |
case 0x0e:/*XORI*/ r[rt]=r[rs]^imm; break;
|
case 0x0e:/*XORI*/ r[rt]=r[rs]^imm; break;
|
case 0x0f:/*LUI*/ r[rt]=(imm<<16); break;
|
case 0x0f:/*LUI*/ r[rt]=(imm<<16); break;
|
case 0x10:/*COP0*/
|
case 0x10:/*COP0*/
|
if((opcode & (1<<23)) == 0){ //move from CP0 (mfc0)
|
if((opcode & (1<<23)) == 0){ //move from CP0 (mfc0)
|
switch(rd){
|
switch(rd){
|
case 12: r[rt]=s->status; break;
|
case 12: r[rt]=s->status & 0xffff; break;
|
case 13: r[rt]=s->cp0_cause; break;
|
case 13: r[rt]=s->cp0_cause; break;
|
case 14: r[rt]=s->epc; break;
|
case 14: r[rt]=s->epc; break;
|
case 15: r[rt]=0x00000200; break;
|
case 15: r[rt]=0x00000200; break;
|
default:
|
default:
|
//printf("mfco [%02d]\n", rd);
|
//printf("mfco [%02d]\n", rd);
|
break;
|
break;
|
}
|
}
|
}
|
}
|
else{ //move to CP0 (mtc0)
|
else{ //move to CP0 (mtc0)
|
s->status=r[rt]&1;
|
/* FIXME check CF= reg address */
|
|
s->status=r[rt];
|
if(s->processId && (r[rt]&2)){
|
if(s->processId && (r[rt]&2)){
|
s->userMode|=r[rt]&2;
|
s->userMode|=r[rt]&2;
|
//printf("CpuStatus=%d %d %d\n", r[rt], s->status, s->userMode);
|
//printf("CpuStatus=%d %d %d\n", r[rt], s->status, s->userMode);
|
//s->wakeup = 1;
|
//s->wakeup = 1;
|
//printf("pc=0x%x\n", epc);
|
//printf("pc=0x%x\n", epc);
|
Line 984... |
Line 990... |
// case 0x3b:/*SWC3*/ break;
|
// case 0x3b:/*SWC3*/ break;
|
// case 0x3d:/*SDC1*/ break;
|
// case 0x3d:/*SDC1*/ break;
|
// case 0x3e:/*SDC2*/ break;
|
// case 0x3e:/*SDC2*/ break;
|
// case 0x3f:/*SDC3*/ break;
|
// case 0x3f:/*SDC3*/ break;
|
default:
|
default:
|
|
;
|
/* FIXME should trap unimplemented opcodes */
|
/* FIXME should trap unimplemented opcodes */
|
|
/* FIXME newlib */
|
printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);
|
printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);
|
s->wakeup=1;
|
s->wakeup=1;
|
}
|
}
|
|
|
/* adjust next PC if this was a ajump instruction */
|
/* adjust next PC if this was a ajump instruction */
|
Line 1345... |
Line 1353... |
|
|
/* if file logging is enabled, dump a trace log to file */
|
/* if file logging is enabled, dump a trace log to file */
|
if(log_enabled(s)){
|
if(log_enabled(s)){
|
log_pc = s->op_addr;
|
log_pc = s->op_addr;
|
|
|
for(i=0;i<32;i++){
|
/* skip register zero which does not change */
|
|
for(i=1;i<32;i++){
|
if(s->t.pr[i] != s->r[i]){
|
if(s->t.pr[i] != s->r[i]){
|
fprintf(s->t.log, "(%08X) [%02X]=%08X\n", log_pc, i, s->r[i]);
|
fprintf(s->t.log, "(%08X) [%02X]=%08X\n", log_pc, i, s->r[i]);
|
}
|
}
|
s->t.pr[i] = s->r[i];
|
s->t.pr[i] = s->r[i];
|
}
|
}
|
if(s->lo != s->t.lo){
|
if(s->lo != s->t.lo){
|
fprintf(s->t.log, "(%08X) [LO]=%08X\n", log_pc, s->lo);
|
//fprintf(s->t.log, "(%08X) [LO]=%08X\n", log_pc, s->lo);
|
}
|
}
|
s->t.lo = s->lo;
|
s->t.lo = s->lo;
|
|
|
if(s->hi != s->t.hi){
|
if(s->hi != s->t.hi){
|
fprintf(s->t.log, "(%08X) [HI]=%08X\n", log_pc, s->hi);
|
//fprintf(s->t.log, "(%08X) [HI]=%08X\n", log_pc, s->hi);
|
}
|
}
|
s->t.hi = s->hi;
|
s->t.hi = s->hi;
|
|
|
/* */
|
/* */
|
/* FIXME epc may change by direct write too, handle case */
|
/* FIXME epc may change by direct write too, handle case */
|