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 */
/*
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;
} 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;
} 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;
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;
if (tlb->V0) {
addr = tlb->VPN & ~mask;
#ifdef TARGET_MIPS64
- if (addr >= 0xC00000FF80000000ULL) {
+ if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
addr |= 0x3FFFFF0000000000ULL;
}
#endif
if (tlb->V1) {
addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
#ifdef TARGET_MIPS64
- if (addr >= 0xC00000FF80000000ULL) {
+ if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
addr |= 0x3FFFFF0000000000ULL;
}
#endif
int32_t CCRes;
int32_t Status_rw_bitmask;
int32_t CP1_fcr0;
+ int32_t SEGBITS;
};
/*****************************************************************************/
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x3278FF17,
+ .SEGBITS = 32,
},
{
.name = "4KEcR1",
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x3278FF17,
+ .SEGBITS = 32,
},
{
.name = "4KEc",
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x3278FF17,
+ .SEGBITS = 32,
},
{
.name = "24Kc",
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x3278FF17,
+ .SEGBITS = 32,
},
{
.name = "24Kf",
.Status_rw_bitmask = 0x3678FF17,
.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
(1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
+ .SEGBITS = 32,
},
#ifdef TARGET_MIPS64
{
.Status_rw_bitmask = 0x3678FFFF,
/* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
+ .SEGBITS = 40,
},
{
.name = "5Kc",
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x32F8FFFF,
+ .SEGBITS = 42,
},
{
.name = "5Kf",
/* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
.CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
(0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
+ .SEGBITS = 42,
},
{
.name = "20Kc",
.CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
(1 << FCR0_D) | (1 << FCR0_S) |
(0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
+ .SEGBITS = 40,
},
#endif
};
env->CCRes = def->CCRes;
env->Status_rw_bitmask = def->Status_rw_bitmask;
env->fcr0 = def->CP1_fcr0;
+#ifdef TARGET_MIPS64
+ env->SEGBITS = def->SEGBITS;
+ env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1);
+#endif
#ifdef CONFIG_USER_ONLY
if (env->CP0_Config1 & (1 << CP0C1_FP))
env->hflags |= MIPS_HFLAG_FPU;