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 63375bf9cdb1a5c9a90a6eb7b6f42c6ef0bb92a0
Author: Henry Rovner <[email protected]>
AuthorDate: Thu Jun 27 13:26:54 2024 -0700

    BL808: Replace courier with M0 interrupt controller
    
    It turns out that the D0 core of the BL808 has an IRQ that represents all 
interrupt sources for the M0 core. This change uses this IRQ to access these 
sources, eliminating the need for IPC between M0 and D0.
---
 arch/risc-v/include/bl808/irq.h                    |  1 +
 arch/risc-v/src/bl808/bl808_irq.c                  | 87 ++++++++++++++++++++++
 .../hardware/{bl808_memorymap.h => bl808_m0ic.h}   | 33 +++++---
 arch/risc-v/src/bl808/hardware/bl808_memorymap.h   |  2 +
 4 files changed, 111 insertions(+), 12 deletions(-)

diff --git a/arch/risc-v/include/bl808/irq.h b/arch/risc-v/include/bl808/irq.h
index 60fb0530db..0733536a09 100644
--- a/arch/risc-v/include/bl808/irq.h
+++ b/arch/risc-v/include/bl808/irq.h
@@ -53,6 +53,7 @@
 
 #define BL808_IRQ_UART3 (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + 4)
 #define BL808_IRQ_D0_IPC (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + 38)
+#define BL808_IRQ_M0IC (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + 65)
 
 /* M0 IRQs ******************************************************************/
 
diff --git a/arch/risc-v/src/bl808/bl808_irq.c 
b/arch/risc-v/src/bl808/bl808_irq.c
index 9139a7d95a..343a109418 100644
--- a/arch/risc-v/src/bl808/bl808_irq.c
+++ b/arch/risc-v/src/bl808/bl808_irq.c
@@ -36,6 +36,55 @@
 #include "riscv_ipi.h"
 #include "chip.h"
 
+#include "hardware/bl808_m0ic.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: m0ic_interrupt
+ *
+ * Description:
+ *   Interrupt handler for M0 interrupt controller. Reads status registers
+ *   to find source, and dispatches the appropriate handler.
+ *
+ ****************************************************************************/
+
+static int __m0ic_interrupt(int irq, void *context, void *arg)
+{
+  uint32_t status_0 = getreg32(BL808_M0IC_STATUS(0));
+  uint32_t status_1 = getreg32(BL808_M0IC_STATUS(1));
+
+  /* Check status_0 for interrupt source */
+
+  int m0_extirq = ffs(status_0) - 1;
+  if (m0_extirq < 0)
+    {
+      /* Source not in status_0. Check status_1 */
+
+      m0_extirq = ffs(status_1) + 32 - 1;
+      if (m0_extirq < 32)
+        {
+          /* Interrupt goes off on startup without any
+           * status bits set. When this happens, just return.
+           */
+
+          return OK;
+        }
+    }
+
+  int irqn = m0_extirq + BL808_IRQ_NUM_BASE
+    + BL808_M0_IRQ_OFFSET + RISCV_IRQ_SEXT;
+
+  irq_dispatch(irqn, NULL);
+
+  putreg32(status_0, BL808_M0IC_CLEAR(0));
+  putreg32(status_1, BL808_M0IC_CLEAR(1));
+
+  return OK;
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -137,6 +186,14 @@ void up_disable_irq(int irq)
           modifyreg32(BL808_PLIC_ENABLE1 + (4 * (extirq / 32)),
                       1 << (extirq % 32), 0);
         }
+      else if ((BL808_D0_MAX_EXTIRQ + 1) <= extirq
+               && extirq <= (BL808_M0_MAX_EXTIRQ
+                             + BL808_M0_IRQ_OFFSET))
+        {
+          int m0_extirq = extirq - BL808_M0_IRQ_OFFSET - BL808_IRQ_NUM_BASE;
+          modifyreg32(BL808_M0IC_MASK(m0_extirq / 32),
+                      0, 1 << (m0_extirq % 32));
+        }
       else
         {
           PANIC();
@@ -179,6 +236,14 @@ void up_enable_irq(int irq)
           modifyreg32(BL808_PLIC_ENABLE1 + (4 * (extirq / 32)),
                       0, 1 << (extirq % 32));
         }
+      else if ((BL808_D0_MAX_EXTIRQ + 1) <= extirq
+               && extirq <= (BL808_M0_MAX_EXTIRQ
+                             + BL808_M0_IRQ_OFFSET))
+        {
+          int m0_extirq = extirq - BL808_M0_IRQ_OFFSET - BL808_IRQ_NUM_BASE;
+          modifyreg32(BL808_M0IC_MASK(m0_extirq / 32),
+                      1 << (m0_extirq % 32), 0);
+        }
       else
         {
           PANIC();
@@ -198,5 +263,27 @@ irqstate_t up_irq_enable(void)
 
   oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE);
 
+  /* Enable IRQs from M0IC */
+
+  /* First, clear interrupts */
+
+  putreg32(0xffffffff, BL808_M0IC_CLEAR(0));
+  putreg32(0xffffffff, BL808_M0IC_CLEAR(1));
+
+  /* Mask all sources */
+
+  putreg32(0xffffffff, BL808_M0IC_MASK(0));
+  putreg32(0xffffffff, BL808_M0IC_MASK(1));
+
+  int ret = irq_attach(BL808_IRQ_M0IC, __m0ic_interrupt, NULL);
+  if (ret == OK)
+    {
+      up_enable_irq(BL808_IRQ_M0IC);
+    }
+  else
+    {
+      PANIC();
+    }
+
   return oldstat;
 }
diff --git a/arch/risc-v/src/bl808/hardware/bl808_memorymap.h 
b/arch/risc-v/src/bl808/hardware/bl808_m0ic.h
similarity index 57%
copy from arch/risc-v/src/bl808/hardware/bl808_memorymap.h
copy to arch/risc-v/src/bl808/hardware/bl808_m0ic.h
index b657728b2b..0276f2c563 100644
--- a/arch/risc-v/src/bl808/hardware/bl808_memorymap.h
+++ b/arch/risc-v/src/bl808/hardware/bl808_m0ic.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/risc-v/src/bl808/hardware/bl808_memorymap.h
+ * arch/risc-v/src/bl808/hardware/bl808_m0ic.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,21 +18,30 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_MEMORYMAP_H
-#define __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_MEMORYMAP_H
+#ifndef __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_M0IC_H
+#define __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_M0IC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include "hardware/bl808_memorymap.h"
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-/* Register Base Address ****************************************************/
+/* Register offsets */
+
+#define BL808_M0IC_STATUS_OFFSET(n)            (0x00 + 4 * (n))
+#define BL808_M0IC_MASK_OFFSET(n)              (0x08 + 4 * (n))
+#define BL808_M0IC_CLEAR_OFFSET(n)             (0x10 + 4 * (n))
+
+/* Register locations */
 
-#define BL808_GLB_BASE     0x20000000ul
-#define BL808_GPIO_BASE    0x200008c4ul
-#define BL808_UART0_BASE   0x2000a000ul
-#define BL808_UART1_BASE   0x2000a100ul
-#define BL808_UART2_BASE   0x2000aa00ul
-#define BL808_UART3_BASE   0x30002000ul
-#define BL808_PLIC_BASE    0xe0000000ul
+#define BL808_M0IC_STATUS(n) BL808_M0IC_BASE + BL808_M0IC_STATUS_OFFSET(n)
+#define BL808_M0IC_MASK(n)   BL808_M0IC_BASE + BL808_M0IC_MASK_OFFSET(n)
+#define BL808_M0IC_CLEAR(n)  BL808_M0IC_BASE + BL808_M0IC_CLEAR_OFFSET(n)
 
-#endif /* __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_MEMORYMAP_H */
+#endif /* __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_M0IC_H */
diff --git a/arch/risc-v/src/bl808/hardware/bl808_memorymap.h 
b/arch/risc-v/src/bl808/hardware/bl808_memorymap.h
index b657728b2b..eb0d0dba14 100644
--- a/arch/risc-v/src/bl808/hardware/bl808_memorymap.h
+++ b/arch/risc-v/src/bl808/hardware/bl808_memorymap.h
@@ -28,6 +28,8 @@
 /* Register Base Address ****************************************************/
 
 #define BL808_GLB_BASE     0x20000000ul
+#define BL808_M0IC_BASE    0x20000050ul
+
 #define BL808_GPIO_BASE    0x200008c4ul
 #define BL808_UART0_BASE   0x2000a000ul
 #define BL808_UART1_BASE   0x2000a100ul

Reply via email to