feat(gic): add APIs to raise NS and S-EL1 SGIs

This patch adds two helper functions:
 - plat_ic_raise_ns_sgi to raise a NS SGI
 - plat_ic_raise_s_el1_sgi to raise a S-EL1 SGI

Signed-off-by: Florian Lugou <florian.lugou@provenrun.com>
Change-Id: I6f262dd1da1d77fec3f850eb74189e726b8e24da
This commit is contained in:
Florian Lugou 2021-09-08 12:40:24 +02:00
parent 28a28511c4
commit dcb31ff790
11 changed files with 109 additions and 11 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -417,7 +418,7 @@ void gicv2_set_interrupt_type(unsigned int id, unsigned int type)
* The proc_num parameter must be the linear index of the target PE in the
* system.
******************************************************************************/
void gicv2_raise_sgi(int sgi_num, int proc_num)
void gicv2_raise_sgi(int sgi_num, bool ns, int proc_num)
{
unsigned int sgir_val, target;
@ -437,7 +438,7 @@ void gicv2_raise_sgi(int sgi_num, int proc_num)
target = driver_data->target_masks[proc_num];
assert(target != 0U);
sgir_val = GICV2_SGIR_VALUE(SGIR_TGT_SPECIFIC, target, sgi_num);
sgir_val = GICV2_SGIR_VALUE(SGIR_TGT_SPECIFIC, target, ns, sgi_num);
/*
* Ensure that any shared variable updates depending on out of band

View file

@ -1095,11 +1095,12 @@ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
}
/*******************************************************************************
* This function raises the specified Secure Group 0 SGI.
* This function raises the specified SGI of the specified group.
*
* The target parameter must be a valid MPIDR in the system.
******************************************************************************/
void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target)
void gicv3_raise_sgi(unsigned int sgi_num, gicv3_irq_group_t group,
u_register_t target)
{
unsigned int tgt, aff3, aff2, aff1, aff0;
uint64_t sgi_val;
@ -1129,7 +1130,22 @@ void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target)
* interrupt trigger are observed before raising SGI.
*/
dsbishst();
write_icc_sgi0r_el1(sgi_val);
switch (group) {
case GICV3_G0:
write_icc_sgi0r_el1(sgi_val);
break;
case GICV3_G1NS:
write_icc_asgi1r(sgi_val);
break;
case GICV3_G1S:
write_icc_sgi1r(sgi_val);
break;
default:
assert(false);
break;
}
isb();
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -282,6 +283,7 @@ DEFINE_COPROCR_RW_FUNCS(icc_eoir0_el1, ICC_EOIR0)
DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1)
DEFINE_COPROCR_RW_FUNCS_64(icc_sgi0r_el1, ICC_SGI0R_EL1_64)
DEFINE_COPROCR_WRITE_FUNC_64(icc_sgi1r, ICC_SGI1R_EL1_64)
DEFINE_COPROCR_WRITE_FUNC_64(icc_asgi1r, ICC_ASGI1R_EL1_64)
DEFINE_COPROCR_RW_FUNCS(sdcr, SDCR)
DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
@ -402,6 +404,8 @@ static inline unsigned int get_current_el(void)
#define read_ctr_el0() read_ctr()
#define write_icc_sgi0r_el1(_v) write64_icc_sgi0r_el1(_v)
#define write_icc_sgi1r(_v) write64_icc_sgi1r(_v)
#define write_icc_asgi1r(_v) write64_icc_asgi1r(_v)
#define read_daif() read_cpsr()
#define write_daif(flags) write_cpsr(flags)

View file

@ -79,6 +79,7 @@
******************************************************************************/
#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7
#define ICC_SGI1R S3_0_C12_C11_5
#define ICC_ASGI1R S3_0_C12_C11_6
#define ICC_SRE_EL1 S3_0_C12_C12_5
#define ICC_SRE_EL2 S3_4_C12_C9_5
#define ICC_SRE_EL3 S3_6_C12_C12_5

View file

@ -492,6 +492,7 @@ DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir0_el1, ICC_EOIR0_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r, ICC_ASGI1R)
DEFINE_RENAME_SYSREG_READ_FUNC(amcfgr_el0, AMCFGR_EL0)
DEFINE_RENAME_SYSREG_READ_FUNC(amcgcr_el0, AMCGCR_EL0)

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -50,13 +51,15 @@
#define SGIR_TGTLSTFLT_MASK U(0x3)
#define SGIR_TGTLST_SHIFT 16
#define SGIR_TGTLST_MASK U(0xff)
#define SGIR_NSATT (U(0x1) << 16)
#define SGIR_INTID_MASK ULL(0xf)
#define SGIR_TGT_SPECIFIC U(0)
#define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, intid) \
#define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, nsatt, intid) \
((((tgt_lst_flt) & SGIR_TGTLSTFLT_MASK) << SGIR_TGTLSTFLT_SHIFT) | \
(((tgt) & SGIR_TGTLST_MASK) << SGIR_TGTLST_SHIFT) | \
((nsatt) ? SGIR_NSATT : U(0)) | \
((intid) & SGIR_INTID_MASK))
/*******************************************************************************
@ -127,6 +130,7 @@
#ifndef __ASSEMBLER__
#include <cdefs.h>
#include <stdbool.h>
#include <stdint.h>
#include <common/interrupt_props.h>
@ -185,7 +189,7 @@ void gicv2_enable_interrupt(unsigned int id);
void gicv2_disable_interrupt(unsigned int id);
void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority);
void gicv2_set_interrupt_type(unsigned int id, unsigned int type);
void gicv2_raise_sgi(int sgi_num, int proc_num);
void gicv2_raise_sgi(int sgi_num, bool ns, int proc_num);
void gicv2_set_spi_routing(unsigned int id, int proc_num);
void gicv2_set_interrupt_pending(unsigned int id);
void gicv2_clear_interrupt_pending(unsigned int id);

View file

@ -354,6 +354,12 @@
#include <drivers/arm/gic_common.h>
#include <lib/utils_def.h>
typedef enum {
GICV3_G1S,
GICV3_G1NS,
GICV3_G0
} gicv3_irq_group_t;
static inline uintptr_t gicv3_redist_size(uint64_t typer_val)
{
#if GIC_ENABLE_V4_EXTN
@ -575,7 +581,8 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
unsigned int priority);
void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
unsigned int type);
void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target);
void gicv3_raise_sgi(unsigned int sgi_num, gicv3_irq_group_t group,
u_register_t target);
void gicv3_set_spi_routing(unsigned int id, unsigned int irm,
u_register_t mpidr);
void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);

View file

@ -104,6 +104,8 @@ int plat_ic_has_interrupt_type(unsigned int type);
void plat_ic_set_interrupt_type(unsigned int id, unsigned int type);
void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority);
void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target);
void plat_ic_raise_ns_sgi(int sgi_num, u_register_t target);
void plat_ic_raise_s_el1_sgi(int sgi_num, u_register_t target);
void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
u_register_t mpidr);
void plat_ic_set_interrupt_pending(unsigned int id);

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -34,6 +35,8 @@
#pragma weak plat_ic_set_interrupt_priority
#pragma weak plat_ic_set_interrupt_type
#pragma weak plat_ic_raise_el3_sgi
#pragma weak plat_ic_raise_ns_sgi
#pragma weak plat_ic_raise_s_el1_sgi
#pragma weak plat_ic_set_spi_routing
/*
@ -247,12 +250,44 @@ void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target)
/* Verify that this is a secure SGI */
assert(plat_ic_get_interrupt_type(sgi_num) == INTR_TYPE_EL3);
gicv2_raise_sgi(sgi_num, id);
gicv2_raise_sgi(sgi_num, false, id);
#else
assert(false);
#endif
}
void plat_ic_raise_ns_sgi(int sgi_num, u_register_t target)
{
int id;
/* Target must be a valid MPIDR in the system */
id = plat_core_pos_by_mpidr(target);
assert(id >= 0);
/* Verify that this is a non-secure SGI */
assert(plat_ic_get_interrupt_type(sgi_num) == INTR_TYPE_NS);
gicv2_raise_sgi(sgi_num, true, id);
}
void plat_ic_raise_s_el1_sgi(int sgi_num, u_register_t target)
{
#if GICV2_G0_FOR_EL3
assert(false);
#else
int id;
/* Target must be a valid MPIDR in the system */
id = plat_core_pos_by_mpidr(target);
assert(id >= 0);
/* Verify that this is a secure EL1 SGI */
assert(plat_ic_get_interrupt_type(sgi_num) == INTR_TYPE_S_EL1);
gicv2_raise_sgi(sgi_num, false, id);
#endif
}
void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
u_register_t mpidr)
{

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -39,6 +40,8 @@
#pragma weak plat_ic_set_interrupt_priority
#pragma weak plat_ic_set_interrupt_type
#pragma weak plat_ic_raise_el3_sgi
#pragma weak plat_ic_raise_ns_sgi
#pragma weak plat_ic_raise_s_el1_sgi
#pragma weak plat_ic_set_spi_routing
#pragma weak plat_ic_set_interrupt_pending
#pragma weak plat_ic_clear_interrupt_pending
@ -242,7 +245,31 @@ void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target)
assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) ==
INTR_TYPE_EL3);
gicv3_raise_secure_g0_sgi((unsigned int)sgi_num, target);
gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G0, target);
}
void plat_ic_raise_ns_sgi(int sgi_num, u_register_t target)
{
/* Target must be a valid MPIDR in the system */
assert(plat_core_pos_by_mpidr(target) >= 0);
/* Verify that this is a non-secure SGI */
assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) ==
INTR_TYPE_NS);
gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G1NS, target);
}
void plat_ic_raise_s_el1_sgi(int sgi_num, u_register_t target)
{
/* Target must be a valid MPIDR in the system */
assert(plat_core_pos_by_mpidr(target) >= 0);
/* Verify that this is a secure EL1 SGI */
assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) ==
INTR_TYPE_S_EL1);
gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G1S, target);
}
void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,

View file

@ -87,7 +87,7 @@ static int stm32_pwr_domain_on(u_register_t mpidr)
clk_disable(RTCAPB);
/* Generate an IT to core 1 */
gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP_SECONDARY_CPU);
gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, false, STM32MP_SECONDARY_CPU);
return PSCI_E_SUCCESS;
}