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.
This commit is contained in:
Henry Rovner 2024-06-20 15:04:29 -07:00 committed by Xiang Xiao
parent 142a1e186e
commit 210ea76b04
8 changed files with 261 additions and 2 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#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;
}

View File

@ -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 */

View File

@ -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();

View File

@ -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 */

View File

@ -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 */

View File

@ -34,6 +34,7 @@
#include <sys/mount.h>
#include <sys/boardctl.h>
#include <arch/board/board_memorymap.h>
#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