mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-24 13:05:37 +00:00
target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M
Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security extensions are enabled. We can freely add more items to vmstate_m_security without breaking migration compatibility, because no CPU currently has the ARM_FEATURE_M_SECURITY bit enabled and so this subsection is not yet used by anything. Backports commit 62c58ee0b24eafb44c06402fe059fbd7972eb409 from qemu
This commit is contained in:
parent
5b6e1e2150
commit
5e14b33c65
|
@ -234,10 +234,20 @@ static void arm_cpu_reset(CPUState *s)
|
||||||
if (arm_feature(env, ARM_FEATURE_PMSA)) {
|
if (arm_feature(env, ARM_FEATURE_PMSA)) {
|
||||||
if (cpu->pmsav7_dregion > 0) {
|
if (cpu->pmsav7_dregion > 0) {
|
||||||
if (arm_feature(env, ARM_FEATURE_V8)) {
|
if (arm_feature(env, ARM_FEATURE_V8)) {
|
||||||
memset(env->pmsav8.rbar, 0,
|
memset(env->pmsav8.rbar[M_REG_NS], 0,
|
||||||
sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion);
|
sizeof(*env->pmsav8.rbar[M_REG_NS])
|
||||||
memset(env->pmsav8.rlar, 0,
|
* cpu->pmsav7_dregion);
|
||||||
sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion);
|
memset(env->pmsav8.rlar[M_REG_NS], 0,
|
||||||
|
sizeof(*env->pmsav8.rlar[M_REG_NS])
|
||||||
|
* cpu->pmsav7_dregion);
|
||||||
|
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
|
||||||
|
memset(env->pmsav8.rbar[M_REG_S], 0,
|
||||||
|
sizeof(*env->pmsav8.rbar[M_REG_S])
|
||||||
|
* cpu->pmsav7_dregion);
|
||||||
|
memset(env->pmsav8.rlar[M_REG_S], 0,
|
||||||
|
sizeof(*env->pmsav8.rlar[M_REG_S])
|
||||||
|
* cpu->pmsav7_dregion);
|
||||||
|
}
|
||||||
} else if (arm_feature(env, ARM_FEATURE_V7)) {
|
} else if (arm_feature(env, ARM_FEATURE_V7)) {
|
||||||
memset(env->pmsav7.drbar, 0,
|
memset(env->pmsav7.drbar, 0,
|
||||||
sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
|
sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
|
||||||
|
@ -615,8 +625,12 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
|
||||||
if (nr) {
|
if (nr) {
|
||||||
if (arm_feature(env, ARM_FEATURE_V8)) {
|
if (arm_feature(env, ARM_FEATURE_V8)) {
|
||||||
/* PMSAv8 */
|
/* PMSAv8 */
|
||||||
env->pmsav8.rbar = g_new0(uint32_t, nr);
|
env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr);
|
||||||
env->pmsav8.rlar = g_new0(uint32_t, nr);
|
env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr);
|
||||||
|
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
|
||||||
|
env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr);
|
||||||
|
env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
env->pmsav7.drbar = g_new0(uint32_t, nr);
|
env->pmsav7.drbar = g_new0(uint32_t, nr);
|
||||||
env->pmsav7.drsr = g_new0(uint32_t, nr);
|
env->pmsav7.drsr = g_new0(uint32_t, nr);
|
||||||
|
|
|
@ -548,8 +548,8 @@ typedef struct CPUARMState {
|
||||||
* pmsav7.rnr (region number register)
|
* pmsav7.rnr (region number register)
|
||||||
* pmsav7_dregion (number of configured regions)
|
* pmsav7_dregion (number of configured regions)
|
||||||
*/
|
*/
|
||||||
uint32_t *rbar;
|
uint32_t *rbar[2];
|
||||||
uint32_t *rlar;
|
uint32_t *rlar[2];
|
||||||
uint32_t mair0[2];
|
uint32_t mair0[2];
|
||||||
uint32_t mair1[2];
|
uint32_t mair1[2];
|
||||||
} pmsav8;
|
} pmsav8;
|
||||||
|
|
|
@ -7707,6 +7707,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
|
||||||
{
|
{
|
||||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||||
bool is_user = regime_is_user(env, mmu_idx);
|
bool is_user = regime_is_user(env, mmu_idx);
|
||||||
|
uint32_t secure = regime_is_secure(env, mmu_idx);
|
||||||
int n;
|
int n;
|
||||||
int matchregion = -1;
|
int matchregion = -1;
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
@ -7733,10 +7734,10 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
|
||||||
* with bits [4:0] all zeroes, but the limit address is bits
|
* with bits [4:0] all zeroes, but the limit address is bits
|
||||||
* [31:5] from the register with bits [4:0] all ones.
|
* [31:5] from the register with bits [4:0] all ones.
|
||||||
*/
|
*/
|
||||||
uint32_t base = env->pmsav8.rbar[n] & ~0x1f;
|
uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
|
||||||
uint32_t limit = env->pmsav8.rlar[n] | 0x1f;
|
uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
|
||||||
|
|
||||||
if (!(env->pmsav8.rlar[n] & 0x1)) {
|
if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
|
||||||
/* Region disabled */
|
/* Region disabled */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -7785,8 +7786,8 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
|
||||||
/* hit using the background region */
|
/* hit using the background region */
|
||||||
get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
|
get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
|
||||||
} else {
|
} else {
|
||||||
uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2);
|
uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
|
||||||
uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1);
|
uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
|
||||||
|
|
||||||
if (m_is_system_region(env, address)) {
|
if (m_is_system_region(env, address)) {
|
||||||
/* System space is always execute never */
|
/* System space is always execute never */
|
||||||
|
|
Loading…
Reference in a new issue