summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: fe20d9e)
raw | patch | inline | side by side (parent: fe20d9e)
author | Suman Anna <s-anna@ti.com> | |
Sat, 23 Feb 2019 17:42:06 +0000 (11:42 -0600) | ||
committer | Suman Anna <s-anna@ti.com> | |
Sun, 24 Feb 2019 01:20:48 +0000 (19:20 -0600) |
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/platform drivers (eg: loading). The function also
invokes the da_to_va ops, if present, to allow the remoteproc
platform drivers to provide address translation. However, not all
platform implementations have linear address spaces, and may need
an additional parameter to be able to perform proper translations.
The rproc_da_to_va() API and the rproc .da_to_va ops have therefore
been expanded to take in an additional flags field enabling some
remoteproc implementations (like the TI PRUSS remoteproc driver)
to use these flags. Also, define some semantics for this flags
argument as this can vary from one implementation to another. A
new flags type is encoded into the upper 16 bits along side the
actual value in the lower 16-bits for the flags argument, to
allow different individual implementations to have better
flexibility in interpreting the flags as per their needs.
Also, update the various remoteproc implementations that use the
.da_to_va() ops for the new signature.
Signed-off-by: Suman Anna <s-anna@ti.com>
to kernel address translations to meet the different needs of the
remoteproc core/platform drivers (eg: loading). The function also
invokes the da_to_va ops, if present, to allow the remoteproc
platform drivers to provide address translation. However, not all
platform implementations have linear address spaces, and may need
an additional parameter to be able to perform proper translations.
The rproc_da_to_va() API and the rproc .da_to_va ops have therefore
been expanded to take in an additional flags field enabling some
remoteproc implementations (like the TI PRUSS remoteproc driver)
to use these flags. Also, define some semantics for this flags
argument as this can vary from one implementation to another. A
new flags type is encoded into the upper 16 bits along side the
actual value in the lower 16-bits for the flags argument, to
allow different individual implementations to have better
flexibility in interpreting the flags as per their needs.
Also, update the various remoteproc implementations that use the
.da_to_va() ops for the new signature.
Signed-off-by: Suman Anna <s-anna@ti.com>
index 54c07fd3f2042efdbf60d6a1feb6d891af0a76ee..14d7f15a7c26b9cef87a229379ceecc8e74fbe66 100644 (file)
return -ENOENT;
}
-static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
{
struct imx_rproc *priv = rproc->priv;
void *va = NULL;
index fcba914713a0bbd1863f6938818aefe2a65fc378..0565f6ee41fec06e821b6baa1ffa4666579263a3 100644 (file)
}
}
-static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, int len);
+static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, int len,
+ u32 flags);
/* uio handler dealing with userspace controlled exception interrupt */
static irqreturn_t keystone_rproc_uio_handler(int irq, struct uio_info *uio)
if (!ksproc->rsc_table_size || !ksproc->rsc_table)
return -EINVAL;
- ptr = keystone_rproc_da_to_va(rproc, dma_addr, ksproc->rsc_table_size);
+ ptr = keystone_rproc_da_to_va(rproc, dma_addr, ksproc->rsc_table_size,
+ RPROC_FLAGS_NONE);
if (!ptr)
return -EINVAL;
* can be used either by the remoteproc core for loading (when using kernel
* remoteproc loader), or by any rpmsg bus drivers.
*/
-static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, int len,
+ u32 flags)
{
struct keystone_rproc *ksproc = rproc->priv;
void __iomem *va = NULL;
index d4339a6da616ecfa9d201ca38cece5ee35e7696b..458fc64101a5ae1b4d795ad287af70b801fb3db3 100644 (file)
return ret;
}
-static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len)
+static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
{
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
int offset;
index d7a4b9eca5d25bc6d7d37257f23bb424bc45541e..beeaa5b3b4873a77170cd8f306715ba02d086a57 100644 (file)
return 0;
}
-static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len)
+static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
{
struct q6v5 *qproc = rproc->priv;
int offset;
index f93e1e4a1cc081a987014da52d0460ea454b06d1..5b4d4c662b7b3ac1c7d357b27bfc212fee39e969 100644 (file)
return 0;
}
-static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da, int len)
+static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
{
struct q6v5_wcss *wcss = rproc->priv;
int offset;
index b0e07e9f42d5698e64baa7897d75460c28a89690..eb7d4b9f0e03e4dfb0f4fdc514e867fb9939f942 100644 (file)
return ret;
}
-static void *wcnss_da_to_va(struct rproc *rproc, u64 da, int len)
+static void *wcnss_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
{
struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv;
int offset;
index 48e6b5864d741be1277f2032cdc24947f2172f17..89580b957d66239ecdbde266ea4996c670965a50 100644 (file)
* @rproc: handle of a remote processor
* @da: remoteproc device address to translate
* @len: length of the memory region @da is pointing to
+ * @flags: flags to pass onto platform implementations for aiding translations
*
* Some remote processors will ask us to allocate them physically contiguous
* memory regions (which we call "carveouts"), and map them to specific
* 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.
+ * implementation specific da_to_va ops, if present. The @flags field is passed
+ * onto these ops to aid the translation within the ops implementation. The
+ * @flags field is to be passed as a combination of the RPROC_FLAGS_xxx type
+ * and the pertinent flags value for that type.
*
* The function returns a valid kernel address on success or NULL on failure.
*
* 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)
+void *rproc_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
{
struct rproc_mem_entry *carveout;
void *ptr = NULL;
if (rproc->ops->da_to_va) {
- ptr = rproc->ops->da_to_va(rproc, da, len);
+ ptr = rproc->ops->da_to_va(rproc, da, len, flags);
if (ptr)
goto out;
}
}
/* what's the kernel address of this resource ? */
- ptr = rproc_da_to_va(rproc, rsc->da, rsc->len);
+ ptr = rproc_da_to_va(rproc, rsc->da, rsc->len, RPROC_FLAGS_NONE);
if (!ptr) {
dev_err(dev, "erroneous trace resource entry\n");
return -EINVAL;
phdr->p_flags = PF_R | PF_W | PF_X;
phdr->p_align = 0;
- ptr = rproc_da_to_va(rproc, segment->da, segment->size);
+ ptr = rproc_da_to_va(rproc, segment->da, segment->size,
+ RPROC_FLAGS_NONE);
if (!ptr) {
dev_err(&rproc->dev,
"invalid coredump segment (%pad, %zu)\n",
diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index b17d72ec8603bca2b1a6481c2e3d70c37537cbfd..fff2e0b4685e35a9d96cbf5ae10d42a21814951a 100644 (file)
}
/* grab the kernel address for this device address */
- ptr = rproc_da_to_va(rproc, da, memsz);
+ ptr = rproc_da_to_va(rproc, da, memsz,
+ RPROC_FLAGS_ELF_PHDR | phdr->p_flags);
if (!ptr) {
dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz);
ret = -EINVAL;
if (!shdr)
return NULL;
- return rproc_da_to_va(rproc, shdr->sh_addr, shdr->sh_size);
+ return rproc_da_to_va(rproc, shdr->sh_addr, shdr->sh_size,
+ RPROC_FLAGS_ELF_SHDR | shdr->sh_flags);
}
EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table);
index d711d9430a4ffe2392c3a8af265e1b5d27ccf3a9..c41e58c7f9bdfaa396632aa160703a1861d78a9c 100644 (file)
return 0;
}
-static void *slim_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+static void *slim_rproc_da_to_va(struct rproc *rproc, u64 da, int len,
+ u32 flags)
{
struct st_slim_rproc *slim_rproc = rproc->priv;
void *va = NULL;
index 51efe2c7d2bf734ad2948f6b3992bb418be9f666..6257b1507a16579b8c728c1650875dc78bec1fc7 100644 (file)
return 0;
}
-static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, int len,
+ u32 flags)
{
struct wkup_m3_rproc *wkupm3 = rproc->priv;
void *va = NULL;
index 3dba367a379da8a5da8963385e24150187874284..e0baae1659c2ac3a20753b7db9e652bad99f29bb 100644 (file)
#include <linux/completion.h>
#include <linux/idr.h>
#include <linux/of.h>
+#include <linux/bitops.h>
/**
* struct resource_table - firmware resource table header
struct rproc;
struct firmware;
+/*
+ * Macros to use with flags field in rproc_da_to_va API. Use
+ * the upper 16 bits to dictate the flags type and the lower
+ * 16 bits to pass on the value of the flags pertinent to that
+ * type.
+ *
+ * Add any new flags type at a new bit-field position
+ */
+#define RPROC_FLAGS_SHIFT 16
+#define RPROC_FLAGS_NONE 0
+#define RPROC_FLAGS_ELF_PHDR BIT(0 + RPROC_FLAGS_SHIFT)
+#define RPROC_FLAGS_ELF_SHDR BIT(1 + RPROC_FLAGS_SHIFT)
+
/**
* struct rproc_ops - platform-specific device handlers
* @start: power on the device and boot it
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);
+ void * (*da_to_va)(struct rproc *rproc, u64 da, int len, u32 flags);
int (*parse_fw)(struct rproc *rproc, const struct firmware *fw);
struct resource_table *(*find_loaded_rsc_table)(
struct rproc *rproc, const struct firmware *fw);
void rproc_shutdown(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_da_to_va(struct rproc *rproc, u64 da, int len);
+void *rproc_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags);
int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size);
int rproc_get_id(struct rproc *rproc);
int rproc_pa_to_da(struct rproc *rproc, phys_addr_t pa, u64 *da);