diff options
author | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-06-23 18:04:12 +0000 |
---|---|---|
committer | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-06-23 18:04:12 +0000 |
commit | e034e2c39aee1800101812045690e0575abb428b (patch) | |
tree | d549ba6b2d7b25cf83ab2995b9cee9266fc80f96 /target-mips/helper.c | |
parent | 5c40d2bd4836636b762906bf1516c30b0ed5d74c (diff) |
Handle MIPS64 SEGBITS value correctly.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3011 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips/helper.c')
-rw-r--r-- | target-mips/helper.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/target-mips/helper.c b/target-mips/helper.c index 9da6212a59..87a6a334e8 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -77,7 +77,7 @@ int r4k_map_address (CPUState *env, target_ulong *physical, int *prot, target_ulong tag = address & ~mask; target_ulong VPN = tlb->VPN & ~mask; #ifdef TARGET_MIPS64 - tag &= 0xC00000FFFFFFFFFFULL; + tag &= env->SEGMask; #endif /* Check ASID, virtual page number & size */ @@ -140,18 +140,17 @@ static int get_physical_address (CPUState *env, target_ulong *physical, /* XXX: Assuming : - PABITS = 36 (correct for MIPS64R1) - - SEGBITS = 40 */ } else if (address < 0x3FFFFFFFFFFFFFFFULL) { /* xuseg */ - if (UX && address < 0x000000FFFFFFFFFFULL) { + if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) { ret = env->map_address(env, physical, prot, address, rw, access_type); } else { ret = TLBRET_BADADDR; } } else if (address < 0x7FFFFFFFFFFFFFFFULL) { /* xsseg */ - if (SX && address < 0x400000FFFFFFFFFFULL) { + if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) { ret = env->map_address(env, physical, prot, address, rw, access_type); } else { ret = TLBRET_BADADDR; @@ -159,9 +158,9 @@ static int get_physical_address (CPUState *env, target_ulong *physical, } else if (address < 0xBFFFFFFFFFFFFFFFULL) { /* xkphys */ /* XXX: check supervisor mode */ - if (KX && (address & 0x03FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL) + if (KX && (address & 0x07FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL) { - *physical = address & 0X000000FFFFFFFFFFULL; + *physical = address & 0X0000000FFFFFFFFFULL; *prot = PAGE_READ | PAGE_WRITE; } else { ret = TLBRET_BADADDR; @@ -169,7 +168,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical, } else if (address < 0xFFFFFFFF7FFFFFFFULL) { /* xkseg */ /* XXX: check supervisor mode */ - if (KX && address < 0xC00000FF7FFFFFFFULL) { + if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) { ret = env->map_address(env, physical, prot, address, rw, access_type); } else { ret = TLBRET_BADADDR; @@ -303,10 +302,10 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, env->CP0_EntryHi = (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1)); #ifdef TARGET_MIPS64 - env->CP0_EntryHi &= 0xc00000ffffffffffULL; - env->CP0_XContext = (env->CP0_XContext & 0xfffffffe00000000ULL) | - ((address >> 31) & 0x0000000180000000ULL) | - ((address >> 9) & 0x000000007ffffff0ULL); + env->CP0_EntryHi &= env->SEGMask; + env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) | + ((address & 0xC00000000000ULL) >> (env->SEGBITS - 9)) | + ((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9); #endif env->exception_index = exception; env->error_code = error_code; @@ -555,7 +554,7 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra) if (tlb->V0) { addr = tlb->VPN & ~mask; #ifdef TARGET_MIPS64 - if (addr >= 0xC00000FF80000000ULL) { + if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) { addr |= 0x3FFFFF0000000000ULL; } #endif @@ -568,7 +567,7 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra) if (tlb->V1) { addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); #ifdef TARGET_MIPS64 - if (addr >= 0xC00000FF80000000ULL) { + if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) { addr |= 0x3FFFFF0000000000ULL; } #endif |