mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 13:35:35 +00:00
target/arm: Don't clear supported PMU events when initializing PMCEID1
A bug was introduced during a respin of: commit 57a4a11b2b281bb548b419ca81bfafb214e4c77a target/arm: Add array for supported PMU events, generate PMCEID[01]_EL0 This patch introduced two calls to get_pmceid() during CPU initialization - one each for PMCEID0 and PMCEID1. In addition to building the register values, get_pmceid() clears an internal array mapping event numbers to their implementations (supported_event_map) before rebuilding it. This is an optimization since much of the logic is shared. However, since it was called twice, the contents of supported_event_map reflect only the events in PMCEID1 (the second call to get_pmceid()). Fix this bug by moving the initialization of PMCEID0 and PMCEID1 back into a single function call, and name it more appropriately since it is doing more than simply generating the contents of the PMCEID[01] registers. Backports commit bf8d09694ccc07487cd73d7562081fdaec3370c8 from qemu
This commit is contained in:
parent
3fa54df972
commit
8d7bb2cab3
|
@ -3337,7 +3337,7 @@
|
||||||
#define fp_exception_el fp_exception_el_aarch64
|
#define fp_exception_el fp_exception_el_aarch64
|
||||||
#define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64
|
#define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64
|
||||||
#define gen_cmtst_i64 gen_cmtst_i64_aarch64
|
#define gen_cmtst_i64 gen_cmtst_i64_aarch64
|
||||||
#define get_pmceid get_pmceid_aarch64
|
#define pmu_init pmu_init_aarch64
|
||||||
#define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64
|
#define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64
|
||||||
#define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64
|
#define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64
|
||||||
#define helper_advsimd_add2h helper_advsimd_add2h_aarch64
|
#define helper_advsimd_add2h helper_advsimd_add2h_aarch64
|
||||||
|
|
|
@ -3337,7 +3337,7 @@
|
||||||
#define fp_exception_el fp_exception_el_aarch64eb
|
#define fp_exception_el fp_exception_el_aarch64eb
|
||||||
#define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64eb
|
#define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64eb
|
||||||
#define gen_cmtst_i64 gen_cmtst_i64_aarch64eb
|
#define gen_cmtst_i64 gen_cmtst_i64_aarch64eb
|
||||||
#define get_pmceid get_pmceid_aarch64eb
|
#define pmu_init pmu_init_aarch64eb
|
||||||
#define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64eb
|
#define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64eb
|
||||||
#define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64eb
|
#define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64eb
|
||||||
#define helper_advsimd_add2h helper_advsimd_add2h_aarch64eb
|
#define helper_advsimd_add2h helper_advsimd_add2h_aarch64eb
|
||||||
|
|
|
@ -3322,7 +3322,7 @@
|
||||||
#define cmtst_op cmtst_op_arm
|
#define cmtst_op cmtst_op_arm
|
||||||
#define fp_exception_el fp_exception_el_arm
|
#define fp_exception_el fp_exception_el_arm
|
||||||
#define gen_cmtst_i64 gen_cmtst_i64_arm
|
#define gen_cmtst_i64 gen_cmtst_i64_arm
|
||||||
#define get_pmceid get_pmceid_arm
|
#define pmu_init pmu_init_arm
|
||||||
#define mla_op mla_op_arm
|
#define mla_op mla_op_arm
|
||||||
#define mls_op mls_op_arm
|
#define mls_op mls_op_arm
|
||||||
#define pmccntr_op_start pmccntr_op_start_arm
|
#define pmccntr_op_start pmccntr_op_start_arm
|
||||||
|
|
|
@ -3322,7 +3322,7 @@
|
||||||
#define cmtst_op cmtst_op_armeb
|
#define cmtst_op cmtst_op_armeb
|
||||||
#define fp_exception_el fp_exception_el_armeb
|
#define fp_exception_el fp_exception_el_armeb
|
||||||
#define gen_cmtst_i64 gen_cmtst_i64_armeb
|
#define gen_cmtst_i64 gen_cmtst_i64_armeb
|
||||||
#define get_pmceid get_pmceid_armeb
|
#define pmu_init pmu_init_armeb
|
||||||
#define mla_op mla_op_armeb
|
#define mla_op mla_op_armeb
|
||||||
#define mls_op mls_op_armeb
|
#define mls_op mls_op_armeb
|
||||||
#define pmccntr_op_start pmccntr_op_start_armeb
|
#define pmccntr_op_start pmccntr_op_start_armeb
|
||||||
|
|
|
@ -3331,7 +3331,7 @@ arm_symbols = (
|
||||||
'cmtst_op',
|
'cmtst_op',
|
||||||
'fp_exception_el',
|
'fp_exception_el',
|
||||||
'gen_cmtst_i64',
|
'gen_cmtst_i64',
|
||||||
'get_pmceid',
|
'pmu_init',
|
||||||
'mla_op',
|
'mla_op',
|
||||||
'mls_op',
|
'mls_op',
|
||||||
'pmccntr_op_start',
|
'pmccntr_op_start',
|
||||||
|
@ -3383,7 +3383,7 @@ aarch64_symbols = (
|
||||||
'fp_exception_el',
|
'fp_exception_el',
|
||||||
'gen_a64_set_pc_im',
|
'gen_a64_set_pc_im',
|
||||||
'gen_cmtst_i64',
|
'gen_cmtst_i64',
|
||||||
'get_pmceid',
|
'pmu_init',
|
||||||
'helper_advsimd_acge_f16',
|
'helper_advsimd_acge_f16',
|
||||||
'helper_advsimd_acgt_f16',
|
'helper_advsimd_acgt_f16',
|
||||||
'helper_advsimd_add2h',
|
'helper_advsimd_add2h',
|
||||||
|
|
|
@ -764,8 +764,7 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arm_feature(env, ARM_FEATURE_PMU)) {
|
if (arm_feature(env, ARM_FEATURE_PMU)) {
|
||||||
cpu->pmceid0 = get_pmceid(&cpu->env, 0);
|
pmu_init(cpu);
|
||||||
cpu->pmceid1 = get_pmceid(&cpu->env, 1);
|
|
||||||
|
|
||||||
arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
|
arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
|
||||||
arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
|
arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
|
||||||
|
|
|
@ -964,14 +964,13 @@ void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
|
||||||
void pmu_post_el_change(ARMCPU *cpu, void *ignored);
|
void pmu_post_el_change(ARMCPU *cpu, void *ignored);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_pmceid
|
* pmu_init
|
||||||
* @env: CPUARMState
|
* @cpu: ARMCPU
|
||||||
* @which: which PMCEID register to return (0 or 1)
|
|
||||||
*
|
*
|
||||||
* Return the PMCEID[01]_EL0 register values corresponding to the counters
|
* Initialize the CPU's PMCEID[01]_EL0 registers and associated internal state
|
||||||
* which are supported given the current configuration
|
* for the current configuration
|
||||||
*/
|
*/
|
||||||
uint64_t get_pmceid(CPUARMState *env, unsigned which);
|
void pmu_init(ARMCPU *cpu);
|
||||||
|
|
||||||
/* SCTLR bit meanings. Several bits have been reused in newer
|
/* SCTLR bit meanings. Several bits have been reused in newer
|
||||||
* versions of the architecture; in that case we define constants
|
* versions of the architecture; in that case we define constants
|
||||||
|
|
|
@ -952,22 +952,24 @@ static const pm_event pm_events[] = {
|
||||||
#define UNSUPPORTED_EVENT UINT16_MAX
|
#define UNSUPPORTED_EVENT UINT16_MAX
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called upon initialization to build PMCEID0_EL0 or PMCEID1_EL0 (indicated by
|
* Called upon CPU initialization to initialize PMCEID[01]_EL0 and build a map
|
||||||
* 'which'). We also use it to build a map of ARM event numbers to indices in
|
* of ARM event numbers to indices in our pm_events array.
|
||||||
* our pm_events array.
|
|
||||||
*
|
*
|
||||||
* Note: Events in the 0x40XX range are not currently supported.
|
* Note: Events in the 0x40XX range are not currently supported.
|
||||||
*/
|
*/
|
||||||
uint64_t get_pmceid(CPUARMState *env, unsigned which)
|
void pmu_init(ARMCPU *cpu)
|
||||||
{
|
{
|
||||||
uint64_t pmceid = 0;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
assert(which <= 1);
|
/*
|
||||||
|
* Empty supported_event_map and cpu->pmceid[01] before adding supported
|
||||||
for (i = 0; i < ARRAY_SIZE(env->supported_event_map); i++) {
|
* events to them
|
||||||
env->supported_event_map[i] = UNSUPPORTED_EVENT;
|
*/
|
||||||
|
for (i = 0; i < ARRAY_SIZE(cpu->env.supported_event_map); i++) {
|
||||||
|
cpu->env.supported_event_map[i] = UNSUPPORTED_EVENT;
|
||||||
}
|
}
|
||||||
|
cpu->pmceid0 = 0;
|
||||||
|
cpu->pmceid1 = 0;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(pm_events); i++) {
|
for (i = 0; i < ARRAY_SIZE(pm_events); i++) {
|
||||||
const pm_event *cnt = &pm_events[i];
|
const pm_event *cnt = &pm_events[i];
|
||||||
|
@ -975,13 +977,16 @@ uint64_t get_pmceid(CPUARMState *env, unsigned which)
|
||||||
/* We do not currently support events in the 0x40xx range */
|
/* We do not currently support events in the 0x40xx range */
|
||||||
assert(cnt->number <= 0x3f);
|
assert(cnt->number <= 0x3f);
|
||||||
|
|
||||||
if ((cnt->number & 0x20) == (which << 6) &&
|
if (cnt->supported(&cpu->env)) {
|
||||||
cnt->supported(env)) {
|
cpu->env.supported_event_map[cnt->number] = i;
|
||||||
pmceid |= (1 << (cnt->number & 0x1f));
|
uint64_t event_mask = 1 << (cnt->number & 0x1f);
|
||||||
env->supported_event_map[cnt->number] = i;
|
if (cnt->number & 0x20) {
|
||||||
|
cpu->pmceid1 |= event_mask;
|
||||||
|
} else {
|
||||||
|
cpu->pmceid0 |= event_mask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pmceid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue