mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
fix(gicv3): do not assume redistributors are powered down
When initialising a GICv3 compatible interrupt controller, we currently assume that the GIC is still in its reset state, which means the GICR_WAKER.ProcessorSleep bit is set. There is an "assert" in the GIC setup function to check this. However when using RESET_TO_BL31, there might be prior firmware running, and it might have used the GIC already. This is for instance the case on the Allwinner A523 SoC, where the BootROM initialises the GIC to use it when handling the built-in USB debug protocol. Drop the assert, which is not the right thing to do here anyway: it's not checking an internal state. Instead return early when the redistributor is already marked as active. Also keep waiting if ChildrenAsleep is unexpectedly set, but warn about this. This fixes booting TF-A on an Allwinner A523 SoC when using the USB debug mode. Change-Id: I5be9e1b0489d33b8371fff484e526483d5f3d937 Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
parent
eaaf26e3e6
commit
57f2d009fb
1 changed files with 14 additions and 3 deletions
|
@ -35,11 +35,22 @@ uintptr_t gicv3_get_multichip_base(uint32_t spi_id, uintptr_t gicd_base)
|
|||
*****************************************************************************/
|
||||
void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base)
|
||||
{
|
||||
uint32_t waker = gicr_read_waker(gicr_base);
|
||||
|
||||
/* Only try to mark it as awake when it is asleep. */
|
||||
if ((waker & WAKER_PS_BIT) == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The WAKER_PS_BIT should be changed to 0
|
||||
* only when WAKER_CA_BIT is 1.
|
||||
* ProcessorSleep must only be changed when ChildrenAsleep is 1.
|
||||
* If PS is 1 and CA isn't, wait for that to happen, but warn.
|
||||
*/
|
||||
assert((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U);
|
||||
if ((waker & WAKER_CA_BIT) == 0U) {
|
||||
WARN("GICR_WAKER.ChildrenAsleep unexpectedly set, waiting...\n");
|
||||
while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the connected core as awake */
|
||||
gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT);
|
||||
|
|
Loading…
Add table
Reference in a new issue