From: Kun Qin <ku...@microsoft.com> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4466
This change extended the existing function `ArmGicSendSgiTo` of ArmGicLib to format the incoming parameters to comply with GICv3 and GICv4 spec, and signal software generated interrupts to non secure group 1 at EL1. Cc: Leif Lindholm <quic_llind...@quicinc.com> Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> Cc: Sami Mujawar <sami.muja...@arm.com> Signed-off-by: Kun Qin <ku...@microsoft.com> --- ArmPkg/Drivers/ArmGic/ArmGicLib.c | 52 +++++++++++++++++--- ArmPkg/Include/Library/ArmGicLib.h | 22 +++++++++ 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c index 7f4bb248fc72..830d822d2c05 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c +++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c @@ -146,12 +146,52 @@ ArmGicSendSgiTo ( IN UINT8 SgiId ) { - MmioWrite32 ( - GicDistributorBase + ARM_GIC_ICDSGIR, - ((TargetListFilter & 0x3) << 24) | - ((CPUTargetList & 0xFF) << 16) | - (SgiId & 0xF) - ); + ARM_GIC_ARCH_REVISION Revision; + UINT32 ApplicableTargets; + UINT32 AFF3; + UINT32 AFF2; + UINT32 AFF1; + UINT32 AFF0; + UINT32 Irm; + UINT64 SGIValue; + + Revision = ArmGicGetSupportedArchRevision (); + if (Revision == ARM_GIC_ARCH_REVISION_2) { + MmioWrite32 ( + GicDistributorBase + ARM_GIC_ICDSGIR, + ((TargetListFilter & 0x3) << 24) | + ((CPUTargetList & 0xFF) << 16) | + (SgiId & 0xF) + ); + } else { + // Below routine is adopted from gicv3_raise_secure_g0_sgi in TF-A + + /* Extract affinity fields from target */ + AFF0 = GET_MPIDR_AFF0 (CPUTargetList); + AFF1 = GET_MPIDR_AFF1 (CPUTargetList); + AFF2 = GET_MPIDR_AFF2 (CPUTargetList); + AFF3 = GET_MPIDR_AFF3 (CPUTargetList); + + /* + * Make target list from affinity 0, and ensure GICv3 SGI can target + * this PE. + */ + ApplicableTargets = (1 << AFF0); + + /* + * Evaluate the filter to see if this is for the target or all others + */ + Irm = (TargetListFilter == ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE) ? SGIR_IRM_TO_OTHERS : SGIR_IRM_TO_AFF; + + /* Raise SGI to PE specified by its affinity */ + SGIValue = GICV3_SGIR_VALUE (AFF3, AFF2, AFF1, SgiId, Irm, ApplicableTargets); + + /* + * Ensure that any shared variable updates depending on out of band + * interrupt trigger are observed before raising SGI. + */ + ArmGicV3SendNsG1Sgi (SGIValue); + } } /* diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h index 773b27954522..28d58f187d4f 100644 --- a/ArmPkg/Include/Library/ArmGicLib.h +++ b/ArmPkg/Include/Library/ArmGicLib.h @@ -110,6 +110,28 @@ // Bit Mask for #define ARM_GIC_ICCIAR_ACKINTID 0x3FF +/* ICC SGI macros */ +#define SGIR_TGT_MASK ((UINT64)0xffff) +#define SGIR_AFF1_SHIFT 16 +#define SGIR_INTID_SHIFT 24 +#define SGIR_INTID_MASK ((UINT64)0xf) +#define SGIR_AFF2_SHIFT 32 +#define SGIR_IRM_SHIFT 40 +#define SGIR_IRM_MASK ((UINT64)0x1) +#define SGIR_AFF3_SHIFT 48 +#define SGIR_AFF_MASK ((UINT64)0xff) + +#define SGIR_IRM_TO_AFF 0 +#define SGIR_IRM_TO_OTHERS 1 + +#define GICV3_SGIR_VALUE(_aff3, _aff2, _aff1, _intid, _irm, _tgt) \ + ((((UINT64) (_aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \ + (((UINT64) (_irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \ + (((UINT64) (_aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \ + (((_intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \ + (((_aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \ + ((_tgt) & SGIR_TGT_MASK)) + UINT32 EFIAPI ArmGicGetInterfaceIdentification ( -- 2.41.0.windows.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107189): https://edk2.groups.io/g/devel/message/107189 Mute This Topic: https://groups.io/mt/100337223/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-