From: Peng Fan Date: Tue, 4 Nov 2025 10:05:50 +0000 (+0800) Subject: remoteproc: Extend device_to_virt with a is_iomem parameter X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e76f9a7c9720ea3be3afe4d28fa494c8535bc505;p=thirdparty%2Fu-boot.git remoteproc: Extend device_to_virt with a is_iomem parameter Some areas needs to be initialized by using memcpy_toio and memset_io. Following Linux Kernel commit: 40df0a91b2a5 ("remoteproc: add is_iomem to da_to_va"), add this to U-Boot. Reviewed-by: Ye Li Signed-off-by: Peng Fan --- diff --git a/drivers/remoteproc/renesas_apmu.c b/drivers/remoteproc/renesas_apmu.c index 1a50cd3289b..91586a99e0d 100644 --- a/drivers/remoteproc/renesas_apmu.c +++ b/drivers/remoteproc/renesas_apmu.c @@ -170,11 +170,12 @@ static int renesas_apmu_rproc_init(struct udevice *dev) * @dev: corresponding remote processor device * @da: device address * @size: Size of the memory region @da is pointing to + * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory * * Return: converted virtual address */ static void *renesas_apmu_rproc_device_to_virt(struct udevice *dev, ulong da, - ulong size) + ulong size, bool *is_iomem) { /* * The Cortex R52 and A76 share the same address space, diff --git a/drivers/remoteproc/rproc-elf-loader.c b/drivers/remoteproc/rproc-elf-loader.c index 0b3941b7798..83d70c2fb54 100644 --- a/drivers/remoteproc/rproc-elf-loader.c +++ b/drivers/remoteproc/rproc-elf-loader.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + * Copyright 2025 NXP */ #include #include @@ -9,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -181,27 +183,38 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size) for (i = 0; i < ehdr->e_phnum; i++, phdr++) { void *dst = (void *)(uintptr_t)phdr->p_paddr; void *src = (void *)addr + phdr->p_offset; + bool is_iomem = false; ulong dst_addr; - if (phdr->p_type != PT_LOAD) + if (phdr->p_type != PT_LOAD || !phdr->p_memsz) continue; if (ops->device_to_virt) dst = ops->device_to_virt(dev, (ulong)dst, - phdr->p_memsz); + phdr->p_memsz, &is_iomem); dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n", i, dst, phdr->p_filesz); - if (phdr->p_filesz) - memcpy(dst, src, phdr->p_filesz); - if (phdr->p_filesz != phdr->p_memsz) - memset(dst + phdr->p_filesz, 0x00, - phdr->p_memsz - phdr->p_filesz); + if (phdr->p_filesz) { + if (is_iomem) + memcpy_toio(dst, src, phdr->p_filesz); + else + memcpy(dst, src, phdr->p_filesz); + } + if (phdr->p_filesz != phdr->p_memsz) { + if (is_iomem) + memset_io(dst + phdr->p_filesz, 0x00, + phdr->p_memsz - phdr->p_filesz); + else + memset(dst + phdr->p_filesz, 0x00, + phdr->p_memsz - phdr->p_filesz); + } dst_addr = map_to_sysmem(dst); - flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN), - roundup(dst_addr + phdr->p_filesz, - ARCH_DMA_MINALIGN) - - rounddown(dst_addr, ARCH_DMA_MINALIGN)); + if (!is_iomem) { + flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN), + roundup(dst_addr + phdr->p_filesz, ARCH_DMA_MINALIGN) - + rounddown(dst_addr, ARCH_DMA_MINALIGN)); + } } return 0; @@ -230,6 +243,7 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size) memsz = phdr->p_memsz; filesz = phdr->p_filesz; offset = phdr->p_offset; + bool is_iomem = false; if (phdr->p_type != PT_LOAD) continue; @@ -239,7 +253,7 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size) ptr = (void *)(uintptr_t)da; if (ops->device_to_virt) { - ptr = ops->device_to_virt(dev, da, phdr->p_memsz); + ptr = ops->device_to_virt(dev, da, phdr->p_memsz, &is_iomem); if (!ptr) { dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da, memsz); @@ -248,14 +262,24 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size) } } - if (filesz) - memcpy(ptr, (void *)addr + offset, filesz); - if (filesz != memsz) - memset(ptr + filesz, 0x00, memsz - filesz); + if (filesz) { + if (is_iomem) + memcpy_toio(ptr, (void *)addr + offset, filesz); + else + memcpy(ptr, (void *)addr + offset, filesz); + } + if (filesz != memsz) { + if (is_iomem) + memset_io(ptr + filesz, 0x00, memsz - filesz); + else + memset(ptr + filesz, 0x00, memsz - filesz); + } - flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN), - roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) - - rounddown((ulong)ptr, ARCH_DMA_MINALIGN)); + if (!is_iomem) { + flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN), + roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) - + rounddown((ulong)ptr, ARCH_DMA_MINALIGN)); + } } return ret; @@ -381,6 +405,7 @@ int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr, Elf32_Shdr *shdr; void *src, *dst; ulong dst_addr; + bool is_iomem = false; shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size); if (!shdr) @@ -394,18 +419,22 @@ int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr, src = (void *)fw_addr + shdr->sh_offset; if (ops->device_to_virt) - dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size); + dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size, &is_iomem); else dst = (void *)rsc_addr; dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n", (ulong)dst, *rsc_size); - memcpy(dst, src, *rsc_size); - dst_addr = map_to_sysmem(dst); - flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN), - roundup(dst_addr + *rsc_size, ARCH_DMA_MINALIGN) - - rounddown(dst_addr, ARCH_DMA_MINALIGN)); + if (is_iomem) { + memcpy_toio(dst, src, *rsc_size); + } else { + memcpy(dst, src, *rsc_size); + dst_addr = map_to_sysmem(dst); + flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN), + roundup(dst_addr + *rsc_size, ARCH_DMA_MINALIGN) - + rounddown(dst_addr, ARCH_DMA_MINALIGN)); + } return 0; } @@ -490,6 +519,7 @@ int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr, const struct dm_rproc_ops *ops; Elf64_Shdr *shdr; void *src, *dst; + bool is_iomem = false; shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size); if (!shdr) @@ -503,18 +533,21 @@ int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr, src = (void *)fw_addr + shdr->sh_offset; if (ops->device_to_virt) - dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size); + dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size, &is_iomem); else dst = (void *)rsc_addr; dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n", (ulong)dst, *rsc_size); - memcpy(dst, src, *rsc_size); - flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), - roundup((unsigned long)dst + *rsc_size, - ARCH_DMA_MINALIGN) - - rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); + if (is_iomem) { + memcpy_toio(dst, src, *rsc_size); + } else { + memcpy(dst, src, *rsc_size); + flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), + roundup((unsigned long)dst + *rsc_size, ARCH_DMA_MINALIGN) - + rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); + } return 0; } diff --git a/drivers/remoteproc/sandbox_testproc.c b/drivers/remoteproc/sandbox_testproc.c index ad575a7c10f..7ed38e8656c 100644 --- a/drivers/remoteproc/sandbox_testproc.c +++ b/drivers/remoteproc/sandbox_testproc.c @@ -308,10 +308,11 @@ static int sandbox_testproc_ping(struct udevice *dev) * @dev: device to operate upon * @da: device address * @size: Size of the memory region @da is pointing to + * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory * Return: converted virtual address */ static void *sandbox_testproc_device_to_virt(struct udevice *dev, ulong da, - ulong size) + ulong size, bool *is_iomem) { u64 paddr; diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c index f45da9a68ac..bf721e78bb3 100644 --- a/drivers/remoteproc/stm32_copro.c +++ b/drivers/remoteproc/stm32_copro.c @@ -61,10 +61,11 @@ static int stm32_copro_probe(struct udevice *dev) * @dev: corresponding STM32 remote processor device * @da: device address * @size: Size of the memory region @da is pointing to + * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory * Return: converted virtual address */ static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da, - ulong size) + ulong size, bool *is_iomem) { fdt32_t in_addr = cpu_to_be32(da), end_addr; u64 paddr; diff --git a/drivers/remoteproc/ti_k3_dsp_rproc.c b/drivers/remoteproc/ti_k3_dsp_rproc.c index 5a7d6377283..9275e1b241d 100644 --- a/drivers/remoteproc/ti_k3_dsp_rproc.c +++ b/drivers/remoteproc/ti_k3_dsp_rproc.c @@ -261,7 +261,7 @@ static int k3_dsp_reset(struct udevice *dev) return 0; } -static void *k3_dsp_da_to_va(struct udevice *dev, ulong da, ulong len) +static void *k3_dsp_da_to_va(struct udevice *dev, ulong da, ulong len, bool *is_iomem) { struct k3_dsp_privdata *dsp = dev_get_priv(dev); phys_addr_t bus_addr, dev_addr; diff --git a/drivers/remoteproc/ti_k3_m4_rproc.c b/drivers/remoteproc/ti_k3_m4_rproc.c index 31b9de71579..f358788f07f 100644 --- a/drivers/remoteproc/ti_k3_m4_rproc.c +++ b/drivers/remoteproc/ti_k3_m4_rproc.c @@ -181,7 +181,7 @@ static int k3_m4_stop(struct udevice *dev) return 0; } -static void *k3_m4_da_to_va(struct udevice *dev, ulong da, ulong len) +static void *k3_m4_da_to_va(struct udevice *dev, ulong da, ulong len, bool *is_iomem) { struct k3_m4_privdata *m4 = dev_get_priv(dev); phys_addr_t bus_addr, dev_addr; diff --git a/drivers/remoteproc/ti_k3_r5f_rproc.c b/drivers/remoteproc/ti_k3_r5f_rproc.c index 48401bc6eb6..c738607c109 100644 --- a/drivers/remoteproc/ti_k3_r5f_rproc.c +++ b/drivers/remoteproc/ti_k3_r5f_rproc.c @@ -534,7 +534,7 @@ proc_release: return ret; } -static void *k3_r5f_da_to_va(struct udevice *dev, ulong da, ulong size) +static void *k3_r5f_da_to_va(struct udevice *dev, ulong da, ulong size, bool *is_iomem) { struct k3_r5f_core *core = dev_get_priv(dev); void __iomem *va = NULL; diff --git a/include/remoteproc.h b/include/remoteproc.h index 6f8068e1496..9adc3d17d8f 100644 --- a/include/remoteproc.h +++ b/include/remoteproc.h @@ -495,9 +495,10 @@ struct dm_rproc_ops { * @dev: Remote proc device * @da: Device address * @size: Size of the memory region @da is pointing to + * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory * @return virtual address. */ - void * (*device_to_virt)(struct udevice *dev, ulong da, ulong size); + void * (*device_to_virt)(struct udevice *dev, ulong da, ulong size, bool *is_iomem); int (*add_res)(struct udevice *dev, struct rproc_mem_entry *mapping); void * (*alloc_mem)(struct udevice *dev, unsigned long len,