All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] remoteproc: elf: support platform specific memory hook
@ 2020-07-28  9:29 ` peng.fan
  0 siblings, 0 replies; 7+ messages in thread
From: peng.fan @ 2020-07-28  9:29 UTC (permalink / raw)
  To: ohad, bjorn.andersson, robh+dt, shawnguo, s.hauer, kernel, festevam
  Cc: linux-imx, linux-remoteproc, linux-arm-kernel, linux-kernel, Peng Fan

From: Peng Fan <peng.fan@nxp.com>

To arm64, "dc      zva, dst" is used in memset.
Per ARM DDI 0487A.j, chapter C5.3.8 DC ZVA, Data Cache Zero by VA,

"If the memory region being zeroed is any type of Device memory,
this instruction can give an alignment fault which is prioritized
in the same way as other alignment faults that are determined
by the memory type."

On i.MX platforms, when elf is loaded to onchip TCM area, the region
is ioremapped, so "dc zva, dst" will trigger abort. And ioremap_wc()
on i.MX not able to write correct data to TCM area.

So we need to use io helpers, and extend the elf loader to support
platform specific memory functions.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/remoteproc_elf_loader.c | 20 ++++++++++++++++++--
 include/linux/remoteproc.h                 |  2 ++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index df68d87752e4..f442bac64432 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -129,6 +129,22 @@ u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
 }
 EXPORT_SYMBOL(rproc_elf_get_boot_addr);
 
+static void *rproc_elf_memcpy(struct rproc *rproc, void *dest, const void *src, size_t count)
+{
+	if (!rproc->ops->memcpy)
+		return memcpy(dest, src, count);
+
+	return rproc->ops->memcpy(rproc, dest, src, count);
+}
+
+static void *rproc_elf_memset(struct rproc *rproc, void *s, int c, size_t count)
+{
+	if (!rproc->ops->memset)
+		return memset(s, c, count);
+
+	return rproc->ops->memset(rproc, s, c, count);
+}
+
 /**
  * rproc_elf_load_segments() - load firmware segments to memory
  * @rproc: remote processor which will be booted using these fw segments
@@ -214,7 +230,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 
 		/* put the segment where the remote processor expects it */
 		if (filesz)
-			memcpy(ptr, elf_data + offset, filesz);
+			rproc_elf_memcpy(rproc, ptr, elf_data + offset, filesz);
 
 		/*
 		 * Zero out remaining memory for this segment.
@@ -224,7 +240,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 		 * this.
 		 */
 		if (memsz > filesz)
-			memset(ptr + filesz, 0, memsz - filesz);
+			rproc_elf_memset(rproc, ptr + filesz, 0, memsz - filesz);
 	}
 
 	return ret;
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 0e8d2ff575b4..88fc9643c1a8 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -391,6 +391,8 @@ struct rproc_ops {
 	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);
+	void *(*memcpy)(struct rproc *rproc, void *dest, const void *src, size_t count);
+	void *(*memset)(struct rproc *rproc, void *s, int c, size_t count);
 	unsigned long (*panic)(struct rproc *rproc);
 };
 
-- 
2.16.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 1/2] remoteproc: elf: support platform specific memory hook
@ 2020-07-28  9:29 ` peng.fan
  0 siblings, 0 replies; 7+ messages in thread
From: peng.fan @ 2020-07-28  9:29 UTC (permalink / raw)
  To: ohad, bjorn.andersson, robh+dt, shawnguo, s.hauer, kernel, festevam
  Cc: Peng Fan, linux-remoteproc, linux-imx, linux-arm-kernel, linux-kernel

From: Peng Fan <peng.fan@nxp.com>

To arm64, "dc      zva, dst" is used in memset.
Per ARM DDI 0487A.j, chapter C5.3.8 DC ZVA, Data Cache Zero by VA,

"If the memory region being zeroed is any type of Device memory,
this instruction can give an alignment fault which is prioritized
in the same way as other alignment faults that are determined
by the memory type."

On i.MX platforms, when elf is loaded to onchip TCM area, the region
is ioremapped, so "dc zva, dst" will trigger abort. And ioremap_wc()
on i.MX not able to write correct data to TCM area.

So we need to use io helpers, and extend the elf loader to support
platform specific memory functions.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/remoteproc_elf_loader.c | 20 ++++++++++++++++++--
 include/linux/remoteproc.h                 |  2 ++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index df68d87752e4..f442bac64432 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -129,6 +129,22 @@ u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
 }
 EXPORT_SYMBOL(rproc_elf_get_boot_addr);
 
+static void *rproc_elf_memcpy(struct rproc *rproc, void *dest, const void *src, size_t count)
+{
+	if (!rproc->ops->memcpy)
+		return memcpy(dest, src, count);
+
+	return rproc->ops->memcpy(rproc, dest, src, count);
+}
+
+static void *rproc_elf_memset(struct rproc *rproc, void *s, int c, size_t count)
+{
+	if (!rproc->ops->memset)
+		return memset(s, c, count);
+
+	return rproc->ops->memset(rproc, s, c, count);
+}
+
 /**
  * rproc_elf_load_segments() - load firmware segments to memory
  * @rproc: remote processor which will be booted using these fw segments
@@ -214,7 +230,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 
 		/* put the segment where the remote processor expects it */
 		if (filesz)
-			memcpy(ptr, elf_data + offset, filesz);
+			rproc_elf_memcpy(rproc, ptr, elf_data + offset, filesz);
 
 		/*
 		 * Zero out remaining memory for this segment.
@@ -224,7 +240,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 		 * this.
 		 */
 		if (memsz > filesz)
-			memset(ptr + filesz, 0, memsz - filesz);
+			rproc_elf_memset(rproc, ptr + filesz, 0, memsz - filesz);
 	}
 
 	return ret;
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 0e8d2ff575b4..88fc9643c1a8 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -391,6 +391,8 @@ struct rproc_ops {
 	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);
+	void *(*memcpy)(struct rproc *rproc, void *dest, const void *src, size_t count);
+	void *(*memset)(struct rproc *rproc, void *s, int c, size_t count);
 	unsigned long (*panic)(struct rproc *rproc);
 };
 
-- 
2.16.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] remoteproc: imx_rproc: add elf memory hooks
  2020-07-28  9:29 ` peng.fan
@ 2020-07-28  9:29   ` peng.fan
  -1 siblings, 0 replies; 7+ messages in thread
From: peng.fan @ 2020-07-28  9:29 UTC (permalink / raw)
  To: ohad, bjorn.andersson, robh+dt, shawnguo, s.hauer, kernel, festevam
  Cc: linux-imx, linux-remoteproc, linux-arm-kernel, linux-kernel, Peng Fan

From: Peng Fan <peng.fan@nxp.com>

Please not apply 2/2 for now, this 2/2 has not gone through
test on all i.MX8 platforms.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 8957ed271d20..8ad860c65256 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -6,6 +6,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
@@ -241,10 +242,22 @@ static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len)
 	return va;
 }
 
+static void *imx_rproc_memcpy(struct rproc *rproc, void *dest, const void *src, size_t count)
+{
+       memcpy_toio((void * __iomem)dest, src, count);
+}
+
+static void *imx_rproc_memset(struct rproc *rproc, void *s, int c, size_t count)
+{
+	memset_io((void * __iomem)s, c, count);
+}
+
 static const struct rproc_ops imx_rproc_ops = {
 	.start		= imx_rproc_start,
 	.stop		= imx_rproc_stop,
 	.da_to_va       = imx_rproc_da_to_va,
+	.memset		= imx_rproc_memset,
+	.memcpy		= imx_rproc_memcpy,
 };
 
 static int imx_rproc_addr_init(struct imx_rproc *priv,
-- 
2.16.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] remoteproc: imx_rproc: add elf memory hooks
@ 2020-07-28  9:29   ` peng.fan
  0 siblings, 0 replies; 7+ messages in thread
From: peng.fan @ 2020-07-28  9:29 UTC (permalink / raw)
  To: ohad, bjorn.andersson, robh+dt, shawnguo, s.hauer, kernel, festevam
  Cc: Peng Fan, linux-remoteproc, linux-imx, linux-arm-kernel, linux-kernel

From: Peng Fan <peng.fan@nxp.com>

Please not apply 2/2 for now, this 2/2 has not gone through
test on all i.MX8 platforms.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 8957ed271d20..8ad860c65256 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -6,6 +6,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
@@ -241,10 +242,22 @@ static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len)
 	return va;
 }
 
+static void *imx_rproc_memcpy(struct rproc *rproc, void *dest, const void *src, size_t count)
+{
+       memcpy_toio((void * __iomem)dest, src, count);
+}
+
+static void *imx_rproc_memset(struct rproc *rproc, void *s, int c, size_t count)
+{
+	memset_io((void * __iomem)s, c, count);
+}
+
 static const struct rproc_ops imx_rproc_ops = {
 	.start		= imx_rproc_start,
 	.stop		= imx_rproc_stop,
 	.da_to_va       = imx_rproc_da_to_va,
+	.memset		= imx_rproc_memset,
+	.memcpy		= imx_rproc_memcpy,
 };
 
 static int imx_rproc_addr_init(struct imx_rproc *priv,
-- 
2.16.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] remoteproc: elf: support platform specific memory hook
  2020-07-28  9:31 ` peng.fan
  (?)
@ 2020-07-28 16:51 ` kernel test robot
  -1 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2020-07-28 16:51 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 8441 bytes --]

Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on soc/for-next]
[also build test ERROR on linus/master v5.8-rc7 next-20200728]
[cannot apply to xlnx/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/peng-fan-nxp-com/remoteproc-elf-support-platform-specific-memory-hook/20200728-173920
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
config: i386-randconfig-s001-20200728 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-14) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.2-94-geb6779f6-dirty
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/remoteproc/remoteproc_elf_loader.c: In function 'rproc_elf_memcpy':
>> drivers/remoteproc/remoteproc_elf_loader.c:137:51: error: macro "memcpy" passed 4 arguments, but takes just 3
     137 |  return rproc->ops->memcpy(rproc, dest, src, count);
         |                                                   ^
   In file included from arch/x86/include/asm/string.h:3,
                    from include/linux/string.h:20,
                    from arch/x86/include/asm/page_32.h:35,
                    from arch/x86/include/asm/page.h:14,
                    from arch/x86/include/asm/thread_info.h:12,
                    from include/linux/thread_info.h:38,
                    from arch/x86/include/asm/preempt.h:7,
                    from include/linux/preempt.h:78,
                    from include/linux/spinlock.h:51,
                    from include/linux/seqlock.h:36,
                    from include/linux/time.h:6,
                    from include/linux/stat.h:19,
                    from include/linux/module.h:13,
                    from drivers/remoteproc/remoteproc_elf_loader.c:20:
   arch/x86/include/asm/string_32.h:182: note: macro "memcpy" defined here
     182 | #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
         | 
   drivers/remoteproc/remoteproc_elf_loader.c: In function 'rproc_elf_memset':
>> drivers/remoteproc/remoteproc_elf_loader.c:145:46: error: macro "memset" passed 4 arguments, but takes just 3
     145 |  return rproc->ops->memset(rproc, s, c, count);
         |                                              ^
   In file included from arch/x86/include/asm/string.h:3,
                    from include/linux/string.h:20,
                    from arch/x86/include/asm/page_32.h:35,
                    from arch/x86/include/asm/page.h:14,
                    from arch/x86/include/asm/thread_info.h:12,
                    from include/linux/thread_info.h:38,
                    from arch/x86/include/asm/preempt.h:7,
                    from include/linux/preempt.h:78,
                    from include/linux/spinlock.h:51,
                    from include/linux/seqlock.h:36,
                    from include/linux/time.h:6,
                    from include/linux/stat.h:19,
                    from include/linux/module.h:13,
                    from drivers/remoteproc/remoteproc_elf_loader.c:20:
   arch/x86/include/asm/string_32.h:228: note: macro "memset" defined here
     228 | #define memset(s, c, count) __builtin_memset(s, c, count)
         | 

sparse warnings: (new ones prefixed by >>)

>> drivers/remoteproc/remoteproc_elf_loader.c:137:28: sparse: sparse: macro "memcpy" passed 4 arguments, but takes just 3
>> drivers/remoteproc/remoteproc_elf_loader.c:145:28: sparse: sparse: macro "memset" passed 4 arguments, but takes just 3

vim +/memcpy +137 drivers/remoteproc/remoteproc_elf_loader.c

    19	
  > 20	#include <linux/module.h>
    21	#include <linux/firmware.h>
    22	#include <linux/remoteproc.h>
    23	#include <linux/elf.h>
    24	
    25	#include "remoteproc_internal.h"
    26	#include "remoteproc_elf_helpers.h"
    27	
    28	/**
    29	 * rproc_elf_sanity_check() - Sanity Check for ELF32/ELF64 firmware image
    30	 * @rproc: the remote processor handle
    31	 * @fw: the ELF firmware image
    32	 *
    33	 * Make sure this fw image is sane (ie a correct ELF32/ELF64 file).
    34	 */
    35	int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw)
    36	{
    37		const char *name = rproc->firmware;
    38		struct device *dev = &rproc->dev;
    39		/*
    40		 * Elf files are beginning with the same structure. Thus, to simplify
    41		 * header parsing, we can use the elf32_hdr one for both elf64 and
    42		 * elf32.
    43		 */
    44		struct elf32_hdr *ehdr;
    45		u32 elf_shdr_get_size;
    46		u64 phoff, shoff;
    47		char class;
    48		u16 phnum;
    49	
    50		if (!fw) {
    51			dev_err(dev, "failed to load %s\n", name);
    52			return -EINVAL;
    53		}
    54	
    55		if (fw->size < sizeof(struct elf32_hdr)) {
    56			dev_err(dev, "Image is too small\n");
    57			return -EINVAL;
    58		}
    59	
    60		ehdr = (struct elf32_hdr *)fw->data;
    61	
    62		if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
    63			dev_err(dev, "Image is corrupted (bad magic)\n");
    64			return -EINVAL;
    65		}
    66	
    67		class = ehdr->e_ident[EI_CLASS];
    68		if (class != ELFCLASS32 && class != ELFCLASS64) {
    69			dev_err(dev, "Unsupported class: %d\n", class);
    70			return -EINVAL;
    71		}
    72	
    73		if (class == ELFCLASS64 && fw->size < sizeof(struct elf64_hdr)) {
    74			dev_err(dev, "elf64 header is too small\n");
    75			return -EINVAL;
    76		}
    77	
    78		/* We assume the firmware has the same endianness as the host */
    79	# ifdef __LITTLE_ENDIAN
    80		if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
    81	# else /* BIG ENDIAN */
    82		if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
    83	# endif
    84			dev_err(dev, "Unsupported firmware endianness\n");
    85			return -EINVAL;
    86		}
    87	
    88		phoff = elf_hdr_get_e_phoff(class, fw->data);
    89		shoff = elf_hdr_get_e_shoff(class, fw->data);
    90		phnum =  elf_hdr_get_e_phnum(class, fw->data);
    91		elf_shdr_get_size = elf_size_of_shdr(class);
    92	
    93		if (fw->size < shoff + elf_shdr_get_size) {
    94			dev_err(dev, "Image is too small\n");
    95			return -EINVAL;
    96		}
    97	
    98		if (phnum == 0) {
    99			dev_err(dev, "No loadable segments\n");
   100			return -EINVAL;
   101		}
   102	
   103		if (phoff > fw->size) {
   104			dev_err(dev, "Firmware size is too small\n");
   105			return -EINVAL;
   106		}
   107	
   108		dev_dbg(dev, "Firmware is an elf%d file\n",
   109			class == ELFCLASS32 ? 32 : 64);
   110	
   111		return 0;
   112	}
   113	EXPORT_SYMBOL(rproc_elf_sanity_check);
   114	
   115	/**
   116	 * rproc_elf_get_boot_addr() - Get rproc's boot address.
   117	 * @rproc: the remote processor handle
   118	 * @fw: the ELF firmware image
   119	 *
   120	 * This function returns the entry point address of the ELF
   121	 * image.
   122	 *
   123	 * Note that the boot address is not a configurable property of all remote
   124	 * processors. Some will always boot at a specific hard-coded address.
   125	 */
   126	u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
   127	{
   128		return elf_hdr_get_e_entry(fw_elf_get_class(fw), fw->data);
   129	}
   130	EXPORT_SYMBOL(rproc_elf_get_boot_addr);
   131	
   132	static void *rproc_elf_memcpy(struct rproc *rproc, void *dest, const void *src, size_t count)
   133	{
   134		if (!rproc->ops->memcpy)
   135			return memcpy(dest, src, count);
   136	
 > 137		return rproc->ops->memcpy(rproc, dest, src, count);
   138	}
   139	
   140	static void *rproc_elf_memset(struct rproc *rproc, void *s, int c, size_t count)
   141	{
   142		if (!rproc->ops->memset)
   143			return memset(s, c, count);
   144	
 > 145		return rproc->ops->memset(rproc, s, c, count);
   146	}
   147	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 33288 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] remoteproc: elf: support platform specific memory hook
@ 2020-07-28  9:31 ` peng.fan
  0 siblings, 0 replies; 7+ messages in thread
From: peng.fan @ 2020-07-28  9:31 UTC (permalink / raw)
  To: ohad, bjorn.andersson, robh+dt, shawnguo, s.hauer, kernel,
	festevam, mathieu.poirier, o.rempel
  Cc: linux-imx, linux-remoteproc, linux-arm-kernel, linux-kernel, Peng Fan

From: Peng Fan <peng.fan@nxp.com>

To arm64, "dc      zva, dst" is used in memset.
Per ARM DDI 0487A.j, chapter C5.3.8 DC ZVA, Data Cache Zero by VA,

"If the memory region being zeroed is any type of Device memory,
this instruction can give an alignment fault which is prioritized
in the same way as other alignment faults that are determined
by the memory type."

On i.MX platforms, when elf is loaded to onchip TCM area, the region
is ioremapped, so "dc zva, dst" will trigger abort. And ioremap_wc()
on i.MX not able to write correct data to TCM area.

So we need to use io helpers, and extend the elf loader to support
platform specific memory functions.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/remoteproc_elf_loader.c | 20 ++++++++++++++++++--
 include/linux/remoteproc.h                 |  2 ++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index df68d87752e4..f442bac64432 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -129,6 +129,22 @@ u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
 }
 EXPORT_SYMBOL(rproc_elf_get_boot_addr);
 
+static void *rproc_elf_memcpy(struct rproc *rproc, void *dest, const void *src, size_t count)
+{
+	if (!rproc->ops->memcpy)
+		return memcpy(dest, src, count);
+
+	return rproc->ops->memcpy(rproc, dest, src, count);
+}
+
+static void *rproc_elf_memset(struct rproc *rproc, void *s, int c, size_t count)
+{
+	if (!rproc->ops->memset)
+		return memset(s, c, count);
+
+	return rproc->ops->memset(rproc, s, c, count);
+}
+
 /**
  * rproc_elf_load_segments() - load firmware segments to memory
  * @rproc: remote processor which will be booted using these fw segments
@@ -214,7 +230,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 
 		/* put the segment where the remote processor expects it */
 		if (filesz)
-			memcpy(ptr, elf_data + offset, filesz);
+			rproc_elf_memcpy(rproc, ptr, elf_data + offset, filesz);
 
 		/*
 		 * Zero out remaining memory for this segment.
@@ -224,7 +240,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 		 * this.
 		 */
 		if (memsz > filesz)
-			memset(ptr + filesz, 0, memsz - filesz);
+			rproc_elf_memset(rproc, ptr + filesz, 0, memsz - filesz);
 	}
 
 	return ret;
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 0e8d2ff575b4..88fc9643c1a8 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -391,6 +391,8 @@ struct rproc_ops {
 	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);
+	void *(*memcpy)(struct rproc *rproc, void *dest, const void *src, size_t count);
+	void *(*memset)(struct rproc *rproc, void *s, int c, size_t count);
 	unsigned long (*panic)(struct rproc *rproc);
 };
 
-- 
2.16.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 1/2] remoteproc: elf: support platform specific memory hook
@ 2020-07-28  9:31 ` peng.fan
  0 siblings, 0 replies; 7+ messages in thread
From: peng.fan @ 2020-07-28  9:31 UTC (permalink / raw)
  To: ohad, bjorn.andersson, robh+dt, shawnguo, s.hauer, kernel,
	festevam, mathieu.poirier, o.rempel
  Cc: Peng Fan, linux-remoteproc, linux-imx, linux-arm-kernel, linux-kernel

From: Peng Fan <peng.fan@nxp.com>

To arm64, "dc      zva, dst" is used in memset.
Per ARM DDI 0487A.j, chapter C5.3.8 DC ZVA, Data Cache Zero by VA,

"If the memory region being zeroed is any type of Device memory,
this instruction can give an alignment fault which is prioritized
in the same way as other alignment faults that are determined
by the memory type."

On i.MX platforms, when elf is loaded to onchip TCM area, the region
is ioremapped, so "dc zva, dst" will trigger abort. And ioremap_wc()
on i.MX not able to write correct data to TCM area.

So we need to use io helpers, and extend the elf loader to support
platform specific memory functions.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/remoteproc_elf_loader.c | 20 ++++++++++++++++++--
 include/linux/remoteproc.h                 |  2 ++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index df68d87752e4..f442bac64432 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -129,6 +129,22 @@ u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
 }
 EXPORT_SYMBOL(rproc_elf_get_boot_addr);
 
+static void *rproc_elf_memcpy(struct rproc *rproc, void *dest, const void *src, size_t count)
+{
+	if (!rproc->ops->memcpy)
+		return memcpy(dest, src, count);
+
+	return rproc->ops->memcpy(rproc, dest, src, count);
+}
+
+static void *rproc_elf_memset(struct rproc *rproc, void *s, int c, size_t count)
+{
+	if (!rproc->ops->memset)
+		return memset(s, c, count);
+
+	return rproc->ops->memset(rproc, s, c, count);
+}
+
 /**
  * rproc_elf_load_segments() - load firmware segments to memory
  * @rproc: remote processor which will be booted using these fw segments
@@ -214,7 +230,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 
 		/* put the segment where the remote processor expects it */
 		if (filesz)
-			memcpy(ptr, elf_data + offset, filesz);
+			rproc_elf_memcpy(rproc, ptr, elf_data + offset, filesz);
 
 		/*
 		 * Zero out remaining memory for this segment.
@@ -224,7 +240,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 		 * this.
 		 */
 		if (memsz > filesz)
-			memset(ptr + filesz, 0, memsz - filesz);
+			rproc_elf_memset(rproc, ptr + filesz, 0, memsz - filesz);
 	}
 
 	return ret;
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 0e8d2ff575b4..88fc9643c1a8 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -391,6 +391,8 @@ struct rproc_ops {
 	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);
+	void *(*memcpy)(struct rproc *rproc, void *dest, const void *src, size_t count);
+	void *(*memset)(struct rproc *rproc, void *s, int c, size_t count);
 	unsigned long (*panic)(struct rproc *rproc);
 };
 
-- 
2.16.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-07-28 16:51 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-28  9:29 [PATCH 1/2] remoteproc: elf: support platform specific memory hook peng.fan
2020-07-28  9:29 ` peng.fan
2020-07-28  9:29 ` [PATCH 2/2] remoteproc: imx_rproc: add elf memory hooks peng.fan
2020-07-28  9:29   ` peng.fan
2020-07-28  9:31 [PATCH 1/2] remoteproc: elf: support platform specific memory hook peng.fan
2020-07-28  9:31 ` peng.fan
2020-07-28 16:51 ` kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.