From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JuXbS-0007LJ-8X for qemu-devel@nongnu.org; Fri, 09 May 2008 14:45:58 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JuXbR-0007Kq-C7 for qemu-devel@nongnu.org; Fri, 09 May 2008 14:45:57 -0400 Received: from [199.232.76.173] (port=53875 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JuXbR-0007Km-87 for qemu-devel@nongnu.org; Fri, 09 May 2008 14:45:57 -0400 Received: from savannah.gnu.org ([199.232.41.3]:52960 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 1JuXbQ-0007uR-PC for qemu-devel@nongnu.org; Fri, 09 May 2008 14:45:56 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1JuXbQ-0004RA-Dg for qemu-devel@nongnu.org; Fri, 09 May 2008 18:45:56 +0000 Received: from aurel32 by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1JuXbQ-0004R5-8k for qemu-devel@nongnu.org; Fri, 09 May 2008 18:45:56 +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, 09 May 2008 18:45:56 +0000 Subject: [Qemu-devel] [4396] SH4 MMU improvements 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: 4396 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4396 Author: aurel32 Date: 2008-05-09 18:45:55 +0000 (Fri, 09 May 2008) Log Message: ----------- SH4 MMU improvements (Shin-ichiro KAWASAKI) Modified Paths: -------------- trunk/hw/sh7750.c trunk/target-sh4/cpu.h trunk/target-sh4/exec.h trunk/target-sh4/helper.c trunk/target-sh4/op.c trunk/target-sh4/op_helper.c trunk/target-sh4/translate.c Modified: trunk/hw/sh7750.c =================================================================== --- trunk/hw/sh7750.c 2008-05-09 18:45:47 UTC (rev 4395) +++ trunk/hw/sh7750.c 2008-05-09 18:45:55 UTC (rev 4396) @@ -360,6 +360,9 @@ case SH7750_PTEL_A7: s->cpu->ptel = mem_value; return; + case SH7750_PTEA_A7: + s->cpu->ptea = mem_value & 0x0000000f; + return; case SH7750_TTB_A7: s->cpu->ttb = mem_value; return; Modified: trunk/target-sh4/cpu.h =================================================================== --- trunk/target-sh4/cpu.h 2008-05-09 18:45:47 UTC (rev 4395) +++ trunk/target-sh4/cpu.h 2008-05-09 18:45:55 UTC (rev 4396) @@ -163,5 +163,78 @@ #define MMUCR 0x1F000010 #define MMUCR_AT (1<<0) #define MMUCR_SV (1<<8) +#define MMUCR_URC_BITS (6) +#define MMUCR_URC_OFFSET (10) +#define MMUCR_URC_SIZE (1 << MMUCR_URC_BITS) +#define MMUCR_URC_MASK (((MMUCR_URC_SIZE) - 1) << MMUCR_URC_OFFSET) +static inline int cpu_mmucr_urc (uint32_t mmucr) +{ + return ((mmucr & MMUCR_URC_MASK) >> MMUCR_URC_OFFSET); +} +/* PTEH : Page Translation Entry High register */ +#define PTEH_ASID_BITS (8) +#define PTEH_ASID_SIZE (1 << PTEH_ASID_BITS) +#define PTEH_ASID_MASK (PTEH_ASID_SIZE - 1) +#define cpu_pteh_asid(pteh) ((pteh) & PTEH_ASID_MASK) +#define PTEH_VPN_BITS (22) +#define PTEH_VPN_OFFSET (10) +#define PTEH_VPN_SIZE (1 << PTEH_VPN_BITS) +#define PTEH_VPN_MASK (((PTEH_VPN_SIZE) - 1) << PTEH_VPN_OFFSET) +static inline int cpu_pteh_vpn (uint32_t pteh) +{ + return ((pteh & PTEH_VPN_MASK) >> PTEH_VPN_OFFSET); +} + +/* PTEL : Page Translation Entry Low register */ +#define PTEL_V (1 << 8) +#define cpu_ptel_v(ptel) (((ptel) & PTEL_V) >> 8) +#define PTEL_C (1 << 3) +#define cpu_ptel_c(ptel) (((ptel) & PTEL_C) >> 3) +#define PTEL_D (1 << 2) +#define cpu_ptel_d(ptel) (((ptel) & PTEL_D) >> 2) +#define PTEL_SH (1 << 1) +#define cpu_ptel_sh(ptel)(((ptel) & PTEL_SH) >> 1) +#define PTEL_WT (1 << 0) +#define cpu_ptel_wt(ptel) ((ptel) & PTEL_WT) + +#define PTEL_SZ_HIGH_OFFSET (7) +#define PTEL_SZ_HIGH (1 << PTEL_SZ_HIGH_OFFSET) +#define PTEL_SZ_LOW_OFFSET (4) +#define PTEL_SZ_LOW (1 << PTEL_SZ_LOW_OFFSET) +static inline int cpu_ptel_sz (uint32_t ptel) +{ + int sz; + sz = (ptel & PTEL_SZ_HIGH) >> PTEL_SZ_HIGH_OFFSET; + sz <<= 1; + sz |= (ptel & PTEL_SZ_LOW) >> PTEL_SZ_LOW_OFFSET; + return sz; +} + +#define PTEL_PPN_BITS (19) +#define PTEL_PPN_OFFSET (10) +#define PTEL_PPN_SIZE (1 << PTEL_PPN_BITS) +#define PTEL_PPN_MASK (((PTEL_PPN_SIZE) - 1) << PTEL_PPN_OFFSET) +static inline int cpu_ptel_ppn (uint32_t ptel) +{ + return ((ptel & PTEL_PPN_MASK) >> PTEL_PPN_OFFSET); +} + +#define PTEL_PR_BITS (2) +#define PTEL_PR_OFFSET (5) +#define PTEL_PR_SIZE (1 << PTEL_PR_BITS) +#define PTEL_PR_MASK (((PTEL_PR_SIZE) - 1) << PTEL_PR_OFFSET) +static inline int cpu_ptel_pr (uint32_t ptel) +{ + return ((ptel & PTEL_PR_MASK) >> PTEL_PR_OFFSET); +} + +/* PTEA : Page Translation Entry Assistance register */ +#define PTEA_SA_BITS (3) +#define PTEA_SA_SIZE (1 << PTEA_SA_BITS) +#define PTEA_SA_MASK (PTEA_SA_SIZE - 1) +#define cpu_ptea_sa(ptea) ((ptea) & PTEA_SA_MASK) +#define PTEA_TC (1 << 3) +#define cpu_ptea_tc(ptea) (((ptea) & PTEA_TC) >> 3) + #endif /* _CPU_SH4_H */ Modified: trunk/target-sh4/exec.h =================================================================== --- trunk/target-sh4/exec.h 2008-05-09 18:45:47 UTC (rev 4395) +++ trunk/target-sh4/exec.h 2008-05-09 18:45:55 UTC (rev 4396) @@ -64,6 +64,7 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, int mmu_idx, int is_softmmu); +void cpu_load_tlb(CPUState * env); int find_itlb_entry(CPUState * env, target_ulong address, int use_asid, int update); @@ -81,6 +82,7 @@ void helper_subv_T0_T1(void); void helper_rotcl(uint32_t * addr); void helper_rotcr(uint32_t * addr); +void helper_ldtlb(void); void do_interrupt(CPUState * env); Modified: trunk/target-sh4/helper.c =================================================================== --- trunk/target-sh4/helper.c 2008-05-09 18:45:47 UTC (rev 4395) +++ trunk/target-sh4/helper.c 2008-05-09 18:45:55 UTC (rev 4396) @@ -193,7 +193,7 @@ switch (itlbnb) { case 0: - and_mask = 0x7f; + and_mask = 0x1f; break; case 1: and_mask = 0xe7; @@ -208,7 +208,7 @@ break; } - env->mmucr &= (and_mask << 24); + env->mmucr &= (and_mask << 24) | 0x00ffffff; env->mmucr |= (or_mask << 24); } @@ -216,7 +216,7 @@ { if ((env->mmucr & 0xe0000000) == 0xe0000000) return 0; - if ((env->mmucr & 0x98000000) == 0x08000000) + if ((env->mmucr & 0x98000000) == 0x18000000) return 1; if ((env->mmucr & 0x54000000) == 0x04000000) return 2; @@ -264,7 +264,7 @@ start = (entries[i].vpn << 10) & ~(entries[i].size - 1); end = start + entries[i].size - 1; if (address >= start && address <= end) { /* Match */ - if (match != -1) + if (match != MMU_DTLB_MISS) return MMU_DTLB_MULTIPLE; /* Multiple match */ match = i; } @@ -290,8 +290,10 @@ n = itlb_replacement(env); env->itlb[n] = env->utlb[e]; e = n; - } - } + } else if (e == MMU_DTLB_MISS) + e = MMU_ITLB_MISS; + } else if (e == MMU_DTLB_MISS) + e = MMU_ITLB_MISS; if (e >= 0) update_itlb_use(env, e); return e; @@ -418,6 +420,21 @@ target_ulong physical, page_offset, page_size; int prot, ret, access_type; + switch (rw) { + case 0: + rw = PAGE_READ; + break; + case 1: + rw = PAGE_WRITE; + break; + case 2: /* READ_ACCESS_TYPE == 2 defined in softmmu_template.h */ + rw = PAGE_READ; + break; + default: + /* fatal error */ + assert(0); + } + /* XXXXX */ #if 0 fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n", @@ -479,4 +496,41 @@ return physical; } +void cpu_load_tlb(CPUState * env) +{ + int n = cpu_mmucr_urc(env->mmucr); + tlb_t * entry = &env->utlb[n]; + + /* Take values into cpu status from registers. */ + entry->asid = (uint8_t)cpu_pteh_asid(env->pteh); + entry->vpn = cpu_pteh_vpn(env->pteh); + entry->v = (uint8_t)cpu_ptel_v(env->ptel); + entry->ppn = cpu_ptel_ppn(env->ptel); + entry->sz = (uint8_t)cpu_ptel_sz(env->ptel); + switch (entry->sz) { + case 0: /* 00 */ + entry->size = 1024; /* 1K */ + break; + case 1: /* 01 */ + entry->size = 1024 * 4; /* 4K */ + break; + case 2: /* 10 */ + entry->size = 1024 * 64; /* 64K */ + break; + case 3: /* 11 */ + entry->size = 1024 * 1024; /* 1M */ + break; + default: + assert(0); + break; + } + entry->sh = (uint8_t)cpu_ptel_sh(env->ptel); + entry->c = (uint8_t)cpu_ptel_c(env->ptel); + entry->pr = (uint8_t)cpu_ptel_pr(env->ptel); + entry->d = (uint8_t)cpu_ptel_d(env->ptel); + entry->wt = (uint8_t)cpu_ptel_wt(env->ptel); + entry->sa = (uint8_t)cpu_ptea_sa(env->ptea); + entry->tc = (uint8_t)cpu_ptea_tc(env->ptea); +} + #endif Modified: trunk/target-sh4/op.c =================================================================== --- trunk/target-sh4/op.c 2008-05-09 18:45:47 UTC (rev 4395) +++ trunk/target-sh4/op.c 2008-05-09 18:45:55 UTC (rev 4396) @@ -185,6 +185,12 @@ RETURN(); } +void OPPROTO op_ldtlb(void) +{ + helper_ldtlb(); + RETURN(); +} + void OPPROTO op_sets(void) { env->sr |= SR_S; Modified: trunk/target-sh4/op_helper.c =================================================================== --- trunk/target-sh4/op_helper.c 2008-05-09 18:45:47 UTC (rev 4395) +++ trunk/target-sh4/op_helper.c 2008-05-09 18:45:55 UTC (rev 4396) @@ -76,6 +76,16 @@ #endif +void helper_ldtlb(void) +{ +#ifdef CONFIG_USER_ONLY + /* XXXXX */ + assert(0); +#else + cpu_load_tlb(env); +#endif +} + void helper_addc_T0_T1(void) { uint32_t tmp0, tmp1; Modified: trunk/target-sh4/translate.c =================================================================== --- trunk/target-sh4/translate.c 2008-05-09 18:45:47 UTC (rev 4395) +++ trunk/target-sh4/translate.c 2008-05-09 18:45:55 UTC (rev 4396) @@ -256,7 +256,11 @@ gen_op_clrt(); return; case 0x0038: /* ldtlb */ +#if defined(CONFIG_USER_ONLY) assert(0); /* XXXXX */ +#else + gen_op_ldtlb(); +#endif return; case 0x002b: /* rte */ CHECK_NOT_DELAY_SLOT gen_op_rte();