diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index ec353f7..0b19942 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -331,7 +331,32 @@ static uint64_t pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri) } } -static const ARMCPRegInfo pxa_cp_reginfo[] = { +static const ARMCPRegInfo pxa255_cp14_reginfo[] = { + /* perf register */ + { .name = "CPPMNC", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .readfn = pxa2xx_cppmnc_read, .writefn = pxa2xx_cppmnc_write }, + /* clock counter register */ + { .name = "CPCCNT", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .readfn = pxa2xx_cpccnt_read, .writefn = arm_cp_write_ignore }, + /* performance count registers */ + { .name = "CPPMN0", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CPPMN1", .cp = 14, .crn = 3, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + /* cp14 crn==6: CLKCFG */ + { .name = "CLKCFG", .cp = 14, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .readfn = pxa2xx_clkcfg_read, .writefn = pxa2xx_clkcfg_write }, + /* cp14 crn==7: PWRMODE */ + { .name = "PWRMODE", .cp = 14, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .readfn = arm_cp_read_zero, .writefn = pxa2xx_pwrmode_write }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo pxa270_cp14_reginfo[] = { /* cp14 crm==1: perf registers */ { .name = "CPPMNC", .cp = 14, .crn = 0, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_IO, @@ -365,9 +390,14 @@ static const ARMCPRegInfo pxa_cp_reginfo[] = { REGINFO_SENTINEL }; -static void pxa2xx_setup_cp14(PXA2xxState *s) +static void pxa255_setup_cp14(PXA2xxState *s) +{ + define_arm_cp_regs_with_opaque(s->cpu, pxa255_cp14_reginfo, s); +} + +static void pxa270_setup_cp14(PXA2xxState *s) { - define_arm_cp_regs_with_opaque(s->cpu, pxa_cp_reginfo, s); + define_arm_cp_regs_with_opaque(s->cpu, pxa270_cp14_reginfo, s); } #define MDCNFG 0x00 /* SDRAM Configuration register */ @@ -2141,7 +2171,7 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space, memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem); vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); - pxa2xx_setup_cp14(s); + pxa270_setup_cp14(s); s->mm_base = 0x48000000; s->mm_regs[MDMRS >> 2] = 0x00020002; @@ -2274,7 +2304,7 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size) memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem); vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); - pxa2xx_setup_cp14(s); + pxa255_setup_cp14(s); s->mm_base = 0x48000000; s->mm_regs[MDMRS >> 2] = 0x00020002; diff --git a/target-arm/helper.c b/target-arm/helper.c index 1568aa6..300dad0 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -512,6 +512,17 @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = { REGINFO_SENTINEL }; +static const ARMCPRegInfo not_v7_not_pxa255_cp_reginfo[] = { + /* We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR; + * implementing it as RAZ means the "debug architecture version" bits + * will read as a reserved value, which should cause Linux to not try + * to use the debug hardware. + */ + { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + REGINFO_SENTINEL +}; + static const ARMCPRegInfo not_v7_cp_reginfo[] = { /* Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which * is UNPREDICTABLE; we choose to NOP as most implementations do). @@ -532,13 +543,6 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = { { .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY, .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, .resetvalue = 0 }, - /* We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR; - * implementing it as RAZ means the "debug architecture version" bits - * will read as a reserved value, which should cause Linux to not try - * to use the debug hardware. - */ - { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, /* MMU TLB control. Note that the wildcarding means we cover not just * the unified TLB ops but also the dside/iside/inner-shareable variants. */ @@ -3607,7 +3611,12 @@ void register_cp_regs_for_features(ARMCPU *cpu) define_arm_cp_regs(cpu, v7_cp_reginfo); define_debug_regs(cpu); } else { - define_arm_cp_regs(cpu, not_v7_cp_reginfo); + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { + define_arm_cp_regs(cpu, not_v7_cp_reginfo); + define_arm_cp_regs(cpu, not_v7_not_pxa255_cp_reginfo); + } else { + define_arm_cp_regs(cpu, not_v7_cp_reginfo); + } } if (arm_feature(env, ARM_FEATURE_V8)) { /* AArch64 ID registers, which all have impdef reset values */