From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KWSSw-0004ZU-GC for qemu-devel@nongnu.org; Fri, 22 Aug 2008 04:57:54 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KWSSv-0004Yp-P6 for qemu-devel@nongnu.org; Fri, 22 Aug 2008 04:57:54 -0400 Received: from [199.232.76.173] (port=51521 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KWSSv-0004Yh-KY for qemu-devel@nongnu.org; Fri, 22 Aug 2008 04:57:53 -0400 Received: from savannah.gnu.org ([199.232.41.3]:49182 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KWSSv-0001XG-FZ for qemu-devel@nongnu.org; Fri, 22 Aug 2008 04:57:53 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1KWSSu-00057N-OA for qemu-devel@nongnu.org; Fri, 22 Aug 2008 08:57:52 +0000 Received: from aurel32 by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1KWSSu-00057J-Hy for qemu-devel@nongnu.org; Fri, 22 Aug 2008 08:57:52 +0000 MIME-Version: 1.0 Errors-To: aurel32 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Aurelien Jarno Message-Id: Date: Fri, 22 Aug 2008 08:57:52 +0000 Subject: [Qemu-devel] [5068] [sh4] MMU bug fix Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 5068 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5068 Author: aurel32 Date: 2008-08-22 08:57:52 +0000 (Fri, 22 Aug 2008) Log Message: ----------- [sh4] MMU bug fix Some bugs on SH4 MMU are fixed. - When a TLB entry is overwritten or invalidated, tlb_flush_page() should be invoked to invalidate old entry. - When a ASID is changed, tlb_flush() should be invoke to invalidate entries which have old ASID. - The check for shared bit in TLB entry causes multiple TLB hit exception. As SH3's MMU, shared bit is ignored. - ASID is used when MMUCR's SV bit or SR's MD bit is zero. No need to check both bits are zero. (Shin-ichiro KAWASAKI) Modified Paths: -------------- trunk/hw/sh7750.c trunk/target-sh4/helper.c Modified: trunk/hw/sh7750.c =================================================================== --- trunk/hw/sh7750.c 2008-08-22 08:57:43 UTC (rev 5067) +++ trunk/hw/sh7750.c 2008-08-22 08:57:52 UTC (rev 5068) @@ -30,6 +30,7 @@ #include "sh7750_regs.h" #include "sh7750_regnames.h" #include "sh_intc.h" +#include "exec-all.h" #include "cpu.h" #define NB_DEVICES 4 @@ -356,6 +357,9 @@ s->cpu->mmucr = mem_value; return; case SH7750_PTEH_A7: + /* If asid changes, clear all registered tlb entries. */ + if ((s->cpu->pteh & 0xff) != (mem_value & 0xff)) + tlb_flush(s->cpu, 1); s->cpu->pteh = mem_value; return; case SH7750_PTEL_A7: Modified: trunk/target-sh4/helper.c =================================================================== --- trunk/target-sh4/helper.c 2008-08-22 08:57:43 UTC (rev 5067) +++ trunk/target-sh4/helper.c 2008-08-22 08:57:52 UTC (rev 5068) @@ -251,7 +251,7 @@ for (i = 0; i < nbtlb; i++) { if (!entries[i].v) continue; /* Invalid entry */ - if (use_asid && entries[i].asid != asid && !entries[i].sh) + if (use_asid && entries[i].asid != asid) continue; /* Bad ASID */ #if 0 switch (entries[i].sz) { @@ -320,8 +320,14 @@ else if (e == MMU_DTLB_MISS && update) { e = find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid); if (e >= 0) { + tlb_t * ientry; n = itlb_replacement(env); - env->itlb[n] = env->utlb[e]; + ientry = &env->itlb[n]; + if (ientry->v) { + if (!same_tlb_entry_exists(env->utlb, UTLB_SIZE, ientry)) + tlb_flush_page(env, ientry->vpn << 10); + } + *ientry = env->utlb[e]; e = n; } else if (e == MMU_DTLB_MISS) e = MMU_ITLB_MISS; @@ -356,7 +362,7 @@ int use_asid, is_code, n; tlb_t *matching = NULL; - use_asid = (env->mmucr & MMUCR_SV) == 0 && (env->sr & SR_MD) == 0; + use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0; is_code = env->pc == address; /* Hack */ /* Use a hack to find if this is an instruction or data access */ @@ -540,6 +546,17 @@ int n = cpu_mmucr_urc(env->mmucr); tlb_t * entry = &env->utlb[n]; + if (entry->v) { + /* Overwriting valid entry in utlb. */ + target_ulong address = entry->vpn << 10; + if (!same_tlb_entry_exists(env->itlb, ITLB_SIZE, entry)) { + tlb_flush_page(env, address); + } + } + + /* per utlb access cannot implemented. */ + increment_urc(env); + /* Take values into cpu status from registers. */ entry->asid = (uint8_t)cpu_pteh_asid(env->pteh); entry->vpn = cpu_pteh_vpn(env->pteh);