mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 19:36:35 +08:00
arch/arm: Add the secure handling to gic
Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
@@ -41,6 +41,58 @@
|
|||||||
* Public Functions
|
* 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
|
* Name: arm_gic0_initialize
|
||||||
*
|
*
|
||||||
@@ -144,7 +196,13 @@ void arm_gic_initialize(void)
|
|||||||
|
|
||||||
/* Registers with 1-bit per interrupt */
|
/* 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 */
|
putreg32(0xfe000000, GIC_ICDICER(0)); /* PPIs disabled */
|
||||||
|
|
||||||
/* Registers with 8-bits per interrupt */
|
/* Registers with 8-bits per interrupt */
|
||||||
@@ -304,6 +362,58 @@ uint32_t *arm_decodeirq(uint32_t *regs)
|
|||||||
return 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
|
* Name: up_enable_irq
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -41,6 +41,58 @@
|
|||||||
* Public Functions
|
* 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
|
* Name: arm_gic0_initialize
|
||||||
*
|
*
|
||||||
@@ -144,7 +196,13 @@ void arm_gic_initialize(void)
|
|||||||
|
|
||||||
/* Registers with 1-bit per interrupt */
|
/* 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 */
|
putreg32(0xfe000000, GIC_ICDICER(0)); /* PPIs disabled */
|
||||||
|
|
||||||
/* Registers with 8-bits per interrupt */
|
/* Registers with 8-bits per interrupt */
|
||||||
@@ -313,6 +371,58 @@ uint32_t *arm_decodeirq(uint32_t *regs)
|
|||||||
return 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
|
* Name: up_enable_irq
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -617,7 +617,7 @@
|
|||||||
#define GIC_IRQ_SPI 32 /* First SPI interrupt ID */
|
#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;
|
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
|
* Name: arm_cpu_sgi
|
||||||
*
|
*
|
||||||
@@ -866,7 +922,13 @@ static void arm_gic_initialize(void)
|
|||||||
|
|
||||||
/* Registers with 1-bit per interrupt */
|
/* 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 */
|
putreg32(0xfe000000, GIC_ICDICER(0)); /* PPIs disabled */
|
||||||
|
|
||||||
/* Registers with 8-bits per interrupt */
|
/* Registers with 8-bits per interrupt */
|
||||||
@@ -1038,6 +1100,58 @@ uint64_t *arm64_decodeirq(uint64_t * regs)
|
|||||||
return 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
|
* Name: up_enable_irq
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user