Commit 55754d9ef27178cf0e13aea85062fc4c32e25f83

Authored by bellard
1 parent afc7df11

MMU fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1308 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/helper.c
@@ -414,9 +414,9 @@ target_ulong mmu_probe(target_ulong address, int mmulev) @@ -414,9 +414,9 @@ target_ulong mmu_probe(target_ulong address, int mmulev)
414 return 0; 414 return 0;
415 } 415 }
416 416
  417 +#ifdef DEBUG_MMU
417 void dump_mmu(void) 418 void dump_mmu(void)
418 { 419 {
419 -#ifdef DEBUG_MMU  
420 target_ulong va, va1, va2; 420 target_ulong va, va1, va2;
421 unsigned int n, m, o; 421 unsigned int n, m, o;
422 target_phys_addr_t pde_ptr, pa; 422 target_phys_addr_t pde_ptr, pa;
@@ -448,5 +448,5 @@ void dump_mmu(void) @@ -448,5 +448,5 @@ void dump_mmu(void)
448 } 448 }
449 } 449 }
450 printf("MMU dump ends\n"); 450 printf("MMU dump ends\n");
451 -#endif  
452 } 451 }
  452 +#endif
target-sparc/op_helper.c
@@ -105,8 +105,11 @@ void helper_ld_asi(int asi, int size, int sign) @@ -105,8 +105,11 @@ void helper_ld_asi(int asi, int size, int sign)
105 int reg = (T0 >> 8) & 0xf; 105 int reg = (T0 >> 8) & 0xf;
106 106
107 ret = env->mmuregs[reg]; 107 ret = env->mmuregs[reg];
108 - if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/  
109 - env->mmuregs[4] = 0; 108 + if (reg == 3) /* Fault status cleared on read */
  109 + env->mmuregs[reg] = 0;
  110 +#ifdef DEBUG_MMU
  111 + printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
  112 +#endif
110 } 113 }
111 break; 114 break;
112 case 0x20 ... 0x2f: /* MMU passthrough */ 115 case 0x20 ... 0x2f: /* MMU passthrough */
@@ -131,20 +134,25 @@ void helper_st_asi(int asi, int size, int sign) @@ -131,20 +134,25 @@ void helper_st_asi(int asi, int size, int sign)
131 int mmulev; 134 int mmulev;
132 135
133 mmulev = (T0 >> 8) & 15; 136 mmulev = (T0 >> 8) & 15;
  137 +#ifdef DEBUG_MMU
  138 + printf("mmu flush level %d\n", mmulev);
  139 +#endif
134 switch (mmulev) { 140 switch (mmulev) {
135 case 0: // flush page 141 case 0: // flush page
136 - tlb_flush_page(cpu_single_env, T0 & 0xfffff000); 142 + tlb_flush_page(env, T0 & 0xfffff000);
137 break; 143 break;
138 case 1: // flush segment (256k) 144 case 1: // flush segment (256k)
139 case 2: // flush region (16M) 145 case 2: // flush region (16M)
140 case 3: // flush context (4G) 146 case 3: // flush context (4G)
141 case 4: // flush entire 147 case 4: // flush entire
142 - tlb_flush(cpu_single_env, 1); 148 + tlb_flush(env, 1);
143 break; 149 break;
144 default: 150 default:
145 break; 151 break;
146 } 152 }
  153 +#ifdef DEBUG_MMU
147 dump_mmu(); 154 dump_mmu();
  155 +#endif
148 return; 156 return;
149 } 157 }
150 case 4: /* write MMU regs */ 158 case 4: /* write MMU regs */
@@ -152,20 +160,34 @@ void helper_st_asi(int asi, int size, int sign) @@ -152,20 +160,34 @@ void helper_st_asi(int asi, int size, int sign)
152 int reg = (T0 >> 8) & 0xf, oldreg; 160 int reg = (T0 >> 8) & 0xf, oldreg;
153 161
154 oldreg = env->mmuregs[reg]; 162 oldreg = env->mmuregs[reg];
155 - if (reg == 0) { 163 + switch(reg) {
  164 + case 0:
156 env->mmuregs[reg] &= ~(MMU_E | MMU_NF); 165 env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
157 env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF); 166 env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
158 - } else 167 + if ((oldreg & MMU_E) != (env->mmuregs[reg] & MMU_E))
  168 + tlb_flush(env, 1);
  169 + break;
  170 + case 2:
159 env->mmuregs[reg] = T1; 171 env->mmuregs[reg] = T1;
160 - if (oldreg != env->mmuregs[reg]) {  
161 -#if 0  
162 - // XXX: Only if MMU mapping change, we may need to flush?  
163 - tlb_flush(cpu_single_env, 1);  
164 - cpu_loop_exit();  
165 - FORCE_RET();  
166 -#endif  
167 - } 172 + if (oldreg != env->mmuregs[reg]) {
  173 + /* we flush when the MMU context changes because
  174 + QEMU has no MMU context support */
  175 + tlb_flush(env, 1);
  176 + }
  177 + break;
  178 + case 3:
  179 + case 4:
  180 + break;
  181 + default:
  182 + env->mmuregs[reg] = T1;
  183 + break;
  184 + }
  185 +#ifdef DEBUG_MMU
  186 + if (oldreg != env->mmuregs[reg]) {
  187 + printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
  188 + }
168 dump_mmu(); 189 dump_mmu();
  190 +#endif
169 return; 191 return;
170 } 192 }
171 case 0x17: /* Block copy, sta access */ 193 case 0x17: /* Block copy, sta access */