aboutsummaryrefslogtreecommitdiffstats
path: root/plat/common/plat_gicv2.c
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-09-22 08:32:09 +0100
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-10-16 16:50:01 +0100
commit74dce7fa6e42cab3aa54a9543e4a546c1450b2ae (patch)
tree934d39529b67d798867e252b039f4f8fcae74a67 /plat/common/plat_gicv2.c
parentf3a866004ea8f9a0cd5420f3dd4d4683f638e6da (diff)
downloadplatform_external_arm-trusted-firmware-74dce7fa6e42cab3aa54a9543e4a546c1450b2ae.tar.gz
platform_external_arm-trusted-firmware-74dce7fa6e42cab3aa54a9543e4a546c1450b2ae.tar.bz2
platform_external_arm-trusted-firmware-74dce7fa6e42cab3aa54a9543e4a546c1450b2ae.zip
GIC: Add APIs to set interrupt type and query support
The back end GIC driver converts and assigns the interrupt type to suitable group. For GICv2, a build option GICV2_G0_FOR_EL3 is introduced, which determines to which type Group 0 interrupts maps to. - When the build option is set 0 (the default), Group 0 interrupts are meant for Secure EL1. This is presently the case. - Otherwise, Group 0 interrupts are meant for EL3. This means the SPD will have to synchronously hand over the interrupt to Secure EL1. The query API allows the platform to query whether the platform supports interrupts of a given type. API documentation updated. Change-Id: I60fdb4053ffe0bd006b3b20914914ebd311fc858 Co-authored-by: Yousuf A <yousuf.sait@arm.com> Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'plat/common/plat_gicv2.c')
-rw-r--r--plat/common/plat_gicv2.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/plat/common/plat_gicv2.c b/plat/common/plat_gicv2.c
index d50138edf..c785d8317 100644
--- a/plat/common/plat_gicv2.c
+++ b/plat/common/plat_gicv2.c
@@ -28,6 +28,7 @@
#pragma weak plat_ic_enable_interrupt
#pragma weak plat_ic_disable_interrupt
#pragma weak plat_ic_set_interrupt_priority
+#pragma weak plat_ic_set_interrupt_type
/*
* This function returns the highest priority pending interrupt at
@@ -62,8 +63,13 @@ uint32_t plat_ic_get_pending_interrupt_type(void)
id = gicv2_get_pending_interrupt_type();
/* Assume that all secure interrupts are S-EL1 interrupts */
- if (id < PENDING_G1_INTID)
+ if (id < PENDING_G1_INTID) {
+#if GICV2_G0_FOR_EL3
+ return INTR_TYPE_EL3;
+#else
return INTR_TYPE_S_EL1;
+#endif
+ }
if (id == GIC_SPURIOUS_INTERRUPT)
return INTR_TYPE_INVAL;
@@ -92,7 +98,12 @@ uint32_t plat_ic_get_interrupt_type(uint32_t id)
type = gicv2_get_interrupt_group(id);
/* Assume that all secure interrupts are S-EL1 interrupts */
- return (type) ? INTR_TYPE_NS : INTR_TYPE_S_EL1;
+ return type == GICV2_INTR_GROUP1 ? INTR_TYPE_NS :
+#if GICV2_G0_FOR_EL3
+ INTR_TYPE_EL3;
+#else
+ INTR_TYPE_S_EL1;
+#endif
}
/*
@@ -171,3 +182,41 @@ void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority)
{
gicv2_set_interrupt_priority(id, priority);
}
+
+int plat_ic_has_interrupt_type(unsigned int type)
+{
+ switch (type) {
+#if GICV2_G0_FOR_EL3
+ case INTR_TYPE_EL3:
+#else
+ case INTR_TYPE_S_EL1:
+#endif
+ case INTR_TYPE_NS:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+void plat_ic_set_interrupt_type(unsigned int id, unsigned int type)
+{
+ int gicv2_type = 0;
+
+ /* Map canonical interrupt type to GICv2 type */
+ switch (type) {
+#if GICV2_G0_FOR_EL3
+ case INTR_TYPE_EL3:
+#else
+ case INTR_TYPE_S_EL1:
+#endif
+ gicv2_type = GICV2_INTR_GROUP0;
+ break;
+ case INTR_TYPE_NS:
+ gicv2_type = GICV2_INTR_GROUP1;
+ break;
+ default:
+ assert(0);
+ }
+
+ gicv2_set_interrupt_type(id, gicv2_type);
+}