diff options
author | Sandrine Bailleux <sandrine.bailleux@arm.com> | 2014-05-27 11:50:07 +0100 |
---|---|---|
committer | Sandrine Bailleux <sandrine.bailleux@arm.com> | 2014-06-05 17:39:40 +0100 |
commit | d20903486d0a2cab8dea38df9325a8b81293e6c1 (patch) | |
tree | 2bc2cf234c70654f1ccd782a85111b952db5522b /plat | |
parent | 60663435525ccf1966f9a9122e1680ec8c736d2a (diff) |
juno: Implement functions to access an ARM GIC
Change-Id: I8be0cc5e2495864463c310f2d2d64740495e3bb4
Diffstat (limited to 'plat')
-rw-r--r-- | plat/juno/plat_gic.c | 84 | ||||
-rw-r--r-- | plat/juno/platform.h | 9 |
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); |