Commit acc29852 authored by James kung's avatar James kung Committed by James Kung
Browse files

Prevent pending G1S interrupt become G0 interrupt



According to Arm GIC spec(IHI0069E, section 4.6.1),
when GICD_CTLR.DS == 0, Secure Group 1 interrupts
are treated as Group 0 by a CPU interface if:
- The PE does not implement EL3.
- ICC_SRE_EL1(S).SRE == 0

When a cpu enter suspend or deep idle, it might be
powered off. When the cpu resume, according to
the GIC spec(IHI0069E, section 9.2.15, 9.2.16 and
9.2.22) the ICC_SRE_EL1.SRE reset value is 0 (if
write is allowed) and G0/G1S/G1NS interrupt of the
GIC cpu interface are all disabled.

If a G1S SPI interrupt occurred and the target cpu
of the SPI is assigned to a specific cpu which is
in suspend and is powered off, when the cpu resume
and start to initial the GIC cpu interface, the
initial sequence might affect the interrupt group
type of the pending interrupt on the cpu interface.

Current initial sequence on the cpu interface is:
1. Enable G0 interrupt
2. Enable G1S interrupt
3. Enable ICC_SRE_EL1(S).SRE

It is possible to treat the pending G1S interrupt
as G0 interrupt on the cpu interface if the G1S
SPI interrupt occurred between step2 and step3.

To prevent the above situation happend, the initial
sequence should be changed as follows:
1. Enable ICC_SRE_EL1(S).SRE
2. Enable G0 interrupt
3. Enable G1S interrupt

Change-Id: Ie34f6e0b32eb9a1677ff72571fd4bfdb5cae25b0
Signed-off-by: default avatarJames Kung <kong1191@gmail.com>
parent 49d969bb
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -265,6 +265,10 @@ void gicv3_cpuif_enable(unsigned int proc_num)
write_scr_el3(scr_el3 & (~SCR_NS_BIT));
isb();
/* Write the secure ICC_SRE_EL1 register */
write_icc_sre_el1(ICC_SRE_SRE_BIT);
isb();
/* Program the idle priority in the PMR */
write_icc_pmr_el1(GIC_PRI_MASK);
......@@ -274,9 +278,6 @@ void gicv3_cpuif_enable(unsigned int proc_num)
/* Enable Group1 Secure interrupts */
write_icc_igrpen1_el3(read_icc_igrpen1_el3() |
IGRPEN1_EL3_ENABLE_G1S_BIT);
/* Write the secure ICC_SRE_EL1 register */
write_icc_sre_el1(ICC_SRE_SRE_BIT);
isb();
}
......
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