[PATCH RFC v2 08/10] firmware: riscv: rpmi-tee: cache TEE capabilities

From: Amirreza Zarrabi

Date: Wed Oct 07 2026 - 23:29:54 EST


Query firmware capabilities during transport initialization and cache
support for memory lending, sharing, segmented parcels and signal buses.

Distinguish REE-accessible memory operations from those restricted to
TEE-to-TEE use so Linux only enables operations available to it.

Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi@xxxxxxxxxxxxxxxx>
---
drivers/firmware/riscv_rpmi_tee/driver.c | 73 ++++++++++++++++++++++
drivers/firmware/riscv_rpmi_tee/rpmi_tee_private.h | 15 +++++
2 files changed, 88 insertions(+)

diff --git a/drivers/firmware/riscv_rpmi_tee/driver.c b/drivers/firmware/riscv_rpmi_tee/driver.c
index a683f7d28c25..b43a09f5e853 100644
--- a/drivers/firmware/riscv_rpmi_tee/driver.c
+++ b/drivers/firmware/riscv_rpmi_tee/driver.c
@@ -18,6 +18,33 @@

#include "rpmi_tee_private.h"

+#define RPMI_TEE_FEATURE_MEMORY_LEND 1
+#define RPMI_TEE_FEATURE_MEMORY_SHARE 2
+#define RPMI_TEE_FEATURE_SIGNAL_BUS 3
+#define RPMI_TEE_FEATURE_MULTISEGMENT_OPS 4
+
+#define RPMI_TEE_MEMORY_FEATURE_UNSUPPORTED 0
+#define RPMI_TEE_MEMORY_FEATURE_TEE_ONLY 1
+#define RPMI_TEE_MEMORY_FEATURE_FULLY_SUPPORTED 2
+
+/**
+ * struct rpmi_tee_probe_features_req - TEE_PROBE_FEATURES request
+ * @feature_id: TEE feature identifier to query.
+ */
+struct rpmi_tee_probe_features_req {
+ __le32 feature_id;
+} __packed;
+
+/**
+ * struct rpmi_tee_probe_features_resp - TEE_PROBE_FEATURES response
+ * @status: RPMI completion status.
+ * @value: Feature-specific value.
+ */
+struct rpmi_tee_probe_features_resp {
+ __le32 status;
+ __le32 value;
+} __packed;
+
/**
* struct rpmi_tee_call_req - TEE_CALL request prefix
* @sender_id: Calling REE endpoint identifier.
@@ -186,6 +213,29 @@ static int rpmi_tee_check_transport(struct rpmi_tee_transport *priv)

/* RPMI TEE SERVICE GRP API. */

+/* TEE_PROBE_FEATURES. */
+static int rpmi_tee_probe_features(struct rpmi_tee_transport *priv,
+ u32 feature_id, u32 *value)
+{
+ struct rpmi_tee_probe_features_req req = {
+ .feature_id = cpu_to_le32(feature_id),
+ };
+ struct rpmi_tee_probe_features_resp resp;
+ size_t resp_len = sizeof(resp);
+ int ret;
+
+ ret = rpmi_tee_send(priv, RPMI_TEE_SRV_PROBE_FEATURES, &req,
+ sizeof(req), &resp, &resp_len);
+ if (ret)
+ return ret;
+ if (resp_len != sizeof(resp))
+ return -EPROTO;
+
+ *value = get_unaligned_le32(&resp.value);
+
+ return 0;
+}
+
/* Return the transport that owns @rdev. */
static struct rpmi_tee_transport *
rpmi_tee_device_to_transport(struct rpmi_tee_device *rdev)
@@ -371,6 +421,7 @@ static int rpmi_tee_setup_endpoints(struct rpmi_tee_transport *priv)
static int rpmi_tee_transport_probe(struct platform_device *pdev)
{
struct rpmi_tee_transport *priv;
+ u32 value;
int ret;

priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -394,6 +445,28 @@ static int rpmi_tee_transport_probe(struct platform_device *pdev)
goto out_failed;
}

+ ret = rpmi_tee_probe_features(priv, RPMI_TEE_FEATURE_MEMORY_LEND,
+ &value);
+ if (ret)
+ goto out_failed;
+ priv->mem.lend_ok = value == RPMI_TEE_MEMORY_FEATURE_FULLY_SUPPORTED;
+
+ ret = rpmi_tee_probe_features(priv, RPMI_TEE_FEATURE_MEMORY_SHARE,
+ &value);
+ if (ret)
+ goto out_failed;
+ priv->mem.share_ok = value == RPMI_TEE_MEMORY_FEATURE_FULLY_SUPPORTED;
+
+ ret = rpmi_tee_probe_features(priv, RPMI_TEE_FEATURE_MULTISEGMENT_OPS,
+ &priv->mem.multisegment_max);
+ if (ret)
+ goto out_failed;
+
+ ret = rpmi_tee_probe_features(priv, RPMI_TEE_FEATURE_SIGNAL_BUS,
+ &priv->notif.feature);
+ if (ret)
+ goto out_failed;
+
ret = rpmi_tee_setup_endpoints(priv);
if (ret) {
dev_err_probe(&pdev->dev, ret,
diff --git a/drivers/firmware/riscv_rpmi_tee/rpmi_tee_private.h b/drivers/firmware/riscv_rpmi_tee/rpmi_tee_private.h
index 07e6b9913cb7..0c3cfa0f14ec 100644
--- a/drivers/firmware/riscv_rpmi_tee/rpmi_tee_private.h
+++ b/drivers/firmware/riscv_rpmi_tee/rpmi_tee_private.h
@@ -14,17 +14,28 @@
/* TEE service group and the services used by this module. */
#define RPMI_SRVGRP_TEE 0x10

+#define RPMI_TEE_SRV_PROBE_FEATURES 0x02
#define RPMI_TEE_SRV_PROBE_SYSTEM 0x03
#define RPMI_TEE_SRV_PROBE_DOMAIN 0x04
#define RPMI_TEE_SRV_PROBE_ENDPOINT 0x05
#define RPMI_TEE_SRV_CALL 0x18

+struct rpmi_tee_notif_state {
+ u32 feature;
+};
+
struct rpmi_tee_mbox {
struct mbox_client client;
struct mbox_chan *chan;
u32 max_msg_data_size;
};

+struct rpmi_tee_mem_state {
+ u32 multisegment_max;
+ bool lend_ok;
+ bool share_ok;
+};
+
/**
* struct rpmi_tee_transport - State for one RPMI TEE transport instance
* @dev: Parent platform device.
@@ -33,6 +44,8 @@ struct rpmi_tee_mbox {
* @max_call_resp_size: Maximum TEE_CALL response payload size in bytes.
* @self_id: Local REE physical endpoint identifier.
* @devices: List of registered TEE service devices.
+ * @mem: Memory parcel operation state.
+ * @notif: Signal notification state.
*/
struct rpmi_tee_transport {
struct device *dev;
@@ -41,6 +54,8 @@ struct rpmi_tee_transport {
size_t max_call_resp_size;
u32 self_id;
struct list_head devices;
+ struct rpmi_tee_mem_state mem;
+ struct rpmi_tee_notif_state notif;
};

/* Report local transport errors separately from the returned RPMI status. */

--
2.34.1