From: Tobias Röhmel <quic_troh...@quicinc.com> Signed-off-by: Tobias Röhmel <quic_troh...@quicinc.com> --- target/arm/cpu.h | 10 +++ target/arm/helper.c | 171 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 86e06116a9..632d0d13c6 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -726,8 +726,18 @@ typedef struct CPUArchState { */ uint32_t *rbar[M_REG_NUM_BANKS]; uint32_t *rlar[M_REG_NUM_BANKS]; + uint32_t prbarn[255]; + uint32_t prlarn[255]; + uint32_t hprbarn[255]; + uint32_t hprlarn[255]; uint32_t mair0[M_REG_NUM_BANKS]; uint32_t mair1[M_REG_NUM_BANKS]; + uint32_t prbar; + uint32_t prlar; + uint32_t prselr; + uint32_t hprbar; + uint32_t hprlar; + uint32_t hprselr; } pmsav8; /* v8M SAU */ diff --git a/target/arm/helper.c b/target/arm/helper.c index bdf1df37d5..adbf282d00 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -7422,6 +7422,78 @@ static CPAccessResult access_joscr_jmcr(CPUARMState *env, return CP_ACCESS_OK; } +static void prbar_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->pmsav8.prbarn[env->pmsav8.prselr] = value; +} + +static void prlar_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->pmsav8.prlarn[env->pmsav8.prselr] = value; +} + +static uint64_t prbar_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return env->pmsav8.prbarn[env->pmsav8.prselr]; +} + +static uint64_t prlar_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return env->pmsav8.prlarn[env->pmsav8.prselr]; +} + +static void hprbar_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->pmsav8.hprbarn[env->pmsav8.hprselr] = value; +} + +static void hprlar_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->pmsav8.hprlarn[env->pmsav8.hprselr] = value; +} + +static void hprenr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + uint32_t n; + ARMCPU *cpu = env_archcpu(env); + for (n = 0; n < (int)cpu->pmsav7_dregion; ++n) { + if (value & (1 << n)) { + env->pmsav8.hprlarn[n] |= 0x1; + } else { + env->pmsav8.hprlarn[n] &= (~0x1); + } + } +} + +static uint64_t hprbar_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return env->pmsav8.hprbarn[env->pmsav8.hprselr]; +} + +static uint64_t hprlar_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return env->pmsav8.hprlarn[env->pmsav8.hprselr]; +} + +static uint64_t hprenr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + uint32_t n; + uint32_t result = 0x0; + ARMCPU *cpu = env_archcpu(env); + + for (n = 0; n < (int)cpu->pmsav7_dregion; ++n) { + if (env->pmsav8.hprlarn[n] & 0x1) { + result |= (0x1 << n); + } + } + return result; +} + static const ARMCPRegInfo jazelle_regs[] = { { .name = "JIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0, @@ -8242,6 +8314,46 @@ void register_cp_regs_for_features(ARMCPU *cpu) .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->pmsav7_dregion << 8 }; + /* PMSAv8-R registers*/ + ARMCPRegInfo id_pmsav8_r_reginfo[] = { + { .name = "HMPUIR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 4, .opc2 = 4, + .access = PL2_R, .type = ARM_CP_CONST, + .resetvalue = cpu->pmsav7_dregion}, + /* PMSAv8-R registers */ + { .name = "PRBAR", + .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .readfn = prbar_read, .writefn = prbar_write, + .fieldoffset = offsetof(CPUARMState, pmsav8.prbar)}, + { .name = "PRLAR", + .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 1, + .access = PL1_RW, .resetvalue = 0, + .readfn = prlar_read, .writefn = prlar_write, + .fieldoffset = offsetof(CPUARMState, pmsav8.prlar)}, + { .name = "PRSELR", .resetvalue = 0, + .cp = 15, .opc1 = 0, .crn = 6, .crm = 2, .opc2 = 1, + .access = PL1_RW, .accessfn = access_tvm_trvm, + .fieldoffset = offsetof(CPUARMState, pmsav8.prselr)}, + { .name = "HPRBAR", .resetvalue = 0, + .readfn = hprbar_read, .writefn = hprbar_write, + .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 0, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, pmsav8.hprbar)}, + { .name = "HPRLAR", + .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 1, + .access = PL2_RW, .resetvalue = 0, + .readfn = hprlar_read, .writefn = hprlar_write, + .fieldoffset = offsetof(CPUARMState, pmsav8.hprlar)}, + { .name = "HPRSELR", .resetvalue = 0, + .cp = 15, .opc1 = 4, .crn = 6, .crm = 2, .opc2 = 1, + .access = PL2_RW, .accessfn = access_tvm_trvm, + .fieldoffset = offsetof(CPUARMState, pmsav8.hprselr)}, + { .name = "HPRENR", + .cp = 15, .opc1 = 4, .crn = 6, .crm = 1, .opc2 = 1, + .access = PL2_RW, .resetvalue = 0, + .readfn = hprenr_read, .writefn = hprenr_write}, + }; static const ARMCPRegInfo crn0_wi_reginfo = { .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, @@ -8283,6 +8395,65 @@ void register_cp_regs_for_features(ARMCPU *cpu) define_arm_cp_regs(cpu, id_cp_reginfo); if (!arm_feature(env, ARM_FEATURE_PMSA)) { define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo); + } else if (arm_feature(env, ARM_FEATURE_V8_R)) { + uint32_t i = 0; + char hprbar_string[] = "HPRBAR%u"; + char hprlar_string[] = "HPRLAR%u"; + + char prbar_string[] = "PRBAR%u"; + char prlar_string[] = "PRLAR%u"; + char tmp_string[50]; + define_one_arm_cp_reg(cpu, &id_mpuir_reginfo); + define_arm_cp_regs(cpu, id_pmsav8_r_reginfo); + for (i = 0; i < cpu->pmsav7_dregion; ++i) { + uint8_t crm = 0b1000 | ((i & 0b1110) >> 1); + uint8_t opc2 = (i & 0x1) << 2; + + sprintf(tmp_string, hprbar_string, i); + ARMCPRegInfo tmp_hprbarn_reginfo = { + .name = tmp_string, + .cp = 15, .opc1 = 4, .crn = 6, .crm = crm, .opc2 = opc2, + .access = PL2_RW, .resetvalue = 0, + .accessfn = access_tvm_trvm, + .fieldoffset = offsetof(CPUARMState, pmsav8.hprbarn) + + i * sizeof(env->pmsav8.hprbarn[0]) + }; + define_one_arm_cp_reg(cpu, &tmp_hprbarn_reginfo); + + sprintf(tmp_string, prbar_string, i); + ARMCPRegInfo tmp_prbarn_reginfo = { + .name = tmp_string, + .cp = 15, .opc1 = 0, .crn = 6, .crm = crm, .opc2 = opc2, + .access = PL1_RW, .resetvalue = 0, + .accessfn = access_tvm_trvm, + .fieldoffset = offsetof(CPUARMState, pmsav8.prbarn) + + i * sizeof(env->pmsav8.prbarn[0]) + }; + define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo); + + opc2 = (i & 0x1) << 2 | 0x1; + sprintf(tmp_string, hprlar_string, i); + ARMCPRegInfo tmp_hprlarn_reginfo = { + .name = tmp_string, + .cp = 15, .opc1 = 4, .crn = 6, .crm = crm, .opc2 = opc2, + .access = PL2_RW, .resetvalue = 0, + .accessfn = access_tvm_trvm, + .fieldoffset = offsetof(CPUARMState, pmsav8.hprlarn) + + i * sizeof(env->pmsav8.hprlarn[0]) + }; + define_one_arm_cp_reg(cpu, &tmp_hprlarn_reginfo); + + sprintf(tmp_string, prlar_string, i); + ARMCPRegInfo tmp_prlarn_reginfo = { + .name = tmp_string, + .cp = 15, .opc1 = 0, .crn = 6, .crm = crm, .opc2 = opc2, + .access = PL1_RW, .resetvalue = 0, + .accessfn = access_tvm_trvm, + .fieldoffset = offsetof(CPUARMState, pmsav8.prlarn) + + i * sizeof(env->pmsav8.prlarn[0]) + }; + define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo); + } } else if (arm_feature(env, ARM_FEATURE_V7)) { define_one_arm_cp_reg(cpu, &id_mpuir_reginfo); } -- 2.25.1