OpenCores
URL https://opencores.org/ocsvn/ion/ion/trunk

Subversion Repositories ion

[/] [ion/] [trunk/] [tools/] [slite/] [src/] [slite.c] - Diff between revs 163 and 166

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 163 Rev 166
Line 38... Line 38...
*               Software 'as is' without warranty.  Author liable for nothing.
*               Software 'as is' without warranty.  Author liable for nothing.
*
*
* IMPORTANT: Assumes host is little endian and target is big endian.
* IMPORTANT: Assumes host is little endian and target is big endian.
*-----------------------------------------------------------------------------*/
*-----------------------------------------------------------------------------*/
 
 
 
#include <errno.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdint.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <ctype.h>
Line 125... Line 126...
 
 
    {/* 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,  0x00001000, 0xf8000000, 1, NULL, "Boot BRAM"},
        /* main external ram block  */
        /* main external ram block  */
        {0x80000000,    0x00200000, 0xf8000000, 0, NULL, "XRAM0"},
        {0x80000000,    0x00800000, 0xf8000000, 0, NULL, "XRAM0"},
        {0x00000000,    0x00400000, 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"},
        }
        }
    },
    },
 
 
Line 167... Line 168...
 
 
/** Values for the command line arguments */
/** Values for the command line arguments */
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 */
 
    uint32_t emulate_some_mips32;
    /** 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 184... Line 187...
    uint32_t log_trigger_address;
    uint32_t log_trigger_address;
    /** full name of log file */
    /** full name of log file */
    char *log_file_name;
    char *log_file_name;
    /** bin file to load to each area or null */
    /** bin file to load to each area or null */
    char *bin_filename[NUM_MEM_BLOCKS];
    char *bin_filename[NUM_MEM_BLOCKS];
 
    /** map file to be used for function call tracing, if any */
 
    char *map_filename;
    /** offset into area (in bytes) where bin wile will be loaded */
    /** offset into area (in bytes) where bin wile will be loaded */
    uint32_t offset[NUM_MEM_BLOCKS];
    uint32_t offset[NUM_MEM_BLOCKS];
} t_args;
} t_args;
/** Parse cmd line args globally accessible */
/** Parse cmd line args globally accessible */
t_args cmd_line_args;
t_args cmd_line_args;
Line 262... Line 267...
 
 
/* Much of this is a remnant from Plasma's mlite and is  no longer used. */
/* Much of this is a remnant from Plasma's mlite and is  no longer used. */
/* FIXME Refactor HW system params */
/* FIXME Refactor HW system params */
 
 
#define DBG_REGS          (0x20010000)
#define DBG_REGS          (0x20010000)
 
#define UART_WRITE        (0x20000000)
 
#define UART_READ         (0x20000000)
 
 
#define UART_WRITE        0x20000000
/* FIXME The following addresses are remnants of Plasma to be removed */
#define UART_READ         0x20000000
 
#define IRQ_MASK          0x20000010
#define IRQ_MASK          0x20000010
#define IRQ_STATUS        0x20000020
#define IRQ_STATUS        0x20000020
#define CONFIG_REG        0x20000070
#define CONFIG_REG        0x20000070
#define MMU_PROCESS_ID    0x20000080
#define MMU_PROCESS_ID    0x20000080
#define MMU_FAULT_ADDR    0x20000090
#define MMU_FAULT_ADDR    0x20000090
Line 320... Line 326...
   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 */
   unsigned int hi;
   unsigned int hi;
   unsigned int lo;
   unsigned int lo;
   int status;
   int status;
 
   int32_t trap_cause;          /**< temporary trap code or <0 if no trap */
   unsigned cp0_cause;
   unsigned cp0_cause;
   int userMode;                /**< DEPRECATED, to be removed */
   int userMode;                /**< DEPRECATED, to be removed */
   int processId;               /**< DEPRECATED, to be removed */
   int processId;               /**< DEPRECATED, to be removed */
   int exceptionId;             /**< DEPRECATED, to be removed */
 
   int faultAddr;               /**< DEPRECATED, to be removed */
   int faultAddr;               /**< DEPRECATED, to be removed */
   int irqStatus;               /**< DEPRECATED, to be removed */
   int irqStatus;               /**< DEPRECATED, to be removed */
   int skip;
   int skip;
   t_trace t;
   t_trace t;
   t_block blocks[NUM_MEM_BLOCKS];
   t_block blocks[NUM_MEM_BLOCKS];
Line 344... Line 350...
 
 
static char *opcode_string[]={
static char *opcode_string[]={
   "0SPECIAL","0REGIMM","1J","1JAL","2BEQ","2BNE","3BLEZ","3BGTZ",
   "0SPECIAL","0REGIMM","1J","1JAL","2BEQ","2BNE","3BLEZ","3BGTZ",
   "5ADDI","5ADDIU","5SLTI","5SLTIU","5ANDI","5ORI","5XORI","6LUI",
   "5ADDI","5ADDIU","5SLTI","5SLTIU","5ANDI","5ORI","5XORI","6LUI",
   "cCOP0","cCOP1","cCOP2","cCOP3","2BEQL","2BNEL","3BLEZL","3BGTZL",
   "cCOP0","cCOP1","cCOP2","cCOP3","2BEQL","2BNEL","3BLEZL","3BGTZL",
   "0?","0?","0?","0?","0?","0?","0?","0?",
   "0?","0?","0?","0?","0SPECIAL2","0?","0?","0SPECIAL3",
   "8LB","8LH","8LWL","8LW","8LBU","8LHU","8LWR","0?",
   "8LB","8LH","8LWL","8LW","8LBU","8LHU","8LWR","0?",
   "8SB","8SH","8SWL","8SW","0?","0?","8SWR","0CACHE",
   "8SB","8SH","8SWL","8SW","0?","0?","8SWR","0CACHE",
   "0LL","0LWC1","0LWC2","0LWC3","?","0LDC1","0LDC2","0LDC3"
   "0LL","0LWC1","0LWC2","0LWC3","?","0LDC1","0LDC2","0LDC3"
   "0SC","0SWC1","0SWC2","0SWC3","?","0SDC1","0SDC2","0SDC3"
   "0SC","0SWC1","0SWC2","0SWC3","?","0SDC1","0SDC2","0SDC3"
};
};
Line 368... Line 374...
   "9BLTZ","9BGEZ","9BLTZL","9BGEZL","0?","0?","0?","0?",
   "9BLTZ","9BGEZ","9BLTZL","9BGEZL","0?","0?","0?","0?",
   "0TGEI","0TGEIU","0TLTI","0TLTIU","0TEQI","0?","0TNEI","0?",
   "0TGEI","0TGEIU","0TLTI","0TLTIU","0TEQI","0?","0TNEI","0?",
   "9BLTZAL","9BEQZAL","9BLTZALL","9BGEZALL","0?","0?","0?","0?",
   "9BLTZAL","9BEQZAL","9BLTZALL","9BGEZALL","0?","0?","0?","0?",
   "0?","0?","0?","0?","0?","0?","0?","0?"
   "0?","0?","0?","0?","0?","0?","0?","0?"
};
};
 
/*
 
static char *special2_string[]={
 
    "0MADD","0MADDU","0MUL","0?",  "0?","0?","0?","0?",
 
    "0?","0?","0?","0?",  "0?","0?","0?","0?",
 
    "0?","0?","0?","0?",  "0?","0?","0?","0?",
 
    "0?","0?","0?","0?",  "0?","0?","0?","0?",
 
 
 
    "0CLZ","0CLO","0?","0?",  "0?","0?","0?","0?",
 
    "0?","0?","0?","0?",  "0?","0?","0?","0?",
 
    "0?","0?","0?","0?",  "0?","0?","0?","0?",
 
    "0?","0?","0?","0?",  "0?","0?","0?","0?",
 
};
 
*/
 
 
 
/** local memory used by the console simulation code */
static unsigned int HWMemory[8];
static unsigned int HWMemory[8];
 
 
 
#define MAP_MAX_FUNCTIONS  (400)
 
#define MAP_MAX_NAME_LEN   (80)
 
 
 
/** Information extracted from the map file, if any */
 
typedef struct {
 
    uint32_t num_functions;         /**< number of functions in the table */
 
    FILE *log;                      /**< text log file or stdout */
 
    char *log_filename;             /**< name of log file or NULL */
 
    uint32_t fn_address[MAP_MAX_FUNCTIONS];
 
    char fn_name[MAP_MAX_FUNCTIONS][MAP_MAX_NAME_LEN];
 
} t_map_info;
 
 
 
t_map_info map_info;
 
 
/*---- Local function prototypes ---------------------------------------------*/
/*---- Local function prototypes ---------------------------------------------*/
 
 
/* Debug and logging */
/* Debug and logging */
void init_trace_buffer(t_state *s, t_args *args);
void init_trace_buffer(t_state *s, t_args *args);
void close_trace_buffer(t_state *s);
void close_trace_buffer(t_state *s);
void dump_trace_buffer(t_state *s);
void dump_trace_buffer(t_state *s);
void log_cycle(t_state *s);
uint32_t log_cycle(t_state *s);
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);
void log_failed_assertions(t_state *s);
void log_failed_assertions(t_state *s);
uint32_t log_enabled(t_state *s);
uint32_t log_enabled(t_state *s);
void trigger_log(t_state *s);
void trigger_log(t_state *s);
void print_opcode_fields(uint32_t opcode);
void print_opcode_fields(uint32_t opcode);
 
void reserved_opcode(uint32_t pc, uint32_t opcode, t_state* s);
 
int32_t read_map_file(char *filename, t_map_info* map);
 
void log_call(uint32_t to, uint32_t from);
 
void log_ret(uint32_t to, uint32_t from);
 
int32_t function_index(uint32_t address);
 
 
int32_t parse_cmd_line(uint32_t argc, char **argv, t_args *args);
int32_t parse_cmd_line(uint32_t argc, char **argv, t_args *args);
void usage(void);
void usage(void);
 
 
/* CPU model */
/* CPU model */
Line 402... Line 441...
void start_load(t_state *s, uint32_t addr, int rt, int data);
void start_load(t_state *s, uint32_t addr, int rt, int data);
 
 
 
 
/*---- Local functions -------------------------------------------------------*/
/*---- Local functions -------------------------------------------------------*/
 
 
 
/*---- Call & ret tracing (EARLY DRAFT) --------------------------------------*/
 
 
 
static uint32_t call_depth = 0;
 
 
 
void log_ret(uint32_t to, uint32_t from){
 
    int32_t i,j;
 
 
 
    /* If no map file has been loaded, skip trace */
 
    if((!map_info.num_functions) || (!map_info.log)) return;
 
 
 
    if(call_depth>0){
 
        fprintf(map_info.log, "[%08x]  ", from);
 
        for(j=0;j<call_depth;j++){
 
            fprintf(map_info.log, ". ");
 
        }
 
        fprintf(map_info.log, "}\n");
 
        call_depth--;
 
    }
 
    else{
 
        i = function_index(to);
 
        if(i>=0){
 
            fprintf(map_info.log, "[%08x]  %s\n", from, map_info.fn_name[i]);
 
        }
 
        else{
 
            fprintf(map_info.log, "[%08x]  %08x\n", from, to);
 
        }
 
    }
 
}
 
 
 
/** */
 
void log_call(uint32_t to, uint32_t from){
 
    int32_t i,j;
 
 
 
    /* If no map file has been loaded, skip trace */
 
    if((!map_info.num_functions) || (!map_info.log)) return;
 
 
 
    i = function_index(to);
 
    if(i>=0){
 
        call_depth++;
 
        fprintf(map_info.log, "[%08x]  ", from);
 
        for(j=0;j<call_depth;j++){
 
            fprintf(map_info.log, ". ");
 
        }
 
        fprintf(map_info.log, "%s{\n", map_info.fn_name[i]);
 
    }
 
}
 
 
 
int32_t function_index(uint32_t address){
 
    uint32_t i;
 
 
 
    for(i=0;i<map_info.num_functions;i++){
 
        if(address==map_info.fn_address[i]){
 
            return i;
 
        }
 
    }
 
    return -1;
 
}
 
 
 
/*---- Execution log ---------------------------------------------------------*/
 
 
/** 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 bit CP0.16==1, this is a D-Cache line invalidation access and
    /* 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) */
           the HW will not read any actual data, so skip the log (@note1) */
    if(log_enabled(s) && log!=0 && !(s->status & 0x00010000)){
    if(log_enabled(s) && log!=0 && !(s->status & 0x00010000)){
Line 460... Line 559...
    }
    }
    if(!ptr){
    if(!ptr){
        /* address out of mapped blocks: log and return zero */
        /* address out of mapped blocks: log and return zero */
        /* if bit CP0.16==1, this is a D-Cache line invalidation access and
        /* 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) */
           the HW will not read any actual data, so skip the log (@note1) */
 
        printf("MEM RD ERROR @ 0x%08x [0x%08x]\n", s->pc, full_address);
        if(log_enabled(s) && log!=0 && !(s->status & (1<<16))){
        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 564... Line 664...
        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);
                s->op_addr, address, mask, dvalue);
    }
    }
 
 
    if((address&0xffff0000)==DBG_REGS){
    /* Print anything that's written to a debug register, otherwise ignore it */
        printf("[%04x]=%08x\n", address & 0xffff, value);
    if((address&0xffff0000)==(DBG_REGS&0xffff0000)){
 
        printf("DEBUG REG[%04x]=%08x\n", address & 0xffff, value);
 
        return;
    }
    }
 
 
    switch(address){
    switch(address){
    case UART_WRITE:
    case UART_WRITE:
        putch(value);
        putch(value);
Line 606... Line 708...
            break;
            break;
        }
        }
    }
    }
    if(!ptr){
    if(!ptr){
        /* address out of mapped blocks: log and return zero */
        /* address out of mapped blocks: log and return zero */
 
        printf("MEM WR ERROR @ 0x%08x [0x%08x]\n", s->pc, address);
        if(log_enabled(s) && log!=0){
        if(log_enabled(s) && log!=0){
            fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR UNMAPPED\n",
            fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR UNMAPPED\n",
                s->op_addr, address, mask, dvalue);
                s->op_addr, address, mask, dvalue);
        }
        }
        return;
        return;
Line 717... Line 820...
    data = (data << disp[offset]) & mask[offset];
    data = (data << disp[offset]) & mask[offset];
 
 
    s->r[reg_index] = (s->r[reg_index] & (~mask[offset])) | data;
    s->r[reg_index] = (s->r[reg_index] & (~mask[offset])) | data;
}
}
 
 
 
/*---- Optional MIPS32 opcodes -----------------------------------------------*/
 
 
 
uint32_t count_leading(uint32_t lead, uint32_t src){
 
    uint32_t mask, bit_val, i;
 
 
 
    mask = 0x80000000;
 
    bit_val = lead? mask : 0x0;
 
 
 
    for(i=0;i<32;i++){
 
        if((src & mask) != bit_val){
 
            return i;
 
        }
 
        mask = mask >> 1;
 
    }
 
 
 
    return i;
 
}
 
 
 
uint32_t mult_gpr(uint32_t m1, uint32_t m2){
 
    uint32_t temp;
 
 
 
    temp = m1 * m2;
 
    return temp;
 
}
 
 
 
uint32_t ext_bitfield(uint32_t src, uint32_t opcode){
 
    uint32_t pos, size, mask, value;
 
 
 
    pos = (opcode>>6) & 0x1f;
 
    size = ((opcode>>11) & 0x1f) + 1;
 
    mask = (1 << size)-1;
 
    mask = mask << pos;
 
 
 
    value = (src & mask) >> pos;
 
    return value;
 
}
 
 
 
uint32_t ins_bitfield(uint32_t target, uint32_t src, uint32_t opcode){
 
    uint32_t pos, size, mask, value;
 
 
 
    pos = (opcode>>6) & 0x1f;
 
    size = ((opcode>>11) & 0x1f) + 1;
 
    mask = (1 << size)-1;
 
    mask = mask << pos;
 
 
 
    value = target & (~mask);
 
    value |= ((src << pos) & mask);
 
    return value;
 
}
 
 
/*---- Optional MMU and cache implementation ---------------------------------*/
/*---- Optional MMU and cache implementation ---------------------------------*/
 
 
/*
/*
   The actual core does not have a cache so all of the original Plasma mlite.c
   The actual core does not have a cache so all of the original Plasma mlite.c
Line 788... Line 940...
/** Execute one cycle of the CPU (including any interlock stall cycles) */
/** Execute one cycle of the CPU (including any interlock stall cycles) */
void cycle(t_state *s, int show_mode){
void cycle(t_state *s, int show_mode){
    unsigned int opcode;
    unsigned int opcode;
    int delay_slot = 0; /* 1 of this instruction is a branch */
    int delay_slot = 0; /* 1 of this instruction is a branch */
    unsigned int op, rs, rt, rd, re, func, imm, target;
    unsigned int op, rs, rt, rd, re, func, imm, target;
    int trap_cause = 0;
 
    int imm_shift, branch=0, lbranch=2, skip2=0;
    int imm_shift, branch=0, lbranch=2, skip2=0;
 
    int link=0; /* !=0 if this is a 'branch-and-link' opcode */
    int *r=s->r;
    int *r=s->r;
    unsigned int *u=(unsigned int*)s->r;
    unsigned int *u=(unsigned int*)s->r;
    unsigned int ptr, epc, rSave;
    unsigned int ptr, epc, rSave;
    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;
 
 
 
    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);
 
 
    op = (opcode >> 26) & 0x3f;
    op = (opcode >> 26) & 0x3f;
    rs = (opcode >> 21) & 0x1f;
    rs = (opcode >> 21) & 0x1f;
    rt = (opcode >> 16) & 0x1f;
    rt = (opcode >> 16) & 0x1f;
    rd = (opcode >> 11) & 0x1f;
    rd = (opcode >> 11) & 0x1f;
    re = (opcode >> 6) & 0x1f;
    re = (opcode >> 6) & 0x1f;
Line 843... Line 998...
            }
            }
            else{
            else{
                aux = op&0x03;
                aux = op&0x03;
                switch(rs){
                switch(rs){
                    case 16:
                    case 16:
                        /* FIXME partial decoding */
                        /* FIXME partial decoding of some COP0 opcodes */
                        printf("  RFE      "); format = ' '; break;
                        printf("  RFE      "); format = ' '; break;
                    case 4:
                    case 4:
                        printf("  MTC%1d   ", aux); break;
                        printf("  MTC%1d   ", aux); break;
                    case 0:
                    case 0:
                        printf("  MFC%1d   ", aux); break;
                        printf("  MFC%1d   ", aux); break;
Line 946... Line 1101...
        case 0x02:/*SRL*/  r[rd]=u[rt]>>re;          break;
        case 0x02:/*SRL*/  r[rd]=u[rt]>>re;          break;
        case 0x03:/*SRA*/  r[rd]=r[rt]>>re;          break;
        case 0x03:/*SRA*/  r[rd]=r[rt]>>re;          break;
        case 0x04:/*SLLV*/ r[rd]=r[rt]<<r[rs];       break;
        case 0x04:/*SLLV*/ r[rd]=r[rt]<<r[rs];       break;
        case 0x06:/*SRLV*/ r[rd]=u[rt]>>r[rs];       break;
        case 0x06:/*SRLV*/ r[rd]=u[rt]>>r[rs];       break;
        case 0x07:/*SRAV*/ r[rd]=r[rt]>>r[rs];       break;
        case 0x07:/*SRAV*/ r[rd]=r[rt]>>r[rs];       break;
        case 0x08:/*JR*/   delay_slot=1;
        case 0x08:/*JR*/   if(rs==31) log_ret(r[rs],epc);
 
                           delay_slot=1;
                           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]; break;
                           s->pc_next=r[rs];
 
                           log_call(s->pc_next, epc); 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*/ s->trap_cause = 8;
                              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*/   s->trap_cause = 9;
                              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 992... Line 1147...
        case 0x31:/*TGEU*/ break;
        case 0x31:/*TGEU*/ break;
        case 0x32:/*TLT*/  break;
        case 0x32:/*TLT*/  break;
        case 0x33:/*TLTU*/ break;
        case 0x33:/*TLTU*/ break;
        case 0x34:/*TEQ*/  break;
        case 0x34:/*TEQ*/  break;
        case 0x36:/*TNE*/  break;
        case 0x36:/*TNE*/  break;
        default: printf("ERROR0(*0x%x~0x%x)\n", s->pc, opcode);
        default:
            /* FIXME should trap unknown opcode */
            reserved_opcode(epc, opcode, s);
            s->wakeup=1;
 
        }
        }
        break;
        break;
    case 0x01:/*REGIMM*/
    case 0x01:/*REGIMM*/
        switch(rt){
        switch(rt){
            case 0x10:/*BLTZAL*/ r[31]=s->pc_next;
            case 0x10:/*BLTZAL*/ r[31]=s->pc_next; link=1;
            case 0x00:/*BLTZ*/   branch=r[rs]<0;    break;
            case 0x00:/*BLTZ*/   branch=r[rs]<0;    break;
            case 0x11:/*BGEZAL*/ r[31]=s->pc_next;
            case 0x11:/*BGEZAL*/ r[31]=s->pc_next; link=1;
            case 0x01:/*BGEZ*/   branch=r[rs]>=0;   break;
            case 0x01:/*BGEZ*/   branch=r[rs]>=0;   break;
            case 0x12:/*BLTZALL*/r[31]=s->pc_next;
            case 0x12:/*BLTZALL*/r[31]=s->pc_next; link=1;
            case 0x02:/*BLTZL*/  lbranch=r[rs]<0;   break;
            case 0x02:/*BLTZL*/  lbranch=r[rs]<0;   break;
            case 0x13:/*BGEZALL*/r[31]=s->pc_next;
            case 0x13:/*BGEZALL*/r[31]=s->pc_next; link=1;
            case 0x03:/*BGEZL*/  lbranch=r[rs]>=0;  break;
            case 0x03:/*BGEZL*/  lbranch=r[rs]>=0;  break;
            default: printf("ERROR1\n"); s->wakeup=1;
            default: printf("ERROR1\n"); s->wakeup=1;
        }
        }
        break;
        break;
    case 0x03:/*JAL*/    r[31]=s->pc_next;
    case 0x03:/*JAL*/    r[31]=s->pc_next; log_call(((s->pc&0xf0000000)|target), epc);
    case 0x02:/*J*/      delay_slot=1;
    case 0x02:/*J*/      delay_slot=1;
                       s->pc_next=(s->pc&0xf0000000)|target; break;
                       s->pc_next=(s->pc&0xf0000000)|target; break;
    case 0x04:/*BEQ*/    branch=r[rs]==r[rt];     break;
    case 0x04:/*BEQ*/    branch=r[rs]==r[rt];     break;
    case 0x05:/*BNE*/    branch=r[rs]!=r[rt];     break;
    case 0x05:/*BNE*/    branch=r[rs]!=r[rt];     break;
    case 0x06:/*BLEZ*/   branch=r[rs]<=0;         break;
    case 0x06:/*BLEZ*/   branch=r[rs]<=0;         break;
Line 1035... Line 1189...
                    case 12: r[rt]=s->status & 0x0000003f; break;
                    case 12: r[rt]=s->status & 0x0000003f; 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:
 
                        printf("mfc0 [%02d] @ [0x%08x]\n", rt, s->pc);
                        break;
                        break;
                }
                }
            }
            }
            else{                         //move to CP0 (mtc0)
            else{                         //move to CP0 (mtc0)
                /* FIXME check CF= reg address */
                /* FIXME check CF= reg address */
Line 1050... Line 1205...
                    /* Move to unimplemented COP0 register: display warning */
                    /* Move to unimplemented COP0 register: display warning */
                    /* FIXME should log ignored move */
                    /* FIXME should log ignored move */
                    printf("mtc0 [%2d]=0x%08x @ [0x%08x] IGNORED\n",
                    printf("mtc0 [%2d]=0x%08x @ [0x%08x] IGNORED\n",
                           rd, r[rt], epc);
                           rd, r[rt], epc);
                }
                }
                /* FIXME remove remnants of Plasma MMU simulation */
 
                /*
 
                if(s->processId && (r[rt]&2)){
 
                    s->userMode|=r[rt]&2;
 
                    //printf("CpuStatus=%d %d %d\n", r[rt], s->status, s->userMode);
 
                    //s->wakeup = 1;
 
                    //printf("pc=0x%x\n", epc);
 
                }
 
                */
 
            }
            }
        }
        }
        else{
        else{
            /* tried to execute mtc* or mfc* in user mode: trap */
            /* tried to execute mtc* or mfc* in user mode: trap */
            printf("COP0 UNAVAILABLE address=0x%08x opcode=0x%x -- ",
            printf("COP0 UNAVAILABLE [0x%08x] = 0x%x %c -- ",
                   epc, opcode);
                   epc, opcode, (s->delay_slot? 'D':' '));
            print_opcode_fields(opcode);
            print_opcode_fields(opcode);
            printf("\n");
            printf("\n");
 
 
            trap_cause = 11; /* unavailable coprocessor */
            s->trap_cause = 11; /* unavailable coprocessor */
            s->exceptionId=1;
 
        }
        }
        break;
        break;
    case 0x11:/*COP1*/  unimplemented(s,"COP1");
    case 0x11:/*COP1*/  unimplemented(s,"COP1");
                        break;
                        break;
//      case 0x12:/*COP2*/ break;
//      case 0x12:/*COP2*/ break;
//      case 0x13:/*COP3*/ break;
//      case 0x13:/*COP3*/ break;
    case 0x14:/*BEQL*/  lbranch=r[rs]==r[rt];    break;
    case 0x14:/*BEQL*/  lbranch=r[rs]==r[rt];    break;
    case 0x15:/*BNEL*/  lbranch=r[rs]!=r[rt];    break;
    case 0x15:/*BNEL*/  lbranch=r[rs]!=r[rt];    break;
    case 0x16:/*BLEZL*/ lbranch=r[rs]<=0;        break;
    case 0x16:/*BLEZL*/ lbranch=r[rs]<=0;        break;
    case 0x17:/*BGTZL*/ lbranch=r[rs]>0;         break;
    case 0x17:/*BGTZL*/ lbranch=r[rs]>0;         break;
//      case 0x1c:/*MAD*/  break;   /*IV*/
    case 0x1c:/*SPECIAL2*/
 
        /* MIPS32 opcodes, some of which may be emulated */
 
        if(cmd_line_args.emulate_some_mips32){
 
            switch(func){
 
                case 0x20: /* CLZ */ r[rt] = count_leading(0, r[rs]); break;
 
                case 0x21: /* CLO */ r[rt] = count_leading(1, r[rs]); break;
 
                case 0x02: /* MUL */ r[rd] = mult_gpr(r[rs], r[rt]); break;
 
                default:
 
                    reserved_opcode(epc, opcode, s);
 
            }
 
        }
 
        else{
 
            reserved_opcode(epc, opcode, s);
 
        }
 
        break;
 
    case 0x1f: /* SPECIAL3 */
 
        if(cmd_line_args.emulate_some_mips32){
 
            switch(func){
 
                case 0x00: /* EXT */ r[rt] = ext_bitfield(r[rs], opcode); break;
 
                case 0x04: /* INS */ r[rt] = ins_bitfield(r[rt], r[rs], opcode); break;
 
                default:
 
                    reserved_opcode(epc, opcode, s);
 
            }
 
        }
 
        break;
    case 0x20:/*LB*/    //r[rt]=(signed char)mem_read(s,1,ptr,1);  break;
    case 0x20:/*LB*/    //r[rt]=(signed char)mem_read(s,1,ptr,1);  break;
                        start_load(s, ptr, rt,(signed char)mem_read(s,1,ptr,1));
                        start_load(s, ptr, rt,(signed char)mem_read(s,1,ptr,1));
                        break;
                        break;
 
 
    case 0x21:/*LH*/    //r[rt]=(signed short)mem_read(s,2,ptr,1); break;
    case 0x21:/*LH*/    //r[rt]=(signed short)mem_read(s,2,ptr,1); break;
Line 1132... Line 1301...
//      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:  /* unimplemented opcode */
    default:  /* unimplemented opcode */
        if(cmd_line_args.trap_on_reserved){
        reserved_opcode(epc, opcode, s);
            trap_cause = 10; /* reserved instruction */
 
            s->exceptionId=1;
 
        }
 
        else{
 
            printf("RESERVED OPCODE address=0x%08x opcode=0x%x -- ",
 
                   epc, opcode);
 
            print_opcode_fields(opcode);
 
            printf("\n");
 
        }
        }
 
 
 
    /* */
 
    if((branch || lbranch == 1) && link){
 
        log_call(s->pc_next + imm_shift, epc);
    }
    }
 
 
    /* adjust next PC if this was a a jump instruction */
    /* adjust next PC if this was a a jump instruction */
    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;
Line 1159... Line 1324...
 
 
    /* 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*/
    /* load delay slots not simulated */
    /* load delay slots not simulated */
 
 
    /* Handle exceptions */
    /* Handle exceptions */
   if(s->exceptionId){
   if(s->trap_cause>=0){
        r[rt] = rSave;
        r[rt] = rSave;
        /* set cause field ... */
        /* set cause field ... */
        s->cp0_cause = (s->delay_slot & 0x1) << 31 | (trap_cause & 0x1f) << 2;
        s->cp0_cause = (s->delay_slot & 0x1) << 31 | (s->trap_cause & 0x1f) << 2;
        /* ...save previous KU/IE flags in SR... */
        /* ...save previous KU/IE flags in SR... */
        s->status = (s->status & 0xffffffc3) | ((s->status & 0x0f) << 2);
        s->status = (s->status & 0xffffffc3) | ((s->status & 0x0f) << 2);
        /* ...and raise KU(EXL) kernel mode flag */
        /* ...and raise KU(EXL) kernel mode flag */
        s->status |= 0x02;
        s->status |= 0x02;
        /* adjust epc if we (i.e. the victim instruction) are in a delay slot */
        /* adjust epc if we (i.e. the victim instruction) are in a delay slot */
Line 1174... Line 1339...
            epc = epc - 4;
            epc = epc - 4;
        }
        }
        s->epc = epc;
        s->epc = epc;
        s->pc_next = VECTOR_TRAP;
        s->pc_next = VECTOR_TRAP;
        s->skip = 1;
        s->skip = 1;
        s->exceptionId = 0;
 
        s->userMode = 0;
        s->userMode = 0;
        //s->wakeup = 1;
        //s->wakeup = 1;
    }
    }
 
 
    /* if we're NOT showing output to console, log state of CPU to file */
    /* if we're NOT showing output to console, log state of CPU to file */
    if(!show_mode){
    if(!show_mode){
        log_cycle(s);
        s->wakeup |= log_cycle(s);
    }
    }
 
 
 
 
 
 
    /* if this instruction was any kind of branch that actually jumped, then
    /* if this instruction was any kind of branch that actually jumped, then
Line 1210... Line 1374...
    printf("%02x:", field);
    printf("%02x:", field);
    field = (opcode >>  0)&0x3f;
    field = (opcode >>  0)&0x3f;
    printf("%02x",  field);
    printf("%02x",  field);
}
}
 
 
 
/** Deal with reserved, unimplemented opcodes. Updates s->trap_cause. */
 
void reserved_opcode(uint32_t pc, uint32_t opcode, t_state* s){
 
    if(cmd_line_args.trap_on_reserved){
 
        s->trap_cause = 10; /* reserved instruction */
 
    }
 
    else{
 
        printf("RESERVED OPCODE [0x%08x] = 0x%08x %c -- ",
 
                pc, opcode, (s->delay_slot? 'D':' '));
 
        print_opcode_fields(opcode);
 
        printf("\n");
 
    }
 
}
 
 
 
 
/** Dump CPU state to console */
/** Dump CPU state to console */
void show_state(t_state *s){
void show_state(t_state *s){
    int i,j;
    int i,j;
    printf("pid=%d userMode=%d, epc=0x%x\n", s->processId, s->userMode, s->epc);
    printf("pid=%d userMode=%d, epc=0x%x\n", s->processId, s->userMode, s->epc);
Line 1387... Line 1564...
int read_binary_files(t_state *s, t_args *args){
int read_binary_files(t_state *s, t_args *args){
    FILE *in;
    FILE *in;
    uint8_t *target;
    uint8_t *target;
    uint32_t bytes=0, i, files_read=0;
    uint32_t bytes=0, i, files_read=0;
 
 
 
    /* read map file if requested */
 
    if(args->map_filename!=NULL){
 
        if(read_map_file(args->map_filename, &map_info)<0){
 
            printf("Trouble reading map file '%s', quitting!\n",
 
                   args->map_filename);
 
            return 1;
 
        }
 
        printf("Read %d functions from the map file; call trace enabled.\n\n",
 
               map_info.num_functions);
 
    }
 
 
 
    /* read object code binaries */
    for(i=0;i<NUM_MEM_BLOCKS;i++){
    for(i=0;i<NUM_MEM_BLOCKS;i++){
        bytes = 0;
        bytes = 0;
        if(args->bin_filename[i]!=NULL){
        if(args->bin_filename[i]!=NULL){
 
 
            in = fopen(args->bin_filename[i], "rb");
            in = fopen(args->bin_filename[i], "rb");
Line 1416... Line 1605...
 
 
            fclose(in);
            fclose(in);
 
 
            /* Now reverse the endianness of the data we just read, if it's
            /* Now reverse the endianness of the data we just read, if it's
             necessary. */
             necessary. */
             /* FIXME add cmd line param, etc. */
             /* FIXME handle little-endian stuff (?) */
            //reverse_endianess(target, bytes);
            //reverse_endianess(target, bytes);
 
 
            files_read++;
            files_read++;
        }
        }
        printf("%-16s [size= %6dKB, start= 0x%08x] loaded %d bytes.\n",
        printf("%-16s [size= %6dKB, start= 0x%08x] loaded %d bytes.\n",
Line 1457... Line 1646...
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
 
 
int main(int argc,char *argv[]){
int main(int argc,char *argv[]){
    t_state state, *s=&state;
    t_state state, *s=&state;
 
 
 
 
 
 
    /* Parse command line and pass any relevant arguments to CPU record */
    /* Parse command line and pass any relevant arguments to CPU record */
    if(parse_cmd_line(argc,argv, &cmd_line_args)==0){
    if(parse_cmd_line(argc,argv, &cmd_line_args)==0){
        return 0;
        return 0;
    }
    }
 
 
Line 1484... Line 1675...
 
 
    /* Simulate a CPU reset */
    /* Simulate a CPU reset */
    reset_cpu(s);
    reset_cpu(s);
 
 
    /* Simulate the work of the uClinux bootloader */
    /* Simulate the work of the uClinux bootloader */
    if(cmd_line_args.memory_map == MAP_UCLINUX){
    if(cmd_line_args.memory_map == MAP_UCLINUX_BRAM){
        /* FIXME this is a stub, flesh it out */
        /* FIXME this 'bootloader' is a stub, flesh it out */
        s->pc = 0x80002400;
        s->pc = 0x80002400;
    }
    }
 
 
    /* Enter debug command interface; will only exit clean with user command */
    /* Enter debug command interface; will only exit clean with user command */
    do_debug(s, cmd_line_args.no_prompt);
    do_debug(s, cmd_line_args.no_prompt);
Line 1510... Line 1701...
    s->t.disasm_ptr = VECTOR_RESET;
    s->t.disasm_ptr = VECTOR_RESET;
 
 
#if FILE_LOGGING_DISABLED
#if FILE_LOGGING_DISABLED
    s->t.log = NULL;
    s->t.log = NULL;
    s->t.log_triggered = 0;
    s->t.log_triggered = 0;
 
    map_info.log = NULL;
    return;
    return;
#else
#else
    /* clear trace buffer */
    /* clear trace buffer */
    for(i=0;i<TRACE_BUFFER_SIZE;i++){
    for(i=0;i<TRACE_BUFFER_SIZE;i++){
        s->t.buf[i]=0xffffffff;
        s->t.buf[i]=0xffffffff;
Line 1533... Line 1725...
    }
    }
 
 
    /* Setup log trigger */
    /* Setup log trigger */
    s->t.log_triggered = 0;
    s->t.log_triggered = 0;
    s->t.log_trigger_address = args->log_trigger_address;
    s->t.log_trigger_address = args->log_trigger_address;
 
 
 
    /* if file logging of function calls is enabled, open log file */
 
    if(map_info.log_filename!=NULL){
 
        map_info.log = fopen(map_info.log_filename, "w");
 
        if(map_info.log==NULL){
 
            printf("Error opening log file '%s', file logging disabled\n",
 
                    map_info.log_filename);
 
        }
 
    }
#endif
#endif
}
}
 
 
/** Dumps last jump targets as a chunk of hex numbers (older is left top) */
/** Dumps last jump targets as a chunk of hex numbers (older is left top) */
void dump_trace_buffer(t_state *s){
void dump_trace_buffer(t_state *s){
Line 1549... Line 1750...
        }
        }
    }
    }
}
}
 
 
/** Logs last cycle's activity (changes in state and/or loads/stores) */
/** Logs last cycle's activity (changes in state and/or loads/stores) */
void log_cycle(t_state *s){
uint32_t log_cycle(t_state *s){
    static unsigned int last_pc = 0;
    static unsigned int last_pc = 0;
    int i;
    int i;
    uint32_t log_pc;
    uint32_t log_pc;
 
 
    /* store PC in trace buffer only if there was a jump */
    /* store PC in trace buffer only if there was a jump */
    if(s->pc != (last_pc+4)){
    if(s->pc != (last_pc+4)){
        s->t.buf[s->t.next] = s->pc;
        s->t.buf[s->t.next] = s->pc;
        s->t.next = (s->t.next + 1) % TRACE_BUFFER_SIZE;
        s->t.next = (s->t.next + 1) % TRACE_BUFFER_SIZE;
    }
    }
    last_pc = s->pc;
    last_pc = s->pc;
 
    log_pc = s->op_addr;
 
 
 
 
    /* 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;
 
 
 
        /* skip register zero which does not change */
        /* skip register zero which does not change */
        for(i=1;i<32;i++){
        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]);
Line 1593... Line 1795...
        if(s->status != s->t. status){
        if(s->status != s->t. status){
            fprintf(s->t.log, "(%08X) [SR]=%08X\n", log_pc, s->status);
            fprintf(s->t.log, "(%08X) [SR]=%08X\n", log_pc, s->status);
        }
        }
        s->t.status = s->status;
        s->t.status = s->status;
    }
    }
 
 
 
#if 0
 
    /* FIXME Try to detect a code crash by looking at SP */
 
    if(1){
 
            if((s->r[29]&0xffff0000) == 0xffff00000){
 
                printf("SP derailed! @ 0x%08x [0x%08x]\n", log_pc, s->r[29]);
 
                return 1;
 
            }
 
    }
 
#endif
 
 
 
    return 0;
}
}
 
 
/** Frees debug buffers and closes log file */
/** Frees debug buffers and closes log file */
void close_trace_buffer(t_state *s){
void close_trace_buffer(t_state *s){
    if(s->t.log){
    if(s->t.log){
        fclose(s->t.log);
        fclose(s->t.log);
    }
    }
 
    if(map_info.log){
 
        fclose(map_info.log);
 
    }
}
}
 
 
/** Logs a message for each failed assertion, each in a line */
/** Logs a message for each failed assertion, each in a line */
void log_failed_assertions(t_state *s){
void log_failed_assertions(t_state *s){
    unsigned bitmap = s->failed_assertions;
    unsigned bitmap = s->failed_assertions;
Line 1638... Line 1855...
    s->t.lo = s->lo;
    s->t.lo = s->lo;
    s->t.hi = s->hi;
    s->t.hi = s->hi;
    s->t.epc = s->epc;
    s->t.epc = s->epc;
}
}
 
 
 
int32_t read_map_file(char *filename, t_map_info* map){
 
    FILE *f;
 
    uint32_t address, i;
 
    uint32_t segment_text = 0;
 
    char line[256];
 
    char name[256];
 
 
 
    f = fopen (filename, "rt");  /* open the file for reading */
 
 
 
    if(!f){
 
        return -1;
 
    }
 
 
 
   while(fgets(line, sizeof(line)-1, f) != NULL){
 
       if(!strncmp(line, ".text", 5)){
 
           segment_text = 1;
 
       }
 
       else if(line[0]==' ' && segment_text){
 
            /* may be a function address */
 
            for(i=0;(i<sizeof(line)-1) && (line[i]==' '); i++);
 
            if(line[i]=='0'){
 
                sscanf(line, "%*[ \n\t]%x%*[ \n\t]%s", &address, &(name[0]));
 
 
 
                strncpy(map->fn_name[map->num_functions],
 
                        name, MAP_MAX_NAME_LEN-1);
 
                map->fn_address[map->num_functions] = address;
 
                map->num_functions++;
 
                if(map->num_functions >= MAP_MAX_FUNCTIONS){
 
                    printf("WARNING: too many functions in map file!\n");
 
                    return map->num_functions;
 
                }
 
            }
 
       }
 
       else if(line[0]=='.' && segment_text){
 
           break;
 
       }
 
    }
 
    fclose(f);
 
 
 
#if 0
 
    for(i=0;i<map->num_functions;i++){
 
        printf("--> %08x %s\n", map->fn_address[i], map->fn_name[i]);
 
    }
 
#endif
 
 
 
    return map->num_functions;
 
}
 
 
 
 
void free_cpu(t_state *s){
void free_cpu(t_state *s){
    int i;
    int i;
 
 
    for(i=0;i<NUM_MEM_BLOCKS;i++){
    for(i=0;i<NUM_MEM_BLOCKS;i++){
        free(s->blocks[i].mem);
        free(s->blocks[i].mem);
Line 1656... Line 1922...
    s->status = 0x02; /* kernel mode, interrupts disabled */
    s->status = 0x02; /* kernel mode, interrupts disabled */
    /* init trace struct to prevent spurious logs */
    /* init trace struct to prevent spurious logs */
    s->t.status = s->status;
    s->t.status = s->status;
}
}
 
 
 
/* FIXME redundant function, merge with reserved_opcode */
void unimplemented(t_state *s, const char *txt){
void unimplemented(t_state *s, const char *txt){
    /* FIXME unimplemented opcode trap */
 
    printf("UNIMPLEMENTED: %s\n", txt);
    printf("UNIMPLEMENTED: %s\n", txt);
}
}
 
 
int init_cpu(t_state *s, t_args *args){
int init_cpu(t_state *s, t_args *args){
    int i, j;
    int i, j;
Line 1695... Line 1961...
}
}
 
 
int32_t parse_cmd_line(uint32_t argc, char **argv, t_args *args){
int32_t parse_cmd_line(uint32_t argc, char **argv, t_args *args){
    uint32_t i;
    uint32_t i;
 
 
 
    /* Initialize logging parameters */
 
    map_info.num_functions = 0;
 
    map_info.log_filename = NULL;
 
    map_info.log = stdout;
 
 
    /* 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->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";
    args->log_trigger_address = VECTOR_RESET;
    args->log_trigger_address = VECTOR_RESET;
 
    args->map_filename = NULL;
    for(i=0;i<NUM_MEM_BLOCKS;i++){
    for(i=0;i<NUM_MEM_BLOCKS;i++){
        args->bin_filename[i] = NULL;
        args->bin_filename[i] = NULL;
        args->offset[i] = 0;
        args->offset[i] = 0;
    }
    }
 
 
Line 1717... Line 1990...
            /* plasma simulation not supported, error*/
            /* plasma simulation not supported, error*/
            printf("Error: program compiled for compatibility to MIPS-I\n");
            printf("Error: program compiled for compatibility to MIPS-I\n");
            return 0;
            return 0;
        }
        }
        else if(strcmp(argv[i],"--uclinux")==0){
        else if(strcmp(argv[i],"--uclinux")==0){
            args->memory_map = MAP_UCLINUX;
            args->memory_map = MAP_UCLINUX_BRAM;
            /* FIXME selecting uClinux enables unaligned L/S emulation */
            /* FIXME selecting uClinux enables unaligned L/S emulation */
            args->do_unaligned = 1;
            args->do_unaligned = 1;
        }
        }
        else if(strcmp(argv[i],"--small")==0){
        else if(strcmp(argv[i],"--small")==0){
            args->memory_map = MAP_SMALL;
            args->memory_map = MAP_SMALL;
Line 1733... Line 2006...
            args->no_prompt = 1;
            args->no_prompt = 1;
        }
        }
        else if(strcmp(argv[i],"--notrap10")==0){
        else if(strcmp(argv[i],"--notrap10")==0){
            args->trap_on_reserved = 0;
            args->trap_on_reserved = 0;
        }
        }
 
        else if(strcmp(argv[i],"--nomips32")==0){
 
            args->emulate_some_mips32 = 0;
 
        }
        else if(strncmp(argv[i],"--bram=", strlen("--bram="))==0){
        else if(strncmp(argv[i],"--bram=", strlen("--bram="))==0){
            args->bin_filename[0] = &(argv[i][strlen("--bram=")]);
            args->bin_filename[0] = &(argv[i][strlen("--bram=")]);
        }
        }
        else if(strncmp(argv[i],"--flash=", strlen("--flash="))==0){
        else if(strncmp(argv[i],"--flash=", strlen("--flash="))==0){
            args->bin_filename[3] = &(argv[i][strlen("--flash=")]);
            args->bin_filename[3] = &(argv[i][strlen("--flash=")]);
        }
        }
        else if(strncmp(argv[i],"--xram=", strlen("--xram="))==0){
        else if(strncmp(argv[i],"--xram=", strlen("--xram="))==0){
            args->bin_filename[1] = &(argv[i][strlen("--xram=")]);
            args->bin_filename[1] = &(argv[i][strlen("--xram=")]);
        }
        }
 
        else if(strncmp(argv[i],"--map=", strlen("--map="))==0){
 
            args->map_filename = &(argv[i][strlen("--map=")]);
 
        }
 
        else if(strncmp(argv[i],"--trace_log=", strlen("--trace_log="))==0){
 
            map_info.log_filename = &(argv[i][strlen("--trace_log=")]);
 
        }
        else if(strncmp(argv[i],"--start=", strlen("--start="))==0){
        else if(strncmp(argv[i],"--start=", strlen("--start="))==0){
            sscanf(&(argv[i][strlen("--start=")]), "%x", &(args->start_addr));
            sscanf(&(argv[i][strlen("--start=")]), "%x", &(args->start_addr));
        }
        }
        else if(strncmp(argv[i],"--kernel=", strlen("--kernel="))==0){
        else if(strncmp(argv[i],"--kernel=", strlen("--kernel="))==0){
            args->bin_filename[1] = &(argv[i][strlen("--kernel=")]);
            args->bin_filename[1] = &(argv[i][strlen("--kernel=")]);
Line 1782... Line 2064...
    printf("--bram=<file name>      : BRAM initialization file\n");
    printf("--bram=<file name>      : BRAM initialization file\n");
    printf("--xram=<file name>      : XRAM initialization file\n");
    printf("--xram=<file name>      : XRAM initialization file\n");
    printf("--kernel=<file name>    : XRAM initialization file for uClinux kernel\n");
    printf("--kernel=<file name>    : XRAM initialization file for uClinux kernel\n");
    printf("                          (loads at block offset 0x2000)\n");
    printf("                          (loads at block offset 0x2000)\n");
    printf("--flash=<file name>     : FLASH initialization file\n");
    printf("--flash=<file name>     : FLASH initialization file\n");
 
    printf("--map=<file name>       : Map file to be used for tracing, if any\n");
 
    printf("--trace_log=<file name> : Log file used for tracing, if any\n");
    printf("--trigger=<hex number>  : Log trigger address\n");
    printf("--trigger=<hex number>  : Log trigger address\n");
    printf("--break=<hex number>    : Breakpoint address\n");
    printf("--break=<hex number>    : Breakpoint address\n");
    printf("--start=<hex number>    : Start here instead of at reset vector\n");
    printf("--start=<hex number>    : Start here instead of at reset vector\n");
    printf("--notrap10              : Reserverd opcodes are NOPs and don't trap\n");
    printf("--notrap10              : Reserverd opcodes are NOPs and don't trap\n");
 
    printf("--nomips32              : Do not emulate any mips32 opcodes\n");
    printf("--plasma                : Simulate Plasma instead of MIPS-I\n");
    printf("--plasma                : Simulate Plasma instead of MIPS-I\n");
    printf("--uclinux               : Use memory map tailored to uClinux\n");
    printf("--uclinux               : Use memory map tailored to uClinux\n");
    printf("--unaligned             : Implement unaligned load/store instructions\n");
    printf("--unaligned             : Implement unaligned load/store instructions\n");
    printf("--noprompt              : Run in batch mode\n");
    printf("--noprompt              : Run in batch mode\n");
    printf("--stop_at_zero          : Stop simulation when fetching from address 0x0\n");
    printf("--stop_at_zero          : Stop simulation when fetching from address 0x0\n");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.