mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 06:01:23 +00:00
ARC: perf: Add some comments/debug stuff
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
parent
03c94fcf95
commit
bde80c237e
2 changed files with 37 additions and 34 deletions
|
@ -57,26 +57,7 @@ struct arc_reg_cc_build {
|
||||||
#define PERF_COUNT_ARC_HW_MAX (PERF_COUNT_HW_MAX + 6)
|
#define PERF_COUNT_ARC_HW_MAX (PERF_COUNT_HW_MAX + 6)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The "generalized" performance events seem to really be a copy
|
* Some ARC pct quirks:
|
||||||
* of the available events on x86 processors; the mapping to ARC
|
|
||||||
* events is not always possible 1-to-1. Fortunately, there doesn't
|
|
||||||
* seem to be an exact definition for these events, so we can cheat
|
|
||||||
* a bit where necessary.
|
|
||||||
*
|
|
||||||
* In particular, the following PERF events may behave a bit differently
|
|
||||||
* compared to other architectures:
|
|
||||||
*
|
|
||||||
* PERF_COUNT_HW_CPU_CYCLES
|
|
||||||
* Cycles not in halted state
|
|
||||||
*
|
|
||||||
* PERF_COUNT_HW_REF_CPU_CYCLES
|
|
||||||
* Reference cycles not in halted state, same as PERF_COUNT_HW_CPU_CYCLES
|
|
||||||
* for now as we don't do Dynamic Voltage/Frequency Scaling (yet)
|
|
||||||
*
|
|
||||||
* PERF_COUNT_HW_BUS_CYCLES
|
|
||||||
* Unclear what this means, Intel uses 0x013c, which according to
|
|
||||||
* their datasheet means "unhalted reference cycles". It sounds similar
|
|
||||||
* to PERF_COUNT_HW_REF_CPU_CYCLES, and we use the same counter for it.
|
|
||||||
*
|
*
|
||||||
* PERF_COUNT_HW_STALLED_CYCLES_BACKEND
|
* PERF_COUNT_HW_STALLED_CYCLES_BACKEND
|
||||||
* PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
|
* PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
|
||||||
|
@ -91,21 +72,35 @@ struct arc_reg_cc_build {
|
||||||
* Note that I$ cache misses aren't counted by either of the two!
|
* Note that I$ cache misses aren't counted by either of the two!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ARC PCT has hardware conditions with fixed "names" but variable "indexes"
|
||||||
|
* (based on a specific RTL build)
|
||||||
|
* Below is the static map between perf generic/arc specific event_id and
|
||||||
|
* h/w condition names.
|
||||||
|
* At the time of probe, we loop thru each index and find it's name to
|
||||||
|
* complete the mapping of perf event_id to h/w index as latter is needed
|
||||||
|
* to program the counter really
|
||||||
|
*/
|
||||||
static const char * const arc_pmu_ev_hw_map[] = {
|
static const char * const arc_pmu_ev_hw_map[] = {
|
||||||
|
/* count cycles */
|
||||||
[PERF_COUNT_HW_CPU_CYCLES] = "crun",
|
[PERF_COUNT_HW_CPU_CYCLES] = "crun",
|
||||||
[PERF_COUNT_HW_REF_CPU_CYCLES] = "crun",
|
[PERF_COUNT_HW_REF_CPU_CYCLES] = "crun",
|
||||||
[PERF_COUNT_HW_BUS_CYCLES] = "crun",
|
[PERF_COUNT_HW_BUS_CYCLES] = "crun",
|
||||||
[PERF_COUNT_HW_INSTRUCTIONS] = "iall",
|
|
||||||
[PERF_COUNT_HW_BRANCH_MISSES] = "bpfail",
|
|
||||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp",
|
|
||||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "bflush",
|
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "bflush",
|
||||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "bstall",
|
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "bstall",
|
||||||
[PERF_COUNT_ARC_DCLM] = "dclm",
|
|
||||||
[PERF_COUNT_ARC_DCSM] = "dcsm",
|
/* counts condition */
|
||||||
[PERF_COUNT_ARC_ICM] = "icm",
|
[PERF_COUNT_HW_INSTRUCTIONS] = "iall",
|
||||||
[PERF_COUNT_ARC_BPOK] = "bpok",
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp",
|
||||||
[PERF_COUNT_ARC_EDTLB] = "edtlb",
|
[PERF_COUNT_ARC_BPOK] = "bpok", /* NP-NT, PT-T, PNT-NT */
|
||||||
[PERF_COUNT_ARC_EITLB] = "eitlb",
|
[PERF_COUNT_HW_BRANCH_MISSES] = "bpfail", /* NP-T, PT-NT, PNT-T */
|
||||||
|
|
||||||
|
[PERF_COUNT_ARC_DCLM] = "dclm", /* D-cache Load Miss */
|
||||||
|
[PERF_COUNT_ARC_DCSM] = "dcsm", /* D-cache Store Miss */
|
||||||
|
[PERF_COUNT_ARC_ICM] = "icm", /* I-cache Miss */
|
||||||
|
[PERF_COUNT_ARC_EDTLB] = "edtlb", /* D-TLB Miss */
|
||||||
|
[PERF_COUNT_ARC_EITLB] = "eitlb", /* I-TLB Miss */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define C(_x) PERF_COUNT_HW_CACHE_##_x
|
#define C(_x) PERF_COUNT_HW_CACHE_##_x
|
||||||
|
|
|
@ -90,6 +90,10 @@ static int arc_pmu_cache_event(u64 config)
|
||||||
if (ret == CACHE_OP_UNSUPPORTED)
|
if (ret == CACHE_OP_UNSUPPORTED)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
|
pr_debug("init cache event: type/op/result %d/%d/%d with h/w %d \'%s\'\n",
|
||||||
|
cache_type, cache_op, cache_result, ret,
|
||||||
|
arc_pmu_ev_hw_map[ret]);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +110,9 @@ static int arc_pmu_event_init(struct perf_event *event)
|
||||||
if (arc_pmu->ev_hw_idx[event->attr.config] < 0)
|
if (arc_pmu->ev_hw_idx[event->attr.config] < 0)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
hwc->config = arc_pmu->ev_hw_idx[event->attr.config];
|
hwc->config = arc_pmu->ev_hw_idx[event->attr.config];
|
||||||
pr_debug("initializing event %d with cfg %d\n",
|
pr_debug("init event %d with h/w %d \'%s\'\n",
|
||||||
(int) event->attr.config, (int) hwc->config);
|
(int) event->attr.config, (int) hwc->config,
|
||||||
|
arc_pmu_ev_hw_map[event->attr.config]);
|
||||||
return 0;
|
return 0;
|
||||||
case PERF_TYPE_HW_CACHE:
|
case PERF_TYPE_HW_CACHE:
|
||||||
ret = arc_pmu_cache_event(event->attr.config);
|
ret = arc_pmu_cache_event(event->attr.config);
|
||||||
|
@ -260,19 +265,22 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
|
||||||
arc_pmu->n_counters, arc_pmu->counter_size, cc_bcr.c);
|
arc_pmu->n_counters, arc_pmu->counter_size, cc_bcr.c);
|
||||||
|
|
||||||
cc_name.str[8] = 0;
|
cc_name.str[8] = 0;
|
||||||
for (i = 0; i < PERF_COUNT_HW_MAX; i++)
|
for (i = 0; i < PERF_COUNT_ARC_HW_MAX; i++)
|
||||||
arc_pmu->ev_hw_idx[i] = -1;
|
arc_pmu->ev_hw_idx[i] = -1;
|
||||||
|
|
||||||
|
/* loop thru all available h/w condition indexes */
|
||||||
for (j = 0; j < cc_bcr.c; j++) {
|
for (j = 0; j < cc_bcr.c; j++) {
|
||||||
write_aux_reg(ARC_REG_CC_INDEX, j);
|
write_aux_reg(ARC_REG_CC_INDEX, j);
|
||||||
cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0);
|
cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0);
|
||||||
cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1);
|
cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1);
|
||||||
|
|
||||||
|
/* See if it has been mapped to a perf event_id */
|
||||||
for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) {
|
for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) {
|
||||||
if (arc_pmu_ev_hw_map[i] &&
|
if (arc_pmu_ev_hw_map[i] &&
|
||||||
!strcmp(arc_pmu_ev_hw_map[i], cc_name.str) &&
|
!strcmp(arc_pmu_ev_hw_map[i], cc_name.str) &&
|
||||||
strlen(arc_pmu_ev_hw_map[i])) {
|
strlen(arc_pmu_ev_hw_map[i])) {
|
||||||
pr_debug("mapping %d to idx %d with name %s\n",
|
pr_debug("mapping perf event %2d to h/w event \'%8s\' (idx %d)\n",
|
||||||
i, j, cc_name.str);
|
i, cc_name.str, j);
|
||||||
arc_pmu->ev_hw_idx[i] = j;
|
arc_pmu->ev_hw_idx[i] = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue