Track when ExitBootServices() has been called and make the MM transport
selection helper callable from EFI runtime code.

At runtime, select the FF-A transport only when FF-A runtime mode is
enabled. Otherwise keep using the OP-TEE MM communication path so builds
without CONFIG_ARM_FFA_RT_MODE do not lose their existing runtime
backend.

Reviewed-by: Simon Glass <[email protected]>
Reviewed-by: Abdellatif El Khlifi <[email protected]>
Signed-off-by: Harsimran Singh Tungal <[email protected]>
---
 lib/efi_loader/efi_variable_tee.c | 44 +++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/lib/efi_loader/efi_variable_tee.c 
b/lib/efi_loader/efi_variable_tee.c
index 8a75da414f7..72055b36bba 100644
--- a/lib/efi_loader/efi_variable_tee.c
+++ b/lib/efi_loader/efi_variable_tee.c
@@ -56,12 +56,28 @@ extern struct efi_var_file __efi_runtime_data *efi_var_buf;
 static efi_uintn_t max_buffer_size;    /* comm + var + func + data */
 static efi_uintn_t max_payload_size;   /* func + data */
 static const u16 __efi_runtime_rodata pk[] = u"PK";
+static bool __efi_runtime_data ebs_called;
 
 struct mm_connection {
        struct udevice *tee;
        u32 session;
 };
 
+/**
+ * efi_at_runtime() - Indicate whether the system is in the UEFI runtime phase
+ *
+ * This helper returns whether the firmware has transitioned into the
+ * UEFI runtime phase, meaning that ExitBootServices() has been invoked.
+ *
+ * Return:
+ *   true  - The system is operating in UEFI runtime mode.
+ *   false - The system is still in the boot services phase.
+ */
+static bool __efi_runtime efi_at_runtime(void)
+{
+       return ebs_called;
+}
+
 /**
  * get_connection() - Retrieve OP-TEE session for a specific UUID.
  *
@@ -399,27 +415,30 @@ static efi_status_t ffa_mm_communicate(void *comm_buf, 
ulong comm_buf_size)
 /**
  * get_mm_comms() - detect the available MM transport
  *
- * Make sure the FF-A bus is probed successfully
- * which means FF-A communication with secure world works and ready
- * for use.
+ * Make sure the FF-A bus is probed successfully during the boot phase,
+ * which means FF-A communication with secure world works and is ready for
+ * use. During the runtime phase, use FF-A only when FF-A runtime mode is
+ * enabled; otherwise keep using OP-TEE comms.
  *
- * If FF-A bus is not ready, use OPTEE comms.
+ * If FF-A bus is not ready at boot, use OP-TEE comms.
  *
- * Return:
- *
- * MM_COMMS_FFA or MM_COMMS_OPTEE
+ * Return: MM_COMMS_FFA or MM_COMMS_OPTEE
  */
-static enum mm_comms_select get_mm_comms(void)
+static enum mm_comms_select __efi_runtime get_mm_comms(void)
 {
        struct udevice *dev;
        int ret;
 
-       ret = uclass_first_device_err(UCLASS_FFA, &dev);
-       if (ret) {
-               log_debug("EFI: Cannot find FF-A bus device, trying Optee 
comms\n");
+       if (efi_at_runtime()) {
+               if (IS_ENABLED(CONFIG_ARM_FFA_RT_MODE))
+                       return MM_COMMS_FFA;
                return MM_COMMS_OPTEE;
        }
 
+       ret = uclass_first_device_err(UCLASS_FFA, &dev);
+       if (ret)
+               return MM_COMMS_OPTEE;
+
        return MM_COMMS_FFA;
 }
 #endif
@@ -1018,6 +1037,9 @@ void efi_variables_boot_exit_notify(void)
                        efi_get_next_variable_name_runtime;
        efi_runtime_services.set_variable = efi_set_variable_runtime;
        efi_update_table_header_crc32(&efi_runtime_services.hdr);
+
+       /* Record that ExitBootServices() has been called */
+       ebs_called = true;
 }
 
 /**
-- 
2.34.1

Reply via email to