Commit 55754d9ef27178cf0e13aea85062fc4c32e25f83
1 parent
afc7df11
MMU fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1308 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
38 additions
and
16 deletions
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 */ | ... | ... |