// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
 */
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <elf.h>
#include <remoteproc.h>

/**
 * struct resource_table - firmware resource table header
 * @ver: version number
 * @num: number of resource entries
 * @reserved: reserved (must be zero)
 * @offset: array of offsets pointing at the various resource entries
 *
 * A resource table is essentially a list of system resources required
 * by the remote processor. It may also include configuration entries.
 * If needed, the remote processor firmware should contain this table
 * as a dedicated ".resource_table" ELF section.
 *
 * Some resources entries are mere announcements, where the host is informed
 * of specific remoteproc configuration. Other entries require the host to
 * do something (e.g. allocate a system resource). Sometimes a negotiation
 * is expected, where the firmware requests a resource, and once allocated,
 * the host should provide back its details (e.g. address of an allocated
 * memory region).
 *
 * The header of the resource table, as expressed by this structure,
 * contains a version number (should we need to change this format in the
 * future), the number of available resource entries, and their offsets
 * in the table.
 *
 * Immediately following this header are the resource entries themselves.
 */
struct resource_table {
	u32 ver;
	u32 num;
	u32 reserved[2];
	u32 offset[0];
} __packed;

/* Basic function to verify ELF32 image format */
int rproc_elf32_sanity_check(ulong addr, ulong size)
{
	Elf32_Ehdr *ehdr;
	char class;

	if (!addr) {
		pr_debug("Invalid fw address?\n");
		return -EFAULT;
	}

	if (size < sizeof(Elf32_Ehdr)) {
		pr_debug("Image is too small\n");
		return -ENOSPC;
	}

	ehdr = (Elf32_Ehdr *)addr;
	class = ehdr->e_ident[EI_CLASS];

	if (!IS_ELF(*ehdr) || ehdr->e_type != ET_EXEC || class != ELFCLASS32) {
		pr_debug("Not an executable ELF32 image\n");
		return -EPROTONOSUPPORT;
	}

	/* We assume the firmware has the same endianness as the host */
# ifdef __LITTLE_ENDIAN
	if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
# else /* BIG ENDIAN */
	if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
# endif
		pr_debug("Unsupported firmware endianness\n");
		return -EILSEQ;
	}

	if (size < ehdr->e_shoff + sizeof(Elf32_Shdr)) {
		pr_debug("Image is too small\n");
		return -ENOSPC;
	}

	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
		pr_debug("Image is corrupted (bad magic)\n");
		return -EBADF;
	}

	if (ehdr->e_phnum == 0) {
		pr_debug("No loadable segments\n");
		return -ENOEXEC;
	}

	if (ehdr->e_phoff > size) {
		pr_debug("Firmware size is too small\n");
		return -ENOSPC;
	}

	return 0;
}

/* Basic function to verify ELF64 image format */
int rproc_elf64_sanity_check(ulong addr, ulong size)
{
	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
	char class;

	if (!addr) {
		pr_debug("Invalid fw address?\n");
		return -EFAULT;
	}

	if (size < sizeof(Elf64_Ehdr)) {
		pr_debug("Image is too small\n");
		return -ENOSPC;
	}

	class = ehdr->e_ident[EI_CLASS];

	if (!IS_ELF(*ehdr) || ehdr->e_type != ET_EXEC || class != ELFCLASS64) {
		pr_debug("Not an executable ELF64 image\n");
		return -EPROTONOSUPPORT;
	}

	/* We assume the firmware has the same endianness as the host */
# ifdef __LITTLE_ENDIAN
	if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
# else /* BIG ENDIAN */
	if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
# endif
		pr_debug("Unsupported firmware endianness\n");
		return -EILSEQ;
	}

	if (size < ehdr->e_shoff + sizeof(Elf64_Shdr)) {
		pr_debug("Image is too small\n");
		return -ENOSPC;
	}

	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
		pr_debug("Image is corrupted (bad magic)\n");
		return -EBADF;
	}

	if (ehdr->e_phnum == 0) {
		pr_debug("No loadable segments\n");
		return -ENOEXEC;
	}

	if (ehdr->e_phoff > size) {
		pr_debug("Firmware size is too small\n");
		return -ENOSPC;
	}

	return 0;
}

/* Basic function to verify ELF image format */
int rproc_elf_sanity_check(ulong addr, ulong size)
{
	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;

	if (!addr) {
		dev_err(dev, "Invalid firmware address\n");
		return -EFAULT;
	}

	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
		return rproc_elf64_sanity_check(addr, size);
	else
		return rproc_elf32_sanity_check(addr, size);
}

int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size)
{
	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
	Elf32_Phdr *phdr; /* Program header structure pointer */
	const struct dm_rproc_ops *ops;
	unsigned int i, ret;

	ret =  rproc_elf32_sanity_check(addr, size);
	if (ret) {
		dev_err(dev, "Invalid ELF32 Image %d\n", ret);
		return ret;
	}

	ehdr = (Elf32_Ehdr *)addr;
	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);

	ops = rproc_get_ops(dev);

	/* Load each program header */
	for (i = 0; i < ehdr->e_phnum; ++i) {
		void *dst = (void *)(uintptr_t)phdr->p_paddr;
		void *src = (void *)addr + phdr->p_offset;

		if (phdr->p_type != PT_LOAD)
			continue;

		if (ops->device_to_virt)
			dst = ops->device_to_virt(dev, (ulong)dst,
						  phdr->p_memsz);

		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);
		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
			    roundup((unsigned long)dst + phdr->p_filesz,
				    ARCH_DMA_MINALIGN) -
			    rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
		++phdr;
	}

	return 0;
}

int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
{
	const struct dm_rproc_ops *ops = rproc_get_ops(dev);
	u64 da, memsz, filesz, offset;
	Elf64_Ehdr *ehdr;
	Elf64_Phdr *phdr;
	int i, ret = 0;
	void *ptr;

	dev_dbg(dev, "%s: addr = 0x%lx size = 0x%lx\n", __func__, addr, size);

	if (rproc_elf64_sanity_check(addr, size))
		return -EINVAL;

	ehdr = (Elf64_Ehdr *)addr;
	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);

	/* go through the available ELF segments */
	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
		da = phdr->p_paddr;
		memsz = phdr->p_memsz;
		filesz = phdr->p_filesz;
		offset = phdr->p_offset;

		if (phdr->p_type != PT_LOAD)
			continue;

		dev_dbg(dev, "%s:phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
			__func__, phdr->p_type, da, memsz, filesz);

		ptr = (void *)(uintptr_t)da;
		if (ops->device_to_virt) {
			ptr = ops->device_to_virt(dev, da, phdr->p_memsz);
			if (!ptr) {
				dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da,
					memsz);
				ret = -EINVAL;
				break;
			}
		}

		if (filesz)
			memcpy(ptr, (void *)addr + offset, filesz);
		if (filesz != memsz)
			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));
	}

	return ret;
}

int rproc_elf_load_image(struct udevice *dev, ulong addr, ulong size)
{
	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;

	if (!addr) {
		dev_err(dev, "Invalid firmware address\n");
		return -EFAULT;
	}

	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
		return rproc_elf64_load_image(dev, addr, size);
	else
		return rproc_elf32_load_image(dev, addr, size);
}

static ulong rproc_elf32_get_boot_addr(ulong addr)
{
	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;

	return ehdr->e_entry;
}

static ulong rproc_elf64_get_boot_addr(ulong addr)
{
	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;

	return ehdr->e_entry;
}

ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
{
	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;

	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
		return rproc_elf64_get_boot_addr(addr);
	else
		return rproc_elf32_get_boot_addr(addr);
}

/*
 * Search for the resource table in an ELF32 image.
 * Returns the address of the resource table section if found, NULL if there is
 * no resource table section, or error pointer.
 */
static Elf32_Shdr *rproc_elf32_find_rsc_table(struct udevice *dev,
					      ulong fw_addr, ulong fw_size)
{
	int ret;
	unsigned int i;
	const char *name_table;
	struct resource_table *table;
	const u8 *elf_data = (void *)fw_addr;
	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr;
	Elf32_Shdr *shdr;

	ret = rproc_elf32_sanity_check(fw_addr, fw_size);
	if (ret) {
		pr_debug("Invalid ELF32 Image %d\n", ret);
		return ERR_PTR(ret);
	}

	/* look for the resource table and handle it */
	shdr = (Elf32_Shdr *)(elf_data + ehdr->e_shoff);
	name_table = (const char *)(elf_data +
				    shdr[ehdr->e_shstrndx].sh_offset);

	for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
		u32 size = shdr->sh_size;
		u32 offset = shdr->sh_offset;

		if (strcmp(name_table + shdr->sh_name, ".resource_table"))
			continue;

		table = (struct resource_table *)(elf_data + offset);

		/* make sure we have the entire table */
		if (offset + size > fw_size) {
			pr_debug("resource table truncated\n");
			return ERR_PTR(-ENOSPC);
		}

		/* make sure table has at least the header */
		if (sizeof(*table) > size) {
			pr_debug("header-less resource table\n");
			return ERR_PTR(-ENOSPC);
		}

		/* we don't support any version beyond the first */
		if (table->ver != 1) {
			pr_debug("unsupported fw ver: %d\n", table->ver);
			return ERR_PTR(-EPROTONOSUPPORT);
		}

		/* make sure reserved bytes are zeroes */
		if (table->reserved[0] || table->reserved[1]) {
			pr_debug("non zero reserved bytes\n");
			return ERR_PTR(-EBADF);
		}

		/* make sure the offsets array isn't truncated */
		if (table->num * sizeof(table->offset[0]) +
				 sizeof(*table) > size) {
			pr_debug("resource table incomplete\n");
			return ERR_PTR(-ENOSPC);
		}

		return shdr;
	}

	return NULL;
}

/* Load the resource table from an ELF32 image */
int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
			       ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
{
	const struct dm_rproc_ops *ops;
	Elf32_Shdr *shdr;
	void *src, *dst;

	shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size);
	if (!shdr)
		return -ENODATA;
	if (IS_ERR(shdr))
		return PTR_ERR(shdr);

	ops = rproc_get_ops(dev);
	*rsc_addr = (ulong)shdr->sh_addr;
	*rsc_size = (ulong)shdr->sh_size;

	src = (void *)fw_addr + shdr->sh_offset;
	if (ops->device_to_virt)
		dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
	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));

	return 0;
}

/*
 * Search for the resource table in an ELF64 image.
 * Returns the address of the resource table section if found, NULL if there is
 * no resource table section, or error pointer.
 */
static Elf64_Shdr *rproc_elf64_find_rsc_table(struct udevice *dev,
					      ulong fw_addr, ulong fw_size)
{
	int ret;
	unsigned int i;
	const char *name_table;
	struct resource_table *table;
	const u8 *elf_data = (void *)fw_addr;
	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)fw_addr;
	Elf64_Shdr *shdr;

	ret = rproc_elf64_sanity_check(fw_addr, fw_size);
	if (ret) {
		pr_debug("Invalid ELF64 Image %d\n", ret);
		return ERR_PTR(ret);
	}

	/* look for the resource table and handle it */
	shdr = (Elf64_Shdr *)(elf_data + ehdr->e_shoff);
	name_table = (const char *)(elf_data +
				    shdr[ehdr->e_shstrndx].sh_offset);

	for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
		u64 size = shdr->sh_size;
		u64 offset = shdr->sh_offset;

		if (strcmp(name_table + shdr->sh_name, ".resource_table"))
			continue;

		table = (struct resource_table *)(elf_data + offset);

		/* make sure we have the entire table */
		if (offset + size > fw_size) {
			pr_debug("resource table truncated\n");
			return ERR_PTR(-ENOSPC);
		}

		/* make sure table has at least the header */
		if (sizeof(*table) > size) {
			pr_debug("header-less resource table\n");
			return ERR_PTR(-ENOSPC);
		}

		/* we don't support any version beyond the first */
		if (table->ver != 1) {
			pr_debug("unsupported fw ver: %d\n", table->ver);
			return ERR_PTR(-EPROTONOSUPPORT);
		}

		/* make sure reserved bytes are zeroes */
		if (table->reserved[0] || table->reserved[1]) {
			pr_debug("non zero reserved bytes\n");
			return ERR_PTR(-EBADF);
		}

		/* make sure the offsets array isn't truncated */
		if (table->num * sizeof(table->offset[0]) +
				 sizeof(*table) > size) {
			pr_debug("resource table incomplete\n");
			return ERR_PTR(-ENOSPC);
		}

		return shdr;
	}

	return NULL;
}

/* Load the resource table from an ELF64 image */
int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
			       ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
{
	const struct dm_rproc_ops *ops;
	Elf64_Shdr *shdr;
	void *src, *dst;

	shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size);
	if (!shdr)
		return -ENODATA;
	if (IS_ERR(shdr))
		return PTR_ERR(shdr);

	ops = rproc_get_ops(dev);
	*rsc_addr = (ulong)shdr->sh_addr;
	*rsc_size = (ulong)shdr->sh_size;

	src = (void *)fw_addr + shdr->sh_offset;
	if (ops->device_to_virt)
		dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
	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));

	return 0;
}

/* Load the resource table from an ELF32 or ELF64 image */
int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
			     ulong fw_size, ulong *rsc_addr, ulong *rsc_size)

{
	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr;

	if (!fw_addr)
		return -EFAULT;

	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
		return rproc_elf64_load_rsc_table(dev, fw_addr, fw_size,
						  rsc_addr, rsc_size);
	else
		return rproc_elf32_load_rsc_table(dev, fw_addr, fw_size,
						  rsc_addr, rsc_size);
}
