aboutsummaryrefslogtreecommitdiff
path: root/plat
diff options
context:
space:
mode:
authorSandrine Bailleux <sandrine.bailleux@arm.com>2014-05-27 11:50:07 +0100
committerSandrine Bailleux <sandrine.bailleux@arm.com>2014-06-05 17:39:40 +0100
commitd20903486d0a2cab8dea38df9325a8b81293e6c1 (patch)
tree2bc2cf234c70654f1ccd782a85111b952db5522b /plat
parent60663435525ccf1966f9a9122e1680ec8c736d2a (diff)
juno: Implement functions to access an ARM GIC
Change-Id: I8be0cc5e2495864463c310f2d2d64740495e3bb4
Diffstat (limited to 'plat')
-rw-r--r--plat/juno/plat_gic.c84
-rw-r--r--plat/juno/platform.h9
2 files changed, 91 insertions, 2 deletions
diff --git a/plat/juno/plat_gic.c b/plat/juno/plat_gic.c
index 0afa22d..7758b76 100644
--- a/plat/juno/plat_gic.c
+++ b/plat/juno/plat_gic.c
@@ -29,7 +29,10 @@
*/
#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
#include <gic_v2.h>
+#include <interrupt_mgmt.h>
#include <platform.h>
@@ -195,3 +198,84 @@ uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
*/
return gicv2_interrupt_type_to_line(GICC_BASE, type);
}
+
+/*******************************************************************************
+ * This function returns the type of the highest priority pending interrupt at
+ * the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no
+ * interrupt pending.
+ ******************************************************************************/
+uint32_t ic_get_pending_interrupt_type(void)
+{
+ uint32_t id;
+
+ id = gicc_read_hppir(GICC_BASE);
+
+ /* Assume that all secure interrupts are S-EL1 interrupts */
+ if (id < 1022)
+ return INTR_TYPE_S_EL1;
+
+ if (id == GIC_SPURIOUS_INTERRUPT)
+ return INTR_TYPE_INVAL;
+
+ return INTR_TYPE_NS;
+}
+
+/*******************************************************************************
+ * This function returns the id of the highest priority pending interrupt at
+ * the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no
+ * interrupt pending.
+ ******************************************************************************/
+uint32_t ic_get_pending_interrupt_id(void)
+{
+ uint32_t id;
+
+ id = gicc_read_hppir(GICC_BASE);
+
+ if (id < 1022)
+ return id;
+
+ if (id == 1023)
+ return INTR_ID_UNAVAILABLE;
+
+ /*
+ * Find out which non-secure interrupt it is under the assumption that
+ * the GICC_CTLR.AckCtl bit is 0.
+ */
+ return gicc_read_ahppir(GICC_BASE);
+}
+
+/*******************************************************************************
+ * This functions reads the GIC cpu interface Interrupt Acknowledge register
+ * to start handling the pending interrupt. It returns the contents of the IAR.
+ ******************************************************************************/
+uint32_t ic_acknowledge_interrupt(void)
+{
+ return gicc_read_IAR(GICC_BASE);
+}
+
+/*******************************************************************************
+ * This functions writes the GIC cpu interface End Of Interrupt register with
+ * the passed value to finish handling the active interrupt
+ ******************************************************************************/
+void ic_end_of_interrupt(uint32_t id)
+{
+ gicc_write_EOIR(GICC_BASE, id);
+}
+
+/*******************************************************************************
+ * This function returns the type of the interrupt id depending upon the group
+ * this interrupt has been configured under by the interrupt controller i.e.
+ * group0 or group1.
+ ******************************************************************************/
+uint32_t ic_get_interrupt_type(uint32_t id)
+{
+ uint32_t group;
+
+ group = gicd_get_igroupr(GICD_BASE, id);
+
+ /* Assume that all secure interrupts are S-EL1 interrupts */
+ if (group == GRP0)
+ return INTR_TYPE_S_EL1;
+ else
+ return INTR_TYPE_NS;
+}
diff --git a/plat/juno/platform.h b/plat/juno/platform.h
index 7eb7595..97505de 100644
--- a/plat/juno/platform.h
+++ b/plat/juno/platform.h
@@ -383,7 +383,12 @@ extern unsigned long plat_get_ns_image_entrypoint(void);
extern unsigned long platform_get_stack(unsigned long mpidr);
extern uint64_t plat_get_syscnt_freq(void);
-/* Declarations for fvp_gic.c */
+/* Declarations for plat_gic.c */
+extern uint32_t ic_get_pending_interrupt_id(void);
+extern uint32_t ic_get_pending_interrupt_type(void);
+extern uint32_t ic_acknowledge_interrupt(void);
+extern uint32_t ic_get_interrupt_type(uint32_t id);
+extern void ic_end_of_interrupt(uint32_t id);
extern void gic_cpuif_deactivate(unsigned int);
extern void gic_cpuif_setup(unsigned int);
extern void gic_pcpu_distif_setup(unsigned int);
@@ -391,7 +396,7 @@ extern void gic_setup(void);
extern uint32_t plat_interrupt_type_to_line(uint32_t type,
uint32_t security_state);
-/* Declarations for fvp_topology.c */
+/* Declarations for plat_topology.c */
extern int plat_setup_topology(void);
extern int plat_get_max_afflvl(void);
extern unsigned int plat_get_aff_count(unsigned int, unsigned long);