From 210ea76b04ee162220bc95c0349720e3823dda2c Mon Sep 17 00:00:00 2001 From: Henry Rovner Date: Thu, 20 Jun 2024 15:04:29 -0700 Subject: [PATCH] Add courier system driver This change implements a system for allowing the D0 core (which runs NuttX) to receive forwarded interrupts from the M0 core. This makes it possible for drivers that rely on interrupts to work with peripherals attached to the M0 core. --- arch/risc-v/include/bl808/irq.h | 10 +- arch/risc-v/src/bl808/Make.defs | 1 + arch/risc-v/src/bl808/bl808_courier.c | 123 ++++++++++++++++++ arch/risc-v/src/bl808/bl808_courier.h | 66 ++++++++++ arch/risc-v/src/bl808/bl808_irq.c | 12 ++ arch/risc-v/src/bl808/hardware/bl808_ipc.h | 40 ++++++ .../src/bl808/hardware/bl808_memorymap.h | 6 +- boards/risc-v/bl808/ox64/src/bl808_appinit.c | 5 + 8 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 arch/risc-v/src/bl808/bl808_courier.c create mode 100644 arch/risc-v/src/bl808/bl808_courier.h create mode 100644 arch/risc-v/src/bl808/hardware/bl808_ipc.h diff --git a/arch/risc-v/include/bl808/irq.h b/arch/risc-v/include/bl808/irq.h index b99b1535d69..52d5c3c0e1f 100644 --- a/arch/risc-v/include/bl808/irq.h +++ b/arch/risc-v/include/bl808/irq.h @@ -31,10 +31,18 @@ /* Map RISC-V exception code to NuttX IRQ */ -#define NR_IRQS (RISCV_IRQ_SEXT + 57) +#define NR_IRQS (RISCV_IRQ_SEXT + 114) #define BL808_IRQ_NUM_BASE (16) +#define BL808_M0_IRQ_OFFSET (64) // IRQs tied to M0 core are given a virtual IRQ number +/* D0 IRQs ******************************************************************/ #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) + +/* M0 IRQs ******************************************************************/ +#define BL808_IRQ_UART0 (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + BL808_M0_IRQ_OFFSET + 28) +#define BL808_IRQ_UART1 (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + BL808_M0_IRQ_OFFSET + 29) +#define BL808_IRQ_UART2 (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + BL808_M0_IRQ_OFFSET + 30) #endif /* __ARCH_RISCV_INCLUDE_BL808_IRQ_H */ diff --git a/arch/risc-v/src/bl808/Make.defs b/arch/risc-v/src/bl808/Make.defs index 61a4f41280e..099b7129886 100644 --- a/arch/risc-v/src/bl808/Make.defs +++ b/arch/risc-v/src/bl808/Make.defs @@ -28,3 +28,4 @@ HEAD_ASRC = bl808_head.S CHIP_CSRCS = bl808_start.c bl808_irq_dispatch.c bl808_irq.c CHIP_CSRCS += bl808_timerisr.c bl808_allocateheap.c CHIP_CSRCS += bl808_mm_init.c bl808_pgalloc.c bl808_serial.c +CHIP_CSRCS += bl808_courier.c diff --git a/arch/risc-v/src/bl808/bl808_courier.c b/arch/risc-v/src/bl808/bl808_courier.c new file mode 100644 index 00000000000..c7a696c2e74 --- /dev/null +++ b/arch/risc-v/src/bl808/bl808_courier.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/risc-v/src/bl808/bl808_courier.c + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "hardware/bl808_ipc.h" +#include "riscv_internal.h" +#include "chip.h" +#include "bl808_courier.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: courier_interrupt + * + * Description: + * Interrupt handler for IPC. Reads the IPC message, gets the interrupt + * number and dispatches the appropriate handler. + * + ****************************************************************************/ + +static int __courier_interrupt(int irq, void *context, void *arg) +{ + uint32_t msg = getreg32(IPC2_MSG_READ); + int m0_extirq = msg & BL808_COURIER_IRQN_MASK; + int irqn = m0_extirq + BL808_M0_IRQ_OFFSET + RISCV_IRQ_SEXT; + + irq_dispatch(irqn, NULL); + + bl808_courier_req_irq_enable(m0_extirq); + + putreg32(msg, IPC2_MSG_ACK); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: bl808_courier_req_irq_disable + * + * Description: + * Sends an IPC message to M0 core to enable m0_extirq. + * + ****************************************************************************/ + +void bl808_courier_req_irq_enable(int m0_extirq) +{ + putreg32((m0_extirq & BL808_COURIER_IRQN_MASK) + | (1 << BL808_INT_SIG_SHIFT) + | (1 << BL808_INT_EN_SHIFT), + IPC0_MSG_SEND); +} + +/**************************************************************************** + * Name: bl808_courier_req_irq_disable + * + * Description: + * Sends an IPC message to M0 core to disable m0_extirq. + * + ****************************************************************************/ + +void bl808_courier_req_irq_disable(int m0_extirq) +{ + putreg32((m0_extirq & BL808_COURIER_IRQN_MASK) + | (1 << BL808_INT_SIG_SHIFT), + IPC0_MSG_SEND); +} + +/**************************************************************************** + * Name: bl808_courier_init + * + * Description: + * Enables the IPC interrupt on D0 core and attaches its handler. + * + ****************************************************************************/ + +int bl808_courier_init(void) +{ + putreg32((1 << BL808_INT_SIG_SHIFT), IPC2_INT_UNMASK); + + int ret = irq_attach(BL808_IRQ_D0_IPC, __courier_interrupt, NULL); + if (ret == OK) + { + up_enable_irq(BL808_IRQ_D0_IPC); + } + + return ret; +} diff --git a/arch/risc-v/src/bl808/bl808_courier.h b/arch/risc-v/src/bl808/bl808_courier.h new file mode 100644 index 00000000000..9fc5cd291b8 --- /dev/null +++ b/arch/risc-v/src/bl808/bl808_courier.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/risc-v/src/bl808/bl808_courier.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_RISC_V_SRC_BL808_BL808_COURIER_H +#define __ARCH_RISC_V_SRC_BL808_BL808_COURIER_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BL808_COURIER_IRQN_MASK 0xff +#define BL808_INT_SIG_SHIFT 8 +#define BL808_INT_EN_SHIFT 9 + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: bl808_courier_req_irq_enable + * + * Description: + * Sends an IPC message to M0 core to enable m0_extirq. + * + ****************************************************************************/ + +void bl808_courier_req_irq_enable(int m0_extirq); + +/**************************************************************************** + * Name: bl808_courier_req_irq_disable + * + * Description: + * Sends an IPC message to M0 core to disable m0_extirq. + * + ****************************************************************************/ + +void bl808_courier_req_irq_disable(int m0_extirq); + +/**************************************************************************** + * Name: bl808_courier_init + * + * Description: + * Enables the IPC interrupt on D0 core and attaches its handler. + * + ****************************************************************************/ + +int bl808_courier_init(void); + +#endif /* __ARCH_RISC_V_SRC_BL808_BL808_COURIER_H */ diff --git a/arch/risc-v/src/bl808/bl808_irq.c b/arch/risc-v/src/bl808/bl808_irq.c index 841c1c82ade..97ea7429c15 100644 --- a/arch/risc-v/src/bl808/bl808_irq.c +++ b/arch/risc-v/src/bl808/bl808_irq.c @@ -36,6 +36,8 @@ #include "riscv_ipi.h" #include "chip.h" +#include "bl808_courier.h" + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -137,6 +139,11 @@ void up_disable_irq(int irq) modifyreg32(BL808_PLIC_ENABLE1 + (4 * (extirq / 32)), 1 << (extirq % 32), 0); } + else if (64 <= extirq && extirq <= 127) + { + int m0_extirq = extirq - BL808_M0_IRQ_OFFSET; + bl808_courier_req_irq_disable(m0_extirq); + } else { PANIC(); @@ -179,6 +186,11 @@ void up_enable_irq(int irq) modifyreg32(BL808_PLIC_ENABLE1 + (4 * (extirq / 32)), 0, 1 << (extirq % 32)); } + else if (64 <= extirq && extirq <= 127) + { + int m0_extirq = extirq - BL808_M0_IRQ_OFFSET; + bl808_courier_req_irq_enable(m0_extirq); + } else { PANIC(); diff --git a/arch/risc-v/src/bl808/hardware/bl808_ipc.h b/arch/risc-v/src/bl808/hardware/bl808_ipc.h new file mode 100644 index 00000000000..19fc0b0b064 --- /dev/null +++ b/arch/risc-v/src/bl808/hardware/bl808_ipc.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * arch/risc-v/src/bl808/hardware/bl808_ipc.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_IPC_H +#define __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_IPC_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IPC_MSG_SEND_OFFSET 0x0 +#define IPC0_MSG_SEND (IPC0_BASE + IPC_MSG_SEND_OFFSET) + +#define IPC_MSG_READ_OFFSET 0x24 +#define IPC2_MSG_READ (IPC2_BASE + IPC_MSG_READ_OFFSET) + +#define IPC_MSG_ACK_OFFSET 0x28 +#define IPC2_MSG_ACK (IPC2_BASE + IPC_MSG_ACK_OFFSET) + +#define IPC_INT_UNMASK_OFFSET 0x2c +#define IPC2_INT_UNMASK (IPC2_BASE + IPC_INT_UNMASK_OFFSET) + +#endif /* __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_IPC_H */ diff --git a/arch/risc-v/src/bl808/hardware/bl808_memorymap.h b/arch/risc-v/src/bl808/hardware/bl808_memorymap.h index c68d224adeb..d7a817ef58e 100644 --- a/arch/risc-v/src/bl808/hardware/bl808_memorymap.h +++ b/arch/risc-v/src/bl808/hardware/bl808_memorymap.h @@ -28,6 +28,10 @@ /* Register Base Address ****************************************************/ #define BL808_UART3_BASE 0x30002000ul -#define BL808_PLIC_BASE 0xe0000000ul + +#define IPC0_BASE 0x2000a800ul +#define IPC2_BASE 0x30005000ul + +#define BL808_PLIC_BASE 0xe0000000ul #endif /* __ARCH_RISCV_SRC_BL808_HARDWARE_BL808_MEMORYMAP_H */ diff --git a/boards/risc-v/bl808/ox64/src/bl808_appinit.c b/boards/risc-v/bl808/ox64/src/bl808_appinit.c index d960bc7f4c5..28b3b29373c 100644 --- a/boards/risc-v/bl808/ox64/src/bl808_appinit.c +++ b/boards/risc-v/bl808/ox64/src/bl808_appinit.c @@ -34,6 +34,7 @@ #include #include #include +#include "bl808_courier.h" /**************************************************************************** * Pre-processor Definitions @@ -157,6 +158,10 @@ void board_late_initialize(void) mount_ramdisk(); + /* Initialize courier to get IRQs from M0 */ + + bl808_courier_init(); + /* Perform board-specific initialization */ #ifdef CONFIG_NSH_ARCHINIT