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@oss.qualcomm.com --- 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. */