// SPDX-License-Identifier: GPL-2.0-only /* * Remote Processor Framework ELF loader * * Copyright (C) 2011 Texas Instruments, Inc. * Copyright (C) 2011 Google, Inc. * * Ohad Ben-Cohen <[email protected]> * Brian Swetland <[email protected]> * Mark Grosen <[email protected]> * Fernando Guzman Lugo <[email protected]> * Suman Anna <[email protected]> * Robert Tivy <[email protected]> * Armando Uribe De Leon <[email protected]> * Sjur Brændeland <[email protected]> */ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/firmware.h> #include <linux/remoteproc.h> #include <linux/elf.h> #include "remoteproc_internal.h" #include "remoteproc_elf_helpers.h" /** * rproc_elf_sanity_check() - Sanity Check for ELF32/ELF64 firmware image * @rproc: the remote processor handle * @fw: the ELF firmware image * * Make sure this fw image is sane (ie a correct ELF32/ELF64 file). * * Return: 0 on success and -EINVAL upon any failure */ int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw) { … } EXPORT_SYMBOL(…); /** * rproc_elf_get_boot_addr() - Get rproc's boot address. * @rproc: the remote processor handle * @fw: the ELF firmware image * * Note that the boot address is not a configurable property of all remote * processors. Some will always boot at a specific hard-coded address. * * Return: entry point address of the ELF image * */ u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw) { … } EXPORT_SYMBOL(…); /** * rproc_elf_load_segments() - load firmware segments to memory * @rproc: remote processor which will be booted using these fw segments * @fw: the ELF firmware image * * This function loads the firmware segments to memory, where the remote * processor expects them. * * Some remote processors will expect their code and data to be placed * in specific device addresses, and can't have them dynamically assigned. * * We currently support only those kind of remote processors, and expect * the program header's paddr member to contain those addresses. We then go * through the physically contiguous "carveout" memory regions which we * allocated (and mapped) earlier on behalf of the remote processor, * and "translate" device address to kernel addresses, so we can copy the * segments where they are expected. * * Currently we only support remote processors that required carveout * allocations and got them mapped onto their iommus. Some processors * might be different: they might not have iommus, and would prefer to * directly allocate memory for every segment/resource. This is not yet * supported, though. * * Return: 0 on success and an appropriate error code otherwise */ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) { … } EXPORT_SYMBOL(…); static const void * find_table(struct device *dev, const struct firmware *fw) { … } /** * rproc_elf_load_rsc_table() - load the resource table * @rproc: the rproc handle * @fw: the ELF firmware image * * This function finds the resource table inside the remote processor's * firmware, load it into the @cached_table and update @table_ptr. * * Return: 0 on success, negative errno on failure. */ int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw) { … } EXPORT_SYMBOL(…); /** * rproc_elf_find_loaded_rsc_table() - find the loaded resource table * @rproc: the rproc handle * @fw: the ELF firmware image * * This function finds the location of the loaded resource table. Don't * call this function if the table wasn't loaded yet - it's a bug if you do. * * Return: pointer to the resource table if it is found or NULL otherwise. * If the table wasn't loaded yet the result is unspecified. */ struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw) { … } EXPORT_SYMBOL(…);