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

Subversion Repositories ion

[/] [ion/] [trunk/] [tools/] [slite/] [src/] [slite.c] - Diff between revs 147 and 152

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

Rev 147 Rev 152
Line 41... Line 41...
#include <stdint.h>
#include <stdint.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <ctype.h>
#include <assert.h>
#include <assert.h>
 
 
 
#define R3000_ID (0x00000200)
 
 
/** Set to !=0 to disable file logging (much faster simulation) */
/** Set to !=0 to disable file logging (much faster simulation) */
#define FILE_LOGGING_DISABLED (0)
#define FILE_LOGGING_DISABLED (0)
/** Define to enable cache simulation (unimplemented) */
/** Define to enable cache simulation (unimplemented) */
//#define ENABLE_CACHE
//#define ENABLE_CACHE
 
 
Line 63... Line 65...
    uint8_t  *mem;
    uint8_t  *mem;
    char     *area_name;
    char     *area_name;
} t_block;
} t_block;
 
 
#define NUM_MEM_BLOCKS      (4)
#define NUM_MEM_BLOCKS      (4)
#define NUM_MEM_MAPS        (3)
#define NUM_MEM_MAPS        (4)
 
 
/** Definition of a memory map */
/** Definition of a memory map */
/* FIXME i/o addresses missing, hardcoded */
/* FIXME i/o addresses missing, hardcoded */
typedef struct s_map {
typedef struct s_map {
    t_block blocks[NUM_MEM_BLOCKS];
    t_block blocks[NUM_MEM_BLOCKS];
Line 94... Line 96...
    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 MAP_DEFAULT (0)
#define MAP_DEFAULT (0)
#define MAP_UCLINUX (1)
#define MAP_UCLINUX_BRAM    (1)  /* debug only */
#define MAP_SMALL   (2)
#define MAP_SMALL   (2)
 
#define MAP_UCLINUX         (3)
 
 
t_map memory_maps[NUM_MEM_MAPS] = {
t_map memory_maps[NUM_MEM_MAPS] = {
    {/* Experimental memory map (default) */
    {/* Experimental memory map (default) */
        {/* Bootstrap BRAM, read only */
        {/* Bootstrap BRAM, read only */
        {VECTOR_RESET,  0x00004800, 0xf8000000, 1, NULL, "Boot BRAM"},
        {VECTOR_RESET,  0x00004800, 0xf8000000, 1, NULL, "Boot BRAM"},
Line 110... Line 113...
        /* external flash block */
        /* external flash block */
        {0xb0000000,    0x00040000, 0xf8000000, 0, NULL, "Flash"},
        {0xb0000000,    0x00040000, 0xf8000000, 0, NULL, "Flash"},
        }
        }
    },
    },
 
 
    {/* uClinux memory map */
    {/* 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,    0x00200000, 0xf8000000, 0, NULL, "XRAM0"},
        {0x00000000,    0x00400000, 0xf8000000, 0, NULL, "XRAM1"},
        {0x00000000,    0x00400000, 0xf8000000, 0, NULL, "XRAM1"},
Line 132... Line 135...
        {0x80000000,    0x00001000, 0xf8000000, 0, NULL, "XRAM1"},
        {0x80000000,    0x00001000, 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 with FLASH and XRAM */
 
        {/* Flash mapped at two different addresses is actually meant to be
 
            a single chip (note they have the same size). */
 
         /* E.g. put the bootloader at 0xbfc00000 and the romfs at 0xb0020000;
 
            chip offsets will be 0x0 and 0x20000. */
 
         /* Don't forget there's no address translation here. */
 
        {0xbfc00000,    0x00400000, 0xf8000000, 1, NULL, "Flash (bootloader)"},
 
        {0xb0000000,    0x00400000, 0xf8000000, 1, NULL, "Flash (romfs)"},
 
        /* main external ram block (kernal & user areas ) */
 
        {0x80000000,    0x00200000, 0xf8000000, 0, NULL, "XRAM (kernel)"},
 
        {0x00000000,    0x00400000, 0xf8000000, 0, NULL, "XRAM (user)"},
 
        }
 
    },
};
};
 
 
 
 
/*---- end of system parameters ----------------------------------------------*/
/*---- end of system parameters ----------------------------------------------*/
 
 
Line 272... Line 289...
   unsigned int next;                     /**< internal queue head pointer */
   unsigned int next;                     /**< internal queue head pointer */
   FILE *log;                             /**< text log file or NULL */
   FILE *log;                             /**< text log file or NULL */
   int log_triggered;                     /**< !=0 if log has been triggered */
   int log_triggered;                     /**< !=0 if log has been triggered */
   uint32_t log_trigger_address;          /**< */
   uint32_t log_trigger_address;          /**< */
   int pr[32];                            /**< last value of register bank */
   int pr[32];                            /**< last value of register bank */
   int hi, lo, epc;                       /**< last value of internal regs */
   int hi, lo, epc, status;               /**< last value of internal regs */
} 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 */
Line 346... Line 363...
void log_cycle(t_state *s);
void 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);
 
 
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 876... Line 894...
        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: printf("ERROR0(*0x%x~0x%x)\n", s->pc, opcode);
 
            /* FIXME should trap unknown opcode */
           s->wakeup=1;
           s->wakeup=1;
        }
        }
        break;
        break;
    case 0x01:/*REGIMM*/
    case 0x01:/*REGIMM*/
        switch(rt){
        switch(rt){
Line 908... Line 927...
    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(s->status & 0x02){ /* kernel mode? */
        if((opcode & (1<<23)) == 0){  //move from CP0 (mfc0)
        if((opcode & (1<<23)) == 0){  //move from CP0 (mfc0)
            switch(rd){
            switch(rd){
                case 12: r[rt]=s->status & 0xffff; 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]=0x00000200; break;
                    case 15: r[rt]=R3000_ID; break;
                default:
                default:
                    //printf("mfco [%02d]\n", rd);
                    //printf("mfco [%02d]\n", rd);
                    break;
                    break;
            }
            }
        }
        }
        else{                         //move to CP0 (mtc0)
        else{                         //move to CP0 (mtc0)
            /* FIXME check CF= reg address */
            /* FIXME check CF= reg address */
            s->status=r[rt];
                s->status=r[rt] & 0x0003003f; /* mask W/O bits */
            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);
            }
            }
        }
        }
 
        }
 
        else{
 
            /* tried to execute mtc* or mfc* in user mode: trap */
 
            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;
Line 993... Line 1019...
//      case 0x3f:/*SDC3*/ break;
//      case 0x3f:/*SDC3*/ break;
    default:
    default:
        ;
        ;
        /* FIXME should trap unimplemented opcodes */
        /* FIXME should trap unimplemented opcodes */
        /* FIXME newlib */
        /* FIXME newlib */
        printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);
        printf("ERROR2 address=0x%x opcode=0x%x -- ", epc, opcode);
 
        print_opcode_fields(opcode);
 
        printf("\n");
        s->wakeup=1;
        s->wakeup=1;
    }
    }
 
 
    /* adjust next PC if this was a ajump instruction */
    /* adjust next PC if this was a ajump instruction */
    s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
    s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
Line 1014... Line 1042...
    /* load delay slots not simulated */
    /* load delay slots not simulated */
 
 
    /* Handle exceptions */
    /* Handle exceptions */
   if(s->exceptionId){
   if(s->exceptionId){
        r[rt] = rSave;
        r[rt] = rSave;
        s->cp0_cause = (s->delay_slot & 0x1) << 31 | (trap_cause & 0x1f);
        /* set cause field ... */
 
        s->cp0_cause = (s->delay_slot & 0x1) << 31 | (trap_cause & 0x1f) << 2;
 
        /* ...save previous KU/IE flags in SR... */
 
        s->status = (s->status & 0xffffffc3) | ((s->status & 0x0f) << 2);
 
        /* ...and raise KU(EXL) kernel mode flag */
 
        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 */
        if(s->delay_slot){
        if(s->delay_slot){
        epc = epc - 4;
        epc = epc - 4;
        }
        }
        s->epc = epc;
        s->epc = epc;
Line 1040... Line 1073...
       the next instruction will be in a delay slot. Remember it. */
       the next instruction will be in a delay slot. Remember it. */
    delay_slot = ((lbranch==1) || branch || delay_slot);
    delay_slot = ((lbranch==1) || branch || delay_slot);
    s->delay_slot = delay_slot;
    s->delay_slot = delay_slot;
}
}
 
 
 
/** Print opcode fields for easier debugging */
 
void print_opcode_fields(uint32_t opcode){
 
    uint32_t field;
 
 
 
    field = (opcode >> 26)&0x3f;
 
    printf("%02x:", field);
 
    field = (opcode >> 21)&0x1f;
 
    printf("%02x:", field);
 
    field = (opcode >> 16)&0x1f;
 
    printf("%02x:", field);
 
    field = (opcode >> 11)&0x1f;
 
    printf("%02x:", field);
 
    field = (opcode >>  6)&0x1f;
 
    printf("%02x:", field);
 
    field = (opcode >>  0)&0x3f;
 
    printf("%02x",  field);
 
}
 
 
 
 
/** 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);
    printf("hi=0x%08x lo=0x%08x\n", s->hi, s->lo);
    printf("hi=0x%08x lo=0x%08x\n", s->hi, s->lo);
Line 1370... Line 1422...
        if(s->hi != s->t.hi){
        if(s->hi != s->t.hi){
            //fprintf(s->t.log, "(%08X) [HI]=%08X\n", log_pc, s->hi);
            //fprintf(s->t.log, "(%08X) [HI]=%08X\n", log_pc, s->hi);
        }
        }
        s->t.hi = s->hi;
        s->t.hi = s->hi;
 
 
        /* */
        /* Catch changes in EPC by direct write (mtc0) and by exception */
        /* FIXME epc may change by direct write too, handle case */
 
        if(s->epc != s->t.epc){
        if(s->epc != s->t.epc){
            fprintf(s->t.log, "(%08X) [EP]=%08X\n", log_pc, s->epc);
            fprintf(s->t.log, "(%08X) [EP]=%08X\n", log_pc, s->epc);
        }
        }
        s->t.epc = s->epc;
        s->t.epc = s->epc;
 
 
 
        if(s->status != s->t. status){
 
            fprintf(s->t.log, "(%08X) [SR]=%08X\n", log_pc, s->status);
 
        }
 
        s->t.status = s->status;
    }
    }
}
}
 
 
/** 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){
Line 1435... Line 1491...
 
 
void reset_cpu(t_state *s){
void reset_cpu(t_state *s){
    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 */
 
    s->status = 0x02; /* kernel mode, interrupts disabled */
 
    /* init trace struct to prevent spurious logs */
 
    s->t.status = s->status;
}
}
 
 
void unimplemented(t_state *s, const char *txt){
void unimplemented(t_state *s, const char *txt){
    /* FIXME unimplemented opcode trap */
    /* FIXME unimplemented opcode trap */
    printf("UNIMPLEMENTED: %s\n", txt);
    printf("UNIMPLEMENTED: %s\n", txt);

powered by: WebSVN 2.1.0

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