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
