Re: [PATCH v5 06/16] rpmsg: move the rpmsg control device from rpmsg_char to rpmsg_ctrl

2021-03-02 Thread Mathieu Poirier
On Fri, Feb 19, 2021 at 12:14:51PM +0100, Arnaud Pouliquen wrote:
> Move the code related to the rpmsg_ctrl char device to the new
> rpmsg_ctrl.c module.
> Manage the dependency in the kconfig.
> 
> Signed-off-by: Arnaud Pouliquen 
> ---
>  drivers/rpmsg/Kconfig  |   9 ++
>  drivers/rpmsg/Makefile |   1 +
>  drivers/rpmsg/rpmsg_char.c | 163 
>  drivers/rpmsg/rpmsg_ctrl.c | 216 +
>  4 files changed, 226 insertions(+), 163 deletions(-)
>  create mode 100644 drivers/rpmsg/rpmsg_ctrl.c
> 
> diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
> index 0b4407abdf13..2d0cd7fdd710 100644
> --- a/drivers/rpmsg/Kconfig
> +++ b/drivers/rpmsg/Kconfig
> @@ -10,11 +10,20 @@ config RPMSG_CHAR
>   tristate "RPMSG device interface"
>   depends on RPMSG
>   depends on NET
> + select RPMSG_CTRL
>   help
> Say Y here to export rpmsg endpoints as device files, usually found
> in /dev. They make it possible for user-space programs to send and
> receive rpmsg packets.
>  
> +config RPMSG_CTRL
> + tristate "RPMSG control interface"
> + depends on RPMSG
> + help
> +   Say Y here to enable the support of the /dev/rpmsg_ctlX API. This API

s/rpmsg_ctlX/rpmsg_ctrlX

> +   allows user-space programs to create endpoints with specific service 
> name,
> +   source and destination addresses.
> +
>  config RPMSG_NS
>   tristate "RPMSG name service announcement"
>   depends on RPMSG
> diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
> index 8d452656f0ee..58e3b382e316 100644
> --- a/drivers/rpmsg/Makefile
> +++ b/drivers/rpmsg/Makefile
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_RPMSG)  += rpmsg_core.o
>  obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o
> +obj-$(CONFIG_RPMSG_CTRL) += rpmsg_ctrl.o
>  obj-$(CONFIG_RPMSG_NS)   += rpmsg_ns.o
>  obj-$(CONFIG_RPMSG_MTK_SCP)  += mtk_rpmsg.o
>  qcom_glink-objs  := qcom_glink_native.o qcom_glink_ssr.o
> diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
> index 23e369a00531..83c10b39b139 100644
> --- a/drivers/rpmsg/rpmsg_char.c
> +++ b/drivers/rpmsg/rpmsg_char.c
> @@ -31,28 +31,12 @@
>  static dev_t rpmsg_major;
>  static struct class *rpmsg_class;
>  
> -static DEFINE_IDA(rpmsg_ctrl_ida);
>  static DEFINE_IDA(rpmsg_ept_ida);
>  static DEFINE_IDA(rpmsg_minor_ida);
>  
>  #define dev_to_eptdev(dev) container_of(dev, struct rpmsg_eptdev, dev)
>  #define cdev_to_eptdev(i_cdev) container_of(i_cdev, struct rpmsg_eptdev, 
> cdev)
>  
> -#define dev_to_ctrldev(dev) container_of(dev, struct rpmsg_ctrldev, dev)
> -#define cdev_to_ctrldev(i_cdev) container_of(i_cdev, struct rpmsg_ctrldev, 
> cdev)
> -
> -/**
> - * struct rpmsg_ctrldev - control device for instantiating endpoint devices
> - * @rpdev:   underlaying rpmsg device
> - * @cdev:cdev for the ctrl device
> - * @dev: device for the ctrl device
> - */
> -struct rpmsg_ctrldev {
> - struct rpmsg_device *rpdev;
> - struct cdev cdev;
> - struct device dev;
> -};

This showed up in rpmsg_ctrl.c as rpmsg_ctrl.  The same goes for many functions
names - they are removed here and re-introduced under a different name, which
makes it very hard to follow.  What ends up in the new file should be a carbon
copy of what was moved.

I'm out of time for today, more comments tomorrow.

Thanks,
Mathieu

> -
>  /**
>   * struct rpmsg_eptdev - endpoint device context
>   * @dev: endpoint device
> @@ -411,145 +395,6 @@ int rpmsg_chrdev_create_eptdev(struct rpmsg_device 
> *rpdev, struct device *parent
>  }
>  EXPORT_SYMBOL(rpmsg_chrdev_create_eptdev);
>  
> -static int rpmsg_ctrldev_open(struct inode *inode, struct file *filp)
> -{
> - struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev);
> -
> - get_device(>dev);
> - filp->private_data = ctrldev;
> -
> - return 0;
> -}
> -
> -static int rpmsg_ctrldev_release(struct inode *inode, struct file *filp)
> -{
> - struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev);
> -
> - put_device(>dev);
> -
> - return 0;
> -}
> -
> -static long rpmsg_ctrldev_ioctl(struct file *fp, unsigned int cmd,
> - unsigned long arg)
> -{
> - struct rpmsg_ctrldev *ctrldev = fp->private_data;
> - void __user *argp = (void __user *)arg;
> - struct rpmsg_endpoint_info eptinfo;
> - struct rpmsg_channel_info chinfo;
> -
> - if (cmd != RPMSG_CREATE_EPT_IOCTL)
> - return -EINVAL;
> -
> - if (copy_from_user(, argp, sizeof(eptinfo)))
> - return -EFAULT;
> -
> - memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
> - chinfo.name[RPMSG_NAME_SIZE-1] = '\0';
> - chinfo.src = eptinfo.src;
> - chinfo.dst = eptinfo.dst;
> -
> - return rpmsg_chrdev_create_eptdev(ctrldev->rpdev, >dev, 
> chinfo);
> -};
> -
> -static const struct file_operations 

Re: [PATCH v5 04/16] rpmsg: char: export eptdev create an destroy functions

2021-03-02 Thread Mathieu Poirier
Good morning,

I have started to review this set - comments will be staggered over several
days.

On Fri, Feb 19, 2021 at 12:14:49PM +0100, Arnaud Pouliquen wrote:
> To prepare the split code related to the control and the endpoint
> devices in separate files:
> - suppress the dependency with the rpmsg_ctrldev struct,
> - rename and export the functions in rpmsg_char.h.
> 
> Suggested-by: Mathieu Poirier 
> Signed-off-by: Arnaud Pouliquen 
> ---
>  drivers/rpmsg/rpmsg_char.c | 22 ++--
>  drivers/rpmsg/rpmsg_char.h | 51 ++
>  2 files changed, 66 insertions(+), 7 deletions(-)
>  create mode 100644 drivers/rpmsg/rpmsg_char.h
> 
> diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
> index 9e33b53bbf56..78a6d19fdf82 100644
> --- a/drivers/rpmsg/rpmsg_char.c
> +++ b/drivers/rpmsg/rpmsg_char.c
> @@ -1,5 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /*
> + * Copyright (C) 2021, STMicroelectronics
>   * Copyright (c) 2016, Linaro Ltd.
>   * Copyright (c) 2012, Michal Simek 
>   * Copyright (c) 2012, PetaLogix
> @@ -22,6 +23,7 @@
>  #include 
>  #include 
>  
> +#include "rpmsg_char.h"
>  #include "rpmsg_internal.h"
>  
>  #define RPMSG_DEV_MAX(MINORMASK + 1)
> @@ -78,7 +80,7 @@ struct rpmsg_eptdev {
>   wait_queue_head_t readq;
>  };
>  
> -static int rpmsg_eptdev_destroy(struct device *dev, void *data)
> +static int rpmsg_eptdev_destroy(struct device *dev)
>  {
>   struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
>  
> @@ -277,7 +279,7 @@ static long rpmsg_eptdev_ioctl(struct file *fp, unsigned 
> int cmd,
>   if (cmd != RPMSG_DESTROY_EPT_IOCTL)
>   return -EINVAL;
>  
> - return rpmsg_eptdev_destroy(>dev, NULL);
> + return rpmsg_eptdev_destroy(>dev);
>  }
>  
>  static const struct file_operations rpmsg_eptdev_fops = {
> @@ -336,10 +338,15 @@ static void rpmsg_eptdev_release_device(struct device 
> *dev)
>   kfree(eptdev);
>  }
>  
> -static int rpmsg_eptdev_create(struct rpmsg_ctrldev *ctrldev,
> +int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
> +{
> + return rpmsg_eptdev_destroy(dev);
> +}
> +EXPORT_SYMBOL(rpmsg_chrdev_eptdev_destroy);

Below we have rpmsg_chrdev_create_eptdev() so it would make sense to have
rpmsg_chrdev_destroy_ept().

I would also rename rpmsg_eptdev_destroy() to rpmsg_chrdev_destroy_ept() and
export that symbol rather than introducing a function that only calls another
one.  You did exactly that for rpmsg_chrdev_create_eptdev().

> +
> +int rpmsg_chrdev_create_eptdev(struct rpmsg_device *rpdev, struct device 
> *parent,
>  struct rpmsg_channel_info chinfo)
>  {
> - struct rpmsg_device *rpdev = ctrldev->rpdev;
>   struct rpmsg_eptdev *eptdev;
>   struct device *dev;
>   int ret;
> @@ -359,7 +366,7 @@ static int rpmsg_eptdev_create(struct rpmsg_ctrldev 
> *ctrldev,
>  
>   device_initialize(dev);
>   dev->class = rpmsg_class;
> - dev->parent = >dev;
> + dev->parent = parent;
>   dev->groups = rpmsg_eptdev_groups;
>   dev_set_drvdata(dev, eptdev);
>  
> @@ -402,6 +409,7 @@ static int rpmsg_eptdev_create(struct rpmsg_ctrldev 
> *ctrldev,
>  
>   return ret;
>  }
> +EXPORT_SYMBOL(rpmsg_chrdev_create_eptdev);
>  
>  static int rpmsg_ctrldev_open(struct inode *inode, struct file *filp)
>  {
> @@ -441,7 +449,7 @@ static long rpmsg_ctrldev_ioctl(struct file *fp, unsigned 
> int cmd,
>   chinfo.src = eptinfo.src;
>   chinfo.dst = eptinfo.dst;
>  
> - return rpmsg_eptdev_create(ctrldev, chinfo);
> + return rpmsg_chrdev_create_eptdev(ctrldev->rpdev, >dev, 
> chinfo);

Not sure why we have to change the signature of rpmsg_eptdev_create() but I may
find an answer to that question later on in the patchset.

>  };
>  
>  static const struct file_operations rpmsg_ctrldev_fops = {
> @@ -527,7 +535,7 @@ static void rpmsg_chrdev_remove(struct rpmsg_device 
> *rpdev)
>   int ret;
>  
>   /* Destroy all endpoints */
> - ret = device_for_each_child(>dev, NULL, rpmsg_eptdev_destroy);
> + ret = device_for_each_child(>dev, NULL, 
> rpmsg_chrdev_eptdev_destroy);
>   if (ret)
>   dev_warn(>dev, "failed to nuke endpoints: %d\n", ret);
>  
> diff --git a/drivers/rpmsg/rpmsg_char.h b/drivers/rpmsg/rpmsg_char.h
> new file mode 100644
> index ..0feb3ea9445c
> --- /dev/null
> +++ b/drivers/rpmsg/rpmsg_char.h
> @@ -0,0 +1,51 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> + * Copyright (C) STMicroelectronics

Re: [PATCH v5 05/16] rpmsg: char: dissociate the control device from the rpmsg class

2021-03-02 Thread Mathieu Poirier
On Fri, Feb 19, 2021 at 12:14:50PM +0100, Arnaud Pouliquen wrote:
> The RPMsg control device is a RPMsg device, it is already
> referenced in the RPMsg bus. There is only an interest to
> reference the ept char devices in the rpmsg class.
> This patch prepares the code split of the control and end point
> devices in two separate files.
> 
> Signed-off-by: Arnaud Pouliquen 
> ---
>  drivers/rpmsg/rpmsg_char.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
> index 78a6d19fdf82..23e369a00531 100644
> --- a/drivers/rpmsg/rpmsg_char.c
> +++ b/drivers/rpmsg/rpmsg_char.c
> @@ -485,7 +485,6 @@ static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev)
>   dev = >dev;
>   device_initialize(dev);
>   dev->parent = >dev;
> - dev->class = rpmsg_class;

This may break user space...  It has been around for so long that even if the
information is redundant we have to keep it.

>  
>   cdev_init(>cdev, _ctrldev_fops);
>   ctrldev->cdev.owner = THIS_MODULE;
> -- 
> 2.17.1
> 


Re: [PATCH 0/6] coresight: Patches for v5.12 (perf tools)

2021-03-02 Thread Mathieu Poirier
On Tue, Mar 02, 2021 at 01:24:27PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Mar 02, 2021 at 02:23:14PM +, Mike Leach escreveu:
> > On Tue, 2 Mar 2021 at 12:52, Arnaldo Carvalho de Melo  
> > wrote:
> > > Em Wed, Feb 24, 2021 at 09:48:29AM -0700, Mathieu Poirier escreveu:
> > > > I noticed there is a couple of patchsets [1][2] that haven't made it
> > > > to your tree for the coming v5.12 cycle.  Do you think that can still
> > > > be done?
> 
> > > > I tallied the patches here to make it easier for you to pick up.
> 
> > > > Applies cleanly on perf/core (84b7725536d8)
> 
> > > > [1]. 
> > > > https://lore.kernel.org/lkml/20210202214040.32349-1-mike.le...@linaro.org/
> > > > [2]. 
> > > > https://lore.kernel.org/lkml/20210213113220.292229-1-leo@linaro.org/
> 
> > > These are not applying right now, I've pushed what I have to
> > > tmp.perf/core, please take a look, I'll get back to this after
> > > processing fixes for v5.12 and what is outstanding for v5.13.
>  
> > I've tried [1] on both Linux-5.12-rc1 and your tmp.perf/core and it
> > applies cleanly on both.
> 
> Can you please try one more time, these are the last csets on this
> branch:
> 
>   $ git log --oneline acme/tmp.perf/core -10
>   8e1488a46dcf73b1 (HEAD -> perf/core, five/perf/core, acme/tmp.perf/core, 
> acme.korg/tmp.perf/core) perf cs-etm: Detect pid in VMID for kernel running 
> at EL2
>   47f0d94c203751dd perf cs-etm: Add helper cs_etm__get_pid_fmt()
>   30cb76aabfb4deab perf cs-etm: Support PID tracing in config
>   8c559e8d68630d64 perf cs-etm: Fix bitmap for option
>   2bb4ccbd95d7fbf5 tools headers UAPI: Update tools' copy of 
> linux/coresight-pmu.h
>   42b2b570b34afb5f perf cs-etm: Update ETM metadata format
>   83bf6fb8b076c72f perf vendor events power9: Remove unsupported metrics
>   34968b9327c83589 perf buildid-cache: Add test for PE executable
>   9bb8b74bdb186bd3 perf docs: Add man pages to see also
>   d9fd5a718977702f perf tools: Generate mips syscalls_n64.c syscall table
>   $

As far as I can tell you have all 6 patches.

> 
> I think it doesn't apply because I applied a series from Mathieu
> touching files affected by those two patchkits.
> 
> - Arnaldo
>  
> > Let me know if there is anything else I can try.
> > 
> > Thanks
> > 
> > Mike
> > 
> > 
> > 
> > -- 
> > Mike Leach
> > Principal Engineer, ARM Ltd.
> > Manchester Design Centre. UK
> 
> -- 
> 
> - Arnaldo


Re: [PATCH v6 00/16] remoteproc: Add support for detaching a remote processor

2021-03-01 Thread Mathieu Poirier
On Fri, Feb 26, 2021 at 05:40:49PM +0100, Arnaud POULIQUEN wrote:
> Hi Mathieu,
> 
> On 2/24/21 12:34 AM, Mathieu Poirier wrote:
> > Following the work done here [1], this set provides support for the
> > remoteproc core to release resources associated with a remote processor
> > without having to switch it off. That way a platform driver can be removed
> > or the application processor power cycled while the remote processor is
> > still operating.
> > 
> > Modifications for this revision are detailed in the changelog of each patch
> > but the main difference is that going from RPROC_RUNNING -> RPROC_DETACHED
> > is no longer supported to avoid dealing tricky resource table issues.
> 
> This seems reasonable to me. If necessary, this could be part of a separate 
> series.
> 
> From test point of view, it is working pretty well on my side.

Thanks for taking a look a this.
Mathieu

> 
> Thanks,
> Arnaud
> 
> > 
> > Applies cleanly on rproc-next (e8b4e9a21af7).  I will rebase on 5.12-rc1 
> > when it
> > comes out next week.
> > 
> > Thanks,
> > Mathieu
> > 
> > Arnaud POULIQUEN (1):
> >   remoteproc: stm32: Move memory parsing to rproc_ops
> > 
> > Mathieu Poirier (15):
> >   remoteproc: Remove useless check in rproc_del()
> >   remoteproc: Rename function rproc_actuate()
> >   remoteproc: Add new RPROC_ATTACHED state
> >   remoteproc: Properly represent the attached state
> >   remoteproc: Add new get_loaded_rsc_table() to rproc_ops
> >   remoteproc: stm32: Move resource table setup to rproc_ops
> >   remoteproc: Add new detach() remoteproc operation
> >   remoteproc: Introduce function __rproc_detach()
> >   remoteproc: Introduce function rproc_detach()
> >   remoteproc: Properly deal with the resource table when attached
> >   remoteproc: Properly deal with a kernel panic when attached
> >   remoteproc: Properly deal with a start request when attached
> >   remoteproc: Properly deal with a stop request when attached
> >   remoteproc: Properly deal with a detach request when attached
> >   remoteproc: Refactor rproc delete and cdev release path
> > 
> >  drivers/remoteproc/remoteproc_cdev.c |  21 +-
> >  drivers/remoteproc/remoteproc_core.c | 263 ---
> >  drivers/remoteproc/remoteproc_internal.h |  10 +
> >  drivers/remoteproc/remoteproc_sysfs.c|  17 +-
> >  drivers/remoteproc/stm32_rproc.c | 168 +++
> >  include/linux/remoteproc.h   |  21 +-
> >  6 files changed, 362 insertions(+), 138 deletions(-)
> > 


Re: [PATCH v6 16/16] remoteproc: Refactor rproc delete and cdev release path

2021-03-01 Thread Mathieu Poirier
On Fri, Feb 26, 2021 at 05:23:45PM +0100, Arnaud POULIQUEN wrote:
> 
> 
> On 2/24/21 12:35 AM, Mathieu Poirier wrote:
> > Refactor function rproc_del() and rproc_cdev_release() to take
> > into account the current state of the remote processor when choosing
> > the state to transition to.
> > 
> > Signed-off-by: Mathieu Poirier 
> > ---
> > New for V6:
> > - The RPROC_RUNNING -> RPROC_DETACHED transition is no longer permitted.
> >   to avoid dealing with complex resource table management problems.
> > - Transition to the next state is no longer dictated by a DT binding for
> >   the same reason as above.
> > - Removed Peng and Arnaud's RB tags because of the above.
> > ---
> > 
> >  drivers/remoteproc/remoteproc_cdev.c | 10 --
> >  drivers/remoteproc/remoteproc_core.c |  9 +++--
> >  2 files changed, 15 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/remoteproc/remoteproc_cdev.c 
> > b/drivers/remoteproc/remoteproc_cdev.c
> > index 2db494816d5f..0b8a84c04f76 100644
> > --- a/drivers/remoteproc/remoteproc_cdev.c
> > +++ b/drivers/remoteproc/remoteproc_cdev.c
> > @@ -86,11 +86,17 @@ static long rproc_device_ioctl(struct file *filp, 
> > unsigned int ioctl, unsigned l
> >  static int rproc_cdev_release(struct inode *inode, struct file *filp)
> >  {
> > struct rproc *rproc = container_of(inode->i_cdev, struct rproc, cdev);
> > +   int ret = 0;
> > +
> > +   if (!rproc->cdev_put_on_release)
> > +   return 0;
> >  
> > -   if (rproc->cdev_put_on_release && rproc->state == RPROC_RUNNING)
> > +   if (rproc->state == RPROC_RUNNING)
> > rproc_shutdown(rproc);
> > +   else if (rproc->state == RPROC_ATTACHED)
> > +   ret = rproc_detach(rproc);
> >  
> > -   return 0;
> > +   return ret;
> >  }
> >  
> >  static const struct file_operations rproc_fops = {
> > diff --git a/drivers/remoteproc/remoteproc_core.c 
> > b/drivers/remoteproc/remoteproc_core.c
> > index 00452da25fba..a05d5fec43b1 100644
> > --- a/drivers/remoteproc/remoteproc_core.c
> > +++ b/drivers/remoteproc/remoteproc_core.c
> > @@ -2542,11 +2542,16 @@ EXPORT_SYMBOL(rproc_put);
> >   */
> >  int rproc_del(struct rproc *rproc)
> >  {
> > +   int ret = 0;
> > +
> > if (!rproc)
> > return -EINVAL;
> >  
> > /* TODO: make sure this works with rproc->power > 1 */
> > -   rproc_shutdown(rproc);
> > +   if (rproc->state == RPROC_RUNNING)
> > +   rproc_shutdown(rproc);
> > +   else if (rproc->state == RPROC_ATTACHED)
> > +   ret = rproc_detach(rproc);
> 
> Here i would not update the code to not change the existing behavior of an
> attached firmware.

Upon reflection your assessment is correct.  This is an unintended
consequence of separating the attach and detach funtionality in two patchset.
Fortunately it is easily fixed by calling rproc_detach() before rproc_del() in
the platform driver, or using the DT.

That being said we can't do much for rproc_cdev_release(), otherwise systems
that only support attach/detach functionality would be broken.

> The decision between a detach or a shutdown probably depends on platform.
> We could (as a next step) reintroduce the "autonomous-on-core-reboot" DT
> property for the decision.
> 
> Regards
> Arnaud
> 
> >  
> > mutex_lock(>lock);
> > rproc->state = RPROC_DELETED;
> > @@ -2565,7 +2570,7 @@ int rproc_del(struct rproc *rproc)
> >  
> > device_del(>dev);
> >  
> > -   return 0;
> > +   return ret;
> >  }
> >  EXPORT_SYMBOL(rproc_del);
> >  
> > 


Re: [PATCH v6 11/16] remoteproc: Properly deal with the resource table when attached

2021-03-01 Thread Mathieu Poirier
On Fri, Feb 26, 2021 at 05:21:15PM +0100, Arnaud POULIQUEN wrote:
> 
> 
> On 2/24/21 12:35 AM, Mathieu Poirier wrote:
> > If it is possible to detach the remote processor, keep an untouched
> > copy of the resource table.  That way we can start from the same
> > resource table without having to worry about original values or what
> > elements the startup code has changed when re-attaching to the remote
> > processor.
> > 
> > Signed-off-by: Mathieu Poirier 
> > ---
> > New for V6:
> > - Double free of the cached table has been fixed.
> > - rproc_reset_loaded_rsc_table() has seen a complete re-write.
> > - rproc_stop() now calls rproc_reset_loaded_rsc_table() rather than
> >   dealing with the cached.  This allows to properly shutdown a
> >   remote processor that was attached to.
> > ---
> > 
> >  drivers/remoteproc/remoteproc_core.c | 86 +++-
> >  include/linux/remoteproc.h   |  3 +
> >  2 files changed, 88 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/remoteproc/remoteproc_core.c 
> > b/drivers/remoteproc/remoteproc_core.c
> > index fc01b29290a6..3a4692cc5220 100644
> > --- a/drivers/remoteproc/remoteproc_core.c
> > +++ b/drivers/remoteproc/remoteproc_core.c
> > @@ -1556,6 +1556,21 @@ static int rproc_set_loaded_rsc_table(struct rproc 
> > *rproc)
> > return ret;
> > }
> >  
> > +   /*
> > +* If it is possible to detach the remote processor, keep an untouched
> > +* copy of the resource table.  That way we can start fresh again when
> > +* the remote processor is re-attached, that is:
> > +*
> > +*  DETACHED -> ATTACHED -> DETACHED -> ATTACHED
> > +*
> > +* Free'd in rproc_reset_loaded_rsc_table().
> > +*/
> > +   if (rproc->ops->detach) {
> > +   rproc->clean_table = kmemdup(table_ptr, table_sz, GFP_KERNEL);
> > +   if (!rproc->clean_table)
> > +   return -ENOMEM;
> > +   }
> > +
> > rproc->cached_table = NULL;
> > rproc->table_ptr = table_ptr;
> > rproc->table_sz = table_sz;
> > @@ -1563,6 +1578,65 @@ static int rproc_set_loaded_rsc_table(struct rproc 
> > *rproc)
> > return 0;
> >  }
> >  
> > +static int rproc_reset_loaded_rsc_table(struct rproc *rproc)
> 
> I spent some time to review this function that handles both the resource table
> for both the stop and detach. To make it easier to read, I would divide it 
> into
> two functions.

I suspected rproc_reset_loaded_rsc_table() was trying to do too many things for
its own good and you just confirmed that.

> I added a proposal at the end of this mail.
> 
> Regards,
> Arnaud
> 
> > +{
> > +   struct resource_table *table_ptr;
> > +
> > +   /*
> > +* The cached table is already set if the remote processor was started
> > +* by the remoteproc core.
> > +*/
> > +   if (rproc->state == RPROC_RUNNING) {
> > +   rproc->table_ptr = rproc->cached_table;
> > +   return 0;
> > +   }
> > +
> > +   /* A resource table was never retrieved, nothing to do here */
> > +   if (!rproc->table_ptr)
> > +   return 0;
> > +
> > +   /*
> > +* If we made it to this point a cached_table _must_ have been
> > +* allocated in rproc_set_loaded_rsc_table().  If one isn't present
> > +* something went really wrong and we must complain.
> > +*/
> > +   if (WARN_ON(!rproc->clean_table))
> > +   return -EINVAL;
> > +
> > +   /* Remember where the external entity installed the resource table */
> > +   table_ptr = rproc->table_ptr;
> > +
> > +   /*
> > +* Make a copy of the resource table currently used by the remote
> > +* processor.  Free'd in rproc_detach() or rproc_shutdown().
> > +*/
> > +   rproc->cached_table = kmemdup(rproc->table_ptr,
> > + rproc->table_sz, GFP_KERNEL);
> > +   if (!rproc->cached_table)
> > +   return -ENOMEM;
> > +
> > +   /*
> > +* Use a copy of the resource table for the remainder of the
> > +* shutdown process.
> > +*/
> > +   rproc->table_ptr = rproc->cached_table;
> > +
> > +   /*
> > +* Reset the memory area where the firmware loaded the resource table
> > +* to its original value.  That way when we re-attach the remote
> > +* processor the resource table is clean and ready to be u

Re: [PATCH v6 05/16] remoteproc: Add new get_loaded_rsc_table() to rproc_ops

2021-03-01 Thread Mathieu Poirier
On Fri, Feb 26, 2021 at 05:14:36PM +0100, Arnaud POULIQUEN wrote:
> Hi Mathieu,
> 

Good morning,

> On 2/24/21 12:35 AM, Mathieu Poirier wrote:
> > Add a new get_loaded_rsc_table() operation in order to support
> > scenarios where the remoteproc core has booted a remote processor
> > and detaches from it.  When re-attaching to the remote processor,
> > the core needs to know where the resource table has been placed
> > in memory.
> > 
> > Signed-off-by: Mathieu Poirier 
> > ---
> > New for V6:
> > - Don't return an error if a resource table doesn't exist.
> > ---
> > 
> >  drivers/remoteproc/remoteproc_core.c | 32 
> >  drivers/remoteproc/remoteproc_internal.h | 10 
> >  include/linux/remoteproc.h   |  6 -
> >  3 files changed, 47 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/remoteproc/remoteproc_core.c 
> > b/drivers/remoteproc/remoteproc_core.c
> > index 8c7e9f1d50d7..0012b7bdce24 100644
> > --- a/drivers/remoteproc/remoteproc_core.c
> > +++ b/drivers/remoteproc/remoteproc_core.c
> > @@ -1537,6 +1537,32 @@ static int rproc_fw_boot(struct rproc *rproc, const 
> > struct firmware *fw)
> > return ret;
> >  }
> >  
> > +static int rproc_set_loaded_rsc_table(struct rproc *rproc)
> > +{
> > +   struct resource_table *table_ptr;
> > +   struct device *dev = >dev;
> > +   size_t table_sz;
> > +   int ret;
> > +
> > +   table_ptr = rproc_get_loaded_rsc_table(rproc, _sz);
> > +   if (!table_ptr) {
> > +   /* Not having a resource table is acceptable */
> > +   return 0;
> 
> Would it be an over protection to set rproc->table_ptr to NULL here?
> 

I thought about that too but since memory for @rproc is allocated with kzalloc()
it wouldn't provide anything more. 

> else
> 
> Reviewed-by: Arnaud Pouliquen 
> 
> Thanks,
> Arnaud
> 
> > +   }
> > +
> > +   if (IS_ERR(table_ptr)) {
> > +   ret = PTR_ERR(table_ptr);
> > +   dev_err(dev, "can't load resource table: %d\n", ret);
> > +   return ret;
> > +   }
> > +
> > +   rproc->cached_table = NULL;
> > +   rproc->table_ptr = table_ptr;
> > +   rproc->table_sz = table_sz;
> > +
> > +   return 0;
> > +}
> > +
> >  /*
> >   * Attach to remote processor - similar to rproc_fw_boot() but without
> >   * the steps that deal with the firmware image.
> > @@ -1556,6 +1582,12 @@ static int rproc_attach(struct rproc *rproc)
> > return ret;
> > }
> >  
> > +   ret = rproc_set_loaded_rsc_table(rproc);
> > +   if (ret) {
> > +   dev_err(dev, "can't load resource table: %d\n", ret);
> > +   goto disable_iommu;
> > +   }
> > +
> > /* reset max_notifyid */
> > rproc->max_notifyid = -1;
> >  
> > diff --git a/drivers/remoteproc/remoteproc_internal.h 
> > b/drivers/remoteproc/remoteproc_internal.h
> > index c34002888d2c..4f73aac7e60d 100644
> > --- a/drivers/remoteproc/remoteproc_internal.h
> > +++ b/drivers/remoteproc/remoteproc_internal.h
> > @@ -177,6 +177,16 @@ struct resource_table 
> > *rproc_find_loaded_rsc_table(struct rproc *rproc,
> > return NULL;
> >  }
> >  
> > +static inline
> > +struct resource_table *rproc_get_loaded_rsc_table(struct rproc *rproc,
> > + size_t *size)
> > +{
> > +   if (rproc->ops->get_loaded_rsc_table)
> > +   return rproc->ops->get_loaded_rsc_table(rproc, size);
> > +
> > +   return NULL;
> > +}
> > +
> >  static inline
> >  bool rproc_u64_fit_in_size_t(u64 val)
> >  {
> > diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> > index 6b0a0ed30a03..51538a7d120d 100644
> > --- a/include/linux/remoteproc.h
> > +++ b/include/linux/remoteproc.h
> > @@ -368,7 +368,9 @@ enum rsc_handling_status {
> >   * RSC_HANDLED if resource was handled, RSC_IGNORED if not handled and a
> >   * negative value on error
> >   * @load_rsc_table:load resource table from firmware image
> > - * @find_loaded_rsc_table: find the loaded resouce table
> > + * @find_loaded_rsc_table: find the loaded resource table from firmware 
> > image
> > + * @get_loaded_rsc_table: get resource table installed in memory
> > + *   by external entity
> >   * @load:  load firmware to memory, where the remote processor
> >   * expects to find it
> >   * @sanity_check:  sanity check the fw image
> > @@ -390,6 +392,8 @@ struct rproc_ops {
> >   int offset, int avail);
> > struct resource_table *(*find_loaded_rsc_table)(
> > struct rproc *rproc, const struct firmware *fw);
> > +   struct resource_table *(*get_loaded_rsc_table)(
> > +   struct rproc *rproc, size_t *size);
> > int (*load)(struct rproc *rproc, const struct firmware *fw);
> > int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
> > u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
> > 


Re: [PATCH v4 09/10] coresight: syscfg: Add initial configfs support

2021-02-28 Thread Mathieu Poirier
On Sun, Feb 28, 2021 at 05:02:28PM -0700, Mathieu Poirier wrote:
> On Thu, Jan 28, 2021 at 05:09:35PM +, Mike Leach wrote:
> > Adds configfs subsystem and attributes to the configuration manager
> > to enable the listing of loaded configurations and features.
> > 
> > The default values of feature parameters can be accessed and altered
> > from these attributes to affect all installed devices using the feature.
> > 
> > Signed-off-by: Mike Leach 

I get the following warning when applying this patch:

Applying: coresight: syscfg: Add initial configfs support
.git/rebase-apply/patch:34: new blank line at EOF.
+
warning: 1 line adds whitespace errors.

Please address.

> > ---
> >  drivers/hwtracing/coresight/Makefile  |   3 +-
> >  .../hwtracing/coresight/coresight-config.c|   1 +
> >  .../coresight/coresight-syscfg-configfs.c | 399 ++
> >  .../coresight/coresight-syscfg-configfs.h |  45 ++
> >  .../hwtracing/coresight/coresight-syscfg.c|  77 
> >  .../hwtracing/coresight/coresight-syscfg.h|   7 +
> >  6 files changed, 531 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> >  create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.h
> > 
> > diff --git a/drivers/hwtracing/coresight/Makefile 
> > b/drivers/hwtracing/coresight/Makefile
> > index 2707bfef1b76..391c93a08902 100644
> > --- a/drivers/hwtracing/coresight/Makefile
> > +++ b/drivers/hwtracing/coresight/Makefile
> > @@ -5,7 +5,8 @@
> >  obj-$(CONFIG_CORESIGHT) += coresight.o
> >  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o 
> > \
> > coresight-sysfs.o coresight-syscfg.o coresight-config.o \
> > -   coresight-cfg-preload.o coresight-cfg-afdo.o
> > +   coresight-cfg-preload.o coresight-cfg-afdo.o \
> > +   coresight-syscfg-configfs.o
> >  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
> >  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
> >   coresight-tmc-etr.o
> > diff --git a/drivers/hwtracing/coresight/coresight-config.c 
> > b/drivers/hwtracing/coresight/coresight-config.c
> > index 6cc4b213d9b6..225ceca1428c 100644
> > --- a/drivers/hwtracing/coresight/coresight-config.c
> > +++ b/drivers/hwtracing/coresight/coresight-config.c
> > @@ -243,3 +243,4 @@ void cscfg_csdev_disable_config(struct 
> > cscfg_config_csdev *cfg)
> > cfg->enabled = false;
> > }
> >  }
> > +
> 
> Spurious change
> 
> > diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c 
> > b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> > new file mode 100644
> > index ..79a11ebd6782
> > --- /dev/null
> > +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> > @@ -0,0 +1,399 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> > + * Author: Mike Leach 
> > + */
> > +
> > +#include 
> > +
> > +#include "coresight-syscfg-configfs.h"
> > +
> > +/* create a default ci_type. */
> > +static inline struct config_item_type *cscfg_create_ci_type(void)
> > +{
> > +   struct config_item_type *ci_type;
> > +
> > +   ci_type = devm_kzalloc(to_device_cscfg(), sizeof(*ci_type), GFP_KERNEL);
> > +   if (ci_type)
> > +   ci_type->ct_owner = THIS_MODULE;
> > +
> > +   return ci_type;
> > +}
> > +
> > +/* configurations sub-group */
> > +
> > +/* attributes for the config view group */
> > +static ssize_t cscfg_cfg_description_show(struct config_item *item, char 
> > *page)
> > +{
> > +   struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
> > +struct 
> > cscfg_fs_config, group);
> > +
> > +   return scnprintf(page, PAGE_SIZE, "%s\n", fs_config->desc->brief);
> > +}
> > +CONFIGFS_ATTR_RO(cscfg_cfg_, description);
> > +
> > +static ssize_t cscfg_cfg_feature_refs_show(struct config_item *item, char 
> > *page)
> > +{
> > +   struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
> > +struct 
> > cscfg_fs_config, group);
> > +   const struct cscfg_config_desc *desc = fs_config->desc;
> > +   ssize_t ch_used = 0;
> > +   int i;
> > +
> > +   if (desc->nr_refs) {
> &

Re: [PATCH v4 09/10] coresight: syscfg: Add initial configfs support

2021-02-28 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:35PM +, Mike Leach wrote:
> Adds configfs subsystem and attributes to the configuration manager
> to enable the listing of loaded configurations and features.
> 
> The default values of feature parameters can be accessed and altered
> from these attributes to affect all installed devices using the feature.
> 
> Signed-off-by: Mike Leach 
> ---
>  drivers/hwtracing/coresight/Makefile  |   3 +-
>  .../hwtracing/coresight/coresight-config.c|   1 +
>  .../coresight/coresight-syscfg-configfs.c | 399 ++
>  .../coresight/coresight-syscfg-configfs.h |  45 ++
>  .../hwtracing/coresight/coresight-syscfg.c|  77 
>  .../hwtracing/coresight/coresight-syscfg.h|   7 +
>  6 files changed, 531 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.h
> 
> diff --git a/drivers/hwtracing/coresight/Makefile 
> b/drivers/hwtracing/coresight/Makefile
> index 2707bfef1b76..391c93a08902 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -5,7 +5,8 @@
>  obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
>   coresight-sysfs.o coresight-syscfg.o coresight-config.o \
> - coresight-cfg-preload.o coresight-cfg-afdo.o
> + coresight-cfg-preload.o coresight-cfg-afdo.o \
> + coresight-syscfg-configfs.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
> coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-config.c 
> b/drivers/hwtracing/coresight/coresight-config.c
> index 6cc4b213d9b6..225ceca1428c 100644
> --- a/drivers/hwtracing/coresight/coresight-config.c
> +++ b/drivers/hwtracing/coresight/coresight-config.c
> @@ -243,3 +243,4 @@ void cscfg_csdev_disable_config(struct cscfg_config_csdev 
> *cfg)
>   cfg->enabled = false;
>   }
>  }
> +

Spurious change

> diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c 
> b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> new file mode 100644
> index ..79a11ebd6782
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> @@ -0,0 +1,399 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach 
> + */
> +
> +#include 
> +
> +#include "coresight-syscfg-configfs.h"
> +
> +/* create a default ci_type. */
> +static inline struct config_item_type *cscfg_create_ci_type(void)
> +{
> + struct config_item_type *ci_type;
> +
> + ci_type = devm_kzalloc(to_device_cscfg(), sizeof(*ci_type), GFP_KERNEL);
> + if (ci_type)
> + ci_type->ct_owner = THIS_MODULE;
> +
> + return ci_type;
> +}
> +
> +/* configurations sub-group */
> +
> +/* attributes for the config view group */
> +static ssize_t cscfg_cfg_description_show(struct config_item *item, char 
> *page)
> +{
> + struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
> +  struct 
> cscfg_fs_config, group);
> +
> + return scnprintf(page, PAGE_SIZE, "%s\n", fs_config->desc->brief);
> +}
> +CONFIGFS_ATTR_RO(cscfg_cfg_, description);
> +
> +static ssize_t cscfg_cfg_feature_refs_show(struct config_item *item, char 
> *page)
> +{
> + struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
> +  struct 
> cscfg_fs_config, group);
> + const struct cscfg_config_desc *desc = fs_config->desc;
> + ssize_t ch_used = 0;
> + int i;
> +
> + if (desc->nr_refs) {
> + for (i = 0; i < desc->nr_refs; i++) {
> + ch_used += scnprintf(page + ch_used, PAGE_SIZE - 
> ch_used,
> +  "%s\n", desc->refs[i].name);
> + }
> + }
> + return ch_used;
> +}
> +CONFIGFS_ATTR_RO(cscfg_cfg_, feature_refs);
> +
> +/* list preset values in order of features and params */
> +static ssize_t cscfg_cfg_values_show(struct config_item *item, char *page)
> +{
> + const struct cscfg_feature_desc *feat;
> + const struct cscfg_config_desc *cfg;
> + struct cscfg_fs_preset *fs_preset;
> + int i, j, val_idx, preset_idx;
> + ssize_t used = 0;
> +
> + fs_preset = container_of(to_config_group(item), struct cscfg_fs_preset, 
> group);
> + cfg = fs_preset->desc;
> +
> + if (!cfg->nr_presets)
> + return 0;
> +
> + preset_idx = fs_preset->preset_num - 1;
> +
> + /* start index on the correct array line */
> + val_idx = cfg->nr_total_params * preset_idx;
> +
> + /*
> +  * A set of presets is the sum of all params in used features,
> +  * 

Re: [PATCH v4 08/10] coresight: config: Add preloaded configurations

2021-02-28 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:34PM +, Mike Leach wrote:
> Preload set of configurations.
> 
> This patch creates a small set of preloaded configurations and features
> that are available immediately after coresight has been initialised.
> 
> The current set provides a strobing feature for ETMv4, that creates a
> periodic sampling of trace by switching trace generation on and off
> using counters in the ETM.
> 
> A configuration called "autofdo" is also provided that uses the 'strobing'
> feature and provides a couple of preset values, selectable on the perf
> command line.
> 
> Signed-off-by: Mike Leach 
> ---
>  drivers/hwtracing/coresight/Makefile  |   3 +-
>  .../hwtracing/coresight/coresight-cfg-afdo.c  | 154 ++
>  .../coresight/coresight-cfg-preload.c |  25 +++
>  .../coresight/coresight-cfg-preload.h |  11 ++
>  drivers/hwtracing/coresight/coresight-core.c  |   6 +
>  .../hwtracing/coresight/coresight-syscfg.h|   1 +
>  6 files changed, 199 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-cfg-afdo.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.h
> 
> diff --git a/drivers/hwtracing/coresight/Makefile 
> b/drivers/hwtracing/coresight/Makefile
> index ea544206204d..2707bfef1b76 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -4,7 +4,8 @@
>  #
>  obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
> - coresight-sysfs.o coresight-syscfg.o coresight-config.o
> + coresight-sysfs.o coresight-syscfg.o coresight-config.o \
> + coresight-cfg-preload.o coresight-cfg-afdo.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
> coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-cfg-afdo.c 
> b/drivers/hwtracing/coresight/coresight-cfg-afdo.c
> new file mode 100644
> index ..ff69fb3f4434
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-cfg-afdo.c
> @@ -0,0 +1,154 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(C) 2020 Linaro Limited. All rights reserved.
> + * Author: Mike Leach 
> + */
> +
> +#include "coresight-config.h"
> +#include "coresight-etm4x-cfg.h"
> +
> +/* preload configurations and features */
> +
> +/* preload in features for ETMv4 */
> +
> +/* strobe feature */
> +static struct cscfg_parameter_desc strobe_params[] = {
> + {
> + .name = "window",
> + .value = 5000,
> + },
> + {
> + .name = "period",
> + .value = 1,
> + },
> +};
> +
> +static struct cscfg_regval_desc strobe_regs[] = {
> + /* resource selectors */
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE,
> + .offset = TRCRSCTLRn(2),
> + .hw_info = ETM4_CFG_RES_SEL,
> + .val32 = 0x20001,
> + },
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE,
> + .offset = TRCRSCTLRn(3),
> + .hw_info = ETM4_CFG_RES_SEQ,
> + .val32 = 0x20002,
> + },
> + /* strobe window counter 0 - reload from param 0 */
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_SAVE,
> + .offset = TRCCNTVRn(0),
> + .hw_info = ETM4_CFG_RES_CTR,
> + },
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM,
> + .offset = TRCCNTRLDVRn(0),
> + .hw_info = ETM4_CFG_RES_CTR,
> + .val32 = 0,
> + },
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE,
> + .offset = TRCCNTCTLRn(0),
> + .hw_info = ETM4_CFG_RES_CTR,
> + .val32 = 0x10001,
> + },
> + /* strobe period counter 1 - reload from param 1 */
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_SAVE,
> + .offset = TRCCNTVRn(1),
> + .hw_info = ETM4_CFG_RES_CTR,
> + },
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM,
> + .offset = TRCCNTRLDVRn(1),
> + .hw_info = ETM4_CFG_RES_CTR,
> + .val32 = 1,
> + },
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE,
> + .offset = TRCCNTCTLRn(1),
> + .hw_info = ETM4_CFG_RES_CTR,
> + .val32 = 0x8102,
> + },
> + /* sequencer */
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE,
> + .offset = TRCSEQEVRn(0),
> + .hw_info = ETM4_CFG_RES_SEQ,
> + .val32 = 0x0081,
> + },
> + {
> + .type = CS_CFG_REG_TYPE_RESOURCE,
> + .offset = TRCSEQEVRn(1),
> + .hw_info = ETM4_CFG_RES_SEQ,
> + 

Re: [PATCH v4 07/10] coresight: etm4x: Add complex configuration handlers to etmv4

2021-02-28 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:33PM +, Mike Leach wrote:
> Adds in handlers to allow the ETMv4 to use the complex configuration
> support. Features and configurations can be loaded and selected in the
> device.
> 
> Signed-off-by: Mike Leach 
> ---
>  drivers/hwtracing/coresight/Makefile  |   3 +-
>  .../hwtracing/coresight/coresight-etm4x-cfg.c | 184 ++
>  .../hwtracing/coresight/coresight-etm4x-cfg.h |  29 +++
>  .../coresight/coresight-etm4x-core.c  |  38 +++-
>  .../coresight/coresight-etm4x-sysfs.c |   3 +
>  5 files changed, 254 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h
> 
> diff --git a/drivers/hwtracing/coresight/Makefile 
> b/drivers/hwtracing/coresight/Makefile
> index daad9f103a78..ea544206204d 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -16,7 +16,8 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o
>  coresight-etm3x-y := coresight-etm3x-core.o coresight-etm-cp14.o \
>coresight-etm3x-sysfs.o
>  obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o
> -coresight-etm4x-y := coresight-etm4x-core.o coresight-etm4x-sysfs.o
> +coresight-etm4x-y := coresight-etm4x-core.o coresight-etm4x-sysfs.o \
> + coresight-etm4x-cfg.o
>  obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
>  obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
>  obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c 
> b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> new file mode 100644
> index ..f237a8d02360
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> @@ -0,0 +1,184 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(C) 2020 Linaro Limited. All rights reserved.
> + * Author: Mike Leach 
> + */
> +
> +#include "coresight-etm4x.h"
> +#include "coresight-etm4x-cfg.h"
> +#include "coresight-priv.h"
> +#include "coresight-syscfg.h"
> +
> +/**
> + * etm4_cfg_map_reg_offset - validate and map the register offset into a
> + *location in the driver config struct.
> + *
> + * Limits the number of registers that can be accessed and programmed in
> + * features, to those which are used to control the trace capture parameters.
> + *
> + * Omits or limits access to those which the driver must use exclusively.
> + *
> + * Invalid offsets will result in fail code return and feature load failure.
> + *
> + * @drvdata: driver data to map into.
> + * @reg: register to map.
> + * @offset:  device offset for the register
> + */
> +static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
> +struct cscfg_reg_csdev *reg, u32 offset)
> +{
> + int err = -EINVAL, idx;
> + struct etmv4_config *drvcfg = >config;
> + u32 off_mask;
> +
> +#define CHECKREG(cval, elem) \
> + { \
> + if (offset == cval) { \
> + reg->drv_store = >elem; \
> + err = 0; \
> + break; \
> + } \
> + }
> +
> +#define CHECKREGIDX(cval, elem, off_idx, mask)   \
> + { \
> + if (mask == cval) { \
> + reg->drv_store = >elem[off_idx]; \
> + err = 0; \
> + break; \
> + } \
> + }
> +
> + if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) ||
> + ((offset >= TRCSEQRSTEVR) && (offset <= TRCEXTINSELR)) ||
> + ((offset >= TRCCIDCCTLR0) && (offset <= TRCVMIDCCTLR1))) {
> + do {
> + CHECKREG(TRCEVENTCTL0R, eventctrl0);
> + CHECKREG(TRCEVENTCTL1R, eventctrl1);
> + CHECKREG(TRCSTALLCTLR, stall_ctrl);
> + CHECKREG(TRCTSCTLR, ts_ctrl);
> + CHECKREG(TRCSYNCPR, syncfreq);
> + CHECKREG(TRTLR, ccctlr);
> + CHECKREG(TRCBBCTLR, bb_ctrl);
> + CHECKREG(TRCVICTLR, vinst_ctrl);
> + CHECKREG(TRCVIIECTLR, viiectlr);
> + CHECKREG(TRCVISSCTLR, vissctlr);
> + CHECKREG(TRCVIPCSSCTLR, vipcssctlr);
> + CHECKREG(TRCSEQRSTEVR, seq_rst);
> + CHECKREG(TRCSEQSTR, seq_state);
> + CHECKREG(TRCEXTINSELR, ext_inp);
> + CHECKREG(TRCCIDCCTLR0, ctxid_mask0);
> + CHECKREG(TRCCIDCCTLR1, ctxid_mask1);
> + CHECKREG(TRCVMIDCCTLR0, vmid_mask0);
> + CHECKREG(TRCVMIDCCTLR1, vmid_mask1);
> + } while (0);
> + } else if ((offset & GENMASK(11, 4)) == TRCSEQEVRn(0)) {
> + /* sequencer state control registers */
> + idx = (offset & GENMASK(3, 0)) 

Re: [PATCH v4 02/10] coresight: syscfg: Add registration and feature loading for cs devices

2021-02-27 Thread Mathieu Poirier
On Fri, Feb 26, 2021 at 07:14:32PM +, Mike Leach wrote:
> Hi Mathieu,
> 
> On Fri, 19 Feb 2021 at 18:43, Mathieu Poirier
>  wrote:
> >
> > [...]
> >
> > > +/**
> > > + * List entry for Coresight devices that are registered as supporting 
> > > complex
> > > + * config operations.
> > > + *
> > > + * @csdev:   The registered device.
> > > + * @match_info: The matching type information.
> > > + * @ops: Operations supported by the registered device.
> > > + * @item:list entry.
> > > + */
> > > +struct cscfg_csdev_register {
> > > + struct coresight_device *csdev;
> > > + struct cscfg_match_desc match_info;
> > > + struct cscfg_csdev_feat_ops ops;
> > > + struct list_head item;
> > > +};
> >
> > I would call this structure cscfg_registered_csdev and move it to
> > coresight-config.h.  That way it is consistent with cscfg_config_csdev and
> > cscfg_feature_csdev and located all in the same file.
> >
> 
> I was trying to separate structures that are used to define
> configurations and features, with those that are used to manage the
> same. Hence, most things in coresight_config.h define configurations,
> or their device loaded instance equivalents, and things in
> coresight_syscfg.h are management items. I am happy to change the name
> but would prefer is stay in coresight_syscfg.h

Ok

> 
> Thanks
> 
> Mike
> 


Re: [PATCH v4 06/10] coresight: etm-perf: Update to activate selected configuration

2021-02-25 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:32PM +, Mike Leach wrote:
> Add calls to activate the selected configuration as perf starts
> and stops the tracing session.
> 
> Signed-off-by: Mike Leach 
> ---
>  drivers/hwtracing/coresight/coresight-etm-perf.c | 14 +-
>  drivers/hwtracing/coresight/coresight-etm-perf.h |  2 ++
>  2 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c 
> b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index e270bb1e0f7d..5c1aeddabc59 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -178,6 +178,10 @@ static void free_event_data(struct work_struct *work)
>   /* Free the sink buffers, if there are any */
>   free_sink_buffer(event_data);
>  
> + /* clear any configuration we were using */
> + if (event_data->config_id_hash)
> + cscfg_deactivate_config(event_data->config_id_hash);
> +
>   for_each_cpu(cpu, mask) {
>   struct list_head **ppath;
>  
> @@ -236,7 +240,7 @@ static void etm_free_aux(void *data)
>  static void *etm_setup_aux(struct perf_event *event, void **pages,
>  int nr_pages, bool overwrite)
>  {
> - u32 id;
> + u32 id, config_id;

config_id, cfg_hash, id_hash...

>   int cpu = event->cpu;
>   cpumask_t *mask;
>   struct coresight_device *sink = NULL;
> @@ -253,6 +257,14 @@ static void *etm_setup_aux(struct perf_event *event, 
> void **pages,
>   sink = coresight_get_sink_by_id(id);
>   }
>  
> + /* check if user wants a coresight configuration selected */
> + config_id = (u32)((event->attr.config2 & GENMASK_ULL(63, 32)) >> 32);
> + if (config_id) {
> + if (cscfg_activate_config(config_id))
> + goto err;
> + event_data->config_id_hash = config_id;
> + }
> +
>   mask = _data->mask;
>  
>   /*
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h 
> b/drivers/hwtracing/coresight/coresight-etm-perf.h
> index 3646a3837a0b..751d768939d8 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.h
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
> @@ -49,12 +49,14 @@ struct etm_filters {
>   * @work:Handle to free allocated memory outside IRQ context.
>   * @mask:Hold the CPU(s) this event was set for.
>   * @snk_config:  The sink configuration.
> + * @config_id_hash:  The id of any coresight config selected.
>   * @path:An array of path, each slot for one CPU.
>   */
>  struct etm_event_data {
>   struct work_struct work;
>   cpumask_t mask;
>   void *snk_config;
> + u32 config_id_hash;

Please align this with the naming convention you will be using above and
throughout.

More comments tomorrow.

Thanks,
Mathieu

>   struct list_head * __percpu *path;
>  };
>  
> -- 
> 2.17.1
> 


Re: [PATCH v4 05/10] coresight: syscfg: Add API to activate and enable configurations

2021-02-25 Thread Mathieu Poirier
[...]

> > +
> > +/**
> > + * Mark a config descriptor as active.
> > + * This will be seen when csdev devices are activated in the system.
> > + *
> > + * Selection by hash value - generated from the configuration name when it
> > + * was loaded and added to the cs_etm/configurations file system for 
> > selection
> > + * by perf.
> > + *
> > + * @cfg_hash: Hash value of the selected configuration name.
> > + */
> > +int cscfg_activate_config(unsigned long cfg_hash)
> > +{
> > +   struct cscfg_config_desc *curr_item, *match_item = 0;
> > +
> > +   mutex_lock(_mutex);
> > +
> > +   list_for_each_entry(curr_item, _mgr->data.config_desc_list, item) 
> > {
> > +   if ((unsigned long)curr_item->id_ea->var == cfg_hash) {
> > +   match_item = curr_item;
> > +   atomic_inc(_mgr->data.sys_active_cnt);
> 
> It would be nice to have a comment that mentions why this is needed.  I had to
> go look in patch 09 to see that it prevents a feature from being changed when
> any configuration is active.  And since patch 09 is the only place where
> @sys_active_cnt is used, please move the declaration and handling of the
> variable there.
> 
> > +   break;
> > +   }
> > +   }
> > +   mutex_unlock(_mutex);
> > +
> > +   if (!match_item)
> > +   return -EINVAL;
> > +
> > +   dev_dbg(to_device_cscfg(), "Activate config %s.\n", match_item->name);
> > +
> > +   /* mark the descriptors as active so enable config will use them */
> > +   mutex_lock(_csdev_mutex);
> > +   atomic_inc(_item->active_cnt);
> 
> What is ->active_cnt used for?  I see it referenced in
> cscfg_csdev_enable_active_config() but it doesn't do much other than to 
> confirm
> the configuration has been activated by someone.  
> 
> There is also a chance that a caller would call cscfg_activate_config() once 
> and
> call cscfg_csdev_enable_active_config() multiple time, which would really 
> create
> problems.  I would move the incrementation of sys_active_cnt within the mutex
> hold in cscfg_csdev_enable_active_config() and get rid of ->active_cnt.  If I 
> am
> correct we wouldn't need cscfg_activate_config() after that.
>

I looked at patch 06 and I understand why incrementing sys_active_cnt has to be
done before enabling it.  If it wasn't so someone could update the feature
between the time setup_aux() is called and the event is installed on a CPU.  As
such cscfg_activate_config() should stay but I still think ->active_cnt should
go. 
 
> > +   mutex_unlock(_csdev_mutex);
> > +
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(cscfg_activate_config);
> > +
> > +void cscfg_deactivate_config(unsigned long cfg_hash)
> 
> I'm fine with either cfg_hash or id_hash, but not both.
> 
> > +{
> > +   struct cscfg_config_desc *curr_item, *match_item = 0;
> > +
> > +   mutex_lock(_mutex);
> > +
> > +   list_for_each_entry(curr_item, _mgr->data.config_desc_list, item) 
> > {
> > +   if ((unsigned long)curr_item->id_ea->var == cfg_hash) {
> > +   match_item = curr_item;
> > +   break;
> > +   }
> > +   }
> > +   mutex_unlock(_mutex);
> > +   if (!match_item)
> > +   return;
> > +
> > +   dev_dbg(to_device_cscfg(), "Deactivate config %s.\n", match_item->name);
> > +
> > +   mutex_lock(_csdev_mutex);
> > +   atomic_dec(_item->active_cnt);
> > +   mutex_unlock(_csdev_mutex);
> > +
> > +   atomic_dec(_mgr->data.sys_active_cnt);
> > +}
> > +EXPORT_SYMBOL_GPL(cscfg_deactivate_config);
> > +
> > +/* Find and program any active config for the supplied device.*/
> > +int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
> > +unsigned long id_hash, int preset)
> > +{
> > +   struct cscfg_config_csdev *cfg = NULL, *item;
> > +   const struct cscfg_config_desc *desc;
> > +   int err = 0;
> > +
> > +   /* quickly check global count */
> > +   if (!atomic_read(_mgr->data.sys_active_cnt))
> > +   return 0;
> > +
> > +   mutex_lock(_csdev_mutex);
> > +   list_for_each_entry(item, >config_csdev_list, node) {
> > +   desc = item->desc;
> > +   if ((atomic_read(>active_cnt)) &&
> > +   ((unsigned long)desc->id_ea->var == id_hash)) {
> > +   cfg = item;
> > +   break;
> > +   }
> > +   }
> > +   if (cfg) {
> > +   err = cscfg_csdev_enable_config(cfg, preset);
> > +   if (!err)
> > +   csdev->active_cfg_ctxt = (void *)cfg;
> > +   }
> > +   mutex_unlock(_csdev_mutex);
> > +   return err;
> > +}
> > +EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
> > +
> > +/* save and disable the active config for the device */
> > +void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
> > +{
> > +   struct cscfg_config_csdev *cfg;
> > +
> > +   mutex_lock(_csdev_mutex);
> > +   cfg = (struct cscfg_config_csdev *)csdev->active_cfg_ctxt;
> > +   if (cfg)
> > +   cscfg_csdev_disable_config(cfg);
> > +   

Re: [PATCH v4 05/10] coresight: syscfg: Add API to activate and enable configurations

2021-02-25 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:31PM +, Mike Leach wrote:
> Configurations are first activated, then when any coresight device is
> enabled, the active configurations are checked and any matching
> one is enabled.
> 
> This patch provides the activation / enable API.
> 
> Signed-off-by: Mike Leach 
> ---
>  .../hwtracing/coresight/coresight-config.h|   2 +
>  .../hwtracing/coresight/coresight-syscfg.c| 127 ++
>  .../hwtracing/coresight/coresight-syscfg.h|  10 +-
>  include/linux/coresight.h |   2 +
>  4 files changed, 140 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-config.h 
> b/drivers/hwtracing/coresight/coresight-config.h
> index 98380b496046..26396b70c826 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -156,6 +156,7 @@ struct cscfg_config_feat_ref {
>   * @presets: Array of preset values.
>   * @id_ea:   Extended attribute for perf configid value
>   * @event_ea:Extended attribute for perf event value
> + * @active_cnt: ref count for activate on this configuration.
>   */
>  struct cscfg_config_desc {
>   const char *name;
> @@ -168,6 +169,7 @@ struct cscfg_config_desc {
>   const u64 *presets; /* nr_presets * nr_total_params */
>   struct dev_ext_attribute *id_ea;
>   struct dev_ext_attribute *event_ea;
> + atomic_t active_cnt;
>  };
>  
>  /**
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c 
> b/drivers/hwtracing/coresight/coresight-syscfg.c
> index a070f135eca3..d79cf5b36758 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> @@ -298,6 +298,7 @@ static int cscfg_load_config(struct cscfg_config_desc 
> *cfg_desc)
>   return err;
>  
>   list_add(_desc->item, _mgr->data.config_desc_list);
> + atomic_set(_desc->active_cnt, 0);
>   return 0;
>  }
>  
> @@ -477,6 +478,131 @@ void cscfg_unregister_csdev(struct coresight_device 
> *csdev)
>  }
>  EXPORT_SYMBOL_GPL(cscfg_unregister_csdev);
>  
> +void cscfg_csdev_reset_feats(struct coresight_device *csdev)
> +{
> + struct cscfg_feature_csdev *feat;
> +
> + mutex_lock(_csdev_mutex);
> + if (list_empty(>feature_csdev_list))
> + goto unlock_exit;
> +
> + list_for_each_entry(feat, >feature_csdev_list, node)
> + cscfg_reset_feat(feat);
> +
> +unlock_exit:
> + mutex_unlock(_csdev_mutex);
> +}
> +EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
> +
> +/**
> + * Mark a config descriptor as active.
> + * This will be seen when csdev devices are activated in the system.
> + *
> + * Selection by hash value - generated from the configuration name when it
> + * was loaded and added to the cs_etm/configurations file system for 
> selection
> + * by perf.
> + *
> + * @cfg_hash: Hash value of the selected configuration name.
> + */
> +int cscfg_activate_config(unsigned long cfg_hash)
> +{
> + struct cscfg_config_desc *curr_item, *match_item = 0;
> +
> + mutex_lock(_mutex);
> +
> + list_for_each_entry(curr_item, _mgr->data.config_desc_list, item) 
> {
> + if ((unsigned long)curr_item->id_ea->var == cfg_hash) {
> + match_item = curr_item;
> + atomic_inc(_mgr->data.sys_active_cnt);

It would be nice to have a comment that mentions why this is needed.  I had to
go look in patch 09 to see that it prevents a feature from being changed when
any configuration is active.  And since patch 09 is the only place where
@sys_active_cnt is used, please move the declaration and handling of the
variable there.

> + break;
> + }
> + }
> + mutex_unlock(_mutex);
> +
> + if (!match_item)
> + return -EINVAL;
> +
> + dev_dbg(to_device_cscfg(), "Activate config %s.\n", match_item->name);
> +
> + /* mark the descriptors as active so enable config will use them */
> + mutex_lock(_csdev_mutex);
> + atomic_inc(_item->active_cnt);

What is ->active_cnt used for?  I see it referenced in
cscfg_csdev_enable_active_config() but it doesn't do much other than to confirm
the configuration has been activated by someone.  

There is also a chance that a caller would call cscfg_activate_config() once and
call cscfg_csdev_enable_active_config() multiple time, which would really create
problems.  I would move the incrementation of sys_active_cnt within the mutex
hold in cscfg_csdev_enable_active_config() and get rid of ->active_cnt.  If I am
correct we wouldn't need cscfg_activate_config() after that.

> + mutex_unlock(_csdev_mutex);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(cscfg_activate_config);
> +
> +void cscfg_deactivate_config(unsigned long cfg_hash)

I'm fine with either cfg_hash or id_hash, but not both.

> +{
> + struct cscfg_config_desc *curr_item, *match_item = 0;
> +
> + mutex_lock(_mutex);
> +
> + 

Re: [PATCH] coresight: etm4x: work around clang-12+ build failure

2021-02-25 Thread Mathieu Poirier
Good morning,

On Thu, Feb 25, 2021 at 10:42:58AM +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> clang-12 fails to build the etm4x driver with -fsanitize=array-bounds:
> 
> :1:7: error: expected constant expression in '.inst' directive
> .inst (0xd520|2) << 19) | ((1) << 16) | (((0x160 + (i * 
> 4) >> 2))) >> 7) & 0x7)) << 12) | ((0x160 + (i * 4) >> 2))) & 
> 0xf)) << 8) | (((0x160 + (i * 4) >> 2))) >> 4) & 0x7)) << 
> 5)))|(.L__reg_num_x8))
>   ^
> drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in 
> macro instantiation
> etm4x_relaxed_read32(csa, TRCCNTVRn(i));
> ^
> drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from 
> macro 'etm4x_relaxed_read32'
>  read_etm4x_sysreg_offset((offset), false)))
>  ^
> drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from 
> macro 'read_etm4x_sysreg_offset'
> __val = read_etm4x_sysreg_const_offset((offset)); 
>   \
> ^
> drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from 
> macro 'read_etm4x_sysreg_const_offset'
> READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset))
> ^
> drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from 
> macro 'READ_ETM4x_REG'
> read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg)))
> ^
> arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 
> 'read_sysreg_s'
> asm volatile(__mrs_s("%0", r) : "=r" (__val));  \
>  ^
> arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s'
> "   mrs_s " v ", " __stringify(r) "\n"  \
>  ^
> 
> It appears that the __builin_constant_p() check in
> read_etm4x_sysreg_offset() falsely returns 'true' here because clang
> decides finds that an out-of-bounds access to config->cntr_val[] cannot
> happen, and then it unrolls the loop with constant register numbers. Then
> when actually emitting the output, it fails to figure out the value again.
> 
> While this is incorrect behavior in clang, it is easy to work around
> by avoiding the out-of-bounds array access. Do this by limiting the
> loop counter to the actual dimension of the array.
> 
> Link: https://github.com/ClangBuiltLinux/linux/issues/1310
> Signed-off-by: Arnd Bergmann 
> ---
>  drivers/hwtracing/coresight/coresight-etm4x-core.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
> b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 15016f757828..4cccf874a602 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -691,13 +691,13 @@ static void etm4_disable_hw(void *info)
>   "timeout while waiting for PM stable Trace Status\n");
>  
>   /* read the status of the single shot comparators */
> - for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> + for (i = 0; i < min_t(u32, drvdata->nr_ss_cmp, ETM_MAX_SS_CMP); i++) {
>   config->ss_status[i] =
>   etm4x_relaxed_read32(csa, TRCSSCSRn(i));
>   }
>  
>   /* read back the current counter values */
> - for (i = 0; i < drvdata->nr_cntr; i++) {
> + for (i = 0; i < min_t(u32, drvdata->nr_cntr, ETMv4_MAX_CNTR); i++) {

This patch will work and I'd be happy to apply it if this was the only instance,
but there are dozens of places in the coresight drivers where such patterns are
used.  Why are those not flagged as well?  And shouldn't the real fix be with
clang?

Thanks,
Mathieu 

>   config->cntr_val[i] =
>   etm4x_relaxed_read32(csa, TRCCNTVRn(i));
>   }
> -- 
> 2.29.2
> 


Re: [PATCH RESEND] remoteproc: core: Remove casting to rproc_handle_resource_t

2021-02-24 Thread Mathieu Poirier
On Wed, Feb 24, 2021 at 01:58:25PM +0800, Jindong Yue wrote:
> There are four different callback functions that are used for the
> rproc_handle_resource_t callback that all have different second
> parameter types.
> 
> rproc_handle_vdev -> struct fw_rsc_vdev
> rproc_handle_trace -> struct fw_rsc_trace
> rproc_handle_devmem -> struct fw_rsc_devmem
> rproc_handle_carveout -> struct fw_rsc_carveout
> 
> These callbacks are cast to rproc_handle_resource_t so that there is no
> error about incompatible pointer types. Unfortunately, this is a Clang's
> Control-Flow Integrity checking violation, which verifies that the
> callback function's types match the prototypes exactly before jumping.
> 
> [7.275750] Kernel panic - not syncing: CFI failure (target: 
> rproc_handle_vdev+0x0/0x4)
> [7.283763] CPU: 2 PID: 1 Comm: init Tainted: G C O  
> 5.4.70-03301-g527af2c96672 #17
> [7.292463] Hardware name: NXP i.MX8MPlus EVK board (DT)
> [7.297779] Call trace:
> [7.300232]  dump_backtrace.cfi_jt+0x0/0x4
> [7.304337]  show_stack+0x18/0x24
> [7.307660]  dump_stack+0xb8/0x114
> [7.311069]  panic+0x164/0x3d4
> [7.314130]  __ubsan_handle_cfi_check_fail_abort+0x0/0x14
> [7.319533]  perf_proc_update_handler+0x0/0xcc
> [7.323983]  __cfi_check+0x63278/0x6a290
> [7.327913]  rproc_boot+0x3f8/0x738
> [7.331404]  rproc_add+0x68/0x110
> [7.334738]  imx_rproc_probe+0x5e4/0x708 [imx_rproc]
> [7.339711]  platform_drv_probe+0xac/0xf0
> [7.343726]  really_probe+0x260/0x65c
> [7.347393]  driver_probe_device+0x64/0x100
> [7.351580]  device_driver_attach+0x6c/0xac
> [7.355766]  __driver_attach+0xdc/0x184
> [7.359609]  bus_for_each_dev+0x98/0x104
> [7.363537]  driver_attach+0x24/0x30
> [7.367117]  bus_add_driver+0x100/0x1e0
> [7.370958]  driver_register+0x78/0x114
> [7.374800]  __platform_driver_register+0x44/0x50
> [7.379514]  init_module+0x20/0xfe8 [imx_rproc]
> [7.384049]  do_one_initcall+0x190/0x348
> [7.387979]  do_init_module+0x5c/0x210
> [7.391731]  load_module+0x2fbc/0x3590
> [7.395485]  __arm64_sys_finit_module+0xb8/0xec
> [7.400025]  el0_svc_common+0xb4/0x19c
> [7.403777]  el0_svc_handler+0x74/0x98
> [7.407531]  el0_svc+0x8/0xc
> [7.410419] SMP: stopping secondary CPUs
> [7.414648] Kernel Offset: disabled
> [7.418142] CPU features: 0x00010002,2000200c
> [7.422501] Memory Limit: none
> 
> To fix this, change the second parameter of all functions to void * and
> use a local variable with the correct type so that everything works
> properly. With this, we can remove casting to rproc_handle_resource_t
> for these functions.
> 
> Signed-off-by: Jindong Yue 
> Reviewed-by: Peng Fan 
> Reviewed-by: Sami Tolvanen 

Reviewed-by: Mathieu Poirier 

> ---
>  drivers/remoteproc/remoteproc_core.c | 29 +++-
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/remoteproc/remoteproc_core.c 
> b/drivers/remoteproc/remoteproc_core.c
> index ab150765d124..553e42a4d2a0 100644
> --- a/drivers/remoteproc/remoteproc_core.c
> +++ b/drivers/remoteproc/remoteproc_core.c
> @@ -482,7 +482,7 @@ static int copy_dma_range_map(struct device *to, struct 
> device *from)
>  /**
>   * rproc_handle_vdev() - handle a vdev fw resource
>   * @rproc: the remote processor
> - * @rsc: the vring resource descriptor
> + * @ptr: the vring resource descriptor
>   * @offset: offset of the resource entry
>   * @avail: size of available data (for sanity checking the image)
>   *
> @@ -507,9 +507,10 @@ static int copy_dma_range_map(struct device *to, struct 
> device *from)
>   *
>   * Returns 0 on success, or an appropriate error code otherwise
>   */
> -static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
> +static int rproc_handle_vdev(struct rproc *rproc, void *ptr,
>int offset, int avail)
>  {
> + struct fw_rsc_vdev *rsc = ptr;
>   struct device *dev = >dev;
>   struct rproc_vdev *rvdev;
>   int i, ret;
> @@ -627,7 +628,7 @@ void rproc_vdev_release(struct kref *ref)
>  /**
>   * rproc_handle_trace() - handle a shared trace buffer resource
>   * @rproc: the remote processor
> - * @rsc: the trace resource descriptor
> + * @ptr: the trace resource descriptor
>   * @offset: offset of the resource entry
>   * @avail: size of available data (for sanity checking the image)
>   *
> @@ -641,9 +642,10 @@ void rproc_vdev_release(struct kref *ref)
>   *
>   * Returns 0 on success, or an appropriate error code otherwise
>   */
> -static int rproc_handle_trace(struct rproc *rproc, struct fw_

Re: [PATCH] remoteproc: pru: Replace DEFINE_SIMPLE_ATTRIBUTE with DEFINE_DEBUGFS_ATTRIBUTE

2021-02-24 Thread Mathieu Poirier
On Wed, Feb 24, 2021 at 04:20:29PM +0800, Yang Li wrote:
> Fix the following coccicheck warning:
> ./drivers/remoteproc/pru_rproc.c:247:0-23: WARNING:
> pru_rproc_debug_ss_fops should be defined with DEFINE_DEBUGFS_ATTRIBUTE
> 
> Reported-by: Abaci Robot 
> Signed-off-by: Yang Li 
> ---
>  drivers/remoteproc/pru_rproc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
> index 2667919..04a9d99 100644
> --- a/drivers/remoteproc/pru_rproc.c
> +++ b/drivers/remoteproc/pru_rproc.c
> @@ -244,7 +244,7 @@ static int pru_rproc_debug_ss_get(void *data, u64 *val)
>  
>   return 0;
>  }
> -DEFINE_SIMPLE_ATTRIBUTE(pru_rproc_debug_ss_fops, pru_rproc_debug_ss_get,
> +DEFINE_DEBUGFS_ATTRIBUTE(pru_rproc_debug_ss_fops, pru_rproc_debug_ss_get,
>       pru_rproc_debug_ss_set, "%llu\n");

Reviewed-by: Mathieu Poirier 


>  
>  /*
> -- 
> 1.8.3.1
> 


Re: [PATCH v4 04/10] coresight: etm-perf: update to handle configuration selection

2021-02-24 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:30PM +, Mike Leach wrote:
> Loaded coresight configurations are registered in the cs_etm\cs_config sub
> directory. This extends the etm-perf code to handle these registrations,
> and the cs_syscfg driver to perform the registration on load.
> 
> Signed-off-by: Mike Leach 
> ---
>  .../hwtracing/coresight/coresight-config.h|   5 +-
>  .../hwtracing/coresight/coresight-etm-perf.c  | 164 +++---
>  .../hwtracing/coresight/coresight-etm-perf.h  |   8 +
>  .../hwtracing/coresight/coresight-syscfg.c|  13 +-
>  4 files changed, 166 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-config.h 
> b/drivers/hwtracing/coresight/coresight-config.h
> index 9d66e0071f38..98380b496046 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -154,7 +154,8 @@ struct cscfg_config_feat_ref {
>   * @nr_presets:  Number of sets of presets supplied by this 
> configuration.
>   * @nr_total_params: Sum of all parameters declared by used features
>   * @presets: Array of preset values.
> - *
> + * @id_ea:   Extended attribute for perf configid value
> + * @event_ea:Extended attribute for perf event value
>   */
>  struct cscfg_config_desc {
>   const char *name;
> @@ -165,6 +166,8 @@ struct cscfg_config_desc {
>   int nr_presets;
>   int nr_total_params;
>   const u64 *presets; /* nr_presets * nr_total_params */
> + struct dev_ext_attribute *id_ea;
> + struct dev_ext_attribute *event_ea;
>  };
>  
>  /**
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c 
> b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index a608081bd446..e270bb1e0f7d 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -18,8 +18,10 @@
>  #include 
>  #include 
>  
> +#include "coresight-config.h"
>  #include "coresight-etm-perf.h"
>  #include "coresight-priv.h"
> +#include "coresight-syscfg.h"
>  
>  static struct pmu etm_pmu;
>  static bool etm_perf_up;
> @@ -32,8 +34,13 @@ PMU_FORMAT_ATTR(cycacc,"config:" 
> __stringify(ETM_OPT_CYCACC));
>  PMU_FORMAT_ATTR(contextid,   "config:" __stringify(ETM_OPT_CTXTID));
>  PMU_FORMAT_ATTR(timestamp,   "config:" __stringify(ETM_OPT_TS));
>  PMU_FORMAT_ATTR(retstack,"config:" __stringify(ETM_OPT_RETSTK));
> +/* preset - if sink ID is used as a configuration selector */
> +PMU_FORMAT_ATTR(preset,  "config:0-3");
>  /* Sink ID - same for all ETMs */
>  PMU_FORMAT_ATTR(sinkid,  "config2:0-31");
> +/* config ID - set if a system configuration is selected */
> +PMU_FORMAT_ATTR(configid,"config2:32-63");
> +
>  
>  static struct attribute *etm_config_formats_attr[] = {
>   _attr_cycacc.attr,
> @@ -41,6 +48,8 @@ static struct attribute *etm_config_formats_attr[] = {
>   _attr_timestamp.attr,
>   _attr_retstack.attr,
>   _attr_sinkid.attr,
> + _attr_preset.attr,
> + _attr_configid.attr,
>   NULL,
>  };
>  
> @@ -58,9 +67,29 @@ static const struct attribute_group etm_pmu_sinks_group = {
>   .attrs  = etm_config_sinks_attr,
>  };
>  
> +static struct attribute *etm_config_cscfg_attr[] = {
> + NULL,
> +};
> +
> +static const struct attribute_group etm_pmu_cscfg_group = {
> + .name   = "configurations",
> + .attrs  = etm_config_cscfg_attr,
> +};
> +
> +static struct attribute *etm_config_events_attr[] = {
> + NULL,
> +};
> +
> +static const struct attribute_group etm_pmu_events_group = {
> + .name   = "events",
> + .attrs  = etm_config_events_attr,
> +};
> +
>  static const struct attribute_group *etm_pmu_attr_groups[] = {
>   _pmu_format_group,
>   _pmu_sinks_group,
> + _pmu_cscfg_group,
> + _pmu_events_group,
>   NULL,
>  };
>  
> @@ -219,7 +248,7 @@ static void *etm_setup_aux(struct perf_event *event, void 
> **pages,
>   INIT_WORK(_data->work, free_event_data);
>  
>   /* First get the selected sink from user space. */
> - if (event->attr.config2) {
> + if (event->attr.config2 & GENMASK_ULL(31, 0)) {
>   id = (u32)event->attr.config2;
>   sink = coresight_get_sink_by_id(id);
>   }
> @@ -537,21 +566,17 @@ static ssize_t etm_perf_sink_name_show(struct device 
> *dev,

I would rename this to etm_perf_name_show() so that it doesn't look bizarre when
finding it in etm_perf_add_symlink_group().

>   return scnprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)(ea->var));
>  }
>  
> -int etm_perf_add_symlink_sink(struct coresight_device *csdev)
> +int etm_perf_add_symlink_group(struct device *dev,
> +struct dev_ext_attribute **ext_attr,
> +const char *name,
> +const char *group_name)
>  {
> - int ret;
> + struct dev_ext_attribute *ea;
>   unsigned long hash;
> - const char *name;
> + int ret;
>  

[PATCH 6/6] perf cs-etm: Detect pid in VMID for kernel running at EL2

2021-02-24 Thread Mathieu Poirier
From: Suzuki K Poulose 

The PID of the task could be traced as VMID when the kernel is running
at EL2.  Teach the decoder to look for VMID when the CONTEXTIDR (Arm32)
or CONTEXTIDR_EL1 (Arm64) is invalid but we have a valid VMID.

Cc: Mike Leach 
Cc: Mathieu Poirier 
Cc: Al Grant 
Signed-off-by: Suzuki K Poulose 
Co-developed-by: Leo Yan 
Signed-off-by: Leo Yan 
Reviewed-by: Mathieu Poirier 
Link: https://lore.kernel.org/r/20210213113220.292229-6-leo@linaro.org
---
 .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 38 +--
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c 
b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 3f4bc4050477..4052c9ce6e2f 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -6,6 +6,7 @@
  * Author: Mathieu Poirier 
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -491,13 +492,42 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
const ocsd_generic_trace_elem *elem,
const uint8_t trace_chan_id)
 {
-   pid_t tid;
+   pid_t tid = -1;
+   static u64 pid_fmt;
+   int ret;
 
-   /* Ignore PE_CONTEXT packets that don't have a valid contextID */
-   if (!elem->context.ctxt_id_valid)
+   /*
+* As all the ETMs run at the same exception level, the system should
+* have the same PID format crossing CPUs.  So cache the PID format
+* and reuse it for sequential decoding.
+*/
+   if (!pid_fmt) {
+   ret = cs_etm__get_pid_fmt(trace_chan_id, _fmt);
+   if (ret)
+   return OCSD_RESP_FATAL_SYS_ERR;
+   }
+
+   /*
+* Process the PE_CONTEXT packets if we have a valid contextID or VMID.
+* If the kernel is running at EL2, the PID is traced in CONTEXTIDR_EL2
+* as VMID, Bit ETM_OPT_CTXTID2 is set in this case.
+*/
+   switch (pid_fmt) {
+   case BIT(ETM_OPT_CTXTID):
+   if (elem->context.ctxt_id_valid)
+   tid = elem->context.context_id;
+   break;
+   case BIT(ETM_OPT_CTXTID2):
+   if (elem->context.vmid_valid)
+   tid = elem->context.vmid;
+   break;
+   default:
+   break;
+   }
+
+   if (tid == -1)
return OCSD_RESP_CONT;
 
-   tid =  elem->context.context_id;
if (cs_etm__etmq_set_tid(etmq, tid, trace_chan_id))
return OCSD_RESP_FATAL_SYS_ERR;
 
-- 
2.25.1



[PATCH 4/6] perf cs-etm: Support PID tracing in config

2021-02-24 Thread Mathieu Poirier
From: Suzuki K Poulose 

If the kernel is running at EL2, the pid of a task is exposed via VMID
instead of the CONTEXTID.  Add support for this in the perf tool.

This patch respects user setting if user has specified any configs
from "contextid", "contextid1" or "contextid2"; otherwise, it
dynamically sets config based on PMU format "contextid".

Cc: Mike Leach 
Cc: Mathieu Poirier 
Cc: Al Grant 
Signed-off-by: Suzuki K Poulose 
Co-developed-by: Leo Yan 
Signed-off-by: Leo Yan 
Reviewed-by: Mike Leach 
Reviewed-by: Mathieu Poirier 
Link: https://lore.kernel.org/r/20210213113220.292229-4-leo@linaro.org
---
 tools/include/linux/coresight-pmu.h |  3 ++
 tools/perf/arch/arm/util/cs-etm.c   | 61 +++--
 2 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/tools/include/linux/coresight-pmu.h 
b/tools/include/linux/coresight-pmu.h
index 5dc47cfdcf07..4ac5c081af93 100644
--- a/tools/include/linux/coresight-pmu.h
+++ b/tools/include/linux/coresight-pmu.h
@@ -20,14 +20,17 @@
  */
 #define ETM_OPT_CYCACC 12
 #define ETM_OPT_CTXTID 14
+#define ETM_OPT_CTXTID215
 #define ETM_OPT_TS 28
 #define ETM_OPT_RETSTK 29
 
 /* ETMv4 CONFIGR programming bits for the ETM OPTs */
 #define ETM4_CFG_BIT_CYCACC4
 #define ETM4_CFG_BIT_CTXTID6
+#define ETM4_CFG_BIT_VMID  7
 #define ETM4_CFG_BIT_TS11
 #define ETM4_CFG_BIT_RETSTK12
+#define ETM4_CFG_BIT_VMID_OPT  15
 
 static inline int coresight_get_trace_id(int cpu)
 {
diff --git a/tools/perf/arch/arm/util/cs-etm.c 
b/tools/perf/arch/arm/util/cs-etm.c
index 5b2bb7fc5ee1..911c7f2b3581 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -67,6 +67,7 @@ static int cs_etm_set_context_id(struct auxtrace_record *itr,
char path[PATH_MAX];
int err = -EINVAL;
u32 val;
+   u64 contextid;
 
ptr = container_of(itr, struct cs_etm_recording, itr);
cs_etm_pmu = ptr->cs_etm_pmu;
@@ -86,25 +87,59 @@ static int cs_etm_set_context_id(struct auxtrace_record 
*itr,
goto out;
}
 
+   /* User has configured for PID tracing, respects it. */
+   contextid = evsel->core.attr.config &
+   (BIT(ETM_OPT_CTXTID) | BIT(ETM_OPT_CTXTID2));
+
/*
-* TRCIDR2.CIDSIZE, bit [9-5], indicates whether contextID tracing
-* is supported:
-*  0b0 Context ID tracing is not supported.
-*  0b00100 Maximum of 32-bit Context ID size.
-*  All other values are reserved.
+* If user doesn't configure the contextid format, parse PMU format and
+* enable PID tracing according to the "contextid" format bits:
+*
+*   If bit ETM_OPT_CTXTID is set, trace CONTEXTIDR_EL1;
+*   If bit ETM_OPT_CTXTID2 is set, trace CONTEXTIDR_EL2.
 */
-   val = BMVAL(val, 5, 9);
-   if (!val || val != 0x4) {
-   err = -EINVAL;
-   goto out;
+   if (!contextid)
+   contextid = perf_pmu__format_bits(_etm_pmu->format,
+ "contextid");
+
+   if (contextid & BIT(ETM_OPT_CTXTID)) {
+   /*
+* TRCIDR2.CIDSIZE, bit [9-5], indicates whether contextID
+* tracing is supported:
+*  0b0 Context ID tracing is not supported.
+*  0b00100 Maximum of 32-bit Context ID size.
+*  All other values are reserved.
+*/
+   val = BMVAL(val, 5, 9);
+   if (!val || val != 0x4) {
+   pr_err("%s: CONTEXTIDR_EL1 isn't supported\n",
+  CORESIGHT_ETM_PMU_NAME);
+   err = -EINVAL;
+   goto out;
+   }
+   }
+
+   if (contextid & BIT(ETM_OPT_CTXTID2)) {
+   /*
+* TRCIDR2.VMIDOPT[30:29] != 0 and
+* TRCIDR2.VMIDSIZE[14:10] == 0b00100 (32bit virtual contextid)
+* We can't support CONTEXTIDR in VMID if the size of the
+* virtual context id is < 32bit.
+* Any value of VMIDSIZE >= 4 (i.e, > 32bit) is fine for us.
+*/
+   if (!BMVAL(val, 29, 30) || BMVAL(val, 10, 14) < 4) {
+   pr_err("%s: CONTEXTIDR_EL2 isn't supported\n",
+  CORESIGHT_ETM_PMU_NAME);
+   err = -EINVAL;
+   goto out;
+   }
}
 
/* All good, let the kernel know */
-   evsel->core.attr.config |= (1 << ETM_OPT_CTXTID);
+   evsel->core.attr.config |= contextid;
err = 0;
 
 out:
-
return err;
 }
 
@@ -485,7 +520,9 @@ static u64 cs_etmv4_get_config(struct auxtrace_record *itr)

[PATCH 2/6] tools headers UAPI: Update tools' copy of linux/coresight-pmu.h

2021-02-24 Thread Mathieu Poirier
From: Leo Yan 

To get the changes in the commit:

  "coresight: etm-perf: Clarify comment on perf options".

Signed-off-by: Leo Yan 
Reviewed-by: Suzuki K Poulose 
Reviewed-by: Mathieu Poirier 
Link: https://lore.kernel.org/r/20210213113220.292229-2-leo@linaro.org
---
 tools/include/linux/coresight-pmu.h | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/tools/include/linux/coresight-pmu.h 
b/tools/include/linux/coresight-pmu.h
index b0e35eec6499..5dc47cfdcf07 100644
--- a/tools/include/linux/coresight-pmu.h
+++ b/tools/include/linux/coresight-pmu.h
@@ -10,11 +10,18 @@
 #define CORESIGHT_ETM_PMU_NAME "cs_etm"
 #define CORESIGHT_ETM_PMU_SEED  0x10
 
-/* ETMv3.5/PTM's ETMCR config bit */
-#define ETM_OPT_CYCACC  12
-#define ETM_OPT_CTXTID 14
-#define ETM_OPT_TS  28
-#define ETM_OPT_RETSTK 29
+/*
+ * Below are the definition of bit offsets for perf option, and works as
+ * arbitrary values for all ETM versions.
+ *
+ * Most of them are orignally from ETMv3.5/PTM's ETMCR config, therefore,
+ * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
+ * directly use below macros as config bits.
+ */
+#define ETM_OPT_CYCACC 12
+#define ETM_OPT_CTXTID 14
+#define ETM_OPT_TS 28
+#define ETM_OPT_RETSTK 29
 
 /* ETMv4 CONFIGR programming bits for the ETM OPTs */
 #define ETM4_CFG_BIT_CYCACC4
-- 
2.25.1



[PATCH 3/6] perf cs-etm: Fix bitmap for option

2021-02-24 Thread Mathieu Poirier
From: Suzuki K Poulose 

When set option with macros ETM_OPT_CTXTID and ETM_OPT_TS, it wrongly
takes these two values (14 and 28 prespectively) as bit masks, but
actually both are the offset for bits.  But this doesn't lead to
further failure due to the AND logic operation will be always true for
ETM_OPT_CTXTID / ETM_OPT_TS.

This patch uses the BIT() macro for option bits, thus it can request the
correct bitmaps for "contextid" and "timestamp" when calling
cs_etm_set_option().

Signed-off-by: Suzuki K Poulose 
[Extract the change as a separate patch for easier review]
Signed-off-by: Leo Yan 
Reviewed-by: Mike Leach 
Reviewed-by: Mathieu Poirier 
Link: https://lore.kernel.org/r/20210213113220.292229-3-leo@linaro.org
---
 tools/perf/arch/arm/util/cs-etm.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/perf/arch/arm/util/cs-etm.c 
b/tools/perf/arch/arm/util/cs-etm.c
index b0470f2a955a..5b2bb7fc5ee1 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -169,17 +169,17 @@ static int cs_etm_set_option(struct auxtrace_record *itr,
!cpu_map__has(online_cpus, i))
continue;
 
-   if (option & ETM_OPT_CTXTID) {
+   if (option & BIT(ETM_OPT_CTXTID)) {
err = cs_etm_set_context_id(itr, evsel, i);
if (err)
goto out;
}
-   if (option & ETM_OPT_TS) {
+   if (option & BIT(ETM_OPT_TS)) {
err = cs_etm_set_timestamp(itr, evsel, i);
if (err)
goto out;
}
-   if (option & ~(ETM_OPT_CTXTID | ETM_OPT_TS))
+   if (option & ~(BIT(ETM_OPT_CTXTID) | BIT(ETM_OPT_TS)))
/* Nothing else is currently supported */
goto out;
}
@@ -406,7 +406,7 @@ static int cs_etm_recording_options(struct auxtrace_record 
*itr,
evsel__set_sample_bit(cs_etm_evsel, CPU);
 
err = cs_etm_set_option(itr, cs_etm_evsel,
-   ETM_OPT_CTXTID | ETM_OPT_TS);
+   BIT(ETM_OPT_CTXTID) | BIT(ETM_OPT_TS));
if (err)
goto out;
}
-- 
2.25.1



[PATCH 1/6] perf: cs-etm: update ETM metadata format

2021-02-24 Thread Mathieu Poirier
From: Mike Leach 

The current fixed metadata version format (version 0), means that adding
metadata parameter items renders files from a previous version of perf
unreadable. Per CPU parameters appear in a fixed order, but there is no
field to indicate the number of ETM parameters per CPU.

This patch updates the per CPU parameter blocks to include a NR_PARAMs
value which indicates the number of parameters in the block.

The header version is incremented to 1. Fixed ordering is retained,
new ETM parameters are added to the end of the list.

The reader code is updated to be able to read current version 0 files,
For version 1, the reader will read the number of parameters in the
per CPU block. This allows the reader to process older or newer files
that may have different numbers of parameters than in use at the
time perf was built.

Signed-off-by: Mike Leach 
Reviewed-by: Leo Yan 
Tested-by: Leo Yan 

Link: https://lore.kernel.org/r/20210202214040.32349-1-mike.le...@linaro.org
---
 tools/perf/arch/arm/util/cs-etm.c |   7 +-
 tools/perf/util/cs-etm.c  | 235 --
 tools/perf/util/cs-etm.h  |  30 +++-
 3 files changed, 223 insertions(+), 49 deletions(-)

diff --git a/tools/perf/arch/arm/util/cs-etm.c 
b/tools/perf/arch/arm/util/cs-etm.c
index bd446aba64f7..b0470f2a955a 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -572,7 +572,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
struct auxtrace_record *itr,
struct perf_record_auxtrace_info *info)
 {
-   u32 increment;
+   u32 increment, nr_trc_params;
u64 magic;
struct cs_etm_recording *ptr =
container_of(itr, struct cs_etm_recording, itr);
@@ -607,6 +607,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
 
/* How much space was used */
increment = CS_ETMV4_PRIV_MAX;
+   nr_trc_params = CS_ETMV4_PRIV_MAX - CS_ETMV4_TRCCONFIGR;
} else {
magic = __perf_cs_etmv3_magic;
/* Get configuration register */
@@ -624,11 +625,13 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
 
/* How much space was used */
increment = CS_ETM_PRIV_MAX;
+   nr_trc_params = CS_ETM_PRIV_MAX - CS_ETM_ETMCR;
}
 
/* Build generic header portion */
info->priv[*offset + CS_ETM_MAGIC] = magic;
info->priv[*offset + CS_ETM_CPU] = cpu;
+   info->priv[*offset + CS_ETM_NR_TRC_PARAMS] = nr_trc_params;
/* Where the next CPU entry should start from */
*offset += increment;
 }
@@ -674,7 +677,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
 
/* First fill out the session header */
info->type = PERF_AUXTRACE_CS_ETM;
-   info->priv[CS_HEADER_VERSION_0] = 0;
+   info->priv[CS_HEADER_VERSION] = CS_HEADER_CURRENT_VERSION;
info->priv[CS_PMU_TYPE_CPUS] = type << 32;
info->priv[CS_PMU_TYPE_CPUS] |= nr_cpu;
info->priv[CS_ETM_SNAPSHOT] = ptr->snapshot_mode;
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index a2a369e2fbb6..ee32d023e9bd 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2435,7 +2435,7 @@ static bool cs_etm__is_timeless_decoding(struct 
cs_etm_auxtrace *etm)
 }
 
 static const char * const cs_etm_global_header_fmts[] = {
-   [CS_HEADER_VERSION_0]   = " Header version %llx\n",
+   [CS_HEADER_VERSION] = " Header version %llx\n",
[CS_PMU_TYPE_CPUS]  = " PMU type/num cpus  %llx\n",
[CS_ETM_SNAPSHOT]   = " Snapshot   %llx\n",
 };
@@ -2443,6 +2443,7 @@ static const char * const cs_etm_global_header_fmts[] = {
 static const char * const cs_etm_priv_fmts[] = {
[CS_ETM_MAGIC]  = " Magic number   %llx\n",
[CS_ETM_CPU]= " CPU%lld\n",
+   [CS_ETM_NR_TRC_PARAMS]  = " NR_TRC_PARAMS  %llx\n",
[CS_ETM_ETMCR]  = " ETMCR  %llx\n",
[CS_ETM_ETMTRACEIDR]= " ETMTRACEIDR%llx\n",
[CS_ETM_ETMCCER]= " ETMCCER%llx\n",
@@ -2452,6 +2453,7 @@ static const char * const cs_etm_priv_fmts[] = {
 static const char * const cs_etmv4_priv_fmts[] = {
[CS_ETM_MAGIC]  = " Magic number   %llx\n",
[CS_ETM_CPU]= " CPU%lld\n",
+   [CS_ETM_NR_TRC_PARAMS]  = " NR_TRC_PARAMS  %llx\n",
[CS_ETMV4_TRCCONFIGR]   = " TRCCONFIGR %llx\n",
[CS_ETMV4_TRCTRACEIDR]  = " TRCTRACEIDR%llx\n",
[CS_ETMV4_TRCIDR0]  = " TRCIDR0   

[PATCH 5/6] perf cs-etm: Add helper cs_etm__get_pid_fmt()

2021-02-24 Thread Mathieu Poirier
From: Leo Yan 

This patch adds helper function cs_etm__get_pid_fmt(), by passing
parameter "traceID", it returns the PID format.

Signed-off-by: Leo Yan 
Reviewed-by: Mathieu Poirier 
Reviewed-by: Suzuki K Poulose 
Link: https://lore.kernel.org/r/20210213113220.292229-5-leo@linaro.org
---
 tools/perf/util/cs-etm.c | 42 
 tools/perf/util/cs-etm.h |  1 +
 2 files changed, 43 insertions(+)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index ee32d023e9bd..9ac80fc23c58 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -156,6 +157,47 @@ int cs_etm__get_cpu(u8 trace_chan_id, int *cpu)
return 0;
 }
 
+/*
+ * The returned PID format is presented by two bits:
+ *
+ *   Bit ETM_OPT_CTXTID: CONTEXTIDR or CONTEXTIDR_EL1 is traced;
+ *   Bit ETM_OPT_CTXTID2: CONTEXTIDR_EL2 is traced.
+ *
+ * It's possible that the two bits ETM_OPT_CTXTID and ETM_OPT_CTXTID2
+ * are enabled at the same time when the session runs on an EL2 kernel.
+ * This means the CONTEXTIDR_EL1 and CONTEXTIDR_EL2 both will be
+ * recorded in the trace data, the tool will selectively use
+ * CONTEXTIDR_EL2 as PID.
+ */
+int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt)
+{
+   struct int_node *inode;
+   u64 *metadata, val;
+
+   inode = intlist__find(traceid_list, trace_chan_id);
+   if (!inode)
+   return -EINVAL;
+
+   metadata = inode->priv;
+
+   if (metadata[CS_ETM_MAGIC] == __perf_cs_etmv3_magic) {
+   val = metadata[CS_ETM_ETMCR];
+   /* CONTEXTIDR is traced */
+   if (val & BIT(ETM_OPT_CTXTID))
+   *pid_fmt = BIT(ETM_OPT_CTXTID);
+   } else {
+   val = metadata[CS_ETMV4_TRCCONFIGR];
+   /* CONTEXTIDR_EL2 is traced */
+   if (val & (BIT(ETM4_CFG_BIT_VMID) | BIT(ETM4_CFG_BIT_VMID_OPT)))
+   *pid_fmt = BIT(ETM_OPT_CTXTID2);
+   /* CONTEXTIDR_EL1 is traced */
+   else if (val & BIT(ETM4_CFG_BIT_CTXTID))
+   *pid_fmt = BIT(ETM_OPT_CTXTID);
+   }
+
+   return 0;
+}
+
 void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
  u8 trace_chan_id)
 {
diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
index e153d02df0de..85ed11e9d2a7 100644
--- a/tools/perf/util/cs-etm.h
+++ b/tools/perf/util/cs-etm.h
@@ -193,6 +193,7 @@ struct cs_etm_packet_queue {
 int cs_etm__process_auxtrace_info(union perf_event *event,
  struct perf_session *session);
 int cs_etm__get_cpu(u8 trace_chan_id, int *cpu);
+int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt);
 int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
 pid_t tid, u8 trace_chan_id);
 bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq);
-- 
2.25.1



[PATCH 0/6] coresight: Patches for v5.12 (perf tools)

2021-02-24 Thread Mathieu Poirier
Good day Arnaldo,

I noticed there is a couple of patchsets [1][2] that haven't made it
to your tree for the coming v5.12 cycle.  Do you think that can still
be done? 

I tallied the patches here to make it easier for you to pick up.

Applies cleanly on perf/core (84b7725536d8)

Thanks,
Mathieu

[1]. https://lore.kernel.org/lkml/20210202214040.32349-1-mike.le...@linaro.org/
[2]. https://lore.kernel.org/lkml/20210213113220.292229-1-leo@linaro.org/

Leo Yan (2):
  tools headers UAPI: Update tools' copy of linux/coresight-pmu.h
  perf cs-etm: Add helper cs_etm__get_pid_fmt()

Mike Leach (1):
  perf: cs-etm: update ETM metadata format

Suzuki K Poulose (3):
  perf cs-etm: Fix bitmap for option
  perf cs-etm: Support PID tracing in config
  perf cs-etm: Detect pid in VMID for kernel running at EL2

 tools/include/linux/coresight-pmu.h   |  20 +-
 tools/perf/arch/arm/util/cs-etm.c |  76 +++--
 .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  38 ++-
 tools/perf/util/cs-etm.c  | 277 +++---
 tools/perf/util/cs-etm.h  |  31 +-
 5 files changed, 368 insertions(+), 74 deletions(-)

-- 
2.25.1



Re: [PATCH 0/7] Split Coresight decode by aux records

2021-02-24 Thread Mathieu Poirier
Good day James,

I have received your patchset and added it to my queue.  On the flip side it
will be 3 to 4 weeks (from today) before I get a chance to look at it.  As such
I suggest you don't wait on me before addressing the issues found by Leo.

Thanks,
Mathieu

On Fri, Feb 12, 2021 at 04:45:06PM +0200, James Clark wrote:
> Hi All,
> 
> Since my previous RFC, I've fixed --per-thread mode and solved
> most of the open questions. I've also changed --dump-raw-trace
> to use the same code path so it's also working now.
> 
> I think the only open questions are:
>   * General approach
>   * If aux records need to be saved, or if they can be pulled
> from elsewhere.
> 
> I've also tested perf inject which is now working with troublesome
> files.
> 
> Thanks
> James
> 
> James Clark (7):
>   perf cs-etm: Split up etm queue setup function
>   perf cs-etm: Only search timestamp in current sample's queue.
>   perf cs-etm: Save aux records in each etm queue
>   perf cs-etm: don't process queues until cs_etm__flush_events
>   perf cs-etm: split decode by aux records.
>   perf cs-etm: Use existing decode code path for --dump-raw-trace
>   perf cs-etm: Suppress printing when resetting decoder
> 
>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  10 +-
>  tools/perf/util/cs-etm.c  | 300 ++
>  2 files changed, 168 insertions(+), 142 deletions(-)
> 
> -- 
> 2.28.0
> 


[PATCH v6 11/16] remoteproc: Properly deal with the resource table when attached

2021-02-23 Thread Mathieu Poirier
If it is possible to detach the remote processor, keep an untouched
copy of the resource table.  That way we can start from the same
resource table without having to worry about original values or what
elements the startup code has changed when re-attaching to the remote
processor.

Signed-off-by: Mathieu Poirier 
---
New for V6:
- Double free of the cached table has been fixed.
- rproc_reset_loaded_rsc_table() has seen a complete re-write.
- rproc_stop() now calls rproc_reset_loaded_rsc_table() rather than
  dealing with the cached.  This allows to properly shutdown a
  remote processor that was attached to.
---

 drivers/remoteproc/remoteproc_core.c | 86 +++-
 include/linux/remoteproc.h   |  3 +
 2 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index fc01b29290a6..3a4692cc5220 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1556,6 +1556,21 @@ static int rproc_set_loaded_rsc_table(struct rproc 
*rproc)
return ret;
}
 
+   /*
+* If it is possible to detach the remote processor, keep an untouched
+* copy of the resource table.  That way we can start fresh again when
+* the remote processor is re-attached, that is:
+*
+*  DETACHED -> ATTACHED -> DETACHED -> ATTACHED
+*
+* Free'd in rproc_reset_loaded_rsc_table().
+*/
+   if (rproc->ops->detach) {
+   rproc->clean_table = kmemdup(table_ptr, table_sz, GFP_KERNEL);
+   if (!rproc->clean_table)
+   return -ENOMEM;
+   }
+
rproc->cached_table = NULL;
rproc->table_ptr = table_ptr;
rproc->table_sz = table_sz;
@@ -1563,6 +1578,65 @@ static int rproc_set_loaded_rsc_table(struct rproc 
*rproc)
return 0;
 }
 
+static int rproc_reset_loaded_rsc_table(struct rproc *rproc)
+{
+   struct resource_table *table_ptr;
+
+   /*
+* The cached table is already set if the remote processor was started
+* by the remoteproc core.
+*/
+   if (rproc->state == RPROC_RUNNING) {
+   rproc->table_ptr = rproc->cached_table;
+   return 0;
+   }
+
+   /* A resource table was never retrieved, nothing to do here */
+   if (!rproc->table_ptr)
+   return 0;
+
+   /*
+* If we made it to this point a cached_table _must_ have been
+* allocated in rproc_set_loaded_rsc_table().  If one isn't present
+* something went really wrong and we must complain.
+*/
+   if (WARN_ON(!rproc->clean_table))
+   return -EINVAL;
+
+   /* Remember where the external entity installed the resource table */
+   table_ptr = rproc->table_ptr;
+
+   /*
+* Make a copy of the resource table currently used by the remote
+* processor.  Free'd in rproc_detach() or rproc_shutdown().
+*/
+   rproc->cached_table = kmemdup(rproc->table_ptr,
+ rproc->table_sz, GFP_KERNEL);
+   if (!rproc->cached_table)
+   return -ENOMEM;
+
+   /*
+* Use a copy of the resource table for the remainder of the
+* shutdown process.
+*/
+   rproc->table_ptr = rproc->cached_table;
+
+   /*
+* Reset the memory area where the firmware loaded the resource table
+* to its original value.  That way when we re-attach the remote
+* processor the resource table is clean and ready to be used again.
+*/
+   memcpy(table_ptr, rproc->clean_table, rproc->table_sz);
+
+   /*
+* The clean resource table is no longer needed.  Allocated in
+* rproc_set_loaded_rsc_table().
+*/
+   kfree(rproc->clean_table);
+
+   return 0;
+}
+
 /*
  * Attach to remote processor - similar to rproc_fw_boot() but without
  * the steps that deal with the firmware image.
@@ -1688,7 +1762,11 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
rproc_stop_subdevices(rproc, crashed);
 
/* the installed resource table is no longer accessible */
-   rproc->table_ptr = rproc->cached_table;
+   ret = rproc_reset_loaded_rsc_table(rproc);
+   if (ret) {
+   dev_err(dev, "can't reset resource table: %d\n", ret);
+   return ret;
+   }
 
/* power off the remote processor */
ret = rproc->ops->stop(rproc);
@@ -1721,6 +1799,9 @@ static int __rproc_detach(struct rproc *rproc)
/* Stop any subdevices for the remote processor */
rproc_stop_subdevices(rproc, false);
 
+   /* the installed resource table is no longer accessible */
+   ret = rproc_reset_loaded_rsc_table(rproc);
+
/* Tell the remote processor the core isn't available

[PATCH v6 12/16] remoteproc: Properly deal with a kernel panic when attached

2021-02-23 Thread Mathieu Poirier
The panic handler operation of registered remote processors
should also be called when remote processors have been
attached to.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 3a4692cc5220..0dc518a24104 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2684,7 +2684,11 @@ static int rproc_panic_handler(struct notifier_block 
*nb, unsigned long event,
 
rcu_read_lock();
list_for_each_entry_rcu(rproc, _list, node) {
-   if (!rproc->ops->panic || rproc->state != RPROC_RUNNING)
+   if (!rproc->ops->panic)
+   continue;
+
+   if (rproc->state != RPROC_RUNNING &&
+   rproc->state != RPROC_ATTACHED)
continue;
 
d = rproc->ops->panic(rproc);
-- 
2.25.1



[PATCH v6 13/16] remoteproc: Properly deal with a start request when attached

2021-02-23 Thread Mathieu Poirier
This patch takes into account scenarios where a remote processor
has been attached to when receiving a "start" command from sysfs.

As with the case with the running state, the command can't be
carried out if the remote processor is already in operation.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_cdev.c  | 3 ++-
 drivers/remoteproc/remoteproc_sysfs.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_cdev.c 
b/drivers/remoteproc/remoteproc_cdev.c
index b19ea3057bde..b2cee9afb41b 100644
--- a/drivers/remoteproc/remoteproc_cdev.c
+++ b/drivers/remoteproc/remoteproc_cdev.c
@@ -32,7 +32,8 @@ static ssize_t rproc_cdev_write(struct file *filp, const char 
__user *buf, size_
return -EFAULT;
 
if (!strncmp(cmd, "start", len)) {
-   if (rproc->state == RPROC_RUNNING)
+   if (rproc->state == RPROC_RUNNING ||
+   rproc->state == RPROC_ATTACHED)
return -EBUSY;
 
ret = rproc_boot(rproc);
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index f9694def9b54..66801e6fe5cd 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -194,7 +194,8 @@ static ssize_t state_store(struct device *dev,
int ret = 0;
 
if (sysfs_streq(buf, "start")) {
-   if (rproc->state == RPROC_RUNNING)
+   if (rproc->state == RPROC_RUNNING ||
+   rproc->state == RPROC_ATTACHED)
return -EBUSY;
 
ret = rproc_boot(rproc);
-- 
2.25.1



[PATCH v6 14/16] remoteproc: Properly deal with a stop request when attached

2021-02-23 Thread Mathieu Poirier
Allow a remote processor that was started by another entity to be
switched off by the remoteproc core.  For that to happen a
rproc::ops::stop() operation needs to be available.

Signed-off-by: Mathieu Poirier 
---
New for V6:
- Removed state check in rproc_shutdown() as it is already done in
  in calling functions.
- rproc_shutdown() doesn't return an error code to keep legacy behevior.
- Removed Peng and Arnaud's RB tags because of the above.
---

 drivers/remoteproc/remoteproc_cdev.c  | 3 ++-
 drivers/remoteproc/remoteproc_core.c  | 4 
 drivers/remoteproc/remoteproc_sysfs.c | 3 ++-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_cdev.c 
b/drivers/remoteproc/remoteproc_cdev.c
index b2cee9afb41b..0249d8f6c3f8 100644
--- a/drivers/remoteproc/remoteproc_cdev.c
+++ b/drivers/remoteproc/remoteproc_cdev.c
@@ -38,7 +38,8 @@ static ssize_t rproc_cdev_write(struct file *filp, const char 
__user *buf, size_
 
ret = rproc_boot(rproc);
} else if (!strncmp(cmd, "stop", len)) {
-   if (rproc->state != RPROC_RUNNING)
+   if (rproc->state != RPROC_RUNNING &&
+   rproc->state != RPROC_ATTACHED)
return -EINVAL;
 
rproc_shutdown(rproc);
diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 0dc518a24104..00452da25fba 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1758,6 +1758,10 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
struct device *dev = >dev;
int ret;
 
+   /* No need to continue if a stop() operation has not been provided */
+   if (!rproc->ops->stop)
+   return -EINVAL;
+
/* Stop any subdevices for the remote processor */
rproc_stop_subdevices(rproc, crashed);
 
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 66801e6fe5cd..09eb700c5e7e 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -202,7 +202,8 @@ static ssize_t state_store(struct device *dev,
if (ret)
dev_err(>dev, "Boot failed: %d\n", ret);
} else if (sysfs_streq(buf, "stop")) {
-   if (rproc->state != RPROC_RUNNING)
+   if (rproc->state != RPROC_RUNNING &&
+   rproc->state != RPROC_ATTACHED)
return -EINVAL;
 
rproc_shutdown(rproc);
-- 
2.25.1



[PATCH v6 16/16] remoteproc: Refactor rproc delete and cdev release path

2021-02-23 Thread Mathieu Poirier
Refactor function rproc_del() and rproc_cdev_release() to take
into account the current state of the remote processor when choosing
the state to transition to.

Signed-off-by: Mathieu Poirier 
---
New for V6:
- The RPROC_RUNNING -> RPROC_DETACHED transition is no longer permitted.
  to avoid dealing with complex resource table management problems.
- Transition to the next state is no longer dictated by a DT binding for
  the same reason as above.
- Removed Peng and Arnaud's RB tags because of the above.
---

 drivers/remoteproc/remoteproc_cdev.c | 10 --
 drivers/remoteproc/remoteproc_core.c |  9 +++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_cdev.c 
b/drivers/remoteproc/remoteproc_cdev.c
index 2db494816d5f..0b8a84c04f76 100644
--- a/drivers/remoteproc/remoteproc_cdev.c
+++ b/drivers/remoteproc/remoteproc_cdev.c
@@ -86,11 +86,17 @@ static long rproc_device_ioctl(struct file *filp, unsigned 
int ioctl, unsigned l
 static int rproc_cdev_release(struct inode *inode, struct file *filp)
 {
struct rproc *rproc = container_of(inode->i_cdev, struct rproc, cdev);
+   int ret = 0;
+
+   if (!rproc->cdev_put_on_release)
+   return 0;
 
-   if (rproc->cdev_put_on_release && rproc->state == RPROC_RUNNING)
+   if (rproc->state == RPROC_RUNNING)
rproc_shutdown(rproc);
+   else if (rproc->state == RPROC_ATTACHED)
+   ret = rproc_detach(rproc);
 
-   return 0;
+   return ret;
 }
 
 static const struct file_operations rproc_fops = {
diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 00452da25fba..a05d5fec43b1 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2542,11 +2542,16 @@ EXPORT_SYMBOL(rproc_put);
  */
 int rproc_del(struct rproc *rproc)
 {
+   int ret = 0;
+
if (!rproc)
return -EINVAL;
 
/* TODO: make sure this works with rproc->power > 1 */
-   rproc_shutdown(rproc);
+   if (rproc->state == RPROC_RUNNING)
+   rproc_shutdown(rproc);
+   else if (rproc->state == RPROC_ATTACHED)
+   ret = rproc_detach(rproc);
 
mutex_lock(>lock);
rproc->state = RPROC_DELETED;
@@ -2565,7 +2570,7 @@ int rproc_del(struct rproc *rproc)
 
device_del(>dev);
 
-   return 0;
+   return ret;
 }
 EXPORT_SYMBOL(rproc_del);
 
-- 
2.25.1



[PATCH v6 07/16] remoteproc: stm32: Move memory parsing to rproc_ops

2021-02-23 Thread Mathieu Poirier
From: Arnaud POULIQUEN 

Some actions such as memory resources reallocation are needed when
trying to reattach a co-processor. Use the prepare() operation for
these actions.

Co-developed-by: Mathieu Poirier 
Signed-off-by: Mathieu Poirier 
Signed-off-by: Arnaud POULIQUEN 
---
 drivers/remoteproc/remoteproc_core.c | 14 --
 drivers/remoteproc/stm32_rproc.c | 27 ++-
 2 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 0012b7bdce24..86572880c726 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1582,10 +1582,17 @@ static int rproc_attach(struct rproc *rproc)
return ret;
}
 
+   /* Do anything that is needed to boot the remote processor */
+   ret = rproc_prepare_device(rproc);
+   if (ret) {
+   dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
+   goto disable_iommu;
+   }
+
ret = rproc_set_loaded_rsc_table(rproc);
if (ret) {
dev_err(dev, "can't load resource table: %d\n", ret);
-   goto disable_iommu;
+   goto unprepare_device;
}
 
/* reset max_notifyid */
@@ -1602,7 +1609,7 @@ static int rproc_attach(struct rproc *rproc)
ret = rproc_handle_resources(rproc, rproc_loading_handlers);
if (ret) {
dev_err(dev, "Failed to process resources: %d\n", ret);
-   goto disable_iommu;
+   goto unprepare_device;
}
 
/* Allocate carveout resources associated to rproc */
@@ -1621,6 +1628,9 @@ static int rproc_attach(struct rproc *rproc)
 
 clean_up_resources:
rproc_resource_cleanup(rproc);
+unprepare_device:
+   /* release HW resources if needed */
+   rproc_unprepare_device(rproc);
 disable_iommu:
rproc_disable_iommu(rproc);
return ret;
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index f647e565014b..3d45f51de4d0 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -207,16 +207,7 @@ static int stm32_rproc_mbox_idx(struct rproc *rproc, const 
unsigned char *name)
return -EINVAL;
 }
 
-static int stm32_rproc_elf_load_rsc_table(struct rproc *rproc,
- const struct firmware *fw)
-{
-   if (rproc_elf_load_rsc_table(rproc, fw))
-   dev_warn(>dev, "no resource table found for this 
firmware\n");
-
-   return 0;
-}
-
-static int stm32_rproc_parse_memory_regions(struct rproc *rproc)
+static int stm32_rproc_prepare(struct rproc *rproc)
 {
struct device *dev = rproc->dev.parent;
struct device_node *np = dev->of_node;
@@ -274,12 +265,10 @@ static int stm32_rproc_parse_memory_regions(struct rproc 
*rproc)
 
 static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
 {
-   int ret = stm32_rproc_parse_memory_regions(rproc);
-
-   if (ret)
-   return ret;
+   if (rproc_elf_load_rsc_table(rproc, fw))
+   dev_warn(>dev, "no resource table found for this 
firmware\n");
 
-   return stm32_rproc_elf_load_rsc_table(rproc, fw);
+   return 0;
 }
 
 static irqreturn_t stm32_rproc_wdg(int irq, void *data)
@@ -614,6 +603,7 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, 
size_t *table_sz)
 }
 
 static const struct rproc_ops st_rproc_ops = {
+   .prepare= stm32_rproc_prepare,
.start  = stm32_rproc_start,
.stop   = stm32_rproc_stop,
.attach = stm32_rproc_attach,
@@ -796,14 +786,9 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;
 
-   if (state == M4_STATE_CRUN) {
+   if (state == M4_STATE_CRUN)
rproc->state = RPROC_DETACHED;
 
-   ret = stm32_rproc_parse_memory_regions(rproc);
-   if (ret)
-   goto free_resources;
-   }
-
rproc->has_iommu = false;
ddata->workqueue = create_workqueue(dev_name(dev));
if (!ddata->workqueue) {
-- 
2.25.1



[PATCH v6 09/16] remoteproc: Introduce function __rproc_detach()

2021-02-23 Thread Mathieu Poirier
Introduce function __rproc_detach() to perform the same kind of
operation as rproc_stop(), but instead of switching off the
remote processor using rproc->ops->stop(), it uses
rproc->ops->detach().  That way it is possible for the core
to release the resources associated with a remote processor while
the latter is kept operating.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
---
 drivers/remoteproc/remoteproc_core.c | 30 
 1 file changed, 30 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 86572880c726..0f680b7ff8f1 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1706,6 +1706,36 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
return 0;
 }
 
+/*
+ * __rproc_detach(): Does the opposite of __rproc_attach()
+ */
+static int __maybe_unused __rproc_detach(struct rproc *rproc)
+{
+   struct device *dev = >dev;
+   int ret;
+
+   /* No need to continue if a detach() operation has not been provided */
+   if (!rproc->ops->detach)
+   return -EINVAL;
+
+   /* Stop any subdevices for the remote processor */
+   rproc_stop_subdevices(rproc, false);
+
+   /* Tell the remote processor the core isn't available anymore */
+   ret = rproc->ops->detach(rproc);
+   if (ret) {
+   dev_err(dev, "can't detach from rproc: %d\n", ret);
+   return ret;
+   }
+
+   rproc_unprepare_subdevices(rproc);
+
+   rproc->state = RPROC_DETACHED;
+
+   dev_info(dev, "detached remote processor %s\n", rproc->name);
+
+   return 0;
+}
 
 /**
  * rproc_trigger_recovery() - recover a remoteproc
-- 
2.25.1



[PATCH v6 10/16] remoteproc: Introduce function rproc_detach()

2021-02-23 Thread Mathieu Poirier
Introduce function rproc_detach() to enable the remoteproc
core to release the resources associated with a remote processor
without stopping its operation.

Signed-off-by: Mathieu Poirier 
---
New for V6:
- Checking for rproc->state has been removed.  They have been moved to
  calling functions.
- Freeing the cache table has been moved to the next patch, i.e 11/16.
---

 drivers/remoteproc/remoteproc_core.c | 58 +++-
 include/linux/remoteproc.h   |  1 +
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 0f680b7ff8f1..fc01b29290a6 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1709,7 +1709,7 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
 /*
  * __rproc_detach(): Does the opposite of __rproc_attach()
  */
-static int __maybe_unused __rproc_detach(struct rproc *rproc)
+static int __rproc_detach(struct rproc *rproc)
 {
struct device *dev = >dev;
int ret;
@@ -1948,6 +1948,62 @@ void rproc_shutdown(struct rproc *rproc)
 }
 EXPORT_SYMBOL(rproc_shutdown);
 
+/**
+ * rproc_detach() - Detach the remote processor from the
+ * remoteproc core
+ *
+ * @rproc: the remote processor
+ *
+ * Detach a remote processor (previously attached to with rproc_attach()).
+ *
+ * In case @rproc is still being used by an additional user(s), then
+ * this function will just decrement the power refcount and exit,
+ * without disconnecting the device.
+ *
+ * Function rproc_detach() calls __rproc_detach() in order to let a remote
+ * processor know that services provided by the application processor are
+ * no longer available.  From there it should be possible to remove the
+ * platform driver and even power cycle the application processor (if the HW
+ * supports it) without needing to switch off the remote processor.
+ */
+int rproc_detach(struct rproc *rproc)
+{
+   struct device *dev = >dev;
+   int ret;
+
+   ret = mutex_lock_interruptible(>lock);
+   if (ret) {
+   dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret);
+   return ret;
+   }
+
+   /* if the remote proc is still needed, bail out */
+   if (!atomic_dec_and_test(>power)) {
+   ret = 0;
+   goto out;
+   }
+
+   ret = __rproc_detach(rproc);
+   if (ret) {
+   atomic_inc(>power);
+   goto out;
+   }
+
+   /* clean up all acquired resources */
+   rproc_resource_cleanup(rproc);
+
+   /* release HW resources if needed */
+   rproc_unprepare_device(rproc);
+
+   rproc_disable_iommu(rproc);
+
+   rproc->table_ptr = NULL;
+out:
+   mutex_unlock(>lock);
+   return ret;
+}
+EXPORT_SYMBOL(rproc_detach);
+
 /**
  * rproc_get_by_phandle() - find a remote processor by phandle
  * @phandle: phandle to the rproc
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index eff55ec72e80..e1c843c19cc6 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -662,6 +662,7 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 
of_resm_idx, size_t len,
 
 int rproc_boot(struct rproc *rproc);
 void rproc_shutdown(struct rproc *rproc);
+int rproc_detach(struct rproc *rproc);
 int rproc_set_firmware(struct rproc *rproc, const char *fw_name);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 void rproc_coredump_using_sections(struct rproc *rproc);
-- 
2.25.1



[PATCH v6 15/16] remoteproc: Properly deal with a detach request when attached

2021-02-23 Thread Mathieu Poirier
This patch introduces the capability to detach a remote processor
that has been attached by the remoteproc core.  For that to happen
a rproc::ops::detach() operation needs to be available.

Signed-off-by: Mathieu Poirier 
---
New for V6:
- The RPROC_RUNNING -> RPROC_DETACHED transition is no longer permitted
  to avoid dealing with complex resource table management problems.
- Removed Peng and Arnaud's RB tags because of the above.
---

 drivers/remoteproc/remoteproc_cdev.c  | 5 +
 drivers/remoteproc/remoteproc_sysfs.c | 5 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_cdev.c 
b/drivers/remoteproc/remoteproc_cdev.c
index 0249d8f6c3f8..2db494816d5f 100644
--- a/drivers/remoteproc/remoteproc_cdev.c
+++ b/drivers/remoteproc/remoteproc_cdev.c
@@ -43,6 +43,11 @@ static ssize_t rproc_cdev_write(struct file *filp, const 
char __user *buf, size_
return -EINVAL;
 
rproc_shutdown(rproc);
+   } else if (!strncmp(cmd, "detach", len)) {
+   if (rproc->state != RPROC_ATTACHED)
+   return -EINVAL;
+
+   ret = rproc_detach(rproc);
} else {
dev_err(>dev, "Unrecognized option\n");
ret = -EINVAL;
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 09eb700c5e7e..ad3dd208024c 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -207,6 +207,11 @@ static ssize_t state_store(struct device *dev,
return -EINVAL;
 
rproc_shutdown(rproc);
+   } else if (sysfs_streq(buf, "detach")) {
+   if (rproc->state != RPROC_ATTACHED)
+   return -EINVAL;
+
+   ret = rproc_detach(rproc);
} else {
dev_err(>dev, "Unrecognised option: %s\n", buf);
ret = -EINVAL;
-- 
2.25.1



[PATCH v6 08/16] remoteproc: Add new detach() remoteproc operation

2021-02-23 Thread Mathieu Poirier
Add an new detach() operation in order to support scenarios where
the remoteproc core is going away but the remote processor is
kept operating.  This could be the case when the system is
rebooted or when the platform driver is removed.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 include/linux/remoteproc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 51538a7d120d..eff55ec72e80 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -361,6 +361,7 @@ enum rsc_handling_status {
  * @start: power on the device and boot it
  * @stop:  power off the device
  * @attach:attach to a device that his already powered up
+ * @detach:detach from a device, leaving it powered up
  * @kick:  kick a virtqueue (virtqueue id given as a parameter)
  * @da_to_va:  optional platform hook to perform address translations
  * @parse_fw:  parse firmware to extract information (e.g. resource table)
@@ -385,6 +386,7 @@ struct rproc_ops {
int (*start)(struct rproc *rproc);
int (*stop)(struct rproc *rproc);
int (*attach)(struct rproc *rproc);
+   int (*detach)(struct rproc *rproc);
void (*kick)(struct rproc *rproc, int vqid);
void * (*da_to_va)(struct rproc *rproc, u64 da, size_t len);
int (*parse_fw)(struct rproc *rproc, const struct firmware *fw);
-- 
2.25.1



[PATCH v6 04/16] remoteproc: Properly represent the attached state

2021-02-23 Thread Mathieu Poirier
There is a need to know when a remote processor has been attached
to rather than booted by the remoteproc core.  In order to avoid
manipulating two variables, i.e rproc::autonomous and
rproc::state, get rid of the former and simply use the newly
introduced RPROC_ATTACHED state.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c  | 20 +---
 drivers/remoteproc/remoteproc_sysfs.c |  5 +
 include/linux/remoteproc.h|  2 --
 3 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 7b66e1e96e4a..8c7e9f1d50d7 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1444,7 +1444,7 @@ static int __rproc_attach(struct rproc *rproc)
goto stop_rproc;
}
 
-   rproc->state = RPROC_RUNNING;
+   rproc->state = RPROC_ATTACHED;
 
dev_info(dev, "remote processor %s is now attached\n", rproc->name);
 
@@ -1659,14 +1659,6 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
 
rproc->state = RPROC_OFFLINE;
 
-   /*
-* The remote processor has been stopped and is now offline, which means
-* that the next time it is brought back online the remoteproc core will
-* be responsible to load its firmware.  As such it is no longer
-* autonomous.
-*/
-   rproc->autonomous = false;
-
dev_info(dev, "stopped remote processor %s\n", rproc->name);
 
return 0;
@@ -2077,16 +2069,6 @@ int rproc_add(struct rproc *rproc)
if (ret < 0)
return ret;
 
-   /*
-* Remind ourselves the remote processor has been attached to rather
-* than booted by the remoteproc core.  This is important because the
-* RPROC_DETACHED state will be lost as soon as the remote processor
-* has been attached to.  Used in firmware_show() and reset in
-* rproc_stop().
-*/
-   if (rproc->state == RPROC_DETACHED)
-   rproc->autonomous = true;
-
/* if rproc is marked always-on, request it to boot */
if (rproc->auto_boot) {
ret = rproc_trigger_auto_boot(rproc);
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 4b4aab0d4c4b..f9694def9b54 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -138,11 +138,8 @@ static ssize_t firmware_show(struct device *dev, struct 
device_attribute *attr,
 * If the remote processor has been started by an external
 * entity we have no idea of what image it is running.  As such
 * simply display a generic string rather then rproc->firmware.
-*
-* Here we rely on the autonomous flag because a remote processor
-* may have been attached to and currently in a running state.
 */
-   if (rproc->autonomous)
+   if (rproc->state == RPROC_ATTACHED)
firmware = "unknown";
 
return sprintf(buf, "%s\n", firmware);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index b0a57ff73849..6b0a0ed30a03 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -512,7 +512,6 @@ struct rproc_dump_segment {
  * @table_sz: size of @cached_table
  * @has_iommu: flag to indicate if remote processor is behind an MMU
  * @auto_boot: flag to indicate if remote processor should be auto-started
- * @autonomous: true if an external entity has booted the remote processor
  * @dump_segments: list of segments in the firmware
  * @nb_vdev: number of vdev currently handled by rproc
  * @char_dev: character device of the rproc
@@ -549,7 +548,6 @@ struct rproc {
size_t table_sz;
bool has_iommu;
bool auto_boot;
-   bool autonomous;
struct list_head dump_segments;
int nb_vdev;
u8 elf_class;
-- 
2.25.1



[PATCH v6 06/16] remoteproc: stm32: Move resource table setup to rproc_ops

2021-02-23 Thread Mathieu Poirier
Move the setting of the resource table installed by an external
entity to rproc_ops::get_loaded_rsc_table().  This is to support
scenarios where a remote processor has been started by the core
but is detached at a later stage.  To re-attach the remote
processor, the address of the resource table needs to be available
at a later time than the platform driver's probe() function.

Signed-off-by: Mathieu Poirier 
---
 drivers/remoteproc/stm32_rproc.c | 141 +++
 1 file changed, 68 insertions(+), 73 deletions(-)

diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index ccb3c14a0023..f647e565014b 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -546,6 +546,73 @@ static void stm32_rproc_kick(struct rproc *rproc, int vqid)
}
 }
 
+static int stm32_rproc_da_to_pa(struct rproc *rproc,
+   u64 da, phys_addr_t *pa)
+{
+   struct stm32_rproc *ddata = rproc->priv;
+   struct device *dev = rproc->dev.parent;
+   struct stm32_rproc_mem *p_mem;
+   unsigned int i;
+
+   for (i = 0; i < ddata->nb_rmems; i++) {
+   p_mem = >rmems[i];
+
+   if (da < p_mem->dev_addr ||
+   da >= p_mem->dev_addr + p_mem->size)
+   continue;
+
+   *pa = da - p_mem->dev_addr + p_mem->bus_addr;
+   dev_dbg(dev, "da %llx to pa %#x\n", da, *pa);
+
+   return 0;
+   }
+
+   dev_err(dev, "can't translate da %llx\n", da);
+
+   return -EINVAL;
+}
+
+static struct resource_table *
+stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
+{
+   struct stm32_rproc *ddata = rproc->priv;
+   struct device *dev = rproc->dev.parent;
+   phys_addr_t rsc_pa;
+   u32 rsc_da;
+   int err;
+
+   /* The resource table has already been mapped, nothing to do */
+   if (ddata->rsc_va)
+   goto done;
+
+   err = regmap_read(ddata->rsctbl.map, ddata->rsctbl.reg, _da);
+   if (err) {
+   dev_err(dev, "failed to read rsc tbl addr\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (!rsc_da)
+   /* no rsc table */
+   return ERR_PTR(-ENOENT);
+
+   err = stm32_rproc_da_to_pa(rproc, rsc_da, _pa);
+   if (err)
+   return ERR_PTR(err);
+
+   ddata->rsc_va = devm_ioremap_wc(dev, rsc_pa, RSC_TBL_SIZE);
+   if (IS_ERR_OR_NULL(ddata->rsc_va)) {
+   dev_err(dev, "Unable to map memory region: %pa+%zx\n",
+   _pa, RSC_TBL_SIZE);
+   ddata->rsc_va = NULL;
+   return ERR_PTR(-ENOMEM);
+   }
+
+done:
+   /* Assuming the resource table fits in 1kB is fair */
+   *table_sz = RSC_TBL_SIZE;
+   return (struct resource_table *)ddata->rsc_va;
+}
+
 static const struct rproc_ops st_rproc_ops = {
.start  = stm32_rproc_start,
.stop   = stm32_rproc_stop,
@@ -554,6 +621,7 @@ static const struct rproc_ops st_rproc_ops = {
.load   = rproc_elf_load_segments,
.parse_fw   = stm32_rproc_parse_fw,
.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
+   .get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
.sanity_check   = rproc_elf_sanity_check,
.get_boot_addr  = rproc_elf_get_boot_addr,
 };
@@ -695,75 +763,6 @@ static int stm32_rproc_get_m4_status(struct stm32_rproc 
*ddata,
return regmap_read(ddata->m4_state.map, ddata->m4_state.reg, state);
 }
 
-static int stm32_rproc_da_to_pa(struct platform_device *pdev,
-   struct stm32_rproc *ddata,
-   u64 da, phys_addr_t *pa)
-{
-   struct device *dev = >dev;
-   struct stm32_rproc_mem *p_mem;
-   unsigned int i;
-
-   for (i = 0; i < ddata->nb_rmems; i++) {
-   p_mem = >rmems[i];
-
-   if (da < p_mem->dev_addr ||
-   da >= p_mem->dev_addr + p_mem->size)
-   continue;
-
-   *pa = da - p_mem->dev_addr + p_mem->bus_addr;
-   dev_dbg(dev, "da %llx to pa %#x\n", da, *pa);
-
-   return 0;
-   }
-
-   dev_err(dev, "can't translate da %llx\n", da);
-
-   return -EINVAL;
-}
-
-static int stm32_rproc_get_loaded_rsc_table(struct platform_device *pdev,
-   struct rproc *rproc,
-   struct stm32_rproc *ddata)
-{
-   struct device *dev = >dev;
-   phys_addr_t rsc_pa;
-   u32 rsc_da;
-   int err;
-
-   err = regmap_read(ddata->rsctbl.map, ddata->rsctbl.reg, _da);
-   if (err) {
-   dev_err(dev, "failed to read rsc tbl addr\n");
- 

[PATCH v6 05/16] remoteproc: Add new get_loaded_rsc_table() to rproc_ops

2021-02-23 Thread Mathieu Poirier
Add a new get_loaded_rsc_table() operation in order to support
scenarios where the remoteproc core has booted a remote processor
and detaches from it.  When re-attaching to the remote processor,
the core needs to know where the resource table has been placed
in memory.

Signed-off-by: Mathieu Poirier 
---
New for V6:
- Don't return an error if a resource table doesn't exist.
---

 drivers/remoteproc/remoteproc_core.c | 32 
 drivers/remoteproc/remoteproc_internal.h | 10 
 include/linux/remoteproc.h   |  6 -
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 8c7e9f1d50d7..0012b7bdce24 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1537,6 +1537,32 @@ static int rproc_fw_boot(struct rproc *rproc, const 
struct firmware *fw)
return ret;
 }
 
+static int rproc_set_loaded_rsc_table(struct rproc *rproc)
+{
+   struct resource_table *table_ptr;
+   struct device *dev = >dev;
+   size_t table_sz;
+   int ret;
+
+   table_ptr = rproc_get_loaded_rsc_table(rproc, _sz);
+   if (!table_ptr) {
+   /* Not having a resource table is acceptable */
+   return 0;
+   }
+
+   if (IS_ERR(table_ptr)) {
+   ret = PTR_ERR(table_ptr);
+   dev_err(dev, "can't load resource table: %d\n", ret);
+   return ret;
+   }
+
+   rproc->cached_table = NULL;
+   rproc->table_ptr = table_ptr;
+   rproc->table_sz = table_sz;
+
+   return 0;
+}
+
 /*
  * Attach to remote processor - similar to rproc_fw_boot() but without
  * the steps that deal with the firmware image.
@@ -1556,6 +1582,12 @@ static int rproc_attach(struct rproc *rproc)
return ret;
}
 
+   ret = rproc_set_loaded_rsc_table(rproc);
+   if (ret) {
+   dev_err(dev, "can't load resource table: %d\n", ret);
+   goto disable_iommu;
+   }
+
/* reset max_notifyid */
rproc->max_notifyid = -1;
 
diff --git a/drivers/remoteproc/remoteproc_internal.h 
b/drivers/remoteproc/remoteproc_internal.h
index c34002888d2c..4f73aac7e60d 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -177,6 +177,16 @@ struct resource_table *rproc_find_loaded_rsc_table(struct 
rproc *rproc,
return NULL;
 }
 
+static inline
+struct resource_table *rproc_get_loaded_rsc_table(struct rproc *rproc,
+ size_t *size)
+{
+   if (rproc->ops->get_loaded_rsc_table)
+   return rproc->ops->get_loaded_rsc_table(rproc, size);
+
+   return NULL;
+}
+
 static inline
 bool rproc_u64_fit_in_size_t(u64 val)
 {
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 6b0a0ed30a03..51538a7d120d 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -368,7 +368,9 @@ enum rsc_handling_status {
  * RSC_HANDLED if resource was handled, RSC_IGNORED if not handled and a
  * negative value on error
  * @load_rsc_table:load resource table from firmware image
- * @find_loaded_rsc_table: find the loaded resouce table
+ * @find_loaded_rsc_table: find the loaded resource table from firmware image
+ * @get_loaded_rsc_table: get resource table installed in memory
+ *   by external entity
  * @load:  load firmware to memory, where the remote processor
  * expects to find it
  * @sanity_check:  sanity check the fw image
@@ -390,6 +392,8 @@ struct rproc_ops {
  int offset, int avail);
struct resource_table *(*find_loaded_rsc_table)(
struct rproc *rproc, const struct firmware *fw);
+   struct resource_table *(*get_loaded_rsc_table)(
+   struct rproc *rproc, size_t *size);
int (*load)(struct rproc *rproc, const struct firmware *fw);
int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
-- 
2.25.1



[PATCH v6 02/16] remoteproc: Rename function rproc_actuate()

2021-02-23 Thread Mathieu Poirier
Rename function rproc_actuate() to rproc_attach().  That way it is
easy to understand that it does the opposite of rproc_detach().

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index d2704501b653..7b66e1e96e4a 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1416,7 +1416,7 @@ static int rproc_start(struct rproc *rproc, const struct 
firmware *fw)
return ret;
 }
 
-static int rproc_attach(struct rproc *rproc)
+static int __rproc_attach(struct rproc *rproc)
 {
struct device *dev = >dev;
int ret;
@@ -1541,7 +1541,7 @@ static int rproc_fw_boot(struct rproc *rproc, const 
struct firmware *fw)
  * Attach to remote processor - similar to rproc_fw_boot() but without
  * the steps that deal with the firmware image.
  */
-static int rproc_actuate(struct rproc *rproc)
+static int rproc_attach(struct rproc *rproc)
 {
struct device *dev = >dev;
int ret;
@@ -1581,7 +1581,7 @@ static int rproc_actuate(struct rproc *rproc)
goto clean_up_resources;
}
 
-   ret = rproc_attach(rproc);
+   ret = __rproc_attach(rproc);
if (ret)
goto clean_up_resources;
 
@@ -1802,7 +1802,7 @@ int rproc_boot(struct rproc *rproc)
if (rproc->state == RPROC_DETACHED) {
dev_info(dev, "attaching to %s\n", rproc->name);
 
-   ret = rproc_actuate(rproc);
+   ret = rproc_attach(rproc);
} else {
dev_info(dev, "powering up %s\n", rproc->name);
 
-- 
2.25.1



[PATCH v6 03/16] remoteproc: Add new RPROC_ATTACHED state

2021-02-23 Thread Mathieu Poirier
Add a new RPROC_ATTACHED state to take into account scenarios
where the remoteproc core needs to attach to a remote processor
that is booted by another entity.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_sysfs.c | 1 +
 include/linux/remoteproc.h| 7 +--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 1dbef895e65e..4b4aab0d4c4b 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -172,6 +172,7 @@ static const char * const rproc_state_string[] = {
[RPROC_RUNNING] = "running",
[RPROC_CRASHED] = "crashed",
[RPROC_DELETED] = "deleted",
+   [RPROC_ATTACHED]= "attached",
[RPROC_DETACHED]= "detached",
[RPROC_LAST]= "invalid",
 };
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index f28ee75d1005..b0a57ff73849 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -405,6 +405,8 @@ struct rproc_ops {
  * @RPROC_RUNNING: device is up and running
  * @RPROC_CRASHED: device has crashed; need to start recovery
  * @RPROC_DELETED: device is deleted
+ * @RPROC_ATTACHED:device has been booted by another entity and the core
+ * has attached to it
  * @RPROC_DETACHED:device has been booted by another entity and waiting
  * for the core to attach to it
  * @RPROC_LAST:just keep this one at the end
@@ -421,8 +423,9 @@ enum rproc_state {
RPROC_RUNNING   = 2,
RPROC_CRASHED   = 3,
RPROC_DELETED   = 4,
-   RPROC_DETACHED  = 5,
-   RPROC_LAST  = 6,
+   RPROC_ATTACHED  = 5,
+   RPROC_DETACHED  = 6,
+   RPROC_LAST  = 7,
 };
 
 /**
-- 
2.25.1



[PATCH v6 00/16] remoteproc: Add support for detaching a remote processor

2021-02-23 Thread Mathieu Poirier
Following the work done here [1], this set provides support for the
remoteproc core to release resources associated with a remote processor
without having to switch it off. That way a platform driver can be removed
or the application processor power cycled while the remote processor is
still operating.

Modifications for this revision are detailed in the changelog of each patch
but the main difference is that going from RPROC_RUNNING -> RPROC_DETACHED
is no longer supported to avoid dealing tricky resource table issues.

Applies cleanly on rproc-next (e8b4e9a21af7).  I will rebase on 5.12-rc1 when it
comes out next week.

Thanks,
Mathieu

Arnaud POULIQUEN (1):
  remoteproc: stm32: Move memory parsing to rproc_ops

Mathieu Poirier (15):
  remoteproc: Remove useless check in rproc_del()
  remoteproc: Rename function rproc_actuate()
  remoteproc: Add new RPROC_ATTACHED state
  remoteproc: Properly represent the attached state
  remoteproc: Add new get_loaded_rsc_table() to rproc_ops
  remoteproc: stm32: Move resource table setup to rproc_ops
  remoteproc: Add new detach() remoteproc operation
  remoteproc: Introduce function __rproc_detach()
  remoteproc: Introduce function rproc_detach()
  remoteproc: Properly deal with the resource table when attached
  remoteproc: Properly deal with a kernel panic when attached
  remoteproc: Properly deal with a start request when attached
  remoteproc: Properly deal with a stop request when attached
  remoteproc: Properly deal with a detach request when attached
  remoteproc: Refactor rproc delete and cdev release path

 drivers/remoteproc/remoteproc_cdev.c |  21 +-
 drivers/remoteproc/remoteproc_core.c | 263 ---
 drivers/remoteproc/remoteproc_internal.h |  10 +
 drivers/remoteproc/remoteproc_sysfs.c|  17 +-
 drivers/remoteproc/stm32_rproc.c | 168 +++
 include/linux/remoteproc.h   |  21 +-
 6 files changed, 362 insertions(+), 138 deletions(-)

-- 
2.25.1



[PATCH v6 01/16] remoteproc: Remove useless check in rproc_del()

2021-02-23 Thread Mathieu Poirier
Whether started at probe() time or thereafter from the command
line, a remote processor needs to be shut down before the final
cleanup phases can happen.  Otherwise the system may be left in
an unpredictable state where the remote processor is expecting
the remoteproc core to be providing services when in fact it
no longer exist.

Invariably calling rproc_shutdown() is fine since it will return
immediately if the remote processor has already been switched
off.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index ab150765d124..d2704501b653 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2347,10 +2347,8 @@ int rproc_del(struct rproc *rproc)
if (!rproc)
return -EINVAL;
 
-   /* if rproc is marked always-on, rproc_add() booted it */
/* TODO: make sure this works with rproc->power > 1 */
-   if (rproc->auto_boot)
-   rproc_shutdown(rproc);
+   rproc_shutdown(rproc);
 
mutex_lock(>lock);
rproc->state = RPROC_DELETED;
-- 
2.25.1



Re: [PATCH] remoteproc: core: Remove casting to rproc_handle_resource_t

2021-02-23 Thread Mathieu Poirier
On Tue, 23 Feb 2021 at 09:49, Sami Tolvanen  wrote:
>
> On Tue, Feb 23, 2021 at 8:41 AM Mathieu Poirier
>  wrote:
> >
> > On Mon, 22 Feb 2021 at 15:48, Sami Tolvanen  wrote:
> > >
> > > Hi,
> > >
> > > On Sun, Feb 21, 2021 at 11:18 PM Jindong Yue  wrote:
> > > >
> > > > There are four different callback functions that are used for the
> > > > rproc_handle_resource_t callback that all have different second
> > > > parameter types.
> > > >
> > > > rproc_handle_vdev -> struct fw_rsc_vdev
> > > > rproc_handle_trace -> struct fw_rsc_trace
> > > > rproc_handle_devmem -> struct fw_rsc_devmem
> > > > rproc_handle_carveout -> struct fw_rsc_carveout
> > > >
> > > > These callbacks are cast to rproc_handle_resource_t so that there is no
> > > > error about incompatible pointer types. Unfortunately, this is a control
> > > > flow integrity violation, which verifies that the callback function's
> > > > types match the prototypes exactly before jumping.
> > >
> > > Thank you for sending the patch! It might be worth noting that Clang's
> > > Control-Flow Integrity checking is currently used only in Android
> > > kernels, so while the type mismatches are real and should be fixed,
> > > they don't result in runtime errors without this feature.
> > >
> > > > To fix this, change the second parameter of all functions to void * and
> > > > use a local variable with the correct type so that everything works
> > > > properly. With this, we can remove casting to rproc_handle_resource_t
> > > > for these functions.
> > > >
> > > > Signed-off-by: Jindong Yue 
> > > > Reviewed-by: Peng Fan 
> > >
> > > This looks correct to me. Please feel free to add:
> > >
> > > Reviewed-by: Sami Tolvanen 
> >
> > Where is the original patch?  I can't find it on the linux-remoteproc
> > and linux-kernel mailing lists.
>
> Looks like it was sent to linux-remoteproc, but I also don't see it in
> lore.kernel.org. Not sure what happened there. Jindong, perhaps it's
> worth resending and including linux-kernel too?

Something definitely happened because I can't find anything from
Jindong on the linux-remoteproc list...  A resend it indeed in order.

>
> Sami


Re: [PATCH] remoteproc: core: Remove casting to rproc_handle_resource_t

2021-02-23 Thread Mathieu Poirier
On Mon, 22 Feb 2021 at 15:48, Sami Tolvanen  wrote:
>
> Hi,
>
> On Sun, Feb 21, 2021 at 11:18 PM Jindong Yue  wrote:
> >
> > There are four different callback functions that are used for the
> > rproc_handle_resource_t callback that all have different second
> > parameter types.
> >
> > rproc_handle_vdev -> struct fw_rsc_vdev
> > rproc_handle_trace -> struct fw_rsc_trace
> > rproc_handle_devmem -> struct fw_rsc_devmem
> > rproc_handle_carveout -> struct fw_rsc_carveout
> >
> > These callbacks are cast to rproc_handle_resource_t so that there is no
> > error about incompatible pointer types. Unfortunately, this is a control
> > flow integrity violation, which verifies that the callback function's
> > types match the prototypes exactly before jumping.
>
> Thank you for sending the patch! It might be worth noting that Clang's
> Control-Flow Integrity checking is currently used only in Android
> kernels, so while the type mismatches are real and should be fixed,
> they don't result in runtime errors without this feature.
>
> > To fix this, change the second parameter of all functions to void * and
> > use a local variable with the correct type so that everything works
> > properly. With this, we can remove casting to rproc_handle_resource_t
> > for these functions.
> >
> > Signed-off-by: Jindong Yue 
> > Reviewed-by: Peng Fan 
>
> This looks correct to me. Please feel free to add:
>
> Reviewed-by: Sami Tolvanen 

Where is the original patch?  I can't find it on the linux-remoteproc
and linux-kernel mailing lists.

>
> Sami


Re: [PATCH v26 0/5] Add initial zynqmp R5 remoteproc driver

2021-02-23 Thread Mathieu Poirier
Good morning,

I have received your patchset but currently don't see having the time
to look at it before the middle of March.

Thanks,
Mathieu

On Tue, 23 Feb 2021 at 08:44, Ben Levinsky  wrote:
>
> R5 is included in Xilinx Zynq UltraScale MPSoC so by adding this
> remotproc driver, we can boot the R5 sub-system in two different
> configurations -
> * Split
> * Lockstep
>
> The Xilinx R5 Remoteproc Driver boots the R5's via calls to the Xilinx
> Platform Management Unit that handles the R5 configuration, memory access
> and R5 lifecycle management. The interface to this manager is done in this
> driver via zynqmp_pm_* function calls.
>
> v26:
> - add prepare and unprepare to handle Xilinx platform management's
>   request_node and release node using each core's list of srams
>   that is constructed in each core's zynqmp_r5_probe.
> - add new field sram to zynqmp_r5_rproc to store each core's srams
>   being used as described in device tree. This helps to reduce unneeded 
> looping
>   of the sram prop in device tree. As now only zynqmp_r5_probe has to parse
>   and validate each core's sram property. The ensuing prepare, unprepare
>   and parse_fw logic are now much simpler.
> - similarly add 'size' field to struct sram_addr_data to simplify
>   prepare, unprepare and parse_fw.
>
> Previous version:
> https://patchwork.kernel.org/project/linux-remoteproc/list/?series=412083
>
>
> Ben Levinsky (5):
>   firmware: xilinx: Add ZynqMP firmware ioctl enums for RPU
> configuration.
>   firmware: xilinx: Add shutdown/wakeup APIs
>   firmware: xilinx: Add RPU configuration APIs
>   dt-bindings: remoteproc: Add documentation for ZynqMP R5 rproc
> bindings
>   remoteproc: Add initial zynqmp R5 remoteproc driver
>
>  .../xilinx,zynqmp-r5-remoteproc.yaml  | 223 
>  drivers/firmware/xilinx/zynqmp.c  |  96 ++
>  drivers/remoteproc/Kconfig|   8 +
>  drivers/remoteproc/Makefile   |   1 +
>  drivers/remoteproc/zynqmp_r5_remoteproc.c | 954 ++
>  include/linux/firmware/xlnx-zynqmp.h  |  64 ++
>  6 files changed, 1356 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/remoteproc/xilinx,zynqmp-r5-remoteproc.yaml
>  create mode 100644 drivers/remoteproc/zynqmp_r5_remoteproc.c
>
> --
> 2.17.1
>


Re: [PATCH v4 03/10] coresight: config: Add configuration and feature generic functions

2021-02-22 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:29PM +, Mike Leach wrote:
> Adds a set of generic support functions that allow devices to set and save
> features values on the device, and enable and disable configurations.
> 
> Additional functions for other common operations including feature
> reset.
> 
> Signed-off-by: Mike Leach 
> ---
>  drivers/hwtracing/coresight/Makefile  |   2 +-
>  .../hwtracing/coresight/coresight-config.c| 245 ++
>  .../hwtracing/coresight/coresight-config.h|  14 +-
>  .../hwtracing/coresight/coresight-syscfg.c|   5 +-
>  4 files changed, 262 insertions(+), 4 deletions(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-config.c
> 
> diff --git a/drivers/hwtracing/coresight/Makefile 
> b/drivers/hwtracing/coresight/Makefile
> index 4ce854c434b1..daad9f103a78 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -4,7 +4,7 @@
>  #
>  obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
> - coresight-sysfs.o coresight-syscfg.o
> + coresight-sysfs.o coresight-syscfg.o coresight-config.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
> coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-config.c 
> b/drivers/hwtracing/coresight/coresight-config.c
> new file mode 100644
> index ..6cc4b213d9b6
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-config.c
> @@ -0,0 +1,245 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(C) 2020 Linaro Limited. All rights reserved.
> + * Author: Mike Leach 
> + */
> +
> +#include 
> +#include "coresight-config.h"
> +#include "coresight-priv.h"
> +
> +/*
> + * Write the value held in the register structure into the driver internal 
> memory
> + * location.
> + */
> +static void cscfg_set_reg(struct cscfg_reg_csdev *reg)
> +{
> + u32 *p_val32 = (u32 *)reg->drv_store;
> + u32 tmp32 = reg->value.val32;
> +
> + if (reg->value.type & CS_CFG_REG_TYPE_VAL_64BIT) {
> + *((u64 *)reg->drv_store) = reg->value.val64;
> + return;
> + }
> +
> + if (reg->value.type & CS_CFG_REG_TYPE_VAL_MASK) {
> + tmp32 = *p_val32;
> + tmp32 &= ~reg->value.mask32;
> + tmp32 |= reg->value.val32 & reg->value.mask32;
> + }
> + *p_val32 = tmp32;
> +}
> +
> +/*
> + * Read the driver value into the reg if this is marked as one we want to 
> save.
> + */
> +static void cscfg_save_reg(struct cscfg_reg_csdev *reg)
> +{
> + if (!(reg->value.type & CS_CFG_REG_TYPE_VAL_SAVE))
> + return;
> + if (reg->value.type & CS_CFG_REG_TYPE_VAL_64BIT)
> + reg->value.val64 = *(u64 *)(reg->drv_store);
> + else
> + reg->value.val32 = *(u32 *)(reg->drv_store);
> +}
> +
> +static void cscfg_init_reg_param(struct cscfg_parameter_csdev *param_csdev,
> +  struct cscfg_reg_csdev *reg_csdev)
> +{
> + param_csdev->reg = reg_csdev;

This is the link between registers and parameters... Very important and very
easy to miss.  I'm not use how the situation can be improved other than adding a
comment to highlight the dependency. 

> + param_csdev->val64 = reg_csdev->value.type & CS_CFG_REG_TYPE_VAL_64BIT;
> +
> + if (param_csdev->val64)
> + param_csdev->reg->value.val64 = param_csdev->current_value;
> + else
> + param_csdev->reg->value.val32 = (u32)param_csdev->current_value;
> +}
> +
> +/* set values into the driver locations referenced in cscfg_reg_csdev */
> +static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat)
> +{
> + int i;
> +
> + spin_lock(feat->csdev_spinlock);
> + for (i = 0; i < feat->nr_regs; i++)
> + cscfg_set_reg(>regs[i]);
> + spin_unlock(feat->csdev_spinlock);
> + dev_dbg(>csdev->dev, "Feature %s: %s", feat->desc->name, "set on 
> enable");
> + return 0;
> +}
> +
> +/* copy back values from the driver locations referenced in cscfg_reg_csdev 
> */
> +static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat)

static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat_csdev)

To be modified throughout the patchset. 


> +{
> + int i;
> +
> + spin_lock(feat->csdev_spinlock);
> + for (i = 0; i < feat->nr_regs; i++)
> + cscfg_save_reg(>regs[i]);
> + spin_unlock(feat->csdev_spinlock);
> + dev_dbg(>csdev->dev, "Feature %s: %s", feat->desc->name, "save on 
> disable");
> +}
> +
> +/* default reset - restore default values */
> +void cscfg_reset_feat(struct cscfg_feature_csdev *feat)
> +{
> + struct cscfg_parameter_csdev *param_csdev;
> + struct cscfg_regval_desc *reg_desc;
> + struct cscfg_reg_csdev *reg_csdev;
> + int i;
> +
> + /*
> +  * set the default values for all 

Re: [PATCH v4 02/10] coresight: syscfg: Add registration and feature loading for cs devices

2021-02-22 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:28PM +, Mike Leach wrote:
> API for individual devices to register with the syscfg management
> system is added.
> 
> Devices register with matching information, and any features or
> configurations that match will be loaded into the device.
> 
> The feature and configuration loading is extended so that on load these
> are loaded into any currently registered devices. This allows
> configuration loading after devices have been registered.
> 
> Signed-off-by: Mike Leach 
> ---
>  .../hwtracing/coresight/coresight-config.h|  98 +
>  .../hwtracing/coresight/coresight-syscfg.c| 348 ++
>  .../hwtracing/coresight/coresight-syscfg.h|  20 +
>  include/linux/coresight.h |   5 +
>  4 files changed, 471 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-config.h 
> b/drivers/hwtracing/coresight/coresight-config.h
> index 3fedf8ab3cee..75ecdecf7013 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -164,4 +164,102 @@ struct cscfg_config_desc {
>   const u64 *presets; /* nr_presets * nr_total_params */
>  };
>  
> +/**
> + * config register instance - part of a loaded feature.
> + *maps register values to csdev driver structures
> + *
> + * @value:   value to use when setting feature on device / store for
> + *   readback of volatile values.
> + * @drv_store:   pointer to internal driver element used to set the value
> + *   in hardware.
> + */
> +struct cscfg_reg_csdev {
> + struct cscfg_regval_desc value;

struct cscfg_regval_desc reg_desc;

> + void *drv_store;
> +};
> +
> +/**
> + * config parameter instance - part of a loaded feature.
> + *
> + * @feat:parent feature
> + * @reg: register value updated by this parameter.
> + * @current_value:   current value of parameter - may be set by user via
> + *   sysfs, or modified during device operation.
> + * @val64:   true if 64 bit value
> + */
> +struct cscfg_parameter_csdev {
> + struct cscfg_feature_csdev *feat;

struct cscfg_feature_csdev *feat_csdev;

> + struct cscfg_reg_csdev *reg;

struct cscfg_reg_csdev *reg_csdev;

> + u64 current_value;
> + bool val64;
> +};
> +
> +/**
> + * Feature instance loaded into a CoreSight device.
> + *
> + * When a feature is loaded into a specific device, then this structure holds
> + * the connections between the register / parameter values used and the
> + * internal data structures that are written when the feature is enabled.
> + *
> + * Since applying a feature modifies internal data structures in the device,
> + * then we have a reference to the device spinlock to protect access to these
> + * structures (@csdev_spinlock).
> + *
> + * @desc:pointer to the static descriptor for this feature.
> + * @csdev:   parent CoreSight device instance.
> + * @node:list entry into feature list for this device.
> + * @csdev_spinlock:  device spinlock from csdev instance..
> + * @nr_params:   number of parameters.
> + * @params:  current parameter values on this device
> + * @nr_regs: number of registers to be programmed.
> + * @regs:Programming details for the registers
> + */
> +struct cscfg_feature_csdev {
> + const struct cscfg_feature_desc *desc;

const struct cscfg_feature_desc *feat_desc;

> + struct coresight_device *csdev;
> + struct list_head node;
> + spinlock_t *csdev_spinlock;
> + int nr_params;
> + struct cscfg_parameter_csdev *params;

struct cscfg_parameter_csdev *params_csdev;

> + int nr_regs;
> + struct cscfg_reg_csdev *regs;

struct cscfg_reg_csdev *regs_csdev;
> +};
> +
> +/**
> + * Configuration instance when loaded into a CoreSight device.
> + *
> + * The instance contains references to loaded features on this device that 
> are
> + * used by the configuration.
> + *
> + * @desc:reference to the descriptor for this configuration
> + * @csdev:   parent coresight device for this configuration instance.
> + * @node:list entry within the coresight device
> + * @nr_feat: Number of features on this device that are used in the
> + *configuration.
> + * @feats:   reference to the device features to enable.
> + * @enabled: true if configuration is enabled on this device.
> + */
> +struct cscfg_config_csdev {
> + const struct cscfg_config_desc *desc;

const struct cscfg_config_desc *cfg_desc;

> + struct coresight_device *csdev;
> + struct list_head node;
> + int nr_feat;
> + struct cscfg_feature_csdev **feats;

struct cscfg_feature_csdev **feat_csdev;

> + bool enabled;
> +};
> +
> +/**
> + * Coresight device operations.
> + *
> + * Registered coresight devices provide these operations to manage feature
> + * 

Re: [PATCH v4 01/10] coresight: syscfg: Initial coresight system configuration

2021-02-22 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:27PM +, Mike Leach wrote:
> Creates an system management API to allow complex configurations and
> features to be programmed into a CoreSight infrastructure.
> 
> A feature is defined as a programming set for a device or class of
> devices.
> 
> A configuration is a set of features across the system that are enabled
> for a trace session.
> 
> The API will manage system wide configuration, and allow complex
> programmed features to be added to individual device instances, and
> provide for system wide configuration selection on trace capture
> operations.
> 
> This patch creates the initial data object and the initial API for
> loading configurations and features.
> 
> Signed-off-by: Mike Leach 
> ---
>  drivers/hwtracing/coresight/Makefile  |   2 +-
>  .../hwtracing/coresight/coresight-config.h| 167 +++
>  drivers/hwtracing/coresight/coresight-core.c  |  12 +-
>  .../hwtracing/coresight/coresight-etm-perf.c  |   2 +-
>  .../hwtracing/coresight/coresight-etm-perf.h  |   2 +-
>  .../hwtracing/coresight/coresight-syscfg.c| 197 ++
>  .../hwtracing/coresight/coresight-syscfg.h|  54 +
>  7 files changed, 432 insertions(+), 4 deletions(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-config.h
>  create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.h
> 
> diff --git a/drivers/hwtracing/coresight/Makefile 
> b/drivers/hwtracing/coresight/Makefile
> index f20e357758d1..4ce854c434b1 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -4,7 +4,7 @@
>  #
>  obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
> - coresight-sysfs.o
> + coresight-sysfs.o coresight-syscfg.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
> coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-config.h 
> b/drivers/hwtracing/coresight/coresight-config.h
> new file mode 100644
> index ..3fedf8ab3cee
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -0,0 +1,167 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach 
> + */
> +
> +#ifndef _CORESIGHT_CORESIGHT_CONFIG_H
> +#define _CORESIGHT_CORESIGHT_CONFIG_H
> +
> +#include 
> +#include 
> +
> +/* CoreSight Configuration Management - component and system wide 
> configuration */
> +
> +/*
> + * Register type flags for register value descriptor:
> + * describe how the value is interpreted, and handled.
> + */
> +#define CS_CFG_REG_TYPE_STD  0x80/* reg is standard reg */
> +#define CS_CFG_REG_TYPE_RESOURCE 0x40/* reg is a resource */
> +#define CS_CFG_REG_TYPE_VAL_PARAM0x08/* reg value uses param */
> +#define CS_CFG_REG_TYPE_VAL_MASK 0x04/* reg value bit masked */
> +#define CS_CFG_REG_TYPE_VAL_64BIT0x02/* reg value 64 bit */
> +#define CS_CFG_REG_TYPE_VAL_SAVE 0x01/* reg value save on disable */
> +
> +/*
> + * flags defining what device class a feature will match to when processing a
> + * system configuration - used by config data and devices.
> + */
> +#define  CS_CFG_MATCH_CLASS_SRC_ALL  0x0001  /* match any source */
> +#define CS_CFG_MATCH_CLASS_SRC_ETM4  0x0002  /* match any ETMv4 device */
> +
> +/* flags defining device instance matching - used in config match desc data. 
> */
> +#define CS_CFG_MATCH_INST_ANY0x8000 /* any instance of a 
> class */
> +
> +/*
> + * Limit number of presets in a configuration
> + * This is related to the number of bits (4) we use to select the preset on
> + * the perf command line. Preset 0 is always none selected.
> + * See PMU_FORMAT_ATTR(preset, "config:0-3") in coresight-etm-perf.c
> + */
> +#define CS_CFG_CONFIG_PRESET_MAX 15
> +
> +/**
> + * Parameter descriptor for a device feature.
> + *
> + * @name:  Name of parameter.
> + * @value: Initial or default value.
> + */
> +struct cscfg_parameter_desc {
> + const char *name;
> + u64 value;
> +};
> +
> +/**
> + * Representation of register value.
> + *
> + * Supports full 64 bit register value, or 32 bit value with optional mask
> + * value.
> + *
> + * @type:define register usage and interpretation.
> + * @offset:  the address offset for register in the hardware device (per 
> device specification).
> + * @hw_info: optional hardware device type specific information. (ETM / CTI 
> specific etc)
> + * @val64:   64 bit value.
> + * @val32:   32 bit value.
> + * @mask32:  32 bit mask when using 32 bit value to access device register.
> + */
> +struct cscfg_regval_desc {
> + struct {
> + u32 type:8;
> + u32 offset:12;
> + u32 

Re: [PATCH v4 02/10] coresight: syscfg: Add registration and feature loading for cs devices

2021-02-22 Thread Mathieu Poirier
Hi Mike,

On Thu, Jan 28, 2021 at 05:09:28PM +, Mike Leach wrote:
> API for individual devices to register with the syscfg management
> system is added.
> 
> Devices register with matching information, and any features or
> configurations that match will be loaded into the device.
> 
> The feature and configuration loading is extended so that on load these
> are loaded into any currently registered devices. This allows
> configuration loading after devices have been registered.
> 
> Signed-off-by: Mike Leach 
> ---
>  .../hwtracing/coresight/coresight-config.h|  98 +
>  .../hwtracing/coresight/coresight-syscfg.c| 348 ++
>  .../hwtracing/coresight/coresight-syscfg.h|  20 +
>  include/linux/coresight.h |   5 +
>  4 files changed, 471 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-config.h 
> b/drivers/hwtracing/coresight/coresight-config.h
> index 3fedf8ab3cee..75ecdecf7013 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -164,4 +164,102 @@ struct cscfg_config_desc {
>   const u64 *presets; /* nr_presets * nr_total_params */
>  };
>  
> +/**
> + * config register instance - part of a loaded feature.
> + *maps register values to csdev driver structures
> + *
> + * @value:   value to use when setting feature on device / store for
> + *   readback of volatile values.
> + * @drv_store:   pointer to internal driver element used to set the value
> + *   in hardware.
> + */
> +struct cscfg_reg_csdev {

Please rename this cscfg_regval_csdev to highlight the 1:1 mapping with
cscfg_regval_desc.  Or rename cscfg_regval_desc to cscfg_reg_desc.  I have no
opinion on which one it should be, as long as they are consistent.  Doing so
really helps getting over the naming convention so that we can focus on the core
of the feature.

> + struct cscfg_regval_desc value;
> + void *drv_store;
> +};
> +
> +/**
> + * config parameter instance - part of a loaded feature.
> + *
> + * @feat:parent feature
> + * @reg: register value updated by this parameter.
> + * @current_value:   current value of parameter - may be set by user via
> + *   sysfs, or modified during device operation.
> + * @val64:   true if 64 bit value
> + */
> +struct cscfg_parameter_csdev {
> + struct cscfg_feature_csdev *feat;
> + struct cscfg_reg_csdev *reg;
> + u64 current_value;
> + bool val64;
> +};
> +
> +/**
> + * Feature instance loaded into a CoreSight device.
> + *
> + * When a feature is loaded into a specific device, then this structure holds
> + * the connections between the register / parameter values used and the
> + * internal data structures that are written when the feature is enabled.
> + *
> + * Since applying a feature modifies internal data structures in the device,
> + * then we have a reference to the device spinlock to protect access to these
> + * structures (@csdev_spinlock).
> + *
> + * @desc:pointer to the static descriptor for this feature.
> + * @csdev:   parent CoreSight device instance.
> + * @node:list entry into feature list for this device.
> + * @csdev_spinlock:  device spinlock from csdev instance..
> + * @nr_params:   number of parameters.
> + * @params:  current parameter values on this device
> + * @nr_regs: number of registers to be programmed.
> + * @regs:Programming details for the registers
> + */
> +struct cscfg_feature_csdev {
> + const struct cscfg_feature_desc *desc;
> + struct coresight_device *csdev;
> + struct list_head node;
> + spinlock_t *csdev_spinlock;
> + int nr_params;
> + struct cscfg_parameter_csdev *params;
> + int nr_regs;
> + struct cscfg_reg_csdev *regs;
> +};
> +
> +/**
> + * Configuration instance when loaded into a CoreSight device.
> + *
> + * The instance contains references to loaded features on this device that 
> are
> + * used by the configuration.
> + *
> + * @desc:reference to the descriptor for this configuration
> + * @csdev:   parent coresight device for this configuration instance.
> + * @node:list entry within the coresight device
> + * @nr_feat: Number of features on this device that are used in the
> + *configuration.
> + * @feats:   reference to the device features to enable.
> + * @enabled: true if configuration is enabled on this device.
> + */
> +struct cscfg_config_csdev {
> + const struct cscfg_config_desc *desc;
> + struct coresight_device *csdev;
> + struct list_head node;
> + int nr_feat;
> + struct cscfg_feature_csdev **feats;
> + bool enabled;
> +};
> +
> +/**
> + * Coresight device operations.
> + *
> + * Registered coresight devices provide these operations to manage feature
> + * instances compatible with the device hardware and drivers
> + *
> + * 

Re: [PATCH v4 02/10] coresight: syscfg: Add registration and feature loading for cs devices

2021-02-19 Thread Mathieu Poirier
[...]

> +/**
> + * List entry for Coresight devices that are registered as supporting complex
> + * config operations.
> + *
> + * @csdev:   The registered device.
> + * @match_info: The matching type information.
> + * @ops: Operations supported by the registered device.
> + * @item:list entry.
> + */
> +struct cscfg_csdev_register {
> + struct coresight_device *csdev;
> + struct cscfg_match_desc match_info;
> + struct cscfg_csdev_feat_ops ops;
> + struct list_head item;
> +};

I would call this structure cscfg_registered_csdev and move it to
coresight-config.h.  That way it is consistent with cscfg_config_csdev and
cscfg_feature_csdev and located all in the same file.

I may have to come back to this patch but for now it holds together.

More comments to come on Monday.

Thanks,
Mathieu

> +
>  /* internal core operations for cscfg */
>  int __init cscfg_init(void);
>  void __exit cscfg_exit(void);
> @@ -33,6 +49,10 @@ void __exit cscfg_exit(void);
>  /* syscfg manager external API */
>  int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
>  struct cscfg_feature_desc **feat_descs);
> +int cscfg_register_csdev(struct coresight_device *csdev,
> +  struct cscfg_match_desc *info,
> +  struct cscfg_csdev_feat_ops *ops);
> +void cscfg_unregister_csdev(struct coresight_device *csdev);
>  
>  /**
>   * System configuration manager device.
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 976ec2697610..d0126ed326a6 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -219,6 +219,8 @@ struct coresight_sysfs_link {
>   * @nr_links:   number of sysfs links created to other components from this
>   *   device. These will appear in the "connections" group.
>   * @has_conns_grp: Have added a "connections" group for sysfs links.
> + * @feature_csdev_list: List of complex feature programming added to the 
> device.
> + * @config_csdev_list:  List of system configurations added to the device.
>   */
>  struct coresight_device {
>   struct coresight_platform_data *pdata;
> @@ -240,6 +242,9 @@ struct coresight_device {
>   int nr_links;
>   bool has_conns_grp;
>   bool ect_enabled; /* true only if associated ect device is enabled */
> + /* system configuration and feature lists */
> + struct list_head feature_csdev_list;
> + struct list_head config_csdev_list;
>  };
>  
>  /*
> -- 
> 2.17.1
> 


Re: [PATCH v4 01/10] coresight: syscfg: Initial coresight system configuration

2021-02-18 Thread Mathieu Poirier
On Thu, Jan 28, 2021 at 05:09:27PM +, Mike Leach wrote:
> Creates an system management API to allow complex configurations and
> features to be programmed into a CoreSight infrastructure.
> 
> A feature is defined as a programming set for a device or class of
> devices.
> 
> A configuration is a set of features across the system that are enabled
> for a trace session.
> 
> The API will manage system wide configuration, and allow complex
> programmed features to be added to individual device instances, and
> provide for system wide configuration selection on trace capture
> operations.
> 
> This patch creates the initial data object and the initial API for
> loading configurations and features.
> 
> Signed-off-by: Mike Leach 
> ---
>  drivers/hwtracing/coresight/Makefile  |   2 +-
>  .../hwtracing/coresight/coresight-config.h| 167 +++
>  drivers/hwtracing/coresight/coresight-core.c  |  12 +-
>  .../hwtracing/coresight/coresight-etm-perf.c  |   2 +-
>  .../hwtracing/coresight/coresight-etm-perf.h  |   2 +-
>  .../hwtracing/coresight/coresight-syscfg.c| 197 ++
>  .../hwtracing/coresight/coresight-syscfg.h|  54 +
>  7 files changed, 432 insertions(+), 4 deletions(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-config.h
>  create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.h
> 
> diff --git a/drivers/hwtracing/coresight/Makefile 
> b/drivers/hwtracing/coresight/Makefile
> index f20e357758d1..4ce854c434b1 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -4,7 +4,7 @@
>  #
>  obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
> - coresight-sysfs.o
> + coresight-sysfs.o coresight-syscfg.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
> coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-config.h 
> b/drivers/hwtracing/coresight/coresight-config.h
> new file mode 100644
> index ..3fedf8ab3cee
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -0,0 +1,167 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach 
> + */
> +
> +#ifndef _CORESIGHT_CORESIGHT_CONFIG_H
> +#define _CORESIGHT_CORESIGHT_CONFIG_H
> +
> +#include 
> +#include 
> +
> +/* CoreSight Configuration Management - component and system wide 
> configuration */
> +
> +/*
> + * Register type flags for register value descriptor:
> + * describe how the value is interpreted, and handled.
> + */
> +#define CS_CFG_REG_TYPE_STD  0x80/* reg is standard reg */
> +#define CS_CFG_REG_TYPE_RESOURCE 0x40/* reg is a resource */
> +#define CS_CFG_REG_TYPE_VAL_PARAM0x08/* reg value uses param */
> +#define CS_CFG_REG_TYPE_VAL_MASK 0x04/* reg value bit masked */
> +#define CS_CFG_REG_TYPE_VAL_64BIT0x02/* reg value 64 bit */
> +#define CS_CFG_REG_TYPE_VAL_SAVE 0x01/* reg value save on disable */
> +
> +/*
> + * flags defining what device class a feature will match to when processing a
> + * system configuration - used by config data and devices.
> + */
> +#define  CS_CFG_MATCH_CLASS_SRC_ALL  0x0001  /* match any source */
> +#define CS_CFG_MATCH_CLASS_SRC_ETM4  0x0002  /* match any ETMv4 device */
> +
> +/* flags defining device instance matching - used in config match desc data. 
> */
> +#define CS_CFG_MATCH_INST_ANY0x8000 /* any instance of a 
> class */
> +
> +/*
> + * Limit number of presets in a configuration
> + * This is related to the number of bits (4) we use to select the preset on
> + * the perf command line. Preset 0 is always none selected.
> + * See PMU_FORMAT_ATTR(preset, "config:0-3") in coresight-etm-perf.c
> + */
> +#define CS_CFG_CONFIG_PRESET_MAX 15
> +
> +/**
> + * Parameter descriptor for a device feature.
> + *
> + * @name:  Name of parameter.
> + * @value: Initial or default value.
> + */
> +struct cscfg_parameter_desc {
> + const char *name;
> + u64 value;
> +};
> +
> +/**
> + * Representation of register value.
> + *
> + * Supports full 64 bit register value, or 32 bit value with optional mask
> + * value.
> + *
> + * @type:define register usage and interpretation.
> + * @offset:  the address offset for register in the hardware device (per 
> device specification).
> + * @hw_info: optional hardware device type specific information. (ETM / CTI 
> specific etc)
> + * @val64:   64 bit value.
> + * @val32:   32 bit value.
> + * @mask32:  32 bit mask when using 32 bit value to access device register.
> + */
> +struct cscfg_regval_desc {
> + struct {
> + u32 type:8;
> + u32 offset:12;
> + u32 

Re: [PATCH v4 10/10] coresight: docs: Add documentation for CoreSight config

2021-02-18 Thread Mathieu Poirier
Good day,

I have started to review this set and as usual comments will come over several
days.

On Thu, Jan 28, 2021 at 05:09:36PM +, Mike Leach wrote:
> Adds documentation for the CoreSight System configuration manager.
> 
> Signed-off-by: Mike Leach 
> ---
>  .../trace/coresight/coresight-config.rst  | 244 ++
>  Documentation/trace/coresight/coresight.rst   |  16 ++
>  2 files changed, 260 insertions(+)
>  create mode 100644 Documentation/trace/coresight/coresight-config.rst

At this time the content of the patch and how things have been laid out in
configfs look good to me.  Things can still change at some point in the future
but for now:

Reviewed-by: Mathieu Poirier 

> 
> diff --git a/Documentation/trace/coresight/coresight-config.rst 
> b/Documentation/trace/coresight/coresight-config.rst
> new file mode 100644
> index ..3a4aa7bfa131
> --- /dev/null
> +++ b/Documentation/trace/coresight/coresight-config.rst
> @@ -0,0 +1,244 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==
> +CoreSight System Configuration Manager
> +==
> +
> +:Author:   Mike Leach 
> +:Date: October 2020
> +
> +Introduction
> +
> +
> +The CoreSight System Configuration manager is an API that allows the
> +programming of the CoreSight system with pre-defined configurations that
> +can then be easily enabled from sysfs or perf.
> +
> +Many CoreSight components can be programmed in complex ways - especially 
> ETMs.
> +In addition, components can interact across the CoreSight system, often via
> +the cross trigger components such as CTI and CTM. These system settings can
> +be defined and enabled as named configurations.
> +
> +
> +Basic Concepts
> +==
> +
> +This section introduces the basic concepts of a CoreSight system 
> configuration.
> +
> +
> +Features
> +
> +
> +A feature is a named set of programming for a CoreSight device. The 
> programming
> +is device dependent, and can be defined in terms of absolute register values,
> +resource usage and parameter values.
> +
> +The feature is defined using a descriptor. This descriptor is used to load 
> onto
> +a matching device, either when the feature is loaded into the system, or 
> when the
> +CoreSight device is registered with the configuration manager.
> +
> +The load process involves interpreting the descriptor into a set of register
> +accesses in the driver - the resource usage and parameter descriptions
> +translated into appropriate register accesses. This interpretation makes it 
> easy
> +and efficient for the feature to be programmed onto the device when required.
> +
> +The feature will not be active on the device until the feature is enabled, 
> and
> +the device itself is enabled. When the device is enabled then enabled 
> features
> +will be programmed into the device hardware.
> +
> +A feature is enabled as part of a configuration being enabled on the system.
> +
> +
> +Parameter Value
> +~~~
> +
> +A parameter value is a named value that may be set by the user prior to the
> +feature being enabled that can adjust the behaviour of the operation 
> programmed
> +by the feature.
> +
> +For example, this could be a count value in a programmed operation that 
> repeats
> +at a given rate. When the feature is enabled then the current value of the
> +parameter is used in programming the device.
> +
> +The feature descriptor defines a default value for a parameter, which is used
> +if the user does not supply a new value.
> +
> +Users can update parameter values using the configfs API for the CoreSight
> +system - which is described below.
> +
> +The current value of the parameter is loaded into the device when the feature
> +is enabled on that device.
> +
> +
> +Configurations
> +--
> +
> +A configuration defines a set of features that are to be used in a trace
> +session where the configuration is selected. For any trace session only one
> +configuration may be selected.
> +
> +The features defined may be on any type of device that is registered
> +to support system configuration. A configuration may select features to be
> +enabled on a class of devices - i.e. any ETMv4, or specific devices, e.g. a
> +specific CTI on the system.
> +
> +As with the feature, a descriptor is used to define the configuration.
> +This will define the features that must be enabled as part of the 
> configuration
> +as well as any preset values that can be used to override default parameter
> +values.
> +
> +
> +Preset Values
> +~
> +
&g

Re: [PATCH v5] perf: cs-etm: update ETM metadata format

2021-02-18 Thread Mathieu Poirier
On Tue, Feb 02, 2021 at 09:40:40PM +, Mike Leach wrote:
> The current fixed metadata version format (version 0), means that adding
> metadata parameter items renders files from a previous version of perf
> unreadable. Per CPU parameters appear in a fixed order, but there is no
> field to indicate the number of ETM parameters per CPU.
> 
> This patch updates the per CPU parameter blocks to include a NR_PARAMs
> value which indicates the number of parameters in the block.
> 
> The header version is incremented to 1. Fixed ordering is retained,
> new ETM parameters are added to the end of the list.
> 
> The reader code is updated to be able to read current version 0 files,
> For version 1, the reader will read the number of parameters in the
> per CPU block. This allows the reader to process older or newer files
> that may have different numbers of parameters than in use at the
> time perf was built.
> 
> Signed-off-by: Mike Leach 
> Reviewed-by: Leo Yan 
> Tested-by: Leo Yan 
>

Reviewed-by: Mathieu Poirier 

Please rebase this patch on 5.12-rc1 when it comes out and resend to Arnaldo.

Thanks,
Mathieu
 
> ---
> 
> Changes since v4
> 1. Syntax fixes suggested by Mathieu.
> 
> Changes since v3
> 1. Fixed index bug (Leo)
> 
> Changes since v2
> 1. Add error path print to improve --dump logging
> 2. Replace some hardcoded values with enum consts (Mathieu).
> 
> Changes since v1 (from Review by Leo):
> 1. Split printing routine into sub functions per version
> 2. Renamed NR_PARAMs to NR_TRC_PARAMs to emphasise use as count of trace
> related parameters, not total block parameter.
> 3. Misc other fixes.
> ---
>  tools/perf/arch/arm/util/cs-etm.c |   7 +-
>  tools/perf/util/cs-etm.c  | 235 --
>  tools/perf/util/cs-etm.h  |  30 +++-
>  3 files changed, 223 insertions(+), 49 deletions(-)
> 
> diff --git a/tools/perf/arch/arm/util/cs-etm.c 
> b/tools/perf/arch/arm/util/cs-etm.c
> index bd446aba64f7..b0470f2a955a 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -572,7 +572,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
>   struct auxtrace_record *itr,
>   struct perf_record_auxtrace_info *info)
>  {
> - u32 increment;
> + u32 increment, nr_trc_params;
>   u64 magic;
>   struct cs_etm_recording *ptr =
>   container_of(itr, struct cs_etm_recording, itr);
> @@ -607,6 +607,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
>  
>   /* How much space was used */
>   increment = CS_ETMV4_PRIV_MAX;
> + nr_trc_params = CS_ETMV4_PRIV_MAX - CS_ETMV4_TRCCONFIGR;
>   } else {
>   magic = __perf_cs_etmv3_magic;
>   /* Get configuration register */
> @@ -624,11 +625,13 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
>  
>   /* How much space was used */
>   increment = CS_ETM_PRIV_MAX;
> + nr_trc_params = CS_ETM_PRIV_MAX - CS_ETM_ETMCR;
>   }
>  
>   /* Build generic header portion */
>   info->priv[*offset + CS_ETM_MAGIC] = magic;
>   info->priv[*offset + CS_ETM_CPU] = cpu;
> + info->priv[*offset + CS_ETM_NR_TRC_PARAMS] = nr_trc_params;
>   /* Where the next CPU entry should start from */
>   *offset += increment;
>  }
> @@ -674,7 +677,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
>  
>   /* First fill out the session header */
>   info->type = PERF_AUXTRACE_CS_ETM;
> - info->priv[CS_HEADER_VERSION_0] = 0;
> + info->priv[CS_HEADER_VERSION] = CS_HEADER_CURRENT_VERSION;
>   info->priv[CS_PMU_TYPE_CPUS] = type << 32;
>   info->priv[CS_PMU_TYPE_CPUS] |= nr_cpu;
>   info->priv[CS_ETM_SNAPSHOT] = ptr->snapshot_mode;
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index a2a369e2fbb6..ee32d023e9bd 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -2435,7 +2435,7 @@ static bool cs_etm__is_timeless_decoding(struct 
> cs_etm_auxtrace *etm)
>  }
>  
>  static const char * const cs_etm_global_header_fmts[] = {
> - [CS_HEADER_VERSION_0]   = " Header version %llx\n",
> + [CS_HEADER_VERSION] = " Header version %llx\n",
>   [CS_PMU_TYPE_CPUS]  = " PMU type/num cpus  %llx\n",
>   [CS_ETM_SNAPSHOT]   = " Snapshot   %llx\n",
>  };
> @@ -2443,6 +2443,7 @@ static const char * const cs_etm_global_header_fmts[] = 
> {
>  st

Re: [PATCH v25 5/5] remoteproc: Add initial zynqmp R5 remoteproc driver

2021-02-17 Thread Mathieu Poirier
On Wed, Feb 17, 2021 at 09:34:13PM +, Ben Levinsky wrote:
> 1 more for the pnode_id comment
>

[...]
 
> > > > > +static int parse_tcm_banks(struct rproc *rproc)
> > > > > +{
> > > > > + int i, num_banks;
> > > > > + struct zynqmp_r5_rproc *z_rproc = rproc->priv;
> > > > > + struct device *dev = >dev;
> > > > > + struct device_node *r5_node = z_rproc->dev->of_node;
> > > > > +
> > > > > + /* go through TCM banks for r5 node */
> > > > > + num_banks = of_count_phandle_with_args(r5_node,
> > > > BANK_LIST_PROP, NULL);
> > > > > + if (num_banks <= 0) {
> > > > > + dev_err(dev, "need to specify TCM banks\n");
> > > > > + return -EINVAL;
> > > > > + }
> > > > > + for (i = 0; i < num_banks; i++) {
> > > > > + struct resource rsc;
> > > > > + resource_size_t size;
> > > > > + struct device_node *dt_node;
> > > > > + struct rproc_mem_entry *mem;
> > > > > + int ret;
> > > > > + u32 pnode_id; /* zynqmp_pm* fn's expect u32 */
> > > > > +
> > > > > + dt_node = of_parse_phandle(r5_node, BANK_LIST_PROP, i);
> > > > > + if (!dt_node)
> > > > > + return -EINVAL;
> > > > > +
> > > > > + ret = of_address_to_resource(dt_node, 0, );
> > > > > + if (ret < 0) {
> > > > > + of_node_put(dt_node);
> > > > > + return ret;
> > > > > + }
> > > > > + of_node_put(dt_node);
> > > > > +
> > > > > + ret = zynqmp_r5_pm_request_sram(rsc.start);
> > > > > + if (ret < 0)
> > > > > + return ret;
> > > > > +
> > > > > + /* add carveout */
> > > > > + size = resource_size();
> > > > > + mem = rproc_mem_entry_init(dev, NULL, rsc.start,
> > > > > +(size_t)size, rsc.start,
> > > > > +tcm_mem_alloc,
> > > > > +tcm_mem_release,
> > > > > +rsc.name);
> > > > > + if (!mem) {
> > > > > + ret = zynqmp_pm_release_node(pnode_id);
> > > >
> > > > Where is @pnode_id initialised?
> > >
> > > Good catch. Previously this was value set in an earlier iteration. I will 
> > > fix this
> > > as follows:
> > > - release the R5 cluster by instead passing z_rproc->pnode_id
> > > - release the TCM bank via call to release_sram
> > >
> > > This will also remove the variable pnode_id.
> > >
> 
> 
> typo release_sram should be release_node()
> 
> also instead another, cleaner way might be as follows:
> change zynqmp_r5_request_sram so that it takes 1 more arg to return by 
> reference the TCM bank's Xilinx platform management ID and then set the TCM 
> bank's ID with that information.
> 

That sounds more reasonable.

> Thanks
> Ben
> 
> > > >
> > > > > + if (ret)
> > > > > + dev_warn(dev,
> > > > > +  "fail to release node: %x ret: 
> > > > > %x\n",
> > > > > +  pnode_id, ret);
> > > > > + return -ENOMEM;
> > > > > + }
> > > > > +
> > > > > + mem->priv = (void *)(u64)pnode_id;
> > > >
> > > >
> > > > And here too - how does this work when you test things out on your side?
> > > >
> > > > Please note that I will need a reply to these questions before I review
> > > another
> > > > set.
> > > >
> > > Here I will update as follows:
> > > - set mem->priv to value from zynqmp_banks lookup table that contains
> > > power node IDs
> > >
> > >
> > > > > + rproc_add_carveout(rproc, mem);
> > > > > + }
> > > > > +
> > > > > + return 0;
> > > > > +}
> > > > > +
> > > > > +/*
> > > > > + * zynqmp_r5_parse_fw()
> > > > > + * @rproc: single R5 core's corresponding rproc instance
> > > > > + * @fw: ptr to firmware to be loaded onto r5 core
> > > > > + *
> > > > > + * When loading firmware, ensure the necessary carveouts are in
> > > > remoteproc
> > > > > + *
> > > > > + * return 0 on success, otherwise non-zero value on failure
> > > > > + */
> > > > > +static int zynqmp_r5_parse_fw(struct rproc *rproc, const struct
> > firmware
> > > > *fw)
> > > > > +{
> > > > > + int ret;
> > > > > +
> > > > > + ret = parse_tcm_banks(rproc);
> > > > > + if (ret)
> > > > > + return ret;
> > > > > +
> > > > > + ret = parse_mem_regions(rproc);
> > > > > + if (ret)
> > > > > + return ret;
> > > > > +
> > > > > + ret = rproc_elf_load_rsc_table(rproc, fw);
> > > > > + if (ret == -EINVAL) {
> > > > > + /*
> > > > > +  * resource table only required for IPC.
> > > > > +  * if not present, this is not necessarily an error;
> > > > > +  * for example, loading r5 hello world application
> > > > > +  

Re: [PATCH v25 5/5] remoteproc: Add initial zynqmp R5 remoteproc driver

2021-02-17 Thread Mathieu Poirier
On Wed, Feb 17, 2021 at 07:11:37PM +, Ben Levinsky wrote:
> Hi Mathieu,
> 
> I worked on this further and had 1 more comment on the prepare/unprepare for 
> TCM banks below
>

[...]
 
> > > > + */
> > > > +static int tcm_mem_release(struct rproc *rproc, struct rproc_mem_entry
> > > *mem)
> > > > +{
> > > > +   u32 pnode_id = (u64)mem->priv;
> > > > +
> > > > +   iounmap(mem->va);
> > > > +   return zynqmp_pm_release_node(pnode_id);
> > >
> > > Is the opposite of that call zynqmp_pm_request_node()?  If so doing the
> > > power up
> > > and down of the TCM banks at driver probe() and remove() is highly
> > > inefficient.
> > > Consider using rproc_ops::prepare() and rproc_ops::unprepare().
> > >
> If I understand your comment correctly this is about handling the 
> request_node() and release_node() calls. While its true that these two 
> functions can be moved to prepare and unprepared I think these are still 
> occurring not at probe nor remove.
>

Your assesment is corret and I am in the wrong.  Unfortunately that's what
happens when reviews are spread out over several days. 
 
> For request_node() of the TCM bank this is occurring in parse_fw() in 
> remoteproc_core as in the zynqmp_r5 driver shows below:
> 
>   .parse_fw   = zynqmp_r5_parse_fw,
>   ...
>   Zynqmp_parse_fw calls parse_tcm_banks
> 
>   static int parse_tcm_banks(struct rproc *rproc){
>   ...
>   ret = zynqmp_r5_pm_request_sram(rsc.start);
>   ...
>   mem = rproc_mem_entry_init(dev, NULL, rsc.start,
>  (size_t)size, rsc.start,
>  tcm_mem_alloc,
>  tcm_mem_release,
>  rsc.name);
> 
> For release_node() this is occurring not at remove but instead is managed by 
> remoteproc_core and tied to the lifecyle of the remoteproc carveout since 
> release_node() is within the function tcm_mem_release() and therefore 
> rproc_resource_cleanup() will end up triggering 
> TCM bank cleanup.
> 
> 
> Still it is understandable to prefer prepare/unprepared to contain the 2 
> lines.
> 
> 
> If you still prefer prepare/unprepared is the following implementation ok?
>

The prepare/unprepare functions have been added to specifically handle cases
such as this one where miscellanous actions need to be taken before accessing
the HW.  Using them guarantees the same behavior as the remoteproc core
evolves, something that is less certain for parse_fw and resource cleanup.
 
> prepare: 
>   Just move request_node() line here  
> unprepare: 
>   similarly this is only moving the 1 line of release_node().

That will be just fine.

> 
> If this suggestion satisfies what you are saying I will do so, otherwise 
> please correct my understanding
> 
> 
> Cheers
> Ben 
> 
> 
> 
> > > > +}
> > >
> > > Please move this just after tcm_mem_alloc()
> > >
> > > > +
> > > > +/*
> > > > + * zynqmp_r5_rproc_start
> > > > + * @rproc: single R5 core's corresponding rproc instance
> > > > + *
> > > > + * Start R5 Core from designated boot address.
> > > > + *
> > > > + * return 0 on success, otherwise non-zero value on failure
> > > > + */
> > > > +static int zynqmp_r5_rproc_start(struct rproc *rproc)
> > > > +{
> > > > +   struct zynqmp_r5_rproc *z_rproc = rproc->priv;
> > > > +   enum rpu_boot_mem bootmem;
> > > > +
> > > > +   bootmem = (rproc->bootaddr & 0xF000) == 0xF000 ?
> > > > +  PM_RPU_BOOTMEM_HIVEC : PM_RPU_BOOTMEM_LOVEC;
> > > > +
> > > > +   dev_dbg(rproc->dev.parent, "RPU boot from %s.",
> > > > +   bootmem == PM_RPU_BOOTMEM_HIVEC ? "OCM" : "TCM");
> > > > +
> > > > +   return zynqmp_pm_request_wake(z_rproc->pnode_id, 1,
> > > > + bootmem,
> > > ZYNQMP_PM_REQUEST_ACK_NO);
> > > > +}
> > > > +
> > > > +/*
> > > > + * zynqmp_r5_rproc_stop
> > > > + * @rproc: single R5 core's corresponding rproc instance
> > > > + *
> > > > + * Power down  R5 Core.
> > > > + *
> > > > + * return 0 on success, otherwise non-zero value on failure
> > > > + */
> > > > +static int zynqmp_r5_rproc_stop(struct rproc *rproc)
> > > > +{
> > > > +   struct zynqmp_r5_rproc *z_rproc = rproc->priv;
> > > > +
> > > > +   return zynqmp_pm_force_pwrdwn(z_rproc->pnode_id,
> > > > + ZYNQMP_PM_REQUEST_ACK_BLOCKING);
> > > > +}
> > > > +
> > > > +/*
> > > > + * zynqmp_r5_rproc_mem_alloc
> > > > + * @rproc: single R5 core's corresponding rproc instance
> > > > + * @mem: mem entry to map
> > > > + *
> > > > + * Callback to map va for memory-region's carveout.
> > > > + *
> > > > + * return 0 on success, otherwise non-zero value on failure
> > > > + */
> > > > +static int zynqmp_r5_rproc_mem_alloc(struct rproc *rproc,
> > > > +struct rproc_mem_entry *mem)
> > > > +{
> > > > +   void *va;
> 

Re: [PATCH v5 07/19] remoteproc: Add new get_loaded_rsc_table() to rproc_ops

2021-02-17 Thread Mathieu Poirier
On Mon, Feb 15, 2021 at 02:10:10PM +0100, Arnaud POULIQUEN wrote:
> Hi Mathieu,
> 
> On 2/12/21 12:46 AM, Mathieu Poirier wrote:
> > Add a new get_loaded_rsc_table() operation in order to support
> > scenarios where the remoteproc core has booted a remote processor
> > and detaches from it.  When re-attaching to the remote processor,
> > the core needs to know where the resource table has been placed
> > in memory.
> > 
> > Signed-off-by: Mathieu Poirier 
> > ---
> > New for V5:
> > - Added function rproc_set_loaded_rsc_table() to keep rproc_attach() clean.
> > - Setting ->cached_table, ->table_ptr and ->table_sz in the remoteproc core
> >   rather than the platform drivers.
> > ---
> >  drivers/remoteproc/remoteproc_core.c | 35 
> >  drivers/remoteproc/remoteproc_internal.h | 10 +++
> >  include/linux/remoteproc.h   |  6 +++-
> >  3 files changed, 50 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/remoteproc/remoteproc_core.c 
> > b/drivers/remoteproc/remoteproc_core.c
> > index e6606d10a4c8..741bc20de437 100644
> > --- a/drivers/remoteproc/remoteproc_core.c
> > +++ b/drivers/remoteproc/remoteproc_core.c
> > @@ -1537,6 +1537,35 @@ static int rproc_fw_boot(struct rproc *rproc, const 
> > struct firmware *fw)
> > return ret;
> >  }
> >  
> > +static int rproc_set_loaded_rsc_table(struct rproc *rproc)
> > +{
> > +   struct resource_table *table_ptr;
> > +   struct device *dev = >dev;
> > +   size_t table_sz;
> > +   int ret;
> > +
> > +   table_ptr = rproc_get_loaded_rsc_table(rproc, _sz);
> > +   if (IS_ERR_OR_NULL(table_ptr)) {
> > +   if (!table_ptr)
> > +   ret = -EINVAL;
> 
> I did few tests on this showing that this approach does not cover all use 
> cases.
> 
> The first one is a firmware without resource table. In this case table_ptr
> should be null, or we have to consider the -ENOENT error as a non error 
> usecase.
>

Right, I'll provision for those cases.
 
> The second one, more tricky, is a firmware started by the remoteproc 
> framework.
> In this case the resource table address is retrieved from the ELF file by the
> core part.

Correct.

> So if we detach and reattach rproc_get_loaded_rsc_table cannot return the
> address. Look to me that we should have also an alocation of the clean_table 
> in
> rproc_start and then to keep the memory allocated until a shutdown.

I assumed the address of the resource table found in the ELF image was the same
as the one known by the platform driver.  In hindsight I realise the platform
driver may not know that address.

> 
> That said regarding the complexity to re-attach, I wonder if it would not be
> better to focus first on a simple detach, and address the reattachment in a
> separate series, to move forward in stages.

I agree that OFFLINE -> RUNNING -> DETACHED -> ATTACHED is introducing some
complexity related to the management of the resource table that where not
expected.  We could concentrate on a simple detach and see where that takes us.
It would also mean to get rid of the "autonomous-on-core-shutdown" DT binding. 

Thanks,
Mathieu

> 
> Regards,
> Arnaud
> 
> > +   else
> > +   ret = PTR_ERR(table_ptr);
> > +
> > +   dev_err(dev, "can't load resource table: %d\n", ret);
> > +   return ret;
> > +   }
> > +
> > +   /*
> > +* The resource table is already loaded in device memory, no need
> > +* to work with a cached table.
> > +*/
> > +   rproc->cached_table = NULL;
> > +   rproc->table_ptr = table_ptr;
> > +   rproc->table_sz = table_sz;
> > +
> > +   return 0;
> > +}
> > +
> >  /*
> >   * Attach to remote processor - similar to rproc_fw_boot() but without
> >   * the steps that deal with the firmware image.
> > @@ -1556,6 +1585,12 @@ static int rproc_attach(struct rproc *rproc)
> > return ret;
> > }
> >  
> > +   ret = rproc_set_loaded_rsc_table(rproc);
> > +   if (ret) {
> > +   dev_err(dev, "can't load resource table: %d\n", ret);
> > +   goto disable_iommu;
> > +   }
> > +
> > /* reset max_notifyid */
> > rproc->max_notifyid = -1;
> >  
> > diff --git a/drivers/remoteproc/remoteproc_internal.h 
> > b/drivers/remoteproc/remoteproc_internal.h
> > index c34002888d2c..4f73aac7e60d 100644
> > --- a/drivers/remoteproc/remoteproc_internal.h
> > +++ b/drivers/remotep

Re: [PATCH V3 08/14] coresight: core: Add support for dedicated percpu sinks

2021-02-16 Thread Mathieu Poirier
On Tue, Feb 16, 2021 at 04:10:18PM +0530, Anshuman Khandual wrote:
> 
> 
> On 2/5/21 12:04 AM, Mathieu Poirier wrote:
> > On Thu, Jan 28, 2021 at 09:16:34AM +, Suzuki K Poulose wrote:
> >> On 1/27/21 8:55 AM, Anshuman Khandual wrote:
> >>> Add support for dedicated sinks that are bound to individual CPUs. (e.g,
> >>> TRBE). To allow quicker access to the sink for a given CPU bound source,
> >>> keep a percpu array of the sink devices. Also, add support for building
> >>> a path to the CPU local sink from the ETM.
> >>>
> >>> This adds a new percpu sink type CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM.
> >>> This new sink type is exclusively available and can only work with percpu
> >>> source type device CORESIGHT_DEV_SUBTYPE_SOURCE_PERCPU_PROC.
> >>>
> >>> This defines a percpu structure that accommodates a single 
> >>> coresight_device
> >>> which can be used to store an initialized instance from a sink driver. As
> >>> these sinks are exclusively linked and dependent on corresponding percpu
> >>> sources devices, they should also be the default sink device during a perf
> >>> session.
> >>>
> >>> Outwards device connections are scanned while establishing paths between a
> >>> source and a sink device. But such connections are not present for certain
> >>> percpu source and sink devices which are exclusively linked and dependent.
> >>> Build the path directly and skip connection scanning for such devices.
> >>>
> >>> Cc: Mathieu Poirier 
> >>> Cc: Mike Leach 
> >>> Cc: Suzuki K Poulose 
> >>> Signed-off-by: Anshuman Khandual 
> >>> ---
> >>> Changes in V3:
> >>>
> >>> - Updated coresight_find_default_sink()
> >>>
> >>>   drivers/hwtracing/coresight/coresight-core.c | 16 ++--
> >>>   include/linux/coresight.h| 12 
> >>>   2 files changed, 26 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/drivers/hwtracing/coresight/coresight-core.c 
> >>> b/drivers/hwtracing/coresight/coresight-core.c
> >>> index 0062c89..4795e28 100644
> >>> --- a/drivers/hwtracing/coresight/coresight-core.c
> >>> +++ b/drivers/hwtracing/coresight/coresight-core.c
> >>> @@ -23,6 +23,7 @@
> >>>   #include "coresight-priv.h"
> >>>   static DEFINE_MUTEX(coresight_mutex);
> >>> +DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
> >>>   /**
> >>>* struct coresight_node - elements of a path, from source to sink
> >>> @@ -784,6 +785,13 @@ static int _coresight_build_path(struct 
> >>> coresight_device *csdev,
> >>>   if (csdev == sink)
> >>>   goto out;
> >>> + if (coresight_is_percpu_source(csdev) && coresight_is_percpu_sink(sink) 
> >>> &&
> >>> + sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) {
> >>> + _coresight_build_path(sink, sink, path);
> > 
> > The return value for _coresight_build_path() needs to be checked.  
> > Otherwise a
> > failure to allocate a node for the sink will go unoticed and make for a very
> > hard problem to debug.
> 
> How about this instead ?
> 
> diff --git a/drivers/hwtracing/coresight/coresight-core.c 
> b/drivers/hwtracing/coresight/coresight-core.c
> index 4795e28..e93e669 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -787,9 +787,10 @@ static int _coresight_build_path(struct coresight_device 
> *csdev,
>  
> if (coresight_is_percpu_source(csdev) && 
> coresight_is_percpu_sink(sink) &&
> sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) {
> -   _coresight_build_path(sink, sink, path);
> -   found = true;
> -   goto out;
> +   if (_coresight_build_path(sink, sink, path) == 0) {
> +   found = true;
> +   goto out;
> +   }

I am missing the context now but it is a step in the right direction.  I will
re-assess on your next revision.

> }
>  
> /* Not a sink - recursively explore each port found on this element */
> 
> > 
> >>> + found = true;
> >>> + goto out;
> >>> + }
> >>> +
> >>>   /* Not a si

Re: [PATCH V3 08/14] coresight: core: Add support for dedicated percpu sinks

2021-02-16 Thread Mathieu Poirier
On Mon, Feb 15, 2021 at 05:58:37PM +, Mike Leach wrote:
> Hi Mathieu,
> 
> On Mon, 15 Feb 2021 at 16:56, Mathieu Poirier
>  wrote:
> >
> > On Mon, Feb 15, 2021 at 04:27:26PM +, Mike Leach wrote:
> > > HI Anshuman
> > >
> > > On Wed, 27 Jan 2021 at 08:55, Anshuman Khandual
> > >  wrote:
> > > >
> > > > Add support for dedicated sinks that are bound to individual CPUs. (e.g,
> > > > TRBE). To allow quicker access to the sink for a given CPU bound source,
> > > > keep a percpu array of the sink devices. Also, add support for building
> > > > a path to the CPU local sink from the ETM.
> > > >
> > >
> > > Really need to tighten up the terminology here - I think what you mean
> > > is a PE architecturally defined sink - i.e. one that can be determined
> > > by reading the feature registers on the PE, rather than an ETR which
> > > cannot.
> > > However, the Coresight Base System Architecture specification does
> > > recommend a per cpu design using an ETR per CPU - now I assume that
> > > this case is not catered for in this patch?
> > >
> > > > This adds a new percpu sink type 
> > > > CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM.
> > > > This new sink type is exclusively available and can only work with 
> > > > percpu
> > > > source type device CORESIGHT_DEV_SUBTYPE_SOURCE_PERCPU_PROC.
> > > >
> > >
> > > CORESIGHT_DEV_SUBTYPE_SOURCE_PERCPU_PROC - this does not exist.
> > >
> > > >
> > > > This defines a percpu structure that accommodates a single 
> > > > coresight_device
> > > > which can be used to store an initialized instance from a sink driver. 
> > > > As
> > > > these sinks are exclusively linked and dependent on corresponding percpu
> > > > sources devices, they should also be the default sink device during a 
> > > > perf
> > > > session.
> > > >
> > > > Outwards device connections are scanned while establishing paths 
> > > > between a
> > > > source and a sink device. But such connections are not present for 
> > > > certain
> > > > percpu source and sink devices which are exclusively linked and 
> > > > dependent.
> > > > Build the path directly and skip connection scanning for such devices.
> > > >
> > > > Cc: Mathieu Poirier 
> > > > Cc: Mike Leach 
> > > > Cc: Suzuki K Poulose 
> > > > Signed-off-by: Anshuman Khandual 
> > > > ---
> > > > Changes in V3:
> > > >
> > > > - Updated coresight_find_default_sink()
> > > >
> > > >  drivers/hwtracing/coresight/coresight-core.c | 16 ++--
> > > >  include/linux/coresight.h| 12 
> > > >  2 files changed, 26 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/hwtracing/coresight/coresight-core.c 
> > > > b/drivers/hwtracing/coresight/coresight-core.c
> > > > index 0062c89..4795e28 100644
> > > > --- a/drivers/hwtracing/coresight/coresight-core.c
> > > > +++ b/drivers/hwtracing/coresight/coresight-core.c
> > > > @@ -23,6 +23,7 @@
> > > >  #include "coresight-priv.h"
> > > >
> > > >  static DEFINE_MUTEX(coresight_mutex);
> > > > +DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
> > > >
> > >
> > > If you do indeed mean the architecturally defined sinks then this
> > > could be 'csdev_pe_arch_sink' - or something similar to indicate the
> > > reliance on the PE architecture, unless per-cpu ETR topologies are
> > > also handled here.
> >
> > I would like to treat systems with one ETR per CPU the same way we do for 
> > TRBEs.
> > That way we have two distinct way of working, i.e topologies where the sink 
> > is
> > shared and 1:1 topologies.  As such moving forward with "csdev_pe_arch_sink"
> > could become misleading when 1:1 ETR topologies are supported.
> >
> > Mathieu
> >
> 
> I believe that In terms of connecting source -> sink for 1:1 ETM:ETR,
> then the existing code will already work via the normal build path and
> ports declarations. Suzukis changes in coresight-etm-perf to allow
> multiple sinks of the same type to be active for ETE:TRBE will also
> work for ETx:ETR. (at least in terms of path building - there may
> still be ot

Re: [PATCH v25 5/5] remoteproc: Add initial zynqmp R5 remoteproc driver

2021-02-16 Thread Mathieu Poirier
On Sun, Jan 10, 2021 at 06:02:50PM -0800, Ben Levinsky wrote:
> R5 is included in Xilinx Zynq UltraScale MPSoC so by adding this
> remotproc driver, we can boot the R5 sub-system in two different
> configurations -
>   * Split
>   * Lockstep
> 
> The Xilinx R5 Remoteproc Driver boots the R5's via calls to the Xilinx
> Platform Management Unit that handles the R5 configuration, memory access
> and R5 lifecycle management. The interface to this manager is done in this
> driver via zynqmp_pm_* function calls.
> 
> Signed-off-by: Wendy Liang 
> Signed-off-by: Michal Simek 
> Signed-off-by: Ed Mooring 
> Signed-off-by: Jason Wu 
> Signed-off-by: Ben Levinsky 
> ---
> v25:
> - reword error message for rpu configuration
> - change char name[15] to 16 chars to have null terminated string
>   in parse_mem_regions()
> - reword comments in tcm_mem_alloc
> - call xilinx platform cleanup in parse_tcm_banks() case of failure
> - check value of mbox_send_message in all instances within this driver 
> - indentation in zynqmp_r5_remoteproc driver
> - update style of constructing carveouts to match convention in ST
>   remoteproc drivers. No longer iterate through memory-region property
>   using of_count_phandle_with_args. Instead use of_phandle_iterator
> - use rproc_of_resm_mem_entry_init for vdev0buffer carveout as per feedback
> - rework loop in zynqmp_r5_pm_request_sram as per feedback
> - fix comment and linebreak in tcm_mem_alloc description
> - add comments and remove extraneous devm_ioremap_wc call in tcm_mem_alloc
> - in parse_tcm_banks remove check for bank not being available
> - rework order of locals and remove else in zynqmp_r5_rproc_kick
> - document and update logic for zynqmp_r5_parse_fw
> - add dev_dbg output in event_notified_idr_cb if
>   rproc_vq_interrupt(rproc, id) == IRQ_NONE
> - add comment for handle_event_notified mbox_send_message function call
> - add comment for zynqmp_r5_mb_rx_cb
> - update zynqmp_r5_setup_mbox to match convention of mbox setup in ST
>   remoteproc drivers
> - change return in zynqmp_r5_setup_mbox to use PTR_ERR
> - add zynqmp_r5_cleanup_mbox
> - in zynqmp_r5_probe, reteurn zynqmp_r5_rproc instead of taking in as arg.
> - in zynqmp_r5_probe use return of PTR_ERR and use zynqmp_r5_cleanup_mbox
> - in zynqmp_r5_remoteproc_probe update use return value of zynqmp_r5_probe as
>   either zynqmp_r5_rproc* or PTR_ERR
> - update loop that cleans up cluster and mboxes in zynqmp_r5_remoteproc_probe
> - update loop that cleans up cluster and mboxes in zynqmp_r5_remoteproc_remove
> ---
>  drivers/remoteproc/Kconfig|   8 +
>  drivers/remoteproc/Makefile   |   1 +
>  drivers/remoteproc/zynqmp_r5_remoteproc.c | 898 ++
>  3 files changed, 907 insertions(+)
>  create mode 100644 drivers/remoteproc/zynqmp_r5_remoteproc.c
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index c6659dfea7c7..c2fe54b1d94f 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -275,6 +275,14 @@ config TI_K3_DSP_REMOTEPROC
> It's safe to say N here if you're not interested in utilizing
> the DSP slave processors.
>  
> +config ZYNQMP_R5_REMOTEPROC
> + tristate "ZynqMP R5 remoteproc support"
> + depends on PM && ARCH_ZYNQMP
> + select RPMSG_VIRTIO
> + select ZYNQMP_IPI_MBOX
> + help
> +   Say y or m here to support ZynqMP R5 remote processors via the remote
> +   processor framework.
>  endif # REMOTEPROC
>  
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 3dfa28e6c701..ef1abff654c2 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -33,3 +33,4 @@ obj-$(CONFIG_ST_REMOTEPROC) += st_remoteproc.o
>  obj-$(CONFIG_ST_SLIM_REMOTEPROC) += st_slim_rproc.o
>  obj-$(CONFIG_STM32_RPROC)+= stm32_rproc.o
>  obj-$(CONFIG_TI_K3_DSP_REMOTEPROC)   += ti_k3_dsp_remoteproc.o
> +obj-$(CONFIG_ZYNQMP_R5_REMOTEPROC)   += zynqmp_r5_remoteproc.o
> diff --git a/drivers/remoteproc/zynqmp_r5_remoteproc.c 
> b/drivers/remoteproc/zynqmp_r5_remoteproc.c
> new file mode 100644
> index ..9e228c9ecd43
> --- /dev/null
> +++ b/drivers/remoteproc/zynqmp_r5_remoteproc.c
> @@ -0,0 +1,898 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Zynq R5 Remote Processor driver
> + *
> + * Based on origin OMAP and Zynq Remote Processor driver
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "remoteproc_internal.h"
> +
> +#define MAX_RPROCS   2 /* Support up to 2 RPU */
> +#define MAX_MEM_PNODES   4 /* Max power nodes for one RPU memory 
> instance */
> +
> +#define BANK_LIST_PROP   "sram"
> +#define DDR_LIST_PROP"memory-region"
> +
> +/* IPI buffer MAX length */
> +#define IPI_BUF_LEN_MAX  32U
> +/* RX mailbox 

Re: [PATCH v25 5/5] remoteproc: Add initial zynqmp R5 remoteproc driver

2021-02-15 Thread Mathieu Poirier
Good day,

I have started to review this set - as with previous revisions comments will
come over several days.

On Sun, Jan 10, 2021 at 06:02:50PM -0800, Ben Levinsky wrote:
> R5 is included in Xilinx Zynq UltraScale MPSoC so by adding this
> remotproc driver, we can boot the R5 sub-system in two different
> configurations -
>   * Split
>   * Lockstep
> 
> The Xilinx R5 Remoteproc Driver boots the R5's via calls to the Xilinx
> Platform Management Unit that handles the R5 configuration, memory access
> and R5 lifecycle management. The interface to this manager is done in this
> driver via zynqmp_pm_* function calls.
> 
> Signed-off-by: Wendy Liang 
> Signed-off-by: Michal Simek 
> Signed-off-by: Ed Mooring 
> Signed-off-by: Jason Wu 
> Signed-off-by: Ben Levinsky 
> ---
> v25:
> - reword error message for rpu configuration
> - change char name[15] to 16 chars to have null terminated string
>   in parse_mem_regions()
> - reword comments in tcm_mem_alloc
> - call xilinx platform cleanup in parse_tcm_banks() case of failure
> - check value of mbox_send_message in all instances within this driver 
> - indentation in zynqmp_r5_remoteproc driver
> - update style of constructing carveouts to match convention in ST
>   remoteproc drivers. No longer iterate through memory-region property
>   using of_count_phandle_with_args. Instead use of_phandle_iterator
> - use rproc_of_resm_mem_entry_init for vdev0buffer carveout as per feedback
> - rework loop in zynqmp_r5_pm_request_sram as per feedback
> - fix comment and linebreak in tcm_mem_alloc description
> - add comments and remove extraneous devm_ioremap_wc call in tcm_mem_alloc
> - in parse_tcm_banks remove check for bank not being available
> - rework order of locals and remove else in zynqmp_r5_rproc_kick
> - document and update logic for zynqmp_r5_parse_fw
> - add dev_dbg output in event_notified_idr_cb if
>   rproc_vq_interrupt(rproc, id) == IRQ_NONE
> - add comment for handle_event_notified mbox_send_message function call
> - add comment for zynqmp_r5_mb_rx_cb
> - update zynqmp_r5_setup_mbox to match convention of mbox setup in ST
>   remoteproc drivers
> - change return in zynqmp_r5_setup_mbox to use PTR_ERR
> - add zynqmp_r5_cleanup_mbox
> - in zynqmp_r5_probe, reteurn zynqmp_r5_rproc instead of taking in as arg.
> - in zynqmp_r5_probe use return of PTR_ERR and use zynqmp_r5_cleanup_mbox
> - in zynqmp_r5_remoteproc_probe update use return value of zynqmp_r5_probe as
>   either zynqmp_r5_rproc* or PTR_ERR
> - update loop that cleans up cluster and mboxes in zynqmp_r5_remoteproc_probe
> - update loop that cleans up cluster and mboxes in zynqmp_r5_remoteproc_remove
> ---
>  drivers/remoteproc/Kconfig|   8 +
>  drivers/remoteproc/Makefile   |   1 +
>  drivers/remoteproc/zynqmp_r5_remoteproc.c | 898 ++
>  3 files changed, 907 insertions(+)
>  create mode 100644 drivers/remoteproc/zynqmp_r5_remoteproc.c
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index c6659dfea7c7..c2fe54b1d94f 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -275,6 +275,14 @@ config TI_K3_DSP_REMOTEPROC
> It's safe to say N here if you're not interested in utilizing
> the DSP slave processors.
>  
> +config ZYNQMP_R5_REMOTEPROC
> + tristate "ZynqMP R5 remoteproc support"
> + depends on PM && ARCH_ZYNQMP
> + select RPMSG_VIRTIO
> + select ZYNQMP_IPI_MBOX
> + help
> +   Say y or m here to support ZynqMP R5 remote processors via the remote
> +   processor framework.
>  endif # REMOTEPROC
>  
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 3dfa28e6c701..ef1abff654c2 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -33,3 +33,4 @@ obj-$(CONFIG_ST_REMOTEPROC) += st_remoteproc.o
>  obj-$(CONFIG_ST_SLIM_REMOTEPROC) += st_slim_rproc.o
>  obj-$(CONFIG_STM32_RPROC)+= stm32_rproc.o
>  obj-$(CONFIG_TI_K3_DSP_REMOTEPROC)   += ti_k3_dsp_remoteproc.o
> +obj-$(CONFIG_ZYNQMP_R5_REMOTEPROC)   += zynqmp_r5_remoteproc.o
> diff --git a/drivers/remoteproc/zynqmp_r5_remoteproc.c 
> b/drivers/remoteproc/zynqmp_r5_remoteproc.c
> new file mode 100644
> index ..9e228c9ecd43
> --- /dev/null
> +++ b/drivers/remoteproc/zynqmp_r5_remoteproc.c
> @@ -0,0 +1,898 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Zynq R5 Remote Processor driver
> + *
> + * Based on origin OMAP and Zynq Remote Processor driver
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "remoteproc_internal.h"
> +
> +#define MAX_RPROCS   2 /* Support up to 2 RPU */
> +#define MAX_MEM_PNODES   4 /* Max power nodes for one RPU memory 
> instance */
> +
> +#define BANK_LIST_PROP   "sram"
> +#define DDR_LIST_PROP 

Re: [PATCH V3 08/14] coresight: core: Add support for dedicated percpu sinks

2021-02-15 Thread Mathieu Poirier
On Mon, Feb 15, 2021 at 04:27:26PM +, Mike Leach wrote:
> HI Anshuman
> 
> On Wed, 27 Jan 2021 at 08:55, Anshuman Khandual
>  wrote:
> >
> > Add support for dedicated sinks that are bound to individual CPUs. (e.g,
> > TRBE). To allow quicker access to the sink for a given CPU bound source,
> > keep a percpu array of the sink devices. Also, add support for building
> > a path to the CPU local sink from the ETM.
> >
> 
> Really need to tighten up the terminology here - I think what you mean
> is a PE architecturally defined sink - i.e. one that can be determined
> by reading the feature registers on the PE, rather than an ETR which
> cannot.
> However, the Coresight Base System Architecture specification does
> recommend a per cpu design using an ETR per CPU - now I assume that
> this case is not catered for in this patch?
> 
> > This adds a new percpu sink type CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM.
> > This new sink type is exclusively available and can only work with percpu
> > source type device CORESIGHT_DEV_SUBTYPE_SOURCE_PERCPU_PROC.
> >
> 
> CORESIGHT_DEV_SUBTYPE_SOURCE_PERCPU_PROC - this does not exist.
> 
> >
> > This defines a percpu structure that accommodates a single coresight_device
> > which can be used to store an initialized instance from a sink driver. As
> > these sinks are exclusively linked and dependent on corresponding percpu
> > sources devices, they should also be the default sink device during a perf
> > session.
> >
> > Outwards device connections are scanned while establishing paths between a
> > source and a sink device. But such connections are not present for certain
> > percpu source and sink devices which are exclusively linked and dependent.
> > Build the path directly and skip connection scanning for such devices.
> >
> > Cc: Mathieu Poirier 
> > Cc: Mike Leach 
> > Cc: Suzuki K Poulose 
> > Signed-off-by: Anshuman Khandual 
> > ---
> > Changes in V3:
> >
> > - Updated coresight_find_default_sink()
> >
> >  drivers/hwtracing/coresight/coresight-core.c | 16 ++--
> >  include/linux/coresight.h| 12 
> >  2 files changed, 26 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-core.c 
> > b/drivers/hwtracing/coresight/coresight-core.c
> > index 0062c89..4795e28 100644
> > --- a/drivers/hwtracing/coresight/coresight-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-core.c
> > @@ -23,6 +23,7 @@
> >  #include "coresight-priv.h"
> >
> >  static DEFINE_MUTEX(coresight_mutex);
> > +DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
> >
> 
> If you do indeed mean the architecturally defined sinks then this
> could be 'csdev_pe_arch_sink' - or something similar to indicate the
> reliance on the PE architecture, unless per-cpu ETR topologies are
> also handled here.

I would like to treat systems with one ETR per CPU the same way we do for TRBEs.
That way we have two distinct way of working, i.e topologies where the sink is
shared and 1:1 topologies.  As such moving forward with "csdev_pe_arch_sink"
could become misleading when 1:1 ETR topologies are supported.

Mathieu

> 
> >  /**
> >   * struct coresight_node - elements of a path, from source to sink
> > @@ -784,6 +785,13 @@ static int _coresight_build_path(struct 
> > coresight_device *csdev,
> > if (csdev == sink)
> > goto out;
> >
> > +   if (coresight_is_percpu_source(csdev) && 
> > coresight_is_percpu_sink(sink) &&
> > +   sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) {
> > +   _coresight_build_path(sink, sink, path);
> > +   found = true;
> > +   goto out;
> > +   }
> > +
> > /* Not a sink - recursively explore each port found on this element 
> > */
> > for (i = 0; i < csdev->pdata->nr_outport; i++) {
> > struct coresight_device *child_dev;
> > @@ -999,8 +1007,12 @@ coresight_find_default_sink(struct coresight_device 
> > *csdev)
> > int depth = 0;
> >
> > /* look for a default sink if we have not found for this device */
> > -   if (!csdev->def_sink)
> > -   csdev->def_sink = coresight_find_sink(csdev, );
> > +   if (!csdev->def_sink) {
> > +   if (coresight_is_percpu_source(csdev))
> > +   csdev->def_sink = per_cpu(csdev_sink, 
> > source_

Re: [PATCHv2] coresight: etm4x: Add ETM PID for Cortex-A78

2021-02-15 Thread Mathieu Poirier
On Mon, Feb 15, 2021 at 10:26:38AM +, Mike Leach wrote:
> Reviewed-by: Mike Leach 

I will pick this up when 5.12-rc1 comes out.

Thanks,
Mathieu

> 
> On Sat, 13 Feb 2021 at 11:28, Sai Prakash Ranjan
>  wrote:
> >
> > Add ETM PID for Cortex-A78 to the list of supported ETMs.
> >
> > Signed-off-by: Sai Prakash Ranjan 
> > ---
> >
> > Changes in v2:
> >  * Rebased on top of coresight/next from kernel.org coresight repo.
> >
> > ---
> >  drivers/hwtracing/coresight/coresight-etm4x-core.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
> > b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> > index 15016f757828..a5b13a7779c3 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> > @@ -1951,6 +1951,7 @@ static const struct amba_id etm4_ids[] = {
> > CS_AMBA_UCI_ID(0x000bbd05, uci_id_etm4),/* Cortex-A55 */
> > CS_AMBA_UCI_ID(0x000bbd0a, uci_id_etm4),/* Cortex-A75 */
> > CS_AMBA_UCI_ID(0x000bbd0c, uci_id_etm4),/* Neoverse N1 */
> > +   CS_AMBA_UCI_ID(0x000bbd41, uci_id_etm4),/* Cortex-A78 */
> > CS_AMBA_UCI_ID(0x000f0205, uci_id_etm4),/* Qualcomm Kryo */
> > CS_AMBA_UCI_ID(0x000f0211, uci_id_etm4),/* Qualcomm Kryo */
> > CS_AMBA_UCI_ID(0x000bb802, uci_id_etm4),/* Qualcomm Kryo 385 
> > Cortex-A55 */
> >
> > base-commit: 06c18e28c402ecfb842df8e22a19a097c35ffca9
> > --
> > QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> > of Code Aurora Forum, hosted by The Linux Foundation
> >
> 
> 
> -- 
> Mike Leach
> Principal Engineer, ARM Ltd.
> Manchester Design Centre. UK


Re: [PATCH V3 11/14] coresight: sink: Add TRBE driver

2021-02-12 Thread Mathieu Poirier
On Wed, Jan 27, 2021 at 02:25:35PM +0530, Anshuman Khandual wrote:
> Trace Buffer Extension (TRBE) implements a trace buffer per CPU which is
> accessible via the system registers. The TRBE supports different addressing
> modes including CPU virtual address and buffer modes including the circular
> buffer mode. The TRBE buffer is addressed by a base pointer (TRBBASER_EL1),
> an write pointer (TRBPTR_EL1) and a limit pointer (TRBLIMITR_EL1). But the
> access to the trace buffer could be prohibited by a higher exception level
> (EL3 or EL2), indicated by TRBIDR_EL1.P. The TRBE can also generate a CPU
> private interrupt (PPI) on address translation errors and when the buffer
> is full. Overall implementation here is inspired from the Arm SPE driver.
> 
> Cc: Mathieu Poirier 
> Cc: Mike Leach 
> Cc: Suzuki K Poulose 
> Signed-off-by: Anshuman Khandual 
> ---
> Changes in V3:
> 
> - Added new DT bindings document TRBE.yaml
> - Changed TRBLIMITR_TRIG_MODE_SHIFT from 2 to 3
> - Dropped isb() from trbe_reset_local()
> - Dropped gap between (void *) and buf->trbe_base
> - Changed 'int' to 'unsigned int' in is_trbe_available()
> - Dropped unused function set_trbe_running(), set_trbe_virtual_mode(),
>   set_trbe_enabled() and set_trbe_limit_pointer()
> - Changed get_trbe_flag_update(), is_trbe_programmable() and
>   get_trbe_address_align() to accept TRBIDR value
> - Changed is_trbe_running(), is_trbe_abort(), is_trbe_wrap(), is_trbe_trg(),
>   is_trbe_irq(), get_trbe_bsc() and get_trbe_ec() to accept TRBSR value
> - Dropped snapshot mode condition in arm_trbe_alloc_buffer()
> - Exit arm_trbe_init() when arm64_kernel_unmapped_at_el0() is enabled
> - Compute trbe_limit before trbe_write to get the updated handle
> - Added trbe_stop_and_truncate_event()
> - Dropped trbe_handle_fatal()
> 
>  Documentation/trace/coresight/coresight-trbe.rst |   39 +
>  arch/arm64/include/asm/sysreg.h  |1 +
>  drivers/hwtracing/coresight/Kconfig  |   11 +
>  drivers/hwtracing/coresight/Makefile |1 +
>  drivers/hwtracing/coresight/coresight-trbe.c | 1023 
> ++
>  drivers/hwtracing/coresight/coresight-trbe.h |  160 
>  6 files changed, 1235 insertions(+)
>  create mode 100644 Documentation/trace/coresight/coresight-trbe.rst
>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.h
> 
> diff --git a/Documentation/trace/coresight/coresight-trbe.rst 
> b/Documentation/trace/coresight/coresight-trbe.rst
> new file mode 100644
> index 000..1cbb819
> --- /dev/null
> +++ b/Documentation/trace/coresight/coresight-trbe.rst
> @@ -0,0 +1,39 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==
> +Trace Buffer Extension (TRBE).
> +==
> +
> +:Author:   Anshuman Khandual 
> +:Date: November 2020
> +
> +Hardware Description
> +
> +
> +Trace Buffer Extension (TRBE) is a percpu hardware which captures in system
> +memory, CPU traces generated from a corresponding percpu tracing unit. This
> +gets plugged in as a coresight sink device because the corresponding trace
> +genarators (ETE), are plugged in as source device.
> +
> +The TRBE is not compliant to CoreSight architecture specifications, but is
> +driven via the CoreSight driver framework to support the ETE (which is
> +CoreSight compliant) integration.
> +
> +Sysfs files and directories
> +---
> +
> +The TRBE devices appear on the existing coresight bus alongside the other
> +coresight devices::
> +
> + >$ ls /sys/bus/coresight/devices
> + trbe0  trbe1  trbe2 trbe3
> +
> +The ``trbe`` named TRBEs are associated with a CPU.::
> +
> + >$ ls /sys/bus/coresight/devices/trbe0/
> +align dbm
> +
> +*Key file items are:-*
> +   * ``align``: TRBE write pointer alignment
> +   * ``dbm``: TRBE updates memory with access and dirty flags
> +
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 85ae4db..9e2e9b7 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -97,6 +97,7 @@
>  #define SET_PSTATE_UAO(x)__emit_inst(0xd500401f | PSTATE_UAO | 
> ((!!x) << PSTATE_Imm_shift))
>  #define SET_PSTATE_SSBS(x)   __emit_inst(0xd500401f | PSTATE_SSBS | 
> ((!!x) << PSTATE_Imm_shift))
>  #define SET_PSTATE_TCO(x)__emit_inst(0xd500401f | PSTATE_TCO | 
> ((!!x) << PSTATE_Imm_shift))
> +#define TSB_CSYNC__emit_inst(0xd503225f)
>  
>  #define set_pstate_pan(x)

Re: [PATCH V3 11/14] coresight: sink: Add TRBE driver

2021-02-12 Thread Mathieu Poirier
On Fri, Feb 12, 2021 at 11:13:01AM +0530, Anshuman Khandual wrote:
> 
> 
> On 2/11/21 12:30 AM, Mathieu Poirier wrote:
> > On Wed, Jan 27, 2021 at 02:25:35PM +0530, Anshuman Khandual wrote:
> >> Trace Buffer Extension (TRBE) implements a trace buffer per CPU which is
> >> accessible via the system registers. The TRBE supports different addressing
> >> modes including CPU virtual address and buffer modes including the circular
> >> buffer mode. The TRBE buffer is addressed by a base pointer (TRBBASER_EL1),
> >> an write pointer (TRBPTR_EL1) and a limit pointer (TRBLIMITR_EL1). But the
> >> access to the trace buffer could be prohibited by a higher exception level
> >> (EL3 or EL2), indicated by TRBIDR_EL1.P. The TRBE can also generate a CPU
> >> private interrupt (PPI) on address translation errors and when the buffer
> >> is full. Overall implementation here is inspired from the Arm SPE driver.
> >>
> >> Cc: Mathieu Poirier 
> >> Cc: Mike Leach 
> >> Cc: Suzuki K Poulose 
> >> Signed-off-by: Anshuman Khandual 
> >> ---
> >> Changes in V3:
> >>
> >> - Added new DT bindings document TRBE.yaml
> >> - Changed TRBLIMITR_TRIG_MODE_SHIFT from 2 to 3
> >> - Dropped isb() from trbe_reset_local()
> >> - Dropped gap between (void *) and buf->trbe_base
> >> - Changed 'int' to 'unsigned int' in is_trbe_available()
> >> - Dropped unused function set_trbe_running(), set_trbe_virtual_mode(),
> >>   set_trbe_enabled() and set_trbe_limit_pointer()
> >> - Changed get_trbe_flag_update(), is_trbe_programmable() and
> >>   get_trbe_address_align() to accept TRBIDR value
> >> - Changed is_trbe_running(), is_trbe_abort(), is_trbe_wrap(), 
> >> is_trbe_trg(),
> >>   is_trbe_irq(), get_trbe_bsc() and get_trbe_ec() to accept TRBSR value
> >> - Dropped snapshot mode condition in arm_trbe_alloc_buffer()
> >> - Exit arm_trbe_init() when arm64_kernel_unmapped_at_el0() is enabled
> >> - Compute trbe_limit before trbe_write to get the updated handle
> >> - Added trbe_stop_and_truncate_event()
> >> - Dropped trbe_handle_fatal()
> >>
> >>  Documentation/trace/coresight/coresight-trbe.rst |   39 +
> >>  arch/arm64/include/asm/sysreg.h  |1 +
> >>  drivers/hwtracing/coresight/Kconfig  |   11 +
> >>  drivers/hwtracing/coresight/Makefile |1 +
> >>  drivers/hwtracing/coresight/coresight-trbe.c | 1023 
> >> ++
> >>  drivers/hwtracing/coresight/coresight-trbe.h |  160 
> >>  6 files changed, 1235 insertions(+)
> >>  create mode 100644 Documentation/trace/coresight/coresight-trbe.rst
> >>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.c
> >>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.h
> >> +
> > 
> > [...]
> > 
> >> +static void arm_trbe_probe_coresight_cpu(void *info)
> >> +{
> >> +  struct trbe_drvdata *drvdata = info;
> >> +  struct coresight_desc desc = { 0 };
> >> +  int cpu = smp_processor_id();
> >> +  struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
> >> +  struct coresight_device *trbe_csdev = per_cpu(csdev_sink, cpu);
> >> +  u64 trbidr = read_sysreg_s(SYS_TRBIDR_EL1);
> >> +  struct device *dev;
> >> +
> >> +  if (WARN_ON(!cpudata))
> >> +  goto cpu_clear;
> > 
> > There is already a check for this in arm_trbe_probe_coresight(), we 
> > couldn't be
> > here if there was a problem with the allocation.
> 
> Right but just to be extra cautious. Do you really want this to be dropped ?

I don't think it is necessary but there is no harm in keeping it if you are keen
on it.

> 
> > 
> >> +
> >> +  if (trbe_csdev)
> >> +  return;
> > 
> > Now that's a reason to have a WARN_ON().  If we are probing and a sink is
> > already present in this cpu's slot, something went seriously wrong and we 
> > should
> > be clear about it.
> 
> Right, will add an WARN_ON().
> 
> > 
> >> +
> >> +  cpudata->cpu = smp_processor_id();
> >> +  cpudata->drvdata = drvdata;
> >> +  dev = >drvdata->pdev->dev;
> >> +
> >> +  if (!is_trbe_available()) {
> >> +  pr_err("TRBE is not implemented on cpu %d\n", cpudata->cpu);
> >> +  goto cpu_clear;
> >> +  }
> >> +
> >> +  if (!is_trbe_programmable(trbidr)) {
> >

Re: [PATCH V3 11/14] coresight: sink: Add TRBE driver

2021-02-12 Thread Mathieu Poirier
[...]

> > 
> > 
> >> +  if (nr_pages < 2)
> >> +  return NULL;
> >> +
> >> +  buf = kzalloc_node(sizeof(*buf), GFP_KERNEL, trbe_alloc_node(event));
> >> +  if (IS_ERR(buf))
> >> +  return ERR_PTR(-ENOMEM);
> >> +
> >> +  pglist = kcalloc(nr_pages, sizeof(*pglist), GFP_KERNEL);
> >> +  if (IS_ERR(pglist)) {
> >> +  kfree(buf);
> >> +  return ERR_PTR(-ENOMEM);
> >> +  }
> >> +
> >> +  for (i = 0; i < nr_pages; i++)
> >> +  pglist[i] = virt_to_page(pages[i]);
> >> +
> >> +  buf->trbe_base = (unsigned long) vmap(pglist, nr_pages, VM_MAP, 
> >> PAGE_KERNEL);
> >> +  if (IS_ERR((void *)buf->trbe_base)) {
> > 
> > Why not simply make buf->trbe_base a void * instead of having to do all this
> 
> There are many arithmetic and comparison operations involving trbe_base
> element. Hence it might be better to keep it as unsigned long, also to
> keeps it consistent with other pointers i.e trbe_write, trbe_limit.

That is a fair point.  Please add a comment to explain your design choice and
make sure the sparse checker is happy with all of it.

> 
> Snippet from $cat drivers/hwtracing/coresight/coresight-trbe.c | grep 
> "trbe_base"
> There are just two places type casting trbe_base back to (void *).
> 
>   memset((void *)buf->trbe_base + head, ETE_IGNORE_PACKET, len);
>   return buf->trbe_base + offset;
>   WARN_ON(buf->trbe_write < buf->trbe_base);
>   set_trbe_base_pointer(buf->trbe_base);
>   buf->trbe_base = (unsigned long)vmap(pglist, nr_pages, VM_MAP, 
> PAGE_KERNEL);
>   if (IS_ERR((void *)buf->trbe_base)) {
>   return ERR_PTR(buf->trbe_base);
>   buf->trbe_limit = buf->trbe_base + nr_pages * PAGE_SIZE;
>   buf->trbe_write = buf->trbe_base;
>   vunmap((void *)buf->trbe_base);
>   base = get_trbe_base_pointer();
>   buf->trbe_write = buf->trbe_base + PERF_IDX2OFF(handle->head, buf);
>   if (buf->trbe_limit == buf->trbe_base) {
>   buf->trbe_write = buf->trbe_base + PERF_IDX2OFF(handle->head, buf);
>   if (buf->trbe_limit == buf->trbe_base) {
>   offset = get_trbe_limit_pointer() - get_trbe_base_pointer();
>   buf->trbe_write = buf->trbe_base + PERF_IDX2OFF(handle->head, buf);
>   if (buf->trbe_limit == buf->trbe_base) {
>   WARN_ON(buf->trbe_base != get_trbe_base_pointer());
>   if (get_trbe_write_pointer() == get_trbe_base_pointer())
>   
> > casting?  And IS_ERR() doesn't work with vmap().
> 
> Sure, will drop IS_ERR() here.
> 

[...]


> > 
> >> +
> >> +static ssize_t dbm_show(struct device *dev, struct device_attribute 
> >> *attr, char *buf)
> >> +{
> >> +  struct trbe_cpudata *cpudata = dev_get_drvdata(dev);
> >> +
> >> +  return sprintf(buf, "%d\n", cpudata->trbe_dbm);
> >> +}
> >> +static DEVICE_ATTR_RO(dbm);
> > 
> > What does "dbm" stand for?  Looking at the documentation for TRBIDR_EL1.F, I
> > don't see what "dbm" relates to.
> 
> I made it up to refer TRBIDR_EL1.F as "Dirty (and Access Flag) Bit 
> Management".
> Could change it as "afdbm" to be more specific or if it is preferred.
> 

I don't see "afdbm" being a better solution - why not simply "flag"?



[PATCH v5 18/19] remoteproc: Properly deal with detach request

2021-02-11 Thread Mathieu Poirier
This patch introduces the capability to detach a remote processor
that has been attached to or booted by the remoteproc core.  For
that to happen a rproc::ops::detach() operation need to be
available.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_cdev.c  | 6 ++
 drivers/remoteproc/remoteproc_sysfs.c | 6 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_cdev.c 
b/drivers/remoteproc/remoteproc_cdev.c
index 61541bc7d26c..f7645f289563 100644
--- a/drivers/remoteproc/remoteproc_cdev.c
+++ b/drivers/remoteproc/remoteproc_cdev.c
@@ -43,6 +43,12 @@ static ssize_t rproc_cdev_write(struct file *filp, const 
char __user *buf, size_
return -EINVAL;
 
ret = rproc_shutdown(rproc);
+   } else if (!strncmp(cmd, "detach", len)) {
+   if (rproc->state != RPROC_RUNNING &&
+   rproc->state != RPROC_ATTACHED)
+   return -EINVAL;
+
+   ret = rproc_detach(rproc);
} else {
dev_err(>dev, "Unrecognized option\n");
ret = -EINVAL;
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 7d281cfe3e03..5a239df5877e 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -207,6 +207,12 @@ static ssize_t state_store(struct device *dev,
return -EINVAL;
 
ret = rproc_shutdown(rproc);
+   } else if (sysfs_streq(buf, "detach")) {
+   if (rproc->state != RPROC_RUNNING &&
+   rproc->state != RPROC_ATTACHED)
+   return -EINVAL;
+
+   ret = rproc_detach(rproc);
} else {
dev_err(>dev, "Unrecognised option: %s\n", buf);
ret = -EINVAL;
-- 
2.25.1



[PATCH v5 19/19] remoteproc: Refactor rproc delete and cdev release path

2021-02-11 Thread Mathieu Poirier
Refactor function rproc_del() and rproc_cdev_release() to take
into account the policy specified in the device tree.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_cdev.c | 18 +++---
 drivers/remoteproc/remoteproc_core.c | 36 
 include/linux/remoteproc.h   |  4 
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_cdev.c 
b/drivers/remoteproc/remoteproc_cdev.c
index f7645f289563..9b2fb6fbf8e7 100644
--- a/drivers/remoteproc/remoteproc_cdev.c
+++ b/drivers/remoteproc/remoteproc_cdev.c
@@ -87,11 +87,23 @@ static long rproc_device_ioctl(struct file *filp, unsigned 
int ioctl, unsigned l
 static int rproc_cdev_release(struct inode *inode, struct file *filp)
 {
struct rproc *rproc = container_of(inode->i_cdev, struct rproc, cdev);
+   int ret;
 
-   if (rproc->cdev_put_on_release && rproc->state == RPROC_RUNNING)
-   rproc_shutdown(rproc);
+   if (!rproc->cdev_put_on_release)
+   return 0;
 
-   return 0;
+   /*
+* The application has crashed or is releasing its file handle.  Detach
+* or shutdown the remote processor based on the policy specified in the
+* DT.  No need to check rproc->state right away, it will be done
+* in either rproc_detach() or rproc_shutdown().
+*/
+   if (rproc->autonomous_on_core_shutdown)
+   ret = rproc_detach(rproc);
+   else
+   ret = rproc_shutdown(rproc);
+
+   return ret;
 }
 
 static const struct file_operations rproc_fops = {
diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 12bd177aa8cd..36b3592caf34 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2413,6 +2413,22 @@ static int rproc_alloc_ops(struct rproc *rproc, const 
struct rproc_ops *ops)
return 0;
 }
 
+static void rproc_set_automation_flags(struct rproc *rproc)
+{
+   struct device *dev = rproc->dev.parent;
+   struct device_node *np = dev->of_node;
+   bool core_shutdown;
+
+   /*
+* When function rproc_cdev_release() or rproc_del() are called and
+* the remote processor has been attached to, it will be detached from
+* (rather than turned off) if "autonomous-on-core-shutdown is specified
+* in the DT.
+*/
+   core_shutdown = of_property_read_bool(np, 
"autonomous-on-core-shutdown");
+   rproc->autonomous_on_core_shutdown = core_shutdown;
+}
+
 /**
  * rproc_alloc() - allocate a remote processor handle
  * @dev: the underlying device
@@ -2471,6 +2487,8 @@ struct rproc *rproc_alloc(struct device *dev, const char 
*name,
if (rproc_alloc_ops(rproc, ops))
goto put_device;
 
+   rproc_set_automation_flags(rproc);
+
/* Assign a unique device index and name */
rproc->index = ida_simple_get(_dev_index, 0, 0, GFP_KERNEL);
if (rproc->index < 0) {
@@ -2547,15 +2565,25 @@ EXPORT_SYMBOL(rproc_put);
  * of the outstanding reference created by rproc_alloc. To decrement that
  * one last refcount, one still needs to call rproc_free().
  *
- * Returns 0 on success and -EINVAL if @rproc isn't valid.
+ * Returns 0 on success and a negative error code on failure.
  */
 int rproc_del(struct rproc *rproc)
 {
+   int ret;
+
if (!rproc)
return -EINVAL;
 
-   /* TODO: make sure this works with rproc->power > 1 */
-   rproc_shutdown(rproc);
+   /*
+* TODO: make sure this works with rproc->power > 1
+*
+* No need to check rproc->state right away, it will be done in either
+* rproc_detach() or rproc_shutdown().
+*/
+   if (rproc->autonomous_on_core_shutdown)
+   ret = rproc_detach(rproc);
+   else
+   ret = rproc_shutdown(rproc);
 
mutex_lock(>lock);
rproc->state = RPROC_DELETED;
@@ -2574,7 +2602,7 @@ int rproc_del(struct rproc *rproc)
 
device_del(>dev);
 
-   return 0;
+   return ret;
 }
 EXPORT_SYMBOL(rproc_del);
 
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 5b49c4018e90..bd3ac6a47e47 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -524,6 +524,9 @@ struct rproc_dump_segment {
  * @nb_vdev: number of vdev currently handled by rproc
  * @char_dev: character device of the rproc
  * @cdev_put_on_release: flag to indicate if remoteproc should be shutdown on 
@char_dev release
+ * @autonomous_on_core_shutdown: true if the remote processor should be 
detached
+ *  from (rather than turned off) when the 
remoteproc
+ *  core goes away.
  */
 struct rproc {
struct list_head node;
@@ -563,6 +566,7 @@ struct rproc {
u16

[PATCH v5 15/19] remoteproc: Properly deal with a kernel panic when attached

2021-02-11 Thread Mathieu Poirier
The panic handler operation of registered remote processors
should also be called when remote processors have been
attached to.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 62f708662052..0dd9f02f52b6 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2693,7 +2693,11 @@ static int rproc_panic_handler(struct notifier_block 
*nb, unsigned long event,
 
rcu_read_lock();
list_for_each_entry_rcu(rproc, _list, node) {
-   if (!rproc->ops->panic || rproc->state != RPROC_RUNNING)
+   if (!rproc->ops->panic)
+   continue;
+
+   if (rproc->state != RPROC_RUNNING &&
+   rproc->state != RPROC_ATTACHED)
continue;
 
d = rproc->ops->panic(rproc);
-- 
2.25.1



[PATCH v5 13/19] remoteproc: Properly deal with the resource table

2021-02-11 Thread Mathieu Poirier
If it is possible to detach the remote processor, keep an untouched
copy of the resource table.  That way we can start from the same
resource table without having to worry about original values or what
elements the startup code has changed when re-attaching to the remote
processor.

Reported-by: Arnaud POULIQUEN 
Signed-off-by: Mathieu Poirier 
---
 drivers/remoteproc/remoteproc_core.c   | 70 ++
 drivers/remoteproc/remoteproc_elf_loader.c | 24 +++-
 include/linux/remoteproc.h |  3 +
 3 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 660dcc002ff6..9a77cb6d6470 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1527,7 +1527,9 @@ static int rproc_fw_boot(struct rproc *rproc, const 
struct firmware *fw)
 clean_up_resources:
rproc_resource_cleanup(rproc);
kfree(rproc->cached_table);
+   kfree(rproc->clean_table);
rproc->cached_table = NULL;
+   rproc->clean_table = NULL;
rproc->table_ptr = NULL;
 unprepare_rproc:
/* release HW resources if needed */
@@ -1555,6 +1557,23 @@ static int rproc_set_loaded_rsc_table(struct rproc 
*rproc)
return ret;
}
 
+   /*
+* If it is possible to detach the remote processor, keep an untouched
+* copy of the resource table.  That way we can start fresh again when
+* the remote processor is re-attached, that is:
+*
+*  DETACHED -> ATTACHED -> DETACHED -> ATTACHED
+*
+* A clean copy of the table is also taken in rproc_elf_load_rsc_table()
+* for cases where the remote processor is booted by the remoteproc
+* core and later detached from.
+*/
+   if (rproc->ops->detach) {
+   rproc->clean_table = kmemdup(table_ptr, table_sz, GFP_KERNEL);
+   if (!rproc->clean_table)
+   return -ENOMEM;
+   }
+
/*
 * The resource table is already loaded in device memory, no need
 * to work with a cached table.
@@ -1566,6 +1585,40 @@ static int rproc_set_loaded_rsc_table(struct rproc 
*rproc)
return 0;
 }
 
+static int rproc_reset_loaded_rsc_table(struct rproc *rproc)
+{
+   /*
+* In order to detach() from a remote processor a clean resource table
+* _must_ have been allocated at boot time, either from rproc_fw_boot()
+* or from rproc_attach().  If one isn't present something went really
+* wrong and we must complain.
+*/
+   if (WARN_ON(!rproc->clean_table))
+   return -EINVAL;
+
+   /*
+* Install the clean resource table where the firmware, i.e
+* rproc_get_loaded_rsc_table(), expects it.
+*/
+   memcpy(rproc->table_ptr, rproc->clean_table, rproc->table_sz);
+
+   /*
+* If the remote processors was started by the core then a cached_table
+* is present and we must follow the same cleanup sequence as we would
+* for a shutdown().  As it is in rproc_stop(), use the cached resource
+* table for the rest of the detach process since ->table_ptr will
+* become invalid as soon as carveouts are released in
+* rproc_resource_cleanup().
+*
+* If the remote processor was started by an external entity the
+* cached_table is NULL and the rest of the cleanup code in
+* rproc_free_vring() can deal with that.
+*/
+   rproc->table_ptr = rproc->cached_table;
+
+   return 0;
+}
+
 /*
  * Attach to remote processor - similar to rproc_fw_boot() but without
  * the steps that deal with the firmware image.
@@ -1947,7 +2000,10 @@ void rproc_shutdown(struct rproc *rproc)
 
/* Free the copy of the resource table */
kfree(rproc->cached_table);
+   /* Free the clean resource table */
+   kfree(rproc->clean_table);
rproc->cached_table = NULL;
+   rproc->clean_table = NULL;
rproc->table_ptr = NULL;
 out:
mutex_unlock(>lock);
@@ -2000,6 +2056,16 @@ int rproc_detach(struct rproc *rproc)
goto out;
}
 
+   /*
+* Install a clean resource table for re-attach while
+* rproc->table_ptr is still valid.
+*/
+   ret = rproc_reset_loaded_rsc_table(rproc);
+   if (ret) {
+   atomic_inc(>power);
+   goto out;
+   }
+
/* clean up all acquired resources */
rproc_resource_cleanup(rproc);
 
@@ -2008,10 +2074,14 @@ int rproc_detach(struct rproc *rproc)
 
rproc_disable_iommu(rproc);
 
+   /* Free the copy of the resource table */
+   kfree(rproc->cached_table);
/* Follow the same sequence as in rproc_shutdown() */
kfree(rproc->cached_table);
rproc->cache

[PATCH v5 17/19] remoteproc: Properly deal with a start request when attached

2021-02-11 Thread Mathieu Poirier
This patch takes into account scenarios where a remote processor
has been attached to when receiving a "start" command from sysfs.

As with the "running" case, the command can't be carried out if the
remote processor is already in operation.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_cdev.c  | 3 ++-
 drivers/remoteproc/remoteproc_sysfs.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_cdev.c 
b/drivers/remoteproc/remoteproc_cdev.c
index d06f8d4919c7..61541bc7d26c 100644
--- a/drivers/remoteproc/remoteproc_cdev.c
+++ b/drivers/remoteproc/remoteproc_cdev.c
@@ -32,7 +32,8 @@ static ssize_t rproc_cdev_write(struct file *filp, const char 
__user *buf, size_
return -EFAULT;
 
if (!strncmp(cmd, "start", len)) {
-   if (rproc->state == RPROC_RUNNING)
+   if (rproc->state == RPROC_RUNNING ||
+   rproc->state == RPROC_ATTACHED)
return -EBUSY;
 
ret = rproc_boot(rproc);
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 3696f2ccc785..7d281cfe3e03 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -194,7 +194,8 @@ static ssize_t state_store(struct device *dev,
int ret = 0;
 
if (sysfs_streq(buf, "start")) {
-   if (rproc->state == RPROC_RUNNING)
+   if (rproc->state == RPROC_RUNNING ||
+   rproc->state == RPROC_ATTACHED)
return -EBUSY;
 
ret = rproc_boot(rproc);
-- 
2.25.1



[PATCH v5 16/19] remoteproc: Properly deal with a stop request when attached

2021-02-11 Thread Mathieu Poirier
This patch introduces the capability to stop a remote processor
that has been attached to by the remoteproc core.  For that to
happen a rproc::ops::stop() operation need to be available.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_cdev.c  | 5 +++--
 drivers/remoteproc/remoteproc_core.c  | 6 +-
 drivers/remoteproc/remoteproc_sysfs.c | 5 +++--
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_cdev.c 
b/drivers/remoteproc/remoteproc_cdev.c
index b19ea3057bde..d06f8d4919c7 100644
--- a/drivers/remoteproc/remoteproc_cdev.c
+++ b/drivers/remoteproc/remoteproc_cdev.c
@@ -37,10 +37,11 @@ static ssize_t rproc_cdev_write(struct file *filp, const 
char __user *buf, size_
 
ret = rproc_boot(rproc);
} else if (!strncmp(cmd, "stop", len)) {
-   if (rproc->state != RPROC_RUNNING)
+   if (rproc->state != RPROC_RUNNING &&
+   rproc->state != RPROC_ATTACHED)
return -EINVAL;
 
-   rproc_shutdown(rproc);
+   ret = rproc_shutdown(rproc);
} else {
dev_err(>dev, "Unrecognized option\n");
ret = -EINVAL;
diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 0dd9f02f52b6..12bd177aa8cd 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1740,6 +1740,10 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
struct device *dev = >dev;
int ret;
 
+   /* No need to continue if a stop() operation has not been provided */
+   if (!rproc->ops->stop)
+   return -EINVAL;
+
/* Stop any subdevices for the remote processor */
rproc_stop_subdevices(rproc, crashed);
 
@@ -1977,7 +1981,7 @@ int rproc_shutdown(struct rproc *rproc)
return ret;
}
 
-   if (rproc->state != RPROC_RUNNING) {
+   if (rproc->state != RPROC_RUNNING && rproc->state != RPROC_ATTACHED) {
ret = -EPERM;
goto out;
}
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index f9694def9b54..3696f2ccc785 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -201,10 +201,11 @@ static ssize_t state_store(struct device *dev,
if (ret)
dev_err(>dev, "Boot failed: %d\n", ret);
} else if (sysfs_streq(buf, "stop")) {
-   if (rproc->state != RPROC_RUNNING)
+   if (rproc->state != RPROC_RUNNING &&
+   rproc->state != RPROC_ATTACHED)
return -EINVAL;
 
-   rproc_shutdown(rproc);
+   ret = rproc_shutdown(rproc);
} else {
dev_err(>dev, "Unrecognised option: %s\n", buf);
ret = -EINVAL;
-- 
2.25.1



[PATCH v5 12/19] remoteproc: Introduce function rproc_detach()

2021-02-11 Thread Mathieu Poirier
Introduce function rproc_detach() to enable the remoteproc
core to release the resources associated with a remote processor
without stopping its operation.

Signed-off-by: Mathieu Poirier 
---
New for V5:
- Fixed comment about rproc_actuate() that no longer exists.
- Added call to rproc_unprepare_device() to balance rproc_prepare_device() in
  function rproc_attach().
- Removed RB from Peng and Arnaud because of the above.
---
 drivers/remoteproc/remoteproc_core.c | 66 +++-
 include/linux/remoteproc.h   |  1 +
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index b150138542d4..660dcc002ff6 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1712,7 +1712,7 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
 /*
  * __rproc_detach(): Does the opposite of __rproc_attach()
  */
-static int __maybe_unused __rproc_detach(struct rproc *rproc)
+static int __rproc_detach(struct rproc *rproc)
 {
struct device *dev = >dev;
int ret;
@@ -1954,6 +1954,70 @@ void rproc_shutdown(struct rproc *rproc)
 }
 EXPORT_SYMBOL(rproc_shutdown);
 
+/**
+ * rproc_detach() - Detach the remote processor from the
+ * remoteproc core
+ *
+ * @rproc: the remote processor
+ *
+ * Detach a remote processor (previously attached to with rproc_attach()).
+ *
+ * In case @rproc is still being used by an additional user(s), then
+ * this function will just decrement the power refcount and exit,
+ * without disconnecting the device.
+ *
+ * Function rproc_detach() calls __rproc_detach() in order to let a remote
+ * processor know that services provided by the application processor are
+ * no longer available.  From there it should be possible to remove the
+ * platform driver and even power cycle the application processor (if the HW
+ * supports it) without needing to switch off the remote processor.
+ */
+int rproc_detach(struct rproc *rproc)
+{
+   struct device *dev = >dev;
+   int ret;
+
+   ret = mutex_lock_interruptible(>lock);
+   if (ret) {
+   dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret);
+   return ret;
+   }
+
+   if (rproc->state != RPROC_RUNNING && rproc->state != RPROC_ATTACHED) {
+   ret = -EPERM;
+   goto out;
+   }
+
+   /* if the remote proc is still needed, bail out */
+   if (!atomic_dec_and_test(>power)) {
+   ret = -EBUSY;
+   goto out;
+   }
+
+   ret = __rproc_detach(rproc);
+   if (ret) {
+   atomic_inc(>power);
+   goto out;
+   }
+
+   /* clean up all acquired resources */
+   rproc_resource_cleanup(rproc);
+
+   /* release HW resources if needed */
+   rproc_unprepare_device(rproc);
+
+   rproc_disable_iommu(rproc);
+
+   /* Follow the same sequence as in rproc_shutdown() */
+   kfree(rproc->cached_table);
+   rproc->cached_table = NULL;
+   rproc->table_ptr = NULL;
+out:
+   mutex_unlock(>lock);
+   return ret;
+}
+EXPORT_SYMBOL(rproc_detach);
+
 /**
  * rproc_get_by_phandle() - find a remote processor by phandle
  * @phandle: phandle to the rproc
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index eff55ec72e80..e1c843c19cc6 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -662,6 +662,7 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 
of_resm_idx, size_t len,
 
 int rproc_boot(struct rproc *rproc);
 void rproc_shutdown(struct rproc *rproc);
+int rproc_detach(struct rproc *rproc);
 int rproc_set_firmware(struct rproc *rproc, const char *fw_name);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 void rproc_coredump_using_sections(struct rproc *rproc);
-- 
2.25.1



[PATCH v5 14/19] remoteproc: Add return value to function rproc_shutdown()

2021-02-11 Thread Mathieu Poirier
Add a return value to function rproc_shutdown() in order to
properly deal with error conditions that may occur.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c | 19 ++-
 include/linux/remoteproc.h   |  2 +-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 9a77cb6d6470..62f708662052 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1966,7 +1966,7 @@ EXPORT_SYMBOL(rproc_boot);
  *   returns, and users can still use it with a subsequent rproc_boot(), if
  *   needed.
  */
-void rproc_shutdown(struct rproc *rproc)
+int rproc_shutdown(struct rproc *rproc)
 {
struct device *dev = >dev;
int ret;
@@ -1974,15 +1974,19 @@ void rproc_shutdown(struct rproc *rproc)
ret = mutex_lock_interruptible(>lock);
if (ret) {
dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret);
-   return;
+   return ret;
}
 
-   if (rproc->state != RPROC_RUNNING)
+   if (rproc->state != RPROC_RUNNING) {
+   ret = -EPERM;
goto out;
+   }
 
/* if the remote proc is still needed, bail out */
-   if (!atomic_dec_and_test(>power))
+   if (!atomic_dec_and_test(>power)) {
+   ret = -EBUSY;
goto out;
+   }
 
ret = rproc_stop(rproc, false);
if (ret) {
@@ -1994,7 +1998,11 @@ void rproc_shutdown(struct rproc *rproc)
rproc_resource_cleanup(rproc);
 
/* release HW resources if needed */
-   rproc_unprepare_device(rproc);
+   ret = rproc_unprepare_device(rproc);
+   if (ret) {
+   atomic_inc(>power);
+   goto out;
+   }
 
rproc_disable_iommu(rproc);
 
@@ -2007,6 +2015,7 @@ void rproc_shutdown(struct rproc *rproc)
rproc->table_ptr = NULL;
 out:
mutex_unlock(>lock);
+   return ret;
 }
 EXPORT_SYMBOL(rproc_shutdown);
 
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index e5f52a12a650..5b49c4018e90 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -664,7 +664,7 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 
of_resm_idx, size_t len,
 u32 da, const char *name, ...);
 
 int rproc_boot(struct rproc *rproc);
-void rproc_shutdown(struct rproc *rproc);
+int rproc_shutdown(struct rproc *rproc);
 int rproc_detach(struct rproc *rproc);
 int rproc_set_firmware(struct rproc *rproc, const char *fw_name);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
-- 
2.25.1



[PATCH v5 10/19] remoteproc: Add new detach() remoteproc operation

2021-02-11 Thread Mathieu Poirier
Add an new detach() operation in order to support scenarios where
the remoteproc core is going away but the remote processor is
kept operating.  This could be the case when the system is
rebooted or when the platform driver is removed.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 include/linux/remoteproc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 51538a7d120d..eff55ec72e80 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -361,6 +361,7 @@ enum rsc_handling_status {
  * @start: power on the device and boot it
  * @stop:  power off the device
  * @attach:attach to a device that his already powered up
+ * @detach:detach from a device, leaving it powered up
  * @kick:  kick a virtqueue (virtqueue id given as a parameter)
  * @da_to_va:  optional platform hook to perform address translations
  * @parse_fw:  parse firmware to extract information (e.g. resource table)
@@ -385,6 +386,7 @@ struct rproc_ops {
int (*start)(struct rproc *rproc);
int (*stop)(struct rproc *rproc);
int (*attach)(struct rproc *rproc);
+   int (*detach)(struct rproc *rproc);
void (*kick)(struct rproc *rproc, int vqid);
void * (*da_to_va)(struct rproc *rproc, u64 da, size_t len);
int (*parse_fw)(struct rproc *rproc, const struct firmware *fw);
-- 
2.25.1



[PATCH v5 11/19] remoteproc: Introduce function __rproc_detach()

2021-02-11 Thread Mathieu Poirier
Introduce function __rproc_detach() to perform the same kind of
operation as rproc_stop(), but instead of switching off the
remote processor using rproc->ops->stop(), it uses
rproc->ops->detach().  That way it is possible for the core
to release the resources associated with a remote processor while
the latter is kept operating.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
---
New for V5:
- Removed fancy error recovery when ops->detach() fails to replicate what is
  done in rproc->stop().
---
 drivers/remoteproc/remoteproc_core.c | 30 
 1 file changed, 30 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 5c52c612a7f0..b150138542d4 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1709,6 +1709,36 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
return 0;
 }
 
+/*
+ * __rproc_detach(): Does the opposite of __rproc_attach()
+ */
+static int __maybe_unused __rproc_detach(struct rproc *rproc)
+{
+   struct device *dev = >dev;
+   int ret;
+
+   /* No need to continue if a detach() operation has not been provided */
+   if (!rproc->ops->detach)
+   return -EINVAL;
+
+   /* Stop any subdevices for the remote processor */
+   rproc_stop_subdevices(rproc, false);
+
+   /* Tell the remote processor the core isn't available anymore */
+   ret = rproc->ops->detach(rproc);
+   if (ret) {
+   dev_err(dev, "can't detach from rproc: %d\n", ret);
+   return ret;
+   }
+
+   rproc_unprepare_subdevices(rproc);
+
+   rproc->state = RPROC_DETACHED;
+
+   dev_info(dev, "detached remote processor %s\n", rproc->name);
+
+   return 0;
+}
 
 /**
  * rproc_trigger_recovery() - recover a remoteproc
-- 
2.25.1



[PATCH v5 09/19] remoteproc: stm32: Move memory parsing to rproc_ops

2021-02-11 Thread Mathieu Poirier
From: Arnaud POULIQUEN 

Some actions such as memory resources reallocation are needed when
trying to reattach a co-processor. Use the prepare() operation for
these actions.

Co-developed-by: Mathieu Poirier 
Signed-off-by: Mathieu Poirier 
Signed-off-by: Arnaud POULIQUEN 
---
 drivers/remoteproc/remoteproc_core.c | 14 --
 drivers/remoteproc/stm32_rproc.c | 27 ++-
 2 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 741bc20de437..5c52c612a7f0 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1585,10 +1585,17 @@ static int rproc_attach(struct rproc *rproc)
return ret;
}
 
+   /* Do anything that is needed to boot the remote processor */
+   ret = rproc_prepare_device(rproc);
+   if (ret) {
+   dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
+   goto disable_iommu;
+   }
+
ret = rproc_set_loaded_rsc_table(rproc);
if (ret) {
dev_err(dev, "can't load resource table: %d\n", ret);
-   goto disable_iommu;
+   goto unprepare_device;
}
 
/* reset max_notifyid */
@@ -1605,7 +1612,7 @@ static int rproc_attach(struct rproc *rproc)
ret = rproc_handle_resources(rproc, rproc_loading_handlers);
if (ret) {
dev_err(dev, "Failed to process resources: %d\n", ret);
-   goto disable_iommu;
+   goto unprepare_device;
}
 
/* Allocate carveout resources associated to rproc */
@@ -1624,6 +1631,9 @@ static int rproc_attach(struct rproc *rproc)
 
 clean_up_resources:
rproc_resource_cleanup(rproc);
+unprepare_device:
+   /* release HW resources if needed */
+   rproc_unprepare_device(rproc);
 disable_iommu:
rproc_disable_iommu(rproc);
return ret;
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 826cb7a045df..6f0bb54dec15 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -207,16 +207,7 @@ static int stm32_rproc_mbox_idx(struct rproc *rproc, const 
unsigned char *name)
return -EINVAL;
 }
 
-static int stm32_rproc_elf_load_rsc_table(struct rproc *rproc,
- const struct firmware *fw)
-{
-   if (rproc_elf_load_rsc_table(rproc, fw))
-   dev_warn(>dev, "no resource table found for this 
firmware\n");
-
-   return 0;
-}
-
-static int stm32_rproc_parse_memory_regions(struct rproc *rproc)
+static int stm32_rproc_prepare(struct rproc *rproc)
 {
struct device *dev = rproc->dev.parent;
struct device_node *np = dev->of_node;
@@ -274,12 +265,10 @@ static int stm32_rproc_parse_memory_regions(struct rproc 
*rproc)
 
 static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
 {
-   int ret = stm32_rproc_parse_memory_regions(rproc);
-
-   if (ret)
-   return ret;
+   if (rproc_elf_load_rsc_table(rproc, fw))
+   dev_warn(>dev, "no resource table found for this 
firmware\n");
 
-   return stm32_rproc_elf_load_rsc_table(rproc, fw);
+   return 0;
 }
 
 static irqreturn_t stm32_rproc_wdg(int irq, void *data)
@@ -609,6 +598,7 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, 
size_t *table_sz)
 }
 
 static const struct rproc_ops st_rproc_ops = {
+   .prepare= stm32_rproc_prepare,
.start  = stm32_rproc_start,
.stop   = stm32_rproc_stop,
.attach = stm32_rproc_attach,
@@ -793,14 +783,9 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;
 
-   if (state == M4_STATE_CRUN) {
+   if (state == M4_STATE_CRUN)
rproc->state = RPROC_DETACHED;
 
-   ret = stm32_rproc_parse_memory_regions(rproc);
-   if (ret)
-   goto free_resources;
-   }
-
rproc->has_iommu = false;
ddata->workqueue = create_workqueue(dev_name(dev));
if (!ddata->workqueue) {
-- 
2.25.1



[PATCH v5 05/19] remoteproc: Add new RPROC_ATTACHED state

2021-02-11 Thread Mathieu Poirier
Add a new RPROC_ATTACHED state to take into account scenarios
where the remoteproc core needs to attach to a remote processor
that is booted by another entity.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_sysfs.c | 1 +
 include/linux/remoteproc.h| 7 +--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 1dbef895e65e..4b4aab0d4c4b 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -172,6 +172,7 @@ static const char * const rproc_state_string[] = {
[RPROC_RUNNING] = "running",
[RPROC_CRASHED] = "crashed",
[RPROC_DELETED] = "deleted",
+   [RPROC_ATTACHED]= "attached",
[RPROC_DETACHED]= "detached",
[RPROC_LAST]= "invalid",
 };
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index f28ee75d1005..b0a57ff73849 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -405,6 +405,8 @@ struct rproc_ops {
  * @RPROC_RUNNING: device is up and running
  * @RPROC_CRASHED: device has crashed; need to start recovery
  * @RPROC_DELETED: device is deleted
+ * @RPROC_ATTACHED:device has been booted by another entity and the core
+ * has attached to it
  * @RPROC_DETACHED:device has been booted by another entity and waiting
  * for the core to attach to it
  * @RPROC_LAST:just keep this one at the end
@@ -421,8 +423,9 @@ enum rproc_state {
RPROC_RUNNING   = 2,
RPROC_CRASHED   = 3,
RPROC_DELETED   = 4,
-   RPROC_DETACHED  = 5,
-   RPROC_LAST  = 6,
+   RPROC_ATTACHED  = 5,
+   RPROC_DETACHED  = 6,
+   RPROC_LAST  = 7,
 };
 
 /**
-- 
2.25.1



[PATCH v5 08/19] remoteproc: stm32: Move resource table setup to rproc_ops

2021-02-11 Thread Mathieu Poirier
Move the setting of the resource table installed by an external
entity to rproc_ops::get_loaded_rsc_table().  This is to support
scenarios where a remote processor has been started by the core
but is detached at a later stage.  To re-attach the remote
processor, the address of the resource table needs to be available
at a later time than the platform driver's probe() function.

Signed-off-by: Mathieu Poirier 
---
New for V5:
- stm32_rproc_get_loaded_rsc_table() now returns a resource table pointer.
---
 drivers/remoteproc/stm32_rproc.c | 141 +++
 1 file changed, 68 insertions(+), 73 deletions(-)

diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index a180aeae9675..826cb7a045df 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -541,6 +541,73 @@ static void stm32_rproc_kick(struct rproc *rproc, int vqid)
}
 }
 
+static int stm32_rproc_da_to_pa(struct rproc *rproc,
+   u64 da, phys_addr_t *pa)
+{
+   struct stm32_rproc *ddata = rproc->priv;
+   struct device *dev = rproc->dev.parent;
+   struct stm32_rproc_mem *p_mem;
+   unsigned int i;
+
+   for (i = 0; i < ddata->nb_rmems; i++) {
+   p_mem = >rmems[i];
+
+   if (da < p_mem->dev_addr ||
+   da >= p_mem->dev_addr + p_mem->size)
+   continue;
+
+   *pa = da - p_mem->dev_addr + p_mem->bus_addr;
+   dev_dbg(dev, "da %llx to pa %#x\n", da, *pa);
+
+   return 0;
+   }
+
+   dev_err(dev, "can't translate da %llx\n", da);
+
+   return -EINVAL;
+}
+
+static struct resource_table *
+stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
+{
+   struct stm32_rproc *ddata = rproc->priv;
+   struct device *dev = rproc->dev.parent;
+   phys_addr_t rsc_pa;
+   u32 rsc_da;
+   int err;
+
+   /* The resource table has already been mapped, nothing to do */
+   if (ddata->rsc_va)
+   goto done;
+
+   err = regmap_read(ddata->rsctbl.map, ddata->rsctbl.reg, _da);
+   if (err) {
+   dev_err(dev, "failed to read rsc tbl addr\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (!rsc_da)
+   /* no rsc table */
+   return ERR_PTR(-ENOENT);
+
+   err = stm32_rproc_da_to_pa(rproc, rsc_da, _pa);
+   if (err)
+   return ERR_PTR(err);
+
+   ddata->rsc_va = devm_ioremap_wc(dev, rsc_pa, RSC_TBL_SIZE);
+   if (IS_ERR_OR_NULL(ddata->rsc_va)) {
+   dev_err(dev, "Unable to map memory region: %pa+%zx\n",
+   _pa, RSC_TBL_SIZE);
+   ddata->rsc_va = NULL;
+   return ERR_PTR(-ENOMEM);
+   }
+
+done:
+   /* Assuming the resource table fits in 1kB is fair */
+   *table_sz = RSC_TBL_SIZE;
+   return (struct resource_table *)ddata->rsc_va;
+}
+
 static const struct rproc_ops st_rproc_ops = {
.start  = stm32_rproc_start,
.stop   = stm32_rproc_stop,
@@ -549,6 +616,7 @@ static const struct rproc_ops st_rproc_ops = {
.load   = rproc_elf_load_segments,
.parse_fw   = stm32_rproc_parse_fw,
.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
+   .get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
.sanity_check   = rproc_elf_sanity_check,
.get_boot_addr  = rproc_elf_get_boot_addr,
 };
@@ -692,75 +760,6 @@ static int stm32_rproc_get_m4_status(struct stm32_rproc 
*ddata,
return regmap_read(ddata->m4_state.map, ddata->m4_state.reg, state);
 }
 
-static int stm32_rproc_da_to_pa(struct platform_device *pdev,
-   struct stm32_rproc *ddata,
-   u64 da, phys_addr_t *pa)
-{
-   struct device *dev = >dev;
-   struct stm32_rproc_mem *p_mem;
-   unsigned int i;
-
-   for (i = 0; i < ddata->nb_rmems; i++) {
-   p_mem = >rmems[i];
-
-   if (da < p_mem->dev_addr ||
-   da >= p_mem->dev_addr + p_mem->size)
-   continue;
-
-   *pa = da - p_mem->dev_addr + p_mem->bus_addr;
-   dev_dbg(dev, "da %llx to pa %#x\n", da, *pa);
-
-   return 0;
-   }
-
-   dev_err(dev, "can't translate da %llx\n", da);
-
-   return -EINVAL;
-}
-
-static int stm32_rproc_get_loaded_rsc_table(struct platform_device *pdev,
-   struct rproc *rproc,
-   struct stm32_rproc *ddata)
-{
-   struct device *dev = >dev;
-   phys_addr_t rsc_pa;
-   u32 rsc_da;
-   int err;
-
-   err = regmap_read(ddata->rsctbl.map, ddata->rsctbl.reg, _da);
-  

[PATCH v5 07/19] remoteproc: Add new get_loaded_rsc_table() to rproc_ops

2021-02-11 Thread Mathieu Poirier
Add a new get_loaded_rsc_table() operation in order to support
scenarios where the remoteproc core has booted a remote processor
and detaches from it.  When re-attaching to the remote processor,
the core needs to know where the resource table has been placed
in memory.

Signed-off-by: Mathieu Poirier 
---
New for V5:
- Added function rproc_set_loaded_rsc_table() to keep rproc_attach() clean.
- Setting ->cached_table, ->table_ptr and ->table_sz in the remoteproc core
  rather than the platform drivers.
---
 drivers/remoteproc/remoteproc_core.c | 35 
 drivers/remoteproc/remoteproc_internal.h | 10 +++
 include/linux/remoteproc.h   |  6 +++-
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index e6606d10a4c8..741bc20de437 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1537,6 +1537,35 @@ static int rproc_fw_boot(struct rproc *rproc, const 
struct firmware *fw)
return ret;
 }
 
+static int rproc_set_loaded_rsc_table(struct rproc *rproc)
+{
+   struct resource_table *table_ptr;
+   struct device *dev = >dev;
+   size_t table_sz;
+   int ret;
+
+   table_ptr = rproc_get_loaded_rsc_table(rproc, _sz);
+   if (IS_ERR_OR_NULL(table_ptr)) {
+   if (!table_ptr)
+   ret = -EINVAL;
+   else
+   ret = PTR_ERR(table_ptr);
+
+   dev_err(dev, "can't load resource table: %d\n", ret);
+   return ret;
+   }
+
+   /*
+* The resource table is already loaded in device memory, no need
+* to work with a cached table.
+*/
+   rproc->cached_table = NULL;
+   rproc->table_ptr = table_ptr;
+   rproc->table_sz = table_sz;
+
+   return 0;
+}
+
 /*
  * Attach to remote processor - similar to rproc_fw_boot() but without
  * the steps that deal with the firmware image.
@@ -1556,6 +1585,12 @@ static int rproc_attach(struct rproc *rproc)
return ret;
}
 
+   ret = rproc_set_loaded_rsc_table(rproc);
+   if (ret) {
+   dev_err(dev, "can't load resource table: %d\n", ret);
+   goto disable_iommu;
+   }
+
/* reset max_notifyid */
rproc->max_notifyid = -1;
 
diff --git a/drivers/remoteproc/remoteproc_internal.h 
b/drivers/remoteproc/remoteproc_internal.h
index c34002888d2c..4f73aac7e60d 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -177,6 +177,16 @@ struct resource_table *rproc_find_loaded_rsc_table(struct 
rproc *rproc,
return NULL;
 }
 
+static inline
+struct resource_table *rproc_get_loaded_rsc_table(struct rproc *rproc,
+ size_t *size)
+{
+   if (rproc->ops->get_loaded_rsc_table)
+   return rproc->ops->get_loaded_rsc_table(rproc, size);
+
+   return NULL;
+}
+
 static inline
 bool rproc_u64_fit_in_size_t(u64 val)
 {
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 6b0a0ed30a03..51538a7d120d 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -368,7 +368,9 @@ enum rsc_handling_status {
  * RSC_HANDLED if resource was handled, RSC_IGNORED if not handled and a
  * negative value on error
  * @load_rsc_table:load resource table from firmware image
- * @find_loaded_rsc_table: find the loaded resouce table
+ * @find_loaded_rsc_table: find the loaded resource table from firmware image
+ * @get_loaded_rsc_table: get resource table installed in memory
+ *   by external entity
  * @load:  load firmware to memory, where the remote processor
  * expects to find it
  * @sanity_check:  sanity check the fw image
@@ -390,6 +392,8 @@ struct rproc_ops {
  int offset, int avail);
struct resource_table *(*find_loaded_rsc_table)(
struct rproc *rproc, const struct firmware *fw);
+   struct resource_table *(*get_loaded_rsc_table)(
+   struct rproc *rproc, size_t *size);
int (*load)(struct rproc *rproc, const struct firmware *fw);
int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
-- 
2.25.1



[PATCH v5 06/19] remoteproc: Properly represent the attached state

2021-02-11 Thread Mathieu Poirier
There is a need to know when a remote processor has been attached
to rather than booted by the remoteproc core.  In order to avoid
manipulating two variables, i.e rproc::autonomous and
rproc::state, get rid of the former and simply use the newly
introduced RPROC_ATTACHED state.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c  | 20 +---
 drivers/remoteproc/remoteproc_sysfs.c |  5 +
 include/linux/remoteproc.h|  2 --
 3 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 8afc7e1bd28a..e6606d10a4c8 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1444,7 +1444,7 @@ static int __rproc_attach(struct rproc *rproc)
goto stop_rproc;
}
 
-   rproc->state = RPROC_RUNNING;
+   rproc->state = RPROC_ATTACHED;
 
dev_info(dev, "remote processor %s is now attached\n", rproc->name);
 
@@ -1659,14 +1659,6 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
 
rproc->state = RPROC_OFFLINE;
 
-   /*
-* The remote processor has been stopped and is now offline, which means
-* that the next time it is brought back online the remoteproc core will
-* be responsible to load its firmware.  As such it is no longer
-* autonomous.
-*/
-   rproc->autonomous = false;
-
dev_info(dev, "stopped remote processor %s\n", rproc->name);
 
return 0;
@@ -2080,16 +2072,6 @@ int rproc_add(struct rproc *rproc)
if (ret < 0)
return ret;
 
-   /*
-* Remind ourselves the remote processor has been attached to rather
-* than booted by the remoteproc core.  This is important because the
-* RPROC_DETACHED state will be lost as soon as the remote processor
-* has been attached to.  Used in firmware_show() and reset in
-* rproc_stop().
-*/
-   if (rproc->state == RPROC_DETACHED)
-   rproc->autonomous = true;
-
/* if rproc is marked always-on, request it to boot */
if (rproc->auto_boot) {
ret = rproc_trigger_auto_boot(rproc);
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 4b4aab0d4c4b..f9694def9b54 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -138,11 +138,8 @@ static ssize_t firmware_show(struct device *dev, struct 
device_attribute *attr,
 * If the remote processor has been started by an external
 * entity we have no idea of what image it is running.  As such
 * simply display a generic string rather then rproc->firmware.
-*
-* Here we rely on the autonomous flag because a remote processor
-* may have been attached to and currently in a running state.
 */
-   if (rproc->autonomous)
+   if (rproc->state == RPROC_ATTACHED)
firmware = "unknown";
 
return sprintf(buf, "%s\n", firmware);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index b0a57ff73849..6b0a0ed30a03 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -512,7 +512,6 @@ struct rproc_dump_segment {
  * @table_sz: size of @cached_table
  * @has_iommu: flag to indicate if remote processor is behind an MMU
  * @auto_boot: flag to indicate if remote processor should be auto-started
- * @autonomous: true if an external entity has booted the remote processor
  * @dump_segments: list of segments in the firmware
  * @nb_vdev: number of vdev currently handled by rproc
  * @char_dev: character device of the rproc
@@ -549,7 +548,6 @@ struct rproc {
size_t table_sz;
bool has_iommu;
bool auto_boot;
-   bool autonomous;
struct list_head dump_segments;
int nb_vdev;
u8 elf_class;
-- 
2.25.1



[PATCH v5 03/19] remoteproc: Remove useless check in rproc_del()

2021-02-11 Thread Mathieu Poirier
Whether started at probe() time or thereafter from the command
line, a remote processor needs to be shutdown before the final
cleanup phases can happen.  Otherwise the system may be left in
an unpredictable state where the remote processor is expecting
the remoteproc core to be providing services when in fact it
no longer exist.

Invariably calling rproc_shutdown() is fine since it will return
immediately if the remote processor has already been switched
off.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index f1c097572e01..86bd66955060 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2350,10 +2350,8 @@ int rproc_del(struct rproc *rproc)
if (!rproc)
return -EINVAL;
 
-   /* if rproc is marked always-on, rproc_add() booted it */
/* TODO: make sure this works with rproc->power > 1 */
-   if (rproc->auto_boot)
-   rproc_shutdown(rproc);
+   rproc_shutdown(rproc);
 
mutex_lock(>lock);
rproc->state = RPROC_DELETED;
-- 
2.25.1



[PATCH v5 02/19] remoteproc: Re-check state in rproc_shutdown()

2021-02-11 Thread Mathieu Poirier
The state of the remote processor may have changed between the
time a call to rproc_shutdown() was made and the time it is
executed.  To avoid moving forward with an operation that may
have been cancelled, recheck while holding the mutex.

Cc: 
Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 2394eef383e3..f1c097572e01 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1857,6 +1857,9 @@ void rproc_shutdown(struct rproc *rproc)
return;
}
 
+   if (rproc->state != RPROC_RUNNING)
+   goto out;
+
/* if the remote proc is still needed, bail out */
if (!atomic_dec_and_test(>power))
goto out;
-- 
2.25.1



[PATCH v5 00/19] remoteproc: Add support for detaching a remote processor

2021-02-11 Thread Mathieu Poirier
Following the work done here [1], this set provides support for the
remoteproc core to release resources associated with a remote processor
without having to switch it off. That way a platform driver can be removed
or the application processor power cycled while the remote processor is
still operating.

Modifications for this revision are detailed in the changelog of each patch but
the main enhancement is the setup of a clean resource table when a remote
processor is detached from.

I have tested scenarios where the processor is detached and re-attached when
booted from an external entity and the remoteproc core.  I was also able
to confirm that removing the platform driver of a detached remote processor
works.  Re-attaching the remote processor after re-inserting the platorm driver
also works properly.

Applies cleanly on rproc-next (43d3f2c715ce). 

Thanks,
Mathieu

Arnaud POULIQUEN (1):
  remoteproc: stm32: Move memory parsing to rproc_ops

Mathieu Poirier (18):
  dt-bindings: remoteproc: Add bindind to support autonomous processors
  remoteproc: Re-check state in rproc_shutdown()
  remoteproc: Remove useless check in rproc_del()
  remoteproc: Rename function rproc_actuate()
  remoteproc: Add new RPROC_ATTACHED state
  remoteproc: Properly represent the attached state
  remoteproc: Add new get_loaded_rsc_table() to rproc_ops
  remoteproc: stm32: Move resource table setup to rproc_ops
  remoteproc: Add new detach() remoteproc operation
  remoteproc: Introduce function __rproc_detach()
  remoteproc: Introduce function rproc_detach()
  remoteproc: Properly deal with the resource table
  remoteproc: Add return value to function rproc_shutdown()
  remoteproc: Properly deal with a kernel panic when attached
  remoteproc: Properly deal with a stop request when attached
  remoteproc: Properly deal with a start request when attached
  remoteproc: Properly deal with detach request
  remoteproc: Refactor rproc delete and cdev release path

 .../bindings/remoteproc/remoteproc-core.yaml  |  27 ++
 drivers/remoteproc/remoteproc_cdev.c  |  32 +-
 drivers/remoteproc/remoteproc_core.c  | 307 --
 drivers/remoteproc/remoteproc_elf_loader.c|  24 +-
 drivers/remoteproc/remoteproc_internal.h  |  10 +
 drivers/remoteproc/remoteproc_sysfs.c |  20 +-
 drivers/remoteproc/stm32_rproc.c  | 168 +-
 include/linux/remoteproc.h|  27 +-
 8 files changed, 465 insertions(+), 150 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/remoteproc-core.yaml

-- 
2.25.1



[PATCH v5 04/19] remoteproc: Rename function rproc_actuate()

2021-02-11 Thread Mathieu Poirier
Rename function rproc_actuate() to rproc_attach().  That way it is
easy to understand that it does the opposite of rproc_detach().

Signed-off-by: Mathieu Poirier 
Reviewed-by: Peng Fan 
Reviewed-by: Arnaud Pouliquen 
---
 drivers/remoteproc/remoteproc_core.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 86bd66955060..8afc7e1bd28a 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1416,7 +1416,7 @@ static int rproc_start(struct rproc *rproc, const struct 
firmware *fw)
return ret;
 }
 
-static int rproc_attach(struct rproc *rproc)
+static int __rproc_attach(struct rproc *rproc)
 {
struct device *dev = >dev;
int ret;
@@ -1541,7 +1541,7 @@ static int rproc_fw_boot(struct rproc *rproc, const 
struct firmware *fw)
  * Attach to remote processor - similar to rproc_fw_boot() but without
  * the steps that deal with the firmware image.
  */
-static int rproc_actuate(struct rproc *rproc)
+static int rproc_attach(struct rproc *rproc)
 {
struct device *dev = >dev;
int ret;
@@ -1581,7 +1581,7 @@ static int rproc_actuate(struct rproc *rproc)
goto clean_up_resources;
}
 
-   ret = rproc_attach(rproc);
+   ret = __rproc_attach(rproc);
if (ret)
goto clean_up_resources;
 
@@ -1802,7 +1802,7 @@ int rproc_boot(struct rproc *rproc)
if (rproc->state == RPROC_DETACHED) {
dev_info(dev, "attaching to %s\n", rproc->name);
 
-   ret = rproc_actuate(rproc);
+   ret = rproc_attach(rproc);
} else {
dev_info(dev, "powering up %s\n", rproc->name);
 
-- 
2.25.1



[PATCH v5 01/19] dt-bindings: remoteproc: Add bindind to support autonomous processors

2021-02-11 Thread Mathieu Poirier
This patch adds a binding to guide the remoteproc core on how to deal with
remote processors in two cases:

1) When an application holding a reference to a remote processor character
   device interface crashes.

2) when the platform driver for a remote processor is removed.

In both cases if "autonomous-on-core-reboot" is specified in the remote
processor DT node, the remoteproc core will detach the remote processor
rather than switching it off.

Signed-off-by: Mathieu Poirier 
Reviewed-by: Rob Herring 
---
 .../bindings/remoteproc/remoteproc-core.yaml  | 27 +++
 1 file changed, 27 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/remoteproc-core.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/remoteproc-core.yaml 
b/Documentation/devicetree/bindings/remoteproc/remoteproc-core.yaml
new file mode 100644
index ..e8bb8ef9031a
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/remoteproc-core.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/remoteproc-core.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Binding(s) for a primary processor applicable to all ancillary
+   processors
+
+maintainers:
+  - Bjorn Andersson 
+  - Mathieu Poirier 
+
+description:
+  This document defines the bindings used by a primary processor to determine
+  the state it should leave an ancillary processor when the former is no longer
+  functioning.
+
+properties:
+  autonomous-on-core-reboot:
+$ref: /schemas/types.yaml#/definitions/flag
+description:
+  When specified the ancillary processor should be left operational when
+  the primary processor is no longer available.  Otherwise the ancillary
+  processor should be made inoperative.
+
+additionalProperties: true
-- 
2.25.1



Re: [PATCH V3 11/14] coresight: sink: Add TRBE driver

2021-02-11 Thread Mathieu Poirier
On Wed, Jan 27, 2021 at 02:25:35PM +0530, Anshuman Khandual wrote:
> Trace Buffer Extension (TRBE) implements a trace buffer per CPU which is
> accessible via the system registers. The TRBE supports different addressing
> modes including CPU virtual address and buffer modes including the circular
> buffer mode. The TRBE buffer is addressed by a base pointer (TRBBASER_EL1),
> an write pointer (TRBPTR_EL1) and a limit pointer (TRBLIMITR_EL1). But the
> access to the trace buffer could be prohibited by a higher exception level
> (EL3 or EL2), indicated by TRBIDR_EL1.P. The TRBE can also generate a CPU
> private interrupt (PPI) on address translation errors and when the buffer
> is full. Overall implementation here is inspired from the Arm SPE driver.
> 
> Cc: Mathieu Poirier 
> Cc: Mike Leach 
> Cc: Suzuki K Poulose 
> Signed-off-by: Anshuman Khandual 
> ---
> Changes in V3:
> 
> - Added new DT bindings document TRBE.yaml
> - Changed TRBLIMITR_TRIG_MODE_SHIFT from 2 to 3
> - Dropped isb() from trbe_reset_local()
> - Dropped gap between (void *) and buf->trbe_base
> - Changed 'int' to 'unsigned int' in is_trbe_available()
> - Dropped unused function set_trbe_running(), set_trbe_virtual_mode(),
>   set_trbe_enabled() and set_trbe_limit_pointer()
> - Changed get_trbe_flag_update(), is_trbe_programmable() and
>   get_trbe_address_align() to accept TRBIDR value
> - Changed is_trbe_running(), is_trbe_abort(), is_trbe_wrap(), is_trbe_trg(),
>   is_trbe_irq(), get_trbe_bsc() and get_trbe_ec() to accept TRBSR value
> - Dropped snapshot mode condition in arm_trbe_alloc_buffer()
> - Exit arm_trbe_init() when arm64_kernel_unmapped_at_el0() is enabled
> - Compute trbe_limit before trbe_write to get the updated handle
> - Added trbe_stop_and_truncate_event()
> - Dropped trbe_handle_fatal()
> 
>  Documentation/trace/coresight/coresight-trbe.rst |   39 +
>  arch/arm64/include/asm/sysreg.h  |1 +
>  drivers/hwtracing/coresight/Kconfig  |   11 +
>  drivers/hwtracing/coresight/Makefile |1 +
>  drivers/hwtracing/coresight/coresight-trbe.c | 1023 
> ++
>  drivers/hwtracing/coresight/coresight-trbe.h |  160 
>  6 files changed, 1235 insertions(+)
>  create mode 100644 Documentation/trace/coresight/coresight-trbe.rst
>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.h
> 
> diff --git a/Documentation/trace/coresight/coresight-trbe.rst 
> b/Documentation/trace/coresight/coresight-trbe.rst
> new file mode 100644
> index 000..1cbb819
> --- /dev/null
> +++ b/Documentation/trace/coresight/coresight-trbe.rst
> @@ -0,0 +1,39 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==
> +Trace Buffer Extension (TRBE).
> +==
> +
> +:Author:   Anshuman Khandual 
> +:Date: November 2020
> +
> +Hardware Description
> +
> +
> +Trace Buffer Extension (TRBE) is a percpu hardware which captures in system
> +memory, CPU traces generated from a corresponding percpu tracing unit. This
> +gets plugged in as a coresight sink device because the corresponding trace
> +genarators (ETE), are plugged in as source device.
> +
> +The TRBE is not compliant to CoreSight architecture specifications, but is
> +driven via the CoreSight driver framework to support the ETE (which is
> +CoreSight compliant) integration.
> +
> +Sysfs files and directories
> +---
> +
> +The TRBE devices appear on the existing coresight bus alongside the other
> +coresight devices::
> +
> + >$ ls /sys/bus/coresight/devices
> + trbe0  trbe1  trbe2 trbe3
> +
> +The ``trbe`` named TRBEs are associated with a CPU.::
> +
> + >$ ls /sys/bus/coresight/devices/trbe0/
> +align dbm
> +
> +*Key file items are:-*
> +   * ``align``: TRBE write pointer alignment
> +   * ``dbm``: TRBE updates memory with access and dirty flags
> +
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 85ae4db..9e2e9b7 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -97,6 +97,7 @@
>  #define SET_PSTATE_UAO(x)__emit_inst(0xd500401f | PSTATE_UAO | 
> ((!!x) << PSTATE_Imm_shift))
>  #define SET_PSTATE_SSBS(x)   __emit_inst(0xd500401f | PSTATE_SSBS | 
> ((!!x) << PSTATE_Imm_shift))
>  #define SET_PSTATE_TCO(x)__emit_inst(0xd500401f | PSTATE_TCO | 
> ((!!x) << PSTATE_Imm_shift))
> +#define TSB_CSYNC__emit_inst(0xd503225f)
>  
>  #define set_pstate_pan(x)

[PATCH v2 3/3] Documentation: coresight: Add PID tracing description

2021-02-11 Thread Mathieu Poirier
From: Leo Yan 

After support the PID tracing for the kernel in EL1 or EL2, the usage
gets more complicated.

This patch gives description for the PMU formats of contextID configs,
this can help users to understand how to control the knobs for PID
tracing when the kernel is in different ELs.

Signed-off-by: Leo Yan 
Reviewed-by: Suzuki K Poulose 
Reviewed-by: Mike Leach 
Message-Id: <20210206150833.42120-9-leo@linaro.org>
Signed-off-by: Mathieu Poirier 
---
 Documentation/trace/coresight/coresight.rst | 32 +
 1 file changed, 32 insertions(+)

diff --git a/Documentation/trace/coresight/coresight.rst 
b/Documentation/trace/coresight/coresight.rst
index 0b73acb44efa..169749efd8d1 100644
--- a/Documentation/trace/coresight/coresight.rst
+++ b/Documentation/trace/coresight/coresight.rst
@@ -512,6 +512,38 @@ The --itrace option controls the type and frequency of 
synthesized events
 Note that only 64-bit programs are currently supported - further work is
 required to support instruction decode of 32-bit Arm programs.
 
+2.2) Tracing PID
+
+The kernel can be built to write the PID value into the PE ContextID registers.
+For a kernel running at EL1, the PID is stored in CONTEXTIDR_EL1.  A PE may
+implement Arm Virtualization Host Extensions (VHE), which the kernel can
+run at EL2 as a virtualisation host; in this case, the PID value is stored in
+CONTEXTIDR_EL2.
+
+perf provides PMU formats that program the ETM to insert these values into the
+trace data; the PMU formats are defined as below:
+
+  "contextid1": Available on both EL1 kernel and EL2 kernel.  When the
+kernel is running at EL1, "contextid1" enables the PID
+tracing; when the kernel is running at EL2, this enables
+tracing the PID of guest applications.
+
+  "contextid2": Only usable when the kernel is running at EL2.  When
+selected, enables PID tracing on EL2 kernel.
+
+  "contextid":  Will be an alias for the option that enables PID
+tracing.  I.e,
+contextid == contextid1, on EL1 kernel.
+contextid == contextid2, on EL2 kernel.
+
+perf will always enable PID tracing at the relevant EL, this is accomplished by
+automatically enable the "contextid" config - but for EL2 it is possible to 
make
+specific adjustments using configs "contextid1" and "contextid2", E.g. if a 
user
+wants to trace PIDs for both host and guest, the two configs "contextid1" and
+"contextid2" can be set at the same time:
+
+  perf record -e cs_etm/contextid1,contextid2/u -- vm
+
 
 Generating coverage files for Feedback Directed Optimization: AutoFDO
 -
-- 
2.25.1



[PATCH v2 2/3] coresight: etm-perf: Support PID tracing for kernel at EL2

2021-02-11 Thread Mathieu Poirier
From: Suzuki K Poulose 

When the kernel is running at EL2, the PID is stored in CONTEXTIDR_EL2.
So, tracing CONTEXTIDR_EL1 doesn't give us the pid of the process.
Thus we should trace the VMID with VMIDOPT set to trace CONTEXTIDR_EL2
instead of CONTEXTIDR_EL1.  Given that we have an existing config
option "contextid" and this will be useful for tracing virtual machines
(when we get to support virtualization).

So instead, this patch extends option CTXTID with an extra bit
ETM_OPT_CTXTID2 (bit 15), thus on an EL2 kernel, we will have another
bit available for the perf tool: ETM_OPT_CTXTID is for kernel running in
EL1, ETM_OPT_CTXTID2 is used when kernel runs in EL2 with VHE enabled.

The tool must be backward compatible for users, i.e, "contextid" today
traces PID and that should remain the same; for this purpose, the perf
tool is updated to automatically set corresponding bit for the
"contextid" config, therefore, the user doesn't have to bother which EL
the kernel is running.

  i.e, perf record -e cs_etm/contextid/u --

will always do the "pid" tracing, independent of the kernel EL.

The driver parses the format "contextid", which traces CONTEXTIDR_EL1
for ETM_OPT_CTXTID (on EL1 kernel) and traces CONTEXTIDR_EL2 for
ETM_OPT_CTXTID2 (on EL2 kernel).

Besides the enhancement for format "contexid", extra two formats are
introduced: "contextid1" and "contextid2".  This considers to support
tracing both CONTEXTIDR_EL1 and CONTEXTIDR_EL2 when the kernel is
running at EL2.  Finally, the PMU formats are defined as follow:

  "contextid1": Available on both EL1 kernel and EL2 kernel.  When the
kernel is running at EL1, "contextid1" enables the PID
tracing; when the kernel is running at EL2, this enables
tracing the PID of guest applications.

  "contextid2": Only usable when the kernel is running at EL2.  When
selected, enables PID tracing on EL2 kernel.

  "contextid":  Will be an alias for the option that enables PID
tracing.  I.e,
    contextid == contextid1, on EL1 kernel.
contextid == contextid2, on EL2 kernel.

Cc: Mathieu Poirier 
Cc: Al Grant 
Cc: Mike Leach 
Cc: Leo Yan 
Signed-off-by: Suzuki K Poulose 
[ Added two config formats: contextid1, contextid2 ]
Signed-off-by: Leo Yan 
Reviewed-by: Mike Leach 
Message-Id: <20210206150833.42120-4-leo@linaro.org>
Signed-off-by: Mathieu Poirier 
---
 .../hwtracing/coresight/coresight-etm-perf.c  | 27 ++-
 .../coresight/coresight-etm4x-core.c  | 13 +
 include/linux/coresight-pmu.h |  3 +++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c 
b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 465ef1aa8c82..0f603b4094f2 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -32,15 +32,40 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
  * now take them as general formats and apply on all ETMs.
  */
 PMU_FORMAT_ATTR(cycacc,"config:" __stringify(ETM_OPT_CYCACC));
-PMU_FORMAT_ATTR(contextid, "config:" __stringify(ETM_OPT_CTXTID));
+/* contextid1 enables tracing CONTEXTIDR_EL1 for ETMv4 */
+PMU_FORMAT_ATTR(contextid1,"config:" __stringify(ETM_OPT_CTXTID));
+/* contextid2 enables tracing CONTEXTIDR_EL2 for ETMv4 */
+PMU_FORMAT_ATTR(contextid2,"config:" __stringify(ETM_OPT_CTXTID2));
 PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS));
 PMU_FORMAT_ATTR(retstack,  "config:" __stringify(ETM_OPT_RETSTK));
 /* Sink ID - same for all ETMs */
 PMU_FORMAT_ATTR(sinkid,"config2:0-31");
 
+/*
+ * contextid always traces the "PID".  The PID is in CONTEXTIDR_EL1
+ * when the kernel is running at EL1; when the kernel is at EL2,
+ * the PID is in CONTEXTIDR_EL2.
+ */
+static ssize_t format_attr_contextid_show(struct device *dev,
+ struct device_attribute *attr,
+ char *page)
+{
+   int pid_fmt = ETM_OPT_CTXTID;
+
+#if defined(CONFIG_CORESIGHT_SOURCE_ETM4X)
+   pid_fmt = is_kernel_in_hyp_mode() ? ETM_OPT_CTXTID2 : ETM_OPT_CTXTID;
+#endif
+   return sprintf(page, "config:%d\n", pid_fmt);
+}
+
+struct device_attribute format_attr_contextid =
+   __ATTR(contextid, 0444, format_attr_contextid_show, NULL);
+
 static struct attribute *etm_config_formats_attr[] = {
_attr_cycacc.attr,
_attr_contextid.attr,
+   _attr_contextid1.attr,
+   _attr_contextid2.attr,
_attr_timestamp.attr,
_attr_retstack.attr,
_attr_sinkid.attr,
diff --git a/drivers/hwtracing/coresight/coresight-etm4

[PATCH v2 1/3] coresight: etm-perf: Clarify comment on perf options

2021-02-11 Thread Mathieu Poirier
From: Leo Yan 

In theory, the options should be arbitrary values and are neutral for
any ETM version; so far perf tool uses ETMv3.5/PTM ETMCR config bits
except for register's bit definitions, also uses as options.

This can introduce confusion, especially if we want to add a new option
but the new option is not supported by ETMv3.5/PTM ETMCR.  But on the
other hand, we cannot change options since these options are generic
CoreSight PMU ABI.

For easier maintenance and avoid confusion, this patch refines the
comment to clarify perf options, and gives out the background info for
these bits are coming from ETMv3.5/PTM.  Afterwards, we should take
these options as general knobs, and if there have any confliction with
ETMv3.5/PTM, should consider to define saperate macros for ETMv3.5/PTM
ETMCR config bits.

Suggested-by: Suzuki K Poulose 
Signed-off-by: Leo Yan 
Reviewed-by: Suzuki K Poulose 
Message-Id: <20210206150833.42120-2-leo@linaro.org>
Signed-off-by: Mathieu Poirier 
---
 .../hwtracing/coresight/coresight-etm-perf.c|  5 -
 include/linux/coresight-pmu.h   | 17 -
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c 
b/drivers/hwtracing/coresight/coresight-etm-perf.c
index bdc34ca449f7..465ef1aa8c82 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -27,7 +27,10 @@ static bool etm_perf_up;
 static DEFINE_PER_CPU(struct perf_output_handle, ctx_handle);
 static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
 
-/* ETMv3.5/PTM's ETMCR is 'config' */
+/*
+ * The PMU formats were orignally for ETMv3.5/PTM's ETMCR 'config';
+ * now take them as general formats and apply on all ETMs.
+ */
 PMU_FORMAT_ATTR(cycacc,"config:" __stringify(ETM_OPT_CYCACC));
 PMU_FORMAT_ATTR(contextid, "config:" __stringify(ETM_OPT_CTXTID));
 PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS));
diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h
index b0e35eec6499..5dc47cfdcf07 100644
--- a/include/linux/coresight-pmu.h
+++ b/include/linux/coresight-pmu.h
@@ -10,11 +10,18 @@
 #define CORESIGHT_ETM_PMU_NAME "cs_etm"
 #define CORESIGHT_ETM_PMU_SEED  0x10
 
-/* ETMv3.5/PTM's ETMCR config bit */
-#define ETM_OPT_CYCACC  12
-#define ETM_OPT_CTXTID 14
-#define ETM_OPT_TS  28
-#define ETM_OPT_RETSTK 29
+/*
+ * Below are the definition of bit offsets for perf option, and works as
+ * arbitrary values for all ETM versions.
+ *
+ * Most of them are orignally from ETMv3.5/PTM's ETMCR config, therefore,
+ * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
+ * directly use below macros as config bits.
+ */
+#define ETM_OPT_CYCACC 12
+#define ETM_OPT_CTXTID 14
+#define ETM_OPT_TS 28
+#define ETM_OPT_RETSTK 29
 
 /* ETMv4 CONFIGR programming bits for the ETM OPTs */
 #define ETM4_CFG_BIT_CYCACC4
-- 
2.25.1



[PATCH v2 0/3] coresight: Patches for v5.12 (part 2)

2021-02-11 Thread Mathieu Poirier
Good morning,

My previous submission had the wrong baseline and as such was missing a patch.
This set applies properly on [1].

Thanks for the patience,
Mathieu

[1]. 48139bad913d ACRN: update MAINTAINERS: mailing list is subscribers-only

Leo Yan (2):
  coresight: etm-perf: Clarify comment on perf options
  Documentation: coresight: Add PID tracing description

Suzuki K Poulose (1):
  coresight: etm-perf: Support PID tracing for kernel at EL2

 Documentation/trace/coresight/coresight.rst   | 32 +++
 .../hwtracing/coresight/coresight-etm-perf.c  | 32 +--
 .../coresight/coresight-etm4x-core.c  | 13 
 include/linux/coresight-pmu.h | 20 +---
 4 files changed, 90 insertions(+), 7 deletions(-)

-- 
2.25.1



Re: [PATCH V3 11/14] coresight: sink: Add TRBE driver

2021-02-10 Thread Mathieu Poirier
On Wed, Jan 27, 2021 at 02:25:35PM +0530, Anshuman Khandual wrote:
> Trace Buffer Extension (TRBE) implements a trace buffer per CPU which is
> accessible via the system registers. The TRBE supports different addressing
> modes including CPU virtual address and buffer modes including the circular
> buffer mode. The TRBE buffer is addressed by a base pointer (TRBBASER_EL1),
> an write pointer (TRBPTR_EL1) and a limit pointer (TRBLIMITR_EL1). But the
> access to the trace buffer could be prohibited by a higher exception level
> (EL3 or EL2), indicated by TRBIDR_EL1.P. The TRBE can also generate a CPU
> private interrupt (PPI) on address translation errors and when the buffer
> is full. Overall implementation here is inspired from the Arm SPE driver.
> 
> Cc: Mathieu Poirier 
> Cc: Mike Leach 
> Cc: Suzuki K Poulose 
> Signed-off-by: Anshuman Khandual 
> ---
> Changes in V3:
> 
> - Added new DT bindings document TRBE.yaml
> - Changed TRBLIMITR_TRIG_MODE_SHIFT from 2 to 3
> - Dropped isb() from trbe_reset_local()
> - Dropped gap between (void *) and buf->trbe_base
> - Changed 'int' to 'unsigned int' in is_trbe_available()
> - Dropped unused function set_trbe_running(), set_trbe_virtual_mode(),
>   set_trbe_enabled() and set_trbe_limit_pointer()
> - Changed get_trbe_flag_update(), is_trbe_programmable() and
>   get_trbe_address_align() to accept TRBIDR value
> - Changed is_trbe_running(), is_trbe_abort(), is_trbe_wrap(), is_trbe_trg(),
>   is_trbe_irq(), get_trbe_bsc() and get_trbe_ec() to accept TRBSR value
> - Dropped snapshot mode condition in arm_trbe_alloc_buffer()
> - Exit arm_trbe_init() when arm64_kernel_unmapped_at_el0() is enabled
> - Compute trbe_limit before trbe_write to get the updated handle
> - Added trbe_stop_and_truncate_event()
> - Dropped trbe_handle_fatal()
> 
>  Documentation/trace/coresight/coresight-trbe.rst |   39 +
>  arch/arm64/include/asm/sysreg.h  |1 +
>  drivers/hwtracing/coresight/Kconfig  |   11 +
>  drivers/hwtracing/coresight/Makefile |1 +
>  drivers/hwtracing/coresight/coresight-trbe.c | 1023 
> ++
>  drivers/hwtracing/coresight/coresight-trbe.h |  160 
>  6 files changed, 1235 insertions(+)
>  create mode 100644 Documentation/trace/coresight/coresight-trbe.rst
>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.h
> +

[...]

> +static void arm_trbe_probe_coresight_cpu(void *info)
> +{
> + struct trbe_drvdata *drvdata = info;
> + struct coresight_desc desc = { 0 };
> + int cpu = smp_processor_id();
> + struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
> + struct coresight_device *trbe_csdev = per_cpu(csdev_sink, cpu);
> + u64 trbidr = read_sysreg_s(SYS_TRBIDR_EL1);
> + struct device *dev;
> +
> + if (WARN_ON(!cpudata))
> + goto cpu_clear;

There is already a check for this in arm_trbe_probe_coresight(), we couldn't be
here if there was a problem with the allocation.

> +
> + if (trbe_csdev)
> + return;

Now that's a reason to have a WARN_ON().  If we are probing and a sink is
already present in this cpu's slot, something went seriously wrong and we should
be clear about it.

> +
> + cpudata->cpu = smp_processor_id();
> + cpudata->drvdata = drvdata;
> + dev = >drvdata->pdev->dev;
> +
> + if (!is_trbe_available()) {
> + pr_err("TRBE is not implemented on cpu %d\n", cpudata->cpu);
> + goto cpu_clear;
> + }
> +
> + if (!is_trbe_programmable(trbidr)) {
> + pr_err("TRBE is owned in higher exception level on cpu %d\n", 
> cpudata->cpu);
> + goto cpu_clear;
> + }
> + desc.name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", DRVNAME, 
> smp_processor_id());

We will end up with "arm_trbe0", "arm_trbe1" and so on in sysfs...  Is the
"arm_" part absolutely needed?  I think this should be like what we do for etmv3
and etmv4 where only "etmX" shows up in sysfs.

> + if (IS_ERR(desc.name))
> + goto cpu_clear;
> +
> + desc.type = CORESIGHT_DEV_TYPE_SINK;
> + desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM;
> + desc.ops = _trbe_cs_ops;
> + desc.pdata = dev_get_platdata(dev);
> + desc.groups = arm_trbe_groups;
> + desc.dev = dev;
> + trbe_csdev = coresight_register();
> + if (IS_ERR(trbe_csdev))
> + goto cpu_clear;
> +
> + dev_set_drvdata(_csdev->dev, cpudata);
> + cpudata->trbe_dbm = get_trbe_flag_update(trbidr);
> + 

Re: [PATCH V3 11/14] coresight: sink: Add TRBE driver

2021-02-10 Thread Mathieu Poirier
On Wed, Feb 10, 2021 at 09:42:29AM +0530, Anshuman Khandual wrote:
> 
> 
> On 2/9/21 11:09 PM, Mathieu Poirier wrote:
> > On Fri, Feb 05, 2021 at 10:53:30AM -0700, Mathieu Poirier wrote:
> >> On Wed, Jan 27, 2021 at 02:25:35PM +0530, Anshuman Khandual wrote:
> >>> Trace Buffer Extension (TRBE) implements a trace buffer per CPU which is
> >>> accessible via the system registers. The TRBE supports different 
> >>> addressing
> >>> modes including CPU virtual address and buffer modes including the 
> >>> circular
> >>> buffer mode. The TRBE buffer is addressed by a base pointer 
> >>> (TRBBASER_EL1),
> >>> an write pointer (TRBPTR_EL1) and a limit pointer (TRBLIMITR_EL1). But the
> >>> access to the trace buffer could be prohibited by a higher exception level
> >>> (EL3 or EL2), indicated by TRBIDR_EL1.P. The TRBE can also generate a CPU
> >>> private interrupt (PPI) on address translation errors and when the buffer
> >>> is full. Overall implementation here is inspired from the Arm SPE driver.
> >>>
> >>
> >> I got this message when applying the patch: 
> >>
> >> Applying: coresight: sink: Add TRBE driver
> >> .git/rebase-apply/patch:76: new blank line at EOF.
> >> +
> >> warning: 1 line adds whitespace errors.
> >>  
> >>> Cc: Mathieu Poirier 
> >>> Cc: Mike Leach 
> >>> Cc: Suzuki K Poulose 
> >>> Signed-off-by: Anshuman Khandual 
> >>> ---
> >>> Changes in V3:
> >>>
> >>> - Added new DT bindings document TRBE.yaml
> >>> - Changed TRBLIMITR_TRIG_MODE_SHIFT from 2 to 3
> >>> - Dropped isb() from trbe_reset_local()
> >>> - Dropped gap between (void *) and buf->trbe_base
> >>> - Changed 'int' to 'unsigned int' in is_trbe_available()
> >>> - Dropped unused function set_trbe_running(), set_trbe_virtual_mode(),
> >>>   set_trbe_enabled() and set_trbe_limit_pointer()
> >>> - Changed get_trbe_flag_update(), is_trbe_programmable() and
> >>>   get_trbe_address_align() to accept TRBIDR value
> >>> - Changed is_trbe_running(), is_trbe_abort(), is_trbe_wrap(), 
> >>> is_trbe_trg(),
> >>>   is_trbe_irq(), get_trbe_bsc() and get_trbe_ec() to accept TRBSR value
> >>> - Dropped snapshot mode condition in arm_trbe_alloc_buffer()
> >>> - Exit arm_trbe_init() when arm64_kernel_unmapped_at_el0() is enabled
> >>> - Compute trbe_limit before trbe_write to get the updated handle
> >>> - Added trbe_stop_and_truncate_event()
> >>> - Dropped trbe_handle_fatal()
> >>>
> >>>  Documentation/trace/coresight/coresight-trbe.rst |   39 +
> >>>  arch/arm64/include/asm/sysreg.h  |1 +
> >>>  drivers/hwtracing/coresight/Kconfig  |   11 +
> >>>  drivers/hwtracing/coresight/Makefile |1 +
> >>>  drivers/hwtracing/coresight/coresight-trbe.c | 1023 
> >>> ++
> >>>  drivers/hwtracing/coresight/coresight-trbe.h |  160 
> >>>  6 files changed, 1235 insertions(+)
> >>>  create mode 100644 Documentation/trace/coresight/coresight-trbe.rst
> >>>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.c
> >>>  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.h
> >>>

[...]

> >>> +
> >>> +static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
> >>> +{
> >>> + struct perf_output_handle **handle_ptr = dev;
> >>> + struct perf_output_handle *handle = *handle_ptr;
> >>> + enum trbe_fault_action act;
> >>> +
> >>> + WARN_ON(!is_trbe_irq(read_sysreg_s(SYS_TRBSR_EL1)));
> >>> + clr_trbe_irq();
> >>> +
> >>> + /*
> >>> +  * Ensure the trace is visible to the CPUs and
> >>> +  * any external aborts have been resolved.
> >>> +  */
> >>> + trbe_drain_buffer();
> >>> + isb();
> >>> +
> >>> + if (!perf_get_aux(handle))
> >>> + return IRQ_NONE;
> >>> +
> >>> + if (!is_perf_trbe(handle))
> >>> + return IRQ_NONE;
> >>> +
> >>> + irq_work_run();
> > 
> > There is a comment in the SPE driver about this.  Since this driver closely
> > follows that implementation it would be nice to have the comments as well.
> > Otherwise the reader has to constantly

[PATCH 2/2] Documentation: coresight: Add PID tracing description

2021-02-10 Thread Mathieu Poirier
From: Leo Yan 

After support the PID tracing for the kernel in EL1 or EL2, the usage
gets more complicated.

This patch gives description for the PMU formats of contextID configs,
this can help users to understand how to control the knobs for PID
tracing when the kernel is in different ELs.

Signed-off-by: Leo Yan 
Reviewed-by: Suzuki K Poulose 
Reviewed-by: Mike Leach 
Message-Id: <20210206150833.42120-9-leo@linaro.org>
Signed-off-by: Mathieu Poirier 
---
 Documentation/trace/coresight/coresight.rst | 32 +
 1 file changed, 32 insertions(+)

diff --git a/Documentation/trace/coresight/coresight.rst 
b/Documentation/trace/coresight/coresight.rst
index 0b73acb44efa..169749efd8d1 100644
--- a/Documentation/trace/coresight/coresight.rst
+++ b/Documentation/trace/coresight/coresight.rst
@@ -512,6 +512,38 @@ The --itrace option controls the type and frequency of 
synthesized events
 Note that only 64-bit programs are currently supported - further work is
 required to support instruction decode of 32-bit Arm programs.
 
+2.2) Tracing PID
+
+The kernel can be built to write the PID value into the PE ContextID registers.
+For a kernel running at EL1, the PID is stored in CONTEXTIDR_EL1.  A PE may
+implement Arm Virtualization Host Extensions (VHE), which the kernel can
+run at EL2 as a virtualisation host; in this case, the PID value is stored in
+CONTEXTIDR_EL2.
+
+perf provides PMU formats that program the ETM to insert these values into the
+trace data; the PMU formats are defined as below:
+
+  "contextid1": Available on both EL1 kernel and EL2 kernel.  When the
+kernel is running at EL1, "contextid1" enables the PID
+tracing; when the kernel is running at EL2, this enables
+tracing the PID of guest applications.
+
+  "contextid2": Only usable when the kernel is running at EL2.  When
+selected, enables PID tracing on EL2 kernel.
+
+  "contextid":  Will be an alias for the option that enables PID
+tracing.  I.e,
+contextid == contextid1, on EL1 kernel.
+contextid == contextid2, on EL2 kernel.
+
+perf will always enable PID tracing at the relevant EL, this is accomplished by
+automatically enable the "contextid" config - but for EL2 it is possible to 
make
+specific adjustments using configs "contextid1" and "contextid2", E.g. if a 
user
+wants to trace PIDs for both host and guest, the two configs "contextid1" and
+"contextid2" can be set at the same time:
+
+  perf record -e cs_etm/contextid1,contextid2/u -- vm
+
 
 Generating coverage files for Feedback Directed Optimization: AutoFDO
 -
-- 
2.25.1



[PATCH 1/2] coresight: etm-perf: Support PID tracing for kernel at EL2

2021-02-10 Thread Mathieu Poirier
From: Suzuki K Poulose 

When the kernel is running at EL2, the PID is stored in CONTEXTIDR_EL2.
So, tracing CONTEXTIDR_EL1 doesn't give us the pid of the process.
Thus we should trace the VMID with VMIDOPT set to trace CONTEXTIDR_EL2
instead of CONTEXTIDR_EL1.  Given that we have an existing config
option "contextid" and this will be useful for tracing virtual machines
(when we get to support virtualization).

So instead, this patch extends option CTXTID with an extra bit
ETM_OPT_CTXTID2 (bit 15), thus on an EL2 kernel, we will have another
bit available for the perf tool: ETM_OPT_CTXTID is for kernel running in
EL1, ETM_OPT_CTXTID2 is used when kernel runs in EL2 with VHE enabled.

The tool must be backward compatible for users, i.e, "contextid" today
traces PID and that should remain the same; for this purpose, the perf
tool is updated to automatically set corresponding bit for the
"contextid" config, therefore, the user doesn't have to bother which EL
the kernel is running.

  i.e, perf record -e cs_etm/contextid/u --

will always do the "pid" tracing, independent of the kernel EL.

The driver parses the format "contextid", which traces CONTEXTIDR_EL1
for ETM_OPT_CTXTID (on EL1 kernel) and traces CONTEXTIDR_EL2 for
ETM_OPT_CTXTID2 (on EL2 kernel).

Besides the enhancement for format "contexid", extra two formats are
introduced: "contextid1" and "contextid2".  This considers to support
tracing both CONTEXTIDR_EL1 and CONTEXTIDR_EL2 when the kernel is
running at EL2.  Finally, the PMU formats are defined as follow:

  "contextid1": Available on both EL1 kernel and EL2 kernel.  When the
kernel is running at EL1, "contextid1" enables the PID
tracing; when the kernel is running at EL2, this enables
tracing the PID of guest applications.

  "contextid2": Only usable when the kernel is running at EL2.  When
selected, enables PID tracing on EL2 kernel.

  "contextid":  Will be an alias for the option that enables PID
tracing.  I.e,
    contextid == contextid1, on EL1 kernel.
contextid == contextid2, on EL2 kernel.

Cc: Mathieu Poirier 
Cc: Al Grant 
Cc: Mike Leach 
Cc: Leo Yan 
Signed-off-by: Suzuki K Poulose 
[ Added two config formats: contextid1, contextid2 ]
Signed-off-by: Leo Yan 
Reviewed-by: Mike Leach 
Message-Id: <20210206150833.42120-4-leo@linaro.org>
Signed-off-by: Mathieu Poirier 
---
 .../hwtracing/coresight/coresight-etm-perf.c  | 27 ++-
 .../coresight/coresight-etm4x-core.c  | 13 +
 include/linux/coresight-pmu.h |  3 +++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c 
b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 465ef1aa8c82..0f603b4094f2 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -32,15 +32,40 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
  * now take them as general formats and apply on all ETMs.
  */
 PMU_FORMAT_ATTR(cycacc,"config:" __stringify(ETM_OPT_CYCACC));
-PMU_FORMAT_ATTR(contextid, "config:" __stringify(ETM_OPT_CTXTID));
+/* contextid1 enables tracing CONTEXTIDR_EL1 for ETMv4 */
+PMU_FORMAT_ATTR(contextid1,"config:" __stringify(ETM_OPT_CTXTID));
+/* contextid2 enables tracing CONTEXTIDR_EL2 for ETMv4 */
+PMU_FORMAT_ATTR(contextid2,"config:" __stringify(ETM_OPT_CTXTID2));
 PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS));
 PMU_FORMAT_ATTR(retstack,  "config:" __stringify(ETM_OPT_RETSTK));
 /* Sink ID - same for all ETMs */
 PMU_FORMAT_ATTR(sinkid,"config2:0-31");
 
+/*
+ * contextid always traces the "PID".  The PID is in CONTEXTIDR_EL1
+ * when the kernel is running at EL1; when the kernel is at EL2,
+ * the PID is in CONTEXTIDR_EL2.
+ */
+static ssize_t format_attr_contextid_show(struct device *dev,
+ struct device_attribute *attr,
+ char *page)
+{
+   int pid_fmt = ETM_OPT_CTXTID;
+
+#if defined(CONFIG_CORESIGHT_SOURCE_ETM4X)
+   pid_fmt = is_kernel_in_hyp_mode() ? ETM_OPT_CTXTID2 : ETM_OPT_CTXTID;
+#endif
+   return sprintf(page, "config:%d\n", pid_fmt);
+}
+
+struct device_attribute format_attr_contextid =
+   __ATTR(contextid, 0444, format_attr_contextid_show, NULL);
+
 static struct attribute *etm_config_formats_attr[] = {
_attr_cycacc.attr,
_attr_contextid.attr,
+   _attr_contextid1.attr,
+   _attr_contextid2.attr,
_attr_timestamp.attr,
_attr_retstack.attr,
_attr_sinkid.attr,
diff --git a/drivers/hwtracing/coresight/coresight-etm4

[PATCH 0/2] coresight: Patches for v5.12 (part 2)

2021-02-10 Thread Mathieu Poirier
Hi Greg,

Please see if you can add these 2 patches to your 5.12 tally.  No worries
if you think it is too close to the merge window, I'll simply queue them
for the next one.

Thanks,
Mathieu

Leo Yan (1):
  Documentation: coresight: Add PID tracing description

Suzuki K Poulose (1):
  coresight: etm-perf: Support PID tracing for kernel at EL2

 Documentation/trace/coresight/coresight.rst   | 32 +++
 .../hwtracing/coresight/coresight-etm-perf.c  | 27 +++-
 .../coresight/coresight-etm4x-core.c  | 13 
 include/linux/coresight-pmu.h |  3 ++
 4 files changed, 74 insertions(+), 1 deletion(-)

-- 
2.25.1



Re: [PATCH V3 11/14] coresight: sink: Add TRBE driver

2021-02-09 Thread Mathieu Poirier
On Fri, Feb 05, 2021 at 10:53:30AM -0700, Mathieu Poirier wrote:
> On Wed, Jan 27, 2021 at 02:25:35PM +0530, Anshuman Khandual wrote:
> > Trace Buffer Extension (TRBE) implements a trace buffer per CPU which is
> > accessible via the system registers. The TRBE supports different addressing
> > modes including CPU virtual address and buffer modes including the circular
> > buffer mode. The TRBE buffer is addressed by a base pointer (TRBBASER_EL1),
> > an write pointer (TRBPTR_EL1) and a limit pointer (TRBLIMITR_EL1). But the
> > access to the trace buffer could be prohibited by a higher exception level
> > (EL3 or EL2), indicated by TRBIDR_EL1.P. The TRBE can also generate a CPU
> > private interrupt (PPI) on address translation errors and when the buffer
> > is full. Overall implementation here is inspired from the Arm SPE driver.
> >
> 
> I got this message when applying the patch: 
> 
> Applying: coresight: sink: Add TRBE driver
> .git/rebase-apply/patch:76: new blank line at EOF.
> +
> warning: 1 line adds whitespace errors.
>  
> > Cc: Mathieu Poirier 
> > Cc: Mike Leach 
> > Cc: Suzuki K Poulose 
> > Signed-off-by: Anshuman Khandual 
> > ---
> > Changes in V3:
> > 
> > - Added new DT bindings document TRBE.yaml
> > - Changed TRBLIMITR_TRIG_MODE_SHIFT from 2 to 3
> > - Dropped isb() from trbe_reset_local()
> > - Dropped gap between (void *) and buf->trbe_base
> > - Changed 'int' to 'unsigned int' in is_trbe_available()
> > - Dropped unused function set_trbe_running(), set_trbe_virtual_mode(),
> >   set_trbe_enabled() and set_trbe_limit_pointer()
> > - Changed get_trbe_flag_update(), is_trbe_programmable() and
> >   get_trbe_address_align() to accept TRBIDR value
> > - Changed is_trbe_running(), is_trbe_abort(), is_trbe_wrap(), is_trbe_trg(),
> >   is_trbe_irq(), get_trbe_bsc() and get_trbe_ec() to accept TRBSR value
> > - Dropped snapshot mode condition in arm_trbe_alloc_buffer()
> > - Exit arm_trbe_init() when arm64_kernel_unmapped_at_el0() is enabled
> > - Compute trbe_limit before trbe_write to get the updated handle
> > - Added trbe_stop_and_truncate_event()
> > - Dropped trbe_handle_fatal()
> > 
> >  Documentation/trace/coresight/coresight-trbe.rst |   39 +
> >  arch/arm64/include/asm/sysreg.h  |1 +
> >  drivers/hwtracing/coresight/Kconfig  |   11 +
> >  drivers/hwtracing/coresight/Makefile |1 +
> >  drivers/hwtracing/coresight/coresight-trbe.c | 1023 
> > ++
> >  drivers/hwtracing/coresight/coresight-trbe.h |  160 
> >  6 files changed, 1235 insertions(+)
> >  create mode 100644 Documentation/trace/coresight/coresight-trbe.rst
> >  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.c
> >  create mode 100644 drivers/hwtracing/coresight/coresight-trbe.h
> > 
> > diff --git a/Documentation/trace/coresight/coresight-trbe.rst 
> > b/Documentation/trace/coresight/coresight-trbe.rst
> > new file mode 100644
> > index 000..1cbb819
> > --- /dev/null
> > +++ b/Documentation/trace/coresight/coresight-trbe.rst
> > @@ -0,0 +1,39 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +==
> > +Trace Buffer Extension (TRBE).
> > +==
> > +
> > +:Author:   Anshuman Khandual 
> > +:Date: November 2020
> > +
> > +Hardware Description
> > +
> > +
> > +Trace Buffer Extension (TRBE) is a percpu hardware which captures in system
> > +memory, CPU traces generated from a corresponding percpu tracing unit. This
> > +gets plugged in as a coresight sink device because the corresponding trace
> > +genarators (ETE), are plugged in as source device.
> > +
> > +The TRBE is not compliant to CoreSight architecture specifications, but is
> > +driven via the CoreSight driver framework to support the ETE (which is
> > +CoreSight compliant) integration.
> > +
> > +Sysfs files and directories
> > +---
> > +
> > +The TRBE devices appear on the existing coresight bus alongside the other
> > +coresight devices::
> > +
> > +   >$ ls /sys/bus/coresight/devices
> > +   trbe0  trbe1  trbe2 trbe3
> > +
> > +The ``trbe`` named TRBEs are associated with a CPU.::
> > +
> > +   >$ ls /sys/bus/coresight/devices/trbe0/
> > +align dbm
> > +
> > +*Key file items are:-*
> > +   * ``align``: TRBE write pointer alignment
> > +   * ``dbm``: TRBE updates memo

Re: [PATCH v4 00/17] remoteproc: Add support for detaching a rproc

2021-02-08 Thread Mathieu Poirier
On Wed, Feb 03, 2021 at 08:58:15AM +0100, Arnaud POULIQUEN wrote:
> 
> 
> On 2/2/21 11:42 PM, Mathieu Poirier wrote:
> > On Tue, Feb 02, 2021 at 09:54:13AM +0100, Arnaud POULIQUEN wrote:
> >>
> >>
> >> On 2/2/21 1:49 AM, Mathieu Poirier wrote:
> >>> On Wed, Jan 27, 2021 at 10:21:24AM +0100, Arnaud POULIQUEN wrote:
> >>>> Hi Mathieu
> >>>>
> >>>> On 12/18/20 6:32 PM, Mathieu Poirier wrote:
> >>>>> Following the work done here [1], this set provides support for the
> >>>>> remoteproc core to release resources associated with a remote processor
> >>>>> without having to switch it off. That way a platform driver can be 
> >>>>> removed
> >>>>> or the application processor power cycled while the remote processor is
> >>>>> still operating.
> >>>>>
> >>>>> Of special interest in this series are patches 5 and 6 where getting the
> >>>>> address of the resource table installed by an eternal entity if moved to
> >>>>> the core.  This is to support scenarios where a remote process has been
> >>>>> booted by the core but is being detached.  To re-attach the remote
> >>>>> processor, the address of the resource table needs to be known at a 
> >>>>> later
> >>>>> time than the platform driver's probe() function.
> >>>>>
> >>>>> Applies cleanly on v5.10
> >>>>>
> >>>>> Thanks,
> >>>>> Mathieu
> >>>>>
> >>>>> [1]. https://lkml.org/lkml/2020/7/14/1600
> >>>>>
> >>>>> 
> >>>>> New for v4:
> >>>>> - Made binding description OS agnostic (Rob)
> >>>>> - Added functionality to set the external resource table in the core
> >>>>> - Fixed a crash when detaching (Arnaud)
> >>>>> - Fixed error code propagation in rproc_cdev_relase() and rproc_del() 
> >>>>> (Arnaud)
> >>>>> - Added RB tags
> >>>>
> >>>>
> >>>> I tested you series, attach and  detach is working well.
> >>>>
> >>>> Then I faced issue when tried to re-attach after a detach.
> >>>>
> >>>
> >>> Right, in this case don't expect the re-attach to work properly because 
> >>> function
> >>> stm32_rproc_detach() does not exist.  As such the M4 doesn't put itself 
> >>> back
> >>> in "wait-for-attach" mode as it does when booted by the boot loader.  If I
> >>> remember correctly we talked about that during an earlier conversation 
> >>> and we
> >>> agreed FW support would be needed to properly test the re-attach.
> >>
> >> Yes you are right the remote firmware needs to be inform about the detach, 
> >> and
> >> this is the purpose of the detach ops.
> >> But also some actions are missing on local side as some resources have 
> >> also to
> >> be reinitialized as described in my previous mail.
> >> For instance the resource table is handled by the remoteproc framework. The
> >> remote firmware should only have a read access to this table.
> >>
> >>>  
> >>>> But I don't know if this feature has to be supported in this step.
> >>>>
> >>>> The 2 issues I found are:
> >>>>
> >>>> 1) memory carveouts are released on detach so need to be reinitialized.
> >>>> The use of prepare/unprepare for the attach and detach would solve the 
> >>>> issue but
> >>>> probably need to add parameter to differentiate a start/stop from a 
> >>>> attach/detach.
> > 
> > I am in agreement with you assesment and the patch you have proposed to fix 
> > it.
> > Right now carveouts are properly handled between start and stop operations
> > because their parsing and allocation is done as part for ops:parse_fw(), 
> > which
> > is called for each iteration.  Moving the parsing and allocation to
> > rproc_prepare_device() ends up doing the same thing.
> > 
> > I am not sure we absolutely need an extra parameter to differentiate between
> > start/stop and attach/detach.  Typically the rproc_prepare_device() is used 
> > to
> > do some kind of setup like providing power to a memory bank.  I suppose 
> > that if
> > a memory bank is already powere

<    1   2   3   4   5   6   7   8   9   10   >