--- zzzz-none-000/linux-4.4.271/drivers/remoteproc/remoteproc_elf_loader.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/drivers/remoteproc/remoteproc_elf_loader.c 2023-04-19 10:22:29.000000000 +0000 @@ -39,8 +39,7 @@ * * Make sure this fw image is sane. */ -static int -rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw) +int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw) { const char *name = rproc->firmware; struct device *dev = &rproc->dev; @@ -98,6 +97,7 @@ return 0; } +EXPORT_SYMBOL(rproc_elf_sanity_check); /** * rproc_elf_get_boot_addr() - Get rproc's boot address. @@ -110,13 +110,13 @@ * Note that the boot address is not a configurable property of all remote * processors. Some will always boot at a specific hard-coded address. */ -static u32 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw) { struct elf32_hdr *ehdr = (struct elf32_hdr *)fw->data; return ehdr->e_entry; } +EXPORT_SYMBOL(rproc_elf_get_boot_addr); /** * rproc_elf_load_segments() - load firmware segments to memory @@ -142,8 +142,7 @@ * directly allocate memory for every segment/resource. This is not yet * supported, though. */ -static int -rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) +int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) { struct device *dev = &rproc->dev; struct elf32_hdr *ehdr; @@ -166,18 +165,18 @@ continue; dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n", - phdr->p_type, da, memsz, filesz); + phdr->p_type, da, memsz, filesz); if (filesz > memsz) { dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n", - filesz, memsz); + filesz, memsz); ret = -EINVAL; break; } if (offset + filesz > fw->size) { dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", - offset + filesz, fw->size); + offset + filesz, fw->size); ret = -EINVAL; break; } @@ -207,6 +206,7 @@ return ret; } +EXPORT_SYMBOL(rproc_elf_load_segments); static struct elf32_shdr * find_table(struct device *dev, struct elf32_hdr *ehdr, size_t fw_size) @@ -268,41 +268,49 @@ } /** - * rproc_elf_find_rsc_table() - find the resource table + * rproc_elf_load_rsc_table() - load the resource table * @rproc: the rproc handle * @fw: the ELF firmware image - * @tablesz: place holder for providing back the table size * * This function finds the resource table inside the remote processor's - * firmware. It is used both upon the registration of @rproc (in order - * to look for and register the supported virito devices), and when the - * @rproc is booted. - * - * Returns the pointer to the resource table if it is found, and write its - * size into @tablesz. If a valid table isn't found, NULL is returned - * (and @tablesz isn't set). + * firmware, load it into the @cached_table and update @table_ptr. + * + * Return: 0 on success, negative errno on failure. */ -static struct resource_table * -rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw, - int *tablesz) +int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw) { struct elf32_hdr *ehdr; struct elf32_shdr *shdr; struct device *dev = &rproc->dev; struct resource_table *table = NULL; const u8 *elf_data = fw->data; + size_t tablesz; ehdr = (struct elf32_hdr *)elf_data; shdr = find_table(dev, ehdr, fw->size); if (!shdr) - return NULL; + return -EINVAL; table = (struct resource_table *)(elf_data + shdr->sh_offset); - *tablesz = shdr->sh_size; + tablesz = shdr->sh_size; + + /* + * Create a copy of the resource table. When a virtio device starts + * and calls vring_new_virtqueue() the address of the allocated vring + * will be stored in the cached_table. Before the device is started, + * cached_table will be copied into device memory. + */ + rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); + if (!rproc->cached_table) + return -ENOMEM; - return table; + rproc->table_ptr = rproc->cached_table; + rproc->table_sz = tablesz; + + return 0; } +EXPORT_SYMBOL(rproc_elf_load_rsc_table); /** * rproc_elf_find_loaded_rsc_table() - find the loaded resource table @@ -315,8 +323,8 @@ * Returns the pointer to the resource table if it is found or NULL otherwise. * If the table wasn't loaded yet the result is unspecified. */ -static struct resource_table * -rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw) +struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc, + const struct firmware *fw) { struct elf32_hdr *ehdr = (struct elf32_hdr *)fw->data; struct elf32_shdr *shdr; @@ -327,11 +335,4 @@ return rproc_da_to_va(rproc, shdr->sh_addr, shdr->sh_size); } - -const struct rproc_fw_ops rproc_elf_fw_ops = { - .load = rproc_elf_load_segments, - .find_rsc_table = rproc_elf_find_rsc_table, - .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table, - .sanity_check = rproc_elf_sanity_check, - .get_boot_addr = rproc_elf_get_boot_addr -}; +EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table);