arch/arm: Add the secure handling to gic

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5 2023-08-04 10:14:04 +08:00 committed by Xiang Xiao
parent 7bb563dfe9
commit a96c6f1abf
3 changed files with 338 additions and 4 deletions

View File

@ -41,6 +41,58 @@
* Public Functions
****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_TRUSTZONE
/****************************************************************************
* Name: up_set_secure_irq
*
* Description:
* Secure an IRQ
*
****************************************************************************/
void up_secure_irq(int irq, bool secure)
{
unsigned int val;
if (secure)
{
val = getreg32(GIC_ICDISR(irq)) & (~GIC_ICDISR_INT(irq)); /* group 0 */
}
else
{
val = getreg32(GIC_ICDISR(irq)) | GIC_ICDISR_INT(irq); /* group 1 */
}
putreg32(val, GIC_ICDISR(irq));
}
/****************************************************************************
* Name: up_secure_irq_all
*
* Description:
* Secure all IRQ
*
****************************************************************************/
void up_secure_irq_all(bool secure)
{
unsigned int nlines = arm_gic_nlines();
unsigned int irq;
for (irq = 0; irq < nlines; irq += 32)
{
if (secure)
{
putreg32(0x00000000, GIC_ICDISR(irq)); /* group 0 */
}
else
{
putreg32(0xffffffff, GIC_ICDISR(irq)); /* group 1 */
}
}
}
#endif
/****************************************************************************
* Name: arm_gic0_initialize
*
@ -144,7 +196,13 @@ void arm_gic_initialize(void)
/* Registers with 1-bit per interrupt */
putreg32(0x00000000, GIC_ICDISR(0)); /* SGIs and PPIs secure */
/* per-CPU inerrupts config:
* ID0-ID7(SGI) for Non-secure interrupts
* ID8-ID15(SGI) for Secure interrupts.
* All PPI config as secure interrupts.
*/
putreg32(0x000000ff, GIC_ICDISR(0));
putreg32(0xfe000000, GIC_ICDICER(0)); /* PPIs disabled */
/* Registers with 8-bits per interrupt */
@ -304,6 +362,58 @@ uint32_t *arm_decodeirq(uint32_t *regs)
return regs;
}
/****************************************************************************
* Name: arm_decodefiq
*
* Description:
* This function is called from the FIQ vector handler in arm_vectors.S.
* At this point, the interrupt has been taken and the registers have
* been saved on the stack. This function simply needs to determine the
* the irq number of the interrupt and then to call arm_doirq to dispatch
* the interrupt.
*
* Input Parameters:
* regs - A pointer to the register save area on the stack.
*
****************************************************************************/
uint32_t *arm_decodefiq(uint32_t *regs)
{
uint32_t regval;
int irq;
/* Read the interrupt acknowledge register and get the interrupt ID */
regval = getreg32(GIC_ICCIAR);
irq = (regval & GIC_ICCIAR_INTID_MASK) >> GIC_ICCIAR_INTID_SHIFT;
#ifdef CONFIG_ARMV7A_GIC_EOIMODE
putreg32(regval, GIC_ICCEOIR);
#endif
/* Ignore spurions IRQs. ICCIAR will report 1023 if there is no pending
* interrupt.
*/
DEBUGASSERT(irq < NR_IRQS || irq >= 1022);
if (irq < NR_IRQS)
{
/* Dispatch the interrupt */
regs = arm_doirq(irq, regs);
}
/* Write to the end-of-interrupt register */
#ifdef CONFIG_ARMV7A_GIC_EOIMODE
putreg32(regval, GIC_ICCDIR);
#else
putreg32(regval, GIC_ICCEOIR);
#endif
return regs;
}
/****************************************************************************
* Name: up_enable_irq
*

View File

@ -41,6 +41,58 @@
* Public Functions
****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_TRUSTZONE
/****************************************************************************
* Name: up_set_secure_irq
*
* Description:
* Secure an IRQ
*
****************************************************************************/
void up_secure_irq(int irq, bool secure)
{
unsigned int val;
if (secure)
{
val = getreg32(GIC_ICDISR(irq)) & (~GIC_ICDISR_INT(irq)); /* group 0 */
}
else
{
val = getreg32(GIC_ICDISR(irq)) | GIC_ICDISR_INT(irq); /* group 1 */
}
putreg32(val, GIC_ICDISR(irq));
}
/****************************************************************************
* Name: up_secure_irq_all
*
* Description:
* Secure all IRQ
*
****************************************************************************/
void up_secure_irq_all(bool secure)
{
unsigned int nlines = arm_gic_nlines();
unsigned int irq;
for (irq = 0; irq < nlines; irq += 32)
{
if (secure)
{
putreg32(0x00000000, GIC_ICDISR(irq)); /* group 0 */
}
else
{
putreg32(0xffffffff, GIC_ICDISR(irq)); /* group 1 */
}
}
}
#endif
/****************************************************************************
* Name: arm_gic0_initialize
*
@ -144,7 +196,13 @@ void arm_gic_initialize(void)
/* Registers with 1-bit per interrupt */
putreg32(0x00000000, GIC_ICDISR(0)); /* SGIs and PPIs secure */
/* per-CPU inerrupts config:
* ID0-ID7(SGI) for Non-secure interrupts
* ID8-ID15(SGI) for Secure interrupts.
* All PPI config as secure interrupts.
*/
putreg32(0x000000ff, GIC_ICDISR(0));
putreg32(0xfe000000, GIC_ICDICER(0)); /* PPIs disabled */
/* Registers with 8-bits per interrupt */
@ -313,6 +371,58 @@ uint32_t *arm_decodeirq(uint32_t *regs)
return regs;
}
/****************************************************************************
* Name: arm_decodefiq
*
* Description:
* This function is called from the FIQ vector handler in arm_vectors.S.
* At this point, the interrupt has been taken and the registers have
* been saved on the stack. This function simply needs to determine the
* the irq number of the interrupt and then to call arm_doirq to dispatch
* the interrupt.
*
* Input Parameters:
* regs - A pointer to the register save area on the stack.
*
****************************************************************************/
uint32_t *arm_decodefiq(uint32_t *regs)
{
uint32_t regval;
int irq;
/* Read the interrupt acknowledge register and get the interrupt ID */
regval = getreg32(GIC_ICCIAR);
irq = (regval & GIC_ICCIAR_INTID_MASK) >> GIC_ICCIAR_INTID_SHIFT;
#ifdef CONFIG_ARMV7R_GIC_EOIMODE
putreg32(regval, GIC_ICCEOIR);
#endif
/* Ignore spurions IRQs. ICCIAR will report 1023 if there is no pending
* interrupt.
*/
DEBUGASSERT(irq < NR_IRQS || irq >= 1022);
if (irq < NR_IRQS)
{
/* Dispatch the interrupt */
regs = arm_doirq(irq, regs);
}
/* Write to the end-of-interrupt register */
#ifdef CONFIG_ARMV7R_GIC_EOIMODE
putreg32(regval, GIC_ICCDIR);
#else
putreg32(regval, GIC_ICCEOIR);
#endif
return regs;
}
/****************************************************************************
* Name: up_enable_irq
*

View File

@ -617,7 +617,7 @@
#define GIC_IRQ_SPI 32 /* First SPI interrupt ID */
/****************************************************************************
* Private Functions
* Public Functions
****************************************************************************/
/****************************************************************************
@ -647,6 +647,62 @@ static inline unsigned int arm_gic_nlines(void)
return (field + 1) << 5;
}
#ifdef CONFIG_ARCH_HAVE_TRUSTZONE
/****************************************************************************
* Name: up_set_secure_irq
*
* Description:
* Secure an IRQ
*
****************************************************************************/
void up_secure_irq(int irq, bool secure)
{
unsigned int val;
if (secure)
{
val = getreg32(GIC_ICDISR(irq)) & (~GIC_ICDISR_INT(irq)); /* group 0 */
}
else
{
val = getreg32(GIC_ICDISR(irq)) | GIC_ICDISR_INT(irq); /* group 1 */
}
putreg32(val, GIC_ICDISR(irq));
}
/****************************************************************************
* Name: up_secure_irq_all
*
* Description:
* Secure all IRQ
*
****************************************************************************/
void up_secure_irq_all(bool secure)
{
unsigned int nlines = arm_gic_nlines();
unsigned int irq;
for (irq = 0; irq < nlines; irq += 32)
{
if (secure)
{
putreg32(0x00000000, GIC_ICDISR(irq)); /* group 0 */
}
else
{
putreg32(0xffffffff, GIC_ICDISR(irq)); /* group 1 */
}
}
}
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: arm_cpu_sgi
*
@ -866,7 +922,13 @@ static void arm_gic_initialize(void)
/* Registers with 1-bit per interrupt */
putreg32(0x00000000, GIC_ICDISR(0)); /* SGIs and PPIs secure */
/* per-CPU inerrupts config:
* ID0-ID7(SGI) for Non-secure interrupts
* ID8-ID15(SGI) for Secure interrupts.
* All PPI config as secure interrupts.
*/
putreg32(0x000000ff, GIC_ICDISR(0));
putreg32(0xfe000000, GIC_ICDICER(0)); /* PPIs disabled */
/* Registers with 8-bits per interrupt */
@ -1038,6 +1100,58 @@ uint64_t *arm64_decodeirq(uint64_t * regs)
return regs;
}
/****************************************************************************
* Name: arm64_decodefiq
*
* Description:
* This function is called from the FIQ vector handler in arm_vectors.S.
* At this point, the interrupt has been taken and the registers have
* been saved on the stack. This function simply needs to determine the
* the irq number of the interrupt and then to call arm_doirq to dispatch
* the interrupt.
*
* Input Parameters:
* regs - A pointer to the register save area on the stack.
*
****************************************************************************/
uint64_t *arm64_decodefiq(uint64_t *regs)
{
uint32_t regval;
int irq;
/* Read the interrupt acknowledge register and get the interrupt ID */
regval = getreg32(GIC_ICCIAR);
irq = (regval & GIC_ICCIAR_INTID_MASK) >> GIC_ICCIAR_INTID_SHIFT;
#ifdef CONFIG_ARM_GIC_EOIMODE
putreg32(regval, GIC_ICCEOIR);
#endif
/* Ignore spurions IRQs. ICCIAR will report 1023 if there is no pending
* interrupt.
*/
DEBUGASSERT(irq < NR_IRQS || irq >= 1022);
if (irq < NR_IRQS)
{
/* Dispatch the interrupt */
regs = arm64_doirq(irq, regs);
}
/* Write to the end-of-interrupt register */
#ifdef CONFIG_ARM_GIC_EOIMODE
putreg32(regval, GIC_ICCDIR);
#else
putreg32(regval, GIC_ICCEOIR);
#endif
return regs;
}
/****************************************************************************
* Name: up_enable_irq
*