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

Subversion Repositories ion

[/] [ion/] [trunk/] [tools/] [slite/] [src/] [slite.c] - Diff between revs 27 and 31

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

Rev 27 Rev 31
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>
 
 
/** Set to !=0 to disable file logging */
/** 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
 
 
 
 
#define MEM_SIZE (1024*1024*2)
/*---- Definition of simulated system parameters -----------------------------*/
 
 
 
 
 
#define VECTOR_RESET (0x00000000)
 
#define VECTOR_TRAP  (0x0000003c)
 
 
 
typedef struct s_block {
 
    uint32_t start;
 
    uint32_t size;
 
    uint8_t  *mem;
 
    char     *name;
 
} t_block;
 
 
 
 
 
/* Here's where we define the memory areas (blocks) of the system */
 
/* (make sure they don't overlap or the simulated program will crash) */
 
 
 
#define NUM_MEM_BLOCKS (2)
 
 
 
t_block default_blocks[NUM_MEM_BLOCKS] = {
 
    /* meant as bootstrap block, though it's read/write */
 
    {VECTOR_RESET,  0x00010000, NULL, "ROM"},
 
    /* main ram block  */
 
    {0x80000000,    0x00010000, NULL, "Data"}
 
};
 
 
 
 
#define ntohs(A) ( ((A)>>8) | (((A)&0xff)<<8) )
#define ntohs(A) ( ((A)>>8) | (((A)&0xff)<<8) )
#define htons(A) ntohs(A)
#define htons(A) ntohs(A)
#define ntohl(A) ( ((A)>>24) | (((A)&0xff0000)>>8) | (((A)&0xff00)<<8) | ((A)<<24) )
#define ntohl(A) ( ((A)>>24) | (((A)&0xff0000)>>8) | (((A)&0xff00)<<8) | ((A)<<24) )
#define htonl(A) ntohl(A)
#define htonl(A) ntohl(A)
 
 
Line 60... Line 86...
//Support for Linux
//Support for Linux
#define putch putchar
#define putch putchar
#include <termios.h>
#include <termios.h>
#include <unistd.h>
#include <unistd.h>
 
 
void Sleep(unsigned int value)
void slite_sleep(unsigned int value){
{
 
   usleep(value * 1000);
   usleep(value * 1000);
}
}
 
 
int kbhit(void)
int kbhit(void){
{
 
   struct termios oldt, newt;
   struct termios oldt, newt;
   struct timeval tv;
   struct timeval tv;
   fd_set read_fd;
   fd_set read_fd;
 
 
   tcgetattr(STDIN_FILENO, &oldt);
   tcgetattr(STDIN_FILENO, &oldt);
Line 79... Line 103...
   tcsetattr(STDIN_FILENO, TCSANOW, &newt);
   tcsetattr(STDIN_FILENO, TCSANOW, &newt);
   tv.tv_sec=0;
   tv.tv_sec=0;
   tv.tv_usec=0;
   tv.tv_usec=0;
   FD_ZERO(&read_fd);
   FD_ZERO(&read_fd);
   FD_SET(0,&read_fd);
   FD_SET(0,&read_fd);
   if(select(1, &read_fd, NULL, NULL, &tv) == -1)
    if(select(1, &read_fd, NULL, NULL, &tv) == -1){
      return 0;
      return 0;
 
    }
   //tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
   //tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
   if(FD_ISSET(0,&read_fd))
    if(FD_ISSET(0,&read_fd)){
      return 1;
      return 1;
 
    }
   return 0;
   return 0;
}
}
 
 
int getch(void)
int getch(void){
{
 
   struct termios oldt, newt;
   struct termios oldt, newt;
   int ch;
   int ch;
 
 
   tcgetattr(STDIN_FILENO, &oldt);
   tcgetattr(STDIN_FILENO, &oldt);
   newt = oldt;
   newt = oldt;
Line 104... Line 129...
}
}
#else
#else
//Support for Windows
//Support for Windows
#include <conio.h>
#include <conio.h>
extern void __stdcall Sleep(unsigned long value);
extern void __stdcall Sleep(unsigned long value);
 
 
 
void slite_sleep(unsigned int value){
 
    Sleep(value);
 
}
 
 
#endif
#endif
/*---- End of OS-dependent support functions and definitions -----------------*/
/*---- End of OS-dependent support functions and definitions -----------------*/
 
 
/*---- 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 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 128... Line 157...
#define IRQ_UART_WRITE_AVAILABLE 0x002
#define IRQ_UART_WRITE_AVAILABLE 0x002
#define IRQ_COUNTER18_NOT        0x004
#define IRQ_COUNTER18_NOT        0x004
#define IRQ_COUNTER18            0x008
#define IRQ_COUNTER18            0x008
#define IRQ_MMU                  0x200
#define IRQ_MMU                  0x200
 
 
#define MMU_ENTRIES 4
 
#define MMU_MASK (1024*4-1)
 
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
 
 
/* These are flags that will be used to notify the main cycle function of any
/* These are flags that will be used to notify the main cycle function of any
   failed assertions in its subfunctions. */
   failed assertions in its subfunctions. */
#define ASRT_UNALIGNED_READ         (1<<0)
#define ASRT_UNALIGNED_READ         (1<<0)
Line 146... Line 173...
 
 
 
 
/** Length of debugging jump target queue */
/** Length of debugging jump target queue */
#define TRACE_BUFFER_SIZE (32)
#define TRACE_BUFFER_SIZE (32)
 
 
typedef struct {
typedef struct s_trace {
   unsigned int buf[TRACE_BUFFER_SIZE];   /**< queue of last jump targets */
   unsigned int buf[TRACE_BUFFER_SIZE];   /**< queue of last jump targets */
   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 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;                       /**< last value of internal regs */
} Trace;
} t_trace;
 
 
typedef struct
typedef struct s_state {
{
 
   unsigned int virtualAddress;
 
   unsigned int physicalAddress;
 
} MmuEntry;
 
 
 
typedef struct {
 
   unsigned failed_assertions;            /**< assertion bitmap */
   unsigned failed_assertions;            /**< assertion bitmap */
   unsigned faulty_address;               /**< addr that failed assertion */
   unsigned faulty_address;               /**< addr that failed assertion */
 
 
   int delay_slot;              /**< !=0 if prev. instruction was a branch */
   int delay_slot;              /**< !=0 if prev. instruction was a branch */
 
 
Line 179... Line 200...
   int processId;
   int processId;
   int exceptionId;        /**< DEPRECATED, to be removed */
   int exceptionId;        /**< DEPRECATED, to be removed */
   int faultAddr;
   int faultAddr;
   int irqStatus;
   int irqStatus;
   int skip;
   int skip;
   Trace t;
   t_trace t;
   unsigned char *mem;
   //unsigned char *mem;
 
   t_block blocks[NUM_MEM_BLOCKS];
   int wakeup;
   int wakeup;
   int big_endian;
   int big_endian;
   MmuEntry mmuEntry[MMU_ENTRIES];
} t_state;
} State;
 
 
 
static char *opcode_string[]={
static char *opcode_string[]={
   "SPECIAL","REGIMM","J","JAL","BEQ","BNE","BLEZ","BGTZ",
   "SPECIAL","REGIMM","J","JAL","BEQ","BNE","BLEZ","BGTZ",
   "ADDI","ADDIU","SLTI","SLTIU","ANDI","ORI","XORI","LUI",
   "ADDI","ADDIU","SLTI","SLTIU","ANDI","ORI","XORI","LUI",
   "COP0","COP1","COP2","COP3","BEQL","BNEL","BLEZL","BGTZL",
   "COP0","COP1","COP2","COP3","BEQL","BNEL","BLEZL","BGTZL",
Line 220... Line 241...
static unsigned int HWMemory[8];
static unsigned int HWMemory[8];
 
 
/*---- Local function prototypes ---------------------------------------------*/
/*---- Local function prototypes ---------------------------------------------*/
 
 
/* Debug and logging */
/* Debug and logging */
void init_trace_buffer(State *s, const char *log_file_name);
void init_trace_buffer(t_state *s, const char *log_file_name);
void close_trace_buffer(State *s);
void close_trace_buffer(t_state *s);
void dump_trace_buffer(State *s);
void dump_trace_buffer(t_state *s);
void log_cycle(State *s);
void log_cycle(t_state *s);
void log_read(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(State *s);
void log_failed_assertions(t_state *s);
 
 
 
/* CPU model */
 
void free_cpu(t_state *s);
 
void init_cpu(t_state *s);
 
void reset_cpu(t_state *s);
 
 
/* Hardware simulation */
/* Hardware simulation */
int mem_read(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(State *s, int size, int unsigned address, unsigned value);
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log);
void start_load(State *s, int rt, int data);
void start_load(t_state *s, int rt, int data);
 
 
 
 
/*---- Local functions -------------------------------------------------------*/
/*---- Local functions -------------------------------------------------------*/
 
 
/** 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(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(s->t.log!=NULL && log!=0){
   if(s->t.log!=NULL && log!=0){
      if(size==4){ size=0x04; }
      if(size==4){ size=0x04; }
      else if(size==2){ size=0x02; }
      else if(size==2){ size=0x02; }
      else { size=0x01; }
      else { size=0x01; }
      fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD\n",
      fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD\n",
              s->pc, full_address, /*size,*/ word_value);
              s->pc, full_address, /*size,*/ word_value);
   }
   }
}
}
 
 
/** Read memory, optionally logging */
/** Read memory, optionally logging */
int mem_read(State *s, int size, unsigned int address, int log)
int mem_read(t_state *s, int size, unsigned int address, int log){
{
    unsigned int value=0, word_value=0, i, ptr;
   unsigned int value=0, word_value=0, ptr;
 
   unsigned int full_address = address;
   unsigned int full_address = address;
 
 
   s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
   s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
   switch(address)
    switch(address){
   {
 
      case UART_READ:
      case UART_READ:
         word_value = 0x00000001;
         word_value = 0x00000001;
         log_read(s, full_address, word_value, size, log);
         log_read(s, full_address, word_value, size, log);
         return word_value;
         return word_value;
         /* FIXME Take input from text file */
         /* FIXME Take input from text file */
Line 270... Line 294...
         return HWMemory[0];
         return HWMemory[0];
         */
         */
      case IRQ_MASK:
      case IRQ_MASK:
         return HWMemory[1];
         return HWMemory[1];
      case IRQ_MASK + 4:
      case IRQ_MASK + 4:
         Sleep(10);
       slite_sleep(10);
         return 0;
         return 0;
      case IRQ_STATUS:
      case IRQ_STATUS:
         /*if(kbhit())
         /*if(kbhit())
            s->irqStatus |= IRQ_UART_READ_AVAILABLE;
            s->irqStatus |= IRQ_UART_READ_AVAILABLE;
         return s->irqStatus;
         return s->irqStatus;
Line 287... Line 311...
         return s->processId;
         return s->processId;
      case MMU_FAULT_ADDR:
      case MMU_FAULT_ADDR:
         return s->faultAddr;
         return s->faultAddr;
   }
   }
 
 
   ptr = (unsigned int)s->mem + (address % MEM_SIZE);
    /* point ptr to the byte in the block, or NULL is the address is unmapped */
 
    ptr = 0;
   if(0x10000000 <= address && address < 0x10000000 + 1024*1024)
    for(i=0;i<NUM_MEM_BLOCKS;i++){
      ptr += 1024*1024;
        if(address >= s->blocks[i].start &&
 
          address < s->blocks[i].start + s->blocks[i].size){
 
            ptr = (unsigned)(s->blocks[i].mem) + address - s->blocks[i].start;
 
            break;
 
        }
 
    }
 
    if(!ptr){
 
        /* address out of mapped blocks: log and return zero */
 
        if(s->t.log!=NULL && log!=0){
 
            fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD UNMAPPED\n",
 
                s->pc, full_address, 0);
 
        }
 
        return 0;
 
    }
 
 
 
    /* get the whole word */
   word_value = *(int*)(ptr&0xfffffffc);
   word_value = *(int*)(ptr&0xfffffffc);
   if(s->big_endian)
    if(s->big_endian){
            word_value = ntohl(word_value);
            word_value = ntohl(word_value);
   switch(size)
    }
   {
 
 
    switch(size){
      case 4:
      case 4:
         if(address & 3){
         if(address & 3){
            printf("Unaligned access PC=0x%x address=0x%x\n",
            printf("Unaligned access PC=0x%x address=0x%x\n",
                   (int)s->pc, (int)address);
                   (int)s->pc, (int)address);
         }
         }
         /* We don't want the program to just quit, we want to log the fault */
 
         /* assert((address & 3) == 0); */
 
         if((address & 3) != 0){
         if((address & 3) != 0){
 
            /* unaligned word, log fault */
            s->failed_assertions |= ASRT_UNALIGNED_READ;
            s->failed_assertions |= ASRT_UNALIGNED_READ;
            s->faulty_address = address;
            s->faulty_address = address;
            address = address & 0xfffffffc;
            address = address & 0xfffffffc;
         }
         }
         value = *(int*)ptr;
         value = *(int*)ptr;
         if(s->big_endian)
        if(s->big_endian){
            value = ntohl(value);
            value = ntohl(value);
 
        }
         break;
         break;
      case 2:
      case 2:
         /* We don't want the program to just quit, we want to log the fault */
 
         /* assert((address & 1) == 0); */
 
         if((address & 1) != 0){
         if((address & 1) != 0){
 
            /* unaligned halfword, log fault */
            s->failed_assertions |= ASRT_UNALIGNED_READ;
            s->failed_assertions |= ASRT_UNALIGNED_READ;
            s->faulty_address = address;
            s->faulty_address = address;
            address = address & 0xfffffffe;
            address = address & 0xfffffffe;
         }
         }
         value = *(unsigned short*)ptr;
         value = *(unsigned short*)ptr;
         if(s->big_endian)
        if(s->big_endian){
            value = ntohs((unsigned short)value);
            value = ntohs((unsigned short)value);
 
        }
         break;
         break;
      case 1:
      case 1:
         value = *(unsigned char*)ptr;
         value = *(unsigned char*)ptr;
         break;
         break;
      default:
      default:
 
        /* FIXME this is a bug, should quit */
         printf("ERROR");
         printf("ERROR");
   }
   }
 
 
   log_read(s, full_address, word_value, size, log);
   log_read(s, full_address, word_value, size, log);
   return(value);
   return(value);
}
}
 
 
/** Write memory */
/** Write memory */
void mem_write(State *s, int size, unsigned address, unsigned value)
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log){
{
    unsigned int i, ptr, mask, dvalue, b0, b1, b2, b3;
   unsigned int ptr, mask, dvalue, b0, b1, b2, b3;
 
 
 
   if(s->t.log!=NULL){
   if(s->t.log!=NULL){
      b0 = value & 0x000000ff;
      b0 = value & 0x000000ff;
      b1 = value & 0x0000ff00;
      b1 = value & 0x0000ff00;
      b2 = value & 0x00ff0000;
      b2 = value & 0x00ff0000;
Line 351... Line 390...
 
 
      switch(size){
      switch(size){
         case 4:  mask = 0x0f;
         case 4:  mask = 0x0f;
                  dvalue = value;
                  dvalue = value;
                  break;
                  break;
 
        case 2:
         case 2:  if((address&0x2)==0){
            if((address&0x2)==0){
                     mask = 0xc;
                     mask = 0xc;
                     dvalue = b1<<16 | b0<<16;
                     dvalue = b1<<16 | b0<<16;
                  }
                  }
                  else{
                  else{
                     mask = 0x3;
                     mask = 0x3;
                     dvalue = b1 | b0;
                     dvalue = b1 | b0;
                  }
                  }
                  break;
                  break;
         case 1:  switch(address%4){
        case 1:
 
            switch(address%4){
                  case 0 : mask = 0x8;
                  case 0 : mask = 0x8;
                           dvalue = b0<<24;
                           dvalue = b0<<24;
                           break;
                           break;
                  case 1 : mask = 0x4;
                  case 1 : mask = 0x4;
                           dvalue = b0<<16;
                           dvalue = b0<<16;
Line 379... Line 419...
                  }
                  }
                  break;
                  break;
         default:
         default:
            printf("BUG: mem write size invalid (%08x)\n", s->pc);
            printf("BUG: mem write size invalid (%08x)\n", s->pc);
            exit(2);
            exit(2);
 
 
      }
      }
      fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR\n", s->pc, address, mask, dvalue);
 
 
        fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR\n",
 
                s->pc, address, mask, dvalue);
   }
   }
 
 
   switch(address)
    switch(address){
   {
 
      case UART_WRITE:
      case UART_WRITE:
         putch(value);
         putch(value);
         fflush(stdout);
         fflush(stdout);
         return;
         return;
      case IRQ_MASK:
      case IRQ_MASK:
Line 404... Line 444...
         //printf("processId=%d\n", value);
         //printf("processId=%d\n", value);
         s->processId = value;
         s->processId = value;
         return;
         return;
   }
   }
 
 
   if(MMU_TLB <= address && address <= MMU_TLB+MMU_ENTRIES * 8)
    //ptr = (unsigned int)s->mem + (address % MEM_SIZE);
   {
    if(address >= 0x80000000){
      //printf("TLB 0x%x 0x%x\n", address - MMU_TLB, value);
        ptr = 1;
      ptr = (unsigned int)s->mmuEntry + address - MMU_TLB;
    }
      *(int*)ptr = value;
    ptr = 0;
      s->irqStatus &= ~IRQ_MMU;
    for(i=0;i<NUM_MEM_BLOCKS;i++){
 
        if(address >= s->blocks[i].start &&
 
          address < s->blocks[i].start + s->blocks[i].size){
 
            ptr = (unsigned)(s->blocks[i].mem) + address - s->blocks[i].start;
 
            break;
 
        }
 
    }
 
    if(!ptr){
 
        /* address out of mapped blocks: log and return zero */
 
        if(s->t.log!=NULL && log!=0){
 
            fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR UNMAPPED\n",
 
                s->pc, address, mask, dvalue);
 
        }
      return;
      return;
   }
   }
 
 
   ptr = (unsigned int)s->mem + (address % MEM_SIZE);
    switch(size){
 
 
   if(0x10000000 <= address && address < 0x10000000 + 1024*1024)
 
      ptr += 1024*1024;
 
 
 
   switch(size)
 
   {
 
      case 4:
      case 4:
         /* We don't want the program to just quit, we want to log the fault */
 
         /* assert((address & 3) == 0); */
 
         if((address & 3) != 0){
         if((address & 3) != 0){
 
            /* unaligned word, log fault */
            s->failed_assertions |= ASRT_UNALIGNED_WRITE;
            s->failed_assertions |= ASRT_UNALIGNED_WRITE;
            s->faulty_address = address;
            s->faulty_address = address;
            address = address & (~0x03);
            address = address & (~0x03);
         }
         }
         if(s->big_endian)
        if(s->big_endian){
            value = htonl(value);
            value = htonl(value);
 
        }
         *(int*)ptr = value;
         *(int*)ptr = value;
         break;
         break;
      case 2:
      case 2:
         /* We don't want the program to just quit, we want to log the fault */
 
         /* assert((address & 1) == 0); */
 
         if((address & 1) != 0){
         if((address & 1) != 0){
 
            /* unaligned halfword, log fault */
            s->failed_assertions |= ASRT_UNALIGNED_WRITE;
            s->failed_assertions |= ASRT_UNALIGNED_WRITE;
            s->faulty_address = address;
            s->faulty_address = address;
            address = address & (~0x01);
            address = address & (~0x01);
         }
         }
         if(s->big_endian)
        if(s->big_endian){
            value = htons((unsigned short)value);
            value = htons((unsigned short)value);
 
        }
         *(short*)ptr = (unsigned short)value;
         *(short*)ptr = (unsigned short)value;
         break;
         break;
      case 1:
      case 1:
         *(char*)ptr = (unsigned char)value;
         *(char*)ptr = (unsigned char)value;
         break;
         break;
      default:
      default:
 
        /* FIXME this is a bug, should quit */
         printf("ERROR");
         printf("ERROR");
   }
   }
}
}
 
 
/*---- Optional MMU and cache implementation ---------------------------------*/
/*---- Optional MMU and cache implementation ---------------------------------*/
Line 459... Line 506...
/*
/*
   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.
*/
*/
 
 
#ifdef ENABLE_CACHE
 
#error Cache simulation missing!
 
#else
 
static void cache_init(void) {}
 
#endif
 
/*---- End optional cache implementation -------------------------------------*/
/*---- End optional cache implementation -------------------------------------*/
 
 
 
 
/** Simulates MIPS-I multiplier unsigned behavior*/
/** Simulates MIPS-I multiplier unsigned behavior*/
void mult_big(unsigned int a,
void mult_big(unsigned int a,
              unsigned int b,
              unsigned int b,
              unsigned int *hi,
              unsigned int *hi,
              unsigned int *lo)
              unsigned int *lo){
{
 
   unsigned int ahi, alo, bhi, blo;
   unsigned int ahi, alo, bhi, blo;
   unsigned int c0, c1, c2;
   unsigned int c0, c1, c2;
   unsigned int c1_a, c1_b;
   unsigned int c1_a, c1_b;
 
 
   ahi = a >> 16;
   ahi = a >> 16;
Line 499... Line 540...
 
 
/** Simulates MIPS-I multiplier signed behavior*/
/** Simulates MIPS-I multiplier signed behavior*/
void mult_big_signed(int a,
void mult_big_signed(int a,
                     int b,
                     int b,
                     unsigned int *hi,
                     unsigned int *hi,
                     unsigned int *lo)
                     unsigned int *lo){
{
 
   int64_t xa, xb, xr, temp;
   int64_t xa, xb, xr, temp;
   int32_t rh, rl;
   int32_t rh, rl;
 
 
   xa = a;
   xa = a;
   xb = b;
   xb = b;
Line 518... Line 558...
   *hi = rh;
   *hi = rh;
   *lo = rl;
   *lo = rl;
}
}
 
 
/** Load data from memory (used to simulate load delay slots) */
/** Load data from memory (used to simulate load delay slots) */
void start_load(State *s, int rt, int data){
void start_load(t_state *s, int rt, int data){
   /* load delay slot not simulated */
   /* load delay slot not simulated */
   s->r[rt] = data;
   s->r[rt] = data;
}
}
 
 
/** Execute one cycle of the CPU (including any interlock stall cycles) */
/** Execute one cycle of the CPU (including any interlock stall cycles) */
void cycle(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 trap_cause = 0;
   int imm_shift, branch=0, lbranch=2, skip2=0;
   int imm_shift, branch=0, lbranch=2, skip2=0;
   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;
 
 
   if(!show_mode){
   if(!show_mode){
 
        /* if we're NOT showing output to console, log state of CPU to file */
      log_cycle(s);
      log_cycle(s);
   }
   }
 
 
   opcode = mem_read(s, 4, s->pc, 0);
   opcode = mem_read(s, 4, s->pc, 0);
   op = (opcode >> 26) & 0x3f;
   op = (opcode >> 26) & 0x3f;
Line 551... Line 591...
   imm = opcode & 0xffff;
   imm = opcode & 0xffff;
   imm_shift = (((int)(short)imm) << 2) - 4;
   imm_shift = (((int)(short)imm) << 2) - 4;
   target = (opcode << 6) >> 4;
   target = (opcode << 6) >> 4;
   ptr = (short)imm + r[rs];
   ptr = (short)imm + r[rs];
   r[0] = 0;
   r[0] = 0;
   if(show_mode)
 
   {
    /* if we are priting state to console, do it now */
 
    if(show_mode){
      printf("%8.8x %8.8x ", s->pc, opcode);
      printf("%8.8x %8.8x ", s->pc, opcode);
      if(op == 0)
        if(op == 0){
         printf("%8s ", special_string[func]);
         printf("%8s ", special_string[func]);
      else if(op == 1)
        }
 
        else if(op == 1){
         printf("%8s ", regimm_string[rt]);
         printf("%8s ", regimm_string[rt]);
      else
        }
 
        else{
         printf("%8s ", opcode_string[op]);
         printf("%8s ", opcode_string[op]);
 
        }
 
 
      printf("$%2.2d $%2.2d $%2.2d $%2.2d ", rs, rt, rd, re);
      printf("$%2.2d $%2.2d $%2.2d $%2.2d ", rs, rt, rd, re);
      printf("%4.4x", imm);
      printf("%4.4x", imm);
      if(show_mode == 1)
        if(show_mode == 1){
         printf(" r[%2.2d]=%8.8x r[%2.2d]=%8.8x", rs, r[rs], rt, r[rt]);
         printf(" r[%2.2d]=%8.8x r[%2.2d]=%8.8x", rs, r[rs], rt, r[rt]);
 
        }
      printf("\n");
      printf("\n");
   }
   }
   if(show_mode > 5)
 
 
    /* if we're just showing state to console, quit and don't run instruction */
 
    if(show_mode > 5){
      return;
      return;
 
    }
 
 
   /* epc will point to the victim instruction, i.e. THIS instruction */
   /* epc will point to the victim instruction, i.e. THIS instruction */
   epc = s->pc;
   epc = s->pc;
 
 
   s->pc = s->pc_next;
   s->pc = s->pc_next;
   s->pc_next = s->pc_next + 4;
   s->pc_next = s->pc_next + 4;
   if(s->skip)
    if(s->skip){
   {
 
      s->skip = 0;
      s->skip = 0;
      return;
      return;
   }
   }
   rSave = r[rt];
   rSave = r[rt];
   switch(op)
 
   {
    switch(op){
      case 0x00:/*SPECIAL*/
      case 0x00:/*SPECIAL*/
         switch(func)
        switch(func){
         {
 
            case 0x00:/*SLL*/  r[rd]=r[rt]<<re;          break;
            case 0x00:/*SLL*/  r[rd]=r[rt]<<re;          break;
            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;
Line 659... Line 707...
      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
         {
 
            if(rd == 12){
            if(rd == 12){
               r[rt]=s->status;
               r[rt]=s->status;
            }
            }
            else if(rd == 13){
            else if(rd == 13){
               r[rt]=s->cp0_cause;
               r[rt]=s->cp0_cause;
            }
            }
            else{
            else{
               r[rt]=s->epc;
               r[rt]=s->epc;
            }
            }
         }
         }
         else                         //move to CP0
        else{                         //move to CP0
         {
 
            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);
            }
            }
Line 711... Line 756...
                           start_load(s, rt, (unsigned char)mem_read(s,1,ptr,1));
                           start_load(s, 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, rt, (unsigned short)mem_read(s,2,ptr,1));
                           start_load(s, rt, (unsigned short)mem_read(s,2,ptr,1));
                           break;
                           break;
      case 0x26:/*LWR*/
    case 0x26:/*LWR*/   //target=32-8*(ptr&3);
                           //target=32-8*(ptr&3);
 
                           //r[rt]=(r[rt]&~((unsigned int)0xffffffff>>target))|
                           //r[rt]=(r[rt]&~((unsigned int)0xffffffff>>target))|
                           //((unsigned int)mem_read(s,4,ptr&~3)>>target);
                           //((unsigned int)mem_read(s,4,ptr&~3)>>target);
                           break;
                           break;
      case 0x28:/*SB*/     mem_write(s,1,ptr,r[rt]);  break;
    case 0x28:/*SB*/    mem_write(s,1,ptr,r[rt],1);  break;
      case 0x29:/*SH*/     mem_write(s,2,ptr,r[rt]);  break;
    case 0x29:/*SH*/    mem_write(s,2,ptr,r[rt],1);  break;
      case 0x2a:/*SWL*/
    case 0x2a:/*SWL*/   //mem_write(s,1,ptr,r[rt]>>24);
                           //mem_write(s,1,ptr,r[rt]>>24);
 
                           //mem_write(s,1,ptr+1,r[rt]>>16);
                           //mem_write(s,1,ptr+1,r[rt]>>16);
                           //mem_write(s,1,ptr+2,r[rt]>>8);
                           //mem_write(s,1,ptr+2,r[rt]>>8);
                           //mem_write(s,1,ptr+3,r[rt]); break;
                           //mem_write(s,1,ptr+3,r[rt]); break;
      case 0x2b:/*SW*/     mem_write(s,4,ptr,r[rt]);  break;
    case 0x2b:/*SW*/    mem_write(s,4,ptr,r[rt],1);  break;
      case 0x2e:/*SWR*/    break; //fixme
    case 0x2e:/*SWR*/   break; //FIXME
      case 0x2f:/*CACHE*/  break;
      case 0x2f:/*CACHE*/  break;
      case 0x30:/*LL*/     //r[rt]=mem_read(s,4,ptr);   break;
      case 0x30:/*LL*/     //r[rt]=mem_read(s,4,ptr);   break;
                           start_load(s, rt, mem_read(s,4,ptr,1));
                           start_load(s, 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;
//      case 0x35:/*LDC1*/ break;
//      case 0x35:/*LDC1*/ break;
//      case 0x36:/*LDC2*/ break;
//      case 0x36:/*LDC2*/ break;
//      case 0x37:/*LDC3*/ break;
//      case 0x37:/*LDC3*/ break;
//      case 0x38:/*SC*/     *(int*)ptr=r[rt]; r[rt]=1; break;
//      case 0x38:/*SC*/     *(int*)ptr=r[rt]; r[rt]=1; break;
      case 0x38:/*SC*/     mem_write(s,4,ptr,r[rt]); r[rt]=1; break;
    case 0x38:/*SC*/    mem_write(s,4,ptr,r[rt],1); r[rt]=1; break;
//      case 0x39:/*SWC1*/ break;
//      case 0x39:/*SWC1*/ break;
//      case 0x3a:/*SWC2*/ break;
//      case 0x3a:/*SWC2*/ break;
//      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: printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);
    default:
 
        /* FIXME should trap unimplemented opcodes */
 
        printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);
         s->wakeup=1;
         s->wakeup=1;
   }
   }
   s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
   s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
   s->pc_next &= ~3;
   s->pc_next &= ~3;
   s->skip = (lbranch == 0) | skip2;
   s->skip = (lbranch == 0) | skip2;
 
 
   /* If there was trouble, log it */
    /* If there was trouble (failed assertions), log it */
   if(s->failed_assertions!=0){
   if(s->failed_assertions!=0){
      log_failed_assertions(s);
      log_failed_assertions(s);
      s->failed_assertions=0;
      s->failed_assertions=0;
   }
   }
 
 
   /* if there's a delayed load pending, do it now: load reg with memory data */
   /* if there's a delayed load pending, do it now: load reg with memory data */
   /* 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);
      s->cp0_cause = (s->delay_slot & 0x1) << 31 | (trap_cause & 0x1f);
      /* 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;
Line 784... Line 827...
   delay_slot = ((lbranch==1) || branch || delay_slot);
   delay_slot = ((lbranch==1) || branch || delay_slot);
   s->delay_slot = delay_slot;
   s->delay_slot = delay_slot;
}
}
 
 
/** Dump CPU state to console */
/** Dump CPU state to console */
void show_state(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);
   for(i = 0; i < 4; ++i)
    for(i = 0; i < 4; ++i){
   {
 
      printf("%2.2d ", i * 8);
      printf("%2.2d ", i * 8);
      for(j = 0; j < 8; ++j)
        for(j = 0; j < 8; ++j){
      {
 
         printf("%8.8x ", s->r[i*8+j]);
         printf("%8.8x ", s->r[i*8+j]);
      }
      }
      printf("\n");
      printf("\n");
   }
   }
   //printf("%8.8lx %8.8lx %8.8lx %8.8lx\n", s->pc, s->pc_next, s->hi, s->lo);
   //printf("%8.8lx %8.8lx %8.8lx %8.8lx\n", s->pc, s->pc_next, s->hi, s->lo);
   j = s->pc;
   j = s->pc;
   for(i = -4; i <= 8; ++i)
    for(i = -4; i <= 8; ++i){
   {
 
      printf("%c", i==0 ? '*' : ' ');
      printf("%c", i==0 ? '*' : ' ');
      s->pc = j + i * 4;
      s->pc = j + i * 4;
      cycle(s, 10);
      cycle(s, 10);
   }
   }
   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(State *s)
void do_debug(t_state *s){
{
 
   int ch;
   int ch;
   int i, j=0, watch=0, addr;
   int i, j=0, watch=0, addr;
   s->pc_next = s->pc + 4;
   s->pc_next = s->pc + 4;
   s->skip = 0;
   s->skip = 0;
   s->wakeup = 0;
   s->wakeup = 0;
   show_state(s);
   show_state(s);
   ch = ' ';
   ch = ' ';
   for(;;)
    for(;;){
   {
        if(ch != 'n'){
      if(ch != 'n')
            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=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 > ");
         printf("7=Watch 8=Jump 9=Quit A=dump > ");
      }
      }
      ch = getch();
      ch = getch();
      if(ch != 'n')
        if(ch != 'n'){
         printf("\n");
         printf("\n");
      switch(ch)
        }
      {
        switch(ch){
      case 'a': case 'A':
      case 'a': case 'A':
         dump_trace_buffer(s); break;
         dump_trace_buffer(s); break;
      case '1': case 'd': case ' ':
      case '1': case 'd': case ' ':
         cycle(s, 0); show_state(s); break;
         cycle(s, 0); show_state(s); break;
      case 'n':
      case 'n':
Line 844... Line 881...
      case '2': case 't':
      case '2': case 't':
         cycle(s, 0); printf("*"); cycle(s, 10); break;
         cycle(s, 0); printf("*"); cycle(s, 10); break;
      case '3': case 's':
      case '3': case 's':
         printf("Count> ");
         printf("Count> ");
         scanf("%d", &j);
         scanf("%d", &j);
         for(i = 0; i < j; ++i)
            for(i = 0; i < j; ++i){
            cycle(s, 1);
            cycle(s, 1);
 
            }
         show_state(s);
         show_state(s);
         break;
         break;
      case '4': case 'b':
      case '4': case 'b':
         printf("Line> ");
         printf("Line> ");
         scanf("%x", &j);
         scanf("%x", &j);
         printf("break point=0x%x\n", j);
         printf("break point=0x%x\n", j);
         break;
         break;
      case '5': case 'g':
      case '5': case 'g':
         s->wakeup = 0;
         s->wakeup = 0;
         cycle(s, 0);
         cycle(s, 0);
         while(s->wakeup == 0)
            while(s->wakeup == 0){
         {
 
            if(s->pc == j){
            if(s->pc == j){
               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);
Line 869... Line 906...
         show_state(s);
         show_state(s);
         break;
         break;
      case 'G':
      case 'G':
         s->wakeup = 0;
         s->wakeup = 0;
         cycle(s, 1);
         cycle(s, 1);
         while(s->wakeup == 0)
            while(s->wakeup == 0){
         {
                if(s->pc == j){
            if(s->pc == j)
 
               break;
               break;
 
                }
            cycle(s, 1);
            cycle(s, 1);
         }
         }
         show_state(s);
         show_state(s);
         break;
         break;
      case '6': case 'm':
      case '6': case 'm':
         printf("Memory> ");
         printf("Memory> ");
         scanf("%x", &j);
         scanf("%x", &j);
         for(i = 0; i < 8; ++i)
            for(i = 0; i < 8; ++i){
         {
 
            printf("%8.8x ", mem_read(s, 4, j+i*4, 0));
            printf("%8.8x ", mem_read(s, 4, j+i*4, 0));
         }
         }
         printf("\n");
         printf("\n");
         break;
         break;
      case '7': case 'w':
      case '7': case 'w':
Line 904... Line 940...
      }
      }
   }
   }
}
}
 
 
/** Read binary code and data files */
/** Read binary code and data files */
int read_program(State *s, char *code_name, char *data_name){
int read_program(t_state *s, uint32_t num_files, char **file_names){
   FILE *in;
   FILE *in;
   int bytes, i;
    uint32_t bytes, i, j, files_read=0;
   unsigned char *buffer;
 
 
 
   /* Read code file (.text + .reginfo + .rodata) */
    for(i=0;i<NUM_MEM_BLOCKS;i++){
   in = fopen(code_name, "rb");
        if(i<num_files){
   if(in == NULL)
            in = fopen(file_names[i], "rb");
   {
            if(in == NULL){
      printf("Can't open file %s!\n",code_name);
                for(j=0;j<i;j++){
 
                    free(s->blocks[j].mem);
 
                }
 
                printf("Can't open file %s, quitting!\n",file_names[i]);
      getch();
      getch();
      return(0);
                return(2);
   }
   }
   bytes = fread(s->mem, 1, MEM_SIZE, in);
 
   fclose(in);
 
   in = NULL;
 
   printf("Code [size= %6d, start= 0x%08x]\n", bytes, 0);
 
 
 
   /* Read data file (.data + .bss) if necessary */
            s->blocks[i].mem = (unsigned char*)malloc(s->blocks[i].size);
   if(data_name!=NULL){
 
      in = fopen(data_name, "rb");
            if(s->blocks[i].mem == NULL){
      if(in == NULL)
                for(j=0;j<i;j++){
      {
                    free(s->blocks[j].mem);
         printf("Can't open file %s!\n",data_name);
                }
 
                printf("Can't allocate %d bytes, quitting!\n",
 
                        s->blocks[i].size);
         getch();
         getch();
         return(0);
                return(2);
      }
      }
      /* FIXME Section '.data' start hardcoded to 0x10000 */
 
      buffer = (unsigned char*)malloc(MEM_SIZE);
 
 
 
      bytes = fread(buffer, 1, MEM_SIZE, in);
            memset(s->blocks[i].mem, 0, s->blocks[i].size);
 
 
 
            bytes = fread(s->blocks[i].mem, 1, s->blocks[i].size, in);
      fclose(in);
      fclose(in);
      printf("Data [size= %6d, start= 0x%08x]\n", bytes, 0x10000);
            printf("%-16s [size= %6d, start= 0x%08x]\n",
 
                    s->blocks[i].name,
 
                    bytes,
 
                    s->blocks[i].start);
 
            files_read++;
 
        }
 
        else{
 
            break;
 
        }
 
    }
 
 
      for(i=0;i<bytes;i++){
    if(!files_read){
         s->mem[0x10000+i] = buffer[i];
        printf("No binary object files read, quitting\n");
 
    }
 
    else{
 
        for(i=files_read;i<NUM_MEM_BLOCKS;i++){
 
            s->blocks[i].mem = (unsigned char*)malloc(s->blocks[i].size);
 
 
 
            if(s->blocks[i].mem == NULL){
 
                for(j=0;j<i;j++){
 
                    free(s->blocks[j].mem);
 
                }
 
                printf("Can't allocate %d bytes, quitting!\n",
 
                        s->blocks[i].size);
 
                getch();
 
                return(2);
 
            }
      }
      }
      free(buffer);
 
   }
   }
 
 
   return 1;
    return 0;
}
}
 
 
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
 
 
int main(int argc,char *argv[])
int main(int argc,char *argv[]){
{
    t_state state, *s=&state;
   State state, *s=&state;
 
   int index;
 
   char *code_filename;
 
   char *data_filename;
 
 
 
   printf("MIPS-I emulator\n");
   printf("MIPS-I emulator\n");
   memset(s, 0, sizeof(State));
    init_cpu(s);
   s->big_endian = 1;
 
   s->mem = (unsigned char*)malloc(MEM_SIZE);
 
   memset(s->mem, 0, MEM_SIZE);
 
 
 
 
 
   if(argc==3){
    /* do a minimal check on args */
      code_filename = argv[1];
    if(argc==3 || argc==2){
      data_filename = argv[2];
        /* */
   }
 
   else if(argc==2){
 
      code_filename = argv[1];
 
      data_filename = NULL;
 
   }
   }
   else{
   else{
      printf("Usage:");
      printf("Usage:");
      printf("    slite file.exe <bin code file> [<bin data file>]\n");
      printf("    slite file.exe <bin code file> [<bin data file>]\n");
      return 0;
      return 0;
   }
   }
 
 
   if(!read_program(s, code_filename, data_filename)) return 0;
    if(read_program(s, argc-1, &(argv[1]))){
 
        return 2;
 
    }
 
 
   init_trace_buffer(s, "sw_sim_log.txt");
   init_trace_buffer(s, "sw_sim_log.txt");
   memcpy(s->mem + 1024*1024, s->mem, 1024*1024);  //internal 8KB SRAM
 
   cache_init(); /* stub */
 
 
 
   /* NOTE: Original mlite supported loading little-endian code, which this
   /* NOTE: Original mlite supported loading little-endian code, which this
      program doesn't. The endianess-conversion code has been removed.
      program doesn't. The endianess-conversion code has been removed.
   */
   */
 
 
   /* Simulate a CPU reset */
   /* Simulate a CPU reset */
   /* FIXME cpu reset function needed */
    reset_cpu(s);
   s->pc = 0x0;      /* reset start vector */
 
   s->delay_slot = 0;
 
   s->failed_assertions = 0; /* no failed assertions pending */
 
 
 
   /* FIXME PC fixup at address zero has to be removed */
 
   index = mem_read(s, 4, 0, 0);
 
   if((index & 0xffffff00) == 0x3c1c1000){
 
      s->pc = 0x10000000;
 
   }
 
 
 
   /* 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);
 
 
   /* Close and deallocate everything and quit */
   /* Close and deallocate everything and quit */
   close_trace_buffer(s);
   close_trace_buffer(s);
   free(s->mem);
    free_cpu(s);
   return(0);
   return(0);
}
}
 
 
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
 
 
 
 
void init_trace_buffer(State *s, const char *log_file_name){
void init_trace_buffer(t_state *s, const char *log_file_name){
   int i;
   int i;
 
 
#if FILE_LOGGING_DISABLED
#if FILE_LOGGING_DISABLED
   s->t.log = NULL;
   s->t.log = NULL;
   return;
   return;
Line 1027... Line 1064...
 
 
   /* if file logging is enabled, open log file */
   /* if file logging is enabled, open log file */
   if(log_file_name!=NULL){
   if(log_file_name!=NULL){
      s->t.log = fopen(log_file_name, "w");
      s->t.log = fopen(log_file_name, "w");
      if(s->t.log==NULL){
      if(s->t.log==NULL){
         printf("Error opening log file '%s', file logging disabled\n", log_file_name);
            printf("Error opening log file '%s', file logging disabled\n",
 
                    log_file_name);
      }
      }
   }
   }
   else{
   else{
      s->t.log = NULL;
      s->t.log = NULL;
   }
   }
#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(State *s){
void dump_trace_buffer(t_state *s){
   int i, col;
   int i, col;
 
 
   for(i=0, col=0;i<TRACE_BUFFER_SIZE;i++, col++){
   for(i=0, col=0;i<TRACE_BUFFER_SIZE;i++, col++){
      printf("%08x ", s->t.buf[s->t.next + i]);
      printf("%08x ", s->t.buf[s->t.next + i]);
      if((col % 8)==7){
      if((col % 8)==7){
Line 1049... Line 1087...
      }
      }
   }
   }
}
}
 
 
/** 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(State *s){
void log_cycle(t_state *s){
   static unsigned int last_pc = 0;
   static unsigned int last_pc = 0;
   int i;
   int i;
 
 
   /* 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)){
Line 1086... Line 1124...
      s->t.epc = s->epc;
      s->t.epc = s->epc;
   }
   }
}
}
 
 
/** Frees debug buffers and closes log file */
/** Frees debug buffers and closes log file */
void close_trace_buffer(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);
   }
   }
}
}
 
 
/** 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(State *s){
void log_failed_assertions(t_state *s){
   unsigned bitmap = s->failed_assertions;
   unsigned bitmap = s->failed_assertions;
   int i = 0;
   int i = 0;
 
 
   /* This loop will crash the program if the message table is too short...*/
   /* This loop will crash the program if the message table is too short...*/
   if(s->t.log != NULL){
   if(s->t.log != NULL){
Line 1110... Line 1148...
         bitmap = bitmap >> 1;
         bitmap = bitmap >> 1;
      }
      }
   }
   }
}
}
 
 
 No newline at end of file
 No newline at end of file
 
void free_cpu(t_state *s){
 
    int i;
 
 
 
    for(i=0;i<NUM_MEM_BLOCKS;i++){
 
        free(s->blocks[i].mem);
 
        s->blocks[i].mem = NULL;
 
 
 
    }
 
}
 
 
 
void reset_cpu(t_state *s){
 
    s->pc = VECTOR_RESET;     /* reset start vector */
 
    s->delay_slot = 0;
 
    s->failed_assertions = 0; /* no failed assertions pending */
 
}
 
 
 
void init_cpu(t_state *s){
 
    int i;
 
    memset(s, 0, sizeof(t_state));
 
    s->big_endian = 1;
 
    for(i=0;i<NUM_MEM_BLOCKS;i++){
 
        s->blocks[i].start =  default_blocks[i].start;
 
        s->blocks[i].size =  default_blocks[i].size;
 
        s->blocks[i].name =  default_blocks[i].name;
 
        s->blocks[i].mem = NULL;
 
    }
 
}
 
 
 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.