--- trunk/src/cpu_mips_coproc.c 2007/10/08 16:18:31 11 +++ trunk/src/cpu_mips_coproc.c 2007/10/08 16:18:38 12 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu_mips_coproc.c,v 1.23 2005/06/26 11:36:27 debug Exp $ + * $Id: cpu_mips_coproc.c,v 1.27 2005/08/14 15:47:36 debug Exp $ * * Emulation of MIPS coprocessors. */ @@ -88,7 +88,7 @@ #else const int m16 = 0; #endif - int cpu_type, IB, DB, SB, IC, DC, SC; + int cpu_type, IB, DB, SB, IC, DC, SC, IA, DA; /* Default values: */ c->reg[COP0_CONFIG] = @@ -319,7 +319,8 @@ | ( 1 << 7) /* MMU type: 1=TLB, 3=FMT */ | ( 2 << 0) /* kseg0 cache coherency algorithm */ ; - /* Config select 1: caches etc. TODO: Associativity? */ + /* Config select 1: caches etc. TODO: Don't use + cpu->machine for this stuff! */ IB = cpu->machine->cache_picache_linesize - 1; IB = IB < 0? 0 : (IB > 7? 7 : IB); DB = cpu->machine->cache_pdcache_linesize - 1; @@ -328,14 +329,16 @@ cpu->machine->cache_picache_linesize - 7; DC = cpu->machine->cache_pdcache - cpu->machine->cache_pdcache_linesize - 7; + IA = cpu->cd.mips.cpu_type.piways - 1; + DA = cpu->cd.mips.cpu_type.pdways - 1; cpu->cd.mips.cop0_config_select1 = ((cpu->cd.mips.cpu_type.nr_of_tlb_entries - 1) << 25) | (IC << 22) /* IS: I-cache sets per way */ | (IB << 19) /* IL: I-cache line-size */ - | (1 << 16) /* IA: I-cache assoc. (ways-1) */ + | (IA << 16) /* IA: I-cache assoc. (ways-1) */ | (DC << 13) /* DS: D-cache sets per way */ | (DB << 10) /* DL: D-cache line-size */ - | (1 << 7) /* DA: D-cache assoc. (ways-1) */ + | (DA << 7) /* DA: D-cache assoc. (ways-1) */ | (16 * 0) /* Existance of PerformanceCounters */ | ( 8 * 0) /* Existance of Watch Registers */ | ( 4 * m16) /* Existance of MIPS16 */ @@ -532,14 +535,13 @@ } -#ifdef BINTRANS /* * old_update_translation_table(): */ static void old_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page) { - int a, b; + int a, b, index; struct vth32_table *tbl1; void *p_r, *p_w; uint32_t p_paddr; @@ -555,8 +557,11 @@ a = (vaddr_page >> 22) & 0x3ff; b = (vaddr_page >> 12) & 0x3ff; + index = (vaddr_page >> 12) & 0xfffff; + /* printf("vaddr = %08x, a = %03x, b = %03x\n", (int)vaddr_page,a, b); */ + tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a]; /* printf("tbl1 = %p\n", tbl1); */ if (tbl1 == cpu->cd.mips.vaddr_to_hostaddr_nulltable) { @@ -572,8 +577,7 @@ memset(tbl1, 0, sizeof(struct vth32_table)); } else { tbl1 = cpu->cd.mips.next_free_vth_table; - cpu->cd.mips.next_free_vth_table = - tbl1->next_free; + cpu->cd.mips.next_free_vth_table = tbl1->next_free; tbl1->next_free = NULL; } cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a] = tbl1; @@ -596,33 +600,50 @@ if (writeflag == -1) { /* Forced downgrade to read-only: */ tbl1->haddr_entry[b*2 + 1] = NULL; + if (cpu->cd.mips.host_store == + cpu->cd.mips.host_store_orig) + cpu->cd.mips.host_store[index] = NULL; } else if (writeflag==0 && p_w != NULL && host_page != NULL) { /* Don't degrade a page from writable to readonly. */ } else { if (host_page != NULL) { tbl1->haddr_entry[b*2] = host_page; - if (writeflag) + if (cpu->cd.mips.host_load == + cpu->cd.mips.host_load_orig) + cpu->cd.mips.host_load[index] = host_page; + if (writeflag) { tbl1->haddr_entry[b*2+1] = host_page; - else + if (cpu->cd.mips.host_store == + cpu->cd.mips.host_store_orig) + cpu->cd.mips.host_store[index] = + host_page; + } else { tbl1->haddr_entry[b*2+1] = NULL; + if (cpu->cd.mips.host_store == + cpu->cd.mips.host_store_orig) + cpu->cd.mips.host_store[index] = NULL; + } } else { tbl1->haddr_entry[b*2] = NULL; tbl1->haddr_entry[b*2+1] = NULL; + if (cpu->cd.mips.host_store == + cpu->cd.mips.host_store_orig) { + cpu->cd.mips.host_load[index] = NULL; + cpu->cd.mips.host_store[index] = NULL; + } } tbl1->paddr_entry[b] = paddr_page; } tbl1->bintrans_chunks[b] = NULL; } -#endif /* - * update_translation_table(): + * mips_update_translation_table(): */ -void update_translation_table(struct cpu *cpu, uint64_t vaddr_page, +void mips_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page) { -#ifdef BINTRANS if (!cpu->machine->bintrans_enable) return; @@ -637,17 +658,15 @@ /* TODO */ /* printf("update_translation_table(): TODO\n"); */ -#endif } -#ifdef BINTRANS /* * invalidate_table_entry(): */ static void invalidate_table_entry(struct cpu *cpu, uint64_t vaddr) { - int a, b; + int a, b, index; struct vth32_table *tbl1; void *p_r, *p_w; uint32_t p_paddr; @@ -674,6 +693,7 @@ a = (vaddr >> 22) & 0x3ff; b = (vaddr >> 12) & 0x3ff; + index = (vaddr >> 12) & 0xfffff; /* printf("vaddr = %08x, a = %03x, b = %03x\n", (int)vaddr,a, b); */ @@ -684,6 +704,8 @@ p_paddr = tbl1->paddr_entry[b]; tbl1->bintrans_chunks[b] = NULL; /* printf("B: p_r=%p p_w=%p\n", p_r,p_w); */ + cpu->cd.mips.host_load_orig[index] = NULL; + cpu->cd.mips.host_store_orig[index] = NULL; if (p_r != NULL || p_paddr != 0) { /* printf("Found a mapping, " "vaddr = %08x, a = %03x, b = %03x\n", (int)vaddr,a, b); */ @@ -719,15 +741,23 @@ tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a]; if (tbl1 != cpu->cd.mips.vaddr_to_hostaddr_nulltable) { for (b=0; b<0x400; b++) { + int index; + tbl1->haddr_entry[b*2] = NULL; tbl1->haddr_entry[b*2+1] = NULL; tbl1->paddr_entry[b] = 0; tbl1->bintrans_chunks[b] = NULL; + + if (cpu->cd.mips.host_store == + cpu->cd.mips.host_store_orig) { + index = (a << 10) + b; + cpu->cd.mips.host_load[index] = NULL; + cpu->cd.mips.host_store[index] = NULL; + } } } } } -#endif /* @@ -737,7 +767,6 @@ */ void mips_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t paddr) { -#ifdef BINTRANS paddr &= ~0xfff; if (cpu->machine->bintrans_enable) { @@ -842,8 +871,6 @@ cpu->bintrans_data_hostpage[i] = NULL; } #endif - -#endif } @@ -862,7 +889,6 @@ /* printf("inval(all=%i, kernel=%i, addr=%016llx)\n", all, kernelspace, (long long)vaddr); */ -#ifdef BINTRANS if (!cpu->machine->bintrans_enable) goto nobintrans; @@ -943,7 +969,6 @@ /* TODO: Don't invalidate everything. */ for (i=0; icd.mips.bintrans_data_hostpage[i] = NULL; -#endif if (kernelspace) all = 1; @@ -1276,7 +1301,6 @@ } #endif -#ifdef BINTRANS if (cpu->cd.mips.cpu_type.mmu_model == MMU3K && (oldmode & MIPS1_ISOL_CACHES) != (tmp & MIPS1_ISOL_CACHES)) { @@ -1284,24 +1308,34 @@ treated in bintrans mode by changing the vaddr_to_hostaddr_table0 pointer: */ if (tmp & MIPS1_ISOL_CACHES) { - /* cpu->cd.mips. - dont_run_next_bintrans = 1; */ + /* 2-level table: */ cpu->cd.mips.vaddr_to_hostaddr_table0 = tmp & MIPS1_SWAP_CACHES? cpu->cd.mips. vaddr_to_hostaddr_table0_cacheisol_i : cpu->cd.mips. vaddr_to_hostaddr_table0_cacheisol_d; + + /* 1M-entry table: */ + cpu->cd.mips.host_load = + cpu->cd.mips.host_store = + cpu->cd.mips.huge_r2k3k_cache_table; } else { + /* 2-level table: */ cpu->cd.mips.vaddr_to_hostaddr_table0 = cpu->cd.mips. vaddr_to_hostaddr_table0_kernel; /* TODO: cpu->cd.mips. vaddr_to_hostaddr_table0_user; */ + + /* 1M-entry table: */ + cpu->cd.mips.host_load = + cpu->cd.mips.host_load_orig; + cpu->cd.mips.host_store = + cpu->cd.mips.host_store_orig; } } -#endif unimpl = 0; break; case COP0_CAUSE: @@ -2422,7 +2456,7 @@ /* if (vaddr < 0x10000000) */ wf = 0; - update_translation_table(cpu, vaddr, memblock, + cpu->update_translation_table(cpu, vaddr, memblock, wf, paddr); } } else {