Line 115... |
Line 115... |
#define MAP_UCLINUX (3)
|
#define MAP_UCLINUX (3)
|
|
|
t_map memory_maps[NUM_MEM_MAPS] = {
|
t_map memory_maps[NUM_MEM_MAPS] = {
|
{/* Experimental memory map (default) */
|
{/* Experimental memory map (default) */
|
{/* Bootstrap BRAM, read only */
|
{/* Bootstrap BRAM, read only */
|
{VECTOR_RESET, 0x00004800, 0xf8000000, 1, NULL, "Boot BRAM"},
|
{VECTOR_RESET, 0x00008000, 0xf8000000, 1, NULL, "Boot BRAM"},
|
/* main external ram block */
|
/* main external ram block */
|
{0x00000000, 0x00080000, 0xf8000000, 0, NULL, "XRAM0"},
|
{0x00000000, 0x00080000, 0xf8000000, 0, NULL, "XRAM0"},
|
/* main external ram block */
|
/* main external ram block */
|
{0x80000000, 0x00080000, 0xf8000000, 0, NULL, "XRAM1"},
|
{0x80000000, 0x00080000, 0xf8000000, 0, NULL, "XRAM1"},
|
/* external flash block */
|
/* external flash block */
|
Line 127... |
Line 127... |
}
|
}
|
},
|
},
|
|
|
{/* uClinux memory map with bootstrap BRAM, debug only, to be removed */
|
{/* uClinux memory map with bootstrap BRAM, debug only, to be removed */
|
{/* Bootstrap BRAM, read only */
|
{/* Bootstrap BRAM, read only */
|
{VECTOR_RESET, 0x00001000, 0xf8000000, 1, NULL, "Boot BRAM"},
|
{VECTOR_RESET, 0x00008000, 0xf8000000, 1, NULL, "Boot BRAM"},
|
/* main external ram block */
|
/* main external ram block */
|
{0x80000000, 0x00800000, 0xf8000000, 0, NULL, "XRAM0"},
|
{0x80000000, 0x00800000, 0xf8000000, 0, NULL, "XRAM0"},
|
{0x00000000, 0x00800000, 0xf8000000, 0, NULL, "XRAM1"},
|
{0x00000000, 0x00800000, 0xf8000000, 0, NULL, "XRAM1"},
|
/* external flash block */
|
/* external flash block */
|
{0xb0000000, 0x00100000, 0xf8000000, 0, NULL, "Flash"},
|
{0xb0000000, 0x00100000, 0xf8000000, 0, NULL, "Flash"},
|
}
|
}
|
},
|
},
|
|
|
{/* Experimental memory map with small XRAM */
|
{/* Experimental memory map with small XRAM */
|
{/* Bootstrap BRAM, read only */
|
{/* Bootstrap BRAM, read only */
|
{VECTOR_RESET, 0x00004800, 0xf8000000, 1, NULL, "Boot BRAM"},
|
{VECTOR_RESET, 0x00008000, 0xf8000000, 1, NULL, "Boot BRAM"},
|
/* main external ram block */
|
/* main external ram block */
|
{0x00000000, 0x00001000, 0xf8000000, 0, NULL, "XRAM0"},
|
{0x00000000, 0x00001000, 0xf8000000, 0, NULL, "XRAM0"},
|
/* main external ram block */
|
/* main external ram block */
|
{0x80000000, 0x00001000, 0xf8000000, 0, NULL, "XRAM1"},
|
{0x80000000, 0x00001000, 0xf8000000, 0, NULL, "XRAM1"},
|
/* external flash block */
|
/* external flash block */
|
Line 173... |
Line 173... |
typedef struct s_args {
|
typedef struct s_args {
|
/** !=0 to trap on unimplemented opcodes, 0 to print warning and NOP */
|
/** !=0 to trap on unimplemented opcodes, 0 to print warning and NOP */
|
uint32_t trap_on_reserved;
|
uint32_t trap_on_reserved;
|
/** !=0 to emulate some common mips32 opcodes */
|
/** !=0 to emulate some common mips32 opcodes */
|
uint32_t emulate_some_mips32;
|
uint32_t emulate_some_mips32;
|
|
/** Prescale value used for the timer/counter */
|
|
uint32_t timer_prescaler;
|
/** address to start execution from (by default, reset vector) */
|
/** address to start execution from (by default, reset vector) */
|
uint32_t start_addr;
|
uint32_t start_addr;
|
/** memory map to be used */
|
/** memory map to be used */
|
uint32_t memory_map;
|
uint32_t memory_map;
|
/** implement unaligned load/stores (don't just trap them) */
|
/** implement unaligned load/stores (don't just trap them) */
|
Line 272... |
Line 274... |
/* FIXME Refactor HW system params */
|
/* FIXME Refactor HW system params */
|
|
|
#define DBG_REGS (0x20010000)
|
#define DBG_REGS (0x20010000)
|
#define UART_WRITE (0x20000000)
|
#define UART_WRITE (0x20000000)
|
#define UART_READ (0x20000000)
|
#define UART_READ (0x20000000)
|
|
#define TIMER_READ (0x20000100)
|
|
|
|
#define DEFAULT_TIMER_PRESCALER (50)
|
|
|
/* FIXME The following addresses are remnants of Plasma to be removed */
|
/* FIXME The following addresses are remnants of Plasma to be removed */
|
#define IRQ_MASK 0x20000010
|
#define IRQ_MASK 0x20000010
|
#define IRQ_STATUS 0x20000020
|
#define IRQ_STATUS 0x20000020
|
#define CONFIG_REG 0x20000070
|
#define CONFIG_REG 0x20000070
|
Line 325... |
Line 330... |
uint32_t do_unaligned; /**< !=0 to enable unaligned L/S */
|
uint32_t do_unaligned; /**< !=0 to enable unaligned L/S */
|
uint32_t breakpoint; /**< BP address of 0xffffffff */
|
uint32_t breakpoint; /**< BP address of 0xffffffff */
|
|
|
int delay_slot; /**< !=0 if prev. instruction was a branch */
|
int delay_slot; /**< !=0 if prev. instruction was a branch */
|
uint32_t instruction_ctr; /**< # of instructions executed since reset */
|
uint32_t instruction_ctr; /**< # of instructions executed since reset */
|
|
uint32_t inst_ctr_prescaler; /**< Prescaler counter for instruction ctr. */
|
|
|
int r[32];
|
int r[32];
|
int opcode;
|
int opcode;
|
int pc, pc_next, epc;
|
int pc, pc_next, epc;
|
uint32_t op_addr; /**< address of opcode being simulated */
|
uint32_t op_addr; /**< address of opcode being simulated */
|
Line 534... |
Line 540... |
while(!kbhit());
|
while(!kbhit());
|
HWMemory[0] = getch();
|
HWMemory[0] = getch();
|
//s->irqStatus &= ~IRQ_UART_READ_AVAILABLE; //clear bit
|
//s->irqStatus &= ~IRQ_UART_READ_AVAILABLE; //clear bit
|
printf("%c", HWMemory[0]);
|
printf("%c", HWMemory[0]);
|
return (HWMemory[0] << 24) | 0x03;
|
return (HWMemory[0] << 24) | 0x03;
|
|
case TIMER_READ:
|
|
printf("TIMER = %10d\n", s->instruction_ctr);
|
|
return s->instruction_ctr;
|
|
break;
|
case IRQ_MASK:
|
case IRQ_MASK:
|
return HWMemory[1];
|
return HWMemory[1];
|
case IRQ_MASK + 4:
|
case IRQ_MASK + 4:
|
slite_sleep(10);
|
slite_sleep(10);
|
return 0;
|
return 0;
|
Line 969... |
Line 979... |
}
|
}
|
else{
|
else{
|
/* If there's any hardware interrupt pending, deal with it */
|
/* If there's any hardware interrupt pending, deal with it */
|
for(i=0;i<NUM_HW_IRQS;i++){
|
for(i=0;i<NUM_HW_IRQS;i++){
|
if(s->t.irq_trigger_countdown[i]==0){
|
if(s->t.irq_trigger_countdown[i]==0){
|
/* trigger interrupt i */
|
/* trigger interrupt i IF it is not masked */
|
/* FIXME handle irq mask(s) in SR */
|
if(s->status & (1 << (8 + i))){
|
//cause = 0; /* cause = hardware interrupt */
|
cause = 0; /* cause = hardware interrupt */
|
|
}
|
s->t.irq_trigger_countdown[i]--;
|
s->t.irq_trigger_countdown[i]--;
|
}
|
}
|
else if (s->t.irq_trigger_countdown[i]>0){
|
else if (s->t.irq_trigger_countdown[i]>0){
|
s->t.irq_trigger_countdown[i]--;
|
s->t.irq_trigger_countdown[i]--;
|
}
|
}
|
Line 1016... |
Line 1027... |
char format;
|
char format;
|
uint32_t aux;
|
uint32_t aux;
|
uint32_t target_offset16;
|
uint32_t target_offset16;
|
uint32_t target_long;
|
uint32_t target_long;
|
|
|
|
/* Update cycle counter (we implement an instruction counter actually )*/
|
|
s->inst_ctr_prescaler++;
|
|
if(s->inst_ctr_prescaler == (cmd_line_args.timer_prescaler-1)){
|
|
s->inst_ctr_prescaler = 0;
|
s->instruction_ctr++;
|
s->instruction_ctr++;
|
|
}
|
|
/* No traps pending for this instruction (yet) */
|
s->trap_cause = -1;
|
s->trap_cause = -1;
|
|
|
/* fetch and decode instruction */
|
/* fetch and decode instruction */
|
opcode = mem_read(s, 4, s->pc, 0);
|
opcode = mem_read(s, 4, s->pc, 0);
|
|
|
Line 1175... |
Line 1192... |
s->pc_next=r[rs]; break;
|
s->pc_next=r[rs]; break;
|
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];
|
s->pc_next=r[rs];
|
log_call(s->pc_next, epc); break;
|
log_call(s->pc_next, epc); break;
|
case 0x0a:/*MOVZ*/ if(!r[rt]) r[rd]=r[rs]; break; /*IV*/
|
case 0x0a:/*MOVZ*/ if(cmd_line_args.emulate_some_mips32){ /*IV*/
|
case 0x0b:/*MOVN*/ if(r[rt]) r[rd]=r[rs]; break; /*IV*/
|
if(!r[rt]) r[rd]=r[rs];
|
|
};
|
|
break;
|
|
case 0x0b:/*MOVN*/ if(cmd_line_args.emulate_some_mips32){ /*IV*/
|
|
if(r[rt]) r[rd]=r[rs];
|
|
};
|
|
break;
|
case 0x0c:/*SYSCALL*/ s->trap_cause = 8;
|
case 0x0c:/*SYSCALL*/ s->trap_cause = 8;
|
/*
|
/*
|
//FIXME enable when running uClinux
|
//FIXME enable when running uClinux
|
printf("SYSCALL (%08x)\n", s->pc);
|
printf("SYSCALL (%08x)\n", s->pc);
|
*/
|
*/
|
Line 1249... |
Line 1272... |
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(s->status & 0x02){ /* kernel mode? */
|
if(s->status & 0x02){ /* kernel mode? */
|
if(opcode==0x42000010){ // rfe
|
if(opcode==0x42000010){ // rfe
|
/* FIXME unimplemented yet */
|
/* restore ('pop') the KU/IE flag values */
|
|
s-> status = (s->status & 0xfffffff0) |
|
|
((s->status & 0x03c) >> 2);
|
}
|
}
|
else if((opcode & (1<<23)) == 0){ //move from CP0 (mfc0)
|
else if((opcode & (1<<23)) == 0){ //move from CP0 (mfc0)
|
//printf("mfc0: [%02d]=0x%08x @ [0x%08x]\n", rd, s->status, epc);
|
//printf("mfc0: [%02d]=0x%08x @ [0x%08x]\n", rd, s->status, epc);
|
switch(rd){
|
switch(rd){
|
case 12: r[rt]=s->status & 0x0000003f; break;
|
case 12: r[rt]=s->status & 0x0000ff3f; 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]=R3000_ID; break;
|
case 15: r[rt]=R3000_ID; break;
|
default:
|
default:
|
/* FIXME log access to unimplemented CP0 register */
|
/* FIXME log access to unimplemented CP0 register */
|
Line 1267... |
Line 1292... |
}
|
}
|
}
|
}
|
else{ //move to CP0 (mtc0)
|
else{ //move to CP0 (mtc0)
|
/* FIXME check CF= reg address */
|
/* FIXME check CF= reg address */
|
if(rd==12){
|
if(rd==12){
|
s->status=r[rt] & 0x0003003f; /* mask W/O bits */
|
s->status=r[rt] & 0x0003ff3f; /* mask W/O bits */
|
//printf("mtc0: [SR]=0x%08x @ [0x%08x]\n", s->status, epc);
|
//printf("mtc0: [SR]=0x%08x @ [0x%08x]\n", s->status, epc);
|
}
|
}
|
else{
|
else{
|
/* Move to unimplemented COP0 register: display warning */
|
/* Move to unimplemented COP0 register: display warning */
|
/* FIXME should log ignored move */
|
/* FIXME should log ignored move */
|
Line 2033... |
Line 2058... |
|
|
/* fill cmd line args with default values */
|
/* fill cmd line args with default values */
|
args->memory_map = MAP_DEFAULT;
|
args->memory_map = MAP_DEFAULT;
|
args->trap_on_reserved = 1;
|
args->trap_on_reserved = 1;
|
args->emulate_some_mips32 = 1;
|
args->emulate_some_mips32 = 1;
|
|
args->timer_prescaler = DEFAULT_TIMER_PRESCALER;
|
args->start_addr = VECTOR_RESET;
|
args->start_addr = VECTOR_RESET;
|
args->do_unaligned = 0;
|
args->do_unaligned = 0;
|
args->no_prompt = 0;
|
args->no_prompt = 0;
|
args->breakpoint = 0xffffffff;
|
args->breakpoint = 0xffffffff;
|
args->log_file_name = "sw_sim_log.txt";
|
args->log_file_name = "sw_sim_log.txt";
|