API documentation updated.
Change-Id: Ice7511f8df5356851001d2f7dc2a46cfe318f9ba
Co-authored-by: Yousuf A <yousuf.sait@arm.com>
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
the GIC *Set Active Register* to read and return the active status of the
interrupt.
+Function: void plat_ic_enable_interrupt(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : void
+
+This API should enable the interrupt ID specified by the first parameter,
+``id``. PEs in the system are expected to receive only enabled interrupts.
+
+In case of ARM standard platforms using GIC, the implementation of the API
+inserts barrier to make memory updates visible before enabling interrupt, and
+then writes to GIC *Set Enable Register* to enable the interrupt.
+
+Function: void plat_ic_disable_interrupt(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : void
+
+This API should disable the interrupt ID specified by the first parameter,
+``id``. PEs in the system are not expected to receive disabled interrupts.
+
+In case of ARM standard platforms using GIC, the implementation of the API
+writes to GIC *Clear Enable Register* to disable the interrupt, and inserts
+barrier to make memory updates visible afterwards.
+
----
*Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.*
return gicd_get_isactiver(driver_data->gicd_base, id);
}
+
+/*******************************************************************************
+ * This function enables the interrupt identified by id.
+ ******************************************************************************/
+void gicv2_enable_interrupt(unsigned int id)
+{
+ assert(driver_data);
+ assert(driver_data->gicd_base);
+ assert(id <= MAX_SPI_ID);
+
+ /*
+ * Ensure that any shared variable updates depending on out of band
+ * interrupt trigger are observed before enabling interrupt.
+ */
+ dsbishst();
+ gicd_set_isenabler(driver_data->gicd_base, id);
+}
+
+/*******************************************************************************
+ * This function disables the interrupt identified by id.
+ ******************************************************************************/
+void gicv2_disable_interrupt(unsigned int id)
+{
+ assert(driver_data);
+ assert(driver_data->gicd_base);
+ assert(id <= MAX_SPI_ID);
+
+ /*
+ * Disable interrupt, and ensure that any shared variable updates
+ * depending on out of band interrupt trigger are observed afterwards.
+ */
+ gicd_set_icenabler(driver_data->gicd_base, id);
+ dsbishst();
+}
gicr_write_isenabler0(base, (1 << bit_num));
}
+/*
+ * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
+ * ICENABLER0.
+ */
+void gicr_set_icenabler0(uintptr_t base, unsigned int id)
+{
+ unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1);
+
+ gicr_write_icenabler0(base, (1 << bit_num));
+}
+
/*
* Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
* ISACTIVER0.
return value;
}
+
+/*******************************************************************************
+ * This function enables the interrupt identified by id. The proc_num
+ * is used if the interrupt is SGI or PPI, and programs the corresponding
+ * Redistributor interface.
+ ******************************************************************************/
+void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
+{
+ assert(gicv3_driver_data);
+ assert(gicv3_driver_data->gicd_base);
+ assert(proc_num < gicv3_driver_data->rdistif_num);
+ assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(id <= MAX_SPI_ID);
+
+ /*
+ * Ensure that any shared variable updates depending on out of band
+ * interrupt trigger are observed before enabling interrupt.
+ */
+ dsbishst();
+ if (id < MIN_SPI_ID) {
+ /* For SGIs and PPIs */
+ gicr_set_isenabler0(
+ gicv3_driver_data->rdistif_base_addrs[proc_num],
+ id);
+ } else {
+ gicd_set_isenabler(gicv3_driver_data->gicd_base, id);
+ }
+}
+
+/*******************************************************************************
+ * This function disables the interrupt identified by id. The proc_num
+ * is used if the interrupt is SGI or PPI, and programs the corresponding
+ * Redistributor interface.
+ ******************************************************************************/
+void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num)
+{
+ assert(gicv3_driver_data);
+ assert(gicv3_driver_data->gicd_base);
+ assert(proc_num < gicv3_driver_data->rdistif_num);
+ assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(id <= MAX_SPI_ID);
+
+ /*
+ * Disable interrupt, and ensure that any shared variable updates
+ * depending on out of band interrupt trigger are observed afterwards.
+ */
+ if (id < MIN_SPI_ID) {
+ /* For SGIs and PPIs */
+ gicr_set_icenabler0(
+ gicv3_driver_data->rdistif_base_addrs[proc_num],
+ id);
+
+ /* Write to clear enable requires waiting for pending writes */
+ gicr_wait_for_pending_write(
+ gicv3_driver_data->rdistif_base_addrs[proc_num]);
+ } else {
+ gicd_set_icenabler(gicv3_driver_data->gicd_base, id);
+
+ /* Write to clear enable requires waiting for pending writes */
+ gicd_wait_for_pending_write(gicv3_driver_data->gicd_base);
+ }
+
+ dsbishst();
+}
void gicd_set_igrpmodr(uintptr_t base, unsigned int id);
void gicr_set_igrpmodr0(uintptr_t base, unsigned int id);
void gicr_set_isenabler0(uintptr_t base, unsigned int id);
+void gicr_set_icenabler0(uintptr_t base, unsigned int id);
void gicr_set_igroupr0(uintptr_t base, unsigned int id);
void gicd_clr_igrpmodr(uintptr_t base, unsigned int id);
void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id);
unsigned int gicv2_get_running_priority(void);
void gicv2_set_pe_target_mask(unsigned int proc_num);
unsigned int gicv2_get_interrupt_active(unsigned int id);
+void gicv2_enable_interrupt(unsigned int id);
+void gicv2_disable_interrupt(unsigned int id);
#endif /* __ASSEMBLY__ */
#endif /* __GICV2_H__ */
unsigned int gicv3_get_running_priority(void);
unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num);
+void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num);
+void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num);
#endif /* __ASSEMBLY__ */
#endif /* __GICV3_H__ */
int plat_ic_is_ppi(unsigned int id);
int plat_ic_is_sgi(unsigned int id);
unsigned int plat_ic_get_interrupt_active(unsigned int id);
+void plat_ic_disable_interrupt(unsigned int id);
+void plat_ic_enable_interrupt(unsigned int id);
/*******************************************************************************
* Optional common functions (may be overridden)
#pragma weak plat_ic_is_ppi
#pragma weak plat_ic_is_sgi
#pragma weak plat_ic_get_interrupt_active
+#pragma weak plat_ic_enable_interrupt
+#pragma weak plat_ic_disable_interrupt
/*
* This function returns the highest priority pending interrupt at
{
return gicv2_get_interrupt_active(id);
}
+
+void plat_ic_enable_interrupt(unsigned int id)
+{
+ gicv2_enable_interrupt(id);
+}
+
+void plat_ic_disable_interrupt(unsigned int id)
+{
+ gicv2_disable_interrupt(id);
+}
#pragma weak plat_ic_is_ppi
#pragma weak plat_ic_is_sgi
#pragma weak plat_ic_get_interrupt_active
+#pragma weak plat_ic_enable_interrupt
+#pragma weak plat_ic_disable_interrupt
CASSERT((INTR_TYPE_S_EL1 == INTR_GROUP1S) &&
(INTR_TYPE_NS == INTR_GROUP1NS) &&
{
return gicv3_get_interrupt_active(id, plat_my_core_pos());
}
+
+void plat_ic_enable_interrupt(unsigned int id)
+{
+ gicv3_enable_interrupt(id, plat_my_core_pos());
+}
+
+void plat_ic_disable_interrupt(unsigned int id)
+{
+ gicv3_disable_interrupt(id, plat_my_core_pos());
+}
#endif
#ifdef IMAGE_BL32