Line 137... |
Line 137... |
#define IRQ_COUNTER18 0x008
|
#define IRQ_COUNTER18 0x008
|
#define IRQ_MMU 0x200
|
#define IRQ_MMU 0x200
|
|
|
#define MMU_ENTRIES 4
|
#define MMU_ENTRIES 4
|
#define MMU_MASK (1024*4-1)
|
#define MMU_MASK (1024*4-1)
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/* These are flags that will be used to notify the main cycle function of any
|
|
failed assertions in its subfunctions. */
|
|
#define ASRT_UNALIGNED_READ (1<<0)
|
|
#define ASRT_UNALIGNED_WRITE (1<<1)
|
|
|
|
char *assertion_messages[2] = {
|
|
"Unaligned read",
|
|
"Unaligned write"
|
|
};
|
|
|
|
|
/** Length of debugging jump target queue */
|
/** Length of debugging jump target queue */
|
#define TRACE_BUFFER_SIZE (32)
|
#define TRACE_BUFFER_SIZE (32)
|
|
|
typedef struct {
|
typedef struct {
|
Line 158... |
Line 170... |
} MmuEntry;
|
} MmuEntry;
|
|
|
typedef struct {
|
typedef struct {
|
int load_delay_slot;
|
int load_delay_slot;
|
int delay;
|
int delay;
|
unsigned int delayed_reg;
|
unsigned delayed_reg;
|
int delayed_data;
|
int delayed_data;
|
|
|
|
unsigned failed_assertions; /**< assertion bitmap */
|
|
unsigned faulty_address; /**< addr that failed assertion */
|
|
|
int r[32];
|
int r[32];
|
int opcode;
|
int opcode;
|
int pc, pc_next, epc;
|
int pc, pc_next, epc;
|
unsigned int hi;
|
unsigned int hi;
|
unsigned int lo;
|
unsigned int lo;
|
int status;
|
int status;
|
int userMode;
|
int userMode;
|
int processId;
|
int processId;
|
int exceptionId;
|
int exceptionId; /**< DEPRECATED, to be removed */
|
int faultAddr;
|
int faultAddr;
|
int irqStatus;
|
int irqStatus;
|
int skip;
|
int skip;
|
Trace t;
|
Trace t;
|
unsigned char *mem;
|
unsigned char *mem;
|
Line 218... |
Line 234... |
void init_trace_buffer(State *s, const char *log_file_name);
|
void init_trace_buffer(State *s, const char *log_file_name);
|
void close_trace_buffer(State *s);
|
void close_trace_buffer(State *s);
|
void dump_trace_buffer(State *s);
|
void dump_trace_buffer(State *s);
|
void log_cycle(State *s);
|
void log_cycle(State *s);
|
void log_read(State *s, int full_address, int word_value, int size, int log);
|
void log_read(State *s, int full_address, int word_value, int size, int log);
|
|
void log_failed_assertions(State *s);
|
|
|
/* Hardware simulation */
|
/* Hardware simulation */
|
int mem_read(State *s, int size, unsigned int address, int log);
|
int mem_read(State *s, int size, unsigned int address, int log);
|
void mem_write(State *s, int size, int unsigned address, unsigned value);
|
void mem_write(State *s, int size, int unsigned address, unsigned value);
|
void start_load(State *s, int rt, int data);
|
void start_load(State *s, int rt, int data);
|
Line 293... |
Line 310... |
case 4:
|
case 4:
|
if(address & 3){
|
if(address & 3){
|
printf("Unaligned access PC=0x%x address=0x%x\n",
|
printf("Unaligned access PC=0x%x address=0x%x\n",
|
(int)s->pc, (int)address);
|
(int)s->pc, (int)address);
|
}
|
}
|
assert((address & 3) == 0);
|
/* We don't want the program to just quit, we want to log the fault */
|
|
/* assert((address & 3) == 0); */
|
|
if((address & 3) != 0){
|
|
s->failed_assertions |= ASRT_UNALIGNED_READ;
|
|
s->faulty_address = address;
|
|
address = address & 0xfffffffc;
|
|
}
|
value = *(int*)ptr;
|
value = *(int*)ptr;
|
if(s->big_endian)
|
if(s->big_endian)
|
value = ntohl(value);
|
value = ntohl(value);
|
break;
|
break;
|
case 2:
|
case 2:
|
assert((address & 1) == 0);
|
/* We don't want the program to just quit, we want to log the fault */
|
|
/* assert((address & 1) == 0); */
|
|
if((address & 1) != 0){
|
|
s->failed_assertions |= ASRT_UNALIGNED_READ;
|
|
s->faulty_address = address;
|
|
address = address & 0xfffffffe;
|
|
}
|
value = *(unsigned short*)ptr;
|
value = *(unsigned short*)ptr;
|
if(s->big_endian)
|
if(s->big_endian)
|
value = ntohs((unsigned short)value);
|
value = ntohs((unsigned short)value);
|
break;
|
break;
|
case 1:
|
case 1:
|
Line 400... |
Line 429... |
ptr += 1024*1024;
|
ptr += 1024*1024;
|
|
|
switch(size)
|
switch(size)
|
{
|
{
|
case 4:
|
case 4:
|
assert((address & 3) == 0);
|
/* We don't want the program to just quit, we want to log the fault */
|
|
/* assert((address & 3) == 0); */
|
|
if((address & 3) != 0){
|
|
s->failed_assertions |= ASRT_UNALIGNED_WRITE;
|
|
s->faulty_address = address;
|
|
address = address & (~0x03);
|
|
}
|
if(s->big_endian)
|
if(s->big_endian)
|
value = htonl(value);
|
value = htonl(value);
|
*(int*)ptr = value;
|
*(int*)ptr = value;
|
break;
|
break;
|
case 2:
|
case 2:
|
assert((address & 1) == 0);
|
/* We don't want the program to just quit, we want to log the fault */
|
|
/* assert((address & 1) == 0); */
|
|
if((address & 1) != 0){
|
|
s->failed_assertions |= ASRT_UNALIGNED_WRITE;
|
|
s->faulty_address = address;
|
|
address = address & (~0x01);
|
|
}
|
if(s->big_endian)
|
if(s->big_endian)
|
value = htons((unsigned short)value);
|
value = htons((unsigned short)value);
|
*(short*)ptr = (unsigned short)value;
|
*(short*)ptr = (unsigned short)value;
|
break;
|
break;
|
case 1:
|
case 1:
|
Line 723... |
Line 764... |
}
|
}
|
s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
|
s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
|
s->pc_next &= ~3;
|
s->pc_next &= ~3;
|
s->skip = (lbranch == 0) | skip2;
|
s->skip = (lbranch == 0) | skip2;
|
|
|
|
/* If there was trouble, log it */
|
|
if(s->failed_assertions!=0){
|
|
log_failed_assertions(s);
|
|
s->failed_assertions=0;
|
|
}
|
|
|
|
|
/* if there's a delayed load pending, do it now: load reg with memory data */
|
/* if there's a delayed load pending, do it now: load reg with memory data */
|
if(s->load_delay_slot){
|
if(s->load_delay_slot){
|
/*--- simulate real core's load interlock ---*/
|
/*--- simulate real core's load interlock ---*/
|
if(s->delay<=0){
|
if(s->delay<=0){
|
if(s->delayed_reg>0){
|
if(s->delayed_reg>0){
|
Line 965... |
Line 1013... |
/* NOTE: Original mlite supported loading little-endian code, which this
|
/* NOTE: Original mlite supported loading little-endian code, which this
|
program doesn't. The endianess-conversion code has been removed.
|
program doesn't. The endianess-conversion code has been removed.
|
*/
|
*/
|
|
|
/* Simulate a CPU reset */
|
/* Simulate a CPU reset */
|
s->pc = 0x0;
|
/* FIXME cpu reset function needed */
|
|
s->pc = 0x0; /* reset start vector */
|
|
s->failed_assertions = 0; /* no failed assertions pending */
|
|
|
/* FIXME PC fixup at address zero has to be removed */
|
/* FIXME PC fixup at address zero has to be removed */
|
index = mem_read(s, 4, 0, 0);
|
index = mem_read(s, 4, 0, 0);
|
if((index & 0xffffff00) == 0x3c1c1000){
|
if((index & 0xffffff00) == 0x3c1c1000){
|
s->pc = 0x10000000;
|
s->pc = 0x10000000;
|
}
|
}
|
Line 1065... |
Line 1116... |
if(s->t.log){
|
if(s->t.log){
|
fclose(s->t.log);
|
fclose(s->t.log);
|
}
|
}
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|
|
/** Logs a message for each failed assertion, each in a line */
|
|
void log_failed_assertions(State *s){
|
|
unsigned bitmap = s->failed_assertions;
|
|
int i = 0;
|
|
|
|
/* This loop will crash the program if the message table is too short...*/
|
|
if(s->t.log != NULL){
|
|
for(i=0;i<32;i++){
|
|
if(bitmap & 0x1){
|
|
fprintf(s->t.log, "ASSERTION FAILED: [%08x] %s\n",
|
|
s->faulty_address,
|
|
assertion_messages[i]);
|
|
}
|
|
bitmap = bitmap >> 1;
|
|
}
|
|
}
|
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|