// 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>
#include <dm/device_compat.h>
#include <linux/compat.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++, phdr++) {
		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));
	}

	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);
}
