From 38a7861450409b6b234e12f15b8b516aa71b6610 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Fri, 15 Jan 2016 14:20:57 +0000 Subject: Fix GIC_IPRIORITYR setting in new drivers The code to set the interrupt priority for secure interrupts in the new GICv2 and GICv3 drivers is incorrect. The setup code to configure interrupt priorities of secure interrupts, one interrupt at a time, used gicd_write_ipriorityr()/gicr_write_ipriority() function affecting 4 interrupts at a time. This bug did not manifest itself because all the secure interrupts were configured to the highest secure priority(0) during cold boot and the adjacent non secure interrupt priority would be configured later by the normal world. This patch introduces new accessors, gicd_set_ipriorityr() and gicr_set_ipriorityr(), for configuring priority one interrupt at a time and fixes the the setup code to use the new accessors. Fixes ARM-software/tf-issues#344 Change-Id: I470fd74d2b7fce7058b55d83f604be05a27e1341 --- drivers/arm/gic/common/gic_common.c | 7 ++++++- drivers/arm/gic/v2/gicv2_helpers.c | 4 ++-- drivers/arm/gic/v3/gicv3_helpers.c | 15 ++++++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/arm/gic/common/gic_common.c b/drivers/arm/gic/common/gic_common.c index 17be61d5..2c901bc2 100644 --- a/drivers/arm/gic/common/gic_common.c +++ b/drivers/arm/gic/common/gic_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -306,3 +306,8 @@ void gicd_set_icactiver(uintptr_t base, unsigned int id) gicd_write_icactiver(base, id, (1 << bit_num)); } + +void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK); +} diff --git a/drivers/arm/gic/v2/gicv2_helpers.c b/drivers/arm/gic/v2/gicv2_helpers.c index 8c4e2f0f..e9ae7dfa 100644 --- a/drivers/arm/gic/v2/gicv2_helpers.c +++ b/drivers/arm/gic/v2/gicv2_helpers.c @@ -163,7 +163,7 @@ void gicv2_secure_spis_configure(uintptr_t gicd_base, gicd_clr_igroupr(gicd_base, irq_num); /* Set the priority of this interrupt */ - gicd_write_ipriorityr(gicd_base, + gicd_set_ipriorityr(gicd_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); @@ -210,7 +210,7 @@ void gicv2_secure_ppi_sgi_setup(uintptr_t gicd_base, sec_ppi_sgi_mask |= 1U << irq_num; /* Set the priority of this interrupt */ - gicd_write_ipriorityr(gicd_base, + gicd_set_ipriorityr(gicd_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); } diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 2fb98cbb..4a565045 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -194,6 +194,15 @@ void gicr_set_isenabler0(uintptr_t base, unsigned int id) gicr_write_isenabler0(base, (1 << bit_num)); } +/* + * Accessor to set the byte corresponding to interrupt ID + * in GIC Re-distributor IPRIORITYR. + */ +void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + mmio_write_8(base + GICR_IPRIORITYR + id, pri & GIC_PRI_MASK); +} + /****************************************************************************** * This function marks the core as awake in the re-distributor and * ensures that the interface is active. @@ -330,7 +339,7 @@ void gicv3_secure_spis_configure(uintptr_t gicd_base, gicd_clr_igrpmodr(gicd_base, irq_num); /* Set the priority of this interrupt */ - gicd_write_ipriorityr(gicd_base, + gicd_set_ipriorityr(gicd_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); @@ -404,7 +413,7 @@ void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base, gicr_clr_igrpmodr0(gicr_base, irq_num); /* Set the priority of this interrupt */ - gicr_write_ipriorityr(gicr_base, + gicr_set_ipriorityr(gicr_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); -- cgit