GIC: Add API to get interrupt active status

API documentation updated.

Change-Id: I6d61785af0d5330930c709de971a904dc7c3516c
Co-authored-by: Yousuf A <yousuf.sait@arm.com>
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
This commit is contained in:
Jeenu Viswambharan 2017-09-22 08:32:09 +01:00
parent ca43b55d22
commit cbd3f3706d
12 changed files with 95 additions and 3 deletions

View File

@ -66,6 +66,21 @@ as a Software Generated Interrupt. Software Generated Interrupts are raised by
explicit programming by software, and are typically used in inter-PE
communication. Secure SGIs are reserved for use by Secure world software.
Function: unsigned int plat_ic_get_interrupt_active(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
Argument : unsigned int
Return : int
This API should return the *active* status of the interrupt ID specified by the
first parameter, ``id``.
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.
----
*Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -273,6 +273,14 @@ void gicd_set_icpendr(uintptr_t base, unsigned int id)
gicd_write_icpendr(base, id, (1 << bit_num));
}
unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
{
unsigned int bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
unsigned int reg_val = gicd_read_isactiver(base, id);
return (reg_val >> bit_num) & 0x1;
}
void gicd_set_isactiver(uintptr_t base, unsigned int id)
{
unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -73,6 +73,7 @@ void gicd_set_isenabler(uintptr_t base, unsigned int id);
void gicd_set_icenabler(uintptr_t base, unsigned int id);
void gicd_set_ispendr(uintptr_t base, unsigned int id);
void gicd_set_icpendr(uintptr_t base, unsigned int id);
unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id);
void gicd_set_isactiver(uintptr_t base, unsigned int id);
void gicd_set_icactiver(uintptr_t base, unsigned int id);
void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri);

View File

@ -275,3 +275,16 @@ void gicv2_set_pe_target_mask(unsigned int proc_num)
driver_data->target_masks[proc_num] =
gicv2_get_cpuif_id(driver_data->gicd_base);
}
/*******************************************************************************
* This function returns the active status of the interrupt (either because the
* state is active, or active and pending).
******************************************************************************/
unsigned int gicv2_get_interrupt_active(unsigned int id)
{
assert(driver_data);
assert(driver_data->gicd_base);
assert(id <= MAX_SPI_ID);
return gicd_get_isactiver(driver_data->gicd_base, id);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -171,6 +171,18 @@ 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
* ISACTIVER0.
*/
unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
{
unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
unsigned int reg_val = gicr_read_isactiver0(base);
return (reg_val >> bit_num) & 0x1;
}
/*
* Accessor to set the byte corresponding to interrupt ID
* in GIC Re-distributor IPRIORITYR.

View File

@ -778,3 +778,30 @@ unsigned int gicv3_get_running_priority(void)
{
return read_icc_rpr_el1();
}
/*******************************************************************************
* This function checks if the interrupt identified by id is active (whether the
* state is either active, or active and pending). The proc_num is used if the
* interrupt is SGI or PPI and programs the corresponding Redistributor
* interface.
******************************************************************************/
unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
{
unsigned int value;
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);
if (id < MIN_SPI_ID) {
/* For SGIs and PPIs */
value = gicr_get_isactiver0(
gicv3_driver_data->rdistif_base_addrs[proc_num], id);
} else {
value = gicd_get_isactiver(gicv3_driver_data->gicd_base, id);
}
return value;
}

View File

@ -67,6 +67,7 @@ void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val);
unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id);
unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id);
unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id);
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);

View File

@ -147,6 +147,7 @@ void gicv2_end_of_interrupt(unsigned int id);
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);
#endif /* __ASSEMBLY__ */
#endif /* __GICV2_H__ */

View File

@ -350,6 +350,7 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx
void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx);
unsigned int gicv3_get_running_priority(void);
unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num);
#endif /* __ASSEMBLY__ */
#endif /* __GICV3_H__ */

View File

@ -76,6 +76,7 @@ unsigned int plat_ic_get_running_priority(void);
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);
/*******************************************************************************
* Optional common functions (may be overridden)

View File

@ -24,6 +24,7 @@
#pragma weak plat_ic_is_spi
#pragma weak plat_ic_is_ppi
#pragma weak plat_ic_is_sgi
#pragma weak plat_ic_get_interrupt_active
/*
* This function returns the highest priority pending interrupt at
@ -147,3 +148,8 @@ int plat_ic_is_sgi(unsigned int id)
{
return (id >= MIN_SGI_ID) && (id < MIN_PPI_ID);
}
unsigned int plat_ic_get_interrupt_active(unsigned int id)
{
return gicv2_get_interrupt_active(id);
}

View File

@ -30,6 +30,7 @@
#pragma weak plat_ic_is_spi
#pragma weak plat_ic_is_ppi
#pragma weak plat_ic_is_sgi
#pragma weak plat_ic_get_interrupt_active
CASSERT((INTR_TYPE_S_EL1 == INTR_GROUP1S) &&
(INTR_TYPE_NS == INTR_GROUP1NS) &&
@ -180,6 +181,11 @@ int plat_ic_is_sgi(unsigned int id)
{
return (id >= MIN_SGI_ID) && (id < MIN_PPI_ID);
}
unsigned int plat_ic_get_interrupt_active(unsigned int id)
{
return gicv3_get_interrupt_active(id, plat_my_core_pos());
}
#endif
#ifdef IMAGE_BL32