mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 10:04:26 +00:00
Merge changes from topic "mp/group0_support" into integration
* changes: docs(spm): support for handling Group0 interrupts feat(spmd): introduce platform handler for Group0 interrupt feat(spmd): add support for FFA_EL3_INTR_HANDLE_32 ABI feat(spmd): register handler for group0 interrupt from NWd
This commit is contained in:
commit
17f9732da5
11 changed files with 189 additions and 6 deletions
|
@ -1318,6 +1318,25 @@ A brief description of the events:
|
|||
direct request to SP2 by invoking FFA_RUN.
|
||||
- 9) SPMC resumes the pre-empted vCPU of SP2.
|
||||
|
||||
EL3 interrupt handling
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In GICv3 based systems, EL3 interrupts are configured as Group0 secure
|
||||
interrupts. Execution traps to SPMC when a Group0 interrupt triggers while an
|
||||
SP is running. Further, SPMC running at S-EL2 uses FFA_EL3_INTR_HANDLE ABI to
|
||||
request EL3 platform firmware to handle a pending Group0 interrupt.
|
||||
Similarly, SPMD registers a handler with interrupt management framework to
|
||||
delegate handling of Group0 interrupt to the platform if the interrupt triggers
|
||||
in normal world.
|
||||
|
||||
- Platform hook
|
||||
|
||||
- plat_spmd_handle_group0_interrupt
|
||||
|
||||
SPMD provides platform hook to handle Group0 secure interrupts. In the
|
||||
current design, SPMD expects the platform not to delegate handling to the
|
||||
NWd (such as through SDEI) while processing Group0 interrupts.
|
||||
|
||||
Power management
|
||||
----------------
|
||||
|
||||
|
@ -1557,4 +1576,4 @@ Client <https://developer.arm.com/documentation/den0006/d/>`__
|
|||
|
||||
--------------
|
||||
|
||||
*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
|
||||
*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
|
||||
|
|
|
@ -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)
|
||||
|
|
18
plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c
Normal file
18
plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(SPD_spmd)
|
||||
/*
|
||||
* A dummy implementation of the platform handler for Group0 secure interrupt.
|
||||
*/
|
||||
int plat_spmd_handle_group0_interrupt(uint32_t intid)
|
||||
{
|
||||
(void)intid;
|
||||
return -1;
|
||||
}
|
||||
#endif /*defined(SPD_spmd)*/
|
|
@ -56,6 +56,7 @@ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \
|
|||
plat/arm/board/corstone1000/common/corstone1000_security.c \
|
||||
plat/arm/board/corstone1000/common/corstone1000_plat.c \
|
||||
plat/arm/board/corstone1000/common/corstone1000_pm.c \
|
||||
plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c \
|
||||
${CORSTONE1000_CPU_LIBS} \
|
||||
${CORSTONE1000_GIC_SOURCES}
|
||||
|
||||
|
|
17
plat/arm/board/fvp/fvp_spmd.c
Normal file
17
plat/arm/board/fvp/fvp_spmd.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int plat_spmd_handle_group0_interrupt(uint32_t intid)
|
||||
{
|
||||
/*
|
||||
* As of now, there are no sources of Group0 secure interrupt enabled
|
||||
* for FVP.
|
||||
*/
|
||||
(void)intid;
|
||||
return -1;
|
||||
}
|
|
@ -512,3 +512,7 @@ ifeq (${PLATFORM_TEST_EA_FFH}, 1)
|
|||
endif
|
||||
BL31_SOURCES += plat/arm/board/fvp/aarch64/fvp_ea.c
|
||||
endif
|
||||
|
||||
ifeq (${SPD},spmd)
|
||||
BL31_SOURCES += plat/arm/board/fvp/fvp_spmd.c
|
||||
endif
|
||||
|
|
|
@ -159,3 +159,14 @@ void bl31_platform_setup(void)
|
|||
if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0))
|
||||
remote_dmc_ecc_setup(plat_info.remote_ddr_size);
|
||||
}
|
||||
|
||||
#if defined(SPD_spmd)
|
||||
/*
|
||||
* A dummy implementation of the platform handler for Group0 secure interrupt.
|
||||
*/
|
||||
int plat_spmd_handle_group0_interrupt(uint32_t intid)
|
||||
{
|
||||
(void)intid;
|
||||
return -1;
|
||||
}
|
||||
#endif /*defined(SPD_spmd)*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -245,6 +245,15 @@ static uint64_t hikey_debug_fiq_handler(uint32_t id,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#elif defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)
|
||||
/*
|
||||
* A dummy implementation of the platform handler for Group0 secure interrupt.
|
||||
*/
|
||||
int plat_spmd_handle_group0_interrupt(uint32_t intid)
|
||||
{
|
||||
(void)intid;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void bl31_plat_runtime_setup(void)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -162,3 +162,14 @@ int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)
|
||||
/*
|
||||
* A dummy implementation of the platform handler for Group0 secure interrupt.
|
||||
*/
|
||||
int plat_spmd_handle_group0_interrupt(uint32_t intid)
|
||||
{
|
||||
(void)intid;
|
||||
return -1;
|
||||
}
|
||||
#endif /*defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)*/
|
||||
|
|
|
@ -249,6 +249,74 @@ static uint64_t spmd_secure_interrupt_handler(uint32_t id,
|
|||
SMC_RET0(&ctx->cpu_ctx);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* spmd_group0_interrupt_handler_nwd
|
||||
* Group0 secure interrupt in the normal world are trapped to EL3. Delegate the
|
||||
* handling of the interrupt to the platform handler, and return only upon
|
||||
* successfully handling the Group0 interrupt.
|
||||
******************************************************************************/
|
||||
static uint64_t spmd_group0_interrupt_handler_nwd(uint32_t id,
|
||||
uint32_t flags,
|
||||
void *handle,
|
||||
void *cookie)
|
||||
{
|
||||
uint32_t intid;
|
||||
|
||||
/* Sanity check the security state when the exception was generated. */
|
||||
assert(get_interrupt_src_ss(flags) == NON_SECURE);
|
||||
|
||||
/* Sanity check the pointer to this cpu's context. */
|
||||
assert(handle == cm_get_context(NON_SECURE));
|
||||
|
||||
assert(id == INTR_ID_UNAVAILABLE);
|
||||
|
||||
assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);
|
||||
|
||||
intid = plat_ic_get_pending_interrupt_id();
|
||||
|
||||
if (plat_spmd_handle_group0_interrupt(intid) < 0) {
|
||||
ERROR("Group0 interrupt %u not handled\n", intid);
|
||||
panic();
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -492,6 +560,16 @@ static int spmd_spmc_init(void *pm_addr)
|
|||
panic();
|
||||
}
|
||||
|
||||
/*
|
||||
* Register an interrupt handler routing Group0 interrupts to SPMD
|
||||
* while the NWd is running.
|
||||
*/
|
||||
rc = register_interrupt_type_handler(INTR_TYPE_EL3,
|
||||
spmd_group0_interrupt_handler_nwd,
|
||||
flags);
|
||||
if (rc != 0) {
|
||||
panic();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1089,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);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -93,6 +93,13 @@ spmd_spm_core_context_t *spmd_get_context(void);
|
|||
int spmd_pm_secondary_ep_register(uintptr_t entry_point);
|
||||
bool spmd_check_address_in_binary_image(uint64_t address);
|
||||
|
||||
/*
|
||||
* Platform hook in EL3 firmware to handle for Group0 secure interrupt.
|
||||
* Return values:
|
||||
* 0 = success
|
||||
* otherwise it returns a negative value
|
||||
*/
|
||||
int plat_spmd_handle_group0_interrupt(uint32_t id);
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* SPMD_PRIVATE_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue