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

Subversion Repositories mlite

[/] [mlite/] [trunk/] [tools/] [mlite.c] - Diff between revs 241 and 336

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

Rev 241 Rev 336
Line 16... Line 16...
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <ctype.h>
#include <assert.h>
#include <assert.h>
 
 
//#define ENABLE_CACHE
//#define ENABLE_CACHE
 
//#define SIMPLE_CACHE
 
 
#define MEM_SIZE (1024*1024*2)
#define MEM_SIZE (1024*1024*2)
#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)
 
 
#ifndef WIN32
#ifndef WIN32
#define getch getchar
//Support for Linux
void Sleep(unsigned long value)
#define putch putchar
 
#include <termios.h>
 
#include <unistd.h>
 
void Sleep(unsigned int value)
 
{
 
   usleep(value * 1000);
 
}
 
 
 
int kbhit(void)
 
{
 
   struct termios oldt, newt;
 
   struct timeval tv;
 
   fd_set read_fd;
 
 
 
   tcgetattr(STDIN_FILENO, &oldt);
 
   newt = oldt;
 
   newt.c_lflag &= ~(ICANON | ECHO);
 
   tcsetattr(STDIN_FILENO, TCSANOW, &newt);
 
   tv.tv_sec=0;
 
   tv.tv_usec=0;
 
   FD_ZERO(&read_fd);
 
   FD_SET(0,&read_fd);
 
   if(select(1, &read_fd, NULL, NULL, &tv) == -1)
 
      return 0;
 
   //tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
 
   if(FD_ISSET(0,&read_fd))
 
      return 1;
 
   return 0;
 
}
 
 
 
int getch(void)
{
{
   volatile unsigned long count = value*1000000;
   struct termios oldt, newt;
   while(--count > 0) ;
   int ch;
 
 
 
   tcgetattr(STDIN_FILENO, &oldt);
 
   newt = oldt;
 
   newt.c_lflag &= ~(ICANON | ECHO);
 
   tcsetattr(STDIN_FILENO, TCSANOW, &newt);
 
   ch = getchar();
 
   //tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
 
   return ch;
}
}
#else
#else
 
//Support for Windows
#include <conio.h>
#include <conio.h>
extern void __stdcall Sleep(unsigned long value);
extern void __stdcall Sleep(unsigned long value);
#endif
#endif
 
 
#define UART_WRITE        0x20000000
#define UART_WRITE        0x20000000
Line 54... Line 94...
 
 
#define MMU_ENTRIES 4
#define MMU_ENTRIES 4
#define MMU_MASK (1024*4-1)
#define MMU_MASK (1024*4-1)
typedef struct
typedef struct
{
{
   unsigned long virtualAddress;
   unsigned int virtualAddress;
   unsigned long physicalAddress;
   unsigned int physicalAddress;
} MmuEntry;
} MmuEntry;
 
 
typedef struct {
typedef struct {
   long r[32];
   int r[32];
   long pc, pc_next, epc;
   int pc, pc_next, epc;
   unsigned long hi;
   unsigned int hi;
   unsigned long lo;
   unsigned int lo;
   long status;
   int status;
   long userMode;
   int userMode;
   long processId;
   int processId;
   long exceptionId;
   int exceptionId;
   long faultAddr;
   int faultAddr;
   long irqStatus;
   int irqStatus;
   long skip;
   int skip;
   unsigned char *mem;
   unsigned char *mem;
   long wakeup;
   int wakeup;
   long big_endian;
   int big_endian;
   MmuEntry mmuEntry[MMU_ENTRIES];
   MmuEntry mmuEntry[MMU_ENTRIES];
} 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",
Line 105... Line 145...
   "TGEI","TGEIU","TLTI","TLTIU","TEQI","?","TNEI","?",
   "TGEI","TGEIU","TLTI","TLTIU","TEQI","?","TNEI","?",
   "BLTZAL","BEQZAL","BLTZALL","BGEZALL","?","?","?","?",
   "BLTZAL","BEQZAL","BLTZALL","BGEZALL","?","?","?","?",
   "?","?","?","?","?","?","?","?"
   "?","?","?","?","?","?","?","?"
};
};
 
 
static unsigned long HWMemory[8];
static unsigned int HWMemory[8];
 
 
 
 
static long mem_read(State *s, long size, unsigned long address)
static int mem_read(State *s, int size, unsigned int address)
{
{
   unsigned long value=0, ptr;
   unsigned int value=0, ptr;
 
 
   s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
   s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
   switch(address)
   switch(address)
   {
   {
      case UART_READ:
      case UART_READ:
Line 135... Line 175...
         return s->processId;
         return s->processId;
      case MMU_FAULT_ADDR:
      case MMU_FAULT_ADDR:
         return s->faultAddr;
         return s->faultAddr;
   }
   }
 
 
   ptr = (unsigned long)s->mem + (address % MEM_SIZE);
   ptr = (unsigned int)s->mem + (address % MEM_SIZE);
 
 
   if(0x10000000 <= address && address < 0x10000000 + 1024*1024)
   if(0x10000000 <= address && address < 0x10000000 + 1024*1024)
      ptr = (unsigned long)s->mem + address - 0x10000000;
      ptr = (unsigned int)s->mem + address - 0x10000000;
   else if(address < 1024*8)
   else if(address < 1024*8)
      ptr += 1024*1024;
      ptr += 1024*1024;
 
 
   switch(size)
   switch(size)
   {
   {
      case 4:
      case 4:
         if(address & 3)
         if(address & 3)
            printf("Unaligned access PC=0x%x address=0x%x\n", s->pc, address);
            printf("Unaligned access PC=0x%x address=0x%x\n", (int)s->pc, (int)address);
         assert((address & 3) == 0);
         assert((address & 3) == 0);
         value = *(long*)ptr;
         value = *(int*)ptr;
         if(s->big_endian)
         if(s->big_endian)
            value = ntohl(value);
            value = ntohl(value);
         break;
         break;
      case 2:
      case 2:
         assert((address & 1) == 0);
         assert((address & 1) == 0);
Line 167... Line 207...
         printf("ERROR");
         printf("ERROR");
   }
   }
   return(value);
   return(value);
}
}
 
 
static void mem_write(State *s, long size, long unsigned address, unsigned long value)
static void mem_write(State *s, int size, int unsigned address, unsigned int value)
{
{
   static char_count=0;
   unsigned int ptr;
   unsigned long ptr;
 
 
 
   switch(address)
   switch(address)
   {
   {
      case UART_WRITE:
      case UART_WRITE:
         putch(value);
         putch(value);
 
         fflush(stdout);
         return;
         return;
      case IRQ_MASK:
      case IRQ_MASK:
         HWMemory[1] = value;
         HWMemory[1] = value;
         return;
         return;
      case IRQ_STATUS:
      case IRQ_STATUS:
Line 190... Line 230...
      case MMU_PROCESS_ID:
      case MMU_PROCESS_ID:
         //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)
   if(MMU_TLB <= address && address <= MMU_TLB+MMU_ENTRIES * 8)
   {
   {
      //printf("TLB 0x%x 0x%x\n", address - MMU_TLB, value);
      //printf("TLB 0x%x 0x%x\n", address - MMU_TLB, value);
      ptr = (unsigned long)s->mmuEntry + address - MMU_TLB;
      ptr = (unsigned int)s->mmuEntry + address - MMU_TLB;
      *(int*)ptr = value;
      *(int*)ptr = value;
      s->irqStatus &= ~IRQ_MMU;
      s->irqStatus &= ~IRQ_MMU;
      return;
      return;
   }
   }
 
 
   ptr = (unsigned long)s->mem + (address % MEM_SIZE);
   ptr = (unsigned int)s->mem + (address % MEM_SIZE);
 
 
   if(0x10000000 <= address && address < 0x10000000 + 1024*1024)
   if(0x10000000 <= address && address < 0x10000000 + 1024*1024)
      ptr = (unsigned long)s->mem + address - 0x10000000;
      ptr = (unsigned int)s->mem + address - 0x10000000;
   else if(address < 1024*8)
   else if(address < 1024*8)
      ptr += 1024*1024;
      ptr += 1024*1024;
 
 
   switch(size)
   switch(size)
   {
   {
      case 4:
      case 4:
         assert((address & 3) == 0);
         assert((address & 3) == 0);
         if(s->big_endian)
         if(s->big_endian)
            value = htonl(value);
            value = htonl(value);
         *(long*)ptr = value;
         *(int*)ptr = value;
         break;
         break;
      case 2:
      case 2:
         assert((address & 1) == 0);
         assert((address & 1) == 0);
         if(s->big_endian)
         if(s->big_endian)
            value = htons((unsigned short)value);
            value = htons((unsigned short)value);
Line 231... Line 272...
}
}
 
 
#ifdef ENABLE_CACHE
#ifdef ENABLE_CACHE
/************* Optional MMU and cache implementation *************/
/************* Optional MMU and cache implementation *************/
/* TAG = VirtualAddress | ProcessId | WriteableBit */
/* TAG = VirtualAddress | ProcessId | WriteableBit */
unsigned long mmu_lookup(State *s, unsigned long processId,
unsigned int mmu_lookup(State *s, unsigned int processId,
                         unsigned long address, int write)
                         unsigned int address, int write)
{
{
   int i;
   int i;
   unsigned long compare, tag;
   unsigned int compare, tag;
 
 
   if(processId == 0 || s->userMode == 0)
   if(processId == 0 || s->userMode == 0)
      return address;
      return address;
   //if(address < 0x30000000)
   //if(address < 0x30000000)
   //   return address;
   //   return address;
Line 262... Line 303...
 
 
#define CACHE_SET_ASSOC_LN2   0
#define CACHE_SET_ASSOC_LN2   0
#define CACHE_SET_ASSOC       (1 << CACHE_SET_ASSOC_LN2)
#define CACHE_SET_ASSOC       (1 << CACHE_SET_ASSOC_LN2)
#define CACHE_SIZE_LN2        (13 - CACHE_SET_ASSOC_LN2)  //8 KB
#define CACHE_SIZE_LN2        (13 - CACHE_SET_ASSOC_LN2)  //8 KB
#define CACHE_SIZE            (1 << CACHE_SIZE_LN2)
#define CACHE_SIZE            (1 << CACHE_SIZE_LN2)
#define CACHE_LINE_SIZE_LN2   5                           //32 bytes
#define CACHE_LINE_SIZE_LN2   2                           //4 bytes
#define CACHE_LINE_SIZE       (1 << CACHE_LINE_SIZE_LN2)
#define CACHE_LINE_SIZE       (1 << CACHE_LINE_SIZE_LN2)
 
 
static long cacheData[CACHE_SET_ASSOC][CACHE_SIZE/sizeof(long)];
static int cacheData[CACHE_SET_ASSOC][CACHE_SIZE/sizeof(int)];
static long cacheAddr[CACHE_SET_ASSOC][CACHE_SIZE/CACHE_LINE_SIZE];
static int cacheAddr[CACHE_SET_ASSOC][CACHE_SIZE/CACHE_LINE_SIZE];
static long cacheSetNext;
static int cacheSetNext;
static long cacheMiss, cacheWriteBack, cacheCount;
static int cacheMiss, cacheWriteBack, cacheCount;
 
 
static void cache_init(void)
static void cache_init(void)
{
{
   int set, i;
   int set, i;
   for(set = 0; set < CACHE_SET_ASSOC; ++set)
   for(set = 0; set < CACHE_SET_ASSOC; ++set)
Line 282... Line 323...
   }
   }
}
}
 
 
/* Write-back cache memory tagged by virtual address and processId */
/* Write-back cache memory tagged by virtual address and processId */
/* TAG = virtualAddress | processId | dirtyBit */
/* TAG = virtualAddress | processId | dirtyBit */
static int cache_load(State *s, unsigned long address, int write)
static int cache_load(State *s, unsigned int address, int write)
{
{
   int set, i, pid, miss, offsetAddr, offsetData, offsetMem;
   int set, i, pid, miss, offsetAddr, offsetData, offsetMem;
   unsigned long addrTagMatch, addrPrevMatch=0;
   unsigned int addrTagMatch, addrPrevMatch=0;
   unsigned long addrPrev;
   unsigned int addrPrev;
   unsigned long addressPhysical, tag;
   unsigned int addressPhysical, tag;
 
 
   ++cacheCount;
   ++cacheCount;
   addrTagMatch = address & ~(CACHE_SIZE-1);
   addrTagMatch = address & ~(CACHE_SIZE-1);
   offsetAddr = (address & (CACHE_SIZE-1)) >> CACHE_LINE_SIZE_LN2;
   offsetAddr = (address & (CACHE_SIZE-1)) >> CACHE_LINE_SIZE_LN2;
 
 
Line 312... Line 353...
   {
   {
      ++cacheMiss;
      ++cacheMiss;
      set = cacheSetNext;
      set = cacheSetNext;
      cacheSetNext = (cacheSetNext + 1) & (CACHE_SET_ASSOC-1);
      cacheSetNext = (cacheSetNext + 1) & (CACHE_SET_ASSOC-1);
   }
   }
   else if(write || (address >> 28) != 0x1)
   //else if(write || (address >> 28) != 0x1)
   {
   //{
      tag = cacheAddr[set][offsetAddr];
   //   tag = cacheAddr[set][offsetAddr];
      pid = (tag & (CACHE_SIZE-1)) >> 1;
   //   pid = (tag & (CACHE_SIZE-1)) >> 1; 
      if(pid != s->processId)
   //   if(pid != s->processId)
         miss = 1;
   //      miss = 1;
   }
   //}
 
 
   if(miss)
   if(miss)
   {
   {
      offsetData = address & (CACHE_SIZE-1) & ~(CACHE_LINE_SIZE-1);
      offsetData = address & (CACHE_SIZE-1) & ~(CACHE_LINE_SIZE-1);
 
 
Line 354... Line 395...
   }
   }
   cacheAddr[set][offsetAddr] |= write;
   cacheAddr[set][offsetAddr] |= write;
   return set;
   return set;
}
}
 
 
static long cache_read(State *s, long size, unsigned long address)
static int cache_read(State *s, int size, unsigned int address)
{
{
   int set, offset;
   int set, offset;
   long value;
   int value;
 
 
   if((address >> 28) == 0x2) // && (s->processId == 0 || s->userMode == 0))
   if((address & 0xfe000000) != 0x10000000)
      return mem_read(s, size, address);
      return mem_read(s, size, address);
 
 
   set = cache_load(s, address, 0);
   set = cache_load(s, address, 0);
   if(s->exceptionId)
   if(s->exceptionId)
      return 0;
      return 0;
Line 381... Line 422...
         break;
         break;
   }
   }
   return value;
   return value;
}
}
 
 
static void cache_write(State *s, long size, long unsigned address, unsigned long value)
static void cache_write(State *s, int size, int unsigned address, unsigned int value)
{
{
   int set, offset;
   int set, offset;
   unsigned long mask;
   unsigned int mask;
 
 
   if((address >> 28) == 0x2) // && (s->processId == 0 || s->userMode == 0))
   if((address >> 28) != 0x1) // && (s->processId == 0 || s->userMode == 0))
   {
   {
      mem_write(s, size, address, value);
      mem_write(s, size, address, value);
      return;
      return;
   }
   }
 
 
Line 420... Line 461...
   cacheData[set][offset] = (value & mask) | (cacheData[set][offset] & ~mask);
   cacheData[set][offset] = (value & mask) | (cacheData[set][offset] & ~mask);
}
}
 
 
#define mem_read cache_read
#define mem_read cache_read
#define mem_write cache_write
#define mem_write cache_write
/************* End optional cache implementation *************/
 
#else
#else
static void cache_init(void) {}
static void cache_init(void) {}
#endif
#endif
 
 
void mult_big(unsigned long a,
#ifdef SIMPLE_CACHE
              unsigned long b,
 
              unsigned long *hi,
//Write through direct mapped 8KB cache
              unsigned long *lo)
#define CACHE_MISS 0x1ff
{
static int cacheData[2048];
   unsigned long ahi, alo, bhi, blo;
static int cacheAddr[2048]; //9-bit addresses
   unsigned long c0, c1, c2;
static int cacheTry, cacheMiss, cacheInit;
   unsigned long c1_a, c1_b;
 
 
static int cache_read(State *s, int size, unsigned int address)
 
{
 
   int offset;
 
   unsigned int value, value2, address2=address;
 
 
 
   if(cacheInit == 0)
 
   {
 
      cacheInit = 1;
 
      for(offset = 0; offset < 2048; ++offset)
 
         cacheAddr[offset] = CACHE_MISS;
 
   }
 
 
 
   if(address & 0xefc00000)
 
      return mem_read(s, size, address);
 
 
 
   ++cacheTry;
 
   offset = (address >> 2) & 0x7ff;
 
   if(cacheAddr[offset] != (address >> 13) || cacheAddr[offset] == CACHE_MISS)
 
   {
 
      ++cacheMiss;
 
      cacheAddr[offset] = address >> 13;
 
      cacheData[offset] = mem_read(s, 4, address & ~3);
 
   }
 
   value = cacheData[offset];
 
   if(s->big_endian)
 
      address ^= 3;
 
   switch(size)
 
   {
 
      case 2:
 
         value = (value >> ((address & 2) << 3)) & 0xffff;
 
         break;
 
      case 1:
 
         value = (value >> ((address & 3) << 3)) & 0xff;
 
         break;
 
   }
 
   value2 = mem_read(s, size, address2);
 
   if(value != value2)
 
      printf("miss match\n");
 
   //if((cacheTry & 0xffff) == 0) printf("cache(%d,%d) ", cacheMiss, cacheTry);
 
   return value;
 
}
 
 
 
static void cache_write(State *s, int size, int unsigned address, unsigned int value)
 
{
 
   int offset;
 
 
 
   mem_write(s, size, address, value);
 
   if(address & 0xefc00000)
 
      return;
 
 
 
   offset = (address >> 2) & 0x7ff;
 
   if(size != 4)
 
   {
 
      cacheAddr[offset] = CACHE_MISS;
 
      return;
 
   }
 
   cacheAddr[offset] = address >> 13;
 
   cacheData[offset] = value;
 
}
 
 
 
#define mem_read cache_read
 
#define mem_write cache_write
 
#endif
 
/************* End optional cache implementation *************/
 
 
 
 
 
void mult_big(unsigned int a,
 
              unsigned int b,
 
              unsigned int *hi,
 
              unsigned int *lo)
 
{
 
   unsigned int ahi, alo, bhi, blo;
 
   unsigned int c0, c1, c2;
 
   unsigned int c1_a, c1_b;
 
 
   ahi = a >> 16;
   ahi = a >> 16;
   alo = a & 0xffff;
   alo = a & 0xffff;
   bhi = b >> 16;
   bhi = b >> 16;
   blo = b & 0xffff;
   blo = b & 0xffff;
Line 452... Line 567...
   c0 = (c1 << 16) + (c0 & 0xffff);
   c0 = (c1 << 16) + (c0 & 0xffff);
   *hi = c2;
   *hi = c2;
   *lo = c0;
   *lo = c0;
}
}
 
 
void mult_big_signed(long a,
void mult_big_signed(int a,
                     long b,
                     int b,
                     unsigned long *hi,
                     unsigned int *hi,
                     unsigned long *lo)
                     unsigned int *lo)
{
{
   unsigned long ahi, alo, bhi, blo;
   unsigned int ahi, alo, bhi, blo;
   unsigned long c0, c1, c2;
   unsigned int c0, c1, c2;
   unsigned long c1_a, c1_b;
   unsigned int c1_a, c1_b;
 
 
   ahi = a >> 16;
   ahi = a >> 16;
   alo = a & 0xffff;
   alo = a & 0xffff;
   bhi = b >> 16;
   bhi = b >> 16;
   blo = b & 0xffff;
   blo = b & 0xffff;
Line 482... Line 597...
}
}
 
 
//execute one cycle of a Plasma CPU
//execute one cycle of a Plasma CPU
void cycle(State *s, int show_mode)
void cycle(State *s, int show_mode)
{
{
   unsigned long opcode;
   unsigned int opcode;
   unsigned long op, rs, rt, rd, re, func, imm, target;
   unsigned int op, rs, rt, rd, re, func, imm, target;
   long imm_shift, branch=0, lbranch=2, skip2=0;
   int imm_shift, branch=0, lbranch=2, skip2=0;
   long *r=s->r;
   int *r=s->r;
   unsigned long *u=(unsigned long*)s->r;
   unsigned int *u=(unsigned int*)s->r;
   unsigned long ptr, epc, rSave;
   unsigned int ptr, epc, rSave;
 
 
   opcode = mem_read(s, 4, s->pc);
   opcode = mem_read(s, 4, s->pc);
   op = (opcode >> 26) & 0x3f;
   op = (opcode >> 26) & 0x3f;
   rs = (opcode >> 21) & 0x1f;
   rs = (opcode >> 21) & 0x1f;
   rt = (opcode >> 16) & 0x1f;
   rt = (opcode >> 16) & 0x1f;
   rd = (opcode >> 11) & 0x1f;
   rd = (opcode >> 11) & 0x1f;
   re = (opcode >> 6) & 0x1f;
   re = (opcode >> 6) & 0x1f;
   func = opcode & 0x3f;
   func = opcode & 0x3f;
   imm = opcode & 0xffff;
   imm = opcode & 0xffff;
   imm_shift = (((long)(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(show_mode)
   {
   {
      printf("%8.8lx %8.8lx ", 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.2ld $%2.2ld $%2.2ld $%2.2ld ", rs, rt, rd, re);
      printf("$%2.2d $%2.2d $%2.2d $%2.2d ", rs, rt, rd, re);
      printf("%4.4lx", 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(show_mode > 5)
Line 597... Line 712...
      case 0x06:/*BLEZ*/   branch=r[rs]<=0;         break;
      case 0x06:/*BLEZ*/   branch=r[rs]<=0;         break;
      case 0x07:/*BGTZ*/   branch=r[rs]>0;          break;
      case 0x07:/*BGTZ*/   branch=r[rs]>0;          break;
      case 0x08:/*ADDI*/   r[rt]=r[rs]+(short)imm;  break;
      case 0x08:/*ADDI*/   r[rt]=r[rs]+(short)imm;  break;
      case 0x09:/*ADDIU*/  u[rt]=u[rs]+(short)imm;  break;
      case 0x09:/*ADDIU*/  u[rt]=u[rs]+(short)imm;  break;
      case 0x0a:/*SLTI*/   r[rt]=r[rs]<(short)imm;  break;
      case 0x0a:/*SLTI*/   r[rt]=r[rs]<(short)imm;  break;
      case 0x0b:/*SLTIU*/  u[rt]=u[rs]<(unsigned long)(short)imm; break;
      case 0x0b:/*SLTIU*/  u[rt]=u[rs]<(unsigned int)(short)imm; break;
      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*/
Line 641... Line 756...
      case 0x23:/*LW*/   r[rt]=mem_read(s,4,ptr);   break;
      case 0x23:/*LW*/   r[rt]=mem_read(s,4,ptr);   break;
      case 0x24:/*LBU*/  r[rt]=(unsigned char)mem_read(s,1,ptr); break;
      case 0x24:/*LBU*/  r[rt]=(unsigned char)mem_read(s,1,ptr); break;
      case 0x25:/*LHU*/  r[rt]=(unsigned short)mem_read(s,2,ptr); break;
      case 0x25:/*LHU*/  r[rt]=(unsigned short)mem_read(s,2,ptr); break;
      case 0x26:/*LWR*/
      case 0x26:/*LWR*/
                         //target=32-8*(ptr&3);
                         //target=32-8*(ptr&3);
                         //r[rt]=(r[rt]&~((unsigned long)0xffffffff>>target))|
                         //r[rt]=(r[rt]&~((unsigned int)0xffffffff>>target))|
                         //((unsigned long)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]);  break;
      case 0x29:/*SH*/   mem_write(s,2,ptr,r[rt]);  break;
      case 0x29:/*SH*/   mem_write(s,2,ptr,r[rt]);  break;
      case 0x2a:/*SWL*/
      case 0x2a:/*SWL*/
                         //mem_write(s,1,ptr,r[rt]>>24);  
                         //mem_write(s,1,ptr,r[rt]>>24);  
Line 661... Line 776...
//      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*/     *(long*)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]); 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;
Line 691... Line 806...
   }
   }
}
}
 
 
void show_state(State *s)
void show_state(State *s)
{
{
   long 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);
   for(i = 0; i < 4; ++i)
   for(i = 0; i < 4; ++i)
   {
   {
      printf("%2.2ld ", i * 8);
      printf("%2.2d ", i * 8);
      for(j = 0; j < 8; ++j)
      for(j = 0; j < 8; ++j)
      {
      {
         printf("%8.8lx ", 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;
Line 716... Line 831...
}
}
 
 
void do_debug(State *s)
void do_debug(State *s)
{
{
   int ch;
   int ch;
   long 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.8lx=0x%8.8lx\n", watch, mem_read(s, 4, watch));
            printf("0x%8.8x=0x%8.8x\n", watch, mem_read(s, 4, watch));
         printf("1=Debug 2=Trace 3=Step 4=BreakPt 5=Go 6=Memory ");
         printf("1=Debug 2=Trace 3=Step 4=BreakPt 5=Go 6=Memory ");
         printf("7=Watch 8=Jump 9=Quit> ");
         printf("7=Watch 8=Jump 9=Quit> ");
      }
      }
      ch = getch();
      ch = getch();
      if(ch != 'n')
      if(ch != 'n')
Line 744... Line 859...
         cycle(s, 1); break;
         cycle(s, 1); break;
      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("%ld", &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("%lx", &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);
Line 778... Line 893...
         }
         }
         show_state(s);
         show_state(s);
         break;
         break;
      case '6': case 'm':
      case '6': case 'm':
         printf("Memory> ");
         printf("Memory> ");
         scanf("%lx", &j);
         scanf("%x", &j);
         for(i = 0; i < 8; ++i)
         for(i = 0; i < 8; ++i)
         {
         {
            printf("%8.8lx ", mem_read(s, 4, j+i*4));
            printf("%8.8x ", mem_read(s, 4, j+i*4));
         }
         }
         printf("\n");
         printf("\n");
         break;
         break;
      case '7': case 'w':
      case '7': case 'w':
         printf("Watch> ");
         printf("Watch> ");
         scanf("%lx", &watch);
         scanf("%x", &watch);
         break;
         break;
      case '8': case 'j':
      case '8': case 'j':
         printf("Jump> ");
         printf("Jump> ");
         scanf("%lx", &addr);
         scanf("%x", &addr);
         s->pc = addr;
         s->pc = addr;
         s->pc_next = addr + 4;
         s->pc_next = addr + 4;
         show_state(s);
         show_state(s);
         break;
         break;
      case '9': case 'q':
      case '9': case 'q':
Line 807... Line 922...
 
 
int main(int argc,char *argv[])
int main(int argc,char *argv[])
{
{
   State state, *s=&state;
   State state, *s=&state;
   FILE *in;
   FILE *in;
   long bytes, index;
   int bytes, index;
   printf("Plasma emulator\n");
   printf("Plasma emulator\n");
   memset(s, 0, sizeof(State));
   memset(s, 0, sizeof(State));
   s->big_endian = 1;
   s->big_endian = 1;
   s->mem = (unsigned char*)malloc(MEM_SIZE);
   s->mem = (unsigned char*)malloc(MEM_SIZE);
   memset(s->mem, 0, MEM_SIZE);
   memset(s->mem, 0, MEM_SIZE);
Line 833... Line 948...
      return(0);
      return(0);
   }
   }
   bytes = fread(s->mem, 1, MEM_SIZE, in);
   bytes = fread(s->mem, 1, MEM_SIZE, in);
   fclose(in);
   fclose(in);
   memcpy(s->mem + 1024*1024, s->mem, 1024*8);  //internal 8KB SRAM
   memcpy(s->mem + 1024*1024, s->mem, 1024*8);  //internal 8KB SRAM
   printf("Read %ld bytes.\n", bytes);
   printf("Read %d bytes.\n", bytes);
   cache_init();
   cache_init();
   if(argc == 3 && argv[2][0] == 'B')
   if(argc == 3 && argv[2][0] == 'B')
   {
   {
      printf("Big Endian\n");
      printf("Big Endian\n");
      s->big_endian = 1;
      s->big_endian = 1;
Line 851... Line 966...
   if(argc == 3 && argv[2][0] == 'S')
   if(argc == 3 && argv[2][0] == 'S')
   {  /*make big endian*/
   {  /*make big endian*/
      printf("Big Endian\n");
      printf("Big Endian\n");
      for(index = 0; index < bytes+3; index += 4)
      for(index = 0; index < bytes+3; index += 4)
      {
      {
         *(unsigned long*)&s->mem[index] = htonl(*(unsigned long*)&s->mem[index]);
         *(unsigned int*)&s->mem[index] = htonl(*(unsigned int*)&s->mem[index]);
      }
      }
      in = fopen("big.exe", "wb");
      in = fopen("big.exe", "wb");
      fwrite(s->mem, bytes, 1, in);
      fwrite(s->mem, bytes, 1, in);
      fclose(in);
      fclose(in);
      return(0);
      return(0);

powered by: WebSVN 2.1.0

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