feat(lfa): create LFA SMC handler template
As per the specification v1.0[1], added all Live Firmware Activation
(LFA) SMCs, including their Function IDs (FIDs) and associated error
codes.
A dummy handler function has been created as a template. Subsequent
patches will implement the handling of these SMCs.
[1]: https://developer.arm.com/documentation/den0147/latest/
Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
Change-Id: I5d6500dcff35aa4a438cd5f97f349cd57406ddce
diff --git a/Makefile b/Makefile
index 2d85b72..88c7b69 100644
--- a/Makefile
+++ b/Makefile
@@ -1114,6 +1114,10 @@
$(info DICE_PROTECTION_ENVIRONMENT is an experimental feature)
endif
+ifeq (${LFA_SUPPORT},1)
+ $(warning LFA_SUPPORT is an experimental feature)
+endif #(LFA_SUPPORT)
+
################################################################################
# Process platform overrideable behaviour
################################################################################
@@ -1315,6 +1319,7 @@
EARLY_CONSOLE \
PRESERVE_DSU_PMU_REGS \
HOB_LIST \
+ LFA_SUPPORT \
)))
# Numeric_Flags
@@ -1545,6 +1550,7 @@
EARLY_CONSOLE \
PRESERVE_DSU_PMU_REGS \
HOB_LIST \
+ LFA_SUPPORT \
)))
ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index e390915..8abafcd 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -177,6 +177,11 @@
${MBEDTLS_SOURCES}
endif
+ifeq (${LFA_SUPPORT},1)
+include services/std_svc/lfa/lfa.mk
+BL31_SOURCES += ${LFA_SOURCES}
+endif
+
ifeq ($(CROS_WIDEVINE_SMC),1)
BL31_SOURCES += services/oem/chromeos/widevine_smc_handlers.c
endif
diff --git a/changelog.yaml b/changelog.yaml
index 5a8ca1e..e0a4f42 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -775,6 +775,9 @@
- title: ChromeOS
scope: cros
+ - title: Live Firmware Activation
+ scope: lfa
+
- title: Secure Payload Dispatcher
scope: spd
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index e80f3d1..9d2df33 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -1497,6 +1497,9 @@
per the `PSA Crypto API specification`_. This feature is only supported if
using MbedTLS 3.x version. It is disabled (``0``) by default.
+- ``LFA_SUPPORT``: Boolean flag to enable support for Live Firmware
+ activation as per the specification. This option defaults to 0.
+
- ``TRANSFER_LIST``: Setting this to ``1`` enables support for Firmware
Handoff using Transfer List defined in `Firmware Handoff specification`_.
This defaults to ``0``. Current implementation follows the Firmware Handoff
diff --git a/include/services/lfa_svc.h b/include/services/lfa_svc.h
new file mode 100644
index 0000000..1f91619
--- /dev/null
+++ b/include/services/lfa_svc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef LFA_SVC_H
+#define LFA_SVC_H
+
+#include <lib/smccc.h>
+
+/*
+ * SMC function IDs for LFA Service
+ * Upper word bits set: Fast call, SMC64, Standard Secure Svc. Call (OEN = 4)
+ */
+#define LFA_FID(func_num) \
+ ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ (SMC_64 << FUNCID_CC_SHIFT) | \
+ (OEN_STD_START << FUNCID_OEN_SHIFT) | \
+ ((func_num) << FUNCID_NUM_SHIFT))
+
+#define LFA_VERSION LFA_FID(0x2E0)
+#define LFA_FEATURES LFA_FID(0x2E1)
+#define LFA_GET_INFO LFA_FID(0x2E2)
+#define LFA_GET_INVENTORY LFA_FID(0x2E3)
+#define LFA_PRIME LFA_FID(0x2E4)
+#define LFA_ACTIVATE LFA_FID(0x2E5)
+#define LFA_CANCEL LFA_FID(0x2E6)
+
+/* Check whether FID is in the range */
+#define is_lfa_fid(_fid) \
+ ((_fid >= LFA_VERSION) && (_fid <= LFA_CANCEL))
+
+/* LFA Service Calls version numbers */
+#define LFA_VERSION_MAJOR U(1)
+#define LFA_VERSION_MAJOR_SHIFT 16
+#define LFA_VERSION_MAJOR_MASK U(0x7FFF)
+#define LFA_VERSION_MINOR U(0)
+#define LFA_VERSION_MINOR_SHIFT 0
+#define LFA_VERSION_MINOR_MASK U(0xFFFF)
+
+#define LFA_VERSION_VAL \
+ ((((LFA_VERSION_MAJOR) & LFA_VERSION_MAJOR_MASK) << \
+ LFA_VERSION_MAJOR_SHIFT) \
+ | (((LFA_VERSION_MINOR) & LFA_VERSION_MINOR_MASK) << \
+ LFA_VERSION_MINOR_SHIFT))
+
+/* List of errors as per the specification */
+enum lfa_retc {
+ LFA_SUCCESS = 0,
+ LFA_NOT_SUPPORTED = -1,
+ LFA_BUSY = -2,
+ LFA_AUTH_ERROR = -3,
+ LFA_NO_MEMORY = -4,
+ LFA_CRITICAL_ERROR = -5,
+ LFA_DEVICE_ERROR = -6,
+ LFA_WRONG_STATE = -7,
+ LFA_INVALID_PARAMETERS = -8,
+ LFA_COMPONENT_WRONG_STATE = -9,
+ LFA_INVALID_ADDRESS = -10,
+ LFA_ACTIVATION_FAILED = -11,
+};
+
+/* Initialization routine for the LFA service */
+int lfa_setup(void);
+
+uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
+ u_register_t x3, u_register_t x4, void *cookie,
+ void *handle, u_register_t flags);
+
+#endif /* LFA_SVC_H */
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 4ccca9f..2657387 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -435,3 +435,6 @@
# This flag is temporary and it is expected once the interface is
# finalized, this flag will be removed.
RMMD_ENABLE_IDE_KEY_PROG := 0
+
+# Live firmware activation support
+LFA_SUPPORT := 0
diff --git a/services/std_svc/lfa/lfa.mk b/services/std_svc/lfa/lfa.mk
new file mode 100644
index 0000000..911f72c
--- /dev/null
+++ b/services/std_svc/lfa/lfa.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2025, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LFA_SOURCES += $(addprefix services/std_svc/lfa/, \
+ lfa_main.c)
diff --git a/services/std_svc/lfa/lfa_main.c b/services/std_svc/lfa/lfa_main.c
new file mode 100644
index 0000000..8f3d6ec
--- /dev/null
+++ b/services/std_svc/lfa/lfa_main.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <services/lfa_svc.h>
+#include <smccc_helpers.h>
+
+int lfa_setup(void)
+{
+ return LFA_SUCCESS;
+}
+
+uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
+ u_register_t x3, u_register_t x4, void *cookie,
+ void *handle, u_register_t flags)
+{
+ /**
+ * TODO: Acquire serialization lock.
+ */
+ switch (smc_fid) {
+ case LFA_VERSION:
+ SMC_RET1(handle, LFA_VERSION_VAL);
+ break;
+
+ case LFA_FEATURES:
+ SMC_RET1(handle, is_lfa_fid(x1) ? LFA_SUCCESS : LFA_NOT_SUPPORTED);
+ break;
+
+ case LFA_GET_INFO:
+ break;
+
+ case LFA_GET_INVENTORY:
+ break;
+
+ case LFA_PRIME:
+ break;
+
+ case LFA_ACTIVATE:
+ break;
+
+ case LFA_CANCEL:
+ break;
+
+ default:
+ WARN("Unimplemented LFA Service Call: 0x%x\n", smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+ break; /* unreachable */
+
+ }
+
+ SMC_RET1(handle, SMC_UNK);
+
+ return 0;
+}
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index deca1c0..11c6031 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,6 +15,7 @@
#include <lib/runtime_instr.h>
#include <services/drtm_svc.h>
#include <services/errata_abi_svc.h>
+#include <services/lfa_svc.h>
#include <services/pci_svc.h>
#include <services/rmmd_svc.h>
#include <services/sdei.h>
@@ -86,6 +87,15 @@
}
#endif /* DRTM_SUPPORT */
+#if LFA_SUPPORT
+ /*
+ * Setup/Initialize resources useful during LFA
+ */
+ if (lfa_setup() != 0) {
+ ret = 1;
+ }
+#endif /* LFA_SUPPORT */
+
return ret;
}
@@ -217,6 +227,13 @@
}
#endif /* DRTM_SUPPORT */
+#if LFA_SUPPORT
+ if (is_lfa_fid(smc_fid)) {
+ return lfa_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+ }
+#endif /* LFA_SUPPORT */
+
+
switch (smc_fid) {
case ARM_STD_SVC_CALL_COUNT:
/*