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

Subversion Repositories ion

[/] [ion/] [trunk/] [tools/] [slite/] [src/] [slite.c] - Diff between revs 93 and 105

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

Rev 93 Rev 105
Line 49... Line 49...
//#define ENABLE_CACHE
//#define ENABLE_CACHE
 
 
 
 
/*---- Definition of simulated system parameters -----------------------------*/
/*---- Definition of simulated system parameters -----------------------------*/
 
 
/* Uncomment to simulate Plasma behavior (vectors & memory mapping) */
 
//#define SIMULATE_PLASMA (1)
 
 
 
#ifdef SIMULATE_PLASMA
 
 
 
#define VECTOR_RESET (0x00000000)
 
#define VECTOR_TRAP  (0x0000003c)
 
 
 
#else
 
 
 
#define VECTOR_RESET (0xbfc00000)
#define VECTOR_RESET (0xbfc00000)
#define VECTOR_TRAP  (0xbfc00180)
#define VECTOR_TRAP  (0xbfc00180)
 
 
#endif
 
 
 
/** Definition of a memory block */
/** Definition of a memory block */
typedef struct s_block {
typedef struct s_block {
    uint32_t start;
    uint32_t start;
    uint32_t size;
    uint32_t size;
    uint32_t mask;
    uint32_t mask;
    uint32_t read_only;
    uint32_t read_only;
    uint8_t  *mem;
    uint8_t  *mem;
    char     *area_name;
    char     *area_name;
} t_block;
} t_block;
 
 
 
#define NUM_MEM_BLOCKS      (4)
 
#define NUM_MEM_MAPS        (2)
 
 
 
/** Definition of a memory map */
 
/* FIXME i/o addresses missing, hardcoded */
 
typedef struct s_map {
 
    t_block blocks[NUM_MEM_BLOCKS];
 
} t_map;
 
 
 
 
 
 
/*  Here's where we define the memory areas (blocks) of the system.
/*  Here's where we define the memory areas (blocks) of the system.
 
 
    The blocks should be defined in this order: BRAM, XRAM, FLASH
    The blocks should be defined in this order: BRAM, XRAM, FLASH
 
 
Line 88... Line 86...
    Give any area a size of 0x0 to leave it unused.
    Give any area a size of 0x0 to leave it unused.
 
 
    When a binary file is specified in the cmd line for one of these areas, it
    When a binary file is specified in the cmd line for one of these areas, it
    will be used to initialize it, checking bounds.
    will be used to initialize it, checking bounds.
 
 
 
 
    Memory decoding is done in the order the blocks are defined; the address
    Memory decoding is done in the order the blocks are defined; the address
    is anded with field .mask and then compared to field .start. If they match
    is anded with field .mask and then compared to field .start. If they match
    the address modulo the field .size is used to index the memory block, giving
    the address modulo the field .size is used to index the memory block, giving
    a 'mirror' effect. All of this simulates how the actual hardware works.
    a 'mirror' effect. All of this simulates how the actual hardware works.
    Make sure the blocks don't overlap or the scheme will fail.
    Make sure the blocks don't overlap or the scheme will fail.
*/
*/
 
 
#define NUM_MEM_BLOCKS (3)
#define MAP_DEFAULT (0)
 
#define MAP_UCLINUX (1)
#ifdef SIMULATE_PLASMA
 
 
 
t_block memory_map_default[NUM_MEM_BLOCKS] = {
 
    /* meant as bootstrap block, though it's read/write */
 
    {VECTOR_RESET,  0x00000800, 0xf0000000, 1, NULL, "Boot BRAM"},
 
    /* main external ram block  */
 
    {0x80000000,    0x00001000, 0xf0000000, 0, NULL, "XRAM"},
 
    /* external flash block -- not used in plasma simulation */
 
    {0xb0000000,    0x00000000, 0xf0000000, 0, NULL, "Flash"},
 
};
 
 
 
#else
t_map memory_maps[NUM_MEM_MAPS] = {
 
    {/* Experimental memory map (default) */
t_block memory_map_default[NUM_MEM_BLOCKS] = {
        {/* Bootstrap BRAM, read only */
    /* Bootstrap BRAM, read only */
 
    {VECTOR_RESET,  0x00004800, 0xf8000000, 1, NULL, "Boot BRAM"},
    {VECTOR_RESET,  0x00004800, 0xf8000000, 1, NULL, "Boot BRAM"},
    /* main external ram block  */
    /* main external ram block  */
    {0x00000000,    0x00080000, 0xf8000000, 0, NULL, "XRAM"},
        {0x00000000,    0x00080000, 0xf8000000, 0, NULL, "XRAM0"},
 
        /* main external ram block  */
 
        {0x80000000,    0x00080000, 0xf8000000, 0, NULL, "XRAM1"},
    /* external flash block */
    /* external flash block */
    {0xb0000000,    0x00040000, 0xf8000000, 0, NULL, "Flash"},
    {0xb0000000,    0x00040000, 0xf8000000, 0, NULL, "Flash"},
 
        }
 
    },
 
 
 
    {/* uClinux memory map */
 
        {/* Bootstrap BRAM, read only */
 
        {VECTOR_RESET,  0x00001000, 0xf8000000, 1, NULL, "Boot BRAM"},
 
        /* main external ram block  */
 
        {0x80000000,    0x00200000, 0xf8000000, 0, NULL, "XRAM0"},
 
        {0x00000000,    0x00400000, 0xf8000000, 0, NULL, "XRAM1"},
 
        /* external flash block */
 
        {0xb0000000,    0x00100000, 0xf8000000, 0, NULL, "Flash"},
 
        }
 
    },
};
};
 
 
#endif
 
 
 
/*---- end of system parameters ----------------------------------------------*/
/*---- end of system parameters ----------------------------------------------*/
 
 
 
 
/** Values for the command line arguments */
/** Values for the command line arguments */
typedef struct s_args {
typedef struct s_args {
 
    /** memory map to be used */
 
    uint32_t memory_map;
 
    /** implement unaligned load/stores (don't just trap them) */
 
    uint32_t do_unaligned;
 
    /** start simulation without showing monitor prompt and quit on
 
        end condition -- useful for batch runs */
 
    uint32_t no_prompt;
 
    /** breakpoint address (0xffffffff if unused) */
 
    uint32_t breakpoint;
 
    /** a code fetch from this address starts logging */
    uint32_t log_trigger_address;
    uint32_t log_trigger_address;
 
    /** full name of log file */
    char *log_file_name;
    char *log_file_name;
    char *bin_filename[NUM_MEM_BLOCKS]; /**< bin file to load to area or null */
    /** bin file to load to each area or null */
 
    char *bin_filename[NUM_MEM_BLOCKS];
 
    /** offset into area (in bytes) where bin wile will be loaded */
 
    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 205... Line 219...
/*---- Hardware system parameters --------------------------------------------*/
/*---- Hardware system parameters --------------------------------------------*/
 
 
/* 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 UART_WRITE        0x20000000
#define UART_WRITE        0x20000000
#define UART_READ         0x20000000
#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
Line 249... Line 265...
} t_trace;
} t_trace;
 
 
typedef struct s_state {
typedef struct s_state {
   unsigned failed_assertions;            /**< assertion bitmap */
   unsigned failed_assertions;            /**< assertion bitmap */
   unsigned faulty_address;               /**< addr that failed assertion */
   unsigned faulty_address;               /**< addr that failed assertion */
 
   uint32_t do_unaligned;                 /**< !=0 to enable unaligned L/S */
 
   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 */
 
 
   int r[32];
   int r[32];
   int opcode;
   int opcode;
Line 321... Line 339...
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 */
void free_cpu(t_state *s);
void free_cpu(t_state *s);
int init_cpu(t_state *s);
int init_cpu(t_state *s, t_args *args);
void reset_cpu(t_state *s);
void reset_cpu(t_state *s);
 
void unimplemented(t_state *s, const char *txt);
 
void reverse_endianess(uint8_t *data, uint32_t bytes);
 
 
/* Hardware simulation */
/* Hardware simulation */
int mem_read(t_state *s, int size, unsigned int address, int log);
int mem_read(t_state *s, int size, unsigned int address, int log);
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log);
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log);
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);
Line 489... Line 509...
 
 
        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);
    }
    }
 
 
 
    if((address&0xffff0000)==DBG_REGS){
 
        printf("[%04x]=%08x\n", address & 0xffff, value);
 
    }
 
 
    switch(address){
    switch(address){
    case UART_WRITE:
    case UART_WRITE:
        putch(value);
        putch(value);
        fflush(stdout);
        fflush(stdout);
        return;
        return;
Line 568... Line 592...
        /* FIXME this is a bug, should quit */
        /* FIXME this is a bug, should quit */
        printf("ERROR");
        printf("ERROR");
    }
    }
}
}
 
 
 
/*-- unaligned store and load instructions -----------------------------------*/
 
/*
 
 These are meant to be left unimplemented and trapped. These functions simulate
 
 the unaligned r/w instructions until proper trap handlers are written.
 
*/
 
 
 
void mem_swl(t_state *s, uint32_t address, uint32_t value, uint32_t log){
 
    uint32_t data, offset;
 
 
 
    if(!s->do_unaligned) return unimplemented(s, "SWL");
 
 
 
    offset = (address & 0x03);
 
    address = (address & (~0x03));
 
    data = value;
 
 
 
    while(offset<4){
 
        mem_write(s,1,address+offset,(data>>24) & 0xff,0);
 
        data = data << 8;
 
        offset++;
 
    }
 
}
 
 
 
void mem_swr(t_state *s, uint32_t address, uint32_t value, uint32_t log){
 
    uint32_t data, offset;
 
 
 
    if(!s->do_unaligned) return unimplemented(s, "SWR");
 
 
 
    offset = (address & 0x03);
 
    address = (address & (~0x03));
 
    data = value;
 
 
 
    while(offset>=0){
 
        mem_write(s,1,address+offset,data & 0xff,0);
 
        data = data >> 8;
 
        offset--;
 
    }
 
}
 
 
 
void mem_lwr(t_state *s, uint32_t address, uint32_t reg_index, uint32_t log){
 
    uint32_t offset, data;
 
    uint32_t disp[4] = {24,         16,         8,          0};
 
    uint32_t mask[4] = {0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff};
 
 
 
    if(!s->do_unaligned) return unimplemented(s, "LWR");
 
 
 
    offset = (address & 0x03);
 
    address = (address & (~0x03));
 
 
 
    data = mem_read(s, 4, address, 0);
 
    data = (data >> disp[offset]) & mask[offset];
 
 
 
    s->r[reg_index] = (s->r[reg_index] & (~mask[offset])) | data;
 
}
 
 
 
void mem_lwl(t_state *s, uint32_t address, uint32_t reg_index, uint32_t log){
 
    uint32_t offset, data;
 
    uint32_t disp[4] = {0,          8,          16,         24};
 
    uint32_t mask[4] = {0xffffffff, 0xffffff00, 0xffff0000, 0xff000000};
 
 
 
    if(!s->do_unaligned) return unimplemented(s, "LWL");
 
 
 
    offset = (address & 0x03);
 
    address = (address & (~0x03));
 
 
 
    data = mem_read(s, 4, address, 0);
 
    data = (data << disp[offset]) & mask[offset];
 
 
 
    s->r[reg_index] = (s->r[reg_index] & (~mask[offset])) | data;
 
}
 
 
 
 
/*---- 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
   code for cache simulation has been removed.
   code for cache simulation has been removed.
Line 723... Line 818...
        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; break;
                              //s->exceptionId=1;
        case 0x0d:/*BREAK*/   trap_cause = 9;
                              /*
                              s->exceptionId=1; break;
                              FIXME enable when running uClinux
 
                              printf("SYSCALL (%08x)\n", s->pc);
 
                              */
 
                              break;
 
        case 0x0d:/*BREAK*/   //trap_cause = 9;
 
                              //s->exceptionId=1;
 
                              /*
 
                              FIXME enable when running uClinux
 
                              printf("BREAK (%08x)\n", s->pc);
 
                              */
 
                              break;
        case 0x0f:/*SYNC*/ s->wakeup=1;              break;
        case 0x0f:/*SYNC*/ s->wakeup=1;              break;
        case 0x10:/*MFHI*/ r[rd]=s->hi;              break;
        case 0x10:/*MFHI*/ r[rd]=s->hi;              break;
        case 0x11:/*FTHI*/ s->hi=r[rs];              break;
        case 0x11:/*FTHI*/ s->hi=r[rs];              break;
        case 0x12:/*MFLO*/ r[rd]=s->lo;              break;
        case 0x12:/*MFLO*/ r[rd]=s->lo;              break;
        case 0x13:/*MTLO*/ s->lo=r[rs];              break;
        case 0x13:/*MTLO*/ s->lo=r[rs];              break;
Line 785... Line 890...
    case 0x0c:/*ANDI*/   r[rt]=r[rs]&imm;         break;
    case 0x0c:/*ANDI*/   r[rt]=r[rs]&imm;         break;
    case 0x0d:/*ORI*/    r[rt]=r[rs]|imm;         break;
    case 0x0d:/*ORI*/    r[rt]=r[rs]|imm;         break;
    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
        if((opcode & (1<<23)) == 0){  //move from CP0 (mfc0)
            if(rd == 12){
            switch(rd){
                r[rt]=s->status;
                case 12: r[rt]=s->status; break;
            }
                case 13: r[rt]=s->cp0_cause; break;
            else if(rd == 13){
                case 14: r[rt]=s->epc; break;
                r[rt]=s->cp0_cause;
                case 15: r[rt]=0x00000200; break;
            }
                default:
            else{
                    //printf("mfco [%02d]\n", rd);
                r[rt]=s->epc;
                    break;
            }
            }
        }
        }
        else{                         //move to CP0
        else{                         //move to CP0 (mtc0)
            s->status=r[rt]&1;
            s->status=r[rt]&1;
            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);
            }
            }
        }
        }
        break;
        break;
//      case 0x11:/*COP1*/ break;
    case 0x11:/*COP1*/  unimplemented(s,"COP1");
 
                        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;
Line 821... Line 927...
                        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;
                        start_load(s, ptr, rt, (signed short)mem_read(s,2,ptr,1));
                        start_load(s, ptr, rt, (signed short)mem_read(s,2,ptr,1));
                        break;
                        break;
    case 0x22:/*LWL*/   //target=8*(ptr&3);
    case 0x22:/*LWL*/   mem_lwl(s, ptr, rt, 1);
                        //r[rt]=(r[rt]&~(0xffffffff<<target))|
                        //printf("LWL\n");
                        //      (mem_read(s,4,ptr&~3)<<target); break;
 
                        break;
                        break;
    case 0x23:/*LW*/    //r[rt]=mem_read(s,4,ptr,1);   break;
    case 0x23:/*LW*/    //r[rt]=mem_read(s,4,ptr,1);   break;
                        start_load(s, ptr, rt, mem_read(s,4,ptr,1));
                        start_load(s, ptr, rt, mem_read(s,4,ptr,1));
                        break;
                        break;
    case 0x24:/*LBU*/   //r[rt]=(unsigned char)mem_read(s,1,ptr,1); break;
    case 0x24:/*LBU*/   //r[rt]=(unsigned char)mem_read(s,1,ptr,1); break;
                        start_load(s, ptr, rt, (unsigned char)mem_read(s,1,ptr,1));
                        start_load(s, ptr, rt, (unsigned char)mem_read(s,1,ptr,1));
                        break;
                        break;
    case 0x25:/*LHU*/   //r[rt]= (unsigned short)mem_read(s,2,ptr,1);
    case 0x25:/*LHU*/   //r[rt]= (unsigned short)mem_read(s,2,ptr,1);
                        start_load(s, ptr, rt, (unsigned short)mem_read(s,2,ptr,1));
                        start_load(s, ptr, rt, (unsigned short)mem_read(s,2,ptr,1));
                        break;
                        break;
    case 0x26:/*LWR*/   //target=32-8*(ptr&3);
    case 0x26:/*LWR*/   mem_lwr(s, ptr, rt, 1);
                        //r[rt]=(r[rt]&~((unsigned int)0xffffffff>>target))|
                        //printf("LWR\n");
                        //((unsigned int)mem_read(s,4,ptr&~3)>>target);
 
                        break;
                        break;
    case 0x28:/*SB*/    mem_write(s,1,ptr,r[rt],1);  break;
    case 0x28:/*SB*/    mem_write(s,1,ptr,r[rt],1);  break;
    case 0x29:/*SH*/    mem_write(s,2,ptr,r[rt],1);  break;
    case 0x29:/*SH*/    mem_write(s,2,ptr,r[rt],1);  break;
    case 0x2a:/*SWL*/   //mem_write(s,1,ptr,r[rt]>>24);
    case 0x2a:/*SWL*/   mem_swl(s, ptr, r[rt], 1);
                        //mem_write(s,1,ptr+1,r[rt]>>16);
                        //printf("SWL\n");
                        //mem_write(s,1,ptr+2,r[rt]>>8);
                        break;
                        //mem_write(s,1,ptr+3,r[rt]); break;
 
    case 0x2b:/*SW*/    mem_write(s,4,ptr,r[rt],1);  break;
    case 0x2b:/*SW*/    mem_write(s,4,ptr,r[rt],1);  break;
    case 0x2e:/*SWR*/   break; //FIXME
    case 0x2e:/*SWR*/   mem_swr(s, ptr, r[rt], 1);
    case 0x2f:/*CACHE*/ break;
                        //printf("SWR\n");
    case 0x30:/*LL*/    //r[rt]=mem_read(s,4,ptr);   break;
                        break;
 
    case 0x2f:/*CACHE*/ unimplemented(s,"CACHE");
 
                        break;
 
    case 0x30:/*LL*/    //unimplemented(s,"LL");
                        start_load(s, ptr, rt, mem_read(s,4,ptr,1));
                        start_load(s, ptr, rt, mem_read(s,4,ptr,1));
                        break;
                        break;
//      case 0x31:/*LWC1*/ break;
//      case 0x31:/*LWC1*/ break;
//      case 0x32:/*LWC2*/ break;
//      case 0x32:/*LWC2*/ break;
//      case 0x33:/*LWC3*/ break;
//      case 0x33:/*LWC3*/ break;
Line 936... Line 1042...
    }
    }
    s->pc = j;
    s->pc = j;
}
}
 
 
/** Show debug monitor prompt and execute user command */
/** Show debug monitor prompt and execute user command */
void do_debug(t_state *s){
void do_debug(t_state *s, uint32_t no_prompt){
    int ch;
    int ch;
    int i, j=0, watch=0, addr;
    int i, j=0, watch=0, addr;
 
    j = s->breakpoint;
    s->pc_next = s->pc + 4;
    s->pc_next = s->pc + 4;
    s->skip = 0;
    s->skip = 0;
    s->wakeup = 0;
    s->wakeup = 0;
 
 
 
    printf("Starting simulation.\n");
 
 
 
    if(no_prompt){
 
        ch = '5'; /* 'go' command */
 
        printf("\n\n");
 
    }
 
    else{
    show_state(s);
    show_state(s);
    ch = ' ';
    ch = ' ';
 
    }
 
 
    for(;;){
    for(;;){
        if(ch != 'n'){
        if(ch != 'n' && !no_prompt){
            if(watch){
            if(watch){
                printf("0x%8.8x=0x%8.8x\n", watch, mem_read(s, 4, watch,0));
                printf("0x%8.8x=0x%8.8x\n", watch, mem_read(s, 4, watch,0));
            }
            }
            printf("1=Debug 2=t_trace 3=Step 4=BreakPt 5=Go 6=Memory ");
            printf("1=Debug 2=t_trace 3=Step 4=BreakPt 5=Go 6=Memory ");
            printf("7=Watch 8=Jump 9=Quit A=Dump\n");
            printf("7=Watch 8=Jump 9=Quit A=Dump\n");
            printf("L=LogTrigger > ");
            printf("L=LogTrigger > ");
        }
        }
        ch = getch();
        if(ch==' ') ch = getch();
        if(ch != 'n'){
        if(ch != 'n'){
            printf("\n");
            printf("\n");
        }
        }
        switch(ch){
        switch(ch){
        case 'a': case 'A':
        case 'a': case 'A':
Line 989... Line 1106...
                    printf("\n\nStop: pc = 0x%08x\n\n", j);
                    printf("\n\nStop: pc = 0x%08x\n\n", j);
                    break;
                    break;
                }
                }
                cycle(s, 0);
                cycle(s, 0);
            }
            }
 
            if(no_prompt) return;
            show_state(s);
            show_state(s);
            break;
            break;
        case 'G':
        case 'G':
            s->wakeup = 0;
            s->wakeup = 0;
            cycle(s, 1);
            cycle(s, 1);
Line 1029... Line 1147...
            printf("Address> ");
            printf("Address> ");
            scanf("%x", &(s->t.log_trigger_address));
            scanf("%x", &(s->t.log_trigger_address));
            printf("Log trigger address=0x%x\n", s->t.log_trigger_address);
            printf("Log trigger address=0x%x\n", s->t.log_trigger_address);
            break;
            break;
        }
        }
 
        ch = ' ';
    }
    }
}
}
 
 
/** Read binary code and data files */
/** Read binary code and data files */
int read_binary_files(t_state *s, t_args *args){
int read_binary_files(t_state *s, t_args *args){
    FILE *in;
    FILE *in;
    uint32_t bytes, i, files_read=0;
    uint8_t *target;
 
    uint32_t bytes=0, i, files_read=0;
 
 
    for(i=0;i<NUM_MEM_BLOCKS;i++){
    for(i=0;i<NUM_MEM_BLOCKS;i++){
 
        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");
            if(in == NULL){
            if(in == NULL){
                free_cpu(s);
                free_cpu(s);
                printf("Can't open file %s, quitting!\n",args->bin_filename[i]);
                printf("Can't open file %s, quitting!\n",args->bin_filename[i]);
                return(0);
                return(0);
            }
            }
 
 
            bytes = fread(s->blocks[i].mem, 1, s->blocks[i].size, in);
            /* FIXME load offset 0x2000 for linux kernel hardcoded! */
 
            //bytes = fread((s->blocks[i].mem + 0x2000), 1, s->blocks[i].size, in);
 
            target = (uint8_t *)(s->blocks[i].mem + args->offset[i]);
 
            while(!feof(in) &&
 
                  ((bytes+1024+args->offset[i]) < (s->blocks[i].size))){
 
                bytes += fread(&(target[bytes]), 1, 1024, in);
 
                if(errno!=0){
 
                    printf("ERROR: file load failed with code %d ('%s')\n",
 
                        errno, strerror(errno));
 
                    free_cpu(s);
 
                    return 0;
 
                }
 
            }
 
 
            fclose(in);
            fclose(in);
 
 
 
            /* Now reverse the endianness of the data we just read, if it's
 
             necessary. */
 
             /* FIXME add cmd line param, etc. */
 
            //reverse_endianess(target, bytes);
 
 
 
            files_read++;
 
        }
            printf("%-16s [size= %6dKB, start= 0x%08x] loaded %d bytes.\n",
            printf("%-16s [size= %6dKB, start= 0x%08x] loaded %d bytes.\n",
                    s->blocks[i].area_name,
                    s->blocks[i].area_name,
                    s->blocks[i].size/1024,
                    s->blocks[i].size/1024,
                    s->blocks[i].start,
                    s->blocks[i].start,
                    bytes);
                    bytes);
            files_read++;
 
        }
 
    }
    }
 
 
    if(!files_read){
    if(!files_read){
        free_cpu(s);
        free_cpu(s);
        printf("No binary object files read, quitting\n");
        printf("No binary object files read, quitting\n");
Line 1067... Line 1207...
    }
    }
 
 
    return files_read;
    return files_read;
}
}
 
 
 
void reverse_endianess(uint8_t *data, uint32_t bytes){
 
    uint8_t w[4];
 
    uint32_t i, j;
 
 
 
    for(i=0;i<bytes;i=i+4){
 
        for(j=0;j<4;j++){
 
            w[3-j] = data[i+j];
 
        }
 
        for(j=0;j<4;j++){
 
            data[i+j] = w[j];
 
        }
 
    }
 
}
 
 
 
 
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
 
 
int main(int argc,char *argv[]){
int main(int argc,char *argv[]){
    t_state state, *s=&state;
    t_state state, *s=&state;
 
 
    printf("MIPS-I emulator (" __DATE__ ")\n\n");
 
    if(!init_cpu(s)){
 
        printf("Trouble allocating memory, quitting!\n");
 
        return 1;
 
    };
 
 
 
    /* 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;
    }
    }
 
 
 
    printf("MIPS-I emulator (" __DATE__ ")\n\n");
 
    if(!init_cpu(s, &cmd_line_args)){
 
        printf("Trouble allocating memory, quitting!\n");
 
        return 1;
 
    };
 
 
    /* Read binary object files into memory*/
    /* Read binary object files into memory*/
    if(!read_binary_files(s, &cmd_line_args)){
    if(!read_binary_files(s, &cmd_line_args)){
        return 2;
        return 2;
    }
    }
    printf("\n\n");
    printf("\n\n");
Line 1098... Line 1253...
    */
    */
 
 
    /* Simulate a CPU reset */
    /* Simulate a CPU reset */
    reset_cpu(s);
    reset_cpu(s);
 
 
 
    /* Simulate the work of the uClinux bootloader */
 
    if(cmd_line_args.memory_map == MAP_UCLINUX){
 
        /* FIXME this is a stub, flesh it out */
 
        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);
    do_debug(s, cmd_line_args.no_prompt);
 
 
    /* Close and deallocate everything and quit */
    /* Close and deallocate everything and quit */
    close_trace_buffer(s);
    close_trace_buffer(s);
    free_cpu(s);
    free_cpu(s);
    return(0);
    return(0);
Line 1254... Line 1415...
    s->pc = VECTOR_RESET;     /* reset start vector */
    s->pc = VECTOR_RESET;     /* reset start vector */
    s->delay_slot = 0;
    s->delay_slot = 0;
    s->failed_assertions = 0; /* no failed assertions pending */
    s->failed_assertions = 0; /* no failed assertions pending */
}
}
 
 
int init_cpu(t_state *s){
void unimplemented(t_state *s, const char *txt){
 
    /* FIXME unimplemented opcode trap */
 
    printf("UNIMPLEMENTED: %s\n", txt);
 
}
 
 
 
int init_cpu(t_state *s, t_args *args){
    int i, j;
    int i, j;
 
    uint32_t k = args->memory_map;
 
 
    memset(s, 0, sizeof(t_state));
    memset(s, 0, sizeof(t_state));
    s->big_endian = 1;
    s->big_endian = 1;
 
 
 
    s->do_unaligned = args->do_unaligned;
 
    s->breakpoint = args->breakpoint;
 
 
    /* Initialize memory map */
    /* Initialize memory map */
    for(i=0;i<NUM_MEM_BLOCKS;i++){
    for(i=0;i<NUM_MEM_BLOCKS;i++){
        s->blocks[i].start =  memory_map_default[i].start;
        s->blocks[i].start =        memory_maps[k].blocks[i].start;
        s->blocks[i].size =  memory_map_default[i].size;
        s->blocks[i].size =         memory_maps[k].blocks[i].size;
        s->blocks[i].area_name =  memory_map_default[i].area_name;
        s->blocks[i].area_name =    memory_maps[k].blocks[i].area_name;
        s->blocks[i].mask =  memory_map_default[i].mask;
        s->blocks[i].mask =         memory_maps[k].blocks[i].mask;
        s->blocks[i].read_only =  memory_map_default[i].read_only;
        s->blocks[i].read_only =    memory_maps[k].blocks[i].read_only;
 
 
        s->blocks[i].mem = (unsigned char*)malloc(s->blocks[i].size);
        s->blocks[i].mem = (unsigned char*)malloc(s->blocks[i].size);
 
 
        if(s->blocks[i].mem == NULL){
        if(s->blocks[i].mem == NULL){
            for(j=0;j<i;j++){
            for(j=0;j<i;j++){
Line 1285... Line 1455...
 
 
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;
 
 
    /* fill cmd line args with default values */
    /* fill cmd line args with default values */
    for(i=0;i<NUM_MEM_BLOCKS;i++){
    args->memory_map = MAP_DEFAULT;
        args->bin_filename[i] = NULL;
    args->do_unaligned = 0;
 
    args->no_prompt = 0;
 
    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;
 
    for(i=0;i<NUM_MEM_BLOCKS;i++){
 
        args->bin_filename[i] = NULL;
 
        args->offset[i] = 0;
    }
    }
 
 
    /* parse actual cmd line args */
    /* parse actual cmd line args */
    for(i=1;i<argc;i++){
    for(i=1;i<argc;i++){
        if(strcmp(argv[i],"--plasma")==0){
        if(strcmp(argv[i],"--plasma")==0){
            #ifdef SIMULATE_PLASMA
            /* plasma simulation not supported, error*/
                /* program compiled for plasma compatibility, no problem */
 
            #else
 
                /* program compiled for mips-1 compatibility, 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;
            #endif
        }
 
        else if(strcmp(argv[i],"--uclinux")==0){
 
            args->memory_map = MAP_UCLINUX;
 
            /* FIXME selecting uClinux enables unaligned L/S emulation */
 
            args->do_unaligned = 1;
 
        }
 
        else if(strcmp(argv[i],"--unaligned")==0){
 
            args->do_unaligned = 1;
 
        }
 
        else if(strcmp(argv[i],"--noprompt")==0){
 
            args->no_prompt = 1;
        }
        }
        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[2] = &(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],"--kernel=", strlen("--kernel="))==0){
 
            args->bin_filename[1] = &(argv[i][strlen("--kernel=")]);
 
            /* FIXME uClinux kernel 'offset' hardcoded */
 
            args->offset[1] = 0x2000;
 
        }
        else if(strncmp(argv[i],"--trigger=", strlen("--trigger="))==0){
        else if(strncmp(argv[i],"--trigger=", strlen("--trigger="))==0){
            sscanf(&(argv[i][strlen("--trigger=")]), "%x", &(args->log_trigger_address));
            sscanf(&(argv[i][strlen("--trigger=")]), "%x", &(args->log_trigger_address));
        }
        }
 
        else if(strncmp(argv[i],"--breakpoint=", strlen("--breakpoint="))==0){
 
            sscanf(&(argv[i][strlen("--breakpoint=")]), "%x", &(args->breakpoint));
 
        }
        else if((strcmp(argv[i],"--help")==0)||(strcmp(argv[i],"-h")==0)){
        else if((strcmp(argv[i],"--help")==0)||(strcmp(argv[i],"-h")==0)){
            usage();
            usage();
            return 0;
            return 0;
        }
        }
        else{
        else{
Line 1334... Line 1524...
    printf("Usage:");
    printf("Usage:");
    printf("    slite file.exe [arguments]\n");
    printf("    slite file.exe [arguments]\n");
    printf("Arguments:\n");
    printf("Arguments:\n");
    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("                          (loads at block offset 0x2000)\n");
    printf("--flash=<file name>     : FLASH initialization file\n");
    printf("--flash=<file name>     : FLASH initialization file\n");
    printf("--trigger=<hex number>  : Log trigger address\n");
    printf("--trigger=<hex number>  : Log trigger address\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("--unaligned             : Implement unaligned load/store instructions\n");
 
    printf("--noprompt              : Run in batch mode\n");
 
    printf("--stop_at_zero          : Stop simulation when fetching from address 0x0\n");
    printf("--help, -h              : Show this usage text\n");
    printf("--help, -h              : Show this usage text\n");
}
}
 
 
 No newline at end of file
 No newline at end of file
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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