Re: [PATCH v1 1/2] arm: a driver for on-chip ETM and ETB

2009-10-12 Thread Alexander Shishkin
2009/10/12 Linus Walleij linus.ml.wall...@gmail.com:
 2009/10/11 Alexander Shishkin virtu...@slind.org:

 This driver implements support for on-chip Embedded Tracing Macrocell and
 Embedded Trace Buffer. It allows to trigger tracing of kernel execution flow
 and exporting trace output to userspace via character device and a sysrq
 combo.

 Cool, can it at all be interfaced to kernel tracing mechanisms like
 ftrace, LTTng...? Or is this entirely orthogonal?
I'll have to check on that.

 First, these are registered as platform devices, should they not be AMBA
 devices (i.e. PrimeCells?) I think that's what they are, and they probably
 have device ID:s to be matched in the last words of their 4K pages
 do they not?
Only ETMv3.2 and are said to comply with AMBA with regards to
peripheral id and component id registers and I'm not quite sure how
useful those are. Whereas having those as platform devices provides
the possibility to have them defined per platform for most of ETM
versions.

 (...)
 diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
 new file mode 100644
 index 000..3e7b431
 --- /dev/null
 +++ b/arch/arm/kernel/etm.c
 @@ -0,0 +1,588 @@
 +/*
 + * linux/arch/arm/kernel/etm.c
 + *
 + * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer.
 + *
 + * Copyright (C) 2009 Nokia Corporation.
 + * Alexander Shishkin
 + *
 + * 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/kernel.h
 +#include linux/init.h
 +#include linux/types.h
 +#include linux/io.h
 +#include linux/clk.h
 +#include linux/sysrq.h
 +#include linux/platform_device.h
 +#include linux/fs.h
 +#include linux/uaccess.h
 +#include linux/miscdevice.h
 +#include linux/vmalloc.h
 +#include linux/mutex.h
 +#include asm/hardware/coresight.h
 +#include asm/sections.h
 +
 +MODULE_LICENSE(GPL);
 +MODULE_AUTHOR(Alexander Shishkin);
 +
 +static struct tracectx tracer;
 +
 +static inline bool trace_isrunning(struct tracectx *t)
 +{
 +       return !!(t-flags  TRACER_RUNNING);
 +}
 +
 +static int etm_setup_address_range(struct tracectx *t, int n,
 +               unsigned long start, unsigned long end, int exclude, int 
 data)
 +{
 +       u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
 +                   ETMAAT_NOVALCMP;
 +
 +       if (n  1 || n  t-ncmppairs)
 +               return -EINVAL;
 +
 +       /* comparators and ranges are numbered starting with 1 as opposed
 +        * to bits in a word */
 +       n--;
 +
 +       if (data)
 +               flags |= ETMAAT_DLOADSTORE;
 +       else
 +               flags |= ETMAAT_IEXEC;
 +
 +       /* first comparator for the range */
 +       etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
 +       etm_writel(t, start, ETMR_COMP_VAL(n * 2));
 +
 +       /* second comparator is right next to it */
 +       etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
 +       etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
 +
 +       flags = exclude ? ETMTE_INCLEXCL : 0;
 +       etm_writel(t, flags | (1  n), ETMR_TRACEENCTRL);
 +
 +       return 0;
 +}
 +
 +static int trace_start(struct tracectx *t)
 +{
 +       u32 v;
 +       unsigned long timeout = TRACER_TIMEOUT;
 +
 +       etb_unlock(t);
 +
 +       etb_writel(t, 0, ETBR_FORMATTERCTRL);
 +       etb_writel(t, 1, ETBR_CTRL);
 +
 +       etb_lock(t);
 +
 +       /* configure etm */
 +       v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t-etm_portsz);
 +
 +       if (t-flags  TRACER_CYCLE_ACC)
 +               v |= ETMCTRL_CYCLEACCURATE;
 +
 +       etm_unlock(t);
 +
 +       etm_writel(t, v, ETMR_CTRL);
 +
 +       while (!(etm_readl(t, ETMR_CTRL)  ETMCTRL_PROGRAM)  --timeout)
 +               ;
 +       if (!timeout) {
 +               dev_dbg(t-dev, Waiting for progbit to assert timed out\n);
 +               etm_lock(t);
 +               return -EFAULT;
 +       }
 +
 +       etm_setup_address_range(t, 1, (unsigned long)_stext,
 +                       (unsigned long)_etext, 0, 0);
 +       etm_writel(t, 0, ETMR_TRACEENCTRL2);
 +       etm_writel(t, 0, ETMR_TRACESSCTRL);
 +       etm_writel(t, 0x6f, ETMR_TRACEENEVT);
 +
 +       v = ~ETMCTRL_PROGRAM;
 +       v |= ETMCTRL_PORTSEL;
 +
 +       etm_writel(t, v, ETMR_CTRL);
 +
 +       timeout = TRACER_TIMEOUT;
 +       while (etm_readl(t, ETMR_CTRL)  ETMCTRL_PROGRAM  --timeout)
 +               ;
 +       if (!timeout) {
 +               dev_dbg(t-dev, Waiting for progbit to deassert timed 
 out\n);
 +               etm_lock(t);
 +               return -EFAULT;
 +       }
 +
 +       etm_lock(t);
 +
 +       t-flags |= TRACER_RUNNING;
 +
 +       return 0;
 +}
 +
 +static int trace_stop(struct tracectx *t)
 +{
 +       unsigned long timeout = TRACER_TIMEOUT;
 +
 +       etm_unlock(t);
 +
 +       etm_writel(t, 0x440, ETMR_CTRL);
 +       while (!(etm_readl(t, ETMR_CTRL)  ETMCTRL_PROGRAM)  

[PATCH v1 1/2] arm: a driver for on-chip ETM and ETB

2009-10-11 Thread Alexander Shishkin
This driver implements support for on-chip Embedded Tracing Macrocell and
Embedded Trace Buffer. It allows to trigger tracing of kernel execution flow
and exporting trace output to userspace via character device and a sysrq
combo.

Trace output can then be decoded by a fairly simple open source tool [1]
which is already sufficient to get the idea of what the kernel is doing.

[1]: http://github.com/virtuoso/etm2human

Signed-off-by: Alexander Shishkin virtu...@slind.org
Signed-off-by: Juha Leppanen juha_motorsport...@luukku.com
---
Changes:
v1 -- fixed comments from Juha Leppanen
v0 -- initial implementation, has been sent to linux-omap only

 arch/arm/Kconfig.debug|8 +
 arch/arm/include/asm/hardware/coresight.h |  164 
 arch/arm/kernel/Makefile  |2 +
 arch/arm/kernel/etm.c |  588 +
 4 files changed, 762 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/hardware/coresight.h
 create mode 100644 arch/arm/kernel/etm.c

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 1a6f70e..ac83c03 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -83,6 +83,14 @@ config DEBUG_ICEDCC
  It does include a timeout to ensure that the system does not
  totally freeze when there is nothing connected to read.
 
+config OC_ETM
+   tristate On-chip ETM and ETB
+   depends on ARCH_OMAP3
+   help
+ Enables the on-chip embedded trace macrocell and embedded trace
+ buffer driver that will allow you to collect traces of the
+ kernel code.
+
 config DEBUG_DC21285_PORT
bool Kernel low-level debugging messages via footbridge serial port
depends on DEBUG_LL  FOOTBRIDGE
diff --git a/arch/arm/include/asm/hardware/coresight.h 
b/arch/arm/include/asm/hardware/coresight.h
new file mode 100644
index 000..ba22df9
--- /dev/null
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -0,0 +1,164 @@
+/*
+ * linux/arch/arm/include/asm/hardware/coresight.h
+ *
+ * CoreSight components' registers
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * 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 __ASM_HARDWARE_CORESIGHT_H
+#define __ASM_HARDWARE_CORESIGHT_H
+
+#define TRACER_ACCESSED_BIT0
+#define TRACER_RUNNING_BIT 1
+#define TRACER_CYCLE_ACC_BIT   2
+#define TRACER_ACCESSEDBIT(TRACER_ACCESSED_BIT)
+#define TRACER_RUNNING BIT(TRACER_RUNNING_BIT)
+#define TRACER_CYCLE_ACC   BIT(TRACER_CYCLE_ACC_BIT)
+
+struct tracectx {
+   unsigned int etb_bufsz;
+   void __iomem *etb_regs;
+   void __iomem *etm_regs;
+   unsigned long flags;
+   int ncmppairs;
+   int etm_portsz;
+   struct device *dev;
+   struct mutex mutex;
+};
+
+#define TRACER_TIMEOUT 1
+
+#define etm_writel(t, v, x) \
+   (__raw_writel((v), (t)-etm_regs + (x)))
+#define etm_readl(t, x) (__raw_readl((t)-etm_regs + (x)))
+
+/* CoreSight Management Registers */
+#define CSMR_LOCKACCESS 0xfb0
+#define CSMR_LOCKSTATUS 0xfb4
+#define CSMR_AUTHSTATUS 0xfb8
+#define CSMR_DEVID 0xfc8
+#define CSMR_DEVTYPE   0xfcc
+/* CoreSight Component Registers */
+#define CSCR_CLASS 0xff4
+
+#define CSCR_PRSR  0x314
+
+#define UNLOCK_MAGIC   0xc5acce55
+
+/* ETM control register, ETM Architecture, 3.3.1 */
+#define ETMR_CTRL  0
+#define ETMCTRL_POWERDOWN  1
+#define ETMCTRL_PROGRAM(1  10)
+#define ETMCTRL_PORTSEL(1  11)
+#define ETMCTRL_DO_CONTEXTID   (3  14)
+#define ETMCTRL_PORTMASK1  (7  4)
+#define ETMCTRL_PORTMASK2  (1  21)
+#define ETMCTRL_PORTMASK   (ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2)
+#define ETMCTRL_PORTSIZE(x) x)  7)  4) | (!!((x)  8))  21)
+#define ETMCTRL_DO_CPRT(1  1)
+#define ETMCTRL_DATAMASK   (3  2)
+#define ETMCTRL_DATA_DO_DATA   (1  2)
+#define ETMCTRL_DATA_DO_ADDR   (1  3)
+#define ETMCTRL_DATA_DO_BOTH   (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR)
+#define ETMCTRL_BRANCH_OUTPUT  (1  8)
+#define ETMCTRL_CYCLEACCURATE  (1  12)
+
+/* ETM configuration code register */
+#define ETMR_CONFCODE  (0x04)
+
+/* ETM trace start/stop resource control register */
+#define ETMR_TRACESSCTRL   (0x18)
+
+/* ETM trigger event register */
+#define ETMR_TRIGEVT   (0x08)
+
+/* address access type register bits, ETM architecture,
+ * table 3-27 */
+/* - access type */
+#define ETMAAT_IFETCH  0
+#define ETMAAT_IEXEC   1
+#define ETMAAT_IEXECPASS   2
+#define ETMAAT_IEXECFAIL   3
+#define ETMAAT_DLOADSTORE  4
+#define ETMAAT_DLOAD   5
+#define ETMAAT_DSTORE  6
+/* - comparison access size */
+#define ETMAAT_JAVA(0  3)
+#define ETMAAT_THUMB   (1  3)
+#define ETMAAT_ARM  

Re: [PATCH v1 1/2] arm: a driver for on-chip ETM and ETB

2009-10-11 Thread Linus Walleij
2009/10/11 Alexander Shishkin virtu...@slind.org:

 This driver implements support for on-chip Embedded Tracing Macrocell and
 Embedded Trace Buffer. It allows to trigger tracing of kernel execution flow
 and exporting trace output to userspace via character device and a sysrq
 combo.

Cool, can it at all be interfaced to kernel tracing mechanisms like
ftrace, LTTng...? Or is this entirely orthogonal?

First, these are registered as platform devices, should they not be AMBA
devices (i.e. PrimeCells?) I think that's what they are, and they probably
have device ID:s to be matched in the last words of their 4K pages
do they not?

 (...)
 diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
 new file mode 100644
 index 000..3e7b431
 --- /dev/null
 +++ b/arch/arm/kernel/etm.c
 @@ -0,0 +1,588 @@
 +/*
 + * linux/arch/arm/kernel/etm.c
 + *
 + * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer.
 + *
 + * Copyright (C) 2009 Nokia Corporation.
 + * Alexander Shishkin
 + *
 + * 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/kernel.h
 +#include linux/init.h
 +#include linux/types.h
 +#include linux/io.h
 +#include linux/clk.h
 +#include linux/sysrq.h
 +#include linux/platform_device.h
 +#include linux/fs.h
 +#include linux/uaccess.h
 +#include linux/miscdevice.h
 +#include linux/vmalloc.h
 +#include linux/mutex.h
 +#include asm/hardware/coresight.h
 +#include asm/sections.h
 +
 +MODULE_LICENSE(GPL);
 +MODULE_AUTHOR(Alexander Shishkin);
 +
 +static struct tracectx tracer;
 +
 +static inline bool trace_isrunning(struct tracectx *t)
 +{
 +       return !!(t-flags  TRACER_RUNNING);
 +}
 +
 +static int etm_setup_address_range(struct tracectx *t, int n,
 +               unsigned long start, unsigned long end, int exclude, int data)
 +{
 +       u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
 +                   ETMAAT_NOVALCMP;
 +
 +       if (n  1 || n  t-ncmppairs)
 +               return -EINVAL;
 +
 +       /* comparators and ranges are numbered starting with 1 as opposed
 +        * to bits in a word */
 +       n--;
 +
 +       if (data)
 +               flags |= ETMAAT_DLOADSTORE;
 +       else
 +               flags |= ETMAAT_IEXEC;
 +
 +       /* first comparator for the range */
 +       etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
 +       etm_writel(t, start, ETMR_COMP_VAL(n * 2));
 +
 +       /* second comparator is right next to it */
 +       etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
 +       etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
 +
 +       flags = exclude ? ETMTE_INCLEXCL : 0;
 +       etm_writel(t, flags | (1  n), ETMR_TRACEENCTRL);
 +
 +       return 0;
 +}
 +
 +static int trace_start(struct tracectx *t)
 +{
 +       u32 v;
 +       unsigned long timeout = TRACER_TIMEOUT;
 +
 +       etb_unlock(t);
 +
 +       etb_writel(t, 0, ETBR_FORMATTERCTRL);
 +       etb_writel(t, 1, ETBR_CTRL);
 +
 +       etb_lock(t);
 +
 +       /* configure etm */
 +       v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t-etm_portsz);
 +
 +       if (t-flags  TRACER_CYCLE_ACC)
 +               v |= ETMCTRL_CYCLEACCURATE;
 +
 +       etm_unlock(t);
 +
 +       etm_writel(t, v, ETMR_CTRL);
 +
 +       while (!(etm_readl(t, ETMR_CTRL)  ETMCTRL_PROGRAM)  --timeout)
 +               ;
 +       if (!timeout) {
 +               dev_dbg(t-dev, Waiting for progbit to assert timed out\n);
 +               etm_lock(t);
 +               return -EFAULT;
 +       }
 +
 +       etm_setup_address_range(t, 1, (unsigned long)_stext,
 +                       (unsigned long)_etext, 0, 0);
 +       etm_writel(t, 0, ETMR_TRACEENCTRL2);
 +       etm_writel(t, 0, ETMR_TRACESSCTRL);
 +       etm_writel(t, 0x6f, ETMR_TRACEENEVT);
 +
 +       v = ~ETMCTRL_PROGRAM;
 +       v |= ETMCTRL_PORTSEL;
 +
 +       etm_writel(t, v, ETMR_CTRL);
 +
 +       timeout = TRACER_TIMEOUT;
 +       while (etm_readl(t, ETMR_CTRL)  ETMCTRL_PROGRAM  --timeout)
 +               ;
 +       if (!timeout) {
 +               dev_dbg(t-dev, Waiting for progbit to deassert timed 
 out\n);
 +               etm_lock(t);
 +               return -EFAULT;
 +       }
 +
 +       etm_lock(t);
 +
 +       t-flags |= TRACER_RUNNING;
 +
 +       return 0;
 +}
 +
 +static int trace_stop(struct tracectx *t)
 +{
 +       unsigned long timeout = TRACER_TIMEOUT;
 +
 +       etm_unlock(t);
 +
 +       etm_writel(t, 0x440, ETMR_CTRL);
 +       while (!(etm_readl(t, ETMR_CTRL)  ETMCTRL_PROGRAM)  --timeout)
 +               ;
 +       if (!timeout) {
 +               dev_dbg(t-dev, Waiting for progbit to assert timed out\n);
 +               etm_lock(t);
 +               return -EFAULT;
 +       }
 +
 +       etm_lock(t);
 +
 +       etb_unlock(t);
 +       etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
 +
 +       timeout = TRACER_TIMEOUT;
 +       while 

Re: [PATCH v1 1/2] arm: a driver for on-chip ETM and ETB

2009-10-11 Thread Russell King - ARM Linux
On Mon, Oct 12, 2009 at 12:07:57AM +0200, Linus Walleij wrote:
 First, these are registered as platform devices, should they not be AMBA
 devices (i.e. PrimeCells?) I think that's what they are, and they probably
 have device ID:s to be matched in the last words of their 4K pages
 do they not?

It does look like it's Primecell-like, so it should be using the
primecell support so that others can make use of this.  As such, it
should not be OMAP specific.

  +       clk = clk_get(pdev-dev, emu_core_alwon_ck);
  +       clk_enable(clk);
  +
  +       clk = clk_get(pdev-dev, emu_per_alwon_ck);
  +       clk_enable(clk);
  +
  +       clk = clk_get(pdev-dev, emu_mpu_alwon_ck);
  +       clk_enable(clk);
  +
  +       clk = clk_get(pdev-dev, emu_src_ck);
  +       clk_enable(clk);
 
 Are these clocks really generic? It looks a lot like OMAP-specific
 stuff. Is it possible to hide these behind a single clock inside the
 platform? like etbclock or so that increase refcount of the others
 by 1?

First obvious problem is that there's no error checking there.

Second problem is that this could very well be a generic driver, and
OMAP specifics should not be in here.  Looking at the Coresight ETM11
documentation, there's:

ATCLK - ATB interface clock
CLK - main clock
PCLKDBG - Debug APB clock or PCLK - APB clock

I'm not sure why OMAP seems to have four clocks when the ETM has only
three clocks itself.
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html