MMU fixes

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1308 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2005-02-22 19:14:33 +00:00
parent afc7df1148
commit 55754d9ef2
2 changed files with 38 additions and 16 deletions

View File

@ -414,9 +414,9 @@ target_ulong mmu_probe(target_ulong address, int mmulev)
return 0; return 0;
} }
#ifdef DEBUG_MMU
void dump_mmu(void) void dump_mmu(void)
{ {
#ifdef DEBUG_MMU
target_ulong va, va1, va2; target_ulong va, va1, va2;
unsigned int n, m, o; unsigned int n, m, o;
target_phys_addr_t pde_ptr, pa; target_phys_addr_t pde_ptr, pa;
@ -448,5 +448,5 @@ void dump_mmu(void)
} }
} }
printf("MMU dump ends\n"); printf("MMU dump ends\n");
#endif
} }
#endif

View File

@ -105,8 +105,11 @@ void helper_ld_asi(int asi, int size, int sign)
int reg = (T0 >> 8) & 0xf; int reg = (T0 >> 8) & 0xf;
ret = env->mmuregs[reg]; ret = env->mmuregs[reg];
if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/ if (reg == 3) /* Fault status cleared on read */
env->mmuregs[4] = 0; env->mmuregs[reg] = 0;
#ifdef DEBUG_MMU
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
#endif
} }
break; break;
case 0x20 ... 0x2f: /* MMU passthrough */ case 0x20 ... 0x2f: /* MMU passthrough */
@ -131,20 +134,25 @@ void helper_st_asi(int asi, int size, int sign)
int mmulev; int mmulev;
mmulev = (T0 >> 8) & 15; mmulev = (T0 >> 8) & 15;
#ifdef DEBUG_MMU
printf("mmu flush level %d\n", mmulev);
#endif
switch (mmulev) { switch (mmulev) {
case 0: // flush page case 0: // flush page
tlb_flush_page(cpu_single_env, T0 & 0xfffff000); tlb_flush_page(env, T0 & 0xfffff000);
break; break;
case 1: // flush segment (256k) case 1: // flush segment (256k)
case 2: // flush region (16M) case 2: // flush region (16M)
case 3: // flush context (4G) case 3: // flush context (4G)
case 4: // flush entire case 4: // flush entire
tlb_flush(cpu_single_env, 1); tlb_flush(env, 1);
break; break;
default: default:
break; break;
} }
#ifdef DEBUG_MMU
dump_mmu(); dump_mmu();
#endif
return; return;
} }
case 4: /* write MMU regs */ case 4: /* write MMU regs */
@ -152,20 +160,34 @@ void helper_st_asi(int asi, int size, int sign)
int reg = (T0 >> 8) & 0xf, oldreg; int reg = (T0 >> 8) & 0xf, oldreg;
oldreg = env->mmuregs[reg]; oldreg = env->mmuregs[reg];
if (reg == 0) { switch(reg) {
case 0:
env->mmuregs[reg] &= ~(MMU_E | MMU_NF); env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF); env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
} else if ((oldreg & MMU_E) != (env->mmuregs[reg] & MMU_E))
tlb_flush(env, 1);
break;
case 2:
env->mmuregs[reg] = T1; env->mmuregs[reg] = T1;
if (oldreg != env->mmuregs[reg]) { if (oldreg != env->mmuregs[reg]) {
#if 0 /* we flush when the MMU context changes because
// XXX: Only if MMU mapping change, we may need to flush? QEMU has no MMU context support */
tlb_flush(cpu_single_env, 1); tlb_flush(env, 1);
cpu_loop_exit(); }
FORCE_RET(); break;
#endif case 3:
case 4:
break;
default:
env->mmuregs[reg] = T1;
break;
}
#ifdef DEBUG_MMU
if (oldreg != env->mmuregs[reg]) {
printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
} }
dump_mmu(); dump_mmu();
#endif
return; return;
} }
case 0x17: /* Block copy, sta access */ case 0x17: /* Block copy, sta access */