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;
}
#ifdef DEBUG_MMU
void dump_mmu(void)
{
#ifdef DEBUG_MMU
target_ulong va, va1, va2;
unsigned int n, m, o;
target_phys_addr_t pde_ptr, pa;
@ -448,5 +448,5 @@ void dump_mmu(void)
}
}
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;
ret = env->mmuregs[reg];
if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/
env->mmuregs[4] = 0;
if (reg == 3) /* Fault status cleared on read */
env->mmuregs[reg] = 0;
#ifdef DEBUG_MMU
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
#endif
}
break;
case 0x20 ... 0x2f: /* MMU passthrough */
@ -131,20 +134,25 @@ void helper_st_asi(int asi, int size, int sign)
int mmulev;
mmulev = (T0 >> 8) & 15;
#ifdef DEBUG_MMU
printf("mmu flush level %d\n", mmulev);
#endif
switch (mmulev) {
case 0: // flush page
tlb_flush_page(cpu_single_env, T0 & 0xfffff000);
tlb_flush_page(env, T0 & 0xfffff000);
break;
case 1: // flush segment (256k)
case 2: // flush region (16M)
case 3: // flush context (4G)
case 4: // flush entire
tlb_flush(cpu_single_env, 1);
tlb_flush(env, 1);
break;
default:
break;
}
#ifdef DEBUG_MMU
dump_mmu();
#endif
return;
}
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;
oldreg = env->mmuregs[reg];
if (reg == 0) {
switch(reg) {
case 0:
env->mmuregs[reg] &= ~(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;
if (oldreg != env->mmuregs[reg]) {
#if 0
// XXX: Only if MMU mapping change, we may need to flush?
tlb_flush(cpu_single_env, 1);
cpu_loop_exit();
FORCE_RET();
#endif
}
if (oldreg != env->mmuregs[reg]) {
/* we flush when the MMU context changes because
QEMU has no MMU context support */
tlb_flush(env, 1);
}
break;
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();
#endif
return;
}
case 0x17: /* Block copy, sta access */