Commit e034e2c39aee1800101812045690e0575abb428b

Authored by ths
1 parent 5c40d2bd

Handle MIPS64 SEGBITS value correctly.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3011 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/cpu.h
... ... @@ -102,6 +102,8 @@ struct CPUMIPSState {
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);
... ...
target-mips/helper.c
... ... @@ -77,7 +77,7 @@ int r4k_map_address (CPUState *env, target_ulong *physical, int *prot,
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,18 +140,17 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
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,9 +158,9 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
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,7 +168,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
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,10 +302,10 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
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,7 +554,7 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra)
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,7 +567,7 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra)
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
... ...
target-mips/op.c
... ... @@ -1328,7 +1328,7 @@ void op_mtc0_entryhi (void)
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,7 +1526,8 @@ void op_mtc0_desave (void)
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  
... ...
target-mips/op_helper.c
... ... @@ -374,7 +374,7 @@ static void r4k_fill_tlb (int idx)
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;
... ...
target-mips/translate_init.c
... ... @@ -71,6 +71,7 @@ struct mips_def_t {
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,6 +88,7 @@ static mips_def_t mips_defs[] =
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,6 +100,7 @@ static mips_def_t mips_defs[] =
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,6 +112,7 @@ static mips_def_t mips_defs[] =
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,6 +124,7 @@ static mips_def_t mips_defs[] =
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,6 +138,7 @@ static mips_def_t mips_defs[] =
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,6 +153,7 @@ static mips_def_t mips_defs[] =
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,6 +168,7 @@ static mips_def_t mips_defs[] =
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,6 +186,7 @@ static mips_def_t mips_defs[] =
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,6 +207,7 @@ static mips_def_t mips_defs[] =
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,6 +284,10 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
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;
... ...