Commit 40df0a91 authored by Peng Fan's avatar Peng Fan Committed by Bjorn Andersson

remoteproc: add is_iomem to da_to_va

Introduce an extra parameter is_iomem to da_to_va, then the caller
could take the memory as normal memory or io mapped memory.
Reviewed-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Signed-off-by: default avatarPeng Fan <peng.fan@nxp.com>
Link: https://lore.kernel.org/r/1615029865-23312-5-git-send-email-peng.fan@oss.nxp.comSigned-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 2cfc056e
...@@ -208,7 +208,7 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da, ...@@ -208,7 +208,7 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
return -ENOENT; return -ENOENT;
} }
static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct imx_rproc *priv = rproc->priv; struct imx_rproc *priv = rproc->priv;
void *va = NULL; void *va = NULL;
......
...@@ -121,7 +121,7 @@ static void ingenic_rproc_kick(struct rproc *rproc, int vqid) ...@@ -121,7 +121,7 @@ static void ingenic_rproc_kick(struct rproc *rproc, int vqid)
writel(vqid, vpu->aux_base + REG_CORE_MSG); writel(vqid, vpu->aux_base + REG_CORE_MSG);
} }
static void *ingenic_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *ingenic_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct vpu *vpu = rproc->priv; struct vpu *vpu = rproc->priv;
void __iomem *va = NULL; void __iomem *va = NULL;
......
...@@ -246,7 +246,7 @@ static void keystone_rproc_kick(struct rproc *rproc, int vqid) ...@@ -246,7 +246,7 @@ static void keystone_rproc_kick(struct rproc *rproc, int vqid)
* can be used either by the remoteproc core for loading (when using kernel * can be used either by the remoteproc core for loading (when using kernel
* remoteproc loader), or by any rpmsg bus drivers. * remoteproc loader), or by any rpmsg bus drivers.
*/ */
static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct keystone_rproc *ksproc = rproc->priv; struct keystone_rproc *ksproc = rproc->priv;
void __iomem *va = NULL; void __iomem *va = NULL;
......
...@@ -272,7 +272,7 @@ static int scp_elf_load_segments(struct rproc *rproc, const struct firmware *fw) ...@@ -272,7 +272,7 @@ static int scp_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
} }
/* grab the kernel address for this device address */ /* grab the kernel address for this device address */
ptr = (void __iomem *)rproc_da_to_va(rproc, da, memsz); ptr = (void __iomem *)rproc_da_to_va(rproc, da, memsz, NULL);
if (!ptr) { if (!ptr) {
dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz); dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz);
ret = -EINVAL; ret = -EINVAL;
...@@ -509,7 +509,7 @@ static void *mt8192_scp_da_to_va(struct mtk_scp *scp, u64 da, size_t len) ...@@ -509,7 +509,7 @@ static void *mt8192_scp_da_to_va(struct mtk_scp *scp, u64 da, size_t len)
return NULL; return NULL;
} }
static void *scp_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *scp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct mtk_scp *scp = (struct mtk_scp *)rproc->priv; struct mtk_scp *scp = (struct mtk_scp *)rproc->priv;
...@@ -627,7 +627,7 @@ void *scp_mapping_dm_addr(struct mtk_scp *scp, u32 mem_addr) ...@@ -627,7 +627,7 @@ void *scp_mapping_dm_addr(struct mtk_scp *scp, u32 mem_addr)
{ {
void *ptr; void *ptr;
ptr = scp_da_to_va(scp->rproc, mem_addr, 0); ptr = scp_da_to_va(scp->rproc, mem_addr, 0, NULL);
if (!ptr) if (!ptr)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
......
...@@ -728,7 +728,7 @@ static int omap_rproc_stop(struct rproc *rproc) ...@@ -728,7 +728,7 @@ static int omap_rproc_stop(struct rproc *rproc)
* Return: translated virtual address in kernel memory space on success, * Return: translated virtual address in kernel memory space on success,
* or NULL on failure. * or NULL on failure.
*/ */
static void *omap_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *omap_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct omap_rproc *oproc = rproc->priv; struct omap_rproc *oproc = rproc->priv;
int i; int i;
......
...@@ -465,7 +465,7 @@ static void *pru_i_da_to_va(struct pru_rproc *pru, u32 da, size_t len) ...@@ -465,7 +465,7 @@ static void *pru_i_da_to_va(struct pru_rproc *pru, u32 da, size_t len)
* core for any PRU client drivers. The PRU Instruction RAM access is restricted * core for any PRU client drivers. The PRU Instruction RAM access is restricted
* only to the PRU loader code. * only to the PRU loader code.
*/ */
static void *pru_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *pru_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct pru_rproc *pru = rproc->priv; struct pru_rproc *pru = rproc->priv;
......
...@@ -281,7 +281,7 @@ static int adsp_stop(struct rproc *rproc) ...@@ -281,7 +281,7 @@ static int adsp_stop(struct rproc *rproc)
return ret; return ret;
} }
static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
int offset; int offset;
......
...@@ -242,7 +242,7 @@ static int adsp_stop(struct rproc *rproc) ...@@ -242,7 +242,7 @@ static int adsp_stop(struct rproc *rproc)
return ret; return ret;
} }
static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
int offset; int offset;
......
...@@ -410,7 +410,7 @@ static int q6v5_wcss_stop(struct rproc *rproc) ...@@ -410,7 +410,7 @@ static int q6v5_wcss_stop(struct rproc *rproc)
return 0; return 0;
} }
static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct q6v5_wcss *wcss = rproc->priv; struct q6v5_wcss *wcss = rproc->priv;
int offset; int offset;
......
...@@ -320,7 +320,7 @@ static int wcnss_stop(struct rproc *rproc) ...@@ -320,7 +320,7 @@ static int wcnss_stop(struct rproc *rproc)
return ret; return ret;
} }
static void *wcnss_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *wcnss_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv; struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv;
int offset; int offset;
......
...@@ -189,13 +189,13 @@ EXPORT_SYMBOL(rproc_va_to_pa); ...@@ -189,13 +189,13 @@ EXPORT_SYMBOL(rproc_va_to_pa);
* here the output of the DMA API for the carveouts, which should be more * here the output of the DMA API for the carveouts, which should be more
* correct. * correct.
*/ */
void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct rproc_mem_entry *carveout; struct rproc_mem_entry *carveout;
void *ptr = NULL; void *ptr = NULL;
if (rproc->ops->da_to_va) { if (rproc->ops->da_to_va) {
ptr = rproc->ops->da_to_va(rproc, da, len); ptr = rproc->ops->da_to_va(rproc, da, len, is_iomem);
if (ptr) if (ptr)
goto out; goto out;
} }
...@@ -217,6 +217,9 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) ...@@ -217,6 +217,9 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len)
ptr = carveout->va + offset; ptr = carveout->va + offset;
if (is_iomem)
*is_iomem = carveout->is_iomem;
break; break;
} }
......
...@@ -153,17 +153,21 @@ static void rproc_copy_segment(struct rproc *rproc, void *dest, ...@@ -153,17 +153,21 @@ static void rproc_copy_segment(struct rproc *rproc, void *dest,
size_t offset, size_t size) size_t offset, size_t size)
{ {
void *ptr; void *ptr;
bool is_iomem;
if (segment->dump) { if (segment->dump) {
segment->dump(rproc, segment, dest, offset, size); segment->dump(rproc, segment, dest, offset, size);
} else { } else {
ptr = rproc_da_to_va(rproc, segment->da + offset, size); ptr = rproc_da_to_va(rproc, segment->da + offset, size, &is_iomem);
if (!ptr) { if (!ptr) {
dev_err(&rproc->dev, dev_err(&rproc->dev,
"invalid copy request for segment %pad with offset %zu and size %zu)\n", "invalid copy request for segment %pad with offset %zu and size %zu)\n",
&segment->da, offset, size); &segment->da, offset, size);
memset(dest, 0xff, size); memset(dest, 0xff, size);
} else { } else {
if (is_iomem)
memcpy_fromio(dest, ptr, size);
else
memcpy(dest, ptr, size); memcpy(dest, ptr, size);
} }
} }
......
...@@ -132,7 +132,7 @@ static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf, ...@@ -132,7 +132,7 @@ static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf,
char buf[100]; char buf[100];
int len; int len;
va = rproc_da_to_va(data->rproc, trace->da, trace->len); va = rproc_da_to_va(data->rproc, trace->da, trace->len, NULL);
if (!va) { if (!va) {
len = scnprintf(buf, sizeof(buf), "Trace %s not available\n", len = scnprintf(buf, sizeof(buf), "Trace %s not available\n",
......
...@@ -175,6 +175,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) ...@@ -175,6 +175,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
u64 offset = elf_phdr_get_p_offset(class, phdr); u64 offset = elf_phdr_get_p_offset(class, phdr);
u32 type = elf_phdr_get_p_type(class, phdr); u32 type = elf_phdr_get_p_type(class, phdr);
void *ptr; void *ptr;
bool is_iomem;
if (type != PT_LOAD) if (type != PT_LOAD)
continue; continue;
...@@ -204,7 +205,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) ...@@ -204,7 +205,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
} }
/* grab the kernel address for this device address */ /* grab the kernel address for this device address */
ptr = rproc_da_to_va(rproc, da, memsz); ptr = rproc_da_to_va(rproc, da, memsz, &is_iomem);
if (!ptr) { if (!ptr) {
dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da, dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da,
memsz); memsz);
...@@ -213,8 +214,12 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) ...@@ -213,8 +214,12 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
} }
/* put the segment where the remote processor expects it */ /* put the segment where the remote processor expects it */
if (filesz) if (filesz) {
if (is_iomem)
memcpy_fromio(ptr, (void __iomem *)(elf_data + offset), filesz);
else
memcpy(ptr, elf_data + offset, filesz); memcpy(ptr, elf_data + offset, filesz);
}
/* /*
* Zero out remaining memory for this segment. * Zero out remaining memory for this segment.
...@@ -223,9 +228,13 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) ...@@ -223,9 +228,13 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
* did this for us. albeit harmless, we may consider removing * did this for us. albeit harmless, we may consider removing
* this. * this.
*/ */
if (memsz > filesz) if (memsz > filesz) {
if (is_iomem)
memset_io((void __iomem *)(ptr + filesz), 0, memsz - filesz);
else
memset(ptr + filesz, 0, memsz - filesz); memset(ptr + filesz, 0, memsz - filesz);
} }
}
return ret; return ret;
} }
...@@ -377,6 +386,6 @@ struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc, ...@@ -377,6 +386,6 @@ struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc,
return NULL; return NULL;
} }
return rproc_da_to_va(rproc, sh_addr, sh_size); return rproc_da_to_va(rproc, sh_addr, sh_size, NULL);
} }
EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table); EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table);
...@@ -84,7 +84,7 @@ static inline void rproc_char_device_remove(struct rproc *rproc) ...@@ -84,7 +84,7 @@ static inline void rproc_char_device_remove(struct rproc *rproc)
void rproc_free_vring(struct rproc_vring *rvring); void rproc_free_vring(struct rproc_vring *rvring);
int rproc_alloc_vring(struct rproc_vdev *rvdev, int i); int rproc_alloc_vring(struct rproc_vdev *rvdev, int i);
void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len); void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem);
phys_addr_t rproc_va_to_pa(void *cpu_addr); phys_addr_t rproc_va_to_pa(void *cpu_addr);
int rproc_trigger_recovery(struct rproc *rproc); int rproc_trigger_recovery(struct rproc *rproc);
......
...@@ -174,7 +174,7 @@ static int slim_rproc_stop(struct rproc *rproc) ...@@ -174,7 +174,7 @@ static int slim_rproc_stop(struct rproc *rproc)
return 0; return 0;
} }
static void *slim_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *slim_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct st_slim_rproc *slim_rproc = rproc->priv; struct st_slim_rproc *slim_rproc = rproc->priv;
void *va = NULL; void *va = NULL;
......
...@@ -354,7 +354,7 @@ static int k3_dsp_rproc_stop(struct rproc *rproc) ...@@ -354,7 +354,7 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
* can be used either by the remoteproc core for loading (when using kernel * can be used either by the remoteproc core for loading (when using kernel
* remoteproc loader), or by any rpmsg bus drivers. * remoteproc loader), or by any rpmsg bus drivers.
*/ */
static void *k3_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *k3_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct k3_dsp_rproc *kproc = rproc->priv; struct k3_dsp_rproc *kproc = rproc->priv;
void __iomem *va = NULL; void __iomem *va = NULL;
......
...@@ -590,7 +590,7 @@ static int k3_r5_rproc_stop(struct rproc *rproc) ...@@ -590,7 +590,7 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
* present in a DSP or IPU device). The translated addresses can be used * present in a DSP or IPU device). The translated addresses can be used
* either by the remoteproc core for loading, or by any rpmsg bus drivers. * either by the remoteproc core for loading, or by any rpmsg bus drivers.
*/ */
static void *k3_r5_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *k3_r5_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct k3_r5_rproc *kproc = rproc->priv; struct k3_r5_rproc *kproc = rproc->priv;
struct k3_r5_core *core = kproc->core; struct k3_r5_core *core = kproc->core;
......
...@@ -89,7 +89,7 @@ static int wkup_m3_rproc_stop(struct rproc *rproc) ...@@ -89,7 +89,7 @@ static int wkup_m3_rproc_stop(struct rproc *rproc)
return error; return error;
} }
static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{ {
struct wkup_m3_rproc *wkupm3 = rproc->priv; struct wkup_m3_rproc *wkupm3 = rproc->priv;
void *va = NULL; void *va = NULL;
......
...@@ -386,7 +386,7 @@ struct rproc_ops { ...@@ -386,7 +386,7 @@ struct rproc_ops {
int (*stop)(struct rproc *rproc); int (*stop)(struct rproc *rproc);
int (*attach)(struct rproc *rproc); int (*attach)(struct rproc *rproc);
void (*kick)(struct rproc *rproc, int vqid); void (*kick)(struct rproc *rproc, int vqid);
void * (*da_to_va)(struct rproc *rproc, u64 da, size_t len); void * (*da_to_va)(struct rproc *rproc, u64 da, size_t len, bool *is_iomem);
int (*parse_fw)(struct rproc *rproc, const struct firmware *fw); int (*parse_fw)(struct rproc *rproc, const struct firmware *fw);
int (*handle_rsc)(struct rproc *rproc, u32 rsc_type, void *rsc, int (*handle_rsc)(struct rproc *rproc, u32 rsc_type, void *rsc,
int offset, int avail); int offset, int avail);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment