Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e3e2c7c authored by Ohad Ben-Cohen's avatar Ohad Ben-Cohen
Browse files

remoteproc: cleanup resource table parsing paths



rproc_handle_resources() looks for the resource table and then
invokes a resource handler function which it took as a parameter.

This works, but it's a bit unintuitive to follow.

Instead of passing around function pointers, this patch changes
rproc_handle_resource() to just find and return the resource table,
and then the calling sites of rproc_handle_resource() invoke their
resource handlers directly.

Signed-off-by: default avatarOhad Ben-Cohen <ohad@wizery.com>
Cc: Brian Swetland <swetland@google.com>
Cc: Iliyan Malchev <malchev@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Mark Grosen <mgrosen@ti.com>
Cc: John Williams <john.williams@petalogix.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Loic PALLARDY <loic.pallardy@stericsson.com>
Cc: Ludovic BARRE <ludovic.barre@stericsson.com>
Cc: Omar Ramirez Luna <omar.luna@linaro.org>
Cc: Guzman Lugo Fernando <fernando.lugo@ti.com>
Cc: Anna Suman <s-anna@ti.com>
Cc: Clark Rob <rob@ti.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Saravana Kannan <skannan@codeaurora.org>
Cc: David Brown <davidb@codeaurora.org>
Cc: Kieran Bingham <kieranbingham@gmail.com>
Cc: Tony Lindgren <tony@atomide.com>
parent 63140e0e
Loading
Loading
Loading
Loading
+39 −33
Original line number Original line Diff line number Diff line
@@ -822,32 +822,31 @@ rproc_handle_virtio_rsc(struct rproc *rproc, struct resource_table *table, int l
}
}


/**
/**
 * rproc_handle_resources() - find and handle the resource table
 * rproc_find_rsc_table() - find the resource table
 * @rproc: the rproc handle
 * @rproc: the rproc handle
 * @elf_data: the content of the ELF firmware image
 * @elf_data: the content of the ELF firmware image
 * @len: firmware size (in bytes)
 * @len: firmware size (in bytes)
 * @handler: function that should be used to handle the resource table
 * @tablesz: place holder for providing back the table size
 *
 *
 * This function finds the resource table inside the remote processor's
 * This function finds the resource table inside the remote processor's
 * firmware, and invoke a user-supplied handler with it (we have two
 * firmware. It is used both upon the registration of @rproc (in order
 * possible handlers: one is invoked upon registration of @rproc,
 * to look for and register the supported virito devices), and when the
 * in order to register the supported virito devices, and the other is
 * @rproc is booted.
 * invoked when @rproc is actually booted).
 *
 *
 * Returns the pointer to the resource table if it is found, and write its
 * Currently this function fails if a resource table doesn't exist.
 * size into @tablesz. If a valid table isn't found, NULL is returned
 * This restriction will be removed when we'll start supporting remote
 * (and @tablesz isn't set).
 * processors that don't need a resource table.
 */
 */
static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data,
static struct resource_table *
				size_t len, rproc_handle_resources_t handler)
rproc_find_rsc_table(struct rproc *rproc, const u8 *elf_data, size_t len,

							int *tablesz)
{
{
	struct elf32_hdr *ehdr;
	struct elf32_hdr *ehdr;
	struct elf32_shdr *shdr;
	struct elf32_shdr *shdr;
	const char *name_table;
	const char *name_table;
	struct device *dev = rproc->dev;
	struct device *dev = rproc->dev;
	int i, ret = -EINVAL;
	struct resource_table *table = NULL;
	struct resource_table *table;
	int i;


	ehdr = (struct elf32_hdr *)elf_data;
	ehdr = (struct elf32_hdr *)elf_data;
	shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
	shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
@@ -866,39 +865,39 @@ static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data,
		/* make sure we have the entire table */
		/* make sure we have the entire table */
		if (offset + size > len) {
		if (offset + size > len) {
			dev_err(dev, "resource table truncated\n");
			dev_err(dev, "resource table truncated\n");
			return -EINVAL;
			return NULL;
		}
		}


		/* make sure table has at least the header */
		/* make sure table has at least the header */
		if (sizeof(struct resource_table) > size) {
		if (sizeof(struct resource_table) > size) {
			dev_err(dev, "header-less resource table\n");
			dev_err(dev, "header-less resource table\n");
			return -EINVAL;
			return NULL;
		}
		}


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


		/* make sure reserved bytes are zeroes */
		/* make sure reserved bytes are zeroes */
		if (table->reserved[0] || table->reserved[1]) {
		if (table->reserved[0] || table->reserved[1]) {
			dev_err(dev, "non zero reserved bytes\n");
			dev_err(dev, "non zero reserved bytes\n");
			return -EINVAL;
			return NULL;
		}
		}


		/* make sure the offsets array isn't truncated */
		/* make sure the offsets array isn't truncated */
		if (table->num * sizeof(table->offset[0]) +
		if (table->num * sizeof(table->offset[0]) +
				sizeof(struct resource_table) > size) {
				sizeof(struct resource_table) > size) {
			dev_err(dev, "resource table incomplete\n");
			dev_err(dev, "resource table incomplete\n");
			return -EINVAL;
			return NULL;
		}
		}


		ret = handler(rproc, table, shdr->sh_size);
		*tablesz = shdr->sh_size;
		break;
		break;
	}
	}


	return ret;
	return table;
}
}


/**
/**
@@ -1012,7 +1011,8 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
	struct device *dev = rproc->dev;
	struct device *dev = rproc->dev;
	const char *name = rproc->firmware;
	const char *name = rproc->firmware;
	struct elf32_hdr *ehdr;
	struct elf32_hdr *ehdr;
	int ret;
	struct resource_table *table;
	int ret, tablesz;


	ret = rproc_fw_sanity_check(rproc, fw);
	ret = rproc_fw_sanity_check(rproc, fw);
	if (ret)
	if (ret)
@@ -1039,9 +1039,13 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
	 */
	 */
	rproc->bootaddr = ehdr->e_entry;
	rproc->bootaddr = ehdr->e_entry;


	/* look for the resource table */
	table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz);
	if (!table)
		goto clean_up;

	/* handle fw resources which are required to boot rproc */
	/* handle fw resources which are required to boot rproc */
	ret = rproc_handle_resources(rproc, fw->data, fw->size,
	ret = rproc_handle_boot_rsc(rproc, table, tablesz);
						rproc_handle_boot_rsc);
	if (ret) {
	if (ret) {
		dev_err(dev, "Failed to process resources: %d\n", ret);
		dev_err(dev, "Failed to process resources: %d\n", ret);
		goto clean_up;
		goto clean_up;
@@ -1084,19 +1088,21 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
{
{
	struct rproc *rproc = context;
	struct rproc *rproc = context;
	struct device *dev = rproc->dev;
	struct resource_table *table;
	int ret;
	int ret, tablesz;


	if (rproc_fw_sanity_check(rproc, fw) < 0)
	if (rproc_fw_sanity_check(rproc, fw) < 0)
		goto out;
		goto out;


	/* does the fw support any virtio devices ? */
	/* look for the resource table */
	ret = rproc_handle_resources(rproc, fw->data, fw->size,
	table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz);
						rproc_handle_virtio_rsc);
	if (!table)
	if (ret) {
		goto out;
		dev_info(dev, "No fw virtio device was found\n");

	/* look for virtio devices and register them */
	ret = rproc_handle_virtio_rsc(rproc, table, tablesz);
	if (ret)
		goto out;
		goto out;
	}


out:
out:
	if (fw)
	if (fw)