mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-25 14:25:44 +00:00
GIC: Add APIs to enable and disable interrupt
API documentation updated. Change-Id: Ice7511f8df5356851001d2f7dc2a46cfe318f9ba Co-authored-by: Yousuf A <yousuf.sait@arm.com> Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
This commit is contained in:
parent
cbd3f3706d
commit
979225f4ee
10 changed files with 170 additions and 0 deletions
docs
drivers/arm/gic
include
plat/common
|
@ -81,6 +81,36 @@ In case of ARM standard platforms using GIC, the implementation of the API reads
|
|||
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.*
|
||||
|
|
|
@ -288,3 +288,37 @@ unsigned int gicv2_get_interrupt_active(unsigned int id)
|
|||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -171,6 +171,17 @@ void gicr_set_isenabler0(uintptr_t base, unsigned int id)
|
|||
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.
|
||||
|
|
|
@ -805,3 +805,67 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
|
|||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id);
|
|||
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);
|
||||
|
|
|
@ -148,6 +148,8 @@ unsigned int gicv2_get_interrupt_group(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__ */
|
||||
|
|
|
@ -351,6 +351,8 @@ void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ct
|
|||
|
||||
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__ */
|
||||
|
|
|
@ -77,6 +77,8 @@ int plat_ic_is_spi(unsigned int id);
|
|||
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)
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#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
|
||||
|
@ -153,3 +155,13 @@ unsigned int plat_ic_get_interrupt_active(unsigned int id)
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#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) &&
|
||||
|
@ -186,6 +188,16 @@ unsigned int plat_ic_get_interrupt_active(unsigned int id)
|
|||
{
|
||||
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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue