mirror of
https://github.com/qemu/qemu.git
synced 2024-11-29 06:43:37 +08:00
MMU fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1308 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
afc7df1148
commit
55754d9ef2
@ -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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user