Message ID | 1427917039-43206-3-git-send-email-d-gerlach@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Dave, On Wed, Apr 1, 2015 at 10:37 PM, Dave Gerlach <d-gerlach@ti.com> wrote: > From: Suman Anna <s-anna@ti.com> > > The rproc_da_to_va API is currently used to perform any device to > kernel address translations to meet the different needs of the remoteproc > core/drivers (eg: loading). The functionality is achieved within the > remoteproc core, and is limited only for carveouts allocated within the > core. > > A new rproc ops, da_to_va, is added to provide flexibility to platform > implementations to perform the address translation themselves when the > above conditions cannot be met by the implementations. The rproc_da_to_va() > API is extended to invoke this ops if present, and fallback to regular > processing if the platform implementation cannot provide the translation. > This will allow any remoteproc implementations to translate addresses for > dedicated memories like internal memories. Can you please provide specific examples where this is needed and how it is going to be used? Thanks, Ohad.
Hi Ohad, On 05/09/2015 02:54 AM, Ohad Ben-Cohen wrote: > Hi Dave, > > On Wed, Apr 1, 2015 at 10:37 PM, Dave Gerlach <d-gerlach@ti.com> wrote: >> From: Suman Anna <s-anna@ti.com> >> >> The rproc_da_to_va API is currently used to perform any device to >> kernel address translations to meet the different needs of the remoteproc >> core/drivers (eg: loading). The functionality is achieved within the >> remoteproc core, and is limited only for carveouts allocated within the >> core. >> >> A new rproc ops, da_to_va, is added to provide flexibility to platform >> implementations to perform the address translation themselves when the >> above conditions cannot be met by the implementations. The rproc_da_to_va() >> API is extended to invoke this ops if present, and fallback to regular >> processing if the platform implementation cannot provide the translation. >> This will allow any remoteproc implementations to translate addresses for >> dedicated memories like internal memories. > > Can you please provide specific examples where this is needed and how > it is going to be used? We will be using this for the WkupM3 remoteproc driver, and also using it for a PRUSS remoteproc driver (on downstream kernel for now) on TI AM335x/AM437x SoCs. The driver uses a firmware where all segments are placed only in internal RAMs (nothing in DDR), and we use the remoteproc core's ELF loader code to perform the loading. We need a way for the remoteproc elf loader core to be able to translate these device addresses into a kernel mapped addresses so that the loader code can copy the firmware segments. The previous attempt on this was to use a new resource type through the resource table, whereby we are publishing and storing the internal memory translations were stored in the remoteproc core [1]. regards Suman [1] https://patchwork.kernel.org/patch/5602981/
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 5a6c192..f1efe62 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -159,28 +159,46 @@ static void rproc_disable_iommu(struct rproc *rproc) return; } -/* +/** + * rproc_da_to_va() - lookup the kernel virtual address for a remoteproc address + * @rproc: handle of a remote processor + * @da: remoteproc device address to translate + * @len: length of the memory region @da is pointing to + * * Some remote processors will ask us to allocate them physically contiguous * memory regions (which we call "carveouts"), and map them to specific - * device addresses (which are hardcoded in the firmware). + * device addresses (which are hardcoded in the firmware). They may also have + * dedicated memory regions internal to the processors, and use them either + * exclusively or alongside carveouts. * * They may then ask us to copy objects into specific device addresses (e.g. * code/data sections) or expose us certain symbols in other device address * (e.g. their trace buffer). * - * This function is an internal helper with which we can go over the allocated - * carveouts and translate specific device address to kernel virtual addresses - * so we can access the referenced memory. + * This function is a helper function with which we can go over the allocated + * carveouts and translate specific device addresses to kernel virtual addresses + * so we can access the referenced memory. This function also allows to perform + * translations on the internal remoteproc memory regions through a platform + * implementation specific da_to_va ops, if present. + * + * The function returns a valid kernel address on success or NULL on failure. * * Note: phys_to_virt(iommu_iova_to_phys(rproc->domain, da)) will work too, * but only on kernel direct mapped RAM memory. Instead, we're just using - * here the output of the DMA API, which should be more correct. + * here the output of the DMA API for the carveouts, which should be more + * correct. */ void *rproc_da_to_va(struct rproc *rproc, u64 da, int len) { struct rproc_mem_entry *carveout; void *ptr = NULL; + if (rproc->ops->da_to_va) { + ptr = rproc->ops->da_to_va(rproc, da, len); + if (ptr) + goto out; + } + list_for_each_entry(carveout, &rproc->carveouts, node) { int offset = da - carveout->da; @@ -197,6 +215,7 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, int len) break; } +out: return ptr; } EXPORT_SYMBOL(rproc_da_to_va); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 0c7d403..81b224d 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -331,11 +331,13 @@ struct rproc; * @start: power on the device and boot it * @stop: power off the device * @kick: kick a virtqueue (virtqueue id given as a parameter) + * @da_to_va: optional platform hook to perform address translations */ struct rproc_ops { int (*start)(struct rproc *rproc); int (*stop)(struct rproc *rproc); void (*kick)(struct rproc *rproc, int vqid); + void * (*da_to_va)(struct rproc *rproc, u64 da, int len); }; /**