/[gxemul]/upstream/0.3.4/src/cpu_mips.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /upstream/0.3.4/src/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/src/cpu_mips.c revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC upstream/0.3.4/src/cpu_mips.c revision 11 by dpavlin, Mon Oct 8 16:18:31 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_mips.c,v 1.34 2005/03/20 20:27:26 debug Exp $   *  $Id: cpu_mips.c,v 1.46 2005/06/26 22:23:42 debug Exp $
29   *   *
30   *  MIPS core CPU emulation.   *  MIPS core CPU emulation.
31   */   */
# Line 34  Line 34 
34  #include <stdlib.h>  #include <stdlib.h>
35  #include <string.h>  #include <string.h>
36  #include <sys/types.h>  #include <sys/types.h>
 #include <sys/time.h>  
 #include <sys/resource.h>  
37  #include <ctype.h>  #include <ctype.h>
38    
39  #include "../config.h"  #include "../config.h"
# Line 115  static char *regname(struct machine *mac Line 113  static char *regname(struct machine *mac
113          ch[3] = ch[2] = '\0';          ch[3] = ch[2] = '\0';
114    
115          if (r<0 || r>=32)          if (r<0 || r>=32)
116                  strcpy(ch, "xx");                  strlcpy(ch, "xx", sizeof(ch));
117          else if (machine->show_symbolic_register_names)          else if (machine->show_symbolic_register_names)
118                  strcpy(ch, regnames[r]);                  strlcpy(ch, regnames[r], sizeof(ch));
119          else          else
120                  sprintf(ch, "r%i", r);                  snprintf(ch, sizeof(ch), "r%i", r);
121    
122          return ch;          return ch;
123  }  }
# Line 129  static char *regname(struct machine *mac Line 127  static char *regname(struct machine *mac
127   *  mips_cpu_new():   *  mips_cpu_new():
128   *   *
129   *  Create a new MIPS cpu object.   *  Create a new MIPS cpu object.
130     *
131     *  Returns 1 on success, 0 if there was no valid MIPS processor with
132     *  a matching name.
133   */   */
134  struct cpu *mips_cpu_new(struct memory *mem, struct machine *machine,  int mips_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
135          int cpu_id, char *cpu_type_name)          int cpu_id, char *cpu_type_name)
136  {  {
         struct cpu *cpu;  
137          int i, found, j, tags_size, n_cache_lines, size_per_cache_line;          int i, found, j, tags_size, n_cache_lines, size_per_cache_line;
138          struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;          struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;
139          int64_t secondary_cache_size;          int64_t secondary_cache_size;
# Line 151  struct cpu *mips_cpu_new(struct memory * Line 151  struct cpu *mips_cpu_new(struct memory *
151          }          }
152    
153          if (found == -1)          if (found == -1)
154                  return NULL;                  return 0;
   
         cpu = malloc(sizeof(struct cpu));  
         if (cpu == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
155    
         memset(cpu, 0, sizeof(struct cpu));  
156          cpu->memory_rw          = mips_memory_rw;          cpu->memory_rw          = mips_memory_rw;
157          cpu->cd.mips.cpu_type   = cpu_type_defs[found];          cpu->cd.mips.cpu_type   = cpu_type_defs[found];
158          cpu->name               = cpu->cd.mips.cpu_type.name;          cpu->name               = cpu->cd.mips.cpu_type.name;
         cpu->mem                = mem;  
         cpu->machine            = machine;  
         cpu->cpu_id             = cpu_id;  
159          cpu->byte_order         = EMUL_LITTLE_ENDIAN;          cpu->byte_order         = EMUL_LITTLE_ENDIAN;
         cpu->bootstrap_cpu_flag = 0;  
         cpu->running            = 0;  
160          cpu->cd.mips.gpr[MIPS_GPR_SP]   = INITIAL_STACK_POINTER;          cpu->cd.mips.gpr[MIPS_GPR_SP]   = INITIAL_STACK_POINTER;
161    
162          if (cpu_id == 0)          if (cpu_id == 0)
# Line 341  struct cpu *mips_cpu_new(struct memory * Line 329  struct cpu *mips_cpu_new(struct memory *
329                          cpu->translate_address = translate_address_generic;                          cpu->translate_address = translate_address_generic;
330          }          }
331    
332          return cpu;          return 1;
333  }  }
334    
335    
# Line 665  void mips_cpu_register_match(struct mach Line 653  void mips_cpu_register_match(struct mach
653                                  if (writeflag) {                                  if (writeflag) {
654                                          coproc_register_write(m->cpus[cpunr],                                          coproc_register_write(m->cpus[cpunr],
655                                              m->cpus[cpunr]->cd.mips.coproc[0], nr,                                              m->cpus[cpunr]->cd.mips.coproc[0], nr,
656                                              valuep, 1);                                              valuep, 1, 0);
657                                  } else {                                  } else {
658                                          /*  TODO: Use coproc_register_read instead?  */                                          /*  TODO: Use coproc_register_read instead?  */
659                                          *valuep = m->cpus[cpunr]->cd.mips.coproc[0]->reg[nr];                                          *valuep = m->cpus[cpunr]->cd.mips.coproc[0]->reg[nr];
# Line 728  int mips_cpu_disassemble_instr(struct cp Line 716  int mips_cpu_disassemble_instr(struct cp
716          if (running)          if (running)
717                  dumpaddr = cpu->pc;                  dumpaddr = cpu->pc;
718    
719            if ((dumpaddr & 3) != 0)
720                    printf("WARNING: Unaligned address!\n");
721    
722          symbol = get_symbol_name(&cpu->machine->symbol_context,          symbol = get_symbol_name(&cpu->machine->symbol_context,
723              dumpaddr, &offset);              dumpaddr, &offset);
724          if (symbol != NULL && offset==0)          if (symbol != NULL && offset==0)
# Line 1608  void mips_cpu_exception(struct cpu *cpu, Line 1599  void mips_cpu_exception(struct cpu *cpu,
1599    
1600          if (tlb && vaddr < 0x1000) {          if (tlb && vaddr < 0x1000) {
1601                  uint64_t offset;                  uint64_t offset;
1602                  char *symbol = get_symbol_name(                  char *symbol = get_symbol_name(&cpu->machine->symbol_context,
1603                      &cpu->machine->symbol_context, cpu->cd.mips.pc_last, &offset);                      cpu->cd.mips.pc_last, &offset);
1604                  fatal("warning: LOW reference vaddr=0x%08x, exception %s, pc=%08llx <%s>\n",                  fatal("[ ");
1605                      (int)vaddr, exception_names[exccode], (long long)cpu->cd.mips.pc_last, symbol? symbol : "(no symbol)");                  if (cpu->machine->ncpus > 1)
1606                            fatal("cpu%i: ", cpu->cpu_id);
1607                    fatal("warning: LOW reference vaddr=0x%08llx, exception %s, "
1608                        "pc=%08llx <%s> ]\n", (long long)vaddr,
1609                        exception_names[exccode], (long long)cpu->cd.mips.pc_last,
1610                        symbol? symbol : "(no symbol)");
1611    
1612    #ifdef TRACE_NULL_CRASHES
1613                    /*  This can be useful for debugging kernel bugs:  */
1614                    {
1615                            int i = cpu->trace_null_index;
1616                            do {
1617                                    fatal("TRACE: 0x%016llx\n",
1618                                        cpu->trace_null_addr[i]);
1619                                    i ++;
1620                                    i %= TRACE_NULL_N_ENTRIES;
1621                            } while (i != cpu->trace_null_index);
1622                    }
1623                    cpu->running = 0;
1624                    cpu->dead = 1;
1625    #endif
1626          }          }
1627    
1628          /*  Clear the exception code bits of the cause register...  */          /*  Clear the exception code bits of the cause register...  */
# Line 1881  int mips_cpu_run_instr(struct emul *emul Line 1892  int mips_cpu_run_instr(struct emul *emul
1892          /*  Cache the program counter in a local variable:  */          /*  Cache the program counter in a local variable:  */
1893          cached_pc = cpu->pc;          cached_pc = cpu->pc;
1894    
1895    #ifdef TRACE_NULL_CRASHES
1896            cpu->trace_null_addr[cpu->trace_null_index] = cached_pc;
1897            cpu->trace_null_index ++;
1898            cpu->trace_null_index %= TRACE_NULL_N_ENTRIES;
1899    #endif
1900    
1901          /*  Hardwire the zero register to 0:  */          /*  Hardwire the zero register to 0:  */
1902          cpu->cd.mips.gpr[MIPS_GPR_ZERO] = 0;          cpu->cd.mips.gpr[MIPS_GPR_ZERO] = 0;
1903    
# Line 1961  int mips_cpu_run_instr(struct emul *emul Line 1978  int mips_cpu_run_instr(struct emul *emul
1978    
1979    
1980          /*          /*
1981           *  ROM emulation:           *  ROM emulation:  (0xbfcXXXXX or 0x9fcXXXXX)
1982           *           *
1983           *  This assumes that a jal was made to a ROM address,           *  This assumes that a jal was made to a ROM address,
1984           *  and we should return via gpr ra.           *  and we should return via gpr ra.
1985           */           */
1986          if ((cached_pc & 0xfff00000) == 0xbfc00000 &&          if ((cached_pc & 0xdff00000) == 0x9fc00000 &&
1987              cpu->machine->prom_emulation) {              cpu->machine->prom_emulation) {
1988                  int rom_jal, res = 1;                  int rom_jal = 1, res = 1;
1989                  switch (cpu->machine->machine_type) {                  switch (cpu->machine->machine_type) {
1990                  case MACHINE_DEC:                  case MACHINE_DEC:
1991                          res = decstation_prom_emul(cpu);                          res = decstation_prom_emul(cpu);
                         rom_jal = 1;  
1992                          break;                          break;
1993                  case MACHINE_PS2:                  case MACHINE_PS2:
1994                          res = playstation2_sifbios_emul(cpu);                          res = playstation2_sifbios_emul(cpu);
                         rom_jal = 1;  
1995                          break;                          break;
1996                  case MACHINE_ARC:                  case MACHINE_ARC:
1997                  case MACHINE_SGI:                  case MACHINE_SGI:
1998                          res = arcbios_emul(cpu);                          res = arcbios_emul(cpu);
1999                          rom_jal = 1;                          break;
2000                    case MACHINE_EVBMIPS:
2001                            res = yamon_emul(cpu);
2002                          break;                          break;
2003                  default:                  default:
2004                          rom_jal = 0;                          rom_jal = 0;
# Line 2116  int mips_cpu_run_instr(struct emul *emul Line 2133  int mips_cpu_run_instr(struct emul *emul
2133    
2134    
2135  #ifdef BINTRANS  #ifdef BINTRANS
2136          /*  Caches are not very coozy to handle in bintrans:  */          if ((single_step || instruction_trace_cached)
         switch (cpu->cd.mips.cpu_type.mmu_model) {  
         case MMU3K:  
                 if (cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & MIPS1_ISOL_CACHES) {  
                         /*  cpu->cd.mips.dont_run_next_bintrans = 1;  */  
                         cpu->cd.mips.vaddr_to_hostaddr_table0 =  
                             cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & MIPS1_SWAP_CACHES?  
                                cpu->cd.mips.vaddr_to_hostaddr_table0_cacheisol_i  
                              : cpu->cd.mips.vaddr_to_hostaddr_table0_cacheisol_d;  
                 } else {  
                         cpu->cd.mips.vaddr_to_hostaddr_table0 =  
                             cpu->cd.mips.vaddr_to_hostaddr_table0_kernel;  
   
                         /*  TODO: cpu->cd.mips.vaddr_to_hostaddr_table0_user;  */  
                 }  
                 break;  
         default:  
                 cpu->cd.mips.vaddr_to_hostaddr_table0 =  
                     cpu->cd.mips.vaddr_to_hostaddr_table0_kernel;  
                 /*  TODO: cpu->cd.mips.vaddr_to_hostaddr_table0_user;  */  
         }  
   
         if ((single_step || cpu->machine->instruction_trace)  
2137              && cpu->machine->bintrans_enable)              && cpu->machine->bintrans_enable)
2138                  cpu->cd.mips.dont_run_next_bintrans = 1;                  cpu->cd.mips.dont_run_next_bintrans = 1;
2139  #endif  #endif
# Line 2288  int mips_cpu_run_instr(struct emul *emul Line 2283  int mips_cpu_run_instr(struct emul *emul
2283                                          res &= BINTRANS_N_MASK;                                          res &= BINTRANS_N_MASK;
2284    
2285                                          if (cpu->cd.mips.cpu_type.exc_model != EXC3K) {                                          if (cpu->cd.mips.cpu_type.exc_model != EXC3K) {
                                                 /*  TODO: 32-bit or 64-bit?  */  
2286                                                  int x = cp0->reg[COP0_COUNT], y = cp0->reg[COP0_COMPARE];                                                  int x = cp0->reg[COP0_COUNT], y = cp0->reg[COP0_COMPARE];
2287                                                  int diff = x - y;                                                  int diff = x - y;
2288                                                  if (diff < 0 && diff + (res-1) >= 0                                                  if (diff < 0 && diff + (res-1) >= 0
# Line 3329  int mips_cpu_run_instr(struct emul *emul Line 3323  int mips_cpu_run_instr(struct emul *emul
3323                                           *  (This cache-line was written to by                                           *  (This cache-line was written to by
3324                                           *  someone else.)                                           *  someone else.)
3325                                           */                                           */
3326                                          if (cpu->cd.mips.rmw == 0) {                                          if (cpu->cd.mips.rmw == 0 ||
3327                                                cpu->cd.mips.rmw_addr != addr ||
3328                                                cpu->cd.mips.rmw_len != wlen) {
3329                                                  /*  The store failed:  */                                                  /*  The store failed:  */
3330                                                  cpu->cd.mips.gpr[rt] = 0;                                                  cpu->cd.mips.gpr[rt] = 0;
3331                                                  if (instruction_trace_cached)                                                  if (instruction_trace_cached)
# Line 3373  int mips_cpu_run_instr(struct emul *emul Line 3369  int mips_cpu_run_instr(struct emul *emul
3369                                                                      !(cp0->reg[COP0_STATUS] & STATUS_FR))) {                                                                      !(cp0->reg[COP0_STATUS] & STATUS_FR))) {
3370                                                                          uint64_t a, b;                                                                          uint64_t a, b;
3371                                                                          coproc_register_read(cpu,                                                                          coproc_register_read(cpu,
3372                                                                              cpu->cd.mips.coproc[cpnr], rt, &a);                                                                              cpu->cd.mips.coproc[cpnr], rt, &a, 0);
3373                                                                          coproc_register_read(cpu,                                                                          coproc_register_read(cpu,
3374                                                                              cpu->cd.mips.coproc[cpnr], rt^1, &b);                                                                              cpu->cd.mips.coproc[cpnr], rt^1, &b, 0);
3375                                                                          if (rt & 1)                                                                          if (rt & 1)
3376                                                                                  fatal("WARNING: SDCx in 32-bit mode from odd register!\n");                                                                                  fatal("WARNING: SDCx in 32-bit mode from odd register!\n");
3377                                                                          value = (a & 0xffffffffULL)                                                                          value = (a & 0xffffffffULL)
3378                                                                              | (b << 32);                                                                              | (b << 32);
3379                                                                  } else                                                                  } else
3380                                                                          coproc_register_read(cpu, cpu->cd.mips.coproc[cpnr], rt, &value);                                                                          coproc_register_read(cpu, cpu->cd.mips.coproc[cpnr], rt, &value, 0);
3381                                                          }                                                          }
3382                                                          break;                                                          break;
3383                                          default:                                          default:
# Line 3518  int mips_cpu_run_instr(struct emul *emul Line 3514  int mips_cpu_run_instr(struct emul *emul
3514                                                                  b = (int64_t)(int32_t) (value >> 32);                                                                  b = (int64_t)(int32_t) (value >> 32);
3515                                                                  coproc_register_write(cpu,                                                                  coproc_register_write(cpu,
3516                                                                      cpu->cd.mips.coproc[cpnr], rt, &a,                                                                      cpu->cd.mips.coproc[cpnr], rt, &a,
3517                                                                      hi6==HI6_LDC1 || hi6==HI6_LDC2);                                                                      hi6==HI6_LDC1 || hi6==HI6_LDC2, 0);
3518                                                                  coproc_register_write(cpu,                                                                  coproc_register_write(cpu,
3519                                                                      cpu->cd.mips.coproc[cpnr], rt ^ 1, &b,                                                                      cpu->cd.mips.coproc[cpnr], rt ^ 1, &b,
3520                                                                      hi6==HI6_LDC1 || hi6==HI6_LDC2);                                                                      hi6==HI6_LDC1 || hi6==HI6_LDC2, 0);
3521                                                                  if (rt & 1)                                                                  if (rt & 1)
3522                                                                          fatal("WARNING: LDCx in 32-bit mode to odd register!\n");                                                                          fatal("WARNING: LDCx in 32-bit mode to odd register!\n");
3523                                                          } else {                                                          } else {
3524                                                                  coproc_register_write(cpu,                                                                  coproc_register_write(cpu,
3525                                                                      cpu->cd.mips.coproc[cpnr], rt, &value,                                                                      cpu->cd.mips.coproc[cpnr], rt, &value,
3526                                                                      hi6==HI6_LDC1 || hi6==HI6_LDC2);                                                                      hi6==HI6_LDC1 || hi6==HI6_LDC2, 0);
3527                                                          }                                                          }
3528                                                  }                                                  }
3529                                                  break;                                                  break;

Legend:
Removed from v.2  
changed lines
  Added in v.11

  ViewVC Help
Powered by ViewVC 1.1.26