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
This commit is contained in:
Soby Mathew 2016-01-15 14:20:57 +00:00
parent a91e12fbea
commit 38a7861450
4 changed files with 22 additions and 7 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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:
@ -167,6 +167,7 @@ void gicd_set_ispendr(uintptr_t base, unsigned int id);
void gicd_set_icpendr(uintptr_t base, unsigned int id);
void gicd_set_isactiver(uintptr_t base, unsigned int id);
void gicd_set_icactiver(uintptr_t base, unsigned int id);
void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri);
#endif /* __ASSEMBLY__ */