lib: arm_ffa: Add support for sending FFA_MSG_SEND_DIRECT_REQ2 requests Bug: 391968135 Change-Id: Ibd6638f1c3b52f9ab68539892672487f8ed0b200
diff --git a/lib/arm_ffa/arm_ffa.c b/lib/arm_ffa/arm_ffa.c index 6fbe3c7..e2c68c4 100644 --- a/lib/arm_ffa/arm_ffa.c +++ b/lib/arm_ffa/arm_ffa.c
@@ -49,6 +49,7 @@ static bool supports_ns_bit = false; static bool supports_rx_release = false; static bool console_log_is_unsupported; +static bool send_direct_req2_is_unsupported; static mutex_t ffa_rxtx_buffer_lock = MUTEX_INITIAL_VALUE(ffa_rxtx_buffer_lock); @@ -467,6 +468,69 @@ return smc8(fid, sender_receiver_id, flags, a0, a1, a2, a3, a4); } +status_t arm_ffa_msg_send_direct_req2(uuid_t uuid, + uint16_t receiver_id, + uint64_t args[static 14], + struct smc_ret18* resp) { + struct smc_ret18 smc_ret; + uint64_t uuid_lo_hi[2]; + uint32_t fid = SMC_FC64_FFA_MSG_SEND_DIRECT_REQ2; + uint32_t sender_receiver_id = ((uint32_t)ffa_local_id << 16) | receiver_id; + + if (send_direct_req2_is_unsupported) { + return FFA_ERROR_NOT_SUPPORTED; + } + + if (!args || !resp) { + return ERR_INVALID_ARGS; + } + + uuid_to_le64_pair(uuid, uuid_lo_hi); + + smc_ret = smc18(fid, sender_receiver_id, uuid_lo_hi[0], uuid_lo_hi[1], + args[0], args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8], args[9], args[10], args[11], + args[12], args[13]); + + switch ((uint32_t)smc_ret.r0) { + case SMC_FC64_FFA_MSG_SEND_DIRECT_RESP2: + *resp = smc_ret; + return NO_ERROR; + + case SMC_FC_FFA_ERROR: + switch ((int32_t)smc_ret.r2) { + case FFA_ERROR_NOT_SUPPORTED: + send_direct_req2_is_unsupported = true; + return ERR_NOT_SUPPORTED; + case FFA_ERROR_INVALID_PARAMETERS: + dprintf(CRITICAL, "Invalid parameters for direct request2\n"); + return ERR_INVALID_ARGS; + default: + return ERR_NOT_VALID; + } + + case SMC_UNKNOWN: + send_direct_req2_is_unsupported = true; + return ERR_NOT_SUPPORTED; + + case SMC_FC_FFA_INTERRUPT: + /* + * SMC_FC_FFA_INTERRUPT or SMC_FC_FFA_YIELD can be returned per the FF-A + * spec but it shouldn't happen when Trusty is the receiver of requests. + */ + panic("Received SMC_FC_FFA_INTERRUPT in response to direct request2"); + + case SMC_FC_FFA_YIELD: + /* See previous case */ + panic("Received SMC_FC_FFA_YIELD in response to direct request2"); + + default: + dprintf(CRITICAL, "Unexpected response (%x) to direct request2\n", + (uint32_t)smc_ret.r0); + return ERR_NOT_VALID; + } +} + ssize_t arm_ffa_console_log(const char* buf, size_t len) { struct smc_ret8 smc_ret;
diff --git a/lib/arm_ffa/include/lib/arm_ffa/arm_ffa.h b/lib/arm_ffa/include/lib/arm_ffa/arm_ffa.h index c33437e..f446b35 100644 --- a/lib/arm_ffa/include/lib/arm_ffa/arm_ffa.h +++ b/lib/arm_ffa/include/lib/arm_ffa/arm_ffa.h
@@ -26,6 +26,7 @@ #include <arch/ops.h> #include <interface/arm_ffa/arm_ffa.h> #include <lib/smc/smc.h> +#include <lib/trusty/uuid.h> #include <stdbool.h> /** @@ -177,6 +178,22 @@ ulong a4); /** + * arm_ffa_msg_send_direct_req2() - Send a direct message request. + * + * @uuid: Handler UUID. + * @receiver_id: Receiver ID. + * @args: Contents of message - x4-x17. Must not be %NULL. + * @resp: The registers passed back in response to the direct message iff + * the request was successful. Must not be %NULL. + * + * Return: 0 on success, LK error code on failure. + */ +status_t arm_ffa_msg_send_direct_req2(uuid_t uuid, + uint16_t receiver_id, + uint64_t args[static REQ2_OTHER_PARAM_REGS], + struct smc_ret18* resp); + +/** * arm_ffa_console_log() - Output a buffer using %FFA_CONSOLE_LOG. * * @buf: The buffer to print.