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

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

revision 25 by dpavlin, Mon Oct 8 16:19:56 2007 UTC revision 26 by dpavlin, Mon Oct 8 16:20:10 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_mips_coproc.c,v 1.33 2006/06/22 13:30:38 debug Exp $   *  $Id: cpu_mips_coproc.c,v 1.37 2006/06/25 02:46:07 debug Exp $
29   *   *
30   *  Emulation of MIPS coprocessors.   *  Emulation of MIPS coprocessors.
31   */   */
# Line 557  void coproc_register_read(struct cpu *cp Line 557  void coproc_register_read(struct cpu *cp
557          if (cp->coproc_nr==0 && reg_nr==COP0_PAGEMASK)  unimpl = 0;          if (cp->coproc_nr==0 && reg_nr==COP0_PAGEMASK)  unimpl = 0;
558          if (cp->coproc_nr==0 && reg_nr==COP0_WIRED)     unimpl = 0;          if (cp->coproc_nr==0 && reg_nr==COP0_WIRED)     unimpl = 0;
559          if (cp->coproc_nr==0 && reg_nr==COP0_BADVADDR)  unimpl = 0;          if (cp->coproc_nr==0 && reg_nr==COP0_BADVADDR)  unimpl = 0;
560          if (cp->coproc_nr==0 && reg_nr==COP0_COUNT) {          if (cp->coproc_nr==0 && reg_nr==COP0_COUNT)     unimpl = 0;
 #if 0  
                 /*  
                  *  This speeds up delay-loops that just read the count  
                  *  register until it has reached a certain value. (Only for  
                  *  R4000 etc.)  
                  *  
                  *  TODO: Maybe this should be optional?  
                  */  
                 if (cpu->cd.mips.cpu_type.exc_model != EXC3K) {  
                         int increase = 500;  
                         int32_t x = cp->reg[COP0_COUNT];  
                         int32_t y = cp->reg[COP0_COMPARE];  
                         int32_t diff = x - y;  
                         if (diff < 0 && diff + increase >= 0  
                             && cpu->cd.mips.compare_register_set) {  
                                 mips_cpu_interrupt(cpu, 7);  
                                 cpu->cd.mips.compare_register_set = 0;  
                         }  
                         cp->reg[COP0_COUNT] = (int64_t)  
                             (int32_t)(cp->reg[COP0_COUNT] + increase);  
                 }  
 #endif  
                 unimpl = 0;  
         }  
561          if (cp->coproc_nr==0 && reg_nr==COP0_ENTRYHI)   unimpl = 0;          if (cp->coproc_nr==0 && reg_nr==COP0_ENTRYHI)   unimpl = 0;
562          if (cp->coproc_nr==0 && reg_nr==COP0_COMPARE)   unimpl = 0;          if (cp->coproc_nr==0 && reg_nr==COP0_COMPARE)   unimpl = 0;
563          if (cp->coproc_nr==0 && reg_nr==COP0_STATUS)    unimpl = 0;          if (cp->coproc_nr==0 && reg_nr==COP0_STATUS)    unimpl = 0;
# Line 828  void coproc_register_write(struct cpu *c Line 804  void coproc_register_write(struct cpu *c
804                  case COP0_STATUS:                  case COP0_STATUS:
805                          oldmode = cp->reg[COP0_STATUS];                          oldmode = cp->reg[COP0_STATUS];
806                          tmp &= ~(1 << 21);      /*  bit 21 is read-only  */                          tmp &= ~(1 << 21);      /*  bit 21 is read-only  */
807    
808                          /*                          /*
809                           *  TODO: Perhaps this can be solved some other                           *  When isolating caches, invalidate all translations.
810                           *  way, like in the old bintrans system?                           *  During the isolation, a special hack in memory_rw.c
811                             *  prevents translation tables from being updated, so
812                             *  the translation caches don't have to be invalidated
813                             *  when switching back to normal mode.
814                           */                           */
815                          if (cpu->cd.mips.cpu_type.mmu_model == MMU3K &&                          if (cpu->cd.mips.cpu_type.mmu_model == MMU3K &&
816                              (oldmode & MIPS1_ISOL_CACHES) !=                              (oldmode & MIPS1_ISOL_CACHES) !=
817                              (tmp & MIPS1_ISOL_CACHES)) {                              (tmp & MIPS1_ISOL_CACHES)) {
818                                  cpu->invalidate_translation_caches(                                  /*  Invalidate everything if we are switching
819                                      cpu, 0, INVALIDATE_ALL);                                      to isolated mode:  */
820                                    if (tmp & MIPS1_ISOL_CACHES) {
821                                            cpu->invalidate_translation_caches(
822                                                cpu, 0, INVALIDATE_ALL);
823                                    }
824    
825                                  /*  Perhaps add some kind of INVALIDATE_  #if 1
826                                      ALL_PADDR_WHICH_HAS_A_CORRESPONDING_                                  /*
827                                      VADDR of some kind? :-)  */                                   *  NOTE: This is not needed for NetBSD, but
828                                     *  Ultrix and Linux still needs this. They
829                                     *  shouldn't, though. Something else is buggy.
830                                     */
831                                  cpu_create_or_reset_tc(cpu);                                  cpu_create_or_reset_tc(cpu);
832    #endif
833                          }                          }
834                          unimpl = 0;                          unimpl = 0;
835                          break;                          break;
# Line 1756  void coproc_tlbwri(struct cpu *cpu, int Line 1744  void coproc_tlbwri(struct cpu *cpu, int
1744                                  cp->tlbs[index].hi |= TLB_G;                                  cp->tlbs[index].hi |= TLB_G;
1745                  }                  }
1746    
 #if 1  
                 cpu_create_or_reset_tc(cpu);  
 #else  
1747                  /*  Invalidate any code translations, if we are writing                  /*  Invalidate any code translations, if we are writing
1748                      Dirty pages to the TLB:  */                      Dirty pages to the TLB:  */
1749  if (cp->reg[COP0_PAGEMASK] != 0)                  if (cp->reg[COP0_PAGEMASK] != 0 &&
1750  printf("MASK = %08"PRIx32"\n", (uint32_t)cp->reg[COP0_PAGEMASK]);                      cp->reg[COP0_PAGEMASK] != 0x1800) {
1751                            printf("TODO: MASK = %08"PRIx32"\n",
1752                                (uint32_t)cp->reg[COP0_PAGEMASK]);
1753                            exit(1);
1754                    }
1755    
1756  //              if (cp->tlbs[index].lo0 & ENTRYLO_D)                  if (cp->tlbs[index].lo0 & ENTRYLO_D)
1757                          cpu->invalidate_code_translation(cpu,                          cpu->invalidate_code_translation(cpu,
1758                              ((cp->tlbs[index].lo0 & ENTRYLO_PFN_MASK)                              ((cp->tlbs[index].lo0 & ENTRYLO_PFN_MASK)
1759                              >> ENTRYLO_PFN_SHIFT) << 12,                              >> ENTRYLO_PFN_SHIFT) << 12,
1760                              INVALIDATE_PADDR);                              INVALIDATE_PADDR);
1761  //              if (cp->tlbs[index].lo1 & ENTRYLO_D)                  if (cp->tlbs[index].lo1 & ENTRYLO_D)
1762                          cpu->invalidate_code_translation(cpu,                          cpu->invalidate_code_translation(cpu,
1763                              ((cp->tlbs[index].lo1 & ENTRYLO_PFN_MASK)                              ((cp->tlbs[index].lo1 & ENTRYLO_PFN_MASK)
1764                              >> ENTRYLO_PFN_SHIFT) << 12,                              >> ENTRYLO_PFN_SHIFT) << 12,
1765                              INVALIDATE_PADDR);                              INVALIDATE_PADDR);
1766    
1767    #if 1
1768          if (cpu->cd.mips.cpu_type.mmu_model == MMU10K) {          if (cpu->cd.mips.cpu_type.mmu_model == MMU10K) {
1769                          oldvaddr = cp->tlbs[index].hi & ENTRYHI_VPN2_MASK_R10K;                          oldvaddr = cp->tlbs[index].hi & ENTRYHI_VPN2_MASK_R10K;
1770                          /*  44 addressable bits:  */                          /*  44 addressable bits:  */
# Line 1797  ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) Line 1786  ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT)
1786  cpu->invalidate_translation_caches(cpu, ((cp->tlbs[index].lo1 &  cpu->invalidate_translation_caches(cpu, ((cp->tlbs[index].lo1 &
1787  ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << 12, INVALIDATE_PADDR);  ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << 12, INVALIDATE_PADDR);
1788    
 cpu->invalidate_translation_caches(cpu, oldvaddr, INVALIDATE_VADDR);  
 cpu->invalidate_translation_caches(cpu, oldvaddr | 0x1000, INVALIDATE_VADDR);  
   
   
1789  #endif  #endif
1790          }          }
1791  }  }

Legend:
Removed from v.25  
changed lines
  Added in v.26

  ViewVC Help
Powered by ViewVC 1.1.26