From f3a866004ea8f9a0cd5420f3dd4d4683f638e6da Mon Sep 17 00:00:00 2001 From: Jeenu Viswambharan Date: Fri, 22 Sep 2017 08:32:09 +0100 Subject: [PATCH] GIC: Add API to set interrupt priority API documentation updated. Change-Id: Ib700eb1b8ca65503aeed0ac4ce0e7b934df67ff9 Co-authored-by: Yousuf A Signed-off-by: Jeenu Viswambharan --- docs/platform-interrupt-controller-API.rst | 15 ++++++++++++++ drivers/arm/gic/v2/gicv2_main.c | 13 ++++++++++++ drivers/arm/gic/v3/gicv3_main.c | 23 ++++++++++++++++++++++ include/drivers/arm/gicv2.h | 1 + include/drivers/arm/gicv3.h | 2 ++ include/plat/common/platform.h | 1 + plat/common/plat_gicv2.c | 6 ++++++ plat/common/plat_gicv3.c | 6 ++++++ 8 files changed, 67 insertions(+) diff --git a/docs/platform-interrupt-controller-API.rst b/docs/platform-interrupt-controller-API.rst index bea1a64b5..3161c20a2 100644 --- a/docs/platform-interrupt-controller-API.rst +++ b/docs/platform-interrupt-controller-API.rst @@ -111,6 +111,21 @@ 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. +Function: void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority); [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int + Argument : unsigned int + Return : void + +This API should set the priority of the interrupt specified by first parameter +``id`` to the value set by the second parameter ``priority``. + +In case of ARM standard platforms using GIC, the implementation of the API +writes to GIC *Priority Register* set interrupt priority. + ---- *Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.* diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index e0058ad13..4861e02df 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -322,3 +322,16 @@ void gicv2_disable_interrupt(unsigned int id) gicd_set_icenabler(driver_data->gicd_base, id); dsbishst(); } + +/******************************************************************************* + * This function sets the interrupt priority as supplied for the given interrupt + * id. + ******************************************************************************/ +void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority) +{ + assert(driver_data); + assert(driver_data->gicd_base); + assert(id <= MAX_SPI_ID); + + gicd_set_ipriorityr(driver_data->gicd_base, id, priority); +} diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index b3231993e..d0ecab615 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -869,3 +869,26 @@ void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num) dsbishst(); } + +/******************************************************************************* + * This function sets the interrupt priority as supplied for the given interrupt + * id. + ******************************************************************************/ +void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num, + unsigned int priority) +{ + uintptr_t gicr_base; + + 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) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + gicr_set_ipriorityr(gicr_base, id, priority); + } else { + gicd_set_ipriorityr(gicv3_driver_data->gicd_base, id, priority); + } +} diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h index 0af1a25e2..91674fd36 100644 --- a/include/drivers/arm/gicv2.h +++ b/include/drivers/arm/gicv2.h @@ -150,6 +150,7 @@ 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); +void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority); #endif /* __ASSEMBLY__ */ #endif /* __GICV2_H__ */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index 6e6a47b97..f753ca265 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -353,6 +353,8 @@ 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); +void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num, + unsigned int priority); #endif /* __ASSEMBLY__ */ #endif /* __GICV3_H__ */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 671aa61e8..03f529cb0 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -79,6 +79,7 @@ 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); +void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority); /******************************************************************************* * Optional common functions (may be overridden) diff --git a/plat/common/plat_gicv2.c b/plat/common/plat_gicv2.c index 2591805de..d50138edf 100644 --- a/plat/common/plat_gicv2.c +++ b/plat/common/plat_gicv2.c @@ -27,6 +27,7 @@ #pragma weak plat_ic_get_interrupt_active #pragma weak plat_ic_enable_interrupt #pragma weak plat_ic_disable_interrupt +#pragma weak plat_ic_set_interrupt_priority /* * This function returns the highest priority pending interrupt at @@ -165,3 +166,8 @@ void plat_ic_disable_interrupt(unsigned int id) { gicv2_disable_interrupt(id); } + +void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority) +{ + gicv2_set_interrupt_priority(id, priority); +} diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c index 2a1f0f5c5..230d90ca9 100644 --- a/plat/common/plat_gicv3.c +++ b/plat/common/plat_gicv3.c @@ -33,6 +33,7 @@ #pragma weak plat_ic_get_interrupt_active #pragma weak plat_ic_enable_interrupt #pragma weak plat_ic_disable_interrupt +#pragma weak plat_ic_set_interrupt_priority CASSERT((INTR_TYPE_S_EL1 == INTR_GROUP1S) && (INTR_TYPE_NS == INTR_GROUP1NS) && @@ -198,6 +199,11 @@ void plat_ic_disable_interrupt(unsigned int id) { gicv3_disable_interrupt(id, plat_my_core_pos()); } + +void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority) +{ + gicv3_set_interrupt_priority(id, plat_my_core_pos(), priority); +} #endif #ifdef IMAGE_BL32