summaryrefslogtreecommitdiff
path: root/drivers/arm/gic
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2018-03-22 08:57:52 +0000
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>2018-03-26 09:45:48 +0100
commit17e84eedb2fb40d8682802cf2e23ddf67928c51d (patch)
treea91ef44ab2642507d6ffe1d39fd4fb5a2a1dd2cb /drivers/arm/gic
parentf13ef37a38cec17f72f08dc63bbbe546a54d78a7 (diff)
GIC: Fix setting interrupt configuration
- Interrupt configuration is a 2-bit field, so the field shift has to be double that of the bit number. - Interrupt configuration (level- or edge-trigger) is specified in the MSB of the field, not LSB. Fixes applied to both GICv2 and GICv3 drivers. Fixes ARM-software/tf-issues#570 Change-Id: Ia6ae6ed9ba9fb0e3eb0f921a833af48e365ba359 Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'drivers/arm/gic')
-rw-r--r--drivers/arm/gic/common/gic_common.c11
-rw-r--r--drivers/arm/gic/v3/gicv3_helpers.c20
2 files changed, 20 insertions, 11 deletions
diff --git a/drivers/arm/gic/common/gic_common.c b/drivers/arm/gic/common/gic_common.c
index d523772b..07ed63d7 100644
--- a/drivers/arm/gic/common/gic_common.c
+++ b/drivers/arm/gic/common/gic_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -302,12 +302,15 @@ void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
{
- unsigned bit_num = id & ((1 << ICFGR_SHIFT) - 1);
+ /* Interrupt configuration is a 2-bit field */
+ unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1);
+ unsigned int bit_shift = bit_num << 1;
+
uint32_t reg_val = gicd_read_icfgr(base, id);
/* Clear the field, and insert required configuration */
- reg_val &= ~(GIC_CFG_MASK << bit_num);
- reg_val |= ((cfg & GIC_CFG_MASK) << bit_num);
+ reg_val &= ~(GIC_CFG_MASK << bit_shift);
+ reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
gicd_write_icfgr(base, id, reg_val);
}
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index dee63f18..69c69512 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -232,12 +232,15 @@ void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
*/
void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
{
- unsigned bit_num = id & ((1 << ICFGR_SHIFT) - 1);
+ /* Interrupt configuration is a 2-bit field */
+ unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1);
+ unsigned int bit_shift = bit_num << 1;
+
uint32_t reg_val = gicr_read_icfgr0(base);
/* Clear the field, and insert required configuration */
- reg_val &= ~(GIC_CFG_MASK << bit_num);
- reg_val |= ((cfg & GIC_CFG_MASK) << bit_num);
+ reg_val &= ~(GIC_CFG_MASK << bit_shift);
+ reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
gicr_write_icfgr0(base, reg_val);
}
@@ -248,12 +251,15 @@ void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
*/
void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg)
{
- unsigned bit_num = id & ((1 << ICFGR_SHIFT) - 1);
+ /* Interrupt configuration is a 2-bit field */
+ unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1);
+ unsigned int bit_shift = bit_num << 1;
+
uint32_t reg_val = gicr_read_icfgr1(base);
/* Clear the field, and insert required configuration */
- reg_val &= ~(GIC_CFG_MASK << bit_num);
- reg_val |= ((cfg & GIC_CFG_MASK) << bit_num);
+ reg_val &= ~(GIC_CFG_MASK << bit_shift);
+ reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
gicr_write_icfgr1(base, reg_val);
}