Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-16 Thread Mathieu Poirier
On Wed, Feb 15, 2017 at 11:43:27AM +, Mark Rutland wrote:
> On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> > Coresight includes debug module and usually the module connects with CPU
> > debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> > the debug registers in the chapter "H9: External Debug Register
> > Descriptions".
> 
> This should have been in the binding description also.
> 
> The layout of the ARM ARM can change over time, so please refer to the
> full document number, which can be found at the bottom of each page
> (e.g. ARM DDI 0487A.j).
> 
> > After enable the debug module we can check CPU state and PC value, etc.
> > So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> > into infinite loop with IRQ disabled. So the CPU cannot switch context
> > and handle any interrupt, so it cannot handle SMP call for stack dump,
> > etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> > ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> > firmware and cannot return back to kernel.
> 
> I would generally expect that the secure world would lock down
> debugging, as this poses a security risk.
> 
> I take it that this is only unlocked on development firmware.
> 
> Given that cores can be powered down outside of our control, I'm not
> sure that accesses to these registers is safe in general.
> 
> > This patch is to enable coresight debug module and register callback
> > notifier for panic; so when system detect the CPU lockup we can utilize
> > debug module registers to get to know PC value for all CPUs; so we can
> > quickly know the hang address for CPUs.
> >
> > This is initial driver for coresight debug module and could enhance it
> > later according to debugging requirement.
> 
> How does this interact with an external debugger making use of these
> registers?
> 
> [...]
> 
> > +static struct debug_drvdata *debug_drvdata[NR_CPUS];
> 
> A per-cpu variable is preferred to an NR_CPUS sized array.
> 
> > +
> > +static void debug_os_unlock(struct debug_drvdata *drvdata)
> > +{
> > + /* Unlocks the debug registers */
> > + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> > + isb();
> > +}
> 
> I do not believe this barrier is correct.

Mark has a point - isb() sounds like an overkill to prevent
re-ordering (same for the ETM4x driver).  smb_wmb() should be sufficient.  

> 
> [...]
> 
> > +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> > +{
> > + u32 pcsr_hi, pcsr_lo;
> > +
> > + CS_UNLOCK(drvdata->base);
> > +
> > + debug_os_unlock(drvdata);
> > +
> > +#ifdef CONFIG_64BIT
> > + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> > + pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> > +
> > + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
> > +  ((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
> > +#else
> > + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> > +
> > + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
> > +#endif
> > +
> > + CS_LOCK(drvdata->base);
> > +}
> 
> Per ARM DDI 0487A.k_iss10775, H9.2.32, "EDPCSR, External Debug Program
> Counter Sample Register":
> 
> Implemented only if the OPTIONAL PC Sample-based Profiling
> Extension is implemented.
> 
> So even if we have access to an MMIO debug interface, we cannot
> necessarily acecess this register.
> 
> [...]
> 
> > +/*
> > + * Dump out memory limit information on panic.
> > + */
> > +static int dump_debug(struct notifier_block *self, unsigned long v, void 
> > *p)
> > +{
> > + int i;
> > +
> > + pr_emerg("Coresight debug module:\n");
> > +
> > + for_each_possible_cpu(i) {
> > +
> > + if (!debug_drvdata[i])
> > + continue;
> > +
> > + debug_read_pcsr(debug_drvdata[i]);
> > + }
> 
> Is there no potential for deadlock with a CPU reading its own debug
> interface registers?
> 
> [...]
> 
> > +static struct amba_id debug_ids[] = {
> > + {   /* Debug for Cortex-A53 */
> > + .id = 0x000bbd03,
> > + .mask   = 0x000f,
> > + .data   = "debug",
> > + },
> > + { 0, 0},
> > +};
> 
> The DT binding said nothing about Cortex-A53.
> 
> How variable are the MMIO registers in practice? Do we need to know the
> particular CPU?
> 
> Thanks,
> Mark.
> IMPORTANT NOTICE: The contents of this email and any attachments are 
> confidential and may also be privileged. If you are not the intended 
> recipient, please notify the sender immediately and do not disclose the 
> contents to any other person, use it for any purpose, or store or copy the 
> information in any medium. Thank you.


Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-16 Thread Mathieu Poirier
On Wed, Feb 15, 2017 at 11:43:27AM +, Mark Rutland wrote:
> On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> > Coresight includes debug module and usually the module connects with CPU
> > debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> > the debug registers in the chapter "H9: External Debug Register
> > Descriptions".
> 
> This should have been in the binding description also.
> 
> The layout of the ARM ARM can change over time, so please refer to the
> full document number, which can be found at the bottom of each page
> (e.g. ARM DDI 0487A.j).
> 
> > After enable the debug module we can check CPU state and PC value, etc.
> > So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> > into infinite loop with IRQ disabled. So the CPU cannot switch context
> > and handle any interrupt, so it cannot handle SMP call for stack dump,
> > etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> > ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> > firmware and cannot return back to kernel.
> 
> I would generally expect that the secure world would lock down
> debugging, as this poses a security risk.
> 
> I take it that this is only unlocked on development firmware.
> 
> Given that cores can be powered down outside of our control, I'm not
> sure that accesses to these registers is safe in general.
> 
> > This patch is to enable coresight debug module and register callback
> > notifier for panic; so when system detect the CPU lockup we can utilize
> > debug module registers to get to know PC value for all CPUs; so we can
> > quickly know the hang address for CPUs.
> >
> > This is initial driver for coresight debug module and could enhance it
> > later according to debugging requirement.
> 
> How does this interact with an external debugger making use of these
> registers?
> 
> [...]
> 
> > +static struct debug_drvdata *debug_drvdata[NR_CPUS];
> 
> A per-cpu variable is preferred to an NR_CPUS sized array.
> 
> > +
> > +static void debug_os_unlock(struct debug_drvdata *drvdata)
> > +{
> > + /* Unlocks the debug registers */
> > + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> > + isb();
> > +}
> 
> I do not believe this barrier is correct.

Mark has a point - isb() sounds like an overkill to prevent
re-ordering (same for the ETM4x driver).  smb_wmb() should be sufficient.  

> 
> [...]
> 
> > +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> > +{
> > + u32 pcsr_hi, pcsr_lo;
> > +
> > + CS_UNLOCK(drvdata->base);
> > +
> > + debug_os_unlock(drvdata);
> > +
> > +#ifdef CONFIG_64BIT
> > + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> > + pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> > +
> > + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
> > +  ((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
> > +#else
> > + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> > +
> > + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
> > +#endif
> > +
> > + CS_LOCK(drvdata->base);
> > +}
> 
> Per ARM DDI 0487A.k_iss10775, H9.2.32, "EDPCSR, External Debug Program
> Counter Sample Register":
> 
> Implemented only if the OPTIONAL PC Sample-based Profiling
> Extension is implemented.
> 
> So even if we have access to an MMIO debug interface, we cannot
> necessarily acecess this register.
> 
> [...]
> 
> > +/*
> > + * Dump out memory limit information on panic.
> > + */
> > +static int dump_debug(struct notifier_block *self, unsigned long v, void 
> > *p)
> > +{
> > + int i;
> > +
> > + pr_emerg("Coresight debug module:\n");
> > +
> > + for_each_possible_cpu(i) {
> > +
> > + if (!debug_drvdata[i])
> > + continue;
> > +
> > + debug_read_pcsr(debug_drvdata[i]);
> > + }
> 
> Is there no potential for deadlock with a CPU reading its own debug
> interface registers?
> 
> [...]
> 
> > +static struct amba_id debug_ids[] = {
> > + {   /* Debug for Cortex-A53 */
> > + .id = 0x000bbd03,
> > + .mask   = 0x000f,
> > + .data   = "debug",
> > + },
> > + { 0, 0},
> > +};
> 
> The DT binding said nothing about Cortex-A53.
> 
> How variable are the MMIO registers in practice? Do we need to know the
> particular CPU?
> 
> Thanks,
> Mark.
> IMPORTANT NOTICE: The contents of this email and any attachments are 
> confidential and may also be privileged. If you are not the intended 
> recipient, please notify the sender immediately and do not disclose the 
> contents to any other person, use it for any purpose, or store or copy the 
> information in any medium. Thank you.


Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-16 Thread Leo Yan
Hi Mathieu,

On Wed, Feb 15, 2017 at 02:08:05PM -0700, Mathieu Poirier wrote:
> On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> > Coresight includes debug module and usually the module connects with CPU
> > debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> > the debug registers in the chapter "H9: External Debug Register
> > Descriptions".
> > 
> > After enable the debug module we can check CPU state and PC value, etc.
> > So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> > into infinite loop with IRQ disabled. So the CPU cannot switch context
> > and handle any interrupt, so it cannot handle SMP call for stack dump,
> > etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> > ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> > firmware and cannot return back to kernel.
> > 
> > This patch is to enable coresight debug module and register callback
> > notifier for panic; so when system detect the CPU lockup we can utilize
> > debug module registers to get to know PC value for all CPUs; so we can
> > quickly know the hang address for CPUs.
> > 
> > This is initial driver for coresight debug module and could enhance it
> > later according to debugging requirement.
> > 
> > Signed-off-by: Leo Yan 
> > ---
> >  drivers/hwtracing/coresight/Kconfig   |   8 ++
> >  drivers/hwtracing/coresight/Makefile  |   1 +
> >  drivers/hwtracing/coresight/coresight-debug.c | 169 
> > ++
> >  3 files changed, 178 insertions(+)
> >  create mode 100644 drivers/hwtracing/coresight/coresight-debug.c
> > 
> > diff --git a/drivers/hwtracing/coresight/Kconfig 
> > b/drivers/hwtracing/coresight/Kconfig
> > index 130cb21..dcf59cc 100644
> > --- a/drivers/hwtracing/coresight/Kconfig
> > +++ b/drivers/hwtracing/coresight/Kconfig
> > @@ -89,4 +89,12 @@ config CORESIGHT_STM
> >   logging useful software events or data coming from various entities
> >   in the system, possibly running different OSs
> >  
> > +config CORESIGHT_DEBUG
> > +   bool "CoreSight debug driver"
> > +   depends on ARM || ARM64
> > +   help
> > + This driver provides support for coresight debugging module. This
> > + is primarily used for printing out debug registers for panic and
> > + soft and hard lockup.
> > +
> >  endif
> > diff --git a/drivers/hwtracing/coresight/Makefile 
> > b/drivers/hwtracing/coresight/Makefile
> > index af480d9..d540d45 100644
> > --- a/drivers/hwtracing/coresight/Makefile
> > +++ b/drivers/hwtracing/coresight/Makefile
> > @@ -16,3 +16,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o 
> > \
> > coresight-etm4x-sysfs.o
> >  obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
> >  obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
> > +obj-$(CONFIG_CORESIGHT_DEBUG) += coresight-debug.o
> > diff --git a/drivers/hwtracing/coresight/coresight-debug.c 
> > b/drivers/hwtracing/coresight/coresight-debug.c
> > new file mode 100644
> > index 000..28206a83
> > --- /dev/null
> > +++ b/drivers/hwtracing/coresight/coresight-debug.c
> > @@ -0,0 +1,169 @@
> > +/*
> > + * Copyright(C) 2017 Linaro Limited. All rights reserved.
> > + * Author: Leo Yan 
> > + *
> > + * 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.
> > + *
> > + * This program is distributed in the hope that it will be useful, but 
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
> > for
> > + * more details.
> > + *
> > + * You should have received a copy of the GNU General Public License along 
> > with
> > + * this program.  If not, see .
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> 
> When possible, please try to order the header files alphabetically.

Will fix.

> > +
> > +#include "coresight-priv.h"
> > +
> > +#define EDPCSR_LO  0x0A0
> > +#define EDPCSR_HI  0x0AC
> > +#define EDOSLAR0x300
> > +#define EDOSLSR0x304
> > +#define EDPDCR 0x310
> > +#define EDPDSR 0x314
> 
> EDOSLSR, DEPDCR and EDPDSR aren't used in the code presented below.

Will remove them.

> > +
> > +struct debug_drvdata {
> > +   void __iomem*base;
> > +   struct device   *dev;
> > +   int cpu;
> > +};
> > +
> > +static struct debug_drvdata *debug_drvdata[NR_CPUS];
> > +
> > +static void debug_os_unlock(struct debug_drvdata *drvdata)
> > +{
> > +   /* Unlocks 

Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-16 Thread Leo Yan
Hi Mathieu,

On Wed, Feb 15, 2017 at 02:08:05PM -0700, Mathieu Poirier wrote:
> On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> > Coresight includes debug module and usually the module connects with CPU
> > debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> > the debug registers in the chapter "H9: External Debug Register
> > Descriptions".
> > 
> > After enable the debug module we can check CPU state and PC value, etc.
> > So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> > into infinite loop with IRQ disabled. So the CPU cannot switch context
> > and handle any interrupt, so it cannot handle SMP call for stack dump,
> > etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> > ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> > firmware and cannot return back to kernel.
> > 
> > This patch is to enable coresight debug module and register callback
> > notifier for panic; so when system detect the CPU lockup we can utilize
> > debug module registers to get to know PC value for all CPUs; so we can
> > quickly know the hang address for CPUs.
> > 
> > This is initial driver for coresight debug module and could enhance it
> > later according to debugging requirement.
> > 
> > Signed-off-by: Leo Yan 
> > ---
> >  drivers/hwtracing/coresight/Kconfig   |   8 ++
> >  drivers/hwtracing/coresight/Makefile  |   1 +
> >  drivers/hwtracing/coresight/coresight-debug.c | 169 
> > ++
> >  3 files changed, 178 insertions(+)
> >  create mode 100644 drivers/hwtracing/coresight/coresight-debug.c
> > 
> > diff --git a/drivers/hwtracing/coresight/Kconfig 
> > b/drivers/hwtracing/coresight/Kconfig
> > index 130cb21..dcf59cc 100644
> > --- a/drivers/hwtracing/coresight/Kconfig
> > +++ b/drivers/hwtracing/coresight/Kconfig
> > @@ -89,4 +89,12 @@ config CORESIGHT_STM
> >   logging useful software events or data coming from various entities
> >   in the system, possibly running different OSs
> >  
> > +config CORESIGHT_DEBUG
> > +   bool "CoreSight debug driver"
> > +   depends on ARM || ARM64
> > +   help
> > + This driver provides support for coresight debugging module. This
> > + is primarily used for printing out debug registers for panic and
> > + soft and hard lockup.
> > +
> >  endif
> > diff --git a/drivers/hwtracing/coresight/Makefile 
> > b/drivers/hwtracing/coresight/Makefile
> > index af480d9..d540d45 100644
> > --- a/drivers/hwtracing/coresight/Makefile
> > +++ b/drivers/hwtracing/coresight/Makefile
> > @@ -16,3 +16,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o 
> > \
> > coresight-etm4x-sysfs.o
> >  obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
> >  obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
> > +obj-$(CONFIG_CORESIGHT_DEBUG) += coresight-debug.o
> > diff --git a/drivers/hwtracing/coresight/coresight-debug.c 
> > b/drivers/hwtracing/coresight/coresight-debug.c
> > new file mode 100644
> > index 000..28206a83
> > --- /dev/null
> > +++ b/drivers/hwtracing/coresight/coresight-debug.c
> > @@ -0,0 +1,169 @@
> > +/*
> > + * Copyright(C) 2017 Linaro Limited. All rights reserved.
> > + * Author: Leo Yan 
> > + *
> > + * 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.
> > + *
> > + * This program is distributed in the hope that it will be useful, but 
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
> > for
> > + * more details.
> > + *
> > + * You should have received a copy of the GNU General Public License along 
> > with
> > + * this program.  If not, see .
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> 
> When possible, please try to order the header files alphabetically.

Will fix.

> > +
> > +#include "coresight-priv.h"
> > +
> > +#define EDPCSR_LO  0x0A0
> > +#define EDPCSR_HI  0x0AC
> > +#define EDOSLAR0x300
> > +#define EDOSLSR0x304
> > +#define EDPDCR 0x310
> > +#define EDPDSR 0x314
> 
> EDOSLSR, DEPDCR and EDPDSR aren't used in the code presented below.

Will remove them.

> > +
> > +struct debug_drvdata {
> > +   void __iomem*base;
> > +   struct device   *dev;
> > +   int cpu;
> > +};
> > +
> > +static struct debug_drvdata *debug_drvdata[NR_CPUS];
> > +
> > +static void debug_os_unlock(struct debug_drvdata *drvdata)
> > +{
> > +   /* Unlocks the debug registers */
> > +   

Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-16 Thread Leo Yan
Hi Mark,

On Wed, Feb 15, 2017 at 11:44:16AM +, Mark Rutland wrote:
> [resending due to a mail server snafu]
> 
> On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> > Coresight includes debug module and usually the module connects with CPU
> > debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> > the debug registers in the chapter "H9: External Debug Register
> > Descriptions".
> 
> This should have been in the binding description also.
> 
> The layout of the ARM ARM can change over time, so please refer to the
> full document number, which can be found at the bottom of each page
> (e.g. ARM DDI 0487A.j).

Good to know this. Will use this way to connect code with spec.

> > After enable the debug module we can check CPU state and PC value, etc.
> > So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> > into infinite loop with IRQ disabled. So the CPU cannot switch context
> > and handle any interrupt, so it cannot handle SMP call for stack dump,
> > etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> > ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> > firmware and cannot return back to kernel.
> 
> I would generally expect that the secure world would lock down
> debugging, as this poses a security risk.
> 
> I take it that this is only unlocked on development firmware.
> 
> Given that cores can be powered down outside of our control, I'm not
> sure that accesses to these registers is safe in general.

Mike Leach has gave method in another email to check CPU power state in
register EDPRSR.PU before access EDPCSR register.

For security state, I will check if EDSCR.NS bit can be use to
distinguish CPU is secure or non-secure state. And also follow Mike's
suggestion to use EDPCSR = 0x_ as hint that the CPU is in
secure state.

> > This patch is to enable coresight debug module and register callback
> > notifier for panic; so when system detect the CPU lockup we can utilize
> > debug module registers to get to know PC value for all CPUs; so we can
> > quickly know the hang address for CPUs.
> > 
> > This is initial driver for coresight debug module and could enhance it
> > later according to debugging requirement.
> 
> How does this interact with an external debugger making use of these
> registers?

IIUC, external debugger also will access these registers, like use
EDPCSR to display PC value. I have no idea for the connection between
this driver with external debugger, except I think we can use this
driver to enable clock for CPU debug module.

> [...]
> 
> > +static struct debug_drvdata *debug_drvdata[NR_CPUS];
> 
> A per-cpu variable is preferred to an NR_CPUS sized array.

Will do.

> > +
> > +static void debug_os_unlock(struct debug_drvdata *drvdata)
> > +{
> > +   /* Unlocks the debug registers */
> > +   writel_relaxed(0x0, drvdata->base + EDOSLAR);
> > +   isb();
> > +}
> 
> I do not believe this barrier is correct.

I copied the code piece from coresight-etm4x.c.

I guess here is to ensure the os unlock operations is finished before
any sequential register accessing. I think isb() is redundant for
debug module and we can only use writel_relaxed() will be enough for
accessing EDOSLAR and EDPCSR, these two registers are in the same
endpoint so we don't need add extra barrier for them. Is this correct?

> [...]
> 
> > +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> > +{
> > +   u32 pcsr_hi, pcsr_lo;
> > +
> > +   CS_UNLOCK(drvdata->base);
> > +
> > +   debug_os_unlock(drvdata);
> > +
> > +#ifdef CONFIG_64BIT
> > +   pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> > +   pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> > +
> > +   pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
> > +((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
> > +#else
> > +   pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> > +
> > +   pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
> > +#endif
> > +
> > +   CS_LOCK(drvdata->base);
> > +}
> 
> Per ARM DDI 0487A.k_iss10775, H9.2.32, "EDPCSR, External Debug Program
> Counter Sample Register":
> 
>   Implemented only if the OPTIONAL PC Sample-based Profiling
>   Extension is implemented.
> 
> So even if we have access to an MMIO debug interface, we cannot
> necessarily acecess this register.

Eventually this is a hardware feature, right? If so we can use one DT
property to describe this.

> [...]
> 
> > +/*
> > + * Dump out memory limit information on panic.
> > + */
> > +static int dump_debug(struct notifier_block *self, unsigned long v, void 
> > *p)
> > +{
> > +   int i;
> > +
> > +   pr_emerg("Coresight debug module:\n");
> > +
> > +   for_each_possible_cpu(i) {
> > +
> > +   if (!debug_drvdata[i])
> > +   continue;
> > +
> > +   debug_read_pcsr(debug_drvdata[i]);
> > +   }
> 
> Is there no potential for deadlock with a CPU reading its own debug
> interface registers?

Have 

Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-16 Thread Leo Yan
Hi Mark,

On Wed, Feb 15, 2017 at 11:44:16AM +, Mark Rutland wrote:
> [resending due to a mail server snafu]
> 
> On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> > Coresight includes debug module and usually the module connects with CPU
> > debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> > the debug registers in the chapter "H9: External Debug Register
> > Descriptions".
> 
> This should have been in the binding description also.
> 
> The layout of the ARM ARM can change over time, so please refer to the
> full document number, which can be found at the bottom of each page
> (e.g. ARM DDI 0487A.j).

Good to know this. Will use this way to connect code with spec.

> > After enable the debug module we can check CPU state and PC value, etc.
> > So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> > into infinite loop with IRQ disabled. So the CPU cannot switch context
> > and handle any interrupt, so it cannot handle SMP call for stack dump,
> > etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> > ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> > firmware and cannot return back to kernel.
> 
> I would generally expect that the secure world would lock down
> debugging, as this poses a security risk.
> 
> I take it that this is only unlocked on development firmware.
> 
> Given that cores can be powered down outside of our control, I'm not
> sure that accesses to these registers is safe in general.

Mike Leach has gave method in another email to check CPU power state in
register EDPRSR.PU before access EDPCSR register.

For security state, I will check if EDSCR.NS bit can be use to
distinguish CPU is secure or non-secure state. And also follow Mike's
suggestion to use EDPCSR = 0x_ as hint that the CPU is in
secure state.

> > This patch is to enable coresight debug module and register callback
> > notifier for panic; so when system detect the CPU lockup we can utilize
> > debug module registers to get to know PC value for all CPUs; so we can
> > quickly know the hang address for CPUs.
> > 
> > This is initial driver for coresight debug module and could enhance it
> > later according to debugging requirement.
> 
> How does this interact with an external debugger making use of these
> registers?

IIUC, external debugger also will access these registers, like use
EDPCSR to display PC value. I have no idea for the connection between
this driver with external debugger, except I think we can use this
driver to enable clock for CPU debug module.

> [...]
> 
> > +static struct debug_drvdata *debug_drvdata[NR_CPUS];
> 
> A per-cpu variable is preferred to an NR_CPUS sized array.

Will do.

> > +
> > +static void debug_os_unlock(struct debug_drvdata *drvdata)
> > +{
> > +   /* Unlocks the debug registers */
> > +   writel_relaxed(0x0, drvdata->base + EDOSLAR);
> > +   isb();
> > +}
> 
> I do not believe this barrier is correct.

I copied the code piece from coresight-etm4x.c.

I guess here is to ensure the os unlock operations is finished before
any sequential register accessing. I think isb() is redundant for
debug module and we can only use writel_relaxed() will be enough for
accessing EDOSLAR and EDPCSR, these two registers are in the same
endpoint so we don't need add extra barrier for them. Is this correct?

> [...]
> 
> > +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> > +{
> > +   u32 pcsr_hi, pcsr_lo;
> > +
> > +   CS_UNLOCK(drvdata->base);
> > +
> > +   debug_os_unlock(drvdata);
> > +
> > +#ifdef CONFIG_64BIT
> > +   pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> > +   pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> > +
> > +   pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
> > +((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
> > +#else
> > +   pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> > +
> > +   pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
> > +#endif
> > +
> > +   CS_LOCK(drvdata->base);
> > +}
> 
> Per ARM DDI 0487A.k_iss10775, H9.2.32, "EDPCSR, External Debug Program
> Counter Sample Register":
> 
>   Implemented only if the OPTIONAL PC Sample-based Profiling
>   Extension is implemented.
> 
> So even if we have access to an MMIO debug interface, we cannot
> necessarily acecess this register.

Eventually this is a hardware feature, right? If so we can use one DT
property to describe this.

> [...]
> 
> > +/*
> > + * Dump out memory limit information on panic.
> > + */
> > +static int dump_debug(struct notifier_block *self, unsigned long v, void 
> > *p)
> > +{
> > +   int i;
> > +
> > +   pr_emerg("Coresight debug module:\n");
> > +
> > +   for_each_possible_cpu(i) {
> > +
> > +   if (!debug_drvdata[i])
> > +   continue;
> > +
> > +   debug_read_pcsr(debug_drvdata[i]);
> > +   }
> 
> Is there no potential for deadlock with a CPU reading its own debug
> interface registers?

Have 

Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-15 Thread Mathieu Poirier
On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> Coresight includes debug module and usually the module connects with CPU
> debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> the debug registers in the chapter "H9: External Debug Register
> Descriptions".
> 
> After enable the debug module we can check CPU state and PC value, etc.
> So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> into infinite loop with IRQ disabled. So the CPU cannot switch context
> and handle any interrupt, so it cannot handle SMP call for stack dump,
> etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> firmware and cannot return back to kernel.
> 
> This patch is to enable coresight debug module and register callback
> notifier for panic; so when system detect the CPU lockup we can utilize
> debug module registers to get to know PC value for all CPUs; so we can
> quickly know the hang address for CPUs.
> 
> This is initial driver for coresight debug module and could enhance it
> later according to debugging requirement.
> 
> Signed-off-by: Leo Yan 
> ---
>  drivers/hwtracing/coresight/Kconfig   |   8 ++
>  drivers/hwtracing/coresight/Makefile  |   1 +
>  drivers/hwtracing/coresight/coresight-debug.c | 169 
> ++
>  3 files changed, 178 insertions(+)
>  create mode 100644 drivers/hwtracing/coresight/coresight-debug.c
> 
> diff --git a/drivers/hwtracing/coresight/Kconfig 
> b/drivers/hwtracing/coresight/Kconfig
> index 130cb21..dcf59cc 100644
> --- a/drivers/hwtracing/coresight/Kconfig
> +++ b/drivers/hwtracing/coresight/Kconfig
> @@ -89,4 +89,12 @@ config CORESIGHT_STM
> logging useful software events or data coming from various entities
> in the system, possibly running different OSs
>  
> +config CORESIGHT_DEBUG
> + bool "CoreSight debug driver"
> + depends on ARM || ARM64
> + help
> +   This driver provides support for coresight debugging module. This
> +   is primarily used for printing out debug registers for panic and
> +   soft and hard lockup.
> +
>  endif
> diff --git a/drivers/hwtracing/coresight/Makefile 
> b/drivers/hwtracing/coresight/Makefile
> index af480d9..d540d45 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
>   coresight-etm4x-sysfs.o
>  obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
>  obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
> +obj-$(CONFIG_CORESIGHT_DEBUG) += coresight-debug.o
> diff --git a/drivers/hwtracing/coresight/coresight-debug.c 
> b/drivers/hwtracing/coresight/coresight-debug.c
> new file mode 100644
> index 000..28206a83
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-debug.c
> @@ -0,0 +1,169 @@
> +/*
> + * Copyright(C) 2017 Linaro Limited. All rights reserved.
> + * Author: Leo Yan 
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful, but 
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program.  If not, see .
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

When possible, please try to order the header files alphabetically.

> +
> +#include "coresight-priv.h"
> +
> +#define EDPCSR_LO0x0A0
> +#define EDPCSR_HI0x0AC
> +#define EDOSLAR  0x300
> +#define EDOSLSR  0x304
> +#define EDPDCR   0x310
> +#define EDPDSR   0x314

EDOSLSR, DEPDCR and EDPDSR aren't used in the code presented below.

> +
> +struct debug_drvdata {
> + void __iomem*base;
> + struct device   *dev;
> + int cpu;
> +};
> +
> +static struct debug_drvdata *debug_drvdata[NR_CPUS];
> +
> +static void debug_os_unlock(struct debug_drvdata *drvdata)
> +{
> + /* Unlocks the debug registers */
> + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> + isb();
> +}
> +
> +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> +{
> + u32 pcsr_hi, pcsr_lo;
> +
> + CS_UNLOCK(drvdata->base);
> +
> + debug_os_unlock(drvdata);
> +
> +#ifdef CONFIG_64BIT
> + pcsr_lo = 

Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-15 Thread Mathieu Poirier
On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> Coresight includes debug module and usually the module connects with CPU
> debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> the debug registers in the chapter "H9: External Debug Register
> Descriptions".
> 
> After enable the debug module we can check CPU state and PC value, etc.
> So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> into infinite loop with IRQ disabled. So the CPU cannot switch context
> and handle any interrupt, so it cannot handle SMP call for stack dump,
> etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> firmware and cannot return back to kernel.
> 
> This patch is to enable coresight debug module and register callback
> notifier for panic; so when system detect the CPU lockup we can utilize
> debug module registers to get to know PC value for all CPUs; so we can
> quickly know the hang address for CPUs.
> 
> This is initial driver for coresight debug module and could enhance it
> later according to debugging requirement.
> 
> Signed-off-by: Leo Yan 
> ---
>  drivers/hwtracing/coresight/Kconfig   |   8 ++
>  drivers/hwtracing/coresight/Makefile  |   1 +
>  drivers/hwtracing/coresight/coresight-debug.c | 169 
> ++
>  3 files changed, 178 insertions(+)
>  create mode 100644 drivers/hwtracing/coresight/coresight-debug.c
> 
> diff --git a/drivers/hwtracing/coresight/Kconfig 
> b/drivers/hwtracing/coresight/Kconfig
> index 130cb21..dcf59cc 100644
> --- a/drivers/hwtracing/coresight/Kconfig
> +++ b/drivers/hwtracing/coresight/Kconfig
> @@ -89,4 +89,12 @@ config CORESIGHT_STM
> logging useful software events or data coming from various entities
> in the system, possibly running different OSs
>  
> +config CORESIGHT_DEBUG
> + bool "CoreSight debug driver"
> + depends on ARM || ARM64
> + help
> +   This driver provides support for coresight debugging module. This
> +   is primarily used for printing out debug registers for panic and
> +   soft and hard lockup.
> +
>  endif
> diff --git a/drivers/hwtracing/coresight/Makefile 
> b/drivers/hwtracing/coresight/Makefile
> index af480d9..d540d45 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
>   coresight-etm4x-sysfs.o
>  obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
>  obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
> +obj-$(CONFIG_CORESIGHT_DEBUG) += coresight-debug.o
> diff --git a/drivers/hwtracing/coresight/coresight-debug.c 
> b/drivers/hwtracing/coresight/coresight-debug.c
> new file mode 100644
> index 000..28206a83
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-debug.c
> @@ -0,0 +1,169 @@
> +/*
> + * Copyright(C) 2017 Linaro Limited. All rights reserved.
> + * Author: Leo Yan 
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful, but 
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program.  If not, see .
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

When possible, please try to order the header files alphabetically.

> +
> +#include "coresight-priv.h"
> +
> +#define EDPCSR_LO0x0A0
> +#define EDPCSR_HI0x0AC
> +#define EDOSLAR  0x300
> +#define EDOSLSR  0x304
> +#define EDPDCR   0x310
> +#define EDPDSR   0x314

EDOSLSR, DEPDCR and EDPDSR aren't used in the code presented below.

> +
> +struct debug_drvdata {
> + void __iomem*base;
> + struct device   *dev;
> + int cpu;
> +};
> +
> +static struct debug_drvdata *debug_drvdata[NR_CPUS];
> +
> +static void debug_os_unlock(struct debug_drvdata *drvdata)
> +{
> + /* Unlocks the debug registers */
> + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> + isb();
> +}
> +
> +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> +{
> + u32 pcsr_hi, pcsr_lo;
> +
> + CS_UNLOCK(drvdata->base);
> +
> + debug_os_unlock(drvdata);
> +
> +#ifdef CONFIG_64BIT
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> + pcsr_hi 

Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-15 Thread Mark Rutland
[resending due to a mail server snafu]

On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> Coresight includes debug module and usually the module connects with CPU
> debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> the debug registers in the chapter "H9: External Debug Register
> Descriptions".

This should have been in the binding description also.

The layout of the ARM ARM can change over time, so please refer to the
full document number, which can be found at the bottom of each page
(e.g. ARM DDI 0487A.j).

> After enable the debug module we can check CPU state and PC value, etc.
> So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> into infinite loop with IRQ disabled. So the CPU cannot switch context
> and handle any interrupt, so it cannot handle SMP call for stack dump,
> etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> firmware and cannot return back to kernel.

I would generally expect that the secure world would lock down
debugging, as this poses a security risk.

I take it that this is only unlocked on development firmware.

Given that cores can be powered down outside of our control, I'm not
sure that accesses to these registers is safe in general.

> This patch is to enable coresight debug module and register callback
> notifier for panic; so when system detect the CPU lockup we can utilize
> debug module registers to get to know PC value for all CPUs; so we can
> quickly know the hang address for CPUs.
> 
> This is initial driver for coresight debug module and could enhance it
> later according to debugging requirement.

How does this interact with an external debugger making use of these
registers?

[...]

> +static struct debug_drvdata *debug_drvdata[NR_CPUS];

A per-cpu variable is preferred to an NR_CPUS sized array.

> +
> +static void debug_os_unlock(struct debug_drvdata *drvdata)
> +{
> + /* Unlocks the debug registers */
> + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> + isb();
> +}

I do not believe this barrier is correct.

[...]

> +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> +{
> + u32 pcsr_hi, pcsr_lo;
> +
> + CS_UNLOCK(drvdata->base);
> +
> + debug_os_unlock(drvdata);
> +
> +#ifdef CONFIG_64BIT
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> + pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> +
> + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
> +  ((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
> +#else
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> +
> + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
> +#endif
> +
> + CS_LOCK(drvdata->base);
> +}

Per ARM DDI 0487A.k_iss10775, H9.2.32, "EDPCSR, External Debug Program
Counter Sample Register":

Implemented only if the OPTIONAL PC Sample-based Profiling
Extension is implemented.

So even if we have access to an MMIO debug interface, we cannot
necessarily acecess this register.

[...]

> +/*
> + * Dump out memory limit information on panic.
> + */
> +static int dump_debug(struct notifier_block *self, unsigned long v, void *p)
> +{
> + int i;
> +
> + pr_emerg("Coresight debug module:\n");
> +
> + for_each_possible_cpu(i) {
> +
> + if (!debug_drvdata[i])
> + continue;
> +
> + debug_read_pcsr(debug_drvdata[i]);
> + }

Is there no potential for deadlock with a CPU reading its own debug
interface registers?

[...]

> +static struct amba_id debug_ids[] = {
> + {   /* Debug for Cortex-A53 */
> + .id = 0x000bbd03,
> + .mask   = 0x000f,
> + .data   = "debug",
> + },
> + { 0, 0},
> +};

The DT binding said nothing about Cortex-A53.

How variable are the MMIO registers in practice? Do we need to know the
particular CPU?

Thanks,
Mark.


Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-15 Thread Mark Rutland
[resending due to a mail server snafu]

On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> Coresight includes debug module and usually the module connects with CPU
> debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> the debug registers in the chapter "H9: External Debug Register
> Descriptions".

This should have been in the binding description also.

The layout of the ARM ARM can change over time, so please refer to the
full document number, which can be found at the bottom of each page
(e.g. ARM DDI 0487A.j).

> After enable the debug module we can check CPU state and PC value, etc.
> So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> into infinite loop with IRQ disabled. So the CPU cannot switch context
> and handle any interrupt, so it cannot handle SMP call for stack dump,
> etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> firmware and cannot return back to kernel.

I would generally expect that the secure world would lock down
debugging, as this poses a security risk.

I take it that this is only unlocked on development firmware.

Given that cores can be powered down outside of our control, I'm not
sure that accesses to these registers is safe in general.

> This patch is to enable coresight debug module and register callback
> notifier for panic; so when system detect the CPU lockup we can utilize
> debug module registers to get to know PC value for all CPUs; so we can
> quickly know the hang address for CPUs.
> 
> This is initial driver for coresight debug module and could enhance it
> later according to debugging requirement.

How does this interact with an external debugger making use of these
registers?

[...]

> +static struct debug_drvdata *debug_drvdata[NR_CPUS];

A per-cpu variable is preferred to an NR_CPUS sized array.

> +
> +static void debug_os_unlock(struct debug_drvdata *drvdata)
> +{
> + /* Unlocks the debug registers */
> + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> + isb();
> +}

I do not believe this barrier is correct.

[...]

> +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> +{
> + u32 pcsr_hi, pcsr_lo;
> +
> + CS_UNLOCK(drvdata->base);
> +
> + debug_os_unlock(drvdata);
> +
> +#ifdef CONFIG_64BIT
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> + pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> +
> + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
> +  ((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
> +#else
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> +
> + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
> +#endif
> +
> + CS_LOCK(drvdata->base);
> +}

Per ARM DDI 0487A.k_iss10775, H9.2.32, "EDPCSR, External Debug Program
Counter Sample Register":

Implemented only if the OPTIONAL PC Sample-based Profiling
Extension is implemented.

So even if we have access to an MMIO debug interface, we cannot
necessarily acecess this register.

[...]

> +/*
> + * Dump out memory limit information on panic.
> + */
> +static int dump_debug(struct notifier_block *self, unsigned long v, void *p)
> +{
> + int i;
> +
> + pr_emerg("Coresight debug module:\n");
> +
> + for_each_possible_cpu(i) {
> +
> + if (!debug_drvdata[i])
> + continue;
> +
> + debug_read_pcsr(debug_drvdata[i]);
> + }

Is there no potential for deadlock with a CPU reading its own debug
interface registers?

[...]

> +static struct amba_id debug_ids[] = {
> + {   /* Debug for Cortex-A53 */
> + .id = 0x000bbd03,
> + .mask   = 0x000f,
> + .data   = "debug",
> + },
> + { 0, 0},
> +};

The DT binding said nothing about Cortex-A53.

How variable are the MMIO registers in practice? Do we need to know the
particular CPU?

Thanks,
Mark.


Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-15 Thread Mark Rutland
On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> Coresight includes debug module and usually the module connects with CPU
> debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> the debug registers in the chapter "H9: External Debug Register
> Descriptions".

This should have been in the binding description also.

The layout of the ARM ARM can change over time, so please refer to the
full document number, which can be found at the bottom of each page
(e.g. ARM DDI 0487A.j).

> After enable the debug module we can check CPU state and PC value, etc.
> So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> into infinite loop with IRQ disabled. So the CPU cannot switch context
> and handle any interrupt, so it cannot handle SMP call for stack dump,
> etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> firmware and cannot return back to kernel.

I would generally expect that the secure world would lock down
debugging, as this poses a security risk.

I take it that this is only unlocked on development firmware.

Given that cores can be powered down outside of our control, I'm not
sure that accesses to these registers is safe in general.

> This patch is to enable coresight debug module and register callback
> notifier for panic; so when system detect the CPU lockup we can utilize
> debug module registers to get to know PC value for all CPUs; so we can
> quickly know the hang address for CPUs.
>
> This is initial driver for coresight debug module and could enhance it
> later according to debugging requirement.

How does this interact with an external debugger making use of these
registers?

[...]

> +static struct debug_drvdata *debug_drvdata[NR_CPUS];

A per-cpu variable is preferred to an NR_CPUS sized array.

> +
> +static void debug_os_unlock(struct debug_drvdata *drvdata)
> +{
> + /* Unlocks the debug registers */
> + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> + isb();
> +}

I do not believe this barrier is correct.

[...]

> +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> +{
> + u32 pcsr_hi, pcsr_lo;
> +
> + CS_UNLOCK(drvdata->base);
> +
> + debug_os_unlock(drvdata);
> +
> +#ifdef CONFIG_64BIT
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> + pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> +
> + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
> +  ((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
> +#else
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> +
> + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
> +#endif
> +
> + CS_LOCK(drvdata->base);
> +}

Per ARM DDI 0487A.k_iss10775, H9.2.32, "EDPCSR, External Debug Program
Counter Sample Register":

Implemented only if the OPTIONAL PC Sample-based Profiling
Extension is implemented.

So even if we have access to an MMIO debug interface, we cannot
necessarily acecess this register.

[...]

> +/*
> + * Dump out memory limit information on panic.
> + */
> +static int dump_debug(struct notifier_block *self, unsigned long v, void *p)
> +{
> + int i;
> +
> + pr_emerg("Coresight debug module:\n");
> +
> + for_each_possible_cpu(i) {
> +
> + if (!debug_drvdata[i])
> + continue;
> +
> + debug_read_pcsr(debug_drvdata[i]);
> + }

Is there no potential for deadlock with a CPU reading its own debug
interface registers?

[...]

> +static struct amba_id debug_ids[] = {
> + {   /* Debug for Cortex-A53 */
> + .id = 0x000bbd03,
> + .mask   = 0x000f,
> + .data   = "debug",
> + },
> + { 0, 0},
> +};

The DT binding said nothing about Cortex-A53.

How variable are the MMIO registers in practice? Do we need to know the
particular CPU?

Thanks,
Mark.
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.


Re: [PATCH RFC 2/3] coresight: add support for debug module

2017-02-15 Thread Mark Rutland
On Mon, Feb 13, 2017 at 02:11:37PM +0800, Leo Yan wrote:
> Coresight includes debug module and usually the module connects with CPU
> debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
> the debug registers in the chapter "H9: External Debug Register
> Descriptions".

This should have been in the binding description also.

The layout of the ARM ARM can change over time, so please refer to the
full document number, which can be found at the bottom of each page
(e.g. ARM DDI 0487A.j).

> After enable the debug module we can check CPU state and PC value, etc.
> So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
> into infinite loop with IRQ disabled. So the CPU cannot switch context
> and handle any interrupt, so it cannot handle SMP call for stack dump,
> etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
> ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
> firmware and cannot return back to kernel.

I would generally expect that the secure world would lock down
debugging, as this poses a security risk.

I take it that this is only unlocked on development firmware.

Given that cores can be powered down outside of our control, I'm not
sure that accesses to these registers is safe in general.

> This patch is to enable coresight debug module and register callback
> notifier for panic; so when system detect the CPU lockup we can utilize
> debug module registers to get to know PC value for all CPUs; so we can
> quickly know the hang address for CPUs.
>
> This is initial driver for coresight debug module and could enhance it
> later according to debugging requirement.

How does this interact with an external debugger making use of these
registers?

[...]

> +static struct debug_drvdata *debug_drvdata[NR_CPUS];

A per-cpu variable is preferred to an NR_CPUS sized array.

> +
> +static void debug_os_unlock(struct debug_drvdata *drvdata)
> +{
> + /* Unlocks the debug registers */
> + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> + isb();
> +}

I do not believe this barrier is correct.

[...]

> +static void debug_read_pcsr(struct debug_drvdata *drvdata)
> +{
> + u32 pcsr_hi, pcsr_lo;
> +
> + CS_UNLOCK(drvdata->base);
> +
> + debug_os_unlock(drvdata);
> +
> +#ifdef CONFIG_64BIT
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> + pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> +
> + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
> +  ((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
> +#else
> + pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
> +
> + pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
> +#endif
> +
> + CS_LOCK(drvdata->base);
> +}

Per ARM DDI 0487A.k_iss10775, H9.2.32, "EDPCSR, External Debug Program
Counter Sample Register":

Implemented only if the OPTIONAL PC Sample-based Profiling
Extension is implemented.

So even if we have access to an MMIO debug interface, we cannot
necessarily acecess this register.

[...]

> +/*
> + * Dump out memory limit information on panic.
> + */
> +static int dump_debug(struct notifier_block *self, unsigned long v, void *p)
> +{
> + int i;
> +
> + pr_emerg("Coresight debug module:\n");
> +
> + for_each_possible_cpu(i) {
> +
> + if (!debug_drvdata[i])
> + continue;
> +
> + debug_read_pcsr(debug_drvdata[i]);
> + }

Is there no potential for deadlock with a CPU reading its own debug
interface registers?

[...]

> +static struct amba_id debug_ids[] = {
> + {   /* Debug for Cortex-A53 */
> + .id = 0x000bbd03,
> + .mask   = 0x000f,
> + .data   = "debug",
> + },
> + { 0, 0},
> +};

The DT binding said nothing about Cortex-A53.

How variable are the MMIO registers in practice? Do we need to know the
particular CPU?

Thanks,
Mark.
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.


[PATCH RFC 2/3] coresight: add support for debug module

2017-02-12 Thread Leo Yan
Coresight includes debug module and usually the module connects with CPU
debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
the debug registers in the chapter "H9: External Debug Register
Descriptions".

After enable the debug module we can check CPU state and PC value, etc.
So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
into infinite loop with IRQ disabled. So the CPU cannot switch context
and handle any interrupt, so it cannot handle SMP call for stack dump,
etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
firmware and cannot return back to kernel.

This patch is to enable coresight debug module and register callback
notifier for panic; so when system detect the CPU lockup we can utilize
debug module registers to get to know PC value for all CPUs; so we can
quickly know the hang address for CPUs.

This is initial driver for coresight debug module and could enhance it
later according to debugging requirement.

Signed-off-by: Leo Yan 
---
 drivers/hwtracing/coresight/Kconfig   |   8 ++
 drivers/hwtracing/coresight/Makefile  |   1 +
 drivers/hwtracing/coresight/coresight-debug.c | 169 ++
 3 files changed, 178 insertions(+)
 create mode 100644 drivers/hwtracing/coresight/coresight-debug.c

diff --git a/drivers/hwtracing/coresight/Kconfig 
b/drivers/hwtracing/coresight/Kconfig
index 130cb21..dcf59cc 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -89,4 +89,12 @@ config CORESIGHT_STM
  logging useful software events or data coming from various entities
  in the system, possibly running different OSs
 
+config CORESIGHT_DEBUG
+   bool "CoreSight debug driver"
+   depends on ARM || ARM64
+   help
+ This driver provides support for coresight debugging module. This
+ is primarily used for printing out debug registers for panic and
+ soft and hard lockup.
+
 endif
diff --git a/drivers/hwtracing/coresight/Makefile 
b/drivers/hwtracing/coresight/Makefile
index af480d9..d540d45 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
coresight-etm4x-sysfs.o
 obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
 obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
+obj-$(CONFIG_CORESIGHT_DEBUG) += coresight-debug.o
diff --git a/drivers/hwtracing/coresight/coresight-debug.c 
b/drivers/hwtracing/coresight/coresight-debug.c
new file mode 100644
index 000..28206a83
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-debug.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright(C) 2017 Linaro Limited. All rights reserved.
+ * Author: Leo Yan 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "coresight-priv.h"
+
+#define EDPCSR_LO  0x0A0
+#define EDPCSR_HI  0x0AC
+#define EDOSLAR0x300
+#define EDOSLSR0x304
+#define EDPDCR 0x310
+#define EDPDSR 0x314
+
+struct debug_drvdata {
+   void __iomem*base;
+   struct device   *dev;
+   int cpu;
+};
+
+static struct debug_drvdata *debug_drvdata[NR_CPUS];
+
+static void debug_os_unlock(struct debug_drvdata *drvdata)
+{
+   /* Unlocks the debug registers */
+   writel_relaxed(0x0, drvdata->base + EDOSLAR);
+   isb();
+}
+
+static void debug_read_pcsr(struct debug_drvdata *drvdata)
+{
+   u32 pcsr_hi, pcsr_lo;
+
+   CS_UNLOCK(drvdata->base);
+
+   debug_os_unlock(drvdata);
+
+#ifdef CONFIG_64BIT
+   pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
+   pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
+
+   pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
+((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
+#else
+   pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
+
+   pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
+#endif
+
+   CS_LOCK(drvdata->base);
+}
+
+/*
+ * Dump out memory limit information on 

[PATCH RFC 2/3] coresight: add support for debug module

2017-02-12 Thread Leo Yan
Coresight includes debug module and usually the module connects with CPU
debug logic. ARMv8 architecture reference manual (ARMv8-ARM) has defined
the debug registers in the chapter "H9: External Debug Register
Descriptions".

After enable the debug module we can check CPU state and PC value, etc.
So this is helpful for some CPU lockup bugs, e.g. if one CPU has run
into infinite loop with IRQ disabled. So the CPU cannot switch context
and handle any interrupt, so it cannot handle SMP call for stack dump,
etc. Furthermore, now ARMv8 introduces some other runtime firmwares like
ARM trusted firmware BL31, so sometime CPU hard lock may happen in the
firmware and cannot return back to kernel.

This patch is to enable coresight debug module and register callback
notifier for panic; so when system detect the CPU lockup we can utilize
debug module registers to get to know PC value for all CPUs; so we can
quickly know the hang address for CPUs.

This is initial driver for coresight debug module and could enhance it
later according to debugging requirement.

Signed-off-by: Leo Yan 
---
 drivers/hwtracing/coresight/Kconfig   |   8 ++
 drivers/hwtracing/coresight/Makefile  |   1 +
 drivers/hwtracing/coresight/coresight-debug.c | 169 ++
 3 files changed, 178 insertions(+)
 create mode 100644 drivers/hwtracing/coresight/coresight-debug.c

diff --git a/drivers/hwtracing/coresight/Kconfig 
b/drivers/hwtracing/coresight/Kconfig
index 130cb21..dcf59cc 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -89,4 +89,12 @@ config CORESIGHT_STM
  logging useful software events or data coming from various entities
  in the system, possibly running different OSs
 
+config CORESIGHT_DEBUG
+   bool "CoreSight debug driver"
+   depends on ARM || ARM64
+   help
+ This driver provides support for coresight debugging module. This
+ is primarily used for printing out debug registers for panic and
+ soft and hard lockup.
+
 endif
diff --git a/drivers/hwtracing/coresight/Makefile 
b/drivers/hwtracing/coresight/Makefile
index af480d9..d540d45 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
coresight-etm4x-sysfs.o
 obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
 obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
+obj-$(CONFIG_CORESIGHT_DEBUG) += coresight-debug.o
diff --git a/drivers/hwtracing/coresight/coresight-debug.c 
b/drivers/hwtracing/coresight/coresight-debug.c
new file mode 100644
index 000..28206a83
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-debug.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright(C) 2017 Linaro Limited. All rights reserved.
+ * Author: Leo Yan 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "coresight-priv.h"
+
+#define EDPCSR_LO  0x0A0
+#define EDPCSR_HI  0x0AC
+#define EDOSLAR0x300
+#define EDOSLSR0x304
+#define EDPDCR 0x310
+#define EDPDSR 0x314
+
+struct debug_drvdata {
+   void __iomem*base;
+   struct device   *dev;
+   int cpu;
+};
+
+static struct debug_drvdata *debug_drvdata[NR_CPUS];
+
+static void debug_os_unlock(struct debug_drvdata *drvdata)
+{
+   /* Unlocks the debug registers */
+   writel_relaxed(0x0, drvdata->base + EDOSLAR);
+   isb();
+}
+
+static void debug_read_pcsr(struct debug_drvdata *drvdata)
+{
+   u32 pcsr_hi, pcsr_lo;
+
+   CS_UNLOCK(drvdata->base);
+
+   debug_os_unlock(drvdata);
+
+#ifdef CONFIG_64BIT
+   pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
+   pcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
+
+   pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu,
+((unsigned long)pcsr_hi << 32 | (unsigned long)pcsr_lo));
+#else
+   pcsr_lo = readl_relaxed(drvdata->base + EDPCSR_LO);
+
+   pr_emerg("CPU[%d]: PSCR=0x%lx\n", drvdata->cpu, pcsr_lo);
+#endif
+
+   CS_LOCK(drvdata->base);
+}
+
+/*
+ * Dump out memory limit information on panic.
+ */
+static int