Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230811214031.171020-3-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
rth7680 authored and pm215 committed Aug 31, 2023
1 parent ae4acc6 commit 851ec6e
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 28 deletions.
2 changes: 2 additions & 0 deletions target/arm/cpu.h
Expand Up @@ -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. */

Expand Down
11 changes: 7 additions & 4 deletions target/arm/helper.c
Expand Up @@ -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,
Expand Down Expand Up @@ -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)) {
Expand Down
6 changes: 0 additions & 6 deletions target/arm/internals.h
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions target/arm/tcg/cpu64.c
Expand Up @@ -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;
Expand Down
46 changes: 30 additions & 16 deletions target/arm/tcg/mte_helper.c
Expand Up @@ -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,
Expand All @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions target/arm/tcg/translate-a64.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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. */
Expand Down
2 changes: 2 additions & 0 deletions target/arm/tcg/translate.h
Expand Up @@ -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 */
Expand Down

0 comments on commit 851ec6e

Please sign in to comment.