]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(spmd): add support for FFA_EL3_INTR_HANDLE_32 ABI
authorMadhukar Pappireddy <madhukar.pappireddy@arm.com>
Thu, 2 Mar 2023 22:04:38 +0000 (16:04 -0600)
committerMadhukar Pappireddy <madhukar.pappireddy@arm.com>
Mon, 1 May 2023 18:29:12 +0000 (13:29 -0500)
When Group0 Secure interrupts in secure world get trapped to S-EL2
SPMC, FFA_EL3_INTR_HANDLE ABI is invoked by SPMC to delegate
interrupt handling to EL3 firmware (i.e., SPMD).

SPMD further delegates to platform handler which successfully handles
the Group0 secure interrupt before returning control to SPMC.

Change-Id: I8cc0fec20803b96c81582910ad2668e38b167fb8
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
include/services/ffa_svc.h
services/std_svc/spmd/spmd_main.c

index 8bc911a684e1236696f943a90a5a988038cbe5ff..64af437bb0ce072aa4ceb057a9ce22d9a08dbcdf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,7 @@
 
 /* The macros below are used to identify FFA calls from the SMC function ID */
 #define FFA_FNUM_MIN_VALUE     U(0x60)
-#define FFA_FNUM_MAX_VALUE     U(0x8B)
+#define FFA_FNUM_MAX_VALUE     U(0x8C)
 #define is_ffa_fid(fid) __extension__ ({               \
        __typeof__(fid) _fid = (fid);                   \
        ((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&   \
 #define FFA_FNUM_MSG_SEND2                     U(0x86)
 #define FFA_FNUM_SECONDARY_EP_REGISTER         U(0x87)
 #define FFA_FNUM_PARTITION_INFO_GET_REGS       U(0x8B)
+#define FFA_FNUM_EL3_INTR_HANDLE               U(0x8C)
 
 /* FFA SMC32 FIDs */
 #define FFA_ERROR              FFA_FID(SMC_32, FFA_FNUM_ERROR)
 #define FFA_MEM_FRAG_TX        FFA_FID(SMC_32, FFA_FNUM_MEM_FRAG_TX)
 #define FFA_SPM_ID_GET         FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
 #define FFA_NORMAL_WORLD_RESUME        FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
+#define FFA_EL3_INTR_HANDLE    FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
 
 /* FFA SMC64 FIDs */
 #define FFA_ERROR_SMC64                FFA_FID(SMC_64, FFA_FNUM_ERROR)
index e34d39495fda2eadaaa59bc29fd7f5f4688be1b3..80b506bc60edafbe3698eb75bc4b3ca1d6f36f8e 100644 (file)
@@ -282,6 +282,41 @@ static uint64_t spmd_group0_interrupt_handler_nwd(uint32_t id,
        return 0U;
 }
 
+/*******************************************************************************
+ * spmd_handle_group0_intr_swd
+ * SPMC delegates handling of Group0 secure interrupt to EL3 firmware using
+ * FFA_EL3_INTR_HANDLE SMC call. Further, SPMD delegates the handling of the
+ * interrupt to the platform handler, and returns only upon successfully
+ * handling the Group0 interrupt.
+ ******************************************************************************/
+static uint64_t spmd_handle_group0_intr_swd(void *handle)
+{
+       uint32_t intid;
+
+       /* Sanity check the pointer to this cpu's context */
+       assert(handle == cm_get_context(SECURE));
+
+       assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);
+
+       intid = plat_ic_get_pending_interrupt_id();
+
+       /*
+        * TODO: Currently due to a limitation in SPMD implementation, the
+        * platform handler is expected to not delegate handling to NWd while
+        * processing Group0 secure interrupt.
+        */
+       if (plat_spmd_handle_group0_interrupt(intid) < 0) {
+               /* Group0 interrupt was not handled by the platform. */
+               ERROR("Group0 interrupt %u not handled\n", intid);
+               panic();
+       }
+
+       /* Return success. */
+       SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+                FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+                FFA_PARAM_MBZ);
+}
+
 #if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
 static int spmd_dynamic_map_mem(uintptr_t base_addr, size_t size,
                                 unsigned int attr, uintptr_t *align_addr,
@@ -1132,6 +1167,12 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
                                        handle, flags);
                break; /* Not reached */
 #endif
+       case FFA_EL3_INTR_HANDLE:
+               if (secure_origin) {
+                       return spmd_handle_group0_intr_swd(handle);
+               } else {
+                       return spmd_ffa_error_return(handle, FFA_ERROR_DENIED);
+               }
        default:
                WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
                return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);