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 414 return 0;
415 415 }
416 416  
  417 +#ifdef DEBUG_MMU
417 418 void dump_mmu(void)
418 419 {
419   -#ifdef DEBUG_MMU
420 420 target_ulong va, va1, va2;
421 421 unsigned int n, m, o;
422 422 target_phys_addr_t pde_ptr, pa;
... ... @@ -448,5 +448,5 @@ void dump_mmu(void)
448 448 }
449 449 }
450 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 105 int reg = (T0 >> 8) & 0xf;
106 106  
107 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 114 break;
112 115 case 0x20 ... 0x2f: /* MMU passthrough */
... ... @@ -131,20 +134,25 @@ void helper_st_asi(int asi, int size, int sign)
131 134 int mmulev;
132 135  
133 136 mmulev = (T0 >> 8) & 15;
  137 +#ifdef DEBUG_MMU
  138 + printf("mmu flush level %d\n", mmulev);
  139 +#endif
134 140 switch (mmulev) {
135 141 case 0: // flush page
136   - tlb_flush_page(cpu_single_env, T0 & 0xfffff000);
  142 + tlb_flush_page(env, T0 & 0xfffff000);
137 143 break;
138 144 case 1: // flush segment (256k)
139 145 case 2: // flush region (16M)
140 146 case 3: // flush context (4G)
141 147 case 4: // flush entire
142   - tlb_flush(cpu_single_env, 1);
  148 + tlb_flush(env, 1);
143 149 break;
144 150 default:
145 151 break;
146 152 }
  153 +#ifdef DEBUG_MMU
147 154 dump_mmu();
  155 +#endif
148 156 return;
149 157 }
150 158 case 4: /* write MMU regs */
... ... @@ -152,20 +160,34 @@ void helper_st_asi(int asi, int size, int sign)
152 160 int reg = (T0 >> 8) & 0xf, oldreg;
153 161  
154 162 oldreg = env->mmuregs[reg];
155   - if (reg == 0) {
  163 + switch(reg) {
  164 + case 0:
156 165 env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
157 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 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 189 dump_mmu();
  190 +#endif
169 191 return;
170 192 }
171 193 case 0x17: /* Block copy, sta access */
... ...