mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 01:24:27 +00:00
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>
This commit is contained in:
parent
f13ef37a38
commit
17e84eedb2
3 changed files with 24 additions and 15 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
@ -29,9 +29,9 @@
|
|||
/* Constant to indicate a spurious interrupt in all GIC versions */
|
||||
#define GIC_SPURIOUS_INTERRUPT 1023
|
||||
|
||||
/* Interrupt configurations */
|
||||
#define GIC_INTR_CFG_LEVEL 0
|
||||
#define GIC_INTR_CFG_EDGE 1
|
||||
/* Interrupt configurations: 2-bit fields with LSB reserved */
|
||||
#define GIC_INTR_CFG_LEVEL (0 << 1)
|
||||
#define GIC_INTR_CFG_EDGE (1 << 1)
|
||||
|
||||
/* Constants to categorise priorities */
|
||||
#define GIC_HIGHEST_SEC_PRIORITY 0x0
|
||||
|
|
Loading…
Add table
Reference in a new issue