/[gxemul]/trunk/src/cpus/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 /trunk/src/cpus/cpu_mips.c

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

revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC revision 40 by dpavlin, Mon Oct 8 16:22:11 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_mips.c,v 1.69 2006/10/07 02:05:21 debug Exp $   *  $Id: cpu_mips.c,v 1.79 2007/04/28 09:19:51 debug Exp $
29   *   *
30   *  MIPS core CPU emulation.   *  MIPS core CPU emulation.
31   */   */
# Line 88  void mips32_pc_to_pointers(struct cpu *) Line 88  void mips32_pc_to_pointers(struct cpu *)
88   *  Convert a register number into either 'r0', 'r31' etc, or a symbolic   *  Convert a register number into either 'r0', 'r31' etc, or a symbolic
89   *  name, depending on machine->show_symbolic_register_names.   *  name, depending on machine->show_symbolic_register_names.
90   *   *
91   *  NOTE: _NOT_ reentrant.   *  NOTE: This helper function is _NOT_ reentrant.
92   */   */
93  static char *regname(struct machine *machine, int r)  static char *regname(struct machine *machine, int r)
94  {  {
# Line 304  int mips_cpu_new(struct cpu *cpu, struct Line 304  int mips_cpu_new(struct cpu *cpu, struct
304                  debug(")");                  debug(")");
305          }          }
306    
307            /*  Register the CPU's interrupts:  */
308            for (i=2; i<8; i++) {
309                    struct interrupt template;
310                    char name[50];
311                    snprintf(name, sizeof(name), "%s.%i", cpu->path, i);
312                    memset(&template, 0, sizeof(template));
313                    template.line = 1 << (STATUS_IM_SHIFT + i);
314                    template.name = name;
315                    template.extra = cpu;
316                    template.interrupt_assert = mips_cpu_interrupt_assert;
317                    template.interrupt_deassert = mips_cpu_interrupt_deassert;
318                    interrupt_handler_register(&template);
319    
320                    if (i == 7)
321                            INTERRUPT_CONNECT(name, cpu->cd.mips.irq_compare);
322            }
323    
324          /*  System coprocessor (0), and FPU (1):  */          /*  System coprocessor (0), and FPU (1):  */
325          cpu->cd.mips.coproc[0] = mips_coproc_new(cpu, 0);          cpu->cd.mips.coproc[0] = mips_coproc_new(cpu, 0);
326          cpu->cd.mips.coproc[1] = mips_coproc_new(cpu, 1);          cpu->cd.mips.coproc[1] = mips_coproc_new(cpu, 1);
# Line 516  void mips_cpu_tlbdump(struct machine *m, Line 533  void mips_cpu_tlbdump(struct machine *m,
533          /*  Raw output:  */          /*  Raw output:  */
534          if (rawflag) {          if (rawflag) {
535                  for (i=0; i<m->ncpus; i++) {                  for (i=0; i<m->ncpus; i++) {
536                            struct mips_coproc *cop0 =
537                                m->cpus[i]->cd.mips.coproc[0];
538    
539                          if (x >= 0 && i != x)                          if (x >= 0 && i != x)
540                                  continue;                                  continue;
541    
# Line 523  void mips_cpu_tlbdump(struct machine *m, Line 543  void mips_cpu_tlbdump(struct machine *m,
543                          printf("cpu%i: (", i);                          printf("cpu%i: (", i);
544    
545                          if (m->cpus[i]->is_32bit)                          if (m->cpus[i]->is_32bit)
546                                  printf("index=0x%08x random=0x%08x", (int)m->                                  printf("index=0x%08x random=0x%08x",
547                                      cpus[i]->cd.mips.coproc[0]->reg[COP0_INDEX],                                      (int) cop0->reg[COP0_INDEX],
548                                      (int)m->cpus[i]->cd.mips.coproc[0]->reg                                      (int) cop0->reg[COP0_RANDOM]);
                                     [COP0_RANDOM]);  
549                          else                          else
550                                  printf("index=0x%016"PRIx64                                  printf("index=0x%016"PRIx64
551                                      " random=0x%016"PRIx64,                                      " random=0x%016"PRIx64,
552                                      (uint64_t)m->cpus[i]->cd.mips.coproc[0]->                                      (uint64_t) cop0->reg[COP0_INDEX],
553                                      reg[COP0_INDEX], (uint64_t)m->cpus[i]->                                      (uint64_t) cop0->reg[COP0_RANDOM]);
                                     cd.mips.coproc[0]->reg[COP0_RANDOM]);  
554    
555                          if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)                          if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)
556                                  printf(" wired=0x%"PRIx64, (uint64_t) m->cpus                                  printf(" wired=0x%"PRIx64,
557                                      [i]->cd.mips.coproc[0]->reg[COP0_WIRED]);                                      (uint64_t) cop0->reg[COP0_WIRED]);
558    
559                          printf(")\n");                          printf(")\n");
560    
# Line 544  void mips_cpu_tlbdump(struct machine *m, Line 562  void mips_cpu_tlbdump(struct machine *m,
562                              nr_of_tlb_entries; j++) {                              nr_of_tlb_entries; j++) {
563                                  if (m->cpus[i]->cd.mips.cpu_type.mmu_model ==                                  if (m->cpus[i]->cd.mips.cpu_type.mmu_model ==
564                                      MMU3K)                                      MMU3K)
565                                          printf("%3i: hi=0x%08x lo=0x%08x\n", j,                                          printf("%3i: hi=0x%08"PRIx32" lo=0x%08"
566                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                                              PRIx32"\n", j,
567                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0);                                              (uint32_t) cop0->tlbs[j].hi,
568                                                (uint32_t) cop0->tlbs[j].lo0);
569                                  else if (m->cpus[i]->is_32bit)                                  else if (m->cpus[i]->is_32bit)
570                                          printf("%3i: hi=0x%08x mask=0x%08x "                                          printf("%3i: hi=0x%08"PRIx32" mask=0x"
571                                              "lo0=0x%08x lo1=0x%08x\n", j,                                              "%08"PRIx32" lo0=0x%08"PRIx32
572                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                                              " lo1=0x%08"PRIx32"\n", j,
573                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,                                              (uint32_t) cop0->tlbs[j].hi,
574                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,                                              (uint32_t) cop0->tlbs[j].mask,
575                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);                                              (uint32_t) cop0->tlbs[j].lo0,
576                                                (uint32_t) cop0->tlbs[j].lo1);
577                                  else                                  else
578                                          printf("%3i: hi=0x%016"PRIx64" mask=0x%016"PRIx64" "                                          printf("%3i: hi=0x%016"PRIx64" mask="
579                                              "lo0=0x%016"PRIx64" lo1=0x%016"PRIx64"\n", j,                                              "0x%016"PRIx64" lo0=0x%016"PRIx64
580                                              (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                                              " lo1=0x%016"PRIx64"\n", j,
581                                              (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,                                              (uint64_t) cop0->tlbs[j].hi,
582                                              (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,                                              (uint64_t) cop0->tlbs[j].mask,
583                                              (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);                                              (uint64_t) cop0->tlbs[j].lo0,
584                                                (uint64_t) cop0->tlbs[j].lo1);
585                          }                          }
586                  }                  }
587    
588                  return;                  return;
589          }          }
590    
591          /*  Nicely formatted output:  */          /*  Nicely formatted output:  */
592          for (i=0; i<m->ncpus; i++) {          for (i=0; i<m->ncpus; i++) {
593                  int pageshift = 12;                  int pageshift = 12;
594                    struct mips_coproc *cop0 = m->cpus[i]->cd.mips.coproc[0];
595    
596                  if (x >= 0 && i != x)                  if (x >= 0 && i != x)
597                          continue;                          continue;
# Line 581  void mips_cpu_tlbdump(struct machine *m, Line 604  void mips_cpu_tlbdump(struct machine *m,
604                  switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {                  switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {
605                  case 1:                  case 1:
606                  case 2: printf("index=0x%x random=0x%x",                  case 2: printf("index=0x%x random=0x%x",
607                              (int) ((m->cpus[i]->cd.mips.coproc[0]->                              (int) ((cop0->reg[COP0_INDEX] & R2K3K_INDEX_MASK)
                             reg[COP0_INDEX] & R2K3K_INDEX_MASK)  
608                              >> R2K3K_INDEX_SHIFT),                              >> R2K3K_INDEX_SHIFT),
609                              (int) ((m->cpus[i]->cd.mips.coproc[0]->                              (int) ((cop0->reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)
                             reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)  
610                              >> R2K3K_RANDOM_SHIFT));                              >> R2K3K_RANDOM_SHIFT));
611                          break;                          break;
612                  default:printf("index=0x%x random=0x%x",                  default:printf("index=0x%x random=0x%x",
613                              (int) (m->cpus[i]->cd.mips.coproc[0]->                              (int) (cop0->reg[COP0_INDEX] & INDEX_MASK),
614                              reg[COP0_INDEX] & INDEX_MASK),                              (int) (cop0->reg[COP0_RANDOM] & RANDOM_MASK));
615                              (int) (m->cpus[i]->cd.mips.coproc[0]->                          printf(" wired=0x%"PRIx64,
616                              reg[COP0_RANDOM] & RANDOM_MASK));                              (uint64_t) cop0->reg[COP0_WIRED]);
                         printf(" wired=0x%"PRIx64, (uint64_t)  
                             m->cpus[i]->cd.mips.coproc[0]->reg[COP0_WIRED]);  
617                  }                  }
618    
619                  printf(")\n");                  printf(")\n");
620    
621                  for (j=0; j<m->cpus[i]->cd.mips.cpu_type.                  for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
622                      nr_of_tlb_entries; j++) {                      nr_of_tlb_entries; j++) {
623                          uint64_t hi,lo0,lo1,mask;                          uint64_t hi = cop0->tlbs[j].hi;
624                          hi = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi;                          uint64_t lo0 = cop0->tlbs[j].lo0;
625                          lo0 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0;                          uint64_t lo1 = cop0->tlbs[j].lo1;
626                          lo1 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1;                          uint64_t mask = cop0->tlbs[j].mask;
627                          mask = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask;                          uint64_t psize;
628    
629                            mask |= (1 << (pageshift+1)) - 1;
630                            /*  here mask = e.g. 0x1fff for 4KB pages  */
631    
632                          printf("%3i: ", j);                          printf("%3i: ", j);
633    
634                          switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {                          switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {
635                          case MMU3K:                          case MMU3K:
636                                  if (!(lo0 & R2K3K_ENTRYLO_V)) {                                  if (!(lo0 & R2K3K_ENTRYLO_V)) {
# Line 633  void mips_cpu_tlbdump(struct machine *m, Line 656  void mips_cpu_tlbdump(struct machine *m,
656                          default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){                          default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){
657                                  case MMU32:                                  case MMU32:
658                                          printf("vaddr=0x%08"PRIx32" ",                                          printf("vaddr=0x%08"PRIx32" ",
659                                              (uint32_t) hi);                                              (uint32_t) (hi & ~mask));
660                                          break;                                          break;
661                                  case MMU10K:                                  default:/*  R4x00, R1x000, MIPS64, etc.  */
                                 default:/*  R4000 etc.  */  
662                                          printf("vaddr=%016"PRIx64" ",                                          printf("vaddr=%016"PRIx64" ",
663                                              (uint64_t) hi);                                              (uint64_t) (hi & ~mask));
664                                  }                                  }
665                                  if (hi & TLB_G)                                  if (hi & TLB_G)
666                                          printf("(global): ");                                          printf("(global): ");
# Line 650  void mips_cpu_tlbdump(struct machine *m, Line 672  void mips_cpu_tlbdump(struct machine *m,
672    
673                                  if (!(lo0 & ENTRYLO_V))                                  if (!(lo0 & ENTRYLO_V))
674                                          printf(" p0=(invalid)   ");                                          printf(" p0=(invalid)   ");
675                                  else                                  else {
676                                          printf(" p0=0x%09"PRIx64" ", (uint64_t)                                          uint64_t paddr = lo0 & ENTRYLO_PFN_MASK;
677                                              (((lo0&ENTRYLO_PFN_MASK) >>                                          paddr >>= ENTRYLO_PFN_SHIFT;
678                                              ENTRYLO_PFN_SHIFT) << pageshift));                                          paddr <<= pageshift;
679                                            paddr &= ~(mask >> 1);
680                                            printf(" p0=0x%09"PRIx64" ",
681                                                (uint64_t) paddr);
682                                    }
683                                  printf(lo0 & ENTRYLO_D? "D" : " ");                                  printf(lo0 & ENTRYLO_D? "D" : " ");
684    
685                                  if (!(lo1 & ENTRYLO_V))                                  if (!(lo1 & ENTRYLO_V))
686                                          printf(" p1=(invalid)   ");                                          printf(" p1=(invalid)   ");
687                                  else                                  else {
688                                          printf(" p1=0x%09"PRIx64" ", (uint64_t)                                          uint64_t paddr = lo1 & ENTRYLO_PFN_MASK;
689                                              (((lo1&ENTRYLO_PFN_MASK) >>                                          paddr >>= ENTRYLO_PFN_SHIFT;
690                                              ENTRYLO_PFN_SHIFT) << pageshift));                                          paddr <<= pageshift;
691                                  printf(lo1 & ENTRYLO_D? "D" : " ");                                          paddr &= ~(mask >> 1);
692                                  mask |= (1 << (pageshift+1)) - 1;                                          printf(" p1=0x%09"PRIx64" ",
693                                  switch (mask) {                                              (uint64_t) paddr);
                                 case 0x7ff:     printf(" (1KB)"); break;  
                                 case 0x1fff:    printf(" (4KB)"); break;  
                                 case 0x7fff:    printf(" (16KB)"); break;  
                                 case 0x1ffff:   printf(" (64KB)"); break;  
                                 case 0x7ffff:   printf(" (256KB)"); break;  
                                 case 0x1fffff:  printf(" (1MB)"); break;  
                                 case 0x7fffff:  printf(" (4MB)"); break;  
                                 case 0x1ffffff: printf(" (16MB)"); break;  
                                 case 0x7ffffff: printf(" (64MB)"); break;  
                                 default:printf(" (mask=%08x?)", (int)mask);  
694                                  }                                  }
695                                    printf(lo1 & ENTRYLO_D? "D" : " ");
696    
697                                    /*  convert e.g. 0x1fff to 4096  */
698                                    psize = (mask + 1) >> 1;
699    
700                                    if (psize >= 1024 && psize <= 256*1024)
701                                            printf(" (%iKB)", (int) (psize >> 10));
702                                    else if (psize >= 1024*1024 && psize <=
703                                        64*1024*1024)
704                                            printf(" (%iMB)", (int) (psize >> 20));
705                                    else
706                                            printf(" (?)");
707    
708                                  printf("\n");                                  printf("\n");
709                          }                          }
710                  }                  }
# Line 1277  int mips_cpu_disassemble_instr(struct cp Line 1306  int mips_cpu_disassemble_instr(struct cp
1306                  if (cache_op==2)        debug("index store tag"), showtag=1;                  if (cache_op==2)        debug("index store tag"), showtag=1;
1307                  if (cache_op==3)        debug("create dirty exclusive");                  if (cache_op==3)        debug("create dirty exclusive");
1308                  if (cache_op==4)        debug("hit invalidate");                  if (cache_op==4)        debug("hit invalidate");
1309                  if (cache_op==5)        debug("fill OR hit writeback invalidate");                  if (cache_op==5)     debug("fill OR hit writeback invalidate");
1310                  if (cache_op==6)        debug("hit writeback");                  if (cache_op==6)        debug("hit writeback");
1311                  if (cache_op==7)        debug("hit set virtual");                  if (cache_op==7)        debug("hit set virtual");
1312                  if (running)                  if (running)
# Line 1558  void mips_cpu_register_dump(struct cpu * Line 1587  void mips_cpu_register_dump(struct cpu *
1587                                              "          ");                                              "          ");
1588                                  else                                  else
1589                                          debug(" %3s=%016"PRIx64"%016"PRIx64,                                          debug(" %3s=%016"PRIx64"%016"PRIx64,
1590                                              regname(cpu->machine, r),                                              regname(cpu->machine, r), (uint64_t)
1591                                              (uint64_t)cpu->cd.mips.gpr_quadhi[r],                                              cpu->cd.mips.gpr_quadhi[r],
1592                                              (uint64_t)cpu->cd.mips.gpr[r]);                                              (uint64_t)cpu->cd.mips.gpr[r]);
1593                                  if ((i & 1) == 1)                                  if ((i & 1) == 1)
1594                                          debug("\n");                                          debug("\n");
# Line 1623  void mips_cpu_register_dump(struct cpu * Line 1652  void mips_cpu_register_dump(struct cpu *
1652                                  debug(" c%i,%02i", coprocnr, i);                                  debug(" c%i,%02i", coprocnr, i);
1653    
1654                          if (bits32)                          if (bits32)
1655                                  debug("=%08x", (int)cpu->cd.mips.coproc[coprocnr]->reg[i]);                                  debug("=%08x", (int)cpu->cd.mips.
1656                                        coproc[coprocnr]->reg[i]);
1657                          else {                          else {
1658                                  if (coprocnr == 0 && (i == COP0_COUNT                                  if (coprocnr == 0 && (i == COP0_COUNT
1659                                      || i == COP0_COMPARE || i == COP0_INDEX                                      || i == COP0_COMPARE || i == COP0_INDEX
1660                                      || i == COP0_RANDOM || i == COP0_WIRED))                                      || i == COP0_RANDOM || i == COP0_WIRED))
1661                                          debug(" =         0x%08x", (int)cpu->cd.mips.coproc[coprocnr]->reg[i]);                                          debug(" =         0x%08x",
1662                                                (int) cpu->cd.mips.coproc[
1663                                                coprocnr]->reg[i]);
1664                                  else                                  else
1665                                          debug(" = 0x%016"PRIx64, (uint64_t)                                          debug(" = 0x%016"PRIx64, (uint64_t)
1666                                              cpu->cd.mips.coproc[coprocnr]->reg[i]);                                              cpu->cd.mips.coproc[
1667                                                coprocnr]->reg[i]);
1668                          }                          }
1669    
1670                          if ((i & nm1) == nm1)                          if ((i & nm1) == nm1)
# Line 1647  void mips_cpu_register_dump(struct cpu * Line 1680  void mips_cpu_register_dump(struct cpu *
1680                          debug("cpu%i: ", cpu->cpu_id);                          debug("cpu%i: ", cpu->cpu_id);
1681                          debug("config_select1 = 0x");                          debug("config_select1 = 0x");
1682                          if (cpu->is_32bit)                          if (cpu->is_32bit)
1683                                  debug("%08"PRIx32, (uint32_t)cpu->cd.mips.cop0_config_select1);                                  debug("%08"PRIx32,
1684                                        (uint32_t)cpu->cd.mips.cop0_config_select1);
1685                          else                          else
1686                                  debug("%016"PRIx64, (uint64_t)cpu->cd.mips.cop0_config_select1);                                  debug("%016"PRIx64,
1687                                        (uint64_t)cpu->cd.mips.cop0_config_select1);
1688                          debug("\n");                          debug("\n");
1689                  }                  }
1690    
# Line 1683  void mips_cpu_register_dump(struct cpu * Line 1718  void mips_cpu_register_dump(struct cpu *
1718  }  }
1719    
1720    
 static void add_response_word(struct cpu *cpu, char *r, uint64_t value,  
         size_t maxlen, int len)  
 {  
         char *format = (len == 4)? "%08"PRIx64 : "%016"PRIx64;  
         if (len == 4)  
                 value &= 0xffffffffULL;  
         if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {  
                 if (len == 4) {  
                         value = ((value & 0xff) << 24) +  
                                 ((value & 0xff00) << 8) +  
                                 ((value & 0xff0000) >> 8) +  
                                 ((value & 0xff000000) >> 24);  
                 } else {  
                         value = ((value & 0xff) << 56) +  
                                 ((value & 0xff00) << 40) +  
                                 ((value & 0xff0000) << 24) +  
                                 ((value & 0xff000000ULL) << 8) +  
                                 ((value & 0xff00000000ULL) >> 8) +  
                                 ((value & 0xff0000000000ULL) >> 24) +  
                                 ((value & 0xff000000000000ULL) >> 40) +  
                                 ((value & 0xff00000000000000ULL) >> 56);  
                 }  
         }  
         snprintf(r + strlen(r), maxlen - strlen(r), format, (uint64_t)value);  
 }  
   
   
 /*  
  *  mips_cpu_gdb_stub():  
  *  
  *  Execute a "remote GDB" command. Returns 1 on success, 0 on error.  
  */  
 char *mips_cpu_gdb_stub(struct cpu *cpu, char *cmd)  
 {  
         if (strcmp(cmd, "g") == 0) {  
                 /*  76 registers:  gprs, sr, lo, hi, badvaddr, cause, pc,  
                     fprs, fsr, fir, fp.  */  
                 int i;  
                 char *r;  
                 size_t wlen = cpu->is_32bit?  
                     sizeof(uint32_t) : sizeof(uint64_t);  
                 size_t len = 1 + 76 * wlen;  
                 r = malloc(len);  
                 if (r == NULL) {  
                         fprintf(stderr, "out of memory\n");  
                         exit(1);  
                 }  
                 r[0] = '\0';  
                 for (i=0; i<32; i++)  
                         add_response_word(cpu, r, cpu->cd.mips.gpr[i],  
                             len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[0]->reg[COP0_STATUS], len, wlen);  
                 add_response_word(cpu, r, cpu->cd.mips.lo, len, wlen);  
                 add_response_word(cpu, r, cpu->cd.mips.hi, len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[0]->reg[COP0_BADVADDR], len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[0]->reg[COP0_CAUSE], len, wlen);  
                 add_response_word(cpu, r, cpu->pc, len, wlen);  
                 for (i=0; i<32; i++)  
                         add_response_word(cpu, r,  
                             cpu->cd.mips.coproc[1]->reg[i], len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[1]->reg[31] /* fcsr */, len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[1]->reg[0] /* fcir */, len, wlen);  
   
                 /*  TODO: fp = gpr 30?  */  
                 add_response_word(cpu, r, cpu->cd.mips.gpr[30], len, wlen);  
   
                 return r;  
         }  
   
         if (cmd[0] == 'p') {  
                 int regnr = strtol(cmd + 1, NULL, 16);  
                 size_t wlen = cpu->is_32bit? sizeof(uint32_t):sizeof(uint64_t);  
                 size_t len = 2 * wlen + 1;  
                 char *r = malloc(len);  
                 r[0] = '\0';  
                 if (regnr >= 0 && regnr <= 31) {  
                         add_response_word(cpu, r,  
                             cpu->cd.mips.gpr[regnr], len, wlen);  
                 } else if (regnr == 0x20) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[0]->  
                             reg[COP0_STATUS], len, wlen);  
                 } else if (regnr == 0x21) {  
                         add_response_word(cpu, r, cpu->cd.mips.lo, len, wlen);  
                 } else if (regnr == 0x22) {  
                         add_response_word(cpu, r, cpu->cd.mips.hi, len, wlen);  
                 } else if (regnr == 0x23) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[0]->  
                             reg[COP0_BADVADDR], len, wlen);  
                 } else if (regnr == 0x24) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[0]->  
                             reg[COP0_CAUSE], len, wlen);  
                 } else if (regnr == 0x25) {  
                         add_response_word(cpu, r, cpu->pc, len, wlen);  
                 } else if (regnr >= 0x26 && regnr <= 0x45 &&  
                     cpu->cd.mips.coproc[1] != NULL) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[1]->  
                             reg[regnr - 0x26], len, wlen);  
                 } else if (regnr == 0x46) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[1]->  
                             fcr[MIPS_FPU_FCSR], len, wlen);  
                 } else if (regnr == 0x47) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[1]->  
                             fcr[MIPS_FPU_FCIR], len, wlen);  
                 } else {  
                         /*  Unimplemented:  */  
                         add_response_word(cpu, r, 0xcc000 + regnr, len, wlen);  
                 }  
                 return r;  
         }  
   
         fatal("mips_cpu_gdb_stub(): cmd='%s' TODO\n", cmd);  
         return NULL;  
 }  
   
   
1721  /*  /*
1722   *  mips_cpu_interrupt():   *  mips_cpu_interrupt_assert(), mips_cpu_interrupt_deassert():
  *  
  *  Cause an interrupt. If irq_nr is 2..7, then it is a MIPS hardware  
  *  interrupt. 0 and 1 are ignored (software interrupts).  
1723   *   *
1724   *  If irq_nr is >= 8, then this function calls md_interrupt().   *  Assert or deassert a MIPS CPU interrupt by masking in or out bits
1725     *  in the CAUSE register of coprocessor 0.
1726   */   */
1727  int mips_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  void mips_cpu_interrupt_assert(struct interrupt *interrupt)
1728  {  {
1729          if (irq_nr >= 8) {          struct cpu *cpu = interrupt->extra;
1730                  if (cpu->machine->md_interrupt != NULL)          cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] |= interrupt->line;
                         cpu->machine->md_interrupt(cpu->machine,  
                             cpu, irq_nr, 1);  
                 else  
                         fatal("mips_cpu_interrupt(): irq_nr = %i, "  
                             "but md_interrupt = NULL ?\n", irq_nr);  
                 return 1;  
         }  
   
         if (irq_nr < 2)  
                 return 0;  
   
         cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] |=  
             ((1 << irq_nr) << STATUS_IM_SHIFT);  
   
         return 1;  
1731  }  }
1732    void mips_cpu_interrupt_deassert(struct interrupt *interrupt)
   
 /*  
  *  mips_cpu_interrupt_ack():  
  *  
  *  Acknowledge an interrupt. If irq_nr is 2..7, then it is a MIPS hardware  
  *  interrupt.  Interrupts 0..1 are ignored (software interrupts).  
  *  
  *  If irq_nr is >= 8, then it is machine dependent, and md_interrupt() is  
  *  called.  
  */  
 int mips_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  
1733  {  {
1734          if (irq_nr >= 8) {          struct cpu *cpu = interrupt->extra;
1735                  if (cpu->machine->md_interrupt != NULL)          cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] &= ~interrupt->line;
                         cpu->machine->md_interrupt(cpu->machine, cpu,  
                             irq_nr, 0);  
                 else  
                         fatal("mips_cpu_interrupt_ack(): irq_nr = %i, "  
                             "but md_interrupt = NULL ?\n", irq_nr);  
                 return 1;  
         }  
   
         if (irq_nr < 2)  
                 return 0;  
   
         cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] &=  
             ~((1 << irq_nr) << STATUS_IM_SHIFT);  
   
         return 1;  
1736  }  }
1737    
1738    
# Line 1912  void mips_cpu_exception(struct cpu *cpu, Line 1784  void mips_cpu_exception(struct cpu *cpu,
1784                  switch (exccode) {                  switch (exccode) {
1785    
1786                  case EXCEPTION_INT:                  case EXCEPTION_INT:
1787                          debug(" cause_im=0x%02x", (int)((reg[COP0_CAUSE] & CAUSE_IP_MASK) >> CAUSE_IP_SHIFT));                          debug(" cause_im=0x%02x", (int)
1788                                ((reg[COP0_CAUSE] & CAUSE_IP_MASK)
1789                                >> CAUSE_IP_SHIFT));
1790                          break;                          break;
1791    
1792                  case EXCEPTION_SYS:                  case EXCEPTION_SYS:
# Line 2002  void mips_cpu_exception(struct cpu *cpu, Line 1876  void mips_cpu_exception(struct cpu *cpu,
1876    
1877                  if (exc_model == EXC3K) {                  if (exc_model == EXC3K) {
1878                          reg[COP0_CONTEXT] &= ~R2K3K_CONTEXT_BADVPN_MASK;                          reg[COP0_CONTEXT] &= ~R2K3K_CONTEXT_BADVPN_MASK;
1879                          reg[COP0_CONTEXT] |= ((vaddr_vpn2 << R2K3K_CONTEXT_BADVPN_SHIFT) & R2K3K_CONTEXT_BADVPN_MASK);                          reg[COP0_CONTEXT] |= ((vaddr_vpn2 <<
1880                                R2K3K_CONTEXT_BADVPN_SHIFT) &
1881                                R2K3K_CONTEXT_BADVPN_MASK);
1882    
1883                          reg[COP0_ENTRYHI] = (vaddr & R2K3K_ENTRYHI_VPN_MASK)                          reg[COP0_ENTRYHI] = (vaddr & R2K3K_ENTRYHI_VPN_MASK)
1884                              | (vaddr_asid << R2K3K_ENTRYHI_ASID_SHIFT);                              | (vaddr_asid << R2K3K_ENTRYHI_ASID_SHIFT);
# Line 2012  void mips_cpu_exception(struct cpu *cpu, Line 1888  void mips_cpu_exception(struct cpu *cpu,
1888                          reg[COP0_ENTRYHI] = (int64_t)(int32_t)reg[COP0_ENTRYHI];                          reg[COP0_ENTRYHI] = (int64_t)(int32_t)reg[COP0_ENTRYHI];
1889                  } else {                  } else {
1890                          if (cpu->cd.mips.cpu_type.rev == MIPS_R4100) {                          if (cpu->cd.mips.cpu_type.rev == MIPS_R4100) {
1891                                  reg[COP0_CONTEXT] &= ~CONTEXT_BADVPN2_MASK_R4100;                                  reg[COP0_CONTEXT] &=
1892                                  reg[COP0_CONTEXT] |= ((vaddr_vpn2 << CONTEXT_BADVPN2_SHIFT) & CONTEXT_BADVPN2_MASK_R4100);                                      ~CONTEXT_BADVPN2_MASK_R4100;
1893                                    reg[COP0_CONTEXT] |= ((vaddr_vpn2 <<
1894                                        CONTEXT_BADVPN2_SHIFT) &
1895                                        CONTEXT_BADVPN2_MASK_R4100);
1896    
1897                                  /*  TODO:  fix these  */                                  /*  TODO:  fix these  */
1898                                  reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK;                                  reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK;

Legend:
Removed from v.32  
changed lines
  Added in v.40

  ViewVC Help
Powered by ViewVC 1.1.26