[PATCH 05/10] remoteproc: uclass: Add remoteproc resource handling helpers

Simon Glass sjg at chromium.org
Fri Sep 24 04:49:27 CEST 2021


Hi Amjad,

On Thu, 23 Sept 2021 at 10:47, Amjad Ouled-Ameur
<aouledameur at baylibre.com> wrote:
>
> From: Keerthy <j-keerthy at ti.com>
>
> Add remoteproc resource handling helpers. These functions
> are primarily to parse the resource table and to handle
> different types of resources. Carveout, devmem, trace &
> vring resources are handled.
>
> Signed-off-by: Keerthy <j-keerthy at ti.com>
> [Amjad: fix redefinition of "struct resource_table" and compile warnings ]
> Signed-off-by: Amjad Ouled-Ameur <aouledameur at baylibre.com>
> ---
>
>  drivers/remoteproc/rproc-uclass.c | 562 ++++++++++++++++++++++++++++++
>  include/remoteproc.h              | 384 +++++++++++++++++++-
>  2 files changed, 945 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c
> index 64c47c1e7225..3f7096045548 100644
> --- a/drivers/remoteproc/rproc-uclass.c
> +++ b/drivers/remoteproc/rproc-uclass.c
> @@ -8,6 +8,7 @@
>
>  #define pr_fmt(fmt) "%s: " fmt, __func__
>  #include <common.h>
> +#include <elf.h>
>  #include <errno.h>
>  #include <fdtdec.h>
>  #include <log.h>
> @@ -19,9 +20,21 @@
>  #include <dm.h>
>  #include <dm/uclass.h>
>  #include <dm/uclass-internal.h>
> +#include <linux/compat.h>
>
>  DECLARE_GLOBAL_DATA_PTR;
>
> +struct resource_table {
> +       u32 ver;
> +       u32 num;
> +       u32 reserved[2];
> +       u32 offset[0];
> +} __packed;
> +
> +typedef int (*handle_resource_t) (struct udevice *, void *, int offset, int avail);
> +
> +static struct resource_table *rsc_table;
> +
>  /**
>   * for_each_remoteproc_device() - iterate through the list of rproc devices
>   * @fn: check function to call per match, if this function returns fail,
> @@ -208,6 +221,86 @@ static int rproc_post_probe(struct udevice *dev)
>         return 0;
>  }
>
> +/**
> + * rproc_add_res() - After parsing the resource table add the mappings
> + * @dev:       device we finished probing
> + * @mapping: rproc_mem_entry for the resource
> + *
> + * Return: if the remote proc driver has a add_res routine, invokes it and
> + * hands over the return value. overall, 0 if all went well, else appropriate
> + * error value.
> + */
> +static int rproc_add_res(struct udevice *dev, struct rproc_mem_entry *mapping)
> +{
> +       const struct dm_rproc_ops *ops;
> +
> +       ops = rproc_get_ops(dev);
> +       if (!ops) {
> +               debug("%s driver has no ops?\n", dev->name);
> +               return -EINVAL;
> +       }

Please don't check this as it just bloats the code. The ops must be
provided. Please fix throughout.

> +
> +       if (ops->add_res)
> +               return ops->add_res(dev, mapping);

Don't you want to return -ENOSYS if there is no method here?

> +
> +       return 0;
> +}
> +
> +/**
> + * rproc_alloc_mem() - After parsing the resource table allocat mem
> + * @dev:       device we finished probing
> + * @len: rproc_mem_entry for the resource
> + * @align: alignment for the resource
> + *
> + * Return: if the remote proc driver has a add_res routine, invokes it and
> + * hands over the return value. overall, 0 if all went well, else appropriate
> + * error value.
> + */
> +static void *rproc_alloc_mem(struct udevice *dev, unsigned long len,
> +                            unsigned long align)
> +{
> +       const struct dm_rproc_ops *ops;
> +
> +       ops = rproc_get_ops(dev);
> +       if (!ops) {
> +               debug("%s driver has no ops?\n", dev->name);
> +               return NULL;
> +       }
> +
> +       if (ops->alloc_mem)
> +               return ops->alloc_mem(dev, len, align);
> +
> +       return NULL;
> +}
> +
> +/**
> + * rproc_config_pagetable() - Configure page table for remote processor
> + * @dev:       device we finished probing
> + * @virt: Virtual address of the resource
> + * @phys: Physical address the resource
> + * @len: length the resource
> + *
> + * Return: if the remote proc driver has a add_res routine, invokes it and
> + * hands over the return value. overall, 0 if all went well, else appropriate
> + * error value.
> + */
> +static int rproc_config_pagetable(struct udevice *dev, unsigned int virt,
> +                                 unsigned int phys, unsigned int len)
> +{
> +       const struct dm_rproc_ops *ops;
> +
> +       ops = rproc_get_ops(dev);
> +       if (!ops) {
> +               debug("%s driver has no ops?\n", dev->name);
> +               return -EINVAL;
> +       }
> +
> +       if (ops->config_pagetable)
> +               return ops->config_pagetable(dev, virt, phys, len);
> +
> +       return 0;
> +}
> +
>  UCLASS_DRIVER(rproc) = {
>         .id = UCLASS_REMOTEPROC,
>         .name = "remoteproc",
> @@ -438,3 +531,472 @@ int rproc_is_running(int id)
>  {
>         return _rproc_ops_wrapper(id, RPROC_RUNNING);
>  };
> +
> +/*
> + * Virtio ring descriptors: 16 bytes.  These can chain together via
> + * "next".

What is this code doing in the uclass:

> + */
> +struct vring_desc {
> +       u64 addr;
> +       u32 len;
> +       u16 flags;
> +       u16 next;
> +};
> +
> +/*
> + * u32 is used here for ids for padding reasons.
> + */
> +struct vring_used_elem {
> +       u32 id;
> +       u32 len;
> +};
> +
> +static unsigned int vring_size(unsigned int num, unsigned long align)
> +{
> +       return ((sizeof(struct vring_desc) * num + sizeof(u16) * (3 + num)
> +                + align - 1) & ~(align - 1))
> +           + sizeof(u16) * 3 + sizeof(struct vring_used_elem) * num;
> +}
> +

[..]

Regards,
Simon


More information about the U-Boot mailing list