mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
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 <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
@@ -170,11 +170,12 @@ static int renesas_apmu_rproc_init(struct udevice *dev)
|
|||||||
* @dev: corresponding remote processor device
|
* @dev: corresponding remote processor device
|
||||||
* @da: device address
|
* @da: device address
|
||||||
* @size: Size of the memory region @da is pointing to
|
* @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
|
* Return: converted virtual address
|
||||||
*/
|
*/
|
||||||
static void *renesas_apmu_rproc_device_to_virt(struct udevice *dev, ulong da,
|
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,
|
* The Cortex R52 and A76 share the same address space,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019, STMicroelectronics - All Rights Reserved
|
* Copyright (C) 2019, STMicroelectronics - All Rights Reserved
|
||||||
|
* Copyright 2025 NXP
|
||||||
*/
|
*/
|
||||||
#include <cpu_func.h>
|
#include <cpu_func.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
@@ -9,6 +10,7 @@
|
|||||||
#include <mapmem.h>
|
#include <mapmem.h>
|
||||||
#include <remoteproc.h>
|
#include <remoteproc.h>
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
|
#include <asm/io.h>
|
||||||
#include <dm/device_compat.h>
|
#include <dm/device_compat.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/printk.h>
|
#include <linux/printk.h>
|
||||||
@@ -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++) {
|
for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
|
||||||
void *dst = (void *)(uintptr_t)phdr->p_paddr;
|
void *dst = (void *)(uintptr_t)phdr->p_paddr;
|
||||||
void *src = (void *)addr + phdr->p_offset;
|
void *src = (void *)addr + phdr->p_offset;
|
||||||
|
bool is_iomem = false;
|
||||||
ulong dst_addr;
|
ulong dst_addr;
|
||||||
|
|
||||||
if (phdr->p_type != PT_LOAD)
|
if (phdr->p_type != PT_LOAD || !phdr->p_memsz)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ops->device_to_virt)
|
if (ops->device_to_virt)
|
||||||
dst = ops->device_to_virt(dev, (ulong)dst,
|
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",
|
dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n",
|
||||||
i, dst, phdr->p_filesz);
|
i, dst, phdr->p_filesz);
|
||||||
if (phdr->p_filesz)
|
if (phdr->p_filesz) {
|
||||||
memcpy(dst, src, phdr->p_filesz);
|
if (is_iomem)
|
||||||
if (phdr->p_filesz != phdr->p_memsz)
|
memcpy_toio(dst, src, phdr->p_filesz);
|
||||||
memset(dst + phdr->p_filesz, 0x00,
|
else
|
||||||
phdr->p_memsz - phdr->p_filesz);
|
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);
|
dst_addr = map_to_sysmem(dst);
|
||||||
flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
|
if (!is_iomem) {
|
||||||
roundup(dst_addr + phdr->p_filesz,
|
flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
|
||||||
ARCH_DMA_MINALIGN) -
|
roundup(dst_addr + phdr->p_filesz, ARCH_DMA_MINALIGN) -
|
||||||
rounddown(dst_addr, ARCH_DMA_MINALIGN));
|
rounddown(dst_addr, ARCH_DMA_MINALIGN));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -230,6 +243,7 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
|
|||||||
memsz = phdr->p_memsz;
|
memsz = phdr->p_memsz;
|
||||||
filesz = phdr->p_filesz;
|
filesz = phdr->p_filesz;
|
||||||
offset = phdr->p_offset;
|
offset = phdr->p_offset;
|
||||||
|
bool is_iomem = false;
|
||||||
|
|
||||||
if (phdr->p_type != PT_LOAD)
|
if (phdr->p_type != PT_LOAD)
|
||||||
continue;
|
continue;
|
||||||
@@ -239,7 +253,7 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
|
|||||||
|
|
||||||
ptr = (void *)(uintptr_t)da;
|
ptr = (void *)(uintptr_t)da;
|
||||||
if (ops->device_to_virt) {
|
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) {
|
if (!ptr) {
|
||||||
dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da,
|
dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da,
|
||||||
memsz);
|
memsz);
|
||||||
@@ -248,14 +262,24 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filesz)
|
if (filesz) {
|
||||||
memcpy(ptr, (void *)addr + offset, filesz);
|
if (is_iomem)
|
||||||
if (filesz != memsz)
|
memcpy_toio(ptr, (void *)addr + offset, filesz);
|
||||||
memset(ptr + filesz, 0x00, memsz - 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),
|
if (!is_iomem) {
|
||||||
roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) -
|
flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN),
|
||||||
rounddown((ulong)ptr, ARCH_DMA_MINALIGN));
|
roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) -
|
||||||
|
rounddown((ulong)ptr, ARCH_DMA_MINALIGN));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -381,6 +405,7 @@ int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
|
|||||||
Elf32_Shdr *shdr;
|
Elf32_Shdr *shdr;
|
||||||
void *src, *dst;
|
void *src, *dst;
|
||||||
ulong dst_addr;
|
ulong dst_addr;
|
||||||
|
bool is_iomem = false;
|
||||||
|
|
||||||
shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size);
|
shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size);
|
||||||
if (!shdr)
|
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;
|
src = (void *)fw_addr + shdr->sh_offset;
|
||||||
if (ops->device_to_virt)
|
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
|
else
|
||||||
dst = (void *)rsc_addr;
|
dst = (void *)rsc_addr;
|
||||||
|
|
||||||
dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
|
dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
|
||||||
(ulong)dst, *rsc_size);
|
(ulong)dst, *rsc_size);
|
||||||
|
|
||||||
memcpy(dst, src, *rsc_size);
|
if (is_iomem) {
|
||||||
dst_addr = map_to_sysmem(dst);
|
memcpy_toio(dst, src, *rsc_size);
|
||||||
flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
|
} else {
|
||||||
roundup(dst_addr + *rsc_size, ARCH_DMA_MINALIGN) -
|
memcpy(dst, src, *rsc_size);
|
||||||
rounddown(dst_addr, ARCH_DMA_MINALIGN));
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -490,6 +519,7 @@ int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
|
|||||||
const struct dm_rproc_ops *ops;
|
const struct dm_rproc_ops *ops;
|
||||||
Elf64_Shdr *shdr;
|
Elf64_Shdr *shdr;
|
||||||
void *src, *dst;
|
void *src, *dst;
|
||||||
|
bool is_iomem = false;
|
||||||
|
|
||||||
shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size);
|
shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size);
|
||||||
if (!shdr)
|
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;
|
src = (void *)fw_addr + shdr->sh_offset;
|
||||||
if (ops->device_to_virt)
|
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
|
else
|
||||||
dst = (void *)rsc_addr;
|
dst = (void *)rsc_addr;
|
||||||
|
|
||||||
dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
|
dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
|
||||||
(ulong)dst, *rsc_size);
|
(ulong)dst, *rsc_size);
|
||||||
|
|
||||||
memcpy(dst, src, *rsc_size);
|
if (is_iomem) {
|
||||||
flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
|
memcpy_toio(dst, src, *rsc_size);
|
||||||
roundup((unsigned long)dst + *rsc_size,
|
} else {
|
||||||
ARCH_DMA_MINALIGN) -
|
memcpy(dst, src, *rsc_size);
|
||||||
rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,10 +308,11 @@ static int sandbox_testproc_ping(struct udevice *dev)
|
|||||||
* @dev: device to operate upon
|
* @dev: device to operate upon
|
||||||
* @da: device address
|
* @da: device address
|
||||||
* @size: Size of the memory region @da is pointing to
|
* @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
|
* Return: converted virtual address
|
||||||
*/
|
*/
|
||||||
static void *sandbox_testproc_device_to_virt(struct udevice *dev, ulong da,
|
static void *sandbox_testproc_device_to_virt(struct udevice *dev, ulong da,
|
||||||
ulong size)
|
ulong size, bool *is_iomem)
|
||||||
{
|
{
|
||||||
u64 paddr;
|
u64 paddr;
|
||||||
|
|
||||||
|
|||||||
@@ -61,10 +61,11 @@ static int stm32_copro_probe(struct udevice *dev)
|
|||||||
* @dev: corresponding STM32 remote processor device
|
* @dev: corresponding STM32 remote processor device
|
||||||
* @da: device address
|
* @da: device address
|
||||||
* @size: Size of the memory region @da is pointing to
|
* @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
|
* Return: converted virtual address
|
||||||
*/
|
*/
|
||||||
static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da,
|
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;
|
fdt32_t in_addr = cpu_to_be32(da), end_addr;
|
||||||
u64 paddr;
|
u64 paddr;
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ static int k3_dsp_reset(struct udevice *dev)
|
|||||||
return 0;
|
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);
|
struct k3_dsp_privdata *dsp = dev_get_priv(dev);
|
||||||
phys_addr_t bus_addr, dev_addr;
|
phys_addr_t bus_addr, dev_addr;
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ static int k3_m4_stop(struct udevice *dev)
|
|||||||
return 0;
|
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);
|
struct k3_m4_privdata *m4 = dev_get_priv(dev);
|
||||||
phys_addr_t bus_addr, dev_addr;
|
phys_addr_t bus_addr, dev_addr;
|
||||||
|
|||||||
@@ -534,7 +534,7 @@ proc_release:
|
|||||||
return ret;
|
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);
|
struct k3_r5f_core *core = dev_get_priv(dev);
|
||||||
void __iomem *va = NULL;
|
void __iomem *va = NULL;
|
||||||
|
|||||||
@@ -495,9 +495,10 @@ struct dm_rproc_ops {
|
|||||||
* @dev: Remote proc device
|
* @dev: Remote proc device
|
||||||
* @da: Device address
|
* @da: Device address
|
||||||
* @size: Size of the memory region @da is pointing to
|
* @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.
|
* @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,
|
int (*add_res)(struct udevice *dev,
|
||||||
struct rproc_mem_entry *mapping);
|
struct rproc_mem_entry *mapping);
|
||||||
void * (*alloc_mem)(struct udevice *dev, unsigned long len,
|
void * (*alloc_mem)(struct udevice *dev, unsigned long len,
|
||||||
|
|||||||
Reference in New Issue
Block a user