Revision e034e2c3
b/target-mips/cpu.h | ||
---|---|---|
102 | 102 |
|
103 | 103 |
uint32_t nb_tlb; |
104 | 104 |
uint32_t tlb_in_use; |
105 |
uint32_t SEGBITS; |
|
106 |
target_ulong SEGMask; |
|
105 | 107 |
int (*map_address) (CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type); |
106 | 108 |
void (*do_tlbwi) (void); |
107 | 109 |
void (*do_tlbwr) (void); |
b/target-mips/helper.c | ||
---|---|---|
77 | 77 |
target_ulong tag = address & ~mask; |
78 | 78 |
target_ulong VPN = tlb->VPN & ~mask; |
79 | 79 |
#ifdef TARGET_MIPS64 |
80 |
tag &= 0xC00000FFFFFFFFFFULL;
|
|
80 |
tag &= env->SEGMask;
|
|
81 | 81 |
#endif |
82 | 82 |
|
83 | 83 |
/* Check ASID, virtual page number & size */ |
... | ... | |
140 | 140 |
/* |
141 | 141 |
XXX: Assuming : |
142 | 142 |
- PABITS = 36 (correct for MIPS64R1) |
143 |
- SEGBITS = 40 |
|
144 | 143 |
*/ |
145 | 144 |
} else if (address < 0x3FFFFFFFFFFFFFFFULL) { |
146 | 145 |
/* xuseg */ |
147 |
if (UX && address < 0x000000FFFFFFFFFFULL) {
|
|
146 |
if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
|
|
148 | 147 |
ret = env->map_address(env, physical, prot, address, rw, access_type); |
149 | 148 |
} else { |
150 | 149 |
ret = TLBRET_BADADDR; |
151 | 150 |
} |
152 | 151 |
} else if (address < 0x7FFFFFFFFFFFFFFFULL) { |
153 | 152 |
/* xsseg */ |
154 |
if (SX && address < 0x400000FFFFFFFFFFULL) {
|
|
153 |
if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
|
|
155 | 154 |
ret = env->map_address(env, physical, prot, address, rw, access_type); |
156 | 155 |
} else { |
157 | 156 |
ret = TLBRET_BADADDR; |
... | ... | |
159 | 158 |
} else if (address < 0xBFFFFFFFFFFFFFFFULL) { |
160 | 159 |
/* xkphys */ |
161 | 160 |
/* XXX: check supervisor mode */ |
162 |
if (KX && (address & 0x03FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
|
|
161 |
if (KX && (address & 0x07FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
|
|
163 | 162 |
{ |
164 |
*physical = address & 0X000000FFFFFFFFFFULL;
|
|
163 |
*physical = address & 0X0000000FFFFFFFFFULL;
|
|
165 | 164 |
*prot = PAGE_READ | PAGE_WRITE; |
166 | 165 |
} else { |
167 | 166 |
ret = TLBRET_BADADDR; |
... | ... | |
169 | 168 |
} else if (address < 0xFFFFFFFF7FFFFFFFULL) { |
170 | 169 |
/* xkseg */ |
171 | 170 |
/* XXX: check supervisor mode */ |
172 |
if (KX && address < 0xC00000FF7FFFFFFFULL) {
|
|
171 |
if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
|
|
173 | 172 |
ret = env->map_address(env, physical, prot, address, rw, access_type); |
174 | 173 |
} else { |
175 | 174 |
ret = TLBRET_BADADDR; |
... | ... | |
303 | 302 |
env->CP0_EntryHi = |
304 | 303 |
(env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1)); |
305 | 304 |
#ifdef TARGET_MIPS64 |
306 |
env->CP0_EntryHi &= 0xc00000ffffffffffULL;
|
|
307 |
env->CP0_XContext = (env->CP0_XContext & 0xfffffffe00000000ULL) |
|
|
308 |
((address >> 31) & 0x0000000180000000ULL) |
|
|
309 |
((address >> 9) & 0x000000007ffffff0ULL);
|
|
305 |
env->CP0_EntryHi &= env->SEGMask;
|
|
306 |
env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) |
|
|
307 |
((address & 0xC00000000000ULL) >> (env->SEGBITS - 9)) |
|
|
308 |
((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9);
|
|
310 | 309 |
#endif |
311 | 310 |
env->exception_index = exception; |
312 | 311 |
env->error_code = error_code; |
... | ... | |
555 | 554 |
if (tlb->V0) { |
556 | 555 |
addr = tlb->VPN & ~mask; |
557 | 556 |
#ifdef TARGET_MIPS64 |
558 |
if (addr >= 0xC00000FF80000000ULL) {
|
|
557 |
if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
|
|
559 | 558 |
addr |= 0x3FFFFF0000000000ULL; |
560 | 559 |
} |
561 | 560 |
#endif |
... | ... | |
568 | 567 |
if (tlb->V1) { |
569 | 568 |
addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); |
570 | 569 |
#ifdef TARGET_MIPS64 |
571 |
if (addr >= 0xC00000FF80000000ULL) {
|
|
570 |
if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
|
|
572 | 571 |
addr |= 0x3FFFFF0000000000ULL; |
573 | 572 |
} |
574 | 573 |
#endif |
b/target-mips/op.c | ||
---|---|---|
1328 | 1328 |
/* 1k pages not implemented */ |
1329 | 1329 |
val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF); |
1330 | 1330 |
#ifdef TARGET_MIPS64 |
1331 |
val = T0 & 0xC00000FFFFFFFFFFULL;
|
|
1331 |
val &= env->SEGMask;
|
|
1332 | 1332 |
#endif |
1333 | 1333 |
old = env->CP0_EntryHi; |
1334 | 1334 |
env->CP0_EntryHi = val; |
... | ... | |
1526 | 1526 |
#ifdef TARGET_MIPS64 |
1527 | 1527 |
void op_mtc0_xcontext (void) |
1528 | 1528 |
{ |
1529 |
env->CP0_XContext = (env->CP0_XContext & 0x1ffffffffULL) | (T0 & ~0x1ffffffffULL); |
|
1529 |
target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1; |
|
1530 |
env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask); |
|
1530 | 1531 |
RETURN(); |
1531 | 1532 |
} |
1532 | 1533 |
|
b/target-mips/op_helper.c | ||
---|---|---|
374 | 374 |
tlb = &env->mmu.r4k.tlb[idx]; |
375 | 375 |
tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1); |
376 | 376 |
#ifdef TARGET_MIPS64 |
377 |
tlb->VPN &= 0xC00000FFFFFFFFFFULL;
|
|
377 |
tlb->VPN &= env->SEGMask;
|
|
378 | 378 |
#endif |
379 | 379 |
tlb->ASID = env->CP0_EntryHi & 0xFF; |
380 | 380 |
tlb->PageMask = env->CP0_PageMask; |
b/target-mips/translate_init.c | ||
---|---|---|
71 | 71 |
int32_t CCRes; |
72 | 72 |
int32_t Status_rw_bitmask; |
73 | 73 |
int32_t CP1_fcr0; |
74 |
int32_t SEGBITS; |
|
74 | 75 |
}; |
75 | 76 |
|
76 | 77 |
/*****************************************************************************/ |
... | ... | |
87 | 88 |
.SYNCI_Step = 32, |
88 | 89 |
.CCRes = 2, |
89 | 90 |
.Status_rw_bitmask = 0x3278FF17, |
91 |
.SEGBITS = 32, |
|
90 | 92 |
}, |
91 | 93 |
{ |
92 | 94 |
.name = "4KEcR1", |
... | ... | |
98 | 100 |
.SYNCI_Step = 32, |
99 | 101 |
.CCRes = 2, |
100 | 102 |
.Status_rw_bitmask = 0x3278FF17, |
103 |
.SEGBITS = 32, |
|
101 | 104 |
}, |
102 | 105 |
{ |
103 | 106 |
.name = "4KEc", |
... | ... | |
109 | 112 |
.SYNCI_Step = 32, |
110 | 113 |
.CCRes = 2, |
111 | 114 |
.Status_rw_bitmask = 0x3278FF17, |
115 |
.SEGBITS = 32, |
|
112 | 116 |
}, |
113 | 117 |
{ |
114 | 118 |
.name = "24Kc", |
... | ... | |
120 | 124 |
.SYNCI_Step = 32, |
121 | 125 |
.CCRes = 2, |
122 | 126 |
.Status_rw_bitmask = 0x3278FF17, |
127 |
.SEGBITS = 32, |
|
123 | 128 |
}, |
124 | 129 |
{ |
125 | 130 |
.name = "24Kf", |
... | ... | |
133 | 138 |
.Status_rw_bitmask = 0x3678FF17, |
134 | 139 |
.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | |
135 | 140 |
(1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), |
141 |
.SEGBITS = 32, |
|
136 | 142 |
}, |
137 | 143 |
#ifdef TARGET_MIPS64 |
138 | 144 |
{ |
... | ... | |
147 | 153 |
.Status_rw_bitmask = 0x3678FFFF, |
148 | 154 |
/* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */ |
149 | 155 |
.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV), |
156 |
.SEGBITS = 40, |
|
150 | 157 |
}, |
151 | 158 |
{ |
152 | 159 |
.name = "5Kc", |
... | ... | |
161 | 168 |
.SYNCI_Step = 32, |
162 | 169 |
.CCRes = 2, |
163 | 170 |
.Status_rw_bitmask = 0x32F8FFFF, |
171 |
.SEGBITS = 42, |
|
164 | 172 |
}, |
165 | 173 |
{ |
166 | 174 |
.name = "5Kf", |
... | ... | |
178 | 186 |
/* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */ |
179 | 187 |
.CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) | |
180 | 188 |
(0x81 << FCR0_PRID) | (0x0 << FCR0_REV), |
189 |
.SEGBITS = 42, |
|
181 | 190 |
}, |
182 | 191 |
{ |
183 | 192 |
.name = "20Kc", |
... | ... | |
198 | 207 |
.CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) | |
199 | 208 |
(1 << FCR0_D) | (1 << FCR0_S) | |
200 | 209 |
(0x82 << FCR0_PRID) | (0x0 << FCR0_REV), |
210 |
.SEGBITS = 40, |
|
201 | 211 |
}, |
202 | 212 |
#endif |
203 | 213 |
}; |
... | ... | |
274 | 284 |
env->CCRes = def->CCRes; |
275 | 285 |
env->Status_rw_bitmask = def->Status_rw_bitmask; |
276 | 286 |
env->fcr0 = def->CP1_fcr0; |
287 |
#ifdef TARGET_MIPS64 |
|
288 |
env->SEGBITS = def->SEGBITS; |
|
289 |
env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1); |
|
290 |
#endif |
|
277 | 291 |
#ifdef CONFIG_USER_ONLY |
278 | 292 |
if (env->CP0_Config1 & (1 << CP0C1_FP)) |
279 | 293 |
env->hflags |= MIPS_HFLAG_FPU; |
Also available in: Unified diff