From 63375bf9cdb1a5c9a90a6eb7b6f42c6ef0bb92a0 Mon Sep 17 00:00:00 2001 From: Henry Rovner Date: Thu, 27 Jun 2024 13:26:54 -0700 Subject: [PATCH] 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 +++++++++++++++++++ arch/risc-v/src/bl808/hardware/bl808_m0ic.h | 47 ++++++++++ .../src/bl808/hardware/bl808_memorymap.h | 2 + 4 files changed, 137 insertions(+) create mode 100644 arch/risc-v/src/bl808/hardware/bl808_m0ic.h 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_m0ic.h b/arch/risc-v/src/bl808/hardware/bl808_m0ic.h new file mode 100644 index 0000000000..0276f2c563 --- /dev/null +++ b/arch/risc-v/src/bl808/hardware/bl808_m0ic.h @@ -0,0 +1,47 @@ +/**************************************************************************** + * 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 + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_M0IC_H +#define __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_M0IC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/bl808_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* 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_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_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