Typically the firmware files for the various remoteprocs is split in a number
of files. But in some releases these files are available in their unsplit form.
Extend the mdt loader to detect the unsplit firmware and load it transparently.
Also expose the function that compose the metadata header for validation and
use this from the modem remoteproc driver, so that it can support unsplit files
as well.
Bjorn Andersson (2):
soc: qcom: mdt_loader: Support loading non-split images
remoteproc: qcom: q6v5-mss: Support loading non-split images
drivers/remoteproc/qcom_q6v5_mss.c | 33 ++++++++---
drivers/soc/qcom/mdt_loader.c | 88 ++++++++++++++++++++++++++++-
include/linux/soc/qcom/mdt_loader.h | 2 +
3 files changed, 112 insertions(+), 11 deletions(-)
--
2.18.0
In some software releases the firmware images are not split up with each
loadable segment in it's own file. Check the size of the loaded firmware
to see if it still contains each segment to be loaded, before falling
back to the split-out segments.
Signed-off-by: Bjorn Andersson <[email protected]>
---
drivers/remoteproc/qcom_q6v5_mss.c | 33 ++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index 981581bcdd56..8fcf9d28dd73 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -659,23 +659,29 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
{
unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
dma_addr_t phys;
+ void *metadata;
int mdata_perm;
int xferop_ret;
+ size_t size;
void *ptr;
int ret;
- ptr = dma_alloc_attrs(qproc->dev, fw->size, &phys, GFP_KERNEL, dma_attrs);
+ metadata = qcom_mdt_read_metadata(fw, &size);
+ if (IS_ERR(metadata))
+ return PTR_ERR(metadata);
+
+ ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs);
if (!ptr) {
+ kfree(metadata);
dev_err(qproc->dev, "failed to allocate mdt buffer\n");
return -ENOMEM;
}
- memcpy(ptr, fw->data, fw->size);
+ memcpy(ptr, metadata, size);
/* Hypervisor mapping to access metadata by modem */
mdata_perm = BIT(QCOM_SCM_VMID_HLOS);
- ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm,
- true, phys, fw->size);
+ ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, phys, size);
if (ret) {
dev_err(qproc->dev,
"assigning Q6 access to metadata failed: %d\n", ret);
@@ -693,14 +699,14 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
/* Metadata authentication done, remove modem access */
- xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm,
- false, phys, fw->size);
+ xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, phys, size);
if (xferop_ret)
dev_warn(qproc->dev,
"mdt buffer not reclaimed system may become unstable\n");
free_dma_attrs:
- dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
+ dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs);
+ kfree(metadata);
return ret < 0 ? ret : 0;
}
@@ -981,7 +987,18 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
ptr = qproc->mpss_region + offset;
- if (phdr->p_filesz) {
+ if (phdr->p_filesz && phdr->p_offset < fw->size) {
+ /* Firmware is large enough to be non-split */
+ if (phdr->p_offset + phdr->p_filesz > fw->size) {
+ dev_err(qproc->dev,
+ "failed to load segment %d from truncated file %s\n",
+ i, fw_name);
+ ret = -EINVAL;
+ goto release_firmware;
+ }
+
+ memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz);
+ } else if (phdr->p_filesz) {
/* Replace "xxx.xxx" with "xxx.bxx" */
sprintf(fw_name + fw_name_len - 3, "b%02d", i);
ret = request_firmware(&seg_fw, fw_name, qproc->dev);
--
2.18.0
On Fri, Jun 21, 2019 at 7:22 PM Bjorn Andersson
<[email protected]> wrote:
>
> In some software releases the firmware images are not split up with each
> loadable segment in it's own file. Check the size of the loaded firmware
> to see if it still contains each segment to be loaded, before falling
> back to the split-out segments.
>
> Signed-off-by: Bjorn Andersson <[email protected]>
Reviewed-by: Jeffrey Hugo <[email protected]>
On Fri 21 Jun 18:21 PDT 2019, Bjorn Andersson wrote:
> Typically the firmware files for the various remoteprocs is split in a number
> of files. But in some releases these files are available in their unsplit form.
>
> Extend the mdt loader to detect the unsplit firmware and load it transparently.
>
> Also expose the function that compose the metadata header for validation and
> use this from the modem remoteproc driver, so that it can support unsplit files
> as well.
>
Applied the two patches. Thanks Andy & Jeff.
Regards,
Bjorn
> Bjorn Andersson (2):
> soc: qcom: mdt_loader: Support loading non-split images
> remoteproc: qcom: q6v5-mss: Support loading non-split images
>
> drivers/remoteproc/qcom_q6v5_mss.c | 33 ++++++++---
> drivers/soc/qcom/mdt_loader.c | 88 ++++++++++++++++++++++++++++-
> include/linux/soc/qcom/mdt_loader.h | 2 +
> 3 files changed, 112 insertions(+), 11 deletions(-)
>
> --
> 2.18.0
>