Skip to content

Commit 9ddad4c

Browse files
committed
ARCv3: Add cluster PCTs driver
Driver for supporting ARCv3 cluster performance measurement unit(PMU). Examples of usage: 1. "perf list" shows a list of availabe core and cluster events. 2. "perf stat -a -e cycles,instructions,branches,NOCnumrd0,NOCnumwr0,CLNcycttl ls" 3. "perf record -a -F 250 -e CLNcycttl ls && perf report > perf.report && vi perf.report" Perf record/report works on SMP configuration but meant to be used on UP systems. On multiprocessor systems, it is impossible to determine which executable code is causing events in the cluster. So only one CPU program counter will be recorded for profiling report, and usually this CPU is 0.
1 parent da7891b commit 9ddad4c

File tree

5 files changed

+974
-1
lines changed

5 files changed

+974
-1
lines changed

arch/arc/boot/dts/skeleton_haps.dtsi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@
5858
interrupts = <20>;
5959
};
6060

61+
arcpct2: cluster_pmu {
62+
compatible = "snps,arcv3-cluster-pmu";
63+
#interrupt-cells = <1>;
64+
interrupts = <23>;
65+
};
66+
6167
virtio0: virtio@f0100000 {
6268
compatible = "virtio,mmio";
6369
reg = <0xf0100000 0x2000>;

arch/arc/boot/dts/skeleton_haps_idu.dtsi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,11 @@
6262
#interrupt-cells = <1>;
6363
interrupts = <20>;
6464
};
65+
66+
arcpct2: cluster_pmu {
67+
compatible = "snps,arcv3-cluster-pmu";
68+
#interrupt-cells = <1>;
69+
interrupts = <23>;
70+
};
6571
};
6672
};
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Linux cluster performance counters support for ARCv3.
4+
*
5+
* Copyright (C) 2023 Synopsys, Inc. (www.synopsys.com)
6+
*/
7+
8+
#ifndef __ASM_PERF_CLUSTER_EVENT_H
9+
#define __ASM_PERF_CLUSTER_EVENT_H
10+
11+
#ifndef BIT
12+
#define BIT(x) (1 << (x))
13+
#endif
14+
15+
#define CLNR_ADDR 0x640
16+
#define CLNR_DATA 0x641
17+
18+
#define SCM_AUX_CPCT_BUILD 0xC00
19+
#define SCM_AUX_CPCT_CC_NUM 0xC03
20+
#define SCM_AUX_CPCT_CC_NAME0 0xC04
21+
#define SCM_AUX_CPCT_CC_NAME1 0xC05
22+
#define SCM_AUX_CPCT_CC_NAME2 0xC06
23+
#define SCM_AUX_CPCT_CC_NAME3 0xC07
24+
#define SCM_AUX_CPCT_CONTROL 0xC08
25+
#define SCM_AUX_CPCT_INT_CTRL 0xC09
26+
#define SCM_AUX_CPCT_INT_ACT 0xC0A
27+
// next registers are one per counter:
28+
#define SCM_AUX_CPCT_N_CONFIG 0xD00
29+
#define SCM_AUX_CPCT_COUNTL 0xD02
30+
#define SCM_AUX_CPCT_COUNTH 0xD03
31+
#define SCM_AUX_CPCT_N_SNAPL 0xD04
32+
#define SCM_AUX_CPCT_N_SNAPH 0xD05
33+
#define SCM_AUX_CPCT_INT_CNTL 0xD06
34+
#define SCM_AUX_CPCT_INT_CNTH 0xD07
35+
36+
#define ARC_CLUSTER_PERF_MAX_COUNTERS 32
37+
38+
struct cpct_build {
39+
#ifdef CONFIG_CPU_BIG_ENDIAN
40+
u32 res2:8, num_ctrs:8, res1:4, i:2, cs:2, ver:8;
41+
#else
42+
u32 ver:8, cs:2, i:2, res1:4, num_ctrs:8, res2:8;
43+
#endif
44+
};
45+
46+
struct cpct_cc_num {
47+
#ifdef CONFIG_CPU_BIG_ENDIAN
48+
u32 res:17, cc_num:15;
49+
#else
50+
u32 cc_num:15, res:17;
51+
#endif
52+
};
53+
54+
#define CPCT_NAME_SZ (16+1) // +1 zero
55+
#pragma pack(push, 1)
56+
union cpct_cc_name{
57+
s8 cc[CPCT_NAME_SZ];
58+
u32 uu[4];
59+
};
60+
#pragma pack(pop)
61+
62+
struct cpct_control {
63+
#ifdef CONFIG_CPU_BIG_ENDIAN
64+
u32 res2:14, sn:1, cc:1, res0:15, en:1;
65+
#else
66+
u32 en:1, res0:15, cc:1, sn:1, res2:14;
67+
#endif
68+
};
69+
70+
struct cpct_int_cntrl {
71+
u32 int_ctrl;
72+
};
73+
74+
struct cpct_int_act {
75+
u32 int_act;
76+
};
77+
78+
struct cpct_n_config {
79+
union{
80+
struct{
81+
#ifdef CONFIG_CPU_BIG_ENDIAN
82+
u32 lce:1, len:1, res:12, lsn:1, lcc:1, cc_num:16;
83+
#else
84+
u32 cc_num:16, lcc:1, lsn:1, res:12, len:1, lce:1;
85+
#endif
86+
};
87+
u32 val;
88+
};
89+
};
90+
91+
struct cpct_count {
92+
u32 count;
93+
};
94+
95+
struct cpct_snap {
96+
u32 snap;
97+
};
98+
99+
struct cpct_int_count {
100+
u32 int_cnt;
101+
};
102+
103+
// Events map
104+
#define MAX_CONDITIONS_NUMBER 0x800 // We can't get the maximum event number from any build in registers, thats why
105+
// we need to scan all possible walues up to MAX_CONDITIONS_NUMBER
106+
107+
struct cpct_conditions_entry {
108+
u32 cc_number;
109+
union cpct_cc_name name;
110+
};
111+
112+
#endif

arch/arc/kernel/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o
2525
obj-$(CONFIG_ARC_EMUL_UNALIGNED) += unaligned.o
2626
obj-$(CONFIG_KGDB) += kgdb.o
2727
obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o
28-
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
28+
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cluster.o
2929
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
3030

3131
obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o

0 commit comments

Comments
 (0)