mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-22 05:24:14 +00:00
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:
parent
06d76f319f
commit
34f9052967
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user