@@ -1142,6 +1142,8 @@ CPAccessResult access_ttlb(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread);
CPAccessResult access_ttlbis(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread);
+CPAccessResult access_ttlbos(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread);
bool tlb_force_broadcast(CPUARMState *env);
int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
uint64_t addr);
@@ -388,8 +388,8 @@ CPAccessResult access_ttlbis(CPUARMState *env, const ARMCPRegInfo *ri,
#ifdef TARGET_AARCH64
/* Check for traps from EL1 due to HCR_EL2.TTLB or TTLBOS. */
-static CPAccessResult access_ttlbos(CPUARMState *env, const ARMCPRegInfo *ri,
- bool isread)
+CPAccessResult access_ttlbos(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
if (arm_current_el(env) == 1 &&
(arm_hcr_el2_eff(env) & (HCR_TTLB | HCR_TTLBOS))) {
@@ -4856,202 +4856,6 @@ int ipas2e1_tlbmask(CPUARMState *env, int64_t value)
: ARMMMUIdxBit_Stage2);
}
-#ifdef TARGET_AARCH64
-typedef struct {
- uint64_t base;
- uint64_t length;
-} TLBIRange;
-
-static ARMGranuleSize tlbi_range_tg_to_gran_size(int tg)
-{
- /*
- * Note that the TLBI range TG field encoding differs from both
- * TG0 and TG1 encodings.
- */
- switch (tg) {
- case 1:
- return Gran4K;
- case 2:
- return Gran16K;
- case 3:
- return Gran64K;
- default:
- return GranInvalid;
- }
-}
-
-static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
- uint64_t value)
-{
- unsigned int page_size_granule, page_shift, num, scale, exponent;
- /* Extract one bit to represent the va selector in use. */
- uint64_t select = sextract64(value, 36, 1);
- ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true, false);
- TLBIRange ret = { };
- ARMGranuleSize gran;
-
- page_size_granule = extract64(value, 46, 2);
- gran = tlbi_range_tg_to_gran_size(page_size_granule);
-
- /* The granule encoded in value must match the granule in use. */
- if (gran != param.gran) {
- qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
- page_size_granule);
- return ret;
- }
-
- page_shift = arm_granule_bits(gran);
- num = extract64(value, 39, 5);
- scale = extract64(value, 44, 2);
- exponent = (5 * scale) + 1;
-
- ret.length = (num + 1) << (exponent + page_shift);
-
- if (param.select) {
- ret.base = sextract64(value, 0, 37);
- } else {
- ret.base = extract64(value, 0, 37);
- }
- if (param.ds) {
- /*
- * With DS=1, BaseADDR is always shifted 16 so that it is able
- * to address all 52 va bits. The input address is perforce
- * aligned on a 64k boundary regardless of translation granule.
- */
- page_shift = 16;
- }
- ret.base <<= page_shift;
-
- return ret;
-}
-
-static void do_rvae_write(CPUARMState *env, uint64_t value,
- int idxmap, bool synced)
-{
- ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
- TLBIRange range;
- int bits;
-
- range = tlbi_aa64_get_range(env, one_idx, value);
- bits = tlbbits_for_regime(env, one_idx, range.base);
-
- if (synced) {
- tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
- range.base,
- range.length,
- idxmap,
- bits);
- } else {
- tlb_flush_range_by_mmuidx(env_cpu(env), range.base,
- range.length, idxmap, bits);
- }
-}
-
-static void tlbi_aa64_rvae1_write(CPUARMState *env,
- const ARMCPRegInfo *ri,
- uint64_t value)
-{
- /*
- * Invalidate by VA range, EL1&0.
- * Currently handles all of RVAE1, RVAAE1, RVAALE1 and RVALE1,
- * since we don't support flush-for-specific-ASID-only or
- * flush-last-level-only.
- */
-
- do_rvae_write(env, value, vae1_tlbmask(env),
- tlb_force_broadcast(env));
-}
-
-static void tlbi_aa64_rvae1is_write(CPUARMState *env,
- const ARMCPRegInfo *ri,
- uint64_t value)
-{
- /*
- * Invalidate by VA range, Inner/Outer Shareable EL1&0.
- * Currently handles all of RVAE1IS, RVAE1OS, RVAAE1IS, RVAAE1OS,
- * RVAALE1IS, RVAALE1OS, RVALE1IS and RVALE1OS, since we don't support
- * flush-for-specific-ASID-only, flush-last-level-only or inner/outer
- * shareable specific flushes.
- */
-
- do_rvae_write(env, value, vae1_tlbmask(env), true);
-}
-
-static void tlbi_aa64_rvae2_write(CPUARMState *env,
- const ARMCPRegInfo *ri,
- uint64_t value)
-{
- /*
- * Invalidate by VA range, EL2.
- * Currently handles all of RVAE2 and RVALE2,
- * since we don't support flush-for-specific-ASID-only or
- * flush-last-level-only.
- */
-
- do_rvae_write(env, value, vae2_tlbmask(env),
- tlb_force_broadcast(env));
-
-
-}
-
-static void tlbi_aa64_rvae2is_write(CPUARMState *env,
- const ARMCPRegInfo *ri,
- uint64_t value)
-{
- /*
- * Invalidate by VA range, Inner/Outer Shareable, EL2.
- * Currently handles all of RVAE2IS, RVAE2OS, RVALE2IS and RVALE2OS,
- * since we don't support flush-for-specific-ASID-only,
- * flush-last-level-only or inner/outer shareable specific flushes.
- */
-
- do_rvae_write(env, value, vae2_tlbmask(env), true);
-
-}
-
-static void tlbi_aa64_rvae3_write(CPUARMState *env,
- const ARMCPRegInfo *ri,
- uint64_t value)
-{
- /*
- * Invalidate by VA range, EL3.
- * Currently handles all of RVAE3 and RVALE3,
- * since we don't support flush-for-specific-ASID-only or
- * flush-last-level-only.
- */
-
- do_rvae_write(env, value, ARMMMUIdxBit_E3, tlb_force_broadcast(env));
-}
-
-static void tlbi_aa64_rvae3is_write(CPUARMState *env,
- const ARMCPRegInfo *ri,
- uint64_t value)
-{
- /*
- * Invalidate by VA range, EL3, Inner/Outer Shareable.
- * Currently handles all of RVAE3IS, RVAE3OS, RVALE3IS and RVALE3OS,
- * since we don't support flush-for-specific-ASID-only,
- * flush-last-level-only or inner/outer specific flushes.
- */
-
- do_rvae_write(env, value, ARMMMUIdxBit_E3, true);
-}
-
-static void tlbi_aa64_ripas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- do_rvae_write(env, value, ipas2e1_tlbmask(env, value),
- tlb_force_broadcast(env));
-}
-
-static void tlbi_aa64_ripas2e1is_write(CPUARMState *env,
- const ARMCPRegInfo *ri,
- uint64_t value)
-{
- do_rvae_write(env, value, ipas2e1_tlbmask(env, value), true);
-}
-#endif
-
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
@@ -7312,133 +7116,6 @@ static const ARMCPRegInfo pauth_reginfo[] = {
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
};
-static const ARMCPRegInfo tlbirange_reginfo[] = {
- { .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1,
- .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAE1IS,
- .writefn = tlbi_aa64_rvae1is_write },
- { .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3,
- .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAAE1IS,
- .writefn = tlbi_aa64_rvae1is_write },
- { .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5,
- .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVALE1IS,
- .writefn = tlbi_aa64_rvae1is_write },
- { .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7,
- .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAALE1IS,
- .writefn = tlbi_aa64_rvae1is_write },
- { .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
- .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAE1OS,
- .writefn = tlbi_aa64_rvae1is_write },
- { .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3,
- .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAAE1OS,
- .writefn = tlbi_aa64_rvae1is_write },
- { .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5,
- .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVALE1OS,
- .writefn = tlbi_aa64_rvae1is_write },
- { .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7,
- .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAALE1OS,
- .writefn = tlbi_aa64_rvae1is_write },
- { .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
- .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAE1,
- .writefn = tlbi_aa64_rvae1_write },
- { .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3,
- .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAAE1,
- .writefn = tlbi_aa64_rvae1_write },
- { .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5,
- .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVALE1,
- .writefn = tlbi_aa64_rvae1_write },
- { .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7,
- .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
- .fgt = FGT_TLBIRVAALE1,
- .writefn = tlbi_aa64_rvae1_write },
- { .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
- .access = PL2_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_ripas2e1is_write },
- { .name = "TLBI_RIPAS2LE1IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 6,
- .access = PL2_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_ripas2e1is_write },
- { .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1,
- .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
- .writefn = tlbi_aa64_rvae2is_write },
- { .name = "TLBI_RVALE2IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 5,
- .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
- .writefn = tlbi_aa64_rvae2is_write },
- { .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2,
- .access = PL2_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_ripas2e1_write },
- { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 6,
- .access = PL2_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_ripas2e1_write },
- { .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1,
- .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
- .writefn = tlbi_aa64_rvae2is_write },
- { .name = "TLBI_RVALE2OS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 5,
- .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
- .writefn = tlbi_aa64_rvae2is_write },
- { .name = "TLBI_RVAE2", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 1,
- .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
- .writefn = tlbi_aa64_rvae2_write },
- { .name = "TLBI_RVALE2", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 5,
- .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
- .writefn = tlbi_aa64_rvae2_write },
- { .name = "TLBI_RVAE3IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 1,
- .access = PL3_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_rvae3is_write },
- { .name = "TLBI_RVALE3IS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 5,
- .access = PL3_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_rvae3is_write },
- { .name = "TLBI_RVAE3OS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 1,
- .access = PL3_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_rvae3is_write },
- { .name = "TLBI_RVALE3OS", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 5,
- .access = PL3_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_rvae3is_write },
- { .name = "TLBI_RVAE3", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 1,
- .access = PL3_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_rvae3_write },
- { .name = "TLBI_RVALE3", .state = ARM_CP_STATE_AA64,
- .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5,
- .access = PL3_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbi_aa64_rvae3_write },
-};
-
static const ARMCPRegInfo tlbios_reginfo[] = {
{ .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0,
@@ -9389,9 +9066,6 @@ void register_cp_regs_for_features(ARMCPU *cpu)
if (cpu_isar_feature(aa64_rndr, cpu)) {
define_arm_cp_regs(cpu, rndr_reginfo);
}
- if (cpu_isar_feature(aa64_tlbirange, cpu)) {
- define_arm_cp_regs(cpu, tlbirange_reginfo);
- }
if (cpu_isar_feature(aa64_tlbios, cpu)) {
define_arm_cp_regs(cpu, tlbios_reginfo);
}
@@ -6,6 +6,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "exec/exec-all.h"
#include "cpu.h"
#include "internals.h"
@@ -562,6 +563,329 @@ static const ARMCPRegInfo tlbi_el3_cp_reginfo[] = {
.writefn = tlbi_aa64_vae3_write },
};
+#ifdef TARGET_AARCH64
+typedef struct {
+ uint64_t base;
+ uint64_t length;
+} TLBIRange;
+
+static ARMGranuleSize tlbi_range_tg_to_gran_size(int tg)
+{
+ /*
+ * Note that the TLBI range TG field encoding differs from both
+ * TG0 and TG1 encodings.
+ */
+ switch (tg) {
+ case 1:
+ return Gran4K;
+ case 2:
+ return Gran16K;
+ case 3:
+ return Gran64K;
+ default:
+ return GranInvalid;
+ }
+}
+
+static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
+ uint64_t value)
+{
+ unsigned int page_size_granule, page_shift, num, scale, exponent;
+ /* Extract one bit to represent the va selector in use. */
+ uint64_t select = sextract64(value, 36, 1);
+ ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true, false);
+ TLBIRange ret = { };
+ ARMGranuleSize gran;
+
+ page_size_granule = extract64(value, 46, 2);
+ gran = tlbi_range_tg_to_gran_size(page_size_granule);
+
+ /* The granule encoded in value must match the granule in use. */
+ if (gran != param.gran) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
+ page_size_granule);
+ return ret;
+ }
+
+ page_shift = arm_granule_bits(gran);
+ num = extract64(value, 39, 5);
+ scale = extract64(value, 44, 2);
+ exponent = (5 * scale) + 1;
+
+ ret.length = (num + 1) << (exponent + page_shift);
+
+ if (param.select) {
+ ret.base = sextract64(value, 0, 37);
+ } else {
+ ret.base = extract64(value, 0, 37);
+ }
+ if (param.ds) {
+ /*
+ * With DS=1, BaseADDR is always shifted 16 so that it is able
+ * to address all 52 va bits. The input address is perforce
+ * aligned on a 64k boundary regardless of translation granule.
+ */
+ page_shift = 16;
+ }
+ ret.base <<= page_shift;
+
+ return ret;
+}
+
+static void do_rvae_write(CPUARMState *env, uint64_t value,
+ int idxmap, bool synced)
+{
+ ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
+ TLBIRange range;
+ int bits;
+
+ range = tlbi_aa64_get_range(env, one_idx, value);
+ bits = tlbbits_for_regime(env, one_idx, range.base);
+
+ if (synced) {
+ tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
+ range.base,
+ range.length,
+ idxmap,
+ bits);
+ } else {
+ tlb_flush_range_by_mmuidx(env_cpu(env), range.base,
+ range.length, idxmap, bits);
+ }
+}
+
+static void tlbi_aa64_rvae1_write(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /*
+ * Invalidate by VA range, EL1&0.
+ * Currently handles all of RVAE1, RVAAE1, RVAALE1 and RVALE1,
+ * since we don't support flush-for-specific-ASID-only or
+ * flush-last-level-only.
+ */
+
+ do_rvae_write(env, value, vae1_tlbmask(env),
+ tlb_force_broadcast(env));
+}
+
+static void tlbi_aa64_rvae1is_write(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /*
+ * Invalidate by VA range, Inner/Outer Shareable EL1&0.
+ * Currently handles all of RVAE1IS, RVAE1OS, RVAAE1IS, RVAAE1OS,
+ * RVAALE1IS, RVAALE1OS, RVALE1IS and RVALE1OS, since we don't support
+ * flush-for-specific-ASID-only, flush-last-level-only or inner/outer
+ * shareable specific flushes.
+ */
+
+ do_rvae_write(env, value, vae1_tlbmask(env), true);
+}
+
+static void tlbi_aa64_rvae2_write(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /*
+ * Invalidate by VA range, EL2.
+ * Currently handles all of RVAE2 and RVALE2,
+ * since we don't support flush-for-specific-ASID-only or
+ * flush-last-level-only.
+ */
+
+ do_rvae_write(env, value, vae2_tlbmask(env),
+ tlb_force_broadcast(env));
+
+
+}
+
+static void tlbi_aa64_rvae2is_write(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /*
+ * Invalidate by VA range, Inner/Outer Shareable, EL2.
+ * Currently handles all of RVAE2IS, RVAE2OS, RVALE2IS and RVALE2OS,
+ * since we don't support flush-for-specific-ASID-only,
+ * flush-last-level-only or inner/outer shareable specific flushes.
+ */
+
+ do_rvae_write(env, value, vae2_tlbmask(env), true);
+
+}
+
+static void tlbi_aa64_rvae3_write(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /*
+ * Invalidate by VA range, EL3.
+ * Currently handles all of RVAE3 and RVALE3,
+ * since we don't support flush-for-specific-ASID-only or
+ * flush-last-level-only.
+ */
+
+ do_rvae_write(env, value, ARMMMUIdxBit_E3, tlb_force_broadcast(env));
+}
+
+static void tlbi_aa64_rvae3is_write(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /*
+ * Invalidate by VA range, EL3, Inner/Outer Shareable.
+ * Currently handles all of RVAE3IS, RVAE3OS, RVALE3IS and RVALE3OS,
+ * since we don't support flush-for-specific-ASID-only,
+ * flush-last-level-only or inner/outer specific flushes.
+ */
+
+ do_rvae_write(env, value, ARMMMUIdxBit_E3, true);
+}
+
+static void tlbi_aa64_ripas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ do_rvae_write(env, value, ipas2e1_tlbmask(env, value),
+ tlb_force_broadcast(env));
+}
+
+static void tlbi_aa64_ripas2e1is_write(CPUARMState *env,
+ const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ do_rvae_write(env, value, ipas2e1_tlbmask(env, value), true);
+}
+
+static const ARMCPRegInfo tlbirange_reginfo[] = {
+ { .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1,
+ .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAE1IS,
+ .writefn = tlbi_aa64_rvae1is_write },
+ { .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3,
+ .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAAE1IS,
+ .writefn = tlbi_aa64_rvae1is_write },
+ { .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5,
+ .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVALE1IS,
+ .writefn = tlbi_aa64_rvae1is_write },
+ { .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7,
+ .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAALE1IS,
+ .writefn = tlbi_aa64_rvae1is_write },
+ { .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
+ .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAE1OS,
+ .writefn = tlbi_aa64_rvae1is_write },
+ { .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3,
+ .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAAE1OS,
+ .writefn = tlbi_aa64_rvae1is_write },
+ { .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5,
+ .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVALE1OS,
+ .writefn = tlbi_aa64_rvae1is_write },
+ { .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7,
+ .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAALE1OS,
+ .writefn = tlbi_aa64_rvae1is_write },
+ { .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAE1,
+ .writefn = tlbi_aa64_rvae1_write },
+ { .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAAE1,
+ .writefn = tlbi_aa64_rvae1_write },
+ { .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVALE1,
+ .writefn = tlbi_aa64_rvae1_write },
+ { .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7,
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
+ .fgt = FGT_TLBIRVAALE1,
+ .writefn = tlbi_aa64_rvae1_write },
+ { .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_ripas2e1is_write },
+ { .name = "TLBI_RIPAS2LE1IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 6,
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_ripas2e1is_write },
+ { .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1,
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
+ .writefn = tlbi_aa64_rvae2is_write },
+ { .name = "TLBI_RVALE2IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 5,
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
+ .writefn = tlbi_aa64_rvae2is_write },
+ { .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2,
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_ripas2e1_write },
+ { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 6,
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_ripas2e1_write },
+ { .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1,
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
+ .writefn = tlbi_aa64_rvae2is_write },
+ { .name = "TLBI_RVALE2OS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 5,
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
+ .writefn = tlbi_aa64_rvae2is_write },
+ { .name = "TLBI_RVAE2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 1,
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
+ .writefn = tlbi_aa64_rvae2_write },
+ { .name = "TLBI_RVALE2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 5,
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
+ .writefn = tlbi_aa64_rvae2_write },
+ { .name = "TLBI_RVAE3IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 1,
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_rvae3is_write },
+ { .name = "TLBI_RVALE3IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 5,
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_rvae3is_write },
+ { .name = "TLBI_RVAE3OS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 1,
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_rvae3is_write },
+ { .name = "TLBI_RVALE3OS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 5,
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_rvae3is_write },
+ { .name = "TLBI_RVAE3", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 1,
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_rvae3_write },
+ { .name = "TLBI_RVALE3", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5,
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbi_aa64_rvae3_write },
+};
+#endif
+
void define_tlb_insn_regs(ARMCPU *cpu)
{
CPUARMState *env = &cpu->env;
@@ -591,4 +915,9 @@ void define_tlb_insn_regs(ARMCPU *cpu)
if (arm_feature(env, ARM_FEATURE_EL3)) {
define_arm_cp_regs(cpu, tlbi_el3_cp_reginfo);
}
+#ifdef TARGET_AARCH64
+ if (cpu_isar_feature(aa64_tlbirange, cpu)) {
+ define_arm_cp_regs(cpu, tlbirange_reginfo);
+ }
+#endif
}
Move the TLBI invalidate-range insns across to tlb-insns.c. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/cpregs.h | 2 + target/arm/helper.c | 330 +------------------------------------ target/arm/tcg/tlb-insns.c | 329 ++++++++++++++++++++++++++++++++++++ 3 files changed, 333 insertions(+), 328 deletions(-)