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,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 */ |