aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMadhusudan Bhat <mbhat@netlogicmicro.com>2012-10-31 08:01:27 -0400
committerJohn Crispin <blogic@openwrt.org>2012-11-09 05:37:18 -0500
commitc783390a0ecef08df5c804f8c5f647431a04f502 (patch)
tree31108a6fe38ac9f7ba0e101ee1f2c5f51068f955 /arch
parente7e333cb22e5e34e7a0792f262df52026815662e (diff)
MIPS: oprofile: Support for XLR/XLS processors
Add support for XLR and XLS processors in MIPS Oprofile code. These processors are multi-threaded and have two counters per core. Each counter can track either all the events in the core (global mode), or events in just one thread. We use the counters in the global mode, and use only the first thread in each core to handle the configuration etc. Signed-off-by: Madhusudan Bhat <mbhat@netlogicmicro.com> Signed-off-by: Jayachandran C <jchandra@broadcom.com> Patchwork: http://patchwork.linux-mips.org/patch/4471 Signed-off-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/oprofile/Makefile1
-rw-r--r--arch/mips/oprofile/common.c1
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c29
3 files changed, 31 insertions, 0 deletions
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
index 1208c280f77d..65f5237ec821 100644
--- a/arch/mips/oprofile/Makefile
+++ b/arch/mips/oprofile/Makefile
@@ -12,5 +12,6 @@ oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o
12oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o 12oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o
13oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o 13oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o
14oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o 14oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o
15oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o
15oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o 16oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o
16oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o 17oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index f80480a5a032..abd5a02f47cf 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -91,6 +91,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
91 case CPU_R10000: 91 case CPU_R10000:
92 case CPU_R12000: 92 case CPU_R12000:
93 case CPU_R14000: 93 case CPU_R14000:
94 case CPU_XLR:
94 lmodel = &op_model_mipsxx_ops; 95 lmodel = &op_model_mipsxx_ops;
95 break; 96 break;
96 97
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 28ea1a4cc576..786254630403 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -31,8 +31,22 @@
31 31
32#define M_COUNTER_OVERFLOW (1UL << 31) 32#define M_COUNTER_OVERFLOW (1UL << 31)
33 33
34/* Netlogic XLR specific, count events in all threads in a core */
35#define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13)
36
34static int (*save_perf_irq)(void); 37static int (*save_perf_irq)(void);
35 38
39/*
40 * XLR has only one set of counters per core. Designate the
41 * first hardware thread in the core for setup and init.
42 * Skip CPUs with non-zero hardware thread id (4 hwt per core)
43 */
44#ifdef CONFIG_CPU_XLR
45#define oprofile_skip_cpu(c) ((cpu_logical_map(c) & 0x3) != 0)
46#else
47#define oprofile_skip_cpu(c) 0
48#endif
49
36#ifdef CONFIG_MIPS_MT_SMP 50#ifdef CONFIG_MIPS_MT_SMP
37static int cpu_has_mipsmt_pertccounters; 51static int cpu_has_mipsmt_pertccounters;
38#define WHAT (M_TC_EN_VPE | \ 52#define WHAT (M_TC_EN_VPE | \
@@ -152,6 +166,8 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr)
152 reg.control[i] |= M_PERFCTL_USER; 166 reg.control[i] |= M_PERFCTL_USER;
153 if (ctr[i].exl) 167 if (ctr[i].exl)
154 reg.control[i] |= M_PERFCTL_EXL; 168 reg.control[i] |= M_PERFCTL_EXL;
169 if (current_cpu_type() == CPU_XLR)
170 reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS;
155 reg.counter[i] = 0x80000000 - ctr[i].count; 171 reg.counter[i] = 0x80000000 - ctr[i].count;
156 } 172 }
157} 173}
@@ -162,6 +178,9 @@ static void mipsxx_cpu_setup(void *args)
162{ 178{
163 unsigned int counters = op_model_mipsxx_ops.num_counters; 179 unsigned int counters = op_model_mipsxx_ops.num_counters;
164 180
181 if (oprofile_skip_cpu(smp_processor_id()))
182 return;
183
165 switch (counters) { 184 switch (counters) {
166 case 4: 185 case 4:
167 w_c0_perfctrl3(0); 186 w_c0_perfctrl3(0);
@@ -183,6 +202,9 @@ static void mipsxx_cpu_start(void *args)
183{ 202{
184 unsigned int counters = op_model_mipsxx_ops.num_counters; 203 unsigned int counters = op_model_mipsxx_ops.num_counters;
185 204
205 if (oprofile_skip_cpu(smp_processor_id()))
206 return;
207
186 switch (counters) { 208 switch (counters) {
187 case 4: 209 case 4:
188 w_c0_perfctrl3(WHAT | reg.control[3]); 210 w_c0_perfctrl3(WHAT | reg.control[3]);
@@ -200,6 +222,9 @@ static void mipsxx_cpu_stop(void *args)
200{ 222{
201 unsigned int counters = op_model_mipsxx_ops.num_counters; 223 unsigned int counters = op_model_mipsxx_ops.num_counters;
202 224
225 if (oprofile_skip_cpu(smp_processor_id()))
226 return;
227
203 switch (counters) { 228 switch (counters) {
204 case 4: 229 case 4:
205 w_c0_perfctrl3(0); 230 w_c0_perfctrl3(0);
@@ -372,6 +397,10 @@ static int __init mipsxx_init(void)
372 op_model_mipsxx_ops.cpu_type = "mips/loongson1"; 397 op_model_mipsxx_ops.cpu_type = "mips/loongson1";
373 break; 398 break;
374 399
400 case CPU_XLR:
401 op_model_mipsxx_ops.cpu_type = "mips/xlr";
402 break;
403
375 default: 404 default:
376 printk(KERN_ERR "Profiling unsupported for this CPU\n"); 405 printk(KERN_ERR "Profiling unsupported for this CPU\n");
377 406