From 6671b3d8224a8c4c3fea7cbe66b56945c432393f Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Thu, 2 Mar 2023 16:04:38 -0600 Subject: [PATCH] feat(spmd): add support for FFA_EL3_INTR_HANDLE_32 ABI 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 --- include/services/ffa_svc.h | 6 +++-- services/std_svc/spmd/spmd_main.c | 41 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h index 8bc911a68..64af437bb 100644 --- a/include/services/ffa_svc.h +++ b/include/services/ffa_svc.h @@ -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) && \ @@ -118,6 +118,7 @@ #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) @@ -163,6 +164,7 @@ #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) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index e34d39495..80b506bc6 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -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); -- 2.39.5