diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 20b1c27e..2dd4489c 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -277,6 +277,18 @@ static void arm_cpu_reset(CPUState *s) env->pmsav8.mair1[M_REG_S] = 0; } + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + if (cpu->sau_sregion > 0) { + memset(env->sau.rbar, 0, sizeof(*env->sau.rbar) * cpu->sau_sregion); + memset(env->sau.rlar, 0, sizeof(*env->sau.rlar) * cpu->sau_sregion); + } + env->sau.rnr = 0; + /* SAU_CTRL reset value is IMPDEF; we choose 0, which is what + * the Cortex-M33 does. + */ + env->sau.ctrl = 0; + } + set_flush_to_zero(1, &env->vfp.standard_fp_status); set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status); @@ -652,6 +664,20 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err } } + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + uint32_t nr = cpu->sau_sregion; + + if (nr > 0xff) { + error_setg(errp, "v8M SAU #regions invalid %" PRIu32, nr); + return -1; + } + + if (nr) { + env->sau.rbar = g_new0(uint32_t, nr); + env->sau.rlar = g_new0(uint32_t, nr); + } + } + if (arm_feature(env, ARM_FEATURE_EL3)) { set_feature(env, ARM_FEATURE_VBAR); } diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 2e46a049..0eebef2c 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -572,6 +572,14 @@ typedef struct CPUARMState { uint32_t mair1[M_REG_NUM_BANKS]; } pmsav8; + /* v8M SAU */ + struct { + uint32_t *rbar; + uint32_t *rlar; + uint32_t rnr; + uint32_t ctrl; + } sau; + void *nvic; const struct arm_boot_info *boot_info; @@ -661,6 +669,8 @@ typedef struct ARMCPU { bool has_mpu; /* PMSAv7 MPU number of supported regions */ uint32_t pmsav7_dregion; + /* v8M SAU number of supported regions */ + uint32_t sau_sregion; /* PSCI conduit used to invoke PSCI methods * 0 - disabled, 1 - smc, 2 - hvc