--- trunk/src/cpus/cpu_mips_coproc.c 2007/10/08 16:19:56 24 +++ trunk/src/cpus/cpu_mips_coproc.c 2007/10/08 16:20:10 26 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $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 $ * * Emulation of MIPS coprocessors. */ @@ -557,31 +557,7 @@ if (cp->coproc_nr==0 && reg_nr==COP0_PAGEMASK) unimpl = 0; if (cp->coproc_nr==0 && reg_nr==COP0_WIRED) unimpl = 0; if (cp->coproc_nr==0 && reg_nr==COP0_BADVADDR) unimpl = 0; - if (cp->coproc_nr==0 && reg_nr==COP0_COUNT) { -#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; - } + if (cp->coproc_nr==0 && reg_nr==COP0_COUNT) unimpl = 0; if (cp->coproc_nr==0 && reg_nr==COP0_ENTRYHI) unimpl = 0; if (cp->coproc_nr==0 && reg_nr==COP0_COMPARE) unimpl = 0; if (cp->coproc_nr==0 && reg_nr==COP0_STATUS) unimpl = 0; @@ -828,20 +804,32 @@ case COP0_STATUS: oldmode = cp->reg[COP0_STATUS]; tmp &= ~(1 << 21); /* bit 21 is read-only */ + /* - * TODO: Perhaps this can be solved some other - * way, like in the old bintrans system? + * When isolating caches, invalidate all translations. + * During the isolation, a special hack in memory_rw.c + * prevents translation tables from being updated, so + * the translation caches don't have to be invalidated + * when switching back to normal mode. */ if (cpu->cd.mips.cpu_type.mmu_model == MMU3K && (oldmode & MIPS1_ISOL_CACHES) != (tmp & MIPS1_ISOL_CACHES)) { - cpu->invalidate_translation_caches( - cpu, 0, INVALIDATE_ALL); + /* Invalidate everything if we are switching + to isolated mode: */ + if (tmp & MIPS1_ISOL_CACHES) { + cpu->invalidate_translation_caches( + cpu, 0, INVALIDATE_ALL); + } - /* Perhaps add some kind of INVALIDATE_ - ALL_PADDR_WHICH_HAS_A_CORRESPONDING_ - VADDR of some kind? :-) */ +#if 1 + /* + * NOTE: This is not needed for NetBSD, but + * Ultrix and Linux still needs this. They + * shouldn't, though. Something else is buggy. + */ cpu_create_or_reset_tc(cpu); +#endif } unimpl = 0; break; @@ -1756,26 +1744,27 @@ cp->tlbs[index].hi |= TLB_G; } -#if 1 - cpu_create_or_reset_tc(cpu); -#else /* Invalidate any code translations, if we are writing Dirty pages to the TLB: */ -if (cp->reg[COP0_PAGEMASK] != 0) -printf("MASK = %08"PRIx32"\n", (uint32_t)cp->reg[COP0_PAGEMASK]); + if (cp->reg[COP0_PAGEMASK] != 0 && + cp->reg[COP0_PAGEMASK] != 0x1800) { + printf("TODO: MASK = %08"PRIx32"\n", + (uint32_t)cp->reg[COP0_PAGEMASK]); + exit(1); + } -// if (cp->tlbs[index].lo0 & ENTRYLO_D) + if (cp->tlbs[index].lo0 & ENTRYLO_D) cpu->invalidate_code_translation(cpu, ((cp->tlbs[index].lo0 & ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << 12, INVALIDATE_PADDR); -// if (cp->tlbs[index].lo1 & ENTRYLO_D) + if (cp->tlbs[index].lo1 & ENTRYLO_D) cpu->invalidate_code_translation(cpu, ((cp->tlbs[index].lo1 & ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << 12, INVALIDATE_PADDR); - +#if 1 if (cpu->cd.mips.cpu_type.mmu_model == MMU10K) { oldvaddr = cp->tlbs[index].hi & ENTRYHI_VPN2_MASK_R10K; /* 44 addressable bits: */ @@ -1797,10 +1786,6 @@ cpu->invalidate_translation_caches(cpu, ((cp->tlbs[index].lo1 & ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << 12, INVALIDATE_PADDR); -cpu->invalidate_translation_caches(cpu, oldvaddr, INVALIDATE_VADDR); -cpu->invalidate_translation_caches(cpu, oldvaddr | 0x1000, INVALIDATE_VADDR); - - #endif } }