Re: [PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-08-07 Thread Arnaldo Carvalho de Melo
Em Fri, Aug 07, 2015 at 03:03:02PM +0300, Max Filippov escreveu:
> On Fri, Aug 7, 2015 at 12:13 PM, Peter Zijlstra  wrote:
> > On Thu, Aug 06, 2015 at 04:46:32PM -0300, Arnaldo Carvalho de Melo wrote:
> >> Em Sat, Jul 18, 2015 at 11:30:10AM +0300, Max Filippov escreveu:
> >> > Xtensa Performance Monitor Module has up to 8 32 bit wide performance
> >> > counters. Each counter may be enabled independently and can count any

> >> Has this gone via PeterZ? I added the tools/ bits in my perf/core
> >> branch, will go in next pull req,

> > I was thinking it would go through the xtensa tree. Looks fine at a
> > quick glance and they can actually test it.
 
> Right, had the same idea.

Ok, when you do that, i.e. get the kernel bits in, the tooling part will
be there, as it was already pulled by Ingo, i.e. its in tip.git and thus
should hit 4.3.

- ARnaldo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-08-07 Thread Max Filippov
On Fri, Aug 7, 2015 at 12:13 PM, Peter Zijlstra  wrote:
> On Thu, Aug 06, 2015 at 04:46:32PM -0300, Arnaldo Carvalho de Melo wrote:
>> Em Sat, Jul 18, 2015 at 11:30:10AM +0300, Max Filippov escreveu:
>> > Xtensa Performance Monitor Module has up to 8 32 bit wide performance
>> > counters. Each counter may be enabled independently and can count any
>> > single type of hardware performance events. Event counting may be enabled
>> > and disabled globally (per PMM).
>> > Each counter has status register with bits indicating if the counter has
>> > been overflown and may be programmed to raise profiling IRQ on overflow.
>> > This IRQ is used to rewind counters and allow for counting more than 2^32
>> > samples for counting events and to report samples for sampling events.
>> >
>> > For more details see Tensilica Debug User's Guide, chapter 8
>> > "Performance monitor module".
>>
>> Has this gone via PeterZ? I added the tools/ bits in my perf/core
>> branch, will go in next pull req,
>
> I was thinking it would go through the xtensa tree. Looks fine at a
> quick glance and they can actually test it.

Right, had the same idea.

-- 
Thanks.
-- Max
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-08-07 Thread Peter Zijlstra
On Thu, Aug 06, 2015 at 04:46:32PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Sat, Jul 18, 2015 at 11:30:10AM +0300, Max Filippov escreveu:
> > Xtensa Performance Monitor Module has up to 8 32 bit wide performance
> > counters. Each counter may be enabled independently and can count any
> > single type of hardware performance events. Event counting may be enabled
> > and disabled globally (per PMM).
> > Each counter has status register with bits indicating if the counter has
> > been overflown and may be programmed to raise profiling IRQ on overflow.
> > This IRQ is used to rewind counters and allow for counting more than 2^32
> > samples for counting events and to report samples for sampling events.
> > 
> > For more details see Tensilica Debug User's Guide, chapter 8
> > "Performance monitor module".
> 
> Has this gone via PeterZ? I added the tools/ bits in my perf/core
> branch, will go in next pull req,

I was thinking it would go through the xtensa tree. Looks fine at a
quick glance and they can actually test it.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-08-07 Thread Arnaldo Carvalho de Melo
Em Fri, Aug 07, 2015 at 03:03:02PM +0300, Max Filippov escreveu:
 On Fri, Aug 7, 2015 at 12:13 PM, Peter Zijlstra pet...@infradead.org wrote:
  On Thu, Aug 06, 2015 at 04:46:32PM -0300, Arnaldo Carvalho de Melo wrote:
  Em Sat, Jul 18, 2015 at 11:30:10AM +0300, Max Filippov escreveu:
   Xtensa Performance Monitor Module has up to 8 32 bit wide performance
   counters. Each counter may be enabled independently and can count any

  Has this gone via PeterZ? I added the tools/ bits in my perf/core
  branch, will go in next pull req,

  I was thinking it would go through the xtensa tree. Looks fine at a
  quick glance and they can actually test it.
 
 Right, had the same idea.

Ok, when you do that, i.e. get the kernel bits in, the tooling part will
be there, as it was already pulled by Ingo, i.e. its in tip.git and thus
should hit 4.3.

- ARnaldo
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-08-07 Thread Peter Zijlstra
On Thu, Aug 06, 2015 at 04:46:32PM -0300, Arnaldo Carvalho de Melo wrote:
 Em Sat, Jul 18, 2015 at 11:30:10AM +0300, Max Filippov escreveu:
  Xtensa Performance Monitor Module has up to 8 32 bit wide performance
  counters. Each counter may be enabled independently and can count any
  single type of hardware performance events. Event counting may be enabled
  and disabled globally (per PMM).
  Each counter has status register with bits indicating if the counter has
  been overflown and may be programmed to raise profiling IRQ on overflow.
  This IRQ is used to rewind counters and allow for counting more than 2^32
  samples for counting events and to report samples for sampling events.
  
  For more details see Tensilica Debug User's Guide, chapter 8
  Performance monitor module.
 
 Has this gone via PeterZ? I added the tools/ bits in my perf/core
 branch, will go in next pull req,

I was thinking it would go through the xtensa tree. Looks fine at a
quick glance and they can actually test it.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-08-07 Thread Max Filippov
On Fri, Aug 7, 2015 at 12:13 PM, Peter Zijlstra pet...@infradead.org wrote:
 On Thu, Aug 06, 2015 at 04:46:32PM -0300, Arnaldo Carvalho de Melo wrote:
 Em Sat, Jul 18, 2015 at 11:30:10AM +0300, Max Filippov escreveu:
  Xtensa Performance Monitor Module has up to 8 32 bit wide performance
  counters. Each counter may be enabled independently and can count any
  single type of hardware performance events. Event counting may be enabled
  and disabled globally (per PMM).
  Each counter has status register with bits indicating if the counter has
  been overflown and may be programmed to raise profiling IRQ on overflow.
  This IRQ is used to rewind counters and allow for counting more than 2^32
  samples for counting events and to report samples for sampling events.
 
  For more details see Tensilica Debug User's Guide, chapter 8
  Performance monitor module.

 Has this gone via PeterZ? I added the tools/ bits in my perf/core
 branch, will go in next pull req,

 I was thinking it would go through the xtensa tree. Looks fine at a
 quick glance and they can actually test it.

Right, had the same idea.

-- 
Thanks.
-- Max
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-08-06 Thread Arnaldo Carvalho de Melo
Em Sat, Jul 18, 2015 at 11:30:10AM +0300, Max Filippov escreveu:
> Xtensa Performance Monitor Module has up to 8 32 bit wide performance
> counters. Each counter may be enabled independently and can count any
> single type of hardware performance events. Event counting may be enabled
> and disabled globally (per PMM).
> Each counter has status register with bits indicating if the counter has
> been overflown and may be programmed to raise profiling IRQ on overflow.
> This IRQ is used to rewind counters and allow for counting more than 2^32
> samples for counting events and to report samples for sampling events.
> 
> For more details see Tensilica Debug User's Guide, chapter 8
> "Performance monitor module".

Has this gone via PeterZ? I added the tools/ bits in my perf/core
branch, will go in next pull req,

- Arnaldo
 
> Cc: Peter Zijlstra 
> Cc: Paul Mackerras 
> Cc: Ingo Molnar 
> Cc: Arnaldo Carvalho de Melo 
> Signed-off-by: Max Filippov 
> ---
> Changes v1->v2:
> - use -EINVAL instead of -ENOENT for invalid PMU event configuratons.
> 
>  arch/xtensa/Kconfig |  10 +
>  arch/xtensa/kernel/Makefile |   1 +
>  arch/xtensa/kernel/perf_event.c | 450 
> 
>  3 files changed, 461 insertions(+)
>  create mode 100644 arch/xtensa/kernel/perf_event.c
> 
> diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
> index 3c57934..0e92885 100644
> --- a/arch/xtensa/Kconfig
> +++ b/arch/xtensa/Kconfig
> @@ -126,6 +126,16 @@ config XTENSA_VARIANT_MMU
> Build a Conventional Kernel with full MMU support,
> ie: it supports a TLB with auto-loading, page protection.
>  
> +config XTENSA_VARIANT_HAVE_PERF_EVENTS
> + bool "Core variant has Performance Monitor Module"
> + depends on XTENSA_VARIANT_CUSTOM
> + default n
> + help
> +   Enable if core variant has Performance Monitor Module with
> +   External Registers Interface.
> +
> +   If unsure, say N.
> +
>  config XTENSA_UNALIGNED_USER
>   bool "Unaligned memory access in use space"
>   help
> diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
> index d3a0f0f..547a757 100644
> --- a/arch/xtensa/kernel/Makefile
> +++ b/arch/xtensa/kernel/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_PCI) += pci.o
>  obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
>  obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
>  obj-$(CONFIG_SMP) += smp.o mxhead.o
> +obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o
>  
>  AFLAGS_head.o += -mtext-section-literals
>  
> diff --git a/arch/xtensa/kernel/perf_event.c b/arch/xtensa/kernel/perf_event.c
> new file mode 100644
> index 000..b44df3c
> --- /dev/null
> +++ b/arch/xtensa/kernel/perf_event.c
> @@ -0,0 +1,450 @@
> +/*
> + * Xtensa Performance Monitor Module driver
> + * See Tensilica Debug User's Guide for PMU registers documentation.
> + *
> + * Copyright (C) 2015 Cadence Design Systems Inc.
> + *
> + * 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.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +
> +/* Global control/status for all perf counters */
> +#define XTENSA_PMU_PMG   0x1000
> +/* Perf counter values */
> +#define XTENSA_PMU_PM(i) (0x1080 + (i) * 4)
> +/* Perf counter control registers */
> +#define XTENSA_PMU_PMCTRL(i) (0x1100 + (i) * 4)
> +/* Perf counter status registers */
> +#define XTENSA_PMU_PMSTAT(i) (0x1180 + (i) * 4)
> +
> +#define XTENSA_PMU_PMG_PMEN  0x1
> +
> +#define XTENSA_PMU_COUNTER_MASK  0xULL
> +#define XTENSA_PMU_COUNTER_MAX   0x7fff
> +
> +#define XTENSA_PMU_PMCTRL_INTEN  0x0001
> +#define XTENSA_PMU_PMCTRL_KRNLCNT0x0008
> +#define XTENSA_PMU_PMCTRL_TRACELEVEL 0x00f0
> +#define XTENSA_PMU_PMCTRL_SELECT_SHIFT   8
> +#define XTENSA_PMU_PMCTRL_SELECT 0x1f00
> +#define XTENSA_PMU_PMCTRL_MASK_SHIFT 16
> +#define XTENSA_PMU_PMCTRL_MASK   0x
> +
> +#define XTENSA_PMU_MASK(select, mask) \
> + (((select) << XTENSA_PMU_PMCTRL_SELECT_SHIFT) | \
> +  ((mask) << XTENSA_PMU_PMCTRL_MASK_SHIFT) | \
> +  XTENSA_PMU_PMCTRL_TRACELEVEL | \
> +  XTENSA_PMU_PMCTRL_INTEN)
> +
> +#define XTENSA_PMU_PMSTAT_OVFL   0x0001
> +#define XTENSA_PMU_PMSTAT_INTASRT0x0010
> +
> +struct xtensa_pmu_events {
> + /* Array of events currently on this core */
> + struct perf_event *event[XCHAL_NUM_PERF_COUNTERS];
> + /* Bitmap of used hardware counters */
> + unsigned long used_mask[BITS_TO_LONGS(XCHAL_NUM_PERF_COUNTERS)];
> +};
> +static DEFINE_PER_CPU(struct xtensa_pmu_events, xtensa_pmu_events);
> +
> +static const u32 xtensa_hw_ctl[] = {
> + [PERF_COUNT_HW_CPU_CYCLES]  = XTENSA_PMU_MASK(0, 

Re: [PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-08-06 Thread Arnaldo Carvalho de Melo
Em Sat, Jul 18, 2015 at 11:30:10AM +0300, Max Filippov escreveu:
 Xtensa Performance Monitor Module has up to 8 32 bit wide performance
 counters. Each counter may be enabled independently and can count any
 single type of hardware performance events. Event counting may be enabled
 and disabled globally (per PMM).
 Each counter has status register with bits indicating if the counter has
 been overflown and may be programmed to raise profiling IRQ on overflow.
 This IRQ is used to rewind counters and allow for counting more than 2^32
 samples for counting events and to report samples for sampling events.
 
 For more details see Tensilica Debug User's Guide, chapter 8
 Performance monitor module.

Has this gone via PeterZ? I added the tools/ bits in my perf/core
branch, will go in next pull req,

- Arnaldo
 
 Cc: Peter Zijlstra a.p.zijls...@chello.nl
 Cc: Paul Mackerras pau...@samba.org
 Cc: Ingo Molnar mi...@redhat.com
 Cc: Arnaldo Carvalho de Melo a...@kernel.org
 Signed-off-by: Max Filippov jcmvb...@gmail.com
 ---
 Changes v1-v2:
 - use -EINVAL instead of -ENOENT for invalid PMU event configuratons.
 
  arch/xtensa/Kconfig |  10 +
  arch/xtensa/kernel/Makefile |   1 +
  arch/xtensa/kernel/perf_event.c | 450 
 
  3 files changed, 461 insertions(+)
  create mode 100644 arch/xtensa/kernel/perf_event.c
 
 diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
 index 3c57934..0e92885 100644
 --- a/arch/xtensa/Kconfig
 +++ b/arch/xtensa/Kconfig
 @@ -126,6 +126,16 @@ config XTENSA_VARIANT_MMU
 Build a Conventional Kernel with full MMU support,
 ie: it supports a TLB with auto-loading, page protection.
  
 +config XTENSA_VARIANT_HAVE_PERF_EVENTS
 + bool Core variant has Performance Monitor Module
 + depends on XTENSA_VARIANT_CUSTOM
 + default n
 + help
 +   Enable if core variant has Performance Monitor Module with
 +   External Registers Interface.
 +
 +   If unsure, say N.
 +
  config XTENSA_UNALIGNED_USER
   bool Unaligned memory access in use space
   help
 diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
 index d3a0f0f..547a757 100644
 --- a/arch/xtensa/kernel/Makefile
 +++ b/arch/xtensa/kernel/Makefile
 @@ -13,6 +13,7 @@ obj-$(CONFIG_PCI) += pci.o
  obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
  obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
  obj-$(CONFIG_SMP) += smp.o mxhead.o
 +obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o
  
  AFLAGS_head.o += -mtext-section-literals
  
 diff --git a/arch/xtensa/kernel/perf_event.c b/arch/xtensa/kernel/perf_event.c
 new file mode 100644
 index 000..b44df3c
 --- /dev/null
 +++ b/arch/xtensa/kernel/perf_event.c
 @@ -0,0 +1,450 @@
 +/*
 + * Xtensa Performance Monitor Module driver
 + * See Tensilica Debug User's Guide for PMU registers documentation.
 + *
 + * Copyright (C) 2015 Cadence Design Systems Inc.
 + *
 + * 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.
 + */
 +
 +#include linux/interrupt.h
 +#include linux/irqdomain.h
 +#include linux/module.h
 +#include linux/of.h
 +#include linux/perf_event.h
 +#include linux/platform_device.h
 +
 +#include asm/processor.h
 +#include asm/stacktrace.h
 +
 +/* Global control/status for all perf counters */
 +#define XTENSA_PMU_PMG   0x1000
 +/* Perf counter values */
 +#define XTENSA_PMU_PM(i) (0x1080 + (i) * 4)
 +/* Perf counter control registers */
 +#define XTENSA_PMU_PMCTRL(i) (0x1100 + (i) * 4)
 +/* Perf counter status registers */
 +#define XTENSA_PMU_PMSTAT(i) (0x1180 + (i) * 4)
 +
 +#define XTENSA_PMU_PMG_PMEN  0x1
 +
 +#define XTENSA_PMU_COUNTER_MASK  0xULL
 +#define XTENSA_PMU_COUNTER_MAX   0x7fff
 +
 +#define XTENSA_PMU_PMCTRL_INTEN  0x0001
 +#define XTENSA_PMU_PMCTRL_KRNLCNT0x0008
 +#define XTENSA_PMU_PMCTRL_TRACELEVEL 0x00f0
 +#define XTENSA_PMU_PMCTRL_SELECT_SHIFT   8
 +#define XTENSA_PMU_PMCTRL_SELECT 0x1f00
 +#define XTENSA_PMU_PMCTRL_MASK_SHIFT 16
 +#define XTENSA_PMU_PMCTRL_MASK   0x
 +
 +#define XTENSA_PMU_MASK(select, mask) \
 + (((select)  XTENSA_PMU_PMCTRL_SELECT_SHIFT) | \
 +  ((mask)  XTENSA_PMU_PMCTRL_MASK_SHIFT) | \
 +  XTENSA_PMU_PMCTRL_TRACELEVEL | \
 +  XTENSA_PMU_PMCTRL_INTEN)
 +
 +#define XTENSA_PMU_PMSTAT_OVFL   0x0001
 +#define XTENSA_PMU_PMSTAT_INTASRT0x0010
 +
 +struct xtensa_pmu_events {
 + /* Array of events currently on this core */
 + struct perf_event *event[XCHAL_NUM_PERF_COUNTERS];
 + /* Bitmap of used hardware counters */
 + unsigned long used_mask[BITS_TO_LONGS(XCHAL_NUM_PERF_COUNTERS)];
 +};
 +static DEFINE_PER_CPU(struct xtensa_pmu_events, xtensa_pmu_events);
 +
 +static const u32 

[PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-07-18 Thread Max Filippov
Xtensa Performance Monitor Module has up to 8 32 bit wide performance
counters. Each counter may be enabled independently and can count any
single type of hardware performance events. Event counting may be enabled
and disabled globally (per PMM).
Each counter has status register with bits indicating if the counter has
been overflown and may be programmed to raise profiling IRQ on overflow.
This IRQ is used to rewind counters and allow for counting more than 2^32
samples for counting events and to report samples for sampling events.

For more details see Tensilica Debug User's Guide, chapter 8
"Performance monitor module".

Cc: Peter Zijlstra 
Cc: Paul Mackerras 
Cc: Ingo Molnar 
Cc: Arnaldo Carvalho de Melo 
Signed-off-by: Max Filippov 
---
Changes v1->v2:
- use -EINVAL instead of -ENOENT for invalid PMU event configuratons.

 arch/xtensa/Kconfig |  10 +
 arch/xtensa/kernel/Makefile |   1 +
 arch/xtensa/kernel/perf_event.c | 450 
 3 files changed, 461 insertions(+)
 create mode 100644 arch/xtensa/kernel/perf_event.c

diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 3c57934..0e92885 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -126,6 +126,16 @@ config XTENSA_VARIANT_MMU
  Build a Conventional Kernel with full MMU support,
  ie: it supports a TLB with auto-loading, page protection.
 
+config XTENSA_VARIANT_HAVE_PERF_EVENTS
+   bool "Core variant has Performance Monitor Module"
+   depends on XTENSA_VARIANT_CUSTOM
+   default n
+   help
+ Enable if core variant has Performance Monitor Module with
+ External Registers Interface.
+
+ If unsure, say N.
+
 config XTENSA_UNALIGNED_USER
bool "Unaligned memory access in use space"
help
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index d3a0f0f..547a757 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
 obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
 obj-$(CONFIG_SMP) += smp.o mxhead.o
+obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o
 
 AFLAGS_head.o += -mtext-section-literals
 
diff --git a/arch/xtensa/kernel/perf_event.c b/arch/xtensa/kernel/perf_event.c
new file mode 100644
index 000..b44df3c
--- /dev/null
+++ b/arch/xtensa/kernel/perf_event.c
@@ -0,0 +1,450 @@
+/*
+ * Xtensa Performance Monitor Module driver
+ * See Tensilica Debug User's Guide for PMU registers documentation.
+ *
+ * Copyright (C) 2015 Cadence Design Systems Inc.
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/* Global control/status for all perf counters */
+#define XTENSA_PMU_PMG 0x1000
+/* Perf counter values */
+#define XTENSA_PMU_PM(i)   (0x1080 + (i) * 4)
+/* Perf counter control registers */
+#define XTENSA_PMU_PMCTRL(i)   (0x1100 + (i) * 4)
+/* Perf counter status registers */
+#define XTENSA_PMU_PMSTAT(i)   (0x1180 + (i) * 4)
+
+#define XTENSA_PMU_PMG_PMEN0x1
+
+#define XTENSA_PMU_COUNTER_MASK0xULL
+#define XTENSA_PMU_COUNTER_MAX 0x7fff
+
+#define XTENSA_PMU_PMCTRL_INTEN0x0001
+#define XTENSA_PMU_PMCTRL_KRNLCNT  0x0008
+#define XTENSA_PMU_PMCTRL_TRACELEVEL   0x00f0
+#define XTENSA_PMU_PMCTRL_SELECT_SHIFT 8
+#define XTENSA_PMU_PMCTRL_SELECT   0x1f00
+#define XTENSA_PMU_PMCTRL_MASK_SHIFT   16
+#define XTENSA_PMU_PMCTRL_MASK 0x
+
+#define XTENSA_PMU_MASK(select, mask) \
+   (((select) << XTENSA_PMU_PMCTRL_SELECT_SHIFT) | \
+((mask) << XTENSA_PMU_PMCTRL_MASK_SHIFT) | \
+XTENSA_PMU_PMCTRL_TRACELEVEL | \
+XTENSA_PMU_PMCTRL_INTEN)
+
+#define XTENSA_PMU_PMSTAT_OVFL 0x0001
+#define XTENSA_PMU_PMSTAT_INTASRT  0x0010
+
+struct xtensa_pmu_events {
+   /* Array of events currently on this core */
+   struct perf_event *event[XCHAL_NUM_PERF_COUNTERS];
+   /* Bitmap of used hardware counters */
+   unsigned long used_mask[BITS_TO_LONGS(XCHAL_NUM_PERF_COUNTERS)];
+};
+static DEFINE_PER_CPU(struct xtensa_pmu_events, xtensa_pmu_events);
+
+static const u32 xtensa_hw_ctl[] = {
+   [PERF_COUNT_HW_CPU_CYCLES]  = XTENSA_PMU_MASK(0, 0x1),
+   [PERF_COUNT_HW_INSTRUCTIONS]= XTENSA_PMU_MASK(2, 0x),
+   [PERF_COUNT_HW_CACHE_REFERENCES]= XTENSA_PMU_MASK(10, 0x1),
+   [PERF_COUNT_HW_CACHE_MISSES]= XTENSA_PMU_MASK(12, 0x1),
+   /* Taken and non-taken branches + taken loop ends */
+   [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XTENSA_PMU_MASK(2, 0x490),
+   /* Instruction-related + 

[PATCH v2 07/13] xtensa: implement counting and sampling perf events

2015-07-18 Thread Max Filippov
Xtensa Performance Monitor Module has up to 8 32 bit wide performance
counters. Each counter may be enabled independently and can count any
single type of hardware performance events. Event counting may be enabled
and disabled globally (per PMM).
Each counter has status register with bits indicating if the counter has
been overflown and may be programmed to raise profiling IRQ on overflow.
This IRQ is used to rewind counters and allow for counting more than 2^32
samples for counting events and to report samples for sampling events.

For more details see Tensilica Debug User's Guide, chapter 8
Performance monitor module.

Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Paul Mackerras pau...@samba.org
Cc: Ingo Molnar mi...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@kernel.org
Signed-off-by: Max Filippov jcmvb...@gmail.com
---
Changes v1-v2:
- use -EINVAL instead of -ENOENT for invalid PMU event configuratons.

 arch/xtensa/Kconfig |  10 +
 arch/xtensa/kernel/Makefile |   1 +
 arch/xtensa/kernel/perf_event.c | 450 
 3 files changed, 461 insertions(+)
 create mode 100644 arch/xtensa/kernel/perf_event.c

diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 3c57934..0e92885 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -126,6 +126,16 @@ config XTENSA_VARIANT_MMU
  Build a Conventional Kernel with full MMU support,
  ie: it supports a TLB with auto-loading, page protection.
 
+config XTENSA_VARIANT_HAVE_PERF_EVENTS
+   bool Core variant has Performance Monitor Module
+   depends on XTENSA_VARIANT_CUSTOM
+   default n
+   help
+ Enable if core variant has Performance Monitor Module with
+ External Registers Interface.
+
+ If unsure, say N.
+
 config XTENSA_UNALIGNED_USER
bool Unaligned memory access in use space
help
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index d3a0f0f..547a757 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
 obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
 obj-$(CONFIG_SMP) += smp.o mxhead.o
+obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o
 
 AFLAGS_head.o += -mtext-section-literals
 
diff --git a/arch/xtensa/kernel/perf_event.c b/arch/xtensa/kernel/perf_event.c
new file mode 100644
index 000..b44df3c
--- /dev/null
+++ b/arch/xtensa/kernel/perf_event.c
@@ -0,0 +1,450 @@
+/*
+ * Xtensa Performance Monitor Module driver
+ * See Tensilica Debug User's Guide for PMU registers documentation.
+ *
+ * Copyright (C) 2015 Cadence Design Systems Inc.
+ *
+ * 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.
+ */
+
+#include linux/interrupt.h
+#include linux/irqdomain.h
+#include linux/module.h
+#include linux/of.h
+#include linux/perf_event.h
+#include linux/platform_device.h
+
+#include asm/processor.h
+#include asm/stacktrace.h
+
+/* Global control/status for all perf counters */
+#define XTENSA_PMU_PMG 0x1000
+/* Perf counter values */
+#define XTENSA_PMU_PM(i)   (0x1080 + (i) * 4)
+/* Perf counter control registers */
+#define XTENSA_PMU_PMCTRL(i)   (0x1100 + (i) * 4)
+/* Perf counter status registers */
+#define XTENSA_PMU_PMSTAT(i)   (0x1180 + (i) * 4)
+
+#define XTENSA_PMU_PMG_PMEN0x1
+
+#define XTENSA_PMU_COUNTER_MASK0xULL
+#define XTENSA_PMU_COUNTER_MAX 0x7fff
+
+#define XTENSA_PMU_PMCTRL_INTEN0x0001
+#define XTENSA_PMU_PMCTRL_KRNLCNT  0x0008
+#define XTENSA_PMU_PMCTRL_TRACELEVEL   0x00f0
+#define XTENSA_PMU_PMCTRL_SELECT_SHIFT 8
+#define XTENSA_PMU_PMCTRL_SELECT   0x1f00
+#define XTENSA_PMU_PMCTRL_MASK_SHIFT   16
+#define XTENSA_PMU_PMCTRL_MASK 0x
+
+#define XTENSA_PMU_MASK(select, mask) \
+   (((select)  XTENSA_PMU_PMCTRL_SELECT_SHIFT) | \
+((mask)  XTENSA_PMU_PMCTRL_MASK_SHIFT) | \
+XTENSA_PMU_PMCTRL_TRACELEVEL | \
+XTENSA_PMU_PMCTRL_INTEN)
+
+#define XTENSA_PMU_PMSTAT_OVFL 0x0001
+#define XTENSA_PMU_PMSTAT_INTASRT  0x0010
+
+struct xtensa_pmu_events {
+   /* Array of events currently on this core */
+   struct perf_event *event[XCHAL_NUM_PERF_COUNTERS];
+   /* Bitmap of used hardware counters */
+   unsigned long used_mask[BITS_TO_LONGS(XCHAL_NUM_PERF_COUNTERS)];
+};
+static DEFINE_PER_CPU(struct xtensa_pmu_events, xtensa_pmu_events);
+
+static const u32 xtensa_hw_ctl[] = {
+   [PERF_COUNT_HW_CPU_CYCLES]  = XTENSA_PMU_MASK(0, 0x1),
+   [PERF_COUNT_HW_INSTRUCTIONS]= XTENSA_PMU_MASK(2, 0x),
+   [PERF_COUNT_HW_CACHE_REFERENCES]= XTENSA_PMU_MASK(10, 0x1),
+   [PERF_COUNT_HW_CACHE_MISSES]