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
  *

Reply via email to