提交 851ec6eb 编写于 作者: R Richard Henderson 提交者: Peter Maydell

target/arm: Allow cpu to configure GM blocksize

Previously we hard-coded the blocksize with GMID_EL1_BS.
But the value we choose for -cpu max does not match the
value that cortex-a710 uses.

Mirror the way we handle dcz_blocksize.
Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NRichard Henderson <richard.henderson@linaro.org>
Message-id: 20230811214031.171020-3-richard.henderson@linaro.org
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 ae4acc69
......@@ -1075,6 +1075,8 @@ struct ArchCPU {
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
uint8_t dcz_blocksize;
/* GM blocksize, in log_2(words), ie low 4 bits of GMID_EL0 */
uint8_t gm_blocksize;
uint64_t rvbar_prop; /* Property/input signals. */
......
......@@ -7748,10 +7748,6 @@ static const ARMCPRegInfo mte_reginfo[] = {
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 6,
.access = PL1_RW, .accessfn = access_mte,
.fieldoffset = offsetof(CPUARMState, cp15.gcr_el1) },
{ .name = "GMID_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4,
.access = PL1_R, .accessfn = access_aa64_tid5,
.type = ARM_CP_CONST, .resetvalue = GMID_EL1_BS },
{ .name = "TCO", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
.type = ARM_CP_NO_RAW,
......@@ -9342,6 +9338,13 @@ void register_cp_regs_for_features(ARMCPU *cpu)
* then define only a RAZ/WI version of PSTATE.TCO.
*/
if (cpu_isar_feature(aa64_mte, cpu)) {
ARMCPRegInfo gmid_reginfo = {
.name = "GMID_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4,
.access = PL1_R, .accessfn = access_aa64_tid5,
.type = ARM_CP_CONST, .resetvalue = cpu->gm_blocksize,
};
define_one_arm_cp_reg(cpu, &gmid_reginfo);
define_arm_cp_regs(cpu, mte_reginfo);
define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
} else if (cpu_isar_feature(aa64_mte_insn_reg, cpu)) {
......
......@@ -1246,12 +1246,6 @@ void arm_log_exception(CPUState *cs);
#endif /* !CONFIG_USER_ONLY */
/*
* The log2 of the words in the tag block, for GMID_EL1.BS.
* The is the maximum, 256 bytes, which manipulates 64-bits of tags.
*/
#define GMID_EL1_BS 6
/*
* SVE predicates are 1/8 the size of SVE vectors, and cannot use
* the same simd_desc() encoding due to restrictions on size.
......
......@@ -868,6 +868,7 @@ void aarch64_max_tcg_initfn(Object *obj)
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
cpu->dcz_blocksize = 7; /* 512 bytes */
#endif
cpu->gm_blocksize = 6; /* 256 bytes */
cpu->sve_vq.supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
cpu->sme_vq.supported = SVE_VQ_POW2_MAP;
......
......@@ -421,46 +421,54 @@ void HELPER(st2g_stub)(CPUARMState *env, uint64_t ptr)
}
}
#define LDGM_STGM_SIZE (4 << GMID_EL1_BS)
uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
{
int mmu_idx = cpu_mmu_index(env, false);
uintptr_t ra = GETPC();
int gm_bs = env_archcpu(env)->gm_blocksize;
int gm_bs_bytes = 4 << gm_bs;
void *tag_mem;
ptr = QEMU_ALIGN_DOWN(ptr, LDGM_STGM_SIZE);
ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
/* Trap if accessing an invalid page. */
tag_mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_LOAD,
LDGM_STGM_SIZE, MMU_DATA_LOAD,
LDGM_STGM_SIZE / (2 * TAG_GRANULE), ra);
gm_bs_bytes, MMU_DATA_LOAD,
gm_bs_bytes / (2 * TAG_GRANULE), ra);
/* The tag is squashed to zero if the page does not support tags. */
if (!tag_mem) {
return 0;
}
QEMU_BUILD_BUG_ON(GMID_EL1_BS != 6);
/*
* We are loading 64-bits worth of tags. The ordering of elements
* within the word corresponds to a 64-bit little-endian operation.
* The ordering of elements within the word corresponds to
* a little-endian operation.
*/
return ldq_le_p(tag_mem);
switch (gm_bs) {
case 6:
/* 256 bytes -> 16 tags -> 64 result bits */
return ldq_le_p(tag_mem);
default:
/* cpu configured with unsupported gm blocksize. */
g_assert_not_reached();
}
}
void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
{
int mmu_idx = cpu_mmu_index(env, false);
uintptr_t ra = GETPC();
int gm_bs = env_archcpu(env)->gm_blocksize;
int gm_bs_bytes = 4 << gm_bs;
void *tag_mem;
ptr = QEMU_ALIGN_DOWN(ptr, LDGM_STGM_SIZE);
ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
/* Trap if accessing an invalid page. */
tag_mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_STORE,
LDGM_STGM_SIZE, MMU_DATA_LOAD,
LDGM_STGM_SIZE / (2 * TAG_GRANULE), ra);
gm_bs_bytes, MMU_DATA_LOAD,
gm_bs_bytes / (2 * TAG_GRANULE), ra);
/*
* Tag store only happens if the page support tags,
......@@ -470,12 +478,18 @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
return;
}
QEMU_BUILD_BUG_ON(GMID_EL1_BS != 6);
/*
* We are storing 64-bits worth of tags. The ordering of elements
* within the word corresponds to a 64-bit little-endian operation.
* The ordering of elements within the word corresponds to
* a little-endian operation.
*/
stq_le_p(tag_mem, val);
switch (gm_bs) {
case 6:
stq_le_p(tag_mem, val);
break;
default:
/* cpu configured with unsupported gm blocksize. */
g_assert_not_reached();
}
}
void HELPER(stzgm_tags)(CPUARMState *env, uint64_t ptr, uint64_t val)
......
......@@ -3786,7 +3786,7 @@ static bool trans_STGM(DisasContext *s, arg_ldst_tag *a)
gen_helper_stgm(cpu_env, addr, tcg_rt);
} else {
MMUAccessType acc = MMU_DATA_STORE;
int size = 4 << GMID_EL1_BS;
int size = 4 << s->gm_blocksize;
clean_addr = clean_data_tbi(s, addr);
tcg_gen_andi_i64(clean_addr, clean_addr, -size);
......@@ -3818,7 +3818,7 @@ static bool trans_LDGM(DisasContext *s, arg_ldst_tag *a)
gen_helper_ldgm(tcg_rt, cpu_env, addr);
} else {
MMUAccessType acc = MMU_DATA_LOAD;
int size = 4 << GMID_EL1_BS;
int size = 4 << s->gm_blocksize;
clean_addr = clean_data_tbi(s, addr);
tcg_gen_andi_i64(clean_addr, clean_addr, -size);
......@@ -13896,6 +13896,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
dc->cp_regs = arm_cpu->cp_regs;
dc->features = env->features;
dc->dcz_blocksize = arm_cpu->dcz_blocksize;
dc->gm_blocksize = arm_cpu->gm_blocksize;
#ifdef CONFIG_USER_ONLY
/* In sve_probe_page, we assume TBI is enabled. */
......
......@@ -151,6 +151,8 @@ typedef struct DisasContext {
int8_t btype;
/* A copy of cpu->dcz_blocksize. */
uint8_t dcz_blocksize;
/* A copy of cpu->gm_blocksize. */
uint8_t gm_blocksize;
/* True if this page is guarded. */
bool guarded_page;
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册