target-arm: Convert cp15 crn=9 registers

Convert cp15 crn=9 registers (mostly cache lockdown) to the new scheme.

Note that this change makes OMAPCP cores RAZ/WI the whole c9 space.  This is
a change from previous behaviour, but a return to the behaviour of commit
c3d2689d when OMAP1 support was first added -- subsequent commits have
clearly accidentally relegated the OMAPCP RAZ condition to only a subset of
the crn=9 space when adding support for other cores.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2012-06-20 11:57:18 +00:00
parent 06d76f319f
commit 34f9052967
2 changed files with 59 additions and 79 deletions

View File

@ -23,6 +23,7 @@
#if !defined(CONFIG_USER_ONLY)
#include "hw/loader.h"
#endif
#include "sysemu.h"
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
{
@ -390,6 +391,14 @@ static void cortex_m3_initfn(Object *obj)
cpu->midr = ARM_CPUID_CORTEXM3;
}
static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
{ .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
static void cortex_a8_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@ -421,6 +430,7 @@ static void cortex_a8_initfn(Object *obj)
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */
define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
}
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
@ -498,6 +508,29 @@ static void cortex_a9_initfn(Object *obj)
}
}
#ifndef CONFIG_USER_ONLY
static int a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t *value)
{
/* Linux wants the number of processors from here.
* Might as well set the interrupt-controller bit too.
*/
*value = ((smp_cpus - 1) << 24) | (1 << 23);
return 0;
}
#endif
static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
#ifndef CONFIG_USER_ONLY
{ .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
.access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read,
.writefn = arm_cp_write_ignore, },
#endif
{ .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
static void cortex_a15_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@ -533,6 +566,7 @@ static void cortex_a15_initfn(Object *obj)
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
}
static void ti925t_initfn(Object *obj)

View File

@ -183,6 +183,16 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
*/
{ .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
.access = PL1_W, .type = ARM_CP_WFI },
/* L1 cache lockdown. Not architectural in v6 and earlier but in practice
* implemented in 926, 946, 1026, 1136, 1176 and 11MPCore. StrongARM and
* OMAPCP will override this space.
*/
{ .name = "DLOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_data),
.resetvalue = 0 },
{ .name = "ILOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 1,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_insn),
.resetvalue = 0 },
REGINFO_SENTINEL
};
@ -703,6 +713,9 @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
{ .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
.opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, .type = ARM_CP_OVERRIDE,
.writefn = omap_cachemaint_write },
{ .name = "C9", .cp = 15, .crn = 9,
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
.type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
REGINFO_SENTINEL
};
@ -763,6 +776,15 @@ static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
REGINFO_SENTINEL
};
static const ARMCPRegInfo strongarm_cp_reginfo[] = {
/* Ignore ReadBuffer accesses */
{ .name = "C9_READBUFFER", .cp = 15, .crn = 9,
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
.access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
.resetvalue = 0 },
REGINFO_SENTINEL
};
void register_cp_regs_for_features(ARMCPU *cpu)
{
/* Register all the coprocessor registers based on feature bits */
@ -828,6 +850,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
define_arm_cp_regs(cpu, omap_cp_reginfo);
}
if (arm_feature(env, ARM_FEATURE_STRONGARM)) {
define_arm_cp_regs(cpu, strongarm_cp_reginfo);
}
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
define_arm_cp_regs(cpu, xscale_cp_reginfo);
}
@ -1962,40 +1987,6 @@ void HELPER(set_cp15)(CPUARMState *env, uint32_t insn, uint32_t val)
break;
case 4: /* Reserved. */
goto bad_reg;
case 9:
if (arm_feature(env, ARM_FEATURE_OMAPCP))
break;
if (arm_feature(env, ARM_FEATURE_STRONGARM))
break; /* Ignore ReadBuffer access */
switch (crm) {
case 0: /* Cache lockdown. */
switch (op1) {
case 0: /* L1 cache. */
switch (op2) {
case 0:
env->cp15.c9_data = val;
break;
case 1:
env->cp15.c9_insn = val;
break;
default:
goto bad_reg;
}
break;
case 1: /* L2 cache. */
/* Ignore writes to L2 lockdown/auxiliary registers. */
break;
default:
goto bad_reg;
}
break;
case 1: /* TCM memory region registers. */
/* Not implemented. */
goto bad_reg;
default:
goto bad_reg;
}
break;
case 12: /* Reserved. */
goto bad_reg;
}
@ -2135,51 +2126,6 @@ uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
}
case 4: /* Reserved. */
goto bad_reg;
case 9:
switch (crm) {
case 0: /* Cache lockdown */
switch (op1) {
case 0: /* L1 cache. */
if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
return 0;
}
switch (op2) {
case 0:
return env->cp15.c9_data;
case 1:
return env->cp15.c9_insn;
default:
goto bad_reg;
}
case 1: /* L2 cache */
/* L2 Lockdown and Auxiliary control. */
switch (op2) {
case 0:
/* L2 cache lockdown (A8 only) */
return 0;
case 2:
/* L2 cache auxiliary control (A8) or control (A15) */
if (ARM_CPUID(env) == ARM_CPUID_CORTEXA15) {
/* Linux wants the number of processors from here.
* Might as well set the interrupt-controller bit too.
*/
return ((smp_cpus - 1) << 24) | (1 << 23);
}
return 0;
case 3:
/* L2 cache extended control (A15) */
return 0;
default:
goto bad_reg;
}
default:
goto bad_reg;
}
break;
default:
goto bad_reg;
}
break;
case 11: /* TCM DMA control. */
case 12: /* Reserved. */
goto bad_reg;