This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit a96c6f1abf2d1be80348b38c83e03ead4790c90b Author: hujun5 <[email protected]> AuthorDate: Fri Aug 4 10:14:04 2023 +0800 arch/arm: Add the secure handling to gic Signed-off-by: hujun5 <[email protected]> --- arch/arm/src/armv7-a/arm_gicv2.c | 112 +++++++++++++++++++++++++++++++++- arch/arm/src/armv7-r/arm_gicv2.c | 112 +++++++++++++++++++++++++++++++++- arch/arm64/src/common/arm64_gicv2.c | 118 +++++++++++++++++++++++++++++++++++- 3 files changed, 338 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c index 34fcdbed18..d5fb0dd555 100644 --- a/arch/arm/src/armv7-a/arm_gicv2.c +++ b/arch/arm/src/armv7-a/arm_gicv2.c @@ -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 * diff --git a/arch/arm/src/armv7-r/arm_gicv2.c b/arch/arm/src/armv7-r/arm_gicv2.c index d6ecd7cdd9..83c56001e5 100644 --- a/arch/arm/src/armv7-r/arm_gicv2.c +++ b/arch/arm/src/armv7-r/arm_gicv2.c @@ -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 * diff --git a/arch/arm64/src/common/arm64_gicv2.c b/arch/arm64/src/common/arm64_gicv2.c index 84831f864f..de3127eca1 100644 --- a/arch/arm64/src/common/arm64_gicv2.c +++ b/arch/arm64/src/common/arm64_gicv2.c @@ -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 *
