Moving performance counter/control defines into a single header file, so that software using the MIPS PMU can share the code. Signed-off-by: Deng-Cheng Zhu <dengcheng.zhu@xxxxxxxxx> --- arch/mips/include/asm/pmu.h | 78 +++++++++++++++++++++++++++++++ arch/mips/oprofile/op_model_loongson2.c | 18 +------- arch/mips/oprofile/op_model_mipsxx.c | 21 +-------- arch/mips/oprofile/op_model_rm9000.c | 16 +------ 4 files changed, 82 insertions(+), 51 deletions(-) create mode 100644 arch/mips/include/asm/pmu.h diff --git a/arch/mips/include/asm/pmu.h b/arch/mips/include/asm/pmu.h new file mode 100644 index 0000000..8d39c90 --- /dev/null +++ b/arch/mips/include/asm/pmu.h @@ -0,0 +1,78 @@ +/* + * linux/arch/mips/include/asm/pmu.h + * + * Copyright (C) 2004, 05, 06 by Ralf Baechle + * Copyright (C) 2005 by MIPS Technologies, Inc. + * Copyright (C) 2009 Lemote Inc. + * Author: Yanhua <yanh@xxxxxxxxxx> + * Author: Wu Zhangjin <wuzhangjin@xxxxxxxxx> + * Copyright (C) 2010 MIPS Technologies, Inc. + * Author: Deng-Cheng Zhu (move things from Oprofile to common place) + * + * This file is shared by Oprofile and Perf. It is also shared across the + * Oprofile implementation for different MIPS CPUs. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __MIPS_PMU_H__ +#define __MIPS_PMU_H__ + +/* mipsxx */ +#define M_CONFIG1_PC (1 << 4) + +#define M_PERFCTL_EXL (1UL << 0) +#define M_PERFCTL_KERNEL (1UL << 1) +#define M_PERFCTL_SUPERVISOR (1UL << 2) +#define M_PERFCTL_USER (1UL << 3) +#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) +#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) +#define M_PERFCTL_VPEID(vpe) ((vpe) << 16) +#define M_PERFCTL_MT_EN(filter) ((filter) << 20) +#define M_TC_EN_ALL M_PERFCTL_MT_EN(0) +#define M_TC_EN_VPE M_PERFCTL_MT_EN(1) +#define M_TC_EN_TC M_PERFCTL_MT_EN(2) +#define M_PERFCTL_TCID(tcid) ((tcid) << 22) +#define M_PERFCTL_WIDE (1UL << 30) +#define M_PERFCTL_MORE (1UL << 31) + +#define M_COUNTER_OVERFLOW (1UL << 31) + +/* rm9000 */ +#define RM9K_COUNTER1_EVENT(event) ((event) << 0) +#define RM9K_COUNTER1_SUPERVISOR (1ULL << 7) +#define RM9K_COUNTER1_KERNEL (1ULL << 8) +#define RM9K_COUNTER1_USER (1ULL << 9) +#define RM9K_COUNTER1_ENABLE (1ULL << 10) +#define RM9K_COUNTER1_OVERFLOW (1ULL << 15) + +#define RM9K_COUNTER2_EVENT(event) ((event) << 16) +#define RM9K_COUNTER2_SUPERVISOR (1ULL << 23) +#define RM9K_COUNTER2_KERNEL (1ULL << 24) +#define RM9K_COUNTER2_USER (1ULL << 25) +#define RM9K_COUNTER2_ENABLE (1ULL << 26) +#define RM9K_COUNTER2_OVERFLOW (1ULL << 31) + +extern unsigned int rm9000_perfcount_irq; + +/* loongson2 */ +#define LOONGSON2_CPU_TYPE "mips/loongson2" + +#define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31) + +#define LOONGSON2_PERFCTRL_EXL (1UL << 0) +#define LOONGSON2_PERFCTRL_KERNEL (1UL << 1) +#define LOONGSON2_PERFCTRL_SUPERVISOR (1UL << 2) +#define LOONGSON2_PERFCTRL_USER (1UL << 3) +#define LOONGSON2_PERFCTRL_ENABLE (1UL << 4) +#define LOONGSON2_PERFCTRL_EVENT(idx, event) \ + (((event) & 0x0f) << ((idx) ? 9 : 5)) + +#define read_c0_perfctrl() __read_64bit_c0_register($24, 0) +#define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val) +#define read_c0_perfcnt() __read_64bit_c0_register($25, 0) +#define write_c0_perfcnt(val) __write_64bit_c0_register($25, 0, val) + +#endif /* __MIPS_PMU_H__ */ diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c index 60d3ea6..665e994 100644 --- a/arch/mips/oprofile/op_model_loongson2.c +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -12,27 +12,11 @@ #include <linux/init.h> #include <linux/oprofile.h> #include <linux/interrupt.h> +#include <asm/pmu.h> #include <loongson.h> /* LOONGSON2_PERFCNT_IRQ */ #include "op_impl.h" -#define LOONGSON2_CPU_TYPE "mips/loongson2" - -#define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31) - -#define LOONGSON2_PERFCTRL_EXL (1UL << 0) -#define LOONGSON2_PERFCTRL_KERNEL (1UL << 1) -#define LOONGSON2_PERFCTRL_SUPERVISOR (1UL << 2) -#define LOONGSON2_PERFCTRL_USER (1UL << 3) -#define LOONGSON2_PERFCTRL_ENABLE (1UL << 4) -#define LOONGSON2_PERFCTRL_EVENT(idx, event) \ - (((event) & 0x0f) << ((idx) ? 9 : 5)) - -#define read_c0_perfctrl() __read_64bit_c0_register($24, 0) -#define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val) -#define read_c0_perfcnt() __read_64bit_c0_register($25, 0) -#define write_c0_perfcnt(val) __write_64bit_c0_register($25, 0, val) - static struct loongson2_register_config { unsigned int ctrl; unsigned long long reset_counter1; diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 54759f1..3c7c5e9 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -11,29 +11,14 @@ #include <linux/interrupt.h> #include <linux/smp.h> #include <asm/irq_regs.h> +#include <asm/pmu.h> #include "op_impl.h" -#define M_PERFCTL_EXL (1UL << 0) -#define M_PERFCTL_KERNEL (1UL << 1) -#define M_PERFCTL_SUPERVISOR (1UL << 2) -#define M_PERFCTL_USER (1UL << 3) -#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) -#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) -#define M_PERFCTL_VPEID(vpe) ((vpe) << 16) -#define M_PERFCTL_MT_EN(filter) ((filter) << 20) -#define M_TC_EN_ALL M_PERFCTL_MT_EN(0) -#define M_TC_EN_VPE M_PERFCTL_MT_EN(1) -#define M_TC_EN_TC M_PERFCTL_MT_EN(2) -#define M_PERFCTL_TCID(tcid) ((tcid) << 22) -#define M_PERFCTL_WIDE (1UL << 30) -#define M_PERFCTL_MORE (1UL << 31) - -#define M_COUNTER_OVERFLOW (1UL << 31) - static int (*save_perf_irq)(void); #ifdef CONFIG_MIPS_MT_SMP + static int cpu_has_mipsmt_pertccounters; #define WHAT (M_TC_EN_VPE | \ M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id)) @@ -242,8 +227,6 @@ static int mipsxx_perfcount_handler(void) return handled; } -#define M_CONFIG1_PC (1 << 4) - static inline int __n_counters(void) { if (!(read_c0_config1() & M_CONFIG1_PC)) diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c index 3aa8138..48e7487 100644 --- a/arch/mips/oprofile/op_model_rm9000.c +++ b/arch/mips/oprofile/op_model_rm9000.c @@ -9,24 +9,10 @@ #include <linux/oprofile.h> #include <linux/interrupt.h> #include <linux/smp.h> +#include <asm/pmu.h> #include "op_impl.h" -#define RM9K_COUNTER1_EVENT(event) ((event) << 0) -#define RM9K_COUNTER1_SUPERVISOR (1ULL << 7) -#define RM9K_COUNTER1_KERNEL (1ULL << 8) -#define RM9K_COUNTER1_USER (1ULL << 9) -#define RM9K_COUNTER1_ENABLE (1ULL << 10) -#define RM9K_COUNTER1_OVERFLOW (1ULL << 15) - -#define RM9K_COUNTER2_EVENT(event) ((event) << 16) -#define RM9K_COUNTER2_SUPERVISOR (1ULL << 23) -#define RM9K_COUNTER2_KERNEL (1ULL << 24) -#define RM9K_COUNTER2_USER (1ULL << 25) -#define RM9K_COUNTER2_ENABLE (1ULL << 26) -#define RM9K_COUNTER2_OVERFLOW (1ULL << 31) - -extern unsigned int rm9000_perfcount_irq; static struct rm9k_register_config { unsigned int control; -- 1.7.0.4