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.
This commit is contained in:
Henry Rovner 2024-06-27 13:26:54 -07:00 committed by Xiang Xiao
parent 7d2dbc00f6
commit 63375bf9cd
4 changed files with 137 additions and 0 deletions

View File

@ -53,6 +53,7 @@
#define BL808_IRQ_UART3 (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + 4) #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_D0_IPC (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + 38)
#define BL808_IRQ_M0IC (RISCV_IRQ_SEXT + BL808_IRQ_NUM_BASE + 65)
/* M0 IRQs ******************************************************************/ /* M0 IRQs ******************************************************************/

View File

@ -36,6 +36,55 @@
#include "riscv_ipi.h" #include "riscv_ipi.h"
#include "chip.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 * Public Functions
****************************************************************************/ ****************************************************************************/
@ -137,6 +186,14 @@ void up_disable_irq(int irq)
modifyreg32(BL808_PLIC_ENABLE1 + (4 * (extirq / 32)), modifyreg32(BL808_PLIC_ENABLE1 + (4 * (extirq / 32)),
1 << (extirq % 32), 0); 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 else
{ {
PANIC(); PANIC();
@ -179,6 +236,14 @@ void up_enable_irq(int irq)
modifyreg32(BL808_PLIC_ENABLE1 + (4 * (extirq / 32)), modifyreg32(BL808_PLIC_ENABLE1 + (4 * (extirq / 32)),
0, 1 << (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 else
{ {
PANIC(); PANIC();
@ -198,5 +263,27 @@ irqstate_t up_irq_enable(void)
oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE); 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; return oldstat;
} }

View File

@ -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 <nuttx/config.h>
#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 */

View File

@ -28,6 +28,8 @@
/* Register Base Address ****************************************************/ /* Register Base Address ****************************************************/
#define BL808_GLB_BASE 0x20000000ul #define BL808_GLB_BASE 0x20000000ul
#define BL808_M0IC_BASE 0x20000050ul
#define BL808_GPIO_BASE 0x200008c4ul #define BL808_GPIO_BASE 0x200008c4ul
#define BL808_UART0_BASE 0x2000a000ul #define BL808_UART0_BASE 0x2000a000ul
#define BL808_UART1_BASE 0x2000a100ul #define BL808_UART1_BASE 0x2000a100ul