summaryrefslogtreecommitdiff
path: root/plat/common/plat_gicv2.c
diff options
context:
space:
mode:
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 d50138ed..c785d831 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);
+}