All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Decouple resource table definitions from remoteproc
@ 2026-05-06  5:01 Mukesh Ojha
  2026-05-06  5:01 ` [PATCH 1/5] remoteproc: Move resource table data structure to its own header Mukesh Ojha
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Mukesh Ojha @ 2026-05-06  5:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Mathieu Poirier
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc, Mukesh Ojha

The motivation for this series came from [1], which first introduced
support for Secure PAS with Linux running at EL2. That series covered
both remoteproc subsystems (ADSP/CDSP) and non-remoteproc subsystems
(VIDEO), but resource table parsing was duplicated from the remoteproc
code. The remoteproc driver support for Secure PAS at EL2 has since been
merged, and video enablement is being pursued with [2].

The resource table wire-format structs live in <linux/remoteproc.h>,
but non-remoteproc drivers (e.g. video, GPU) on EL2 SoCs also need
them to parse tables obtained via SCM calls. Move the definitions to
a standalone <linux/rsc_table.h>, add a generic rsc_table_for_each_entry()
iterator, and use it in the remoteproc core and a new Qualcomm MDT
loader API for IOMMU mapping of RSC_DEVMEM entries.

This series is build on top of series
https://lore.kernel.org/lkml/20260430191253.4052025-1-mukesh.ojha@oss.qualcomm.com/
not for technical dependency but for the file change in mdt_loader file.

[1]
https://lore.kernel.org/lkml/aKXqSU-487b6Je2B@linaro.org/

[2]
https://lore.kernel.org/lkml/20260505-glymur-v4-0-17571dbd1caa@oss.qualcomm.com/

Mukesh Ojha (5):
  remoteproc: Move resource table data structure to its own header
  remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources()
  soc: qcom: mdt_loader: add qcom_mdt_pas_map/unmap_devmem_rscs()
  firmware: qcom: scm: replace <linux/remoteproc.h> with
    <linux/rsc_table.h>
  MAINTAINERS: add rsc_table.h to remoteproc entry

 MAINTAINERS                          |   1 +
 drivers/firmware/qcom/qcom_scm.c     |   4 +-
 drivers/remoteproc/remoteproc_core.c |  81 +++---
 drivers/soc/qcom/mdt_loader.c        | 189 ++++++++++++++
 include/linux/remoteproc.h           | 269 +-------------------
 include/linux/rsc_table.h            | 359 +++++++++++++++++++++++++++
 include/linux/soc/qcom/mdt_loader.h  |  22 ++
 7 files changed, 612 insertions(+), 313 deletions(-)
 create mode 100644 include/linux/rsc_table.h

-- 
2.53.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/5] remoteproc: Move resource table data structure to its own header
  2026-05-06  5:01 [PATCH 0/5] Decouple resource table definitions from remoteproc Mukesh Ojha
@ 2026-05-06  5:01 ` Mukesh Ojha
  2026-05-25 15:53   ` Mathieu Poirier
  2026-05-06  5:01 ` [PATCH 2/5] remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources() Mukesh Ojha
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Mukesh Ojha @ 2026-05-06  5:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Mathieu Poirier
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc, Mukesh Ojha

The resource table data structure has traditionally been associated with
the remoteproc framework, where the resource table is included as a
section within the remote processor firmware binary. However, it is also
possible to obtain the resource table through other means—such as from a
reserved memory region populated by the boot firmware, statically
maintained driver data, or via a secure SMC call—when it is not embedded
in the firmware.

There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
etc.) in the upstream kernel that do not use the remoteproc framework to
manage their lifecycle for various reasons.

When Linux is running at EL2, similar to the Qualcomm PAS driver
(qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
also want to use the resource table SMC call to retrieve and map
resources before they are used by the remote processor.

In such cases, the resource table data structure is no longer tightly
coupled with the remoteproc headers. Client drivers that do not use the
remoteproc framework should still be able to parse the resource table
obtained through alternative means. Therefore, there is a need to
decouple the resource table definitions from the remoteproc headers.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 include/linux/remoteproc.h | 269 +-------------------------------
 include/linux/rsc_table.h  | 306 +++++++++++++++++++++++++++++++++++++
 2 files changed, 307 insertions(+), 268 deletions(-)
 create mode 100644 include/linux/rsc_table.h

diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index b4795698d8c2..7c1546d48008 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -42,274 +42,7 @@
 #include <linux/completion.h>
 #include <linux/idr.h>
 #include <linux/of.h>
-
-/**
- * struct resource_table - firmware resource table header
- * @ver: version number
- * @num: number of resource entries
- * @reserved: reserved (must be zero)
- * @offset: array of offsets pointing at the various resource entries
- *
- * A resource table is essentially a list of system resources required
- * by the remote processor. It may also include configuration entries.
- * If needed, the remote processor firmware should contain this table
- * as a dedicated ".resource_table" ELF section.
- *
- * Some resources entries are mere announcements, where the host is informed
- * of specific remoteproc configuration. Other entries require the host to
- * do something (e.g. allocate a system resource). Sometimes a negotiation
- * is expected, where the firmware requests a resource, and once allocated,
- * the host should provide back its details (e.g. address of an allocated
- * memory region).
- *
- * The header of the resource table, as expressed by this structure,
- * contains a version number (should we need to change this format in the
- * future), the number of available resource entries, and their offsets
- * in the table.
- *
- * Immediately following this header are the resource entries themselves,
- * each of which begins with a resource entry header (as described below).
- */
-struct resource_table {
-	u32 ver;
-	u32 num;
-	u32 reserved[2];
-	u32 offset[];
-} __packed;
-
-/**
- * struct fw_rsc_hdr - firmware resource entry header
- * @type: resource type
- * @data: resource data
- *
- * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
- * its @type. The content of the entry itself will immediately follow
- * this header, and it should be parsed according to the resource type.
- */
-struct fw_rsc_hdr {
-	u32 type;
-	u8 data[];
-} __packed;
-
-/**
- * enum fw_resource_type - types of resource entries
- *
- * @RSC_CARVEOUT:   request for allocation of a physically contiguous
- *		    memory region.
- * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
- * @RSC_TRACE:	    announces the availability of a trace buffer into which
- *		    the remote processor will be writing logs.
- * @RSC_VDEV:       declare support for a virtio device, and serve as its
- *		    virtio header.
- * @RSC_LAST:       just keep this one at the end of standard resources
- * @RSC_VENDOR_START:	start of the vendor specific resource types range
- * @RSC_VENDOR_END:	end of the vendor specific resource types range
- *
- * For more details regarding a specific resource type, please see its
- * dedicated structure below.
- *
- * Please note that these values are used as indices to the rproc_handle_rsc
- * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
- * check the validity of an index before the lookup table is accessed, so
- * please update it as needed.
- */
-enum fw_resource_type {
-	RSC_CARVEOUT		= 0,
-	RSC_DEVMEM		= 1,
-	RSC_TRACE		= 2,
-	RSC_VDEV		= 3,
-	RSC_LAST		= 4,
-	RSC_VENDOR_START	= 128,
-	RSC_VENDOR_END		= 512,
-};
-
-#define FW_RSC_ADDR_ANY (-1)
-
-/**
- * struct fw_rsc_carveout - physically contiguous memory request
- * @da: device address
- * @pa: physical address
- * @len: length (in bytes)
- * @flags: iommu protection flags
- * @reserved: reserved (must be zero)
- * @name: human-readable name of the requested memory region
- *
- * This resource entry requests the host to allocate a physically contiguous
- * memory region.
- *
- * These request entries should precede other firmware resource entries,
- * as other entries might request placing other data objects inside
- * these memory regions (e.g. data/code segments, trace resource entries, ...).
- *
- * Allocating memory this way helps utilizing the reserved physical memory
- * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
- * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
- * pressure is important; it may have a substantial impact on performance.
- *
- * If the firmware is compiled with static addresses, then @da should specify
- * the expected device address of this memory region. If @da is set to
- * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
- * overwrite @da with the dynamically allocated address.
- *
- * We will always use @da to negotiate the device addresses, even if it
- * isn't using an iommu. In that case, though, it will obviously contain
- * physical addresses.
- *
- * Some remote processors needs to know the allocated physical address
- * even if they do use an iommu. This is needed, e.g., if they control
- * hardware accelerators which access the physical memory directly (this
- * is the case with OMAP4 for instance). In that case, the host will
- * overwrite @pa with the dynamically allocated physical address.
- * Generally we don't want to expose physical addresses if we don't have to
- * (remote processors are generally _not_ trusted), so we might want to
- * change this to happen _only_ when explicitly required by the hardware.
- *
- * @flags is used to provide IOMMU protection flags, and @name should
- * (optionally) contain a human readable name of this carveout region
- * (mainly for debugging purposes).
- */
-struct fw_rsc_carveout {
-	u32 da;
-	u32 pa;
-	u32 len;
-	u32 flags;
-	u32 reserved;
-	u8 name[32];
-} __packed;
-
-/**
- * struct fw_rsc_devmem - iommu mapping request
- * @da: device address
- * @pa: physical address
- * @len: length (in bytes)
- * @flags: iommu protection flags
- * @reserved: reserved (must be zero)
- * @name: human-readable name of the requested region to be mapped
- *
- * This resource entry requests the host to iommu map a physically contiguous
- * memory region. This is needed in case the remote processor requires
- * access to certain memory-based peripherals; _never_ use it to access
- * regular memory.
- *
- * This is obviously only needed if the remote processor is accessing memory
- * via an iommu.
- *
- * @da should specify the required device address, @pa should specify
- * the physical address we want to map, @len should specify the size of
- * the mapping and @flags is the IOMMU protection flags. As always, @name may
- * (optionally) contain a human readable name of this mapping (mainly for
- * debugging purposes).
- *
- * Note: at this point we just "trust" those devmem entries to contain valid
- * physical addresses, but this isn't safe and will be changed: eventually we
- * want remoteproc implementations to provide us ranges of physical addresses
- * the firmware is allowed to request, and not allow firmwares to request
- * access to physical addresses that are outside those ranges.
- */
-struct fw_rsc_devmem {
-	u32 da;
-	u32 pa;
-	u32 len;
-	u32 flags;
-	u32 reserved;
-	u8 name[32];
-} __packed;
-
-/**
- * struct fw_rsc_trace - trace buffer declaration
- * @da: device address
- * @len: length (in bytes)
- * @reserved: reserved (must be zero)
- * @name: human-readable name of the trace buffer
- *
- * This resource entry provides the host information about a trace buffer
- * into which the remote processor will write log messages.
- *
- * @da specifies the device address of the buffer, @len specifies
- * its size, and @name may contain a human readable name of the trace buffer.
- *
- * After booting the remote processor, the trace buffers are exposed to the
- * user via debugfs entries (called trace0, trace1, etc..).
- */
-struct fw_rsc_trace {
-	u32 da;
-	u32 len;
-	u32 reserved;
-	u8 name[32];
-} __packed;
-
-/**
- * struct fw_rsc_vdev_vring - vring descriptor entry
- * @da: device address
- * @align: the alignment between the consumer and producer parts of the vring
- * @num: num of buffers supported by this vring (must be power of two)
- * @notifyid: a unique rproc-wide notify index for this vring. This notify
- * index is used when kicking a remote processor, to let it know that this
- * vring is triggered.
- * @pa: physical address
- *
- * This descriptor is not a resource entry by itself; it is part of the
- * vdev resource type (see below).
- *
- * Note that @da should either contain the device address where
- * the remote processor is expecting the vring, or indicate that
- * dynamically allocation of the vring's device address is supported.
- */
-struct fw_rsc_vdev_vring {
-	u32 da;
-	u32 align;
-	u32 num;
-	u32 notifyid;
-	u32 pa;
-} __packed;
-
-/**
- * struct fw_rsc_vdev - virtio device header
- * @id: virtio device id (as in virtio_ids.h)
- * @notifyid: a unique rproc-wide notify index for this vdev. This notify
- * index is used when kicking a remote processor, to let it know that the
- * status/features of this vdev have changes.
- * @dfeatures: specifies the virtio device features supported by the firmware
- * @gfeatures: a place holder used by the host to write back the
- * negotiated features that are supported by both sides.
- * @config_len: the size of the virtio config space of this vdev. The config
- * space lies in the resource table immediate after this vdev header.
- * @status: a place holder where the host will indicate its virtio progress.
- * @num_of_vrings: indicates how many vrings are described in this vdev header
- * @reserved: reserved (must be zero)
- * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
- *
- * This resource is a virtio device header: it provides information about
- * the vdev, and is then used by the host and its peer remote processors
- * to negotiate and share certain virtio properties.
- *
- * By providing this resource entry, the firmware essentially asks remoteproc
- * to statically allocate a vdev upon registration of the rproc (dynamic vdev
- * allocation is not yet supported).
- *
- * Note:
- * 1. unlike virtualization systems, the term 'host' here means
- *    the Linux side which is running remoteproc to control the remote
- *    processors. We use the name 'gfeatures' to comply with virtio's terms,
- *    though there isn't really any virtualized guest OS here: it's the host
- *    which is responsible for negotiating the final features.
- *    Yeah, it's a bit confusing.
- *
- * 2. immediately following this structure is the virtio config space for
- *    this vdev (which is specific to the vdev; for more info, read the virtio
- *    spec). The size of the config space is specified by @config_len.
- */
-struct fw_rsc_vdev {
-	u32 id;
-	u32 notifyid;
-	u32 dfeatures;
-	u32 gfeatures;
-	u32 config_len;
-	u8 status;
-	u8 num_of_vrings;
-	u8 reserved[2];
-	struct fw_rsc_vdev_vring vring[];
-} __packed;
+#include <linux/rsc_table.h>
 
 struct rproc;
 
diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h
new file mode 100644
index 000000000000..c32c8b6cd2a7
--- /dev/null
+++ b/include/linux/rsc_table.h
@@ -0,0 +1,306 @@
+/*
+ * Resource table and its types data structure
+ *
+ * Copyright(c) 2011 Texas Instruments, Inc.
+ * Copyright(c) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RSC_TABLE_H
+#define RSC_TABLE_H
+
+/**
+ * struct resource_table - firmware resource table header
+ * @ver: version number
+ * @num: number of resource entries
+ * @reserved: reserved (must be zero)
+ * @offset: array of offsets pointing at the various resource entries
+ *
+ * A resource table is essentially a list of system resources required
+ * by the remote processor. It may also include configuration entries.
+ * If needed, the remote processor firmware should contain this table
+ * as a dedicated ".resource_table" ELF section.
+ *
+ * Some resources entries are mere announcements, where the host is informed
+ * of specific remoteproc configuration. Other entries require the host to
+ * do something (e.g. allocate a system resource). Sometimes a negotiation
+ * is expected, where the firmware requests a resource, and once allocated,
+ * the host should provide back its details (e.g. address of an allocated
+ * memory region).
+ *
+ * The header of the resource table, as expressed by this structure,
+ * contains a version number (should we need to change this format in the
+ * future), the number of available resource entries, and their offsets
+ * in the table.
+ *
+ * Immediately following this header are the resource entries themselves,
+ * each of which begins with a resource entry header (as described below).
+ */
+struct resource_table {
+	u32 ver;
+	u32 num;
+	u32 reserved[2];
+	u32 offset[];
+} __packed;
+
+/**
+ * struct fw_rsc_hdr - firmware resource entry header
+ * @type: resource type
+ * @data: resource data
+ *
+ * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
+ * its @type. The content of the entry itself will immediately follow
+ * this header, and it should be parsed according to the resource type.
+ */
+struct fw_rsc_hdr {
+	u32 type;
+	u8 data[];
+} __packed;
+
+/**
+ * enum fw_resource_type - types of resource entries
+ *
+ * @RSC_CARVEOUT:   request for allocation of a physically contiguous
+ *		    memory region.
+ * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
+ * @RSC_TRACE:	    announces the availability of a trace buffer into which
+ *		    the remote processor will be writing logs.
+ * @RSC_VDEV:       declare support for a virtio device, and serve as its
+ *		    virtio header.
+ * @RSC_LAST:       just keep this one at the end of standard resources
+ * @RSC_VENDOR_START:	start of the vendor specific resource types range
+ * @RSC_VENDOR_END:	end of the vendor specific resource types range
+ *
+ * For more details regarding a specific resource type, please see its
+ * dedicated structure below.
+ *
+ * Please note that these values are used as indices to the rproc_handle_rsc
+ * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
+ * check the validity of an index before the lookup table is accessed, so
+ * please update it as needed.
+ */
+enum fw_resource_type {
+	RSC_CARVEOUT		= 0,
+	RSC_DEVMEM		= 1,
+	RSC_TRACE		= 2,
+	RSC_VDEV		= 3,
+	RSC_LAST		= 4,
+	RSC_VENDOR_START	= 128,
+	RSC_VENDOR_END		= 512,
+};
+
+#define FW_RSC_ADDR_ANY (-1)
+
+/**
+ * struct fw_rsc_carveout - physically contiguous memory request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested memory region
+ *
+ * This resource entry requests the host to allocate a physically contiguous
+ * memory region.
+ *
+ * These request entries should precede other firmware resource entries,
+ * as other entries might request placing other data objects inside
+ * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ *
+ * Allocating memory this way helps utilizing the reserved physical memory
+ * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
+ * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
+ * pressure is important; it may have a substantial impact on performance.
+ *
+ * If the firmware is compiled with static addresses, then @da should specify
+ * the expected device address of this memory region. If @da is set to
+ * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
+ * overwrite @da with the dynamically allocated address.
+ *
+ * We will always use @da to negotiate the device addresses, even if it
+ * isn't using an iommu. In that case, though, it will obviously contain
+ * physical addresses.
+ *
+ * Some remote processors needs to know the allocated physical address
+ * even if they do use an iommu. This is needed, e.g., if they control
+ * hardware accelerators which access the physical memory directly (this
+ * is the case with OMAP4 for instance). In that case, the host will
+ * overwrite @pa with the dynamically allocated physical address.
+ * Generally we don't want to expose physical addresses if we don't have to
+ * (remote processors are generally _not_ trusted), so we might want to
+ * change this to happen _only_ when explicitly required by the hardware.
+ *
+ * @flags is used to provide IOMMU protection flags, and @name should
+ * (optionally) contain a human readable name of this carveout region
+ * (mainly for debugging purposes).
+ */
+struct fw_rsc_carveout {
+	u32 da;
+	u32 pa;
+	u32 len;
+	u32 flags;
+	u32 reserved;
+	u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_devmem - iommu mapping request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested region to be mapped
+ *
+ * This resource entry requests the host to iommu map a physically contiguous
+ * memory region. This is needed in case the remote processor requires
+ * access to certain memory-based peripherals; _never_ use it to access
+ * regular memory.
+ *
+ * This is obviously only needed if the remote processor is accessing memory
+ * via an iommu.
+ *
+ * @da should specify the required device address, @pa should specify
+ * the physical address we want to map, @len should specify the size of
+ * the mapping and @flags is the IOMMU protection flags. As always, @name may
+ * (optionally) contain a human readable name of this mapping (mainly for
+ * debugging purposes).
+ *
+ * Note: at this point we just "trust" those devmem entries to contain valid
+ * physical addresses, but this isn't safe and will be changed: eventually we
+ * want remoteproc implementations to provide us ranges of physical addresses
+ * the firmware is allowed to request, and not allow firmwares to request
+ * access to physical addresses that are outside those ranges.
+ */
+struct fw_rsc_devmem {
+	u32 da;
+	u32 pa;
+	u32 len;
+	u32 flags;
+	u32 reserved;
+	u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_trace - trace buffer declaration
+ * @da: device address
+ * @len: length (in bytes)
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the trace buffer
+ *
+ * This resource entry provides the host information about a trace buffer
+ * into which the remote processor will write log messages.
+ *
+ * @da specifies the device address of the buffer, @len specifies
+ * its size, and @name may contain a human readable name of the trace buffer.
+ *
+ * After booting the remote processor, the trace buffers are exposed to the
+ * user via debugfs entries (called trace0, trace1, etc..).
+ */
+struct fw_rsc_trace {
+	u32 da;
+	u32 len;
+	u32 reserved;
+	u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_vdev_vring - vring descriptor entry
+ * @da: device address
+ * @align: the alignment between the consumer and producer parts of the vring
+ * @num: num of buffers supported by this vring (must be power of two)
+ * @notifyid: a unique rproc-wide notify index for this vring. This notify
+ * index is used when kicking a remote processor, to let it know that this
+ * vring is triggered.
+ * @pa: physical address
+ *
+ * This descriptor is not a resource entry by itself; it is part of the
+ * vdev resource type (see below).
+ *
+ * Note that @da should either contain the device address where
+ * the remote processor is expecting the vring, or indicate that
+ * dynamically allocation of the vring's device address is supported.
+ */
+struct fw_rsc_vdev_vring {
+	u32 da;
+	u32 align;
+	u32 num;
+	u32 notifyid;
+	u32 pa;
+} __packed;
+
+/**
+ * struct fw_rsc_vdev - virtio device header
+ * @id: virtio device id (as in virtio_ids.h)
+ * @notifyid: a unique rproc-wide notify index for this vdev. This notify
+ * index is used when kicking a remote processor, to let it know that the
+ * status/features of this vdev have changes.
+ * @dfeatures: specifies the virtio device features supported by the firmware
+ * @gfeatures: a place holder used by the host to write back the
+ * negotiated features that are supported by both sides.
+ * @config_len: the size of the virtio config space of this vdev. The config
+ * space lies in the resource table immediate after this vdev header.
+ * @status: a place holder where the host will indicate its virtio progress.
+ * @num_of_vrings: indicates how many vrings are described in this vdev header
+ * @reserved: reserved (must be zero)
+ * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
+ *
+ * This resource is a virtio device header: it provides information about
+ * the vdev, and is then used by the host and its peer remote processors
+ * to negotiate and share certain virtio properties.
+ *
+ * By providing this resource entry, the firmware essentially asks remoteproc
+ * to statically allocate a vdev upon registration of the rproc (dynamic vdev
+ * allocation is not yet supported).
+ *
+ * Note:
+ * 1. unlike virtualization systems, the term 'host' here means
+ *    the Linux side which is running remoteproc to control the remote
+ *    processors. We use the name 'gfeatures' to comply with virtio's terms,
+ *    though there isn't really any virtualized guest OS here: it's the host
+ *    which is responsible for negotiating the final features.
+ *    Yeah, it's a bit confusing.
+ *
+ * 2. immediately following this structure is the virtio config space for
+ *    this vdev (which is specific to the vdev; for more info, read the virtio
+ *    spec). The size of the config space is specified by @config_len.
+ */
+struct fw_rsc_vdev {
+	u32 id;
+	u32 notifyid;
+	u32 dfeatures;
+	u32 gfeatures;
+	u32 config_len;
+	u8 status;
+	u8 num_of_vrings;
+	u8 reserved[2];
+	struct fw_rsc_vdev_vring vring[];
+} __packed;
+
+#endif /* RSC_TABLE_H */
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/5] remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources()
  2026-05-06  5:01 [PATCH 0/5] Decouple resource table definitions from remoteproc Mukesh Ojha
  2026-05-06  5:01 ` [PATCH 1/5] remoteproc: Move resource table data structure to its own header Mukesh Ojha
@ 2026-05-06  5:01 ` Mukesh Ojha
  2026-05-25 15:51   ` Mathieu Poirier
  2026-05-06  5:01 ` [PATCH 3/5] soc: qcom: mdt_loader: add qcom_mdt_pas_map/unmap_devmem_rscs() Mukesh Ojha
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Mukesh Ojha @ 2026-05-06  5:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Mathieu Poirier
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc, Mukesh Ojha

Replace the open-coded resource table iteration loop in
rproc_handle_resources() with the rsc_table_for_each_entry() helper.

The remoteproc-specific dispatch logic (vendor resource handling via
rproc_handle_rsc(), RSC_LAST bounds check, handler table lookup) is
moved into a local callback rproc_handle_rsc_entry(), keeping the
iteration mechanics in one canonical place.

The callback receives the payload offset within the table so that
handlers which write back into the resource table (e.g.
rproc_handle_carveout() recording a dynamically allocated address via
rsc_offset) continue to work correctly.

No functional change.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/remoteproc/remoteproc_core.c | 81 +++++++++++++---------------
 include/linux/rsc_table.h            | 53 ++++++++++++++++++
 2 files changed, 91 insertions(+), 43 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index b087ed21858a..f003be006b1b 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1011,60 +1011,55 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = {
 	[RSC_VDEV] = rproc_handle_vdev,
 };
 
-/* handle firmware resource entries before booting the remote processor */
-static int rproc_handle_resources(struct rproc *rproc,
-				  rproc_handle_resource_t handlers[RSC_LAST])
+struct rproc_rsc_cb_data {
+	struct rproc *rproc;
+	rproc_handle_resource_t *handlers;
+};
+
+static int rproc_handle_rsc_entry(u32 type, void *rsc, int offset,
+				  int avail, void *data)
 {
+	struct rproc_rsc_cb_data *d = data;
+	struct rproc *rproc = d->rproc;
 	struct device *dev = &rproc->dev;
 	rproc_handle_resource_t handler;
-	int ret = 0, i;
-
-	if (!rproc->table_ptr)
-		return 0;
+	int ret;
 
-	for (i = 0; i < rproc->table_ptr->num; i++) {
-		int offset = rproc->table_ptr->offset[i];
-		struct fw_rsc_hdr *hdr = (void *)rproc->table_ptr + offset;
-		int avail = rproc->table_sz - offset - sizeof(*hdr);
-		void *rsc = (void *)hdr + sizeof(*hdr);
+	dev_dbg(dev, "rsc: type %d\n", type);
 
-		/* make sure table isn't truncated */
-		if (avail < 0) {
-			dev_err(dev, "rsc table is truncated\n");
-			return -EINVAL;
-		}
-
-		dev_dbg(dev, "rsc: type %d\n", hdr->type);
+	if (type >= RSC_VENDOR_START && type <= RSC_VENDOR_END) {
+		ret = rproc_handle_rsc(rproc, type, rsc, offset, avail);
+		if (ret == RSC_HANDLED)
+			return 0;
+		if (ret < 0)
+			return ret;
+		dev_warn(dev, "unsupported vendor resource %d\n", type);
+		return 0;
+	}
 
-		if (hdr->type >= RSC_VENDOR_START &&
-		    hdr->type <= RSC_VENDOR_END) {
-			ret = rproc_handle_rsc(rproc, hdr->type, rsc,
-					       offset + sizeof(*hdr), avail);
-			if (ret == RSC_HANDLED)
-				continue;
-			else if (ret < 0)
-				break;
+	if (type >= RSC_LAST) {
+		dev_warn(dev, "unsupported resource %d\n", type);
+		return 0;
+	}
 
-			dev_warn(dev, "unsupported vendor resource %d\n",
-				 hdr->type);
-			continue;
-		}
+	handler = d->handlers[type];
+	if (!handler)
+		return 0;
 
-		if (hdr->type >= RSC_LAST) {
-			dev_warn(dev, "unsupported resource %d\n", hdr->type);
-			continue;
-		}
+	return handler(rproc, rsc, offset, avail);
+}
 
-		handler = handlers[hdr->type];
-		if (!handler)
-			continue;
+/* handle firmware resource entries before booting the remote processor */
+static int rproc_handle_resources(struct rproc *rproc,
+				  rproc_handle_resource_t handlers[RSC_LAST])
+{
+	struct rproc_rsc_cb_data d = { .rproc = rproc, .handlers = handlers };
 
-		ret = handler(rproc, rsc, offset + sizeof(*hdr), avail);
-		if (ret)
-			break;
-	}
+	if (!rproc->table_ptr)
+		return 0;
 
-	return ret;
+	return rsc_table_for_each_entry(rproc->table_ptr, rproc->table_sz,
+					&rproc->dev, rproc_handle_rsc_entry, &d);
 }
 
 static int rproc_prepare_subdevices(struct rproc *rproc)
diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h
index c32c8b6cd2a7..c6d6d553d8f1 100644
--- a/include/linux/rsc_table.h
+++ b/include/linux/rsc_table.h
@@ -303,4 +303,57 @@ struct fw_rsc_vdev {
 	struct fw_rsc_vdev_vring vring[];
 } __packed;
 
+/**
+ * rsc_table_for_each_entry() - iterate over all entries in a resource table
+ * @table:    pointer to the resource table
+ * @table_sz: total size of the table buffer in bytes
+ * @dev:      device used for error logging
+ * @cb:       callback invoked for each entry:
+ *              @type   - value from enum fw_resource_type
+ *              @rsc    - pointer to the entry payload (past struct fw_rsc_hdr)
+ *              @offset - byte offset of the payload within the table; callers
+ *                        that write back into the table (e.g. to record a
+ *                        dynamically allocated address) use this to locate the
+ *                        entry for later update
+ *              @avail  - bytes available in the payload
+ *              @data   - caller-supplied private pointer
+ *            Return 0 to continue iteration, non-zero to stop.
+ * @data:     private pointer forwarded to @cb on every call
+ *
+ * Iterates over every resource entry in @table, performing the standard
+ * truncation check, and invokes @cb for each one. Iteration stops on the
+ * first non-zero return from @cb or on a malformed table.
+ *
+ * Returns 0 after a complete iteration, -EINVAL if the table is truncated,
+ * or the first non-zero value returned by @cb.
+ */
+static inline int rsc_table_for_each_entry(struct resource_table *table,
+					   size_t table_sz,
+					   struct device *dev,
+					   int (*cb)(u32 type, void *rsc,
+						     int offset, int avail,
+						     void *data),
+					   void *data) {
+	int i, ret;
+
+	for (i = 0; i < table->num; i++) {
+		int offset = table->offset[i];
+		struct fw_rsc_hdr *hdr = (void *)table + offset;
+		int avail = table_sz - offset - sizeof(*hdr);
+		int rsc_offset = offset + sizeof(*hdr);
+		void *rsc = (void *)hdr + sizeof(*hdr);
+
+		if (avail < 0) {
+			dev_err(dev, "rsc table is truncated\n");
+			return -EINVAL;
+		}
+
+		ret = cb(hdr->type, rsc, rsc_offset, avail, data);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 #endif /* RSC_TABLE_H */
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/5] soc: qcom: mdt_loader: add qcom_mdt_pas_map/unmap_devmem_rscs()
  2026-05-06  5:01 [PATCH 0/5] Decouple resource table definitions from remoteproc Mukesh Ojha
  2026-05-06  5:01 ` [PATCH 1/5] remoteproc: Move resource table data structure to its own header Mukesh Ojha
  2026-05-06  5:01 ` [PATCH 2/5] remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources() Mukesh Ojha
@ 2026-05-06  5:01 ` Mukesh Ojha
  2026-05-26  6:47   ` Dmitry Baryshkov
  2026-05-06  5:01 ` [PATCH 4/5] firmware: qcom: scm: replace <linux/remoteproc.h> with <linux/rsc_table.h> Mukesh Ojha
  2026-05-06  5:01 ` [PATCH 5/5] MAINTAINERS: add rsc_table.h to remoteproc entry Mukesh Ojha
  4 siblings, 1 reply; 11+ messages in thread
From: Mukesh Ojha @ 2026-05-06  5:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Mathieu Poirier
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc, Mukesh Ojha

Add qcom_mdt_pas_map_devmem_rscs() and qcom_mdt_pas_unmap_devmem_rscs()
to IOMMU map/unmap RSC_DEVMEM resource table entries on SoCs where Linux
runs as hypervisor at EL2 and owns the IOMMU mappings for remote
processors.

The map function fetches the resource table via
qcom_scm_pas_get_rsc_table() and iterates over RSC_DEVMEM entries using
rsc_table_for_each_entry(), calling iommu_map() for each. Mapped entries
are tracked in a per-PAS linked list stored in a hash table keyed by
pas_id for later lookup by the unmap function.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/soc/qcom/mdt_loader.c       | 189 ++++++++++++++++++++++++++++
 include/linux/soc/qcom/mdt_loader.h |  22 ++++
 2 files changed, 211 insertions(+)

diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index ed882dd43587..dd84d0eba152 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -11,14 +11,34 @@
 #include <linux/device.h>
 #include <linux/elf.h>
 #include <linux/firmware.h>
+#include <linux/hashtable.h>
 #include <linux/io.h>
+#include <linux/iommu.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/module.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/rsc_table.h>
 #include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/soc/qcom/mdt_loader.h>
 
+#define RSC_TABLE_HASH_BITS	5  /* 32 buckets */
+
+static DEFINE_HASHTABLE(qcom_pas_rsc_table_map, RSC_TABLE_HASH_BITS);
+
+struct qcom_pas_devmem_rsc {
+	struct fw_rsc_devmem *devmem;
+	struct list_head node;
+};
+
+struct qcom_pas_rsc_table_info {
+	struct resource_table *rsc_table;
+	struct list_head devmem_list;
+	struct hlist_node hnode;
+	int pas_id;
+};
+
 static bool mdt_header_valid(const struct firmware *fw)
 {
 	const struct elf32_hdr *ehdr;
@@ -507,5 +527,174 @@ int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *f
 }
 EXPORT_SYMBOL_GPL(qcom_mdt_pas_load);
 
+static void __qcom_mdt_unmap_devmem_rscs(struct qcom_pas_rsc_table_info *info,
+					 struct iommu_domain *domain)
+{
+	struct qcom_pas_devmem_rsc *entry, *tmp;
+
+	list_for_each_entry_safe(entry, tmp, &info->devmem_list, node) {
+		iommu_unmap(domain, entry->devmem->da, entry->devmem->len);
+		list_del(&entry->node);
+		kfree(entry);
+	}
+}
+
+/**
+ * qcom_mdt_pas_unmap_devmem_rscs() - IOMMU unmap device memory resources
+ *					for a given Peripheral
+ * @ctx:	pas context data structure
+ * @domain:	IOMMU domain
+ *
+ * Looks up the resource table info previously stored by
+ * qcom_mdt_pas_map_devmem_rscs(), unmaps all RSC_DEVMEM entries from the
+ * IOMMU domain, and releases the associated memory.
+ */
+void qcom_mdt_pas_unmap_devmem_rscs(struct qcom_scm_pas_context *ctx,
+				    struct iommu_domain *domain)
+{
+	struct qcom_pas_rsc_table_info *info;
+	struct hlist_node *tmp;
+
+	if (!ctx || !domain)
+		return;
+
+	hash_for_each_possible_safe(qcom_pas_rsc_table_map, info, tmp, hnode, ctx->pas_id) {
+		if (info->pas_id != ctx->pas_id)
+			continue;
+
+		__qcom_mdt_unmap_devmem_rscs(info, domain);
+		hash_del(&info->hnode);
+		kfree(info->rsc_table);
+		kfree(info);
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(qcom_mdt_pas_unmap_devmem_rscs);
+
+static int __qcom_mdt_map_devmem_rscs(struct device *dev, void *ptr, int avail,
+				      struct iommu_domain *domain,
+				      struct qcom_pas_rsc_table_info *info)
+{
+	struct qcom_pas_devmem_rsc *devmem_info;
+	struct fw_rsc_devmem *rsc = ptr;
+	int ret;
+
+	if (sizeof(*rsc) > avail) {
+		dev_err(dev, "devmem rsc is truncated\n");
+		return -EINVAL;
+	}
+
+	if (rsc->reserved) {
+		dev_err(dev, "devmem rsc has non zero reserved bytes\n");
+		return -EINVAL;
+	}
+
+	devmem_info = kzalloc(sizeof(*devmem_info), GFP_KERNEL);
+	if (!devmem_info)
+		return -ENOMEM;
+
+	ret = iommu_map(domain, rsc->da, rsc->pa, rsc->len, rsc->flags, GFP_KERNEL);
+	if (ret) {
+		dev_err(dev, "failed to map devmem: %d\n", ret);
+		kfree(devmem_info);
+		return ret;
+	}
+
+	devmem_info->devmem = rsc;
+	list_add_tail(&devmem_info->node, &info->devmem_list);
+
+	dev_dbg(dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
+		rsc->pa, rsc->da, rsc->len);
+
+	return 0;
+}
+
+struct qcom_mdt_map_cb_data {
+	struct device *dev;
+	struct iommu_domain *domain;
+	struct qcom_pas_rsc_table_info *info;
+};
+
+static int qcom_mdt_map_devmem_cb(u32 type, void *rsc, int offset,
+				  int avail, void *data)
+{
+	struct qcom_mdt_map_cb_data *d = data;
+
+	if (type != RSC_DEVMEM)
+		return 0;
+
+	return __qcom_mdt_map_devmem_rscs(d->dev, rsc, avail, d->domain,
+					  d->info);
+}
+
+/**
+ * qcom_mdt_pas_map_devmem_rscs() - IOMMU map device memory resources for
+ *				     a given Peripheral
+ *
+ * This routine should be called when it is known that the SoC is running
+ * with Linux as hypervisor at EL2 where it is in control of the IOMMU map
+ * of the resources for the remote processors.
+ *
+ * @ctx:	    pas context data structure
+ * @domain:	    IOMMU domain
+ * @input_rt:	    input resource table buffer when resource table is part of
+ *		    firmware binary; pass NULL if not available
+ * @input_rt_size:  size of @input_rt; pass zero if @input_rt is NULL
+ *
+ * Returns 0 on success, negative errno otherwise.
+ */
+int qcom_mdt_pas_map_devmem_rscs(struct qcom_scm_pas_context *ctx,
+				 struct iommu_domain *domain,
+				 void *input_rt, size_t input_rt_size)
+{
+	struct qcom_mdt_map_cb_data map_data;
+	size_t output_rt_size = QCOM_MDT_MAX_RSCTABLE_SIZE;
+	struct qcom_pas_rsc_table_info *info;
+	struct resource_table *rsc_table;
+	int ret;
+
+	if (!ctx || !domain)
+		return -EINVAL;
+
+	rsc_table = qcom_scm_pas_get_rsc_table(ctx, input_rt, input_rt_size,
+					       &output_rt_size);
+	if (IS_ERR(rsc_table)) {
+		ret = PTR_ERR(rsc_table);
+		dev_err(ctx->dev, "error %d getting resource_table\n", ret);
+		return ret;
+	}
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info) {
+		ret = -ENOMEM;
+		goto free_rsc_table;
+	}
+
+	map_data.dev = ctx->dev;
+	map_data.domain = domain;
+	map_data.info = info;
+	info->pas_id = ctx->pas_id;
+	info->rsc_table = rsc_table;
+	INIT_LIST_HEAD(&info->devmem_list);
+
+	ret = rsc_table_for_each_entry(rsc_table, output_rt_size, ctx->dev,
+				       qcom_mdt_map_devmem_cb, &map_data);
+	if (ret)
+		goto undo_mapping;
+
+	hash_add(qcom_pas_rsc_table_map, &info->hnode, ctx->pas_id);
+
+	return 0;
+
+undo_mapping:
+	__qcom_mdt_unmap_devmem_rscs(info, domain);
+	kfree(info);
+free_rsc_table:
+	kfree(rsc_table);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_mdt_pas_map_devmem_rscs);
+
 MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format");
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
index 7c551b98e182..304aebb2b9cd 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -8,8 +8,11 @@
 #define QCOM_MDT_TYPE_HASH	(2 << 24)
 #define QCOM_MDT_RELOCATABLE	BIT(27)
 
+#define QCOM_MDT_MAX_RSCTABLE_SIZE	SZ_16K
+
 struct device;
 struct firmware;
+struct iommu_domain;
 struct qcom_scm_pas_context;
 
 #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
@@ -23,6 +26,12 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
 int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw,
 		      const char *firmware, phys_addr_t *reloc_base);
 
+int qcom_mdt_pas_map_devmem_rscs(struct qcom_scm_pas_context *ctx,
+				 struct iommu_domain *domain,
+				 void *input_rt, size_t input_rt_size);
+void qcom_mdt_pas_unmap_devmem_rscs(struct qcom_scm_pas_context *ctx,
+				    struct iommu_domain *domain);
+
 int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
 			  const char *fw_name, void *mem_region,
 			  phys_addr_t mem_phys, size_t mem_size,
@@ -52,6 +61,19 @@ static inline int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx,
 	return -ENODEV;
 }
 
+static inline int qcom_mdt_pas_map_devmem_rscs(struct qcom_scm_pas_context *ctx,
+					       struct iommu_domain *domain,
+					       void *input_rt,
+					       size_t input_rt_size)
+{
+	return -ENODEV;
+}
+
+static inline void qcom_mdt_pas_unmap_devmem_rscs(struct qcom_scm_pas_context *ctx,
+						  struct iommu_domain *domain)
+{
+}
+
 static inline int qcom_mdt_load_no_init(struct device *dev,
 					const struct firmware *fw,
 					const char *fw_name, void *mem_region,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/5] firmware: qcom: scm: replace <linux/remoteproc.h> with <linux/rsc_table.h>
  2026-05-06  5:01 [PATCH 0/5] Decouple resource table definitions from remoteproc Mukesh Ojha
                   ` (2 preceding siblings ...)
  2026-05-06  5:01 ` [PATCH 3/5] soc: qcom: mdt_loader: add qcom_mdt_pas_map/unmap_devmem_rscs() Mukesh Ojha
@ 2026-05-06  5:01 ` Mukesh Ojha
  2026-05-06  5:01 ` [PATCH 5/5] MAINTAINERS: add rsc_table.h to remoteproc entry Mukesh Ojha
  4 siblings, 0 replies; 11+ messages in thread
From: Mukesh Ojha @ 2026-05-06  5:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Mathieu Poirier
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc, Mukesh Ojha

qcom_scm.c only uses struct resource_table, which was moved to
<linux/rsc_table.h> by "remoteproc: Move resource table data structure
to its own header". Drop the heavyweight <linux/remoteproc.h> dependency
and include only the header that provides what is actually needed.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/firmware/qcom/qcom_scm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 2cae35e7c583..d9ee180388aa 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -27,7 +27,7 @@
 #include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 #include <linux/reset-controller.h>
-#include <linux/remoteproc.h>
+#include <linux/rsc_table.h>
 #include <linux/sizes.h>
 #include <linux/types.h>
 
@@ -871,7 +871,7 @@ static void *__qcom_scm_pas_get_rsc_table(u32 pas_id, void *input_rt_tzm,
  * as zero respectively.
  *
  * More about documentation on resource table data structures can be found in
- * include/linux/remoteproc.h
+ * include/linux/rsc_table.h
  *
  * @ctx:	    PAS context
  * @pas_id:	    peripheral authentication service id
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/5] MAINTAINERS: add rsc_table.h to remoteproc entry
  2026-05-06  5:01 [PATCH 0/5] Decouple resource table definitions from remoteproc Mukesh Ojha
                   ` (3 preceding siblings ...)
  2026-05-06  5:01 ` [PATCH 4/5] firmware: qcom: scm: replace <linux/remoteproc.h> with <linux/rsc_table.h> Mukesh Ojha
@ 2026-05-06  5:01 ` Mukesh Ojha
  4 siblings, 0 replies; 11+ messages in thread
From: Mukesh Ojha @ 2026-05-06  5:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Mathieu Poirier
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc, Mukesh Ojha

include/linux/rsc_table.h was split out from include/linux/remoteproc.h
to hold the resource table wire-format definitions. Add it to the
REMOTEPROC entry so it is covered by the same maintainers.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c871acf2179c..b2a6d108c662 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22507,6 +22507,7 @@ F:	Documentation/devicetree/bindings/remoteproc/
 F:	Documentation/staging/remoteproc.rst
 F:	drivers/remoteproc/
 F:	include/linux/remoteproc.h
+F:	include/linux/rsc_table.h
 F:	include/linux/remoteproc/
 
 REMOTE PROCESSOR MESSAGING (RPMSG) SUBSYSTEM
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/5] remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources()
  2026-05-06  5:01 ` [PATCH 2/5] remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources() Mukesh Ojha
@ 2026-05-25 15:51   ` Mathieu Poirier
  0 siblings, 0 replies; 11+ messages in thread
From: Mathieu Poirier @ 2026-05-25 15:51 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Bjorn Andersson, Konrad Dybcio, linux-kernel, linux-arm-msm,
	linux-remoteproc

On Wed, May 06, 2026 at 10:31:04AM +0530, Mukesh Ojha wrote:
> Replace the open-coded resource table iteration loop in
> rproc_handle_resources() with the rsc_table_for_each_entry() helper.
> 
> The remoteproc-specific dispatch logic (vendor resource handling via
> rproc_handle_rsc(), RSC_LAST bounds check, handler table lookup) is
> moved into a local callback rproc_handle_rsc_entry(), keeping the
> iteration mechanics in one canonical place.
> 
> The callback receives the payload offset within the table so that
> handlers which write back into the resource table (e.g.
> rproc_handle_carveout() recording a dynamically allocated address via
> rsc_offset) continue to work correctly.
> 
> No functional change.
> 
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
>  drivers/remoteproc/remoteproc_core.c | 81 +++++++++++++---------------
>  include/linux/rsc_table.h            | 53 ++++++++++++++++++
>  2 files changed, 91 insertions(+), 43 deletions(-)
>

Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
 
> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> index b087ed21858a..f003be006b1b 100644
> --- a/drivers/remoteproc/remoteproc_core.c
> +++ b/drivers/remoteproc/remoteproc_core.c
> @@ -1011,60 +1011,55 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = {
>  	[RSC_VDEV] = rproc_handle_vdev,
>  };
>  
> -/* handle firmware resource entries before booting the remote processor */
> -static int rproc_handle_resources(struct rproc *rproc,
> -				  rproc_handle_resource_t handlers[RSC_LAST])
> +struct rproc_rsc_cb_data {
> +	struct rproc *rproc;
> +	rproc_handle_resource_t *handlers;
> +};
> +
> +static int rproc_handle_rsc_entry(u32 type, void *rsc, int offset,
> +				  int avail, void *data)
>  {
> +	struct rproc_rsc_cb_data *d = data;
> +	struct rproc *rproc = d->rproc;
>  	struct device *dev = &rproc->dev;
>  	rproc_handle_resource_t handler;
> -	int ret = 0, i;
> -
> -	if (!rproc->table_ptr)
> -		return 0;
> +	int ret;
>  
> -	for (i = 0; i < rproc->table_ptr->num; i++) {
> -		int offset = rproc->table_ptr->offset[i];
> -		struct fw_rsc_hdr *hdr = (void *)rproc->table_ptr + offset;
> -		int avail = rproc->table_sz - offset - sizeof(*hdr);
> -		void *rsc = (void *)hdr + sizeof(*hdr);
> +	dev_dbg(dev, "rsc: type %d\n", type);
>  
> -		/* make sure table isn't truncated */
> -		if (avail < 0) {
> -			dev_err(dev, "rsc table is truncated\n");
> -			return -EINVAL;
> -		}
> -
> -		dev_dbg(dev, "rsc: type %d\n", hdr->type);
> +	if (type >= RSC_VENDOR_START && type <= RSC_VENDOR_END) {
> +		ret = rproc_handle_rsc(rproc, type, rsc, offset, avail);
> +		if (ret == RSC_HANDLED)
> +			return 0;
> +		if (ret < 0)
> +			return ret;
> +		dev_warn(dev, "unsupported vendor resource %d\n", type);
> +		return 0;
> +	}
>  
> -		if (hdr->type >= RSC_VENDOR_START &&
> -		    hdr->type <= RSC_VENDOR_END) {
> -			ret = rproc_handle_rsc(rproc, hdr->type, rsc,
> -					       offset + sizeof(*hdr), avail);
> -			if (ret == RSC_HANDLED)
> -				continue;
> -			else if (ret < 0)
> -				break;
> +	if (type >= RSC_LAST) {
> +		dev_warn(dev, "unsupported resource %d\n", type);
> +		return 0;
> +	}
>  
> -			dev_warn(dev, "unsupported vendor resource %d\n",
> -				 hdr->type);
> -			continue;
> -		}
> +	handler = d->handlers[type];
> +	if (!handler)
> +		return 0;
>  
> -		if (hdr->type >= RSC_LAST) {
> -			dev_warn(dev, "unsupported resource %d\n", hdr->type);
> -			continue;
> -		}
> +	return handler(rproc, rsc, offset, avail);
> +}
>  
> -		handler = handlers[hdr->type];
> -		if (!handler)
> -			continue;
> +/* handle firmware resource entries before booting the remote processor */
> +static int rproc_handle_resources(struct rproc *rproc,
> +				  rproc_handle_resource_t handlers[RSC_LAST])
> +{
> +	struct rproc_rsc_cb_data d = { .rproc = rproc, .handlers = handlers };
>  
> -		ret = handler(rproc, rsc, offset + sizeof(*hdr), avail);
> -		if (ret)
> -			break;
> -	}
> +	if (!rproc->table_ptr)
> +		return 0;
>  
> -	return ret;
> +	return rsc_table_for_each_entry(rproc->table_ptr, rproc->table_sz,
> +					&rproc->dev, rproc_handle_rsc_entry, &d);
>  }
>  
>  static int rproc_prepare_subdevices(struct rproc *rproc)
> diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h
> index c32c8b6cd2a7..c6d6d553d8f1 100644
> --- a/include/linux/rsc_table.h
> +++ b/include/linux/rsc_table.h
> @@ -303,4 +303,57 @@ struct fw_rsc_vdev {
>  	struct fw_rsc_vdev_vring vring[];
>  } __packed;
>  
> +/**
> + * rsc_table_for_each_entry() - iterate over all entries in a resource table
> + * @table:    pointer to the resource table
> + * @table_sz: total size of the table buffer in bytes
> + * @dev:      device used for error logging
> + * @cb:       callback invoked for each entry:
> + *              @type   - value from enum fw_resource_type
> + *              @rsc    - pointer to the entry payload (past struct fw_rsc_hdr)
> + *              @offset - byte offset of the payload within the table; callers
> + *                        that write back into the table (e.g. to record a
> + *                        dynamically allocated address) use this to locate the
> + *                        entry for later update
> + *              @avail  - bytes available in the payload
> + *              @data   - caller-supplied private pointer
> + *            Return 0 to continue iteration, non-zero to stop.
> + * @data:     private pointer forwarded to @cb on every call
> + *
> + * Iterates over every resource entry in @table, performing the standard
> + * truncation check, and invokes @cb for each one. Iteration stops on the
> + * first non-zero return from @cb or on a malformed table.
> + *
> + * Returns 0 after a complete iteration, -EINVAL if the table is truncated,
> + * or the first non-zero value returned by @cb.
> + */
> +static inline int rsc_table_for_each_entry(struct resource_table *table,
> +					   size_t table_sz,
> +					   struct device *dev,
> +					   int (*cb)(u32 type, void *rsc,
> +						     int offset, int avail,
> +						     void *data),
> +					   void *data) {
> +	int i, ret;
> +
> +	for (i = 0; i < table->num; i++) {
> +		int offset = table->offset[i];
> +		struct fw_rsc_hdr *hdr = (void *)table + offset;
> +		int avail = table_sz - offset - sizeof(*hdr);
> +		int rsc_offset = offset + sizeof(*hdr);
> +		void *rsc = (void *)hdr + sizeof(*hdr);
> +
> +		if (avail < 0) {
> +			dev_err(dev, "rsc table is truncated\n");
> +			return -EINVAL;
> +		}
> +
> +		ret = cb(hdr->type, rsc, rsc_offset, avail, data);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  #endif /* RSC_TABLE_H */
> -- 
> 2.53.0
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/5] remoteproc: Move resource table data structure to its own header
  2026-05-06  5:01 ` [PATCH 1/5] remoteproc: Move resource table data structure to its own header Mukesh Ojha
@ 2026-05-25 15:53   ` Mathieu Poirier
  2026-05-26  7:49     ` Mukesh Ojha
  0 siblings, 1 reply; 11+ messages in thread
From: Mathieu Poirier @ 2026-05-25 15:53 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Bjorn Andersson, Konrad Dybcio, linux-kernel, linux-arm-msm,
	linux-remoteproc

On Wed, May 06, 2026 at 10:31:03AM +0530, Mukesh Ojha wrote:
> The resource table data structure has traditionally been associated with
> the remoteproc framework, where the resource table is included as a
> section within the remote processor firmware binary. However, it is also
> possible to obtain the resource table through other means—such as from a
> reserved memory region populated by the boot firmware, statically
> maintained driver data, or via a secure SMC call—when it is not embedded
> in the firmware.
> 
> There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> etc.) in the upstream kernel that do not use the remoteproc framework to
> manage their lifecycle for various reasons.
> 
> When Linux is running at EL2, similar to the Qualcomm PAS driver
> (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> also want to use the resource table SMC call to retrieve and map
> resources before they are used by the remote processor.
> 
> In such cases, the resource table data structure is no longer tightly
> coupled with the remoteproc headers. Client drivers that do not use the
> remoteproc framework should still be able to parse the resource table
> obtained through alternative means. Therefore, there is a need to
> decouple the resource table definitions from the remoteproc headers.
> 
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
>  include/linux/remoteproc.h | 269 +-------------------------------
>  include/linux/rsc_table.h  | 306 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 307 insertions(+), 268 deletions(-)
>  create mode 100644 include/linux/rsc_table.h
>

This patch is giving me a checkpatch.pl warning, related to a missing SPDX
header.  With that addressed:

Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
 
> diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> index b4795698d8c2..7c1546d48008 100644
> --- a/include/linux/remoteproc.h
> +++ b/include/linux/remoteproc.h
> @@ -42,274 +42,7 @@
>  #include <linux/completion.h>
>  #include <linux/idr.h>
>  #include <linux/of.h>
> -
> -/**
> - * struct resource_table - firmware resource table header
> - * @ver: version number
> - * @num: number of resource entries
> - * @reserved: reserved (must be zero)
> - * @offset: array of offsets pointing at the various resource entries
> - *
> - * A resource table is essentially a list of system resources required
> - * by the remote processor. It may also include configuration entries.
> - * If needed, the remote processor firmware should contain this table
> - * as a dedicated ".resource_table" ELF section.
> - *
> - * Some resources entries are mere announcements, where the host is informed
> - * of specific remoteproc configuration. Other entries require the host to
> - * do something (e.g. allocate a system resource). Sometimes a negotiation
> - * is expected, where the firmware requests a resource, and once allocated,
> - * the host should provide back its details (e.g. address of an allocated
> - * memory region).
> - *
> - * The header of the resource table, as expressed by this structure,
> - * contains a version number (should we need to change this format in the
> - * future), the number of available resource entries, and their offsets
> - * in the table.
> - *
> - * Immediately following this header are the resource entries themselves,
> - * each of which begins with a resource entry header (as described below).
> - */
> -struct resource_table {
> -	u32 ver;
> -	u32 num;
> -	u32 reserved[2];
> -	u32 offset[];
> -} __packed;
> -
> -/**
> - * struct fw_rsc_hdr - firmware resource entry header
> - * @type: resource type
> - * @data: resource data
> - *
> - * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
> - * its @type. The content of the entry itself will immediately follow
> - * this header, and it should be parsed according to the resource type.
> - */
> -struct fw_rsc_hdr {
> -	u32 type;
> -	u8 data[];
> -} __packed;
> -
> -/**
> - * enum fw_resource_type - types of resource entries
> - *
> - * @RSC_CARVEOUT:   request for allocation of a physically contiguous
> - *		    memory region.
> - * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
> - * @RSC_TRACE:	    announces the availability of a trace buffer into which
> - *		    the remote processor will be writing logs.
> - * @RSC_VDEV:       declare support for a virtio device, and serve as its
> - *		    virtio header.
> - * @RSC_LAST:       just keep this one at the end of standard resources
> - * @RSC_VENDOR_START:	start of the vendor specific resource types range
> - * @RSC_VENDOR_END:	end of the vendor specific resource types range
> - *
> - * For more details regarding a specific resource type, please see its
> - * dedicated structure below.
> - *
> - * Please note that these values are used as indices to the rproc_handle_rsc
> - * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
> - * check the validity of an index before the lookup table is accessed, so
> - * please update it as needed.
> - */
> -enum fw_resource_type {
> -	RSC_CARVEOUT		= 0,
> -	RSC_DEVMEM		= 1,
> -	RSC_TRACE		= 2,
> -	RSC_VDEV		= 3,
> -	RSC_LAST		= 4,
> -	RSC_VENDOR_START	= 128,
> -	RSC_VENDOR_END		= 512,
> -};
> -
> -#define FW_RSC_ADDR_ANY (-1)
> -
> -/**
> - * struct fw_rsc_carveout - physically contiguous memory request
> - * @da: device address
> - * @pa: physical address
> - * @len: length (in bytes)
> - * @flags: iommu protection flags
> - * @reserved: reserved (must be zero)
> - * @name: human-readable name of the requested memory region
> - *
> - * This resource entry requests the host to allocate a physically contiguous
> - * memory region.
> - *
> - * These request entries should precede other firmware resource entries,
> - * as other entries might request placing other data objects inside
> - * these memory regions (e.g. data/code segments, trace resource entries, ...).
> - *
> - * Allocating memory this way helps utilizing the reserved physical memory
> - * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
> - * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
> - * pressure is important; it may have a substantial impact on performance.
> - *
> - * If the firmware is compiled with static addresses, then @da should specify
> - * the expected device address of this memory region. If @da is set to
> - * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
> - * overwrite @da with the dynamically allocated address.
> - *
> - * We will always use @da to negotiate the device addresses, even if it
> - * isn't using an iommu. In that case, though, it will obviously contain
> - * physical addresses.
> - *
> - * Some remote processors needs to know the allocated physical address
> - * even if they do use an iommu. This is needed, e.g., if they control
> - * hardware accelerators which access the physical memory directly (this
> - * is the case with OMAP4 for instance). In that case, the host will
> - * overwrite @pa with the dynamically allocated physical address.
> - * Generally we don't want to expose physical addresses if we don't have to
> - * (remote processors are generally _not_ trusted), so we might want to
> - * change this to happen _only_ when explicitly required by the hardware.
> - *
> - * @flags is used to provide IOMMU protection flags, and @name should
> - * (optionally) contain a human readable name of this carveout region
> - * (mainly for debugging purposes).
> - */
> -struct fw_rsc_carveout {
> -	u32 da;
> -	u32 pa;
> -	u32 len;
> -	u32 flags;
> -	u32 reserved;
> -	u8 name[32];
> -} __packed;
> -
> -/**
> - * struct fw_rsc_devmem - iommu mapping request
> - * @da: device address
> - * @pa: physical address
> - * @len: length (in bytes)
> - * @flags: iommu protection flags
> - * @reserved: reserved (must be zero)
> - * @name: human-readable name of the requested region to be mapped
> - *
> - * This resource entry requests the host to iommu map a physically contiguous
> - * memory region. This is needed in case the remote processor requires
> - * access to certain memory-based peripherals; _never_ use it to access
> - * regular memory.
> - *
> - * This is obviously only needed if the remote processor is accessing memory
> - * via an iommu.
> - *
> - * @da should specify the required device address, @pa should specify
> - * the physical address we want to map, @len should specify the size of
> - * the mapping and @flags is the IOMMU protection flags. As always, @name may
> - * (optionally) contain a human readable name of this mapping (mainly for
> - * debugging purposes).
> - *
> - * Note: at this point we just "trust" those devmem entries to contain valid
> - * physical addresses, but this isn't safe and will be changed: eventually we
> - * want remoteproc implementations to provide us ranges of physical addresses
> - * the firmware is allowed to request, and not allow firmwares to request
> - * access to physical addresses that are outside those ranges.
> - */
> -struct fw_rsc_devmem {
> -	u32 da;
> -	u32 pa;
> -	u32 len;
> -	u32 flags;
> -	u32 reserved;
> -	u8 name[32];
> -} __packed;
> -
> -/**
> - * struct fw_rsc_trace - trace buffer declaration
> - * @da: device address
> - * @len: length (in bytes)
> - * @reserved: reserved (must be zero)
> - * @name: human-readable name of the trace buffer
> - *
> - * This resource entry provides the host information about a trace buffer
> - * into which the remote processor will write log messages.
> - *
> - * @da specifies the device address of the buffer, @len specifies
> - * its size, and @name may contain a human readable name of the trace buffer.
> - *
> - * After booting the remote processor, the trace buffers are exposed to the
> - * user via debugfs entries (called trace0, trace1, etc..).
> - */
> -struct fw_rsc_trace {
> -	u32 da;
> -	u32 len;
> -	u32 reserved;
> -	u8 name[32];
> -} __packed;
> -
> -/**
> - * struct fw_rsc_vdev_vring - vring descriptor entry
> - * @da: device address
> - * @align: the alignment between the consumer and producer parts of the vring
> - * @num: num of buffers supported by this vring (must be power of two)
> - * @notifyid: a unique rproc-wide notify index for this vring. This notify
> - * index is used when kicking a remote processor, to let it know that this
> - * vring is triggered.
> - * @pa: physical address
> - *
> - * This descriptor is not a resource entry by itself; it is part of the
> - * vdev resource type (see below).
> - *
> - * Note that @da should either contain the device address where
> - * the remote processor is expecting the vring, or indicate that
> - * dynamically allocation of the vring's device address is supported.
> - */
> -struct fw_rsc_vdev_vring {
> -	u32 da;
> -	u32 align;
> -	u32 num;
> -	u32 notifyid;
> -	u32 pa;
> -} __packed;
> -
> -/**
> - * struct fw_rsc_vdev - virtio device header
> - * @id: virtio device id (as in virtio_ids.h)
> - * @notifyid: a unique rproc-wide notify index for this vdev. This notify
> - * index is used when kicking a remote processor, to let it know that the
> - * status/features of this vdev have changes.
> - * @dfeatures: specifies the virtio device features supported by the firmware
> - * @gfeatures: a place holder used by the host to write back the
> - * negotiated features that are supported by both sides.
> - * @config_len: the size of the virtio config space of this vdev. The config
> - * space lies in the resource table immediate after this vdev header.
> - * @status: a place holder where the host will indicate its virtio progress.
> - * @num_of_vrings: indicates how many vrings are described in this vdev header
> - * @reserved: reserved (must be zero)
> - * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
> - *
> - * This resource is a virtio device header: it provides information about
> - * the vdev, and is then used by the host and its peer remote processors
> - * to negotiate and share certain virtio properties.
> - *
> - * By providing this resource entry, the firmware essentially asks remoteproc
> - * to statically allocate a vdev upon registration of the rproc (dynamic vdev
> - * allocation is not yet supported).
> - *
> - * Note:
> - * 1. unlike virtualization systems, the term 'host' here means
> - *    the Linux side which is running remoteproc to control the remote
> - *    processors. We use the name 'gfeatures' to comply with virtio's terms,
> - *    though there isn't really any virtualized guest OS here: it's the host
> - *    which is responsible for negotiating the final features.
> - *    Yeah, it's a bit confusing.
> - *
> - * 2. immediately following this structure is the virtio config space for
> - *    this vdev (which is specific to the vdev; for more info, read the virtio
> - *    spec). The size of the config space is specified by @config_len.
> - */
> -struct fw_rsc_vdev {
> -	u32 id;
> -	u32 notifyid;
> -	u32 dfeatures;
> -	u32 gfeatures;
> -	u32 config_len;
> -	u8 status;
> -	u8 num_of_vrings;
> -	u8 reserved[2];
> -	struct fw_rsc_vdev_vring vring[];
> -} __packed;
> +#include <linux/rsc_table.h>
>  
>  struct rproc;
>  
> diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h
> new file mode 100644
> index 000000000000..c32c8b6cd2a7
> --- /dev/null
> +++ b/include/linux/rsc_table.h
> @@ -0,0 +1,306 @@
> +/*
> + * Resource table and its types data structure
> + *
> + * Copyright(c) 2011 Texas Instruments, Inc.
> + * Copyright(c) 2011 Google, Inc.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + *   notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + *   notice, this list of conditions and the following disclaimer in
> + *   the documentation and/or other materials provided with the
> + *   distribution.
> + * * Neither the name Texas Instruments nor the names of its
> + *   contributors may be used to endorse or promote products derived
> + *   from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef RSC_TABLE_H
> +#define RSC_TABLE_H
> +
> +/**
> + * struct resource_table - firmware resource table header
> + * @ver: version number
> + * @num: number of resource entries
> + * @reserved: reserved (must be zero)
> + * @offset: array of offsets pointing at the various resource entries
> + *
> + * A resource table is essentially a list of system resources required
> + * by the remote processor. It may also include configuration entries.
> + * If needed, the remote processor firmware should contain this table
> + * as a dedicated ".resource_table" ELF section.
> + *
> + * Some resources entries are mere announcements, where the host is informed
> + * of specific remoteproc configuration. Other entries require the host to
> + * do something (e.g. allocate a system resource). Sometimes a negotiation
> + * is expected, where the firmware requests a resource, and once allocated,
> + * the host should provide back its details (e.g. address of an allocated
> + * memory region).
> + *
> + * The header of the resource table, as expressed by this structure,
> + * contains a version number (should we need to change this format in the
> + * future), the number of available resource entries, and their offsets
> + * in the table.
> + *
> + * Immediately following this header are the resource entries themselves,
> + * each of which begins with a resource entry header (as described below).
> + */
> +struct resource_table {
> +	u32 ver;
> +	u32 num;
> +	u32 reserved[2];
> +	u32 offset[];
> +} __packed;
> +
> +/**
> + * struct fw_rsc_hdr - firmware resource entry header
> + * @type: resource type
> + * @data: resource data
> + *
> + * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
> + * its @type. The content of the entry itself will immediately follow
> + * this header, and it should be parsed according to the resource type.
> + */
> +struct fw_rsc_hdr {
> +	u32 type;
> +	u8 data[];
> +} __packed;
> +
> +/**
> + * enum fw_resource_type - types of resource entries
> + *
> + * @RSC_CARVEOUT:   request for allocation of a physically contiguous
> + *		    memory region.
> + * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
> + * @RSC_TRACE:	    announces the availability of a trace buffer into which
> + *		    the remote processor will be writing logs.
> + * @RSC_VDEV:       declare support for a virtio device, and serve as its
> + *		    virtio header.
> + * @RSC_LAST:       just keep this one at the end of standard resources
> + * @RSC_VENDOR_START:	start of the vendor specific resource types range
> + * @RSC_VENDOR_END:	end of the vendor specific resource types range
> + *
> + * For more details regarding a specific resource type, please see its
> + * dedicated structure below.
> + *
> + * Please note that these values are used as indices to the rproc_handle_rsc
> + * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
> + * check the validity of an index before the lookup table is accessed, so
> + * please update it as needed.
> + */
> +enum fw_resource_type {
> +	RSC_CARVEOUT		= 0,
> +	RSC_DEVMEM		= 1,
> +	RSC_TRACE		= 2,
> +	RSC_VDEV		= 3,
> +	RSC_LAST		= 4,
> +	RSC_VENDOR_START	= 128,
> +	RSC_VENDOR_END		= 512,
> +};
> +
> +#define FW_RSC_ADDR_ANY (-1)
> +
> +/**
> + * struct fw_rsc_carveout - physically contiguous memory request
> + * @da: device address
> + * @pa: physical address
> + * @len: length (in bytes)
> + * @flags: iommu protection flags
> + * @reserved: reserved (must be zero)
> + * @name: human-readable name of the requested memory region
> + *
> + * This resource entry requests the host to allocate a physically contiguous
> + * memory region.
> + *
> + * These request entries should precede other firmware resource entries,
> + * as other entries might request placing other data objects inside
> + * these memory regions (e.g. data/code segments, trace resource entries, ...).
> + *
> + * Allocating memory this way helps utilizing the reserved physical memory
> + * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
> + * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
> + * pressure is important; it may have a substantial impact on performance.
> + *
> + * If the firmware is compiled with static addresses, then @da should specify
> + * the expected device address of this memory region. If @da is set to
> + * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
> + * overwrite @da with the dynamically allocated address.
> + *
> + * We will always use @da to negotiate the device addresses, even if it
> + * isn't using an iommu. In that case, though, it will obviously contain
> + * physical addresses.
> + *
> + * Some remote processors needs to know the allocated physical address
> + * even if they do use an iommu. This is needed, e.g., if they control
> + * hardware accelerators which access the physical memory directly (this
> + * is the case with OMAP4 for instance). In that case, the host will
> + * overwrite @pa with the dynamically allocated physical address.
> + * Generally we don't want to expose physical addresses if we don't have to
> + * (remote processors are generally _not_ trusted), so we might want to
> + * change this to happen _only_ when explicitly required by the hardware.
> + *
> + * @flags is used to provide IOMMU protection flags, and @name should
> + * (optionally) contain a human readable name of this carveout region
> + * (mainly for debugging purposes).
> + */
> +struct fw_rsc_carveout {
> +	u32 da;
> +	u32 pa;
> +	u32 len;
> +	u32 flags;
> +	u32 reserved;
> +	u8 name[32];
> +} __packed;
> +
> +/**
> + * struct fw_rsc_devmem - iommu mapping request
> + * @da: device address
> + * @pa: physical address
> + * @len: length (in bytes)
> + * @flags: iommu protection flags
> + * @reserved: reserved (must be zero)
> + * @name: human-readable name of the requested region to be mapped
> + *
> + * This resource entry requests the host to iommu map a physically contiguous
> + * memory region. This is needed in case the remote processor requires
> + * access to certain memory-based peripherals; _never_ use it to access
> + * regular memory.
> + *
> + * This is obviously only needed if the remote processor is accessing memory
> + * via an iommu.
> + *
> + * @da should specify the required device address, @pa should specify
> + * the physical address we want to map, @len should specify the size of
> + * the mapping and @flags is the IOMMU protection flags. As always, @name may
> + * (optionally) contain a human readable name of this mapping (mainly for
> + * debugging purposes).
> + *
> + * Note: at this point we just "trust" those devmem entries to contain valid
> + * physical addresses, but this isn't safe and will be changed: eventually we
> + * want remoteproc implementations to provide us ranges of physical addresses
> + * the firmware is allowed to request, and not allow firmwares to request
> + * access to physical addresses that are outside those ranges.
> + */
> +struct fw_rsc_devmem {
> +	u32 da;
> +	u32 pa;
> +	u32 len;
> +	u32 flags;
> +	u32 reserved;
> +	u8 name[32];
> +} __packed;
> +
> +/**
> + * struct fw_rsc_trace - trace buffer declaration
> + * @da: device address
> + * @len: length (in bytes)
> + * @reserved: reserved (must be zero)
> + * @name: human-readable name of the trace buffer
> + *
> + * This resource entry provides the host information about a trace buffer
> + * into which the remote processor will write log messages.
> + *
> + * @da specifies the device address of the buffer, @len specifies
> + * its size, and @name may contain a human readable name of the trace buffer.
> + *
> + * After booting the remote processor, the trace buffers are exposed to the
> + * user via debugfs entries (called trace0, trace1, etc..).
> + */
> +struct fw_rsc_trace {
> +	u32 da;
> +	u32 len;
> +	u32 reserved;
> +	u8 name[32];
> +} __packed;
> +
> +/**
> + * struct fw_rsc_vdev_vring - vring descriptor entry
> + * @da: device address
> + * @align: the alignment between the consumer and producer parts of the vring
> + * @num: num of buffers supported by this vring (must be power of two)
> + * @notifyid: a unique rproc-wide notify index for this vring. This notify
> + * index is used when kicking a remote processor, to let it know that this
> + * vring is triggered.
> + * @pa: physical address
> + *
> + * This descriptor is not a resource entry by itself; it is part of the
> + * vdev resource type (see below).
> + *
> + * Note that @da should either contain the device address where
> + * the remote processor is expecting the vring, or indicate that
> + * dynamically allocation of the vring's device address is supported.
> + */
> +struct fw_rsc_vdev_vring {
> +	u32 da;
> +	u32 align;
> +	u32 num;
> +	u32 notifyid;
> +	u32 pa;
> +} __packed;
> +
> +/**
> + * struct fw_rsc_vdev - virtio device header
> + * @id: virtio device id (as in virtio_ids.h)
> + * @notifyid: a unique rproc-wide notify index for this vdev. This notify
> + * index is used when kicking a remote processor, to let it know that the
> + * status/features of this vdev have changes.
> + * @dfeatures: specifies the virtio device features supported by the firmware
> + * @gfeatures: a place holder used by the host to write back the
> + * negotiated features that are supported by both sides.
> + * @config_len: the size of the virtio config space of this vdev. The config
> + * space lies in the resource table immediate after this vdev header.
> + * @status: a place holder where the host will indicate its virtio progress.
> + * @num_of_vrings: indicates how many vrings are described in this vdev header
> + * @reserved: reserved (must be zero)
> + * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
> + *
> + * This resource is a virtio device header: it provides information about
> + * the vdev, and is then used by the host and its peer remote processors
> + * to negotiate and share certain virtio properties.
> + *
> + * By providing this resource entry, the firmware essentially asks remoteproc
> + * to statically allocate a vdev upon registration of the rproc (dynamic vdev
> + * allocation is not yet supported).
> + *
> + * Note:
> + * 1. unlike virtualization systems, the term 'host' here means
> + *    the Linux side which is running remoteproc to control the remote
> + *    processors. We use the name 'gfeatures' to comply with virtio's terms,
> + *    though there isn't really any virtualized guest OS here: it's the host
> + *    which is responsible for negotiating the final features.
> + *    Yeah, it's a bit confusing.
> + *
> + * 2. immediately following this structure is the virtio config space for
> + *    this vdev (which is specific to the vdev; for more info, read the virtio
> + *    spec). The size of the config space is specified by @config_len.
> + */
> +struct fw_rsc_vdev {
> +	u32 id;
> +	u32 notifyid;
> +	u32 dfeatures;
> +	u32 gfeatures;
> +	u32 config_len;
> +	u8 status;
> +	u8 num_of_vrings;
> +	u8 reserved[2];
> +	struct fw_rsc_vdev_vring vring[];
> +} __packed;
> +
> +#endif /* RSC_TABLE_H */
> -- 
> 2.53.0
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/5] soc: qcom: mdt_loader: add qcom_mdt_pas_map/unmap_devmem_rscs()
  2026-05-06  5:01 ` [PATCH 3/5] soc: qcom: mdt_loader: add qcom_mdt_pas_map/unmap_devmem_rscs() Mukesh Ojha
@ 2026-05-26  6:47   ` Dmitry Baryshkov
  2026-05-26  8:15     ` Mukesh Ojha
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Baryshkov @ 2026-05-26  6:47 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Bjorn Andersson, Konrad Dybcio, Mathieu Poirier, linux-kernel,
	linux-arm-msm, linux-remoteproc

On Wed, May 06, 2026 at 10:31:05AM +0530, Mukesh Ojha wrote:
> Add qcom_mdt_pas_map_devmem_rscs() and qcom_mdt_pas_unmap_devmem_rscs()
> to IOMMU map/unmap RSC_DEVMEM resource table entries on SoCs where Linux
> runs as hypervisor at EL2 and owns the IOMMU mappings for remote
> processors.

Generic rule is 'no API without users'. Please provide a driver using
these functions.

> 
> The map function fetches the resource table via
> qcom_scm_pas_get_rsc_table() and iterates over RSC_DEVMEM entries using
> rsc_table_for_each_entry(), calling iommu_map() for each. Mapped entries
> are tracked in a per-PAS linked list stored in a hash table keyed by
> pas_id for later lookup by the unmap function.
> 
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
>  drivers/soc/qcom/mdt_loader.c       | 189 ++++++++++++++++++++++++++++
>  include/linux/soc/qcom/mdt_loader.h |  22 ++++
>  2 files changed, 211 insertions(+)
> 

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/5] remoteproc: Move resource table data structure to its own header
  2026-05-25 15:53   ` Mathieu Poirier
@ 2026-05-26  7:49     ` Mukesh Ojha
  0 siblings, 0 replies; 11+ messages in thread
From: Mukesh Ojha @ 2026-05-26  7:49 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Bjorn Andersson, Konrad Dybcio, linux-kernel, linux-arm-msm,
	linux-remoteproc

On Mon, May 25, 2026 at 09:53:57AM -0600, Mathieu Poirier wrote:
> On Wed, May 06, 2026 at 10:31:03AM +0530, Mukesh Ojha wrote:
> > The resource table data structure has traditionally been associated with
> > the remoteproc framework, where the resource table is included as a
> > section within the remote processor firmware binary. However, it is also
> > possible to obtain the resource table through other means—such as from a
> > reserved memory region populated by the boot firmware, statically
> > maintained driver data, or via a secure SMC call—when it is not embedded
> > in the firmware.
> > 
> > There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> > etc.) in the upstream kernel that do not use the remoteproc framework to
> > manage their lifecycle for various reasons.
> > 
> > When Linux is running at EL2, similar to the Qualcomm PAS driver
> > (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> > also want to use the resource table SMC call to retrieve and map
> > resources before they are used by the remote processor.
> > 
> > In such cases, the resource table data structure is no longer tightly
> > coupled with the remoteproc headers. Client drivers that do not use the
> > remoteproc framework should still be able to parse the resource table
> > obtained through alternative means. Therefore, there is a need to
> > decouple the resource table definitions from the remoteproc headers.
> > 
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> >  include/linux/remoteproc.h | 269 +-------------------------------
> >  include/linux/rsc_table.h  | 306 +++++++++++++++++++++++++++++++++++++
> >  2 files changed, 307 insertions(+), 268 deletions(-)
> >  create mode 100644 include/linux/rsc_table.h
> >
> 
> This patch is giving me a checkpatch.pl warning, related to a missing SPDX
> header.  With that addressed:
> 
> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
>  

Sure, will take care of it.

-Mukesh

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/5] soc: qcom: mdt_loader: add qcom_mdt_pas_map/unmap_devmem_rscs()
  2026-05-26  6:47   ` Dmitry Baryshkov
@ 2026-05-26  8:15     ` Mukesh Ojha
  0 siblings, 0 replies; 11+ messages in thread
From: Mukesh Ojha @ 2026-05-26  8:15 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Konrad Dybcio, Mathieu Poirier, linux-kernel,
	linux-arm-msm, linux-remoteproc

On Tue, May 26, 2026 at 09:47:27AM +0300, Dmitry Baryshkov wrote:
> On Wed, May 06, 2026 at 10:31:05AM +0530, Mukesh Ojha wrote:
> > Add qcom_mdt_pas_map_devmem_rscs() and qcom_mdt_pas_unmap_devmem_rscs()
> > to IOMMU map/unmap RSC_DEVMEM resource table entries on SoCs where Linux
> > runs as hypervisor at EL2 and owns the IOMMU mappings for remote
> > processors.
> 
> Generic rule is 'no API without users'. Please provide a driver using
> these functions.

All the non-remoteproc client will be the user., I already mentioned
that video is one of user mentioned in the cover-letter.., will add
them as user once there base changes get picked.

> 
> > 
> > The map function fetches the resource table via
> > qcom_scm_pas_get_rsc_table() and iterates over RSC_DEVMEM entries using
> > rsc_table_for_each_entry(), calling iommu_map() for each. Mapped entries
> > are tracked in a per-PAS linked list stored in a hash table keyed by
> > pas_id for later lookup by the unmap function.
> > 
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> >  drivers/soc/qcom/mdt_loader.c       | 189 ++++++++++++++++++++++++++++
> >  include/linux/soc/qcom/mdt_loader.h |  22 ++++
> >  2 files changed, 211 insertions(+)
> > 
> 
> -- 
> With best wishes
> Dmitry

-- 
-Mukesh Ojha

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-05-26  8:15 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-06  5:01 [PATCH 0/5] Decouple resource table definitions from remoteproc Mukesh Ojha
2026-05-06  5:01 ` [PATCH 1/5] remoteproc: Move resource table data structure to its own header Mukesh Ojha
2026-05-25 15:53   ` Mathieu Poirier
2026-05-26  7:49     ` Mukesh Ojha
2026-05-06  5:01 ` [PATCH 2/5] remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources() Mukesh Ojha
2026-05-25 15:51   ` Mathieu Poirier
2026-05-06  5:01 ` [PATCH 3/5] soc: qcom: mdt_loader: add qcom_mdt_pas_map/unmap_devmem_rscs() Mukesh Ojha
2026-05-26  6:47   ` Dmitry Baryshkov
2026-05-26  8:15     ` Mukesh Ojha
2026-05-06  5:01 ` [PATCH 4/5] firmware: qcom: scm: replace <linux/remoteproc.h> with <linux/rsc_table.h> Mukesh Ojha
2026-05-06  5:01 ` [PATCH 5/5] MAINTAINERS: add rsc_table.h to remoteproc entry Mukesh Ojha

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.