Lines Matching +full:arm +full:- +full:softmmu

2  * ARM page table walking.
6 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "qemu/main-loop.h"
13 #include "exec/exec-all.h"
14 #include "exec/page-protection.h"
17 #include "cpu-features.h"
20 # include "tcg/oversized-guest.h"
46 * - if the in_ptw_idx is an ARMMMUIdx_Phys_* then the mmuidx
48 * - if the in_ptw_idx is an ARMMMUIdx_Stage2* then the security
59 * and will not change the state of the softmmu TLBs.
105 for (int i = ARRAY_SIZE(pamax_map) - 1; i >= 0; i--) { in round_down_to_parange_index()
119 * The cpu-specific constant value of PAMax; also used by hw/arm/virt.
124 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { in arm_pamax()
126 FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); in arm_pamax()
129 * id_aa64mmfr0 is a read-only register so values outside of the in arm_pamax()
136 if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) { in arm_pamax()
197 s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW); in ptw_idx_for_stage_2()
199 s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW); in ptw_idx_for_stage_2()
216 return env->cp15.vttbr_el2; in regime_ttbr()
219 return env->cp15.vsttbr_el2; in regime_ttbr()
222 return env->cp15.ttbr0_el[regime_el(env, mmu_idx)]; in regime_ttbr()
224 return env->cp15.ttbr1_el[regime_el(env, mmu_idx)]; in regime_ttbr()
236 switch (env->v7m.mpu_ctrl[is_secure] & in regime_translation_disabled()
314 uint64_t gpccr = env->cp15.gpccr_el3; in granule_protection_check()
336 if (pps > FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE)) { in granule_protection_check()
345 case 0b00: /* non-shareable */ in granule_protection_check()
347 /* Inner and Outer non-cacheable requires Outer shareable. */ in granule_protection_check()
371 /* Note this field is read-only and fixed at reset. */ in granule_protection_check()
387 tableaddr = env->cp15.gptbr_el3 << 12; in granule_protection_check()
397 align = MAX(pps - l0gptsz + 3, 12); in granule_protection_check()
404 index = extract64(paddress, l0gptsz, pps - l0gptsz); in granule_protection_check()
420 align = MAX(l0gptsz - pgs - 1, 12); in granule_protection_check()
432 index = extract64(paddress, pgs + 4, l0gptsz - pgs - 4); in granule_protection_check()
445 * Because the softmmu tlb only works on units of TARGET_PAGE_SIZE, in granule_protection_check()
479 fi->gpcf = GPCF_Fail; in granule_protection_check()
482 fi->gpcf = GPCF_EABT; in granule_protection_check()
485 fi->gpcf = GPCF_AddressSize; in granule_protection_check()
488 fi->gpcf = GPCF_Walk; in granule_protection_check()
490 fi->level = level; in granule_protection_check()
491 fi->paddr = paddress; in granule_protection_check()
492 fi->paddr_space = pspace; in granule_protection_check()
499 * This slightly under-decodes the MAIR_ELx field: in S1_attrs_are_device()
538 * Root translations are always single-stage. in S2_security_space()
568 ARMMMUIdx mmu_idx = ptw->in_mmu_idx; in S1_ptw_translate()
569 ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx; in S1_ptw_translate()
572 ptw->out_virt = addr; in S1_ptw_translate()
574 if (unlikely(ptw->in_debug)) { in S1_ptw_translate()
576 * From gdbstub, do not use softmmu so that we don't modify the in S1_ptw_translate()
577 * state of the cpu at all, including softmmu tlb contents. in S1_ptw_translate()
579 ARMSecuritySpace s2_space = S2_security_space(ptw->in_space, s2_mmu_idx); in S1_ptw_translate()
592 ptw->out_phys = s2.f.phys_addr; in S1_ptw_translate()
594 ptw->out_host = NULL; in S1_ptw_translate()
595 ptw->out_rw = false; in S1_ptw_translate()
596 ptw->out_space = s2.f.attrs.space; in S1_ptw_translate()
602 env->tlb_fi = fi; in S1_ptw_translate()
605 &ptw->out_host, &full); in S1_ptw_translate()
606 env->tlb_fi = NULL; in S1_ptw_translate()
611 ptw->out_phys = full->phys_addr | (addr & ~TARGET_PAGE_MASK); in S1_ptw_translate()
612 ptw->out_rw = full->prot & PAGE_WRITE; in S1_ptw_translate()
613 pte_attrs = full->extra.arm.pte_attrs; in S1_ptw_translate()
614 ptw->out_space = full->attrs.space; in S1_ptw_translate()
621 uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space); in S1_ptw_translate()
628 fi->type = ARMFault_Permission; in S1_ptw_translate()
629 fi->s2addr = addr; in S1_ptw_translate()
630 fi->stage2 = true; in S1_ptw_translate()
631 fi->s1ptw = true; in S1_ptw_translate()
632 fi->s1ns = fault_s1ns(ptw->in_space, s2_mmu_idx); in S1_ptw_translate()
637 ptw->out_be = regime_translation_big_endian(env, mmu_idx); in S1_ptw_translate()
641 assert(fi->type != ARMFault_None); in S1_ptw_translate()
642 if (fi->type == ARMFault_GPCFOnOutput) { in S1_ptw_translate()
643 fi->type = ARMFault_GPCFOnWalk; in S1_ptw_translate()
645 fi->s2addr = addr; in S1_ptw_translate()
646 fi->stage2 = regime_is_stage2(s2_mmu_idx); in S1_ptw_translate()
647 fi->s1ptw = fi->stage2; in S1_ptw_translate()
648 fi->s1ns = fault_s1ns(ptw->in_space, s2_mmu_idx); in S1_ptw_translate()
657 void *host = ptw->out_host; in arm_ldl_ptw()
663 if (ptw->out_be) { in arm_ldl_ptw()
671 .space = ptw->out_space, in arm_ldl_ptw()
672 .secure = arm_space_is_secure(ptw->out_space), in arm_ldl_ptw()
677 if (ptw->out_be) { in arm_ldl_ptw()
678 data = address_space_ldl_be(as, ptw->out_phys, attrs, &result); in arm_ldl_ptw()
680 data = address_space_ldl_le(as, ptw->out_phys, attrs, &result); in arm_ldl_ptw()
683 fi->type = ARMFault_SyncExternalOnWalk; in arm_ldl_ptw()
684 fi->ea = arm_extabort_type(result); in arm_ldl_ptw()
695 void *host = ptw->out_host; in arm_ldq_ptw()
702 if (ptw->out_be) { in arm_ldq_ptw()
708 if (ptw->out_be) { in arm_ldq_ptw()
717 .space = ptw->out_space, in arm_ldq_ptw()
718 .secure = arm_space_is_secure(ptw->out_space), in arm_ldq_ptw()
723 if (ptw->out_be) { in arm_ldq_ptw()
724 data = address_space_ldq_be(as, ptw->out_phys, attrs, &result); in arm_ldq_ptw()
726 data = address_space_ldq_le(as, ptw->out_phys, attrs, &result); in arm_ldq_ptw()
729 fi->type = ARMFault_SyncExternalOnWalk; in arm_ldq_ptw()
730 fi->ea = arm_extabort_type(result); in arm_ldq_ptw()
743 void *host = ptw->out_host; in arm_casq_ptw()
749 .space = ptw->out_space, in arm_casq_ptw()
750 .secure = arm_space_is_secure(ptw->out_space), in arm_casq_ptw()
759 if (ptw->out_be) { in arm_casq_ptw()
760 cur_val = address_space_ldq_be(as, ptw->out_phys, attrs, &result); in arm_casq_ptw()
762 fi->type = ARMFault_SyncExternalOnWalk; in arm_casq_ptw()
763 fi->ea = arm_extabort_type(result); in arm_casq_ptw()
770 address_space_stq_be(as, ptw->out_phys, new_val, attrs, &result); in arm_casq_ptw()
772 fi->type = ARMFault_SyncExternalOnWalk; in arm_casq_ptw()
773 fi->ea = arm_extabort_type(result); in arm_casq_ptw()
782 cur_val = address_space_ldq_le(as, ptw->out_phys, attrs, &result); in arm_casq_ptw()
784 fi->type = ARMFault_SyncExternalOnWalk; in arm_casq_ptw()
785 fi->ea = arm_extabort_type(result); in arm_casq_ptw()
792 address_space_stq_le(as, ptw->out_phys, new_val, attrs, &result); in arm_casq_ptw()
794 fi->type = ARMFault_SyncExternalOnWalk; in arm_casq_ptw()
795 fi->ea = arm_extabort_type(result); in arm_casq_ptw()
811 * Raising a stage2 Protection fault for an atomic update to a read-only in arm_casq_ptw()
814 if (unlikely(!ptw->out_rw)) { in arm_casq_ptw()
817 env->tlb_fi = fi; in arm_casq_ptw()
818 flags = probe_access_full_mmu(env, ptw->out_virt, 0, in arm_casq_ptw()
820 arm_to_core_mmu_idx(ptw->in_ptw_idx), in arm_casq_ptw()
822 env->tlb_fi = NULL; in arm_casq_ptw()
831 assert(fi->type != ARMFault_None); in arm_casq_ptw()
832 fi->s2addr = ptw->out_virt; in arm_casq_ptw()
833 fi->stage2 = true; in arm_casq_ptw()
834 fi->s1ptw = true; in arm_casq_ptw()
835 fi->s1ns = fault_s1ns(ptw->in_space, ptw->in_ptw_idx); in arm_casq_ptw()
840 ptw->out_rw = true; in arm_casq_ptw()
844 if (ptw->out_be) { in arm_casq_ptw()
857 * We can't support the full 64-bit atomic cmpxchg on the host. in arm_casq_ptw()
860 * running in round-robin mode and could only race with dma i/o. in arm_casq_ptw()
869 if (ptw->out_be) { in arm_casq_ptw()
887 /* AArch32 does not have FEAT_HADFS; non-TCG guests only use debug-mode. */ in arm_casq_ptw()
923 * @ap: The 3-bit access permissions (AP[2:0])
924 * @domain_prot: The 2-bit domain access permissions
977 * @ap: The 3-bit access permissions (AP[2:0])
978 * @domain_prot: The 2-bit domain access permissions
989 * @ap: The 2-bit simple AP (AP[2:1])
1029 if (!get_level1_table_address(env, ptw->in_mmu_idx, &table, address)) { in get_phys_addr_v5()
1031 fi->type = ARMFault_Translation; in get_phys_addr_v5()
1038 if (fi->type != ARMFault_None) { in get_phys_addr_v5()
1043 if (regime_el(env, ptw->in_mmu_idx) == 1) { in get_phys_addr_v5()
1044 dacr = env->cp15.dacr_ns; in get_phys_addr_v5()
1046 dacr = env->cp15.dacr_s; in get_phys_addr_v5()
1051 fi->type = ARMFault_Translation; in get_phys_addr_v5()
1058 fi->type = ARMFault_Domain; in get_phys_addr_v5()
1065 result->f.lg_page_size = 20; /* 1MB */ in get_phys_addr_v5()
1079 if (fi->type != ARMFault_None) { in get_phys_addr_v5()
1084 fi->type = ARMFault_Translation; in get_phys_addr_v5()
1089 result->f.lg_page_size = 16; in get_phys_addr_v5()
1094 result->f.lg_page_size = 12; in get_phys_addr_v5()
1102 result->f.lg_page_size = 12; in get_phys_addr_v5()
1108 fi->type = ARMFault_Translation; in get_phys_addr_v5()
1113 result->f.lg_page_size = 10; in get_phys_addr_v5()
1122 result->f.prot = ap_to_rw_prot(env, ptw->in_mmu_idx, ap, domain_prot); in get_phys_addr_v5()
1123 result->f.prot |= result->f.prot ? PAGE_EXEC : 0; in get_phys_addr_v5()
1124 if (!(result->f.prot & (1 << access_type))) { in get_phys_addr_v5()
1126 fi->type = ARMFault_Permission; in get_phys_addr_v5()
1129 result->f.phys_addr = phys_addr; in get_phys_addr_v5()
1132 fi->domain = domain; in get_phys_addr_v5()
1133 fi->level = level; in get_phys_addr_v5()
1142 ARMMMUIdx mmu_idx = ptw->in_mmu_idx; in get_phys_addr_v6()
1161 fi->type = ARMFault_Translation; in get_phys_addr_v6()
1168 if (fi->type != ARMFault_None) { in get_phys_addr_v6()
1176 fi->type = ARMFault_Translation; in get_phys_addr_v6()
1184 dacr = env->cp15.dacr_ns; in get_phys_addr_v6()
1186 dacr = env->cp15.dacr_s; in get_phys_addr_v6()
1194 fi->type = ARMFault_Domain; in get_phys_addr_v6()
1203 result->f.lg_page_size = 24; /* 16MB */ in get_phys_addr_v6()
1207 result->f.lg_page_size = 20; /* 1MB */ in get_phys_addr_v6()
1224 if (fi->type != ARMFault_None) { in get_phys_addr_v6()
1230 fi->type = ARMFault_Translation; in get_phys_addr_v6()
1235 result->f.lg_page_size = 16; in get_phys_addr_v6()
1240 result->f.lg_page_size = 12; in get_phys_addr_v6()
1247 out_space = ptw->in_space; in get_phys_addr_v6()
1251 * the CPU doesn't support TZ or this is a non-secure translation in get_phys_addr_v6()
1252 * regime, because the output space will already be non-secure. in get_phys_addr_v6()
1257 result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; in get_phys_addr_v6()
1266 fi->type = ARMFault_AccessFlag; in get_phys_addr_v6()
1276 result->f.prot = get_S1prot(env, mmu_idx, false, user_rw, prot_rw, in get_phys_addr_v6()
1277 xn, pxn, result->f.attrs.space, out_space); in get_phys_addr_v6()
1278 if (!(result->f.prot & (1 << access_type))) { in get_phys_addr_v6()
1280 fi->type = ARMFault_Permission; in get_phys_addr_v6()
1284 result->f.attrs.space = out_space; in get_phys_addr_v6()
1285 result->f.attrs.secure = arm_space_is_secure(out_space); in get_phys_addr_v6()
1286 result->f.phys_addr = phys_addr; in get_phys_addr_v6()
1289 fi->domain = domain; in get_phys_addr_v6()
1290 fi->level = level; in get_phys_addr_v6()
1297 * @s2ap: The 2-bit stage2 access permissions (S2AP)
1298 * @xn: XN (execute-never) bits
1355 * @xn: XN (execute-never) bit
1356 * @pxn: PXN (privileged execute-never) bit
1395 * R_ZWRVD: permission fault for insn fetched from non-Root, in get_S1prot()
1401 * R_PKTDS: permission fault for insn fetched from non-Realm, in get_S1prot()
1416 if (env->cp15.scr_el3 & SCR_SIF) { in get_S1prot()
1485 * If the sign-extend bit is not the same as t0sz[3], the result in aa32_va_parameters()
1540 * @stride: Page-table stride (See the ARM ARM)
1565 startlevel = -1; in check_s2_mmu_setup()
1567 startlevel = 2 - sl0; in check_s2_mmu_setup()
1596 startlevel = 3 - sl0; in check_s2_mmu_setup()
1608 startlevel = 3 - sl0; in check_s2_mmu_setup()
1623 startlevel = 2 - sl0; in check_s2_mmu_setup()
1627 levels = 3 - startlevel; in check_s2_mmu_setup()
1631 s1_max_iasize = s1_min_iasize + (stride - 1) + 4; in check_s2_mmu_setup()
1662 uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space); in nv_nv1_enabled()
1672 * of a long-format DFSR/IFSR fault register, with the following caveat:
1689 ARMMMUIdx mmu_idx = ptw->in_mmu_idx; in get_phys_addr_lpae()
1730 addrsize = 64 - 8 * param.tbi; in get_phys_addr_lpae()
1731 inputsize = 64 - param.tsz; in get_phys_addr_lpae()
1735 * ID_AA64MMFR0 is a read-only register so values outside of the in get_phys_addr_lpae()
1738 ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); in get_phys_addr_lpae()
1754 inputsize = addrsize - param.tsz; in get_phys_addr_lpae()
1769 addrsize - inputsize); in get_phys_addr_lpae()
1770 if (-top_bits != param.select) { in get_phys_addr_lpae()
1776 stride = arm_granule_bits(param.gran) - 3; in get_phys_addr_lpae()
1783 * implement any ASID-like capability so we can ignore it (instead in get_phys_addr_lpae()
1796 * Note: This is always 0 on 64-bit EL2 and EL3. in get_phys_addr_lpae()
1807 * level = 4 - RoundUp((inputsize - grainsize) / stride) in get_phys_addr_lpae()
1810 * Applying the usual "rounded up m/n is (m+n-1)/n" and simplifying: in get_phys_addr_lpae()
1811 * = 4 - (inputsize - stride - 3 + stride - 1) / stride in get_phys_addr_lpae()
1812 * = 4 - (inputsize - 4) / stride; in get_phys_addr_lpae()
1814 level = 4 - (inputsize - 4) / stride; in get_phys_addr_lpae()
1826 indexmask = MAKE_64BIT_MASK(0, inputsize - (stride * (4 - level))); in get_phys_addr_lpae()
1842 fi->type = ARMFault_AddressSize; in get_phys_addr_lpae()
1848 * and also to mask out CnP (bit 0) which could validly be non-zero. in get_phys_addr_lpae()
1858 * the highest bits of a 52-bit output are placed elsewhere. in get_phys_addr_lpae()
1871 descaddr |= (address >> (stride * (4 - level))) & indexmask; in get_phys_addr_lpae()
1880 if (ptw->in_space == ARMSS_Secure in get_phys_addr_lpae()
1884 * Stage2_S -> Stage2 or Phys_S -> Phys_NS in get_phys_addr_lpae()
1885 * Assert the relative order of the secure/non-secure indexes. in get_phys_addr_lpae()
1889 ptw->in_ptw_idx += 1; in get_phys_addr_lpae()
1890 ptw->in_space = ARMSS_NonSecure; in get_phys_addr_lpae()
1897 if (fi->type != ARMFault_None) { in get_phys_addr_lpae()
1925 fi->type = ARMFault_AddressSize; in get_phys_addr_lpae()
1953 page_size = (1ULL << ((stride * (4 - level)) + 3)); in get_phys_addr_lpae()
1954 descaddr &= ~(hwaddr)(page_size - 1); in get_phys_addr_lpae()
1955 descaddr |= (address & (page_size - 1)); in get_phys_addr_lpae()
1957 if (likely(!ptw->in_debug)) { in get_phys_addr_lpae()
1967 fi->type = ARMFault_AccessFlag; in get_phys_addr_lpae()
1974 * If HD is enabled, pre-emptively set/clear the appropriate AP/S2AP in get_phys_addr_lpae()
2009 out_space = ptw->in_space; in get_phys_addr_lpae()
2014 * R_YMCSL: Executing an insn fetched from non-Realm causes in get_phys_addr_lpae()
2019 result->f.prot = get_S2prot_noexecute(ap); in get_phys_addr_lpae()
2022 result->f.prot = get_S2prot(env, ap, xn, ptw->in_s1_is_el0); in get_phys_addr_lpae()
2025 result->cacheattrs.is_s2_format = true; in get_phys_addr_lpae()
2026 result->cacheattrs.attrs = extract32(attrs, 2, 4); in get_phys_addr_lpae()
2032 result->cacheattrs.attrs); in get_phys_addr_lpae()
2070 * NS changes the output to non-secure space. in get_phys_addr_lpae()
2108 * Note that we modified ptw->in_space earlier for NSTable, but in get_phys_addr_lpae()
2109 * result->f.attrs retains a copy of the original security space. in get_phys_addr_lpae()
2111 result->f.prot = get_S1prot(env, mmu_idx, aarch64, user_rw, prot_rw, in get_phys_addr_lpae()
2112 xn, pxn, result->f.attrs.space, out_space); in get_phys_addr_lpae()
2116 mair = env->cp15.mair_el[regime_el(env, mmu_idx)]; in get_phys_addr_lpae()
2118 result->cacheattrs.is_s2_format = false; in get_phys_addr_lpae()
2119 result->cacheattrs.attrs = extract64(mair, attrindx * 8, 8); in get_phys_addr_lpae()
2123 result->f.extra.arm.guarded = extract64(attrs, 50, 1); /* GP */ in get_phys_addr_lpae()
2125 device = S1_attrs_are_device(result->cacheattrs.attrs); in get_phys_addr_lpae()
2133 * - Alignment fault caused by the memory type in get_phys_addr_lpae()
2134 * - Permission fault in get_phys_addr_lpae()
2135 * - A stage 2 fault on the memory access in get_phys_addr_lpae()
2138 * softmmu tlb hit will also check the alignment; clear along the in get_phys_addr_lpae()
2139 * non-device path so that tlb_fill_flags is consistent in the in get_phys_addr_lpae()
2149 if (address & ((1 << a_bits) - 1)) { in get_phys_addr_lpae()
2150 fi->type = ARMFault_Alignment; in get_phys_addr_lpae()
2153 result->f.tlb_fill_flags = TLB_CHECK_ALIGNED; in get_phys_addr_lpae()
2155 result->f.tlb_fill_flags = 0; in get_phys_addr_lpae()
2158 if (!(result->f.prot & (1 << access_type))) { in get_phys_addr_lpae()
2159 fi->type = ARMFault_Permission; in get_phys_addr_lpae()
2166 if (fi->type != ARMFault_None) { in get_phys_addr_lpae()
2170 * I_YZSVV says that if the in-memory descriptor has changed, in get_phys_addr_lpae()
2182 result->f.attrs.space = out_space; in get_phys_addr_lpae()
2183 result->f.attrs.secure = arm_space_is_secure(out_space); in get_phys_addr_lpae()
2187 * was re-purposed for output address bits. The SH attribute in in get_phys_addr_lpae()
2191 result->cacheattrs.shareability = param.sh; in get_phys_addr_lpae()
2193 result->cacheattrs.shareability = extract32(attrs, 8, 2); in get_phys_addr_lpae()
2196 result->f.phys_addr = descaddr; in get_phys_addr_lpae()
2197 result->f.lg_page_size = ctz64(page_size); in get_phys_addr_lpae()
2201 fi->type = ARMFault_Translation; in get_phys_addr_lpae()
2203 if (fi->s1ptw) { in get_phys_addr_lpae()
2204 /* Retain the existing stage 2 fi->level */ in get_phys_addr_lpae()
2205 assert(fi->stage2); in get_phys_addr_lpae()
2207 fi->level = level; in get_phys_addr_lpae()
2208 fi->stage2 = regime_is_stage2(mmu_idx); in get_phys_addr_lpae()
2210 fi->s1ns = fault_s1ns(ptw->in_space, mmu_idx); in get_phys_addr_lpae()
2224 ARMMMUIdx mmu_idx = ptw->in_mmu_idx; in get_phys_addr_pmsav5()
2227 if (regime_translation_disabled(env, mmu_idx, ptw->in_space)) { in get_phys_addr_pmsav5()
2229 result->f.phys_addr = address; in get_phys_addr_pmsav5()
2230 result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; in get_phys_addr_pmsav5()
2234 result->f.phys_addr = address; in get_phys_addr_pmsav5()
2235 for (n = 7; n >= 0; n--) { in get_phys_addr_pmsav5()
2236 base = env->cp15.c6_region[n]; in get_phys_addr_pmsav5()
2243 mask = (mask << 1) - 1; in get_phys_addr_pmsav5()
2249 fi->type = ARMFault_Background; in get_phys_addr_pmsav5()
2254 mask = env->cp15.pmsav5_insn_ap; in get_phys_addr_pmsav5()
2256 mask = env->cp15.pmsav5_data_ap; in get_phys_addr_pmsav5()
2261 fi->type = ARMFault_Permission; in get_phys_addr_pmsav5()
2262 fi->level = 1; in get_phys_addr_pmsav5()
2266 fi->type = ARMFault_Permission; in get_phys_addr_pmsav5()
2267 fi->level = 1; in get_phys_addr_pmsav5()
2270 result->f.prot = PAGE_READ | PAGE_WRITE; in get_phys_addr_pmsav5()
2273 result->f.prot = PAGE_READ; in get_phys_addr_pmsav5()
2275 result->f.prot |= PAGE_WRITE; in get_phys_addr_pmsav5()
2279 result->f.prot = PAGE_READ | PAGE_WRITE; in get_phys_addr_pmsav5()
2283 fi->type = ARMFault_Permission; in get_phys_addr_pmsav5()
2284 fi->level = 1; in get_phys_addr_pmsav5()
2287 result->f.prot = PAGE_READ; in get_phys_addr_pmsav5()
2290 result->f.prot = PAGE_READ; in get_phys_addr_pmsav5()
2294 fi->type = ARMFault_Permission; in get_phys_addr_pmsav5()
2295 fi->level = 1; in get_phys_addr_pmsav5()
2298 result->f.prot |= PAGE_EXEC; in get_phys_addr_pmsav5()
2320 * The architecture specifies which regions are execute-never; in get_phys_addr_pmsav7_default()
2344 /* True if address is in the M profile PPB region 0xe0000000 - 0xe00fffff */ in m_is_ppb_region()
2353 * 0xe0000000 - 0xffffffff in m_is_system_region()
2365 CPUARMState *env = &cpu->env; in pmsav7_use_background_region()
2372 return env->v7m.mpu_ctrl[is_secure] & R_V7M_MPU_CTRL_PRIVDEFENA_MASK; in pmsav7_use_background_region()
2391 ARMMMUIdx mmu_idx = ptw->in_mmu_idx; in get_phys_addr_pmsav7()
2393 bool secure = arm_space_is_secure(ptw->in_space); in get_phys_addr_pmsav7()
2395 result->f.phys_addr = address; in get_phys_addr_pmsav7()
2396 result->f.lg_page_size = TARGET_PAGE_BITS; in get_phys_addr_pmsav7()
2397 result->f.prot = 0; in get_phys_addr_pmsav7()
2399 if (regime_translation_disabled(env, mmu_idx, ptw->in_space) || in get_phys_addr_pmsav7()
2404 * v7M ARM ARM pseudocode is exception vector reads from the vector in get_phys_addr_pmsav7()
2409 get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot); in get_phys_addr_pmsav7()
2411 for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { in get_phys_addr_pmsav7()
2413 uint32_t base = env->pmsav7.drbar[n]; in get_phys_addr_pmsav7()
2414 uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5); in get_phys_addr_pmsav7()
2418 if (!(env->pmsav7.drsr[n] & 0x1)) { in get_phys_addr_pmsav7()
2428 rmask = (1ull << rsize) - 1; in get_phys_addr_pmsav7()
2451 result->f.lg_page_size = 0; in get_phys_addr_pmsav7()
2462 rsize -= 3; /* sub region size (power of 2) */ in get_phys_addr_pmsav7()
2463 snd = ((address - base) >> rsize) & 0x7; in get_phys_addr_pmsav7()
2464 srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1); in get_phys_addr_pmsav7()
2475 int snd_rounded = snd & ~(i - 1); in get_phys_addr_pmsav7()
2476 uint32_t srdis_multi = extract32(env->pmsav7.drsr[n], in get_phys_addr_pmsav7()
2489 result->f.lg_page_size = rsize; in get_phys_addr_pmsav7()
2494 if (n == -1) { /* no hits */ in get_phys_addr_pmsav7()
2497 fi->type = ARMFault_Background; in get_phys_addr_pmsav7()
2501 &result->f.prot); in get_phys_addr_pmsav7()
2503 uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3); in get_phys_addr_pmsav7()
2504 uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1); in get_phys_addr_pmsav7()
2518 result->f.prot |= PAGE_WRITE; in get_phys_addr_pmsav7()
2522 result->f.prot |= PAGE_READ | PAGE_EXEC; in get_phys_addr_pmsav7()
2527 result->f.prot |= PAGE_READ | PAGE_EXEC; in get_phys_addr_pmsav7()
2543 result->f.prot |= PAGE_WRITE; in get_phys_addr_pmsav7()
2547 result->f.prot |= PAGE_READ | PAGE_EXEC; in get_phys_addr_pmsav7()
2552 result->f.prot |= PAGE_READ | PAGE_EXEC; in get_phys_addr_pmsav7()
2565 result->f.prot &= ~PAGE_EXEC; in get_phys_addr_pmsav7()
2570 fi->type = ARMFault_Permission; in get_phys_addr_pmsav7()
2571 fi->level = 1; in get_phys_addr_pmsav7()
2572 return !(result->f.prot & (1 << access_type)); in get_phys_addr_pmsav7()
2579 return env->pmsav8.hprbar; in regime_rbar()
2581 return env->pmsav8.rbar[secure]; in regime_rbar()
2589 return env->pmsav8.hprlar; in regime_rlar()
2591 return env->pmsav8.rlar[secure]; in regime_rlar()
2602 * that a full phys-to-virt translation does). in pmsav8_mpu_lookup()
2604 * or -1 if no region number is returned (MPU off, address did not in pmsav8_mpu_lookup()
2613 int matchregion = -1; in pmsav8_mpu_lookup()
2616 uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1); in pmsav8_mpu_lookup()
2620 region_counter = cpu->pmsav8r_hdregion; in pmsav8_mpu_lookup()
2622 region_counter = cpu->pmsav7_dregion; in pmsav8_mpu_lookup()
2625 result->f.lg_page_size = TARGET_PAGE_BITS; in pmsav8_mpu_lookup()
2626 result->f.phys_addr = address; in pmsav8_mpu_lookup()
2627 result->f.prot = 0; in pmsav8_mpu_lookup()
2629 *mregion = -1; in pmsav8_mpu_lookup()
2633 fi->stage2 = true; in pmsav8_mpu_lookup()
2637 * Unlike the ARM ARM pseudocode, we don't need to check whether this in pmsav8_mpu_lookup()
2658 fi->level = 0; in pmsav8_mpu_lookup()
2661 for (n = region_counter - 1; n >= 0; n--) { in pmsav8_mpu_lookup()
2665 * with bits [x-1:0] all zeroes, but the limit address is bits in pmsav8_mpu_lookup()
2667 * 5 for Cortex-M and 6 for Cortex-R in pmsav8_mpu_lookup()
2688 ranges_overlap(base, limit - base + 1, in pmsav8_mpu_lookup()
2691 result->f.lg_page_size = 0; in pmsav8_mpu_lookup()
2697 result->f.lg_page_size = 0; in pmsav8_mpu_lookup()
2700 if (matchregion != -1) { in pmsav8_mpu_lookup()
2702 * Multiple regions match -- always a failure (unlike in pmsav8_mpu_lookup()
2703 * PMSAv7 where highest-numbered-region wins) in pmsav8_mpu_lookup()
2705 fi->type = ARMFault_Permission; in pmsav8_mpu_lookup()
2707 fi->level = 1; in pmsav8_mpu_lookup()
2719 fi->type = ARMFault_Background; in pmsav8_mpu_lookup()
2721 fi->type = ARMFault_Permission; in pmsav8_mpu_lookup()
2726 if (matchregion == -1) { in pmsav8_mpu_lookup()
2728 get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot); in pmsav8_mpu_lookup()
2746 result->f.prot = simple_ap_to_rw_prot_is_user(ap, in pmsav8_mpu_lookup()
2749 result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap); in pmsav8_mpu_lookup()
2754 uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)]; in pmsav8_mpu_lookup()
2758 result->f.prot & PAGE_WRITE && mmu_idx != ARMMMUIdx_Stage2) { in pmsav8_mpu_lookup()
2767 result->cacheattrs.is_s2_format = false; in pmsav8_mpu_lookup()
2768 result->cacheattrs.attrs = extract64(mair, attrindx * 8, 8); in pmsav8_mpu_lookup()
2769 result->cacheattrs.shareability = sh; in pmsav8_mpu_lookup()
2772 if (result->f.prot && !xn && !(pxn && !is_user)) { in pmsav8_mpu_lookup()
2773 result->f.prot |= PAGE_EXEC; in pmsav8_mpu_lookup()
2781 fi->type = ARMFault_Permission; in pmsav8_mpu_lookup()
2783 fi->level = 1; in pmsav8_mpu_lookup()
2785 return !(result->f.prot & (1 << access_type)); in pmsav8_mpu_lookup()
2811 * We assume the caller has zero-initialized *sattrs. in v8m_security_lookup()
2818 uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1); in v8m_security_lookup()
2820 if (cpu->idau) { in v8m_security_lookup()
2821 IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau); in v8m_security_lookup()
2822 IDAUInterface *ii = IDAU_INTERFACE(cpu->idau); in v8m_security_lookup()
2824 iic->check(ii, address, &idau_region, &idau_exempt, &idau_ns, in v8m_security_lookup()
2834 sattrs->ns = !is_secure; in v8m_security_lookup()
2839 sattrs->irvalid = true; in v8m_security_lookup()
2840 sattrs->iregion = idau_region; in v8m_security_lookup()
2843 switch (env->sau.ctrl & 3) { in v8m_security_lookup()
2847 sattrs->ns = true; in v8m_security_lookup()
2850 for (r = 0; r < cpu->sau_sregion; r++) { in v8m_security_lookup()
2851 if (env->sau.rlar[r] & 1) { in v8m_security_lookup()
2852 uint32_t base = env->sau.rbar[r] & ~0x1f; in v8m_security_lookup()
2853 uint32_t limit = env->sau.rlar[r] | 0x1f; in v8m_security_lookup()
2857 sattrs->subpage = true; in v8m_security_lookup()
2859 if (sattrs->srvalid) { in v8m_security_lookup()
2862 * as Secure, not NS-Callable, with no valid region in v8m_security_lookup()
2865 sattrs->ns = false; in v8m_security_lookup()
2866 sattrs->nsc = false; in v8m_security_lookup()
2867 sattrs->sregion = 0; in v8m_security_lookup()
2868 sattrs->srvalid = false; in v8m_security_lookup()
2871 if (env->sau.rlar[r] & 2) { in v8m_security_lookup()
2872 sattrs->nsc = true; in v8m_security_lookup()
2874 sattrs->ns = true; in v8m_security_lookup()
2876 sattrs->srvalid = true; in v8m_security_lookup()
2877 sattrs->sregion = r; in v8m_security_lookup()
2890 ranges_overlap(base, limit - base + 1, in v8m_security_lookup()
2893 sattrs->subpage = true; in v8m_security_lookup()
2906 if (sattrs->ns || (!idau_nsc && sattrs->nsc)) { in v8m_security_lookup()
2907 sattrs->ns = false; in v8m_security_lookup()
2908 sattrs->nsc = idau_nsc; in v8m_security_lookup()
2921 ARMMMUIdx mmu_idx = ptw->in_mmu_idx; in get_phys_addr_pmsav8()
2922 bool secure = arm_space_is_secure(ptw->in_space); in get_phys_addr_pmsav8()
2949 fi->type = ARMFault_QEMU_NSCExec; in get_phys_addr_pmsav8()
2951 fi->type = ARMFault_QEMU_SFault; in get_phys_addr_pmsav8()
2953 result->f.lg_page_size = sattrs.subpage ? 0 : TARGET_PAGE_BITS; in get_phys_addr_pmsav8()
2954 result->f.phys_addr = address; in get_phys_addr_pmsav8()
2955 result->f.prot = 0; in get_phys_addr_pmsav8()
2965 result->f.attrs.secure = false; in get_phys_addr_pmsav8()
2966 result->f.attrs.space = ARMSS_NonSecure; in get_phys_addr_pmsav8()
2978 fi->type = ARMFault_QEMU_SFault; in get_phys_addr_pmsav8()
2979 result->f.lg_page_size = sattrs.subpage ? 0 : TARGET_PAGE_BITS; in get_phys_addr_pmsav8()
2980 result->f.phys_addr = address; in get_phys_addr_pmsav8()
2981 result->f.prot = 0; in get_phys_addr_pmsav8()
2990 result->f.lg_page_size = 0; in get_phys_addr_pmsav8()
2996 * Translate from the 4-bit stage 2 representation of
2997 * memory attributes (without cache-allocation hints) to
2998 * the 8-bit representation of the stage 1 MAIR registers
3012 hiattr = loattr = 1; /* non-cacheable */ in convert_stage2_attrs()
3014 if (hiattr != 1) { /* Write-through or write-back */ in convert_stage2_attrs()
3017 if (loattr != 1) { /* Write-through or write-back */ in convert_stage2_attrs()
3028 * memory, according to table D4-42 and pseudocode procedure
3029 * CombineS1S2AttrHints() of ARM DDI 0487B.b (the ARMv8 ARM).
3037 /* non-cacheable has precedence */ in combine_cacheattr_nibble()
3040 /* stage 1 write-through takes precedence */ in combine_cacheattr_nibble()
3043 /* stage 2 write-through takes precedence, but the allocation hint in combine_cacheattr_nibble()
3047 } else { /* write-back */ in combine_cacheattr_nibble()
3080 /* non-Reordering has precedence over Reordering */ in combined_attrs_nofwb()
3083 /* non-Gathering has precedence over Gathering */ in combined_attrs_nofwb()
3100 * in MAIR format, return a value specifying Normal Write-Back, in force_cacheattr_nibble_wb()
3107 * 4 == Non-cacheable in force_cacheattr_nibble_wb()
3108 * Either way, force Write-Back RW allocate non-transient in force_cacheattr_nibble_wb()
3131 * Force Normal Write-Back. Note that if S1 is Normal cacheable in combined_attrs_fwb()
3133 * RW allocate, non-transient. in combined_attrs_fwb()
3143 /* If S1 attrs are Device, use them; otherwise Normal Non-cacheable */ in combined_attrs_fwb()
3182 /* Combine shareability attributes (table D4-43) */ in combine_cacheattrs()
3184 /* if either are outer-shareable, the result is outer-shareable */ in combine_cacheattrs()
3187 /* if either are inner-shareable, the result is inner-shareable */ in combine_cacheattrs()
3190 /* both non-shareable */ in combine_cacheattrs()
3205 * Inner Non-cacheable, Outer Non-cacheable is always treated in combine_cacheattrs()
3223 * still checked for bounds -- see AArch64.S1DisabledOutput().
3232 ARMMMUIdx mmu_idx = ptw->in_mmu_idx; in get_phys_addr_disabled()
3234 uint8_t shareability = 0; /* non-shareable */ in get_phys_addr_disabled()
3250 uint64_t tcr = env->cp15.tcr_el[r_el]; in get_phys_addr_disabled()
3260 if (extract64(address, pamax, addrtop - pamax + 1) != 0) { in get_phys_addr_disabled()
3261 fi->type = ARMFault_AddressSize; in get_phys_addr_disabled()
3262 fi->level = 0; in get_phys_addr_disabled()
3263 fi->stage2 = false; in get_phys_addr_disabled()
3276 /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */ in get_phys_addr_disabled()
3278 uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space); in get_phys_addr_disabled()
3297 result->cacheattrs.is_s2_format = false; in get_phys_addr_disabled()
3301 result->f.phys_addr = address; in get_phys_addr_disabled()
3302 result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; in get_phys_addr_disabled()
3303 result->f.lg_page_size = TARGET_PAGE_BITS; in get_phys_addr_disabled()
3304 result->cacheattrs.shareability = shareability; in get_phys_addr_disabled()
3305 result->cacheattrs.attrs = memattr; in get_phys_addr_disabled()
3317 ARMSecuritySpace in_space = ptw->in_space; in get_phys_addr_twostage()
3331 ipa = result->f.phys_addr; in get_phys_addr_twostage()
3332 ipa_secure = result->f.attrs.secure; in get_phys_addr_twostage()
3333 ipa_space = result->f.attrs.space; in get_phys_addr_twostage()
3335 ptw->in_s1_is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0; in get_phys_addr_twostage()
3336 ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; in get_phys_addr_twostage()
3337 ptw->in_space = ipa_space; in get_phys_addr_twostage()
3338 ptw->in_ptw_idx = ptw_idx_for_stage_2(env, ptw->in_mmu_idx); in get_phys_addr_twostage()
3344 s1_prot = result->f.prot; in get_phys_addr_twostage()
3345 s1_lgpgsz = result->f.lg_page_size; in get_phys_addr_twostage()
3346 s1_guarded = result->f.extra.arm.guarded; in get_phys_addr_twostage()
3347 cacheattrs1 = result->cacheattrs; in get_phys_addr_twostage()
3352 fi->s2addr = ipa; in get_phys_addr_twostage()
3355 result->f.prot &= s1_prot; in get_phys_addr_twostage()
3373 if (result->f.lg_page_size < TARGET_PAGE_BITS || in get_phys_addr_twostage()
3375 result->f.lg_page_size = 0; in get_phys_addr_twostage()
3376 } else if (result->f.lg_page_size < s1_lgpgsz) { in get_phys_addr_twostage()
3377 result->f.lg_page_size = s1_lgpgsz; in get_phys_addr_twostage()
3385 * Normal Non-Shareable, in get_phys_addr_twostage()
3386 * Inner Write-Back Read-Allocate Write-Allocate, in get_phys_addr_twostage()
3387 * Outer Write-Back Read-Allocate Write-Allocate. in get_phys_addr_twostage()
3395 result->cacheattrs = combine_cacheattrs(hcr, cacheattrs1, in get_phys_addr_twostage()
3396 result->cacheattrs); in get_phys_addr_twostage()
3399 result->f.extra.arm.guarded = s1_guarded; in get_phys_addr_twostage()
3402 * Check if IPA translates to secure or non-secure PA space. in get_phys_addr_twostage()
3406 result->f.attrs.secure = in get_phys_addr_twostage()
3407 !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)) in get_phys_addr_twostage()
3409 || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))); in get_phys_addr_twostage()
3410 result->f.attrs.space = arm_secure_to_space(result->f.attrs.secure); in get_phys_addr_twostage()
3422 ARMMMUIdx mmu_idx = ptw->in_mmu_idx; in get_phys_addr_nogpc()
3430 result->f.attrs.space = ptw->in_space; in get_phys_addr_nogpc()
3431 result->f.attrs.secure = arm_space_is_secure(ptw->in_space); in get_phys_addr_nogpc()
3449 ptw->in_ptw_idx = (ptw->in_space == ARMSS_Secure) ? in get_phys_addr_nogpc()
3460 ptw->in_ptw_idx = ptw_idx_for_stage_2(env, mmu_idx); in get_phys_addr_nogpc()
3474 * translations if mmu_idx is a two-stage regime, and EL2 present. in get_phys_addr_nogpc()
3477 ptw->in_mmu_idx = mmu_idx = s1_mmu_idx; in get_phys_addr_nogpc()
3479 !regime_translation_disabled(env, ARMMMUIdx_Stage2, ptw->in_space)) { in get_phys_addr_nogpc()
3487 ptw->in_ptw_idx = arm_space_to_phys(ptw->in_space); in get_phys_addr_nogpc()
3491 result->f.attrs.user = regime_is_user(env, mmu_idx); in get_phys_addr_nogpc()
3500 address += env->cp15.fcseidr_s; in get_phys_addr_nogpc()
3502 address += env->cp15.fcseidr_ns; in get_phys_addr_nogpc()
3508 result->f.lg_page_size = TARGET_PAGE_BITS; in get_phys_addr_nogpc()
3519 /* Pre-v7 MPU */ in get_phys_addr_nogpc()
3524 " mmu_idx %u -> %s (prot %c%c%c)\n", in get_phys_addr_nogpc()
3529 result->f.prot & PAGE_READ ? 'r' : '-', in get_phys_addr_nogpc()
3530 result->f.prot & PAGE_WRITE ? 'w' : '-', in get_phys_addr_nogpc()
3531 result->f.prot & PAGE_EXEC ? 'x' : '-'); in get_phys_addr_nogpc()
3538 if (regime_translation_disabled(env, mmu_idx, ptw->in_space)) { in get_phys_addr_nogpc()
3564 if (!granule_protection_check(env, result->f.phys_addr, in get_phys_addr_gpc()
3565 result->f.attrs.space, fi)) { in get_phys_addr_gpc()
3566 fi->type = ARMFault_GPCFOnOutput; in get_phys_addr_gpc()
3662 CPUARMState *env = &cpu->env; in arm_cpu_get_phys_page_attrs_debug()
3678 return -1; in arm_cpu_get_phys_page_attrs_debug()