Commit 17e84eed authored by Jeenu Viswambharan's avatar Jeenu Viswambharan
Browse files

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: default avatarJeenu Viswambharan <jeenu.viswambharan@arm.com>
parent f13ef37a
/* /*
* 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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -302,12 +302,15 @@ void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) ...@@ -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) 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); uint32_t reg_val = gicd_read_icfgr(base, id);
/* Clear the field, and insert required configuration */ /* Clear the field, and insert required configuration */
reg_val &= ~(GIC_CFG_MASK << bit_num); reg_val &= ~(GIC_CFG_MASK << bit_shift);
reg_val |= ((cfg & GIC_CFG_MASK) << bit_num); reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
gicd_write_icfgr(base, id, reg_val); gicd_write_icfgr(base, id, reg_val);
} }
/* /*
* 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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -232,12 +232,15 @@ void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) ...@@ -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) 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); uint32_t reg_val = gicr_read_icfgr0(base);
/* Clear the field, and insert required configuration */ /* Clear the field, and insert required configuration */
reg_val &= ~(GIC_CFG_MASK << bit_num); reg_val &= ~(GIC_CFG_MASK << bit_shift);
reg_val |= ((cfg & GIC_CFG_MASK) << bit_num); reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
gicr_write_icfgr0(base, reg_val); gicr_write_icfgr0(base, reg_val);
} }
...@@ -248,12 +251,15 @@ void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) ...@@ -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) 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); uint32_t reg_val = gicr_read_icfgr1(base);
/* Clear the field, and insert required configuration */ /* Clear the field, and insert required configuration */
reg_val &= ~(GIC_CFG_MASK << bit_num); reg_val &= ~(GIC_CFG_MASK << bit_shift);
reg_val |= ((cfg & GIC_CFG_MASK) << bit_num); reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
gicr_write_icfgr1(base, reg_val); gicr_write_icfgr1(base, reg_val);
} }
......
/* /*
* 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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -29,9 +29,9 @@ ...@@ -29,9 +29,9 @@
/* Constant to indicate a spurious interrupt in all GIC versions */ /* Constant to indicate a spurious interrupt in all GIC versions */
#define GIC_SPURIOUS_INTERRUPT 1023 #define GIC_SPURIOUS_INTERRUPT 1023
/* Interrupt configurations */ /* Interrupt configurations: 2-bit fields with LSB reserved */
#define GIC_INTR_CFG_LEVEL 0 #define GIC_INTR_CFG_LEVEL (0 << 1)
#define GIC_INTR_CFG_EDGE 1 #define GIC_INTR_CFG_EDGE (1 << 1)
/* Constants to categorise priorities */ /* Constants to categorise priorities */
#define GIC_HIGHEST_SEC_PRIORITY 0x0 #define GIC_HIGHEST_SEC_PRIORITY 0x0
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment