@@ -9,7 +9,6 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/log.h"
-#include "target/arm/idau.h"
#include "trace.h"
#include "cpu.h"
#include "internals.h"
@@ -11693,128 +11692,6 @@ bool m_is_system_region(CPUARMState *env, uint32_t address)
return arm_feature(env, ARM_FEATURE_M) && extract32(address, 29, 3) == 0x7;
}
-static bool v8m_is_sau_exempt(CPUARMState *env,
- uint32_t address, MMUAccessType access_type)
-{
- /* The architecture specifies that certain address ranges are
- * exempt from v8M SAU/IDAU checks.
- */
- return
- (access_type == MMU_INST_FETCH && m_is_system_region(env, address)) ||
- (address >= 0xe0000000 && address <= 0xe0002fff) ||
- (address >= 0xe000e000 && address <= 0xe000efff) ||
- (address >= 0xe002e000 && address <= 0xe002efff) ||
- (address >= 0xe0040000 && address <= 0xe0041fff) ||
- (address >= 0xe00ff000 && address <= 0xe00fffff);
-}
-
-void v8m_security_lookup(CPUARMState *env, uint32_t address,
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
- V8M_SAttributes *sattrs)
-{
- /* Look up the security attributes for this address. Compare the
- * pseudocode SecurityCheck() function.
- * We assume the caller has zero-initialized *sattrs.
- */
- ARMCPU *cpu = env_archcpu(env);
- int r;
- bool idau_exempt = false, idau_ns = true, idau_nsc = true;
- int idau_region = IREGION_NOTVALID;
- uint32_t addr_page_base = address & TARGET_PAGE_MASK;
- uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
-
- if (cpu->idau) {
- IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau);
- IDAUInterface *ii = IDAU_INTERFACE(cpu->idau);
-
- iic->check(ii, address, &idau_region, &idau_exempt, &idau_ns,
- &idau_nsc);
- }
-
- if (access_type == MMU_INST_FETCH && extract32(address, 28, 4) == 0xf) {
- /* 0xf0000000..0xffffffff is always S for insn fetches */
- return;
- }
-
- if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) {
- sattrs->ns = !regime_is_secure(env, mmu_idx);
- return;
- }
-
- if (idau_region != IREGION_NOTVALID) {
- sattrs->irvalid = true;
- sattrs->iregion = idau_region;
- }
-
- switch (env->sau.ctrl & 3) {
- case 0: /* SAU.ENABLE == 0, SAU.ALLNS == 0 */
- break;
- case 2: /* SAU.ENABLE == 0, SAU.ALLNS == 1 */
- sattrs->ns = true;
- break;
- default: /* SAU.ENABLE == 1 */
- for (r = 0; r < cpu->sau_sregion; r++) {
- if (env->sau.rlar[r] & 1) {
- uint32_t base = env->sau.rbar[r] & ~0x1f;
- uint32_t limit = env->sau.rlar[r] | 0x1f;
-
- if (base <= address && limit >= address) {
- if (base > addr_page_base || limit < addr_page_limit) {
- sattrs->subpage = true;
- }
- if (sattrs->srvalid) {
- /* If we hit in more than one region then we must report
- * as Secure, not NS-Callable, with no valid region
- * number info.
- */
- sattrs->ns = false;
- sattrs->nsc = false;
- sattrs->sregion = 0;
- sattrs->srvalid = false;
- break;
- } else {
- if (env->sau.rlar[r] & 2) {
- sattrs->nsc = true;
- } else {
- sattrs->ns = true;
- }
- sattrs->srvalid = true;
- sattrs->sregion = r;
- }
- } else {
- /*
- * Address not in this region. We must check whether the
- * region covers addresses in the same page as our address.
- * In that case we must not report a size that covers the
- * whole page for a subsequent hit against a different MPU
- * region or the background region, because it would result
- * in incorrect TLB hits for subsequent accesses to
- * addresses that are in this MPU region.
- */
- if (limit >= base &&
- ranges_overlap(base, limit - base + 1,
- addr_page_base,
- TARGET_PAGE_SIZE)) {
- sattrs->subpage = true;
- }
- }
- }
- }
- break;
- }
-
- /*
- * The IDAU will override the SAU lookup results if it specifies
- * higher security than the SAU does.
- */
- if (!idau_ns) {
- if (sattrs->ns || (!idau_nsc && sattrs->nsc)) {
- sattrs->ns = false;
- sattrs->nsc = idau_nsc;
- }
- }
-}
-
/* Combine either inner or outer cacheability attributes for normal
* memory, according to table D4-42 and pseudocode procedure
* CombineS1S2AttrHints() of ARM DDI 0487B.b (the ARMv8 ARM).
@@ -11,6 +11,7 @@
#include "qemu/range.h"
#include "cpu.h"
#include "internals.h"
+#include "idau.h"
#include "ptw.h"
@@ -766,6 +767,131 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
return !(*prot & (1 << access_type));
}
+static bool v8m_is_sau_exempt(CPUARMState *env,
+ uint32_t address, MMUAccessType access_type)
+{
+ /*
+ * The architecture specifies that certain address ranges are
+ * exempt from v8M SAU/IDAU checks.
+ */
+ return
+ (access_type == MMU_INST_FETCH && m_is_system_region(env, address)) ||
+ (address >= 0xe0000000 && address <= 0xe0002fff) ||
+ (address >= 0xe000e000 && address <= 0xe000efff) ||
+ (address >= 0xe002e000 && address <= 0xe002efff) ||
+ (address >= 0xe0040000 && address <= 0xe0041fff) ||
+ (address >= 0xe00ff000 && address <= 0xe00fffff);
+}
+
+void v8m_security_lookup(CPUARMState *env, uint32_t address,
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
+ V8M_SAttributes *sattrs)
+{
+ /*
+ * Look up the security attributes for this address. Compare the
+ * pseudocode SecurityCheck() function.
+ * We assume the caller has zero-initialized *sattrs.
+ */
+ ARMCPU *cpu = env_archcpu(env);
+ int r;
+ bool idau_exempt = false, idau_ns = true, idau_nsc = true;
+ int idau_region = IREGION_NOTVALID;
+ uint32_t addr_page_base = address & TARGET_PAGE_MASK;
+ uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
+
+ if (cpu->idau) {
+ IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau);
+ IDAUInterface *ii = IDAU_INTERFACE(cpu->idau);
+
+ iic->check(ii, address, &idau_region, &idau_exempt, &idau_ns,
+ &idau_nsc);
+ }
+
+ if (access_type == MMU_INST_FETCH && extract32(address, 28, 4) == 0xf) {
+ /* 0xf0000000..0xffffffff is always S for insn fetches */
+ return;
+ }
+
+ if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) {
+ sattrs->ns = !regime_is_secure(env, mmu_idx);
+ return;
+ }
+
+ if (idau_region != IREGION_NOTVALID) {
+ sattrs->irvalid = true;
+ sattrs->iregion = idau_region;
+ }
+
+ switch (env->sau.ctrl & 3) {
+ case 0: /* SAU.ENABLE == 0, SAU.ALLNS == 0 */
+ break;
+ case 2: /* SAU.ENABLE == 0, SAU.ALLNS == 1 */
+ sattrs->ns = true;
+ break;
+ default: /* SAU.ENABLE == 1 */
+ for (r = 0; r < cpu->sau_sregion; r++) {
+ if (env->sau.rlar[r] & 1) {
+ uint32_t base = env->sau.rbar[r] & ~0x1f;
+ uint32_t limit = env->sau.rlar[r] | 0x1f;
+
+ if (base <= address && limit >= address) {
+ if (base > addr_page_base || limit < addr_page_limit) {
+ sattrs->subpage = true;
+ }
+ if (sattrs->srvalid) {
+ /*
+ * If we hit in more than one region then we must report
+ * as Secure, not NS-Callable, with no valid region
+ * number info.
+ */
+ sattrs->ns = false;
+ sattrs->nsc = false;
+ sattrs->sregion = 0;
+ sattrs->srvalid = false;
+ break;
+ } else {
+ if (env->sau.rlar[r] & 2) {
+ sattrs->nsc = true;
+ } else {
+ sattrs->ns = true;
+ }
+ sattrs->srvalid = true;
+ sattrs->sregion = r;
+ }
+ } else {
+ /*
+ * Address not in this region. We must check whether the
+ * region covers addresses in the same page as our address.
+ * In that case we must not report a size that covers the
+ * whole page for a subsequent hit against a different MPU
+ * region or the background region, because it would result
+ * in incorrect TLB hits for subsequent accesses to
+ * addresses that are in this MPU region.
+ */
+ if (limit >= base &&
+ ranges_overlap(base, limit - base + 1,
+ addr_page_base,
+ TARGET_PAGE_SIZE)) {
+ sattrs->subpage = true;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ /*
+ * The IDAU will override the SAU lookup results if it specifies
+ * higher security than the SAU does.
+ */
+ if (!idau_ns) {
+ if (sattrs->ns || (!idau_nsc && sattrs->nsc)) {
+ sattrs->ns = false;
+ sattrs->nsc = idau_nsc;
+ }
+ }
+}
+
static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
hwaddr *phys_ptr, MemTxAttrs *txattrs,