[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v5 5/7] target/arm: Add PMSAv8r registers
From: |
Peter Maydell |
Subject: |
Re: [PATCH v5 5/7] target/arm: Add PMSAv8r registers |
Date: |
Mon, 5 Dec 2022 17:07:09 +0000 |
On Sun, 27 Nov 2022 at 13:21, <tobias.roehmel@rwth-aachen.de> wrote:
>
> From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
>
> Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Only some minor fixes needed in this one.
> ---
> target/arm/cpu.c | 24 +++-
> target/arm/cpu.h | 6 +
> target/arm/helper.c | 299 +++++++++++++++++++++++++++++++++++++++++++
> target/arm/machine.c | 28 ++++
> 4 files changed, 356 insertions(+), 1 deletion(-)
> @@ -2001,8 +2009,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error
> **errp)
> */
> if (!cpu->has_mpu) {
> cpu->pmsav7_dregion = 0;
> + cpu->pmsav8r_hdregion = 0;
> }
> - if (cpu->pmsav7_dregion == 0) {
> + if ((cpu->pmsav7_dregion == 0) && (cpu->pmsav8r_hdregion == 0)) {
> cpu->has_mpu = false;
> }
This leaves the door open for a CPU with 0 dregions but some hdregions.
That I think doesn't make sense, so we should just disallow it.
We can do that by combining these two if()s into one:
if (!cpu->has_mpu || cpu->pmsav7_dregion == 0) {
cpu->has_mpu = false;
cpu->pmsav7_dregion = 0;
cpu->pmsav8r_hdregion = 0;
}
> @@ -2030,6 +2039,19 @@ static void arm_cpu_realizefn(DeviceState *dev, Error
> **errp)
> env->pmsav7.dracr = g_new0(uint32_t, nr);
> }
> }
> +
> + if (cpu->pmsav8r_hdregion > 0xFF) {
Lowercase for hex digits, please (matches the check on pmsav7_dregion).
> + error_setg(errp, "PMSAv8 MPU EL2 #regions invalid %" PRIu32,
> + cpu->pmsav8r_hdregion);
> + return;
> + }
> +
> + if (cpu->pmsav8r_hdregion) {
> + env->pmsav8.hprbar = g_new0(uint32_t,
> + cpu->pmsav8r_hdregion);
> + env->pmsav8.hprlar = g_new0(uint32_t,
> + cpu->pmsav8r_hdregion);
> + }
> }
>
> if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
> +static const ARMCPRegInfo pmsav8r_cp_reginfo[] = {
> + { .name = "PRBAR",
> + .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 0,
> + .access = PL1_RW, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
> + .accessfn = access_tvm_trvm,
> + .readfn = prbar_read, .writefn = prbar_write },
> + { .name = "PRLAR",
> + .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 1,
> + .access = PL1_RW, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
> + .accessfn = access_tvm_trvm,
> + .readfn = prlar_read, .writefn = prlar_write },
> + { .name = "PRSELR", .resetvalue = 0,
> + .cp = 15, .opc1 = 0, .crn = 6, .crm = 2, .opc2 = 1,
> + .access = PL1_RW, .accessfn = access_tvm_trvm,
> + .writefn = prselr_write,
> + .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]) },
> + { .name = "HPRBAR", .resetvalue = 0,
> + .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 0,
> + .access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
> + .readfn = hprbar_read, .writefn = hprbar_write },
> + { .name = "HPRLAR",
> + .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 1,
> + .access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
> + .readfn = hprlar_read, .writefn = hprlar_write },
These 4 registers should be just ARM_CP_NO_RAW, not
ARM_CP_ALIAS | ARM_CP_NO_RAW.
> + { .name = "HPRSELR", .resetvalue = 0,
> + .cp = 15, .opc1 = 4, .crn = 6, .crm = 2, .opc2 = 1,
> + .access = PL2_RW,
> + .writefn = hprselr_write,
> + .fieldoffset = offsetof(CPUARMState, pmsav8.hprselr) },
> + { .name = "HPRENR",
> + .cp = 15, .opc1 = 4, .crn = 6, .crm = 1, .opc2 = 1,
> + .access = PL2_RW, .type = ARM_CP_ALIAS,
> + .readfn = hprenr_read, .writefn = hprenr_write },
> +};
> +
> static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
> /* Reset for all these registers is handled in arm_cpu_reset(),
> * because the PMSAv7 is also used by M-profile CPUs, which do
> @@ -8166,6 +8382,13 @@ void register_cp_regs_for_features(ARMCPU *cpu)
> .access = PL1_R, .type = ARM_CP_CONST,
> .resetvalue = cpu->pmsav7_dregion << 8
> };
> + /* HMPUIR is specific to PMSA V8 */
> + ARMCPRegInfo id_hmpuir_reginfo = {
> + .name = "HMPUIR",
> + .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 4,
> + .access = PL2_R, .type = ARM_CP_CONST,
> + .resetvalue = cpu->pmsav8r_hdregion
> + };
> 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,
> @@ -8208,6 +8431,71 @@ 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_PMSA) &&
> + arm_feature(env, ARM_FEATURE_V8)) {
> + uint32_t i = 0;
> + g_autofree char *tmp_string_pr;
> + g_autofree char *tmp_string_hpr;
> +
> + define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
> + define_one_arm_cp_reg(cpu, &id_hmpuir_reginfo);
> + define_arm_cp_regs(cpu, pmsav8r_cp_reginfo);
> +
> + /* Register alias is only valid for first 32 indexes */
> + for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) {
> + uint8_t crm = 0b1000 | extract32(i, 1, 3);
> + uint8_t opc1 = extract32(i, 4, 1);
> + uint8_t opc2 = extract32(i, 0, 1) << 2;
> +
> + tmp_string_pr = g_strdup_printf("PRBAR%u", i);
> + ARMCPRegInfo tmp_prbarn_reginfo = {
> + .name = tmp_string_pr, .type = ARM_CP_ALIAS |
> ARM_CP_NO_RAW,
All these registers hould be just ARM_CP_NO_RAW, not
ARM_CP_ALIAS | ARM_CP_NO_RAW.
> + .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 =
> opc2,
> + .access = PL1_RW, .resetvalue = 0,
> + .accessfn = access_tvm_trvm,
> + .writefn = pmsav8r_regn_write, .readfn =
> pmsav8r_regn_read
> + };
> + define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
This is still leaking the name strings. If you don't want to
use g_autofree then you must free the strings yourself.
> +
> + opc2 = extract32(i, 0, 1) << 2 | 0x1;
> + tmp_string_pr = g_strdup_printf("PRLAR%u", i);
> + ARMCPRegInfo tmp_prlarn_reginfo = {
> + .name = tmp_string_pr, .type = ARM_CP_ALIAS |
> ARM_CP_NO_RAW,
> + .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 =
> opc2,
> + .access = PL1_RW, .resetvalue = 0,
> + .accessfn = access_tvm_trvm,
> + .writefn = pmsav8r_regn_write, .readfn =
> pmsav8r_regn_read
> + };
> + define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
> + }
> +
> + /* Register alias is only valid for first 32 indexes */
> + for (i = 0; i < MIN(cpu->pmsav8r_hdregion, 32); ++i) {
> + uint8_t crm = 0b1000 | extract32(i, 1, 3);
> + uint8_t opc1 = 0b100 | extract32(i, 4, 1);
> + uint8_t opc2 = extract32(i, 0, 1) << 2;
> +
> + tmp_string_hpr = g_strdup_printf("HPRBAR%u", i);
> + ARMCPRegInfo tmp_hprbarn_reginfo = {
> + .name = tmp_string_hpr,
> + .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
> + .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 =
> opc2,
> + .access = PL2_RW, .resetvalue = 0,
> + .writefn = pmsav8r_regn_write, .readfn =
> pmsav8r_regn_read
> + };
> + define_one_arm_cp_reg(cpu, &tmp_hprbarn_reginfo);
> +
> + opc2 = extract32(i, 0, 1) << 2 | 0x1;
> + tmp_string_hpr = g_strdup_printf("HPRLAR%u", i);
> + ARMCPRegInfo tmp_hprlarn_reginfo = {
> + .name = tmp_string_hpr,
> + .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
> + .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 =
> opc2,
> + .access = PL2_RW, .resetvalue = 0,
> + .writefn = pmsav8r_regn_write, .readfn =
> pmsav8r_regn_read
> + };
> + define_one_arm_cp_reg(cpu, &tmp_hprlarn_reginfo);
> + }
> } else if (arm_feature(env, ARM_FEATURE_V7)) {
> define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
> }
thanks
-- PMM
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [PATCH v5 5/7] target/arm: Add PMSAv8r registers,
Peter Maydell <=