forked from nuttx/nuttx-update
arch/risc-v: qemu: add AIA support
Implement AIA support for qemu rv-virt. Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
This commit is contained in:
parent
5f70307111
commit
b35f7aed48
7 changed files with 248 additions and 40 deletions
|
@ -34,7 +34,21 @@ Build and install ``qemu``::
|
||||||
$ make
|
$ make
|
||||||
$ sudo make install
|
$ sudo make install
|
||||||
|
|
||||||
QEMU 7.2.9 or later and OpenSBI v1.1 or later (usually shipped with QEMU) is required, to support RISC-V "Sstc" Extension. It is also recommended to use the latest QEMU and OpenSBI.
|
Minimum Requirement
|
||||||
|
===================
|
||||||
|
|
||||||
|
The table below lists all the minimum versions for QEMU and OpenSBI.
|
||||||
|
For stability, it is also recommended to use the latest QEMU and OpenSBI.
|
||||||
|
|
||||||
|
+----------------------------+--------------+-----------------+
|
||||||
|
| Extension | QEMU Version | OpenSBI Version |
|
||||||
|
+============================+==============+=================+
|
||||||
|
| No extension | 6.2.0 | v1.0 |
|
||||||
|
+----------------------------+--------------+-----------------+
|
||||||
|
| SSTC | 7.2.9 | v1.1 |
|
||||||
|
+----------------------------+--------------+-----------------+
|
||||||
|
| AIA | 8.2.0 | v1.2 |
|
||||||
|
+----------------------------+--------------+-----------------+
|
||||||
|
|
||||||
For users who wish to use their own OpenSBI, please refer to `OpenSBI repository <https://github.com/riscv-software-src/opensbi>`_.
|
For users who wish to use their own OpenSBI, please refer to `OpenSBI repository <https://github.com/riscv-software-src/opensbi>`_.
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "hardware/qemu_rv_clint.h"
|
#include "hardware/qemu_rv_clint.h"
|
||||||
#include "hardware/qemu_rv_memorymap.h"
|
#include "hardware/qemu_rv_memorymap.h"
|
||||||
#include "hardware/qemu_rv_plic.h"
|
#include "hardware/qemu_rv_plic.h"
|
||||||
|
#include "hardware/qemu_rv_aplic.h"
|
||||||
|
|
||||||
#include "riscv_internal.h"
|
#include "riscv_internal.h"
|
||||||
#include "riscv_percpu.h"
|
#include "riscv_percpu.h"
|
||||||
|
|
36
arch/risc-v/src/qemu-rv/hardware/qemu_rv_aplic.h
Normal file
36
arch/risc-v/src/qemu-rv/hardware/qemu_rv_aplic.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* arch/risc-v/src/qemu-rv/hardware/qemu_rv_aplic.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_QEMU_RV_HARDWARE_QEMU_RV_APLIC_H
|
||||||
|
#define __ARCH_RISCV_SRC_QEMU_RV_HARDWARE_QEMU_RV_APLIC_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define QEMU_RV_APLIC_NR_IRQ 0x60
|
||||||
|
|
||||||
|
#endif /* __ARCH_RISCV_SRC_QEMU_RV_HARDWARE_QEMU_RV_APLIC_H */
|
|
@ -34,10 +34,12 @@
|
||||||
#define RISCV_CLINT_MSIP QEMU_RV_CLINT_MSIP
|
#define RISCV_CLINT_MSIP QEMU_RV_CLINT_MSIP
|
||||||
#define RISCV_ACLINT_SSIP QEMU_RV_ACLINT_SSIP
|
#define RISCV_ACLINT_SSIP QEMU_RV_ACLINT_SSIP
|
||||||
|
|
||||||
|
#ifndef CONFIG_ARCH_RV_USE_IMSIC_IPI
|
||||||
#ifdef CONFIG_ARCH_USE_S_MODE
|
#ifdef CONFIG_ARCH_USE_S_MODE
|
||||||
# define RISCV_IPI RISCV_ACLINT_SSIP
|
# define RISCV_IPI RISCV_ACLINT_SSIP
|
||||||
#else
|
#else
|
||||||
# define RISCV_IPI RISCV_CLINT_MSIP
|
# define RISCV_IPI RISCV_CLINT_MSIP
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ARCH_RISCV_SRC_QEMU_RV_HARDWARE_QEMU_RV_CLINT_H */
|
#endif /* __ARCH_RISCV_SRC_QEMU_RV_HARDWARE_QEMU_RV_CLINT_H */
|
||||||
|
|
|
@ -33,4 +33,12 @@
|
||||||
|
|
||||||
#define QEMU_RV_RESET_BASE 0x100000
|
#define QEMU_RV_RESET_BASE 0x100000
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_S_MODE
|
||||||
|
# define QEMU_RV_APLIC_BASE 0x0d000000
|
||||||
|
# define QEMU_RV_IMSIC_BASE 0x28000000
|
||||||
|
#else
|
||||||
|
# define QEMU_RV_APLIC_BASE 0x0c000000
|
||||||
|
# define QEMU_RV_IMSIC_BASE 0x24000000
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ARCH_RISCV_SRC_QEMU_RV_HARDWARE_QEMU_RV_MEMORYMAP_H */
|
#endif /* __ARCH_RISCV_SRC_QEMU_RV_HARDWARE_QEMU_RV_MEMORYMAP_H */
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "riscv_internal.h"
|
#include "riscv_internal.h"
|
||||||
#include "riscv_ipi.h"
|
#include "riscv_ipi.h"
|
||||||
|
#include "riscv_aia.h"
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -52,8 +53,12 @@ void up_irqinitialize(void)
|
||||||
|
|
||||||
/* Disable all global interrupts */
|
/* Disable all global interrupts */
|
||||||
|
|
||||||
|
#ifndef CONFIG_ARCH_RV_HAVE_APLIC
|
||||||
putreg32(0x0, QEMU_RV_PLIC_ENABLE1);
|
putreg32(0x0, QEMU_RV_PLIC_ENABLE1);
|
||||||
putreg32(0x0, QEMU_RV_PLIC_ENABLE2);
|
putreg32(0x0, QEMU_RV_PLIC_ENABLE2);
|
||||||
|
#else
|
||||||
|
riscv_aplic_disable_irqs(QEMU_RV_APLIC_BASE, QEMU_RV_APLIC_NR_IRQ);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Colorize the interrupt stack for debug purposes */
|
/* Colorize the interrupt stack for debug purposes */
|
||||||
|
|
||||||
|
@ -62,10 +67,31 @@ void up_irqinitialize(void)
|
||||||
riscv_stack_color(g_intstackalloc, intstack_size);
|
riscv_stack_color(g_intstackalloc, intstack_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set priority for all global interrupts to 1 (lowest) */
|
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_RV_HAVE_IMSIC
|
||||||
|
/* Set default IRQ target hart index to 0 and EIID */
|
||||||
|
|
||||||
|
for (id = 0; id < QEMU_RV_APLIC_NR_IRQ; id++)
|
||||||
|
{
|
||||||
|
riscv_aplic_configure_irq(QEMU_RV_APLIC_BASE, id + 1, 0, id + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
riscv_aplic_init_msi(QEMU_RV_APLIC_BASE, QEMU_RV_IMSIC_BASE, 0, 3, 0, 0);
|
||||||
|
#elif defined(CONFIG_ARCH_RV_HAVE_APLIC)
|
||||||
|
/* Set default IRQ target hart index to 0 and priority */
|
||||||
|
|
||||||
|
for (id = 0; id < QEMU_RV_APLIC_NR_IRQ; id++)
|
||||||
|
{
|
||||||
|
riscv_aplic_configure_irq(QEMU_RV_APLIC_BASE, id + 1,
|
||||||
|
RISCV_APLIC_DEFAULT_PRIORITY, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
riscv_aplic_init(QEMU_RV_APLIC_BASE, RISCV_APLIC_ENABLE_IDELIVERY,
|
||||||
|
RISCV_APLIC_ENABLE_ITHRESHOLD);
|
||||||
|
#else
|
||||||
|
/* Set priority for all global interrupts to 1 (lowest) */
|
||||||
|
|
||||||
for (id = 1; id <= 52; id++)
|
for (id = 1; id <= 52; id++)
|
||||||
{
|
{
|
||||||
putreg32(1, (uintptr_t)(QEMU_RV_PLIC_PRIORITY + 4 * id));
|
putreg32(1, (uintptr_t)(QEMU_RV_PLIC_PRIORITY + 4 * id));
|
||||||
|
@ -74,6 +100,7 @@ void up_irqinitialize(void)
|
||||||
/* Set irq threshold to 0 (permits all global interrupts) */
|
/* Set irq threshold to 0 (permits all global interrupts) */
|
||||||
|
|
||||||
putreg32(0, QEMU_RV_PLIC_THRESHOLD);
|
putreg32(0, QEMU_RV_PLIC_THRESHOLD);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Attach the common interrupt handler */
|
/* Attach the common interrupt handler */
|
||||||
|
|
||||||
|
@ -84,8 +111,12 @@ void up_irqinitialize(void)
|
||||||
|
|
||||||
riscv_ipi_clear(0);
|
riscv_ipi_clear(0);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_RV_USE_IMSIC_IPI
|
||||||
|
riscv_imsic_local_eie_enable(RISCV_IMSIC_IPI_ID);
|
||||||
|
#else
|
||||||
up_enable_irq(RISCV_IRQ_SOFT);
|
up_enable_irq(RISCV_IRQ_SOFT);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
|
|
||||||
|
@ -119,6 +150,24 @@ void up_disable_irq(int irq)
|
||||||
|
|
||||||
CLEAR_CSR(CSR_IE, IE_TIE);
|
CLEAR_CSR(CSR_IE, IE_TIE);
|
||||||
}
|
}
|
||||||
|
else if (irq == RISCV_IRQ_EXT)
|
||||||
|
{
|
||||||
|
/* Read m/sstatus & clear external interrupt enable in m/sie */
|
||||||
|
|
||||||
|
CLEAR_CSR(CSR_IE, IE_EIE);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_RV_HAVE_IMSIC
|
||||||
|
/* Set IMSIC irq threshold to 0 (permits all global interrupts) */
|
||||||
|
|
||||||
|
riscv_imsic_csr_write(ISELECT_EITHRESHOLD,
|
||||||
|
RISCV_IMSIC_DISABLE_EITHRESHOLD);
|
||||||
|
|
||||||
|
/* Enable irq delivery for IMSIC */
|
||||||
|
|
||||||
|
riscv_imsic_csr_write(ISELECT_EIDELIVERY,
|
||||||
|
RISCV_IMSIC_DISABLE_EIDELIVERY);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else if (irq > RISCV_IRQ_EXT)
|
else if (irq > RISCV_IRQ_EXT)
|
||||||
{
|
{
|
||||||
extirq = irq - RISCV_IRQ_EXT;
|
extirq = irq - RISCV_IRQ_EXT;
|
||||||
|
@ -127,8 +176,15 @@ void up_disable_irq(int irq)
|
||||||
|
|
||||||
if (0 <= extirq && extirq <= 63)
|
if (0 <= extirq && extirq <= 63)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_ARCH_RV_HAVE_APLIC
|
||||||
modifyreg32(QEMU_RV_PLIC_ENABLE1 + (4 * (extirq / 32)),
|
modifyreg32(QEMU_RV_PLIC_ENABLE1 + (4 * (extirq / 32)),
|
||||||
1 << (extirq % 32), 0);
|
1 << (extirq % 32), 0);
|
||||||
|
#else
|
||||||
|
riscv_aplic_disable_irq(QEMU_RV_APLIC_BASE, extirq);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_ARCH_RV_HAVE_IMSIC
|
||||||
|
riscv_imsic_local_eie_disable(extirq);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -161,6 +217,24 @@ void up_enable_irq(int irq)
|
||||||
|
|
||||||
SET_CSR(CSR_IE, IE_TIE);
|
SET_CSR(CSR_IE, IE_TIE);
|
||||||
}
|
}
|
||||||
|
else if (irq == RISCV_IRQ_EXT)
|
||||||
|
{
|
||||||
|
/* Read m/sstatus & set external interrupt enable in m/sie */
|
||||||
|
|
||||||
|
SET_CSR(CSR_IE, IE_EIE);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_RV_HAVE_IMSIC
|
||||||
|
/* Set IMSIC irq threshold to 0 (permits all global interrupts) */
|
||||||
|
|
||||||
|
riscv_imsic_csr_write(ISELECT_EITHRESHOLD,
|
||||||
|
RISCV_IMSIC_ENABLE_EITHRESHOLD);
|
||||||
|
|
||||||
|
/* Enable irq delivery for IMSIC */
|
||||||
|
|
||||||
|
riscv_imsic_csr_write(ISELECT_EIDELIVERY,
|
||||||
|
RISCV_IMSIC_ENABLE_EIDELIVERY);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else if (irq > RISCV_IRQ_EXT)
|
else if (irq > RISCV_IRQ_EXT)
|
||||||
{
|
{
|
||||||
extirq = irq - RISCV_IRQ_EXT;
|
extirq = irq - RISCV_IRQ_EXT;
|
||||||
|
@ -169,8 +243,18 @@ void up_enable_irq(int irq)
|
||||||
|
|
||||||
if (0 <= extirq && extirq <= 63)
|
if (0 <= extirq && extirq <= 63)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_ARCH_RV_HAVE_APLIC
|
||||||
modifyreg32(QEMU_RV_PLIC_ENABLE1 + (4 * (extirq / 32)),
|
modifyreg32(QEMU_RV_PLIC_ENABLE1 + (4 * (extirq / 32)),
|
||||||
0, 1 << (extirq % 32));
|
0, 1 << (extirq % 32));
|
||||||
|
#else
|
||||||
|
riscv_aplic_configure_irq(QEMU_RV_APLIC_BASE, extirq,
|
||||||
|
RISCV_APLIC_SOURCECFG_SM_EDGE_RISE,
|
||||||
|
riscv_mhartid());
|
||||||
|
#ifdef CONFIG_ARCH_RV_HAVE_IMSIC
|
||||||
|
riscv_imsic_local_eie_enable(extirq);
|
||||||
|
#endif
|
||||||
|
riscv_aplic_enable_irq(QEMU_RV_APLIC_BASE, extirq);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -185,11 +269,20 @@ irqstate_t up_irq_enable(void)
|
||||||
|
|
||||||
/* Enable external interrupts (mie/sie) */
|
/* Enable external interrupts (mie/sie) */
|
||||||
|
|
||||||
SET_CSR(CSR_IE, IE_EIE);
|
up_enable_irq(RISCV_IRQ_EXT);
|
||||||
|
|
||||||
/* Read and enable global interrupts (M/SIE) in m/sstatus */
|
/* Read and enable global interrupts (M/SIE) in m/sstatus */
|
||||||
|
|
||||||
oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE);
|
oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE);
|
||||||
|
|
||||||
|
/* Enable APLIC irq */
|
||||||
|
#ifdef CONFIG_ARCH_RV_HAVE_IMSIC
|
||||||
|
modifyreg32(QEMU_RV_APLIC_BASE + RISCV_APLIC_DOMAINCFG, 0x0,
|
||||||
|
RISCV_APLIC_DOMAINCFG_IE | RISCV_APLIC_DOMAINCFG_DM);
|
||||||
|
#elif defined(CONFIG_ARCH_RV_HAVE_APLIC)
|
||||||
|
modifyreg32(QEMU_RV_APLIC_BASE + RISCV_APLIC_DOMAINCFG, 0x0,
|
||||||
|
RISCV_APLIC_DOMAINCFG_IE);
|
||||||
|
#endif
|
||||||
|
|
||||||
return oldstat;
|
return oldstat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "riscv_internal.h"
|
#include "riscv_internal.h"
|
||||||
|
#include "riscv_aia.h"
|
||||||
#include "hardware/qemu_rv_memorymap.h"
|
#include "hardware/qemu_rv_memorymap.h"
|
||||||
#include "hardware/qemu_rv_plic.h"
|
#include "hardware/qemu_rv_plic.h"
|
||||||
|
|
||||||
|
@ -39,49 +40,102 @@
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_RV32
|
|
||||||
# define RV_IRQ_MASK 27
|
|
||||||
#else
|
|
||||||
# define RV_IRQ_MASK 59
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
#ifdef CONFIG_ARCH_RV_HAVE_IMSIC
|
||||||
* riscv_dispatch_irq
|
static void *riscv_dispatch_irq_ext(uintreg_t irq, uintreg_t *regs)
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void *riscv_dispatch_irq(uintreg_t vector, uintreg_t *regs)
|
|
||||||
{
|
{
|
||||||
int irq = (vector >> RV_IRQ_MASK) | (vector & 0xf);
|
int extirq;
|
||||||
|
|
||||||
/* Firstly, check if the irq is machine external interrupt */
|
while ((extirq = SWAP_CSR(CSR_TOPEI, 0)) != 0)
|
||||||
|
|
||||||
if (RISCV_IRQ_EXT == irq)
|
|
||||||
{
|
{
|
||||||
uintptr_t val = getreg32(QEMU_RV_PLIC_CLAIM);
|
extirq = (extirq >> TOPI_IID_SHIFT) + irq;
|
||||||
|
regs = riscv_doirq(extirq, regs);
|
||||||
/* Add the value to nuttx irq which is offset to the mext */
|
}
|
||||||
|
|
||||||
irq += val;
|
return regs;
|
||||||
}
|
}
|
||||||
|
#elif defined(CONFIG_ARCH_RV_HAVE_APLIC)
|
||||||
/* EXT means no interrupt */
|
static void *riscv_dispatch_irq_ext(uintreg_t irq, uintreg_t *regs)
|
||||||
|
{
|
||||||
if (RISCV_IRQ_EXT != irq)
|
int extirq;
|
||||||
{
|
int hartid = riscv_mhartid();
|
||||||
/* Deliver the IRQ */
|
uintptr_t aplic_base = RISCV_APLIC_IDC(QEMU_RV_APLIC_BASE, hartid) +
|
||||||
|
RISCV_APLIC_IDC_CLAIMI;
|
||||||
regs = riscv_doirq(irq, regs);
|
|
||||||
}
|
while ((extirq = getreg32(aplic_base)) != 0)
|
||||||
|
{
|
||||||
if (RISCV_IRQ_EXT <= irq)
|
extirq = (extirq >> RISCV_APLIC_IDC_TOPI_ID_SHIFT) + irq;
|
||||||
{
|
regs = riscv_doirq(extirq, regs);
|
||||||
/* Then write PLIC_CLAIM to clear pending in PLIC */
|
}
|
||||||
|
|
||||||
putreg32(irq - RISCV_IRQ_EXT, QEMU_RV_PLIC_CLAIM);
|
return regs;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void *riscv_dispatch_irq_ext(uintreg_t irq, uintreg_t *regs)
|
||||||
|
{
|
||||||
|
int extirq;
|
||||||
|
|
||||||
|
while ((extirq = getreg32(QEMU_RV_PLIC_CLAIM)) != 0)
|
||||||
|
{
|
||||||
|
regs = riscv_doirq(irq + extirq, regs);
|
||||||
|
putreg32(extirq, QEMU_RV_PLIC_CLAIM);
|
||||||
|
}
|
||||||
|
|
||||||
|
return regs;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_RV_EXT_AIA
|
||||||
|
static void *riscv_dispatch_async_irq(uintreg_t irq, uintreg_t *regs)
|
||||||
|
{
|
||||||
|
while ((irq = READ_CSR(CSR_TOPI)) != 0)
|
||||||
|
{
|
||||||
|
irq = (irq >> TOPI_IID_SHIFT) + RISCV_IRQ_ASYNC;
|
||||||
|
|
||||||
|
if (RISCV_IRQ_EXT == irq)
|
||||||
|
{
|
||||||
|
regs = riscv_dispatch_irq_ext(irq, regs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regs = riscv_doirq(irq, regs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return regs;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void *riscv_dispatch_async_irq(uintreg_t irq, uintreg_t *regs)
|
||||||
|
{
|
||||||
|
irq += RISCV_IRQ_ASYNC;
|
||||||
|
|
||||||
|
if (irq == RISCV_IRQ_EXT)
|
||||||
|
{
|
||||||
|
regs = riscv_dispatch_irq_ext(irq, regs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regs = riscv_doirq(irq, regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return regs;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *riscv_dispatch_irq(uintreg_t vector, uintreg_t *regs)
|
||||||
|
{
|
||||||
|
int irq = vector & (~RISCV_IRQ_BIT);
|
||||||
|
|
||||||
|
if ((vector & RISCV_IRQ_BIT) != 0)
|
||||||
|
{
|
||||||
|
regs = riscv_dispatch_async_irq(irq, regs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regs = riscv_doirq(irq, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return regs;
|
return regs;
|
||||||
|
|
Loading…
Reference in a new issue