Qualcomm remote processor may rely on static and dynamic resources for
it to be functional. For most of the Qualcomm SoCs, when run with Gunyah
or older QHEE hypervisor, all the resources whether it is static or
dynamic, is managed by the hypervisor. Dynamic resources if it is
present for a remote processor will always be coming from secure world
via SMC call while static resources may be present in remote processor
firmware binary or it may be coming from SMC call along with dynamic
resources.

Remoteproc already has method like rproc_elf_load_rsc_table() to check
firmware binary has resources or not and if it is not having then we
pass NULL and zero as input resource table and its size argument
respectively to qcom_scm_pas_get_rsc_table() and while it has resource
present then it should pass the present resources to Trustzone(TZ) so that
it could authenticate the present resources and append dynamic resource
to return in output_rt argument along with authenticated resources.

Extend parse_fw callback to include SMC call to get resources from
Trustzone and to leverage resource table parsing and mapping and
unmapping code from the remoteproc framework.

Signed-off-by: Mukesh Ojha <mukesh.o...@oss.qualcomm.com>
---
 drivers/remoteproc/qcom_q6v5_pas.c | 60 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_pas.c 
b/drivers/remoteproc/qcom_q6v5_pas.c
index ad87e0334a7d..9a0c0e8f5506 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -34,6 +34,7 @@
 #define QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS     100
 
 #define MAX_ASSIGN_COUNT 3
+#define MAX_RSCTABLE_SIZE      SZ_16K
 
 struct qcom_pas_data {
        int crash_reason_smem;
@@ -408,6 +409,61 @@ static void *qcom_pas_da_to_va(struct rproc *rproc, u64 
da, size_t len, bool *is
        return pas->mem_region + offset;
 }
 
+static int qcom_pas_parse_firmware(struct rproc *rproc, const struct firmware 
*fw)
+{
+       size_t output_rt_size = MAX_RSCTABLE_SIZE;
+       struct qcom_pas *pas = rproc->priv;
+       struct resource_table *table = NULL;
+       void *output_rt;
+       size_t table_sz;
+       int ret;
+
+       ret = qcom_register_dump_segments(rproc, fw);
+       if (ret) {
+               dev_err(pas->dev, "Error in registering dump segments\n");
+               return ret;
+       }
+
+       if (!rproc->has_iommu)
+               return ret;
+
+       ret = rproc_elf_load_rsc_table(rproc, fw);
+       if (ret)
+               dev_info(&rproc->dev, "Error in loading resource table from 
firmware\n");
+
+       table = rproc->table_ptr;
+       table_sz = rproc->table_sz;
+
+       /*
+        * Qualcomm remote processor may rely on static and dynamic resources 
for
+        * it to be functional. For most of the Qualcomm SoCs, when run with 
Gunyah
+        * or older QHEE hypervisor, all the resources whether it is static or 
dynamic,
+        * is managed by present hypervisor. Dynamic resources if it is present 
for
+        * a remote processor will always be coming from secure world via SMC 
call
+        * while static resources may be present in remote processor firmware 
binary
+        * or it may be coming from SMC call along with dynamic resources.
+        *
+        * Here, we call rproc_elf_load_rsc_table() to check firmware binary 
has resources
+        * or not and if it is not having then we pass NULL and zero as input 
resource
+        * table pointer and size respectively to the argument of 
qcom_scm_pas_get_rsc_table()
+        * and this is even true for Qualcomm remote processor who does follow 
remoteproc
+        * framework.
+        */
+       ret = qcom_scm_pas_get_rsc_table(pas->pas_id, table, table_sz, 
&output_rt,
+                                        &output_rt_size);
+       if (ret) {
+               dev_err(pas->dev, "error %d getting resource_table\n", ret);
+               return ret;
+       }
+
+       kfree(rproc->cached_table);
+       rproc->cached_table = output_rt;
+       rproc->table_ptr = rproc->cached_table;
+       rproc->table_sz = output_rt_size;
+
+       return ret;
+}
+
 static unsigned long qcom_pas_panic(struct rproc *rproc)
 {
        struct qcom_pas *pas = rproc->priv;
@@ -420,7 +476,7 @@ static const struct rproc_ops qcom_pas_ops = {
        .start = qcom_pas_start,
        .stop = qcom_pas_stop,
        .da_to_va = qcom_pas_da_to_va,
-       .parse_fw = qcom_register_dump_segments,
+       .parse_fw = qcom_pas_parse_firmware,
        .load = qcom_pas_load,
        .panic = qcom_pas_panic,
 };
@@ -430,7 +486,7 @@ static const struct rproc_ops qcom_pas_minidump_ops = {
        .start = qcom_pas_start,
        .stop = qcom_pas_stop,
        .da_to_va = qcom_pas_da_to_va,
-       .parse_fw = qcom_register_dump_segments,
+       .parse_fw = qcom_pas_parse_firmware,
        .load = qcom_pas_load,
        .panic = qcom_pas_panic,
        .coredump = qcom_pas_minidump,

-- 
2.50.1


Reply via email to