From eb68ea9b10c190c237216dee92166f9e7b2ce3d4 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 running priority Document the API in separate platform interrupt controller API document. Change-Id: If18f208e10a8a243f5c59d226fcf48e985941949 Co-authored-by: Yousuf A Signed-off-by: Jeenu Viswambharan --- docs/platform-interrupt-controller-API.rst | 32 ++++++++++++++++++++++++++++++ docs/porting-guide.rst | 6 +++++- drivers/arm/gic/v2/gicv2_main.c | 12 +++++++++++ drivers/arm/gic/v2/gicv2_private.h | 7 ++++++- drivers/arm/gic/v3/gicv3_main.c | 9 +++++++++ include/drivers/arm/gicv2.h | 3 ++- include/drivers/arm/gicv3.h | 2 ++ include/lib/aarch32/arch_helpers.h | 1 + include/lib/aarch64/arch.h | 1 + include/lib/aarch64/arch_helpers.h | 1 + include/plat/common/platform.h | 5 +++++ plat/common/plat_gicv2.c | 9 ++++++++- plat/common/plat_gicv3.c | 10 +++++++++- 13 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 docs/platform-interrupt-controller-API.rst diff --git a/docs/platform-interrupt-controller-API.rst b/docs/platform-interrupt-controller-API.rst new file mode 100644 index 00000000..9ef2e3f6 --- /dev/null +++ b/docs/platform-interrupt-controller-API.rst @@ -0,0 +1,32 @@ +Platform Interrupt Controller API documentation +=============================================== + +.. section-numbering:: + :suffix: . + +.. contents:: + +This document lists the optional platform interrupt controller API that +abstracts the runtime configuration and control of interrupt controller from the +generic code. The mandatory APIs are described in the `porting guide`__. + +.. __: porting-guide.rst#interrupt-management-framework-in-bl31 + +Function: unsigned int plat_ic_get_running_priority(void); [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : unsigned int + +This API should return the priority of the interrupt the PE is currently +servicing. This must be be called only after an interrupt has already been +acknowledged via. ``plat_ic_acknowledge_interrupt``. + +In the case of ARM standard platforms using GIC, the *Running Priority Register* +is read to determine the priority of the interrupt. + +---- + +*Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.* diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst index 6c07b2eb..c0b173c6 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -2289,6 +2289,10 @@ Standard layer to use GICv2 and the FVP can be configured to use either GICv2 or GICv3 depending on the build flag ``FVP_USE_GIC_DRIVER`` (See FVP platform specific build options in `User Guide`_ for more details). +See also: `Interrupt Controller Abstraction APIs`__. + +.. __: platform-interrupt-controller-API.rst + Function : plat\_interrupt\_type\_to\_line() [mandatory] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2636,7 +2640,7 @@ amount of open resources per driver. -------------- -*Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.* .. _Migration Guide: platform-migration-guide.rst .. _include/plat/common/platform.h: ../include/plat/common/platform.h diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index deac927c..7759a551 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -240,3 +240,15 @@ unsigned int gicv2_get_interrupt_group(unsigned int id) return gicd_get_igroupr(driver_data->gicd_base, id); } + +/******************************************************************************* + * This function returns the priority of the interrupt the processor is + * currently servicing. + ******************************************************************************/ +unsigned int gicv2_get_running_priority(void) +{ + assert(driver_data); + assert(driver_data->gicc_base); + + return gicc_read_rpr(driver_data->gicc_base); +} diff --git a/drivers/arm/gic/v2/gicv2_private.h b/drivers/arm/gic/v2/gicv2_private.h index 91ab43a2..7703cbe5 100644 --- a/drivers/arm/gic/v2/gicv2_private.h +++ b/drivers/arm/gic/v2/gicv2_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -80,6 +80,11 @@ static inline unsigned int gicc_read_iidr(uintptr_t base) return mmio_read_32(base + GICC_IIDR); } +static inline unsigned int gicc_read_rpr(uintptr_t base) +{ + return mmio_read_32(base + GICC_RPR); +} + /******************************************************************************* * GIC CPU interface accessors for writing entire registers ******************************************************************************/ diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 1a018d80..7e757430 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -769,3 +769,12 @@ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) gicd_wait_for_pending_write(gicd_base); } + +/******************************************************************************* + * This function gets the priority of the interrupt the processor is currently + * servicing. + ******************************************************************************/ +unsigned int gicv3_get_running_priority(void) +{ + return read_icc_rpr_el1(); +} diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h index a7880254..1ef0779b 100644 --- a/include/drivers/arm/gicv2.h +++ b/include/drivers/arm/gicv2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -136,6 +136,7 @@ unsigned int gicv2_get_pending_interrupt_id(void); unsigned int gicv2_acknowledge_interrupt(void); void gicv2_end_of_interrupt(unsigned int id); unsigned int gicv2_get_interrupt_group(unsigned int id); +unsigned int gicv2_get_running_priority(void); #endif /* __ASSEMBLY__ */ #endif /* __GICV2_H__ */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index c52fe483..4548a87c 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -349,5 +349,7 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ 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); + #endif /* __ASSEMBLY__ */ #endif /* __GICV3_H__ */ diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h index 5d318360..1f4f2162 100644 --- a/include/lib/aarch32/arch_helpers.h +++ b/include/lib/aarch32/arch_helpers.h @@ -257,6 +257,7 @@ DEFINE_COPROCR_RW_FUNCS(icc_sre_el1, ICC_SRE) DEFINE_COPROCR_RW_FUNCS(icc_sre_el2, ICC_HSRE) DEFINE_COPROCR_RW_FUNCS(icc_sre_el3, ICC_MSRE) DEFINE_COPROCR_RW_FUNCS(icc_pmr_el1, ICC_PMR) +DEFINE_COPROCR_RW_FUNCS(icc_rpr_el1, ICC_RPR) DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el3, ICC_MGRPEN1) DEFINE_COPROCR_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0) DEFINE_COPROCR_RW_FUNCS(icc_hppir0_el1, ICC_HPPIR0) diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index f85e7897..3fb6846c 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -68,6 +68,7 @@ #define ICC_CTLR_EL1 S3_0_C12_C12_4 #define ICC_CTLR_EL3 S3_6_C12_C12_4 #define ICC_PMR_EL1 S3_0_C4_C6_0 +#define ICC_RPR_EL1 S3_0_C12_C11_3 #define ICC_IGRPEN1_EL3 S3_6_c12_c12_7 #define ICC_IGRPEN0_EL1 S3_0_c12_c12_6 #define ICC_HPPIR0_EL1 S3_0_c12_c8_2 diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 0d0d7d33..dbbbaeb0 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -313,6 +313,7 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1) +DEFINE_RENAME_SYSREG_READ_FUNC(icc_rpr_el1, ICC_RPR_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el3, ICC_IGRPEN1_EL3) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir0_el1, ICC_HPPIR0_EL1) diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index e189f648..7468352d 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -69,6 +69,11 @@ void plat_ic_end_of_interrupt(uint32_t id); uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state); +/******************************************************************************* + * Optional interrupt management functions, depending on chosen EL3 components. + ******************************************************************************/ +unsigned int plat_ic_get_running_priority(void); + /******************************************************************************* * Optional common functions (may be overridden) ******************************************************************************/ diff --git a/plat/common/plat_gicv2.c b/plat/common/plat_gicv2.c index 50a81818..1be693bb 100644 --- a/plat/common/plat_gicv2.c +++ b/plat/common/plat_gicv2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,6 +20,8 @@ #pragma weak plat_ic_end_of_interrupt #pragma weak plat_interrupt_type_to_line +#pragma weak plat_ic_get_running_priority + /* * This function returns the highest priority pending interrupt at * the Interrupt controller @@ -122,3 +124,8 @@ uint32_t plat_interrupt_type_to_line(uint32_t type, return ((gicv2_is_fiq_enabled()) ? __builtin_ctz(SCR_FIQ_BIT) : __builtin_ctz(SCR_IRQ_BIT)); } + +unsigned int plat_ic_get_running_priority(void) +{ + return gicv2_get_running_priority(); +} diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c index 030a1d90..02317f1d 100644 --- a/plat/common/plat_gicv3.c +++ b/plat/common/plat_gicv3.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 */ @@ -26,6 +26,8 @@ #pragma weak plat_ic_end_of_interrupt #pragma weak plat_interrupt_type_to_line +#pragma weak plat_ic_get_running_priority + CASSERT((INTR_TYPE_S_EL1 == INTR_GROUP1S) && (INTR_TYPE_NS == INTR_GROUP1NS) && (INTR_TYPE_EL3 == INTR_GROUP0), assert_interrupt_type_mismatch); @@ -155,6 +157,12 @@ uint32_t plat_interrupt_type_to_line(uint32_t type, return __builtin_ctz(SCR_FIQ_BIT); } } + +unsigned int plat_ic_get_running_priority(void) +{ + return gicv3_get_running_priority(); +} + #endif #ifdef IMAGE_BL32 -- cgit v1.2.3