From cbd3f3706d4217ee3669deeb52b158e84eb97f56 Mon Sep 17 00:00:00 2001 From: Jeenu Viswambharan Date: Fri, 22 Sep 2017 08:32:09 +0100 Subject: GIC: Add API to get interrupt active status API documentation updated. Change-Id: I6d61785af0d5330930c709de971a904dc7c3516c Co-authored-by: Yousuf A Signed-off-by: Jeenu Viswambharan --- drivers/arm/gic/common/gic_common.c | 10 +++++++++- drivers/arm/gic/common/gic_common_private.h | 3 ++- drivers/arm/gic/v2/gicv2_main.c | 13 +++++++++++++ drivers/arm/gic/v3/gicv3_helpers.c | 14 +++++++++++++- drivers/arm/gic/v3/gicv3_main.c | 27 +++++++++++++++++++++++++++ drivers/arm/gic/v3/gicv3_private.h | 1 + 6 files changed, 65 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/arm/gic/common/gic_common.c b/drivers/arm/gic/common/gic_common.c index 6535813f..71155a97 100644 --- a/drivers/arm/gic/common/gic_common.c +++ b/drivers/arm/gic/common/gic_common.c @@ -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); diff --git a/drivers/arm/gic/common/gic_common_private.h b/drivers/arm/gic/common/gic_common_private.h index 2077cc46..8b96b37b 100644 --- a/drivers/arm/gic/common/gic_common_private.h +++ b/drivers/arm/gic/common/gic_common_private.h @@ -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); diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index 28266807..e33353a8 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -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); +} diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 73ad060f..81d50ad4 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -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. diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 7e757430..08cf0957 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -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; +} diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index 59298edf..bb8ad9ae 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -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); -- cgit v1.2.3