提交 b2fa1797 编写于 作者: P pbrook

Fix ARMv6 translation table base address calculation.

Signed-off-by: NPaul Brook <paul@codesourcery.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5514 c046a42c-6fe2-441c-8c8c-71466251a162
上级 83c1f87c
......@@ -107,7 +107,9 @@ typedef struct CPUARMState {
uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
uint32_t c2_base0; /* MMU translation table base 0. */
uint32_t c2_base1; /* MMU translation table base 1. */
uint32_t c2_mask; /* MMU translation table base mask. */
uint32_t c2_control; /* MMU translation table base control. */
uint32_t c2_mask; /* MMU translation table base selection mask. */
uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
uint32_t c2_data; /* MPU data cachable bits. */
uint32_t c2_insn; /* MPU instruction cachable bits. */
uint32_t c3; /* MMU domain access control register
......
......@@ -168,6 +168,7 @@ void cpu_reset(CPUARMState *env)
if (IS_M(env))
env->uncached_cpsr &= ~CPSR_I;
env->vfp.xregs[ARM_VFP_FPEXC] = 0;
env->cp15.c2_base_mask = 0xffffc000u;
#endif
env->regs[15] = 0;
tlb_flush(env, 1);
......@@ -910,6 +911,19 @@ static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
}
}
static uint32_t get_level1_table_address(CPUState *env, uint32_t address)
{
uint32_t table;
if (address & env->cp15.c2_mask)
table = env->cp15.c2_base1 & 0xffffc000;
else
table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
table |= (address >> 18) & 0x3ffc;
return table;
}
static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
int is_user, uint32_t *phys_ptr, int *prot)
{
......@@ -923,11 +937,7 @@ static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
/* Pagetable walk. */
/* Lookup l1 descriptor. */
if (address & env->cp15.c2_mask)
table = env->cp15.c2_base1;
else
table = env->cp15.c2_base0;
table = (table & 0xffffc000) | ((address >> 18) & 0x3ffc);
table = get_level1_table_address(env, address);
desc = ldl_phys(table);
type = (desc & 3);
domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
......@@ -1015,11 +1025,7 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
/* Pagetable walk. */
/* Lookup l1 descriptor. */
if (address & env->cp15.c2_mask)
table = env->cp15.c2_base1;
else
table = env->cp15.c2_base0;
table = (table & 0xffffc000) | ((address >> 18) & 0x3ffc);
table = get_level1_table_address(env, address);
desc = ldl_phys(table);
type = (desc & 3);
if (type == 0) {
......@@ -1365,7 +1371,10 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
env->cp15.c2_base1 = val;
break;
case 2:
val &= 7;
env->cp15.c2_control = val;
env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val);
break;
default:
goto bad_reg;
......@@ -1683,17 +1692,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
case 1:
return env->cp15.c2_base1;
case 2:
{
int n;
uint32_t mask;
n = 0;
mask = env->cp15.c2_mask;
while (mask) {
n++;
mask <<= 1;
}
return n;
}
return env->cp15.c2_control;
default:
goto bad_reg;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册