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