qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: wangjunqiang <wangjunqiang@iscas.ac.cn>
To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org
Cc: liweiwei@iscas.ac.cn, wangjunqiang <wangjunqiang@iscas.ac.cn>,
	bin.meng@windriver.com, Alistair.Francis@wdc.com,
	alapha23@gmail.com, palmer@dabbelt.com
Subject: [RFC PATCH 2/5] hw/intc: Add Nuclei ECLIC device
Date: Fri,  7 May 2021 16:16:51 +0800	[thread overview]
Message-ID: <20210507081654.11056-3-wangjunqiang@iscas.ac.cn> (raw)
In-Reply-To: <20210507081654.11056-1-wangjunqiang@iscas.ac.cn>

This patch provides an implementation of Nuclei ECLIC Device.
Nuclei processor core have been equipped with an Enhanced Core Local
Interrupt Controller (ECLIC), which is optimized based on the RISC-V
standard CLIC, to manage all interrupt sources.

https://doc.nucleisys.com/nuclei_spec/isa/eclic.html
---
 hw/intc/Kconfig                |   3 +
 hw/intc/meson.build            |   1 +
 hw/intc/nuclei_eclic.c         | 437 +++++++++++++++++++++++++++++++++
 include/hw/intc/nuclei_eclic.h | 115 +++++++++
 4 files changed, 556 insertions(+)
 create mode 100644 hw/intc/nuclei_eclic.c
 create mode 100644 include/hw/intc/nuclei_eclic.h

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index f4694088a4..eab30f6ffd 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -73,3 +73,6 @@ config GOLDFISH_PIC
 
 config M68K_IRQC
     bool
+
+config NUCLEI_ECLIC
+    bool
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 1c299039f6..7577ba69d2 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -50,6 +50,7 @@ specific_ss.add(when: 'CONFIG_S390_FLIC_KVM', if_true: files('s390_flic_kvm.c'))
 specific_ss.add(when: 'CONFIG_SH_INTC', if_true: files('sh_intc.c'))
 specific_ss.add(when: 'CONFIG_SIFIVE_CLINT', if_true: files('sifive_clint.c'))
 specific_ss.add(when: 'CONFIG_SIFIVE_PLIC', if_true: files('sifive_plic.c'))
+specific_ss.add(when: 'CONFIG_NUCLEI_ECLIC', if_true: files('nuclei_eclic.c'))
 specific_ss.add(when: 'CONFIG_XICS', if_true: files('xics.c'))
 specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XICS'],
 		if_true: files('xics_kvm.c'))
diff --git a/hw/intc/nuclei_eclic.c b/hw/intc/nuclei_eclic.c
new file mode 100644
index 0000000000..52de83cb1d
--- /dev/null
+++ b/hw/intc/nuclei_eclic.c
@@ -0,0 +1,437 @@
+/*
+ * NUCLEI ECLIC(Enhanced Core Local Interrupt Controller)
+ *
+ * Copyright (c) 2020 Gao ZhiYuan <alapha23@gmail.com>
+ * Copyright (c) 2020-2021 PLCT Lab.All rights reserved.
+ *
+ * This provides a parameterizable interrupt controller based on NucLei's ECLIC.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/sysbus.h"
+#include "hw/pci/msi.h"
+#include "hw/boards.h"
+#include "hw/qdev-properties.h"
+#include "target/riscv/cpu.h"
+#include "sysemu/sysemu.h"
+#include "hw/intc/nuclei_eclic.h"
+#include "qapi/error.h"
+
+#define RISCV_DEBUG_ECLIC 0
+
+static void riscv_cpu_eclic_interrupt(RISCVCPU *cpu, int exccode)
+{
+    CPURISCVState *env = &cpu->env;
+    bool locked = false;
+
+    env->exccode = exccode;
+
+    if (!qemu_mutex_iothread_locked()) {
+        locked = true;
+        qemu_mutex_lock_iothread();
+    }
+
+    if (exccode != -1) {
+        env->irq_pending = true;
+        cpu_interrupt(CPU(cpu), CPU_INTERRUPT_ECLIC);
+    } else {
+        env->irq_pending = false;
+        cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_ECLIC);
+    }
+
+    if (locked) {
+        qemu_mutex_unlock_iothread();
+    }
+}
+
+static int level_compare(NucLeiECLICState *eclic,
+                         ECLICPendingInterrupt *irq1,
+                         ECLICPendingInterrupt *irq2)
+{
+    if (irq1->level == irq2->level) {
+        if (irq1->prio == irq2->prio) {
+            if (irq1->irq >= irq2->irq) {
+                return 0;
+            } else {
+                return 1;
+            }
+        } else if (irq1->prio > irq2->level) {
+            return 0;
+        } else {
+            return 1;
+        }
+    } else if (irq1->level > irq2->level) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+static void nuclei_eclic_next_interrupt(void *eclic_ptr)
+{
+    RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(0));
+    CPURISCVState *env = &cpu->env;
+    NucLeiECLICState *eclic = (NucLeiECLICState *)eclic_ptr;
+    ECLICPendingInterrupt *active;
+    target_ulong mil;
+    int shv;
+
+    QLIST_FOREACH(active, &eclic->pending_list, next)
+    {
+        if (active->enable) {
+            mil = get_field(env->mintstatus, MINTSTATUS_MIL);
+            if (active->level >= eclic->mth && active->level > mil) {
+                shv = eclic->clicintattr[active->irq] & 0x1;
+                eclic->active_count++;
+                riscv_cpu_eclic_interrupt(cpu,
+                                          (active->irq & 0xFFF) | (shv << 12) | (active->level << 13));
+                return;
+            }
+        }
+    }
+}
+
+static void nuclei_eclic_update_intmth(NucLeiECLICState *eclic,
+                                       int irq, int mth)
+{
+    eclic->mth = mth;
+    nuclei_eclic_next_interrupt(eclic);
+}
+
+static void update_eclic_int_info(NucLeiECLICState *eclic, int irq)
+{
+    int level_width = (eclic->cliccfg >> 1) & 0xF;
+    if (level_width > CLICINTCTLBITS) {
+        level_width = CLICINTCTLBITS;
+    }
+    int prio_width = CLICINTCTLBITS - level_width;
+
+    if (level_width == 0) {
+        eclic->clicintlist[irq].level = 255;
+    } else {
+        eclic->clicintlist[irq].level = ((
+                                             (eclic->clicintctl[irq] >> (8 - level_width)) &
+                                             ~((char)0x80 >> (8 - level_width)))
+                                         << (8 - level_width)) |
+                                        (0xff >> level_width);
+    }
+
+    if (prio_width == 0) {
+        eclic->clicintlist[irq].prio = 0;
+    } else {
+        eclic->clicintlist[irq].prio =
+            (eclic->clicintctl[irq] >> (8 - level_width)) &
+            ~(0x80 >> (8 - prio_width));
+    }
+
+    eclic->clicintlist[irq].enable = eclic->clicintie[irq] & 0x1;
+    eclic->clicintlist[irq].trigger = (eclic->clicintattr[irq] >> 1) & 0x3;
+}
+
+static void eclic_remove_pending_list(NucLeiECLICState *eclic, int irq)
+{
+    QLIST_REMOVE(&eclic->clicintlist[irq], next);
+}
+
+static void eclic_insert_pending_list(NucLeiECLICState *eclic, int irq)
+{
+    ECLICPendingInterrupt *node;
+    if (QLIST_EMPTY(&eclic->pending_list)) {
+        QLIST_INSERT_HEAD(&eclic->pending_list, &eclic->clicintlist[irq], next);
+    } else {
+        QLIST_FOREACH(node, &eclic->pending_list, next)
+        {
+            if (level_compare(eclic, node, &eclic->clicintlist[irq])) {
+                QLIST_INSERT_BEFORE(node, &eclic->clicintlist[irq], next);
+                break;
+            } else if (node->next.le_next == NULL) {
+                QLIST_INSERT_AFTER(node, &eclic->clicintlist[irq], next);
+                break;
+            }
+        }
+    }
+}
+
+static void nuclei_eclic_update_intip(NucLeiECLICState *eclic, int irq, int new_intip)
+{
+
+    int old_intip = eclic->clicintlist[irq].sig;
+    int trigger = (eclic->clicintattr[irq] >> 1) & 0x3;
+    if (((trigger == 0) && new_intip) ||
+        ((trigger == 1) && !old_intip && new_intip) ||
+        ((trigger == 3) && old_intip && !new_intip)) {
+        eclic->clicintip[irq] = 1;
+        eclic->clicintlist[irq].sig = new_intip;
+        eclic_insert_pending_list(eclic, irq);
+    } else {
+        if (eclic->clicintip[irq]) {
+            eclic_remove_pending_list(eclic, irq);
+        }
+        eclic->clicintip[irq] = 0;
+        eclic->clicintlist[irq].sig = new_intip;
+    }
+
+    nuclei_eclic_next_interrupt(eclic);
+}
+
+static void nuclei_eclic_update_intie(NucLeiECLICState *eclic,
+                                      int irq, int new_intie)
+{
+    eclic->clicintie[irq] = new_intie;
+    update_eclic_int_info(eclic, irq);
+    nuclei_eclic_next_interrupt(eclic);
+}
+
+static void nuclei_eclic_update_intattr(NucLeiECLICState *eclic,
+                                        int irq, int new_intattr)
+{
+    eclic->clicintattr[irq] = new_intattr;
+    update_eclic_int_info(eclic, irq);
+    nuclei_eclic_next_interrupt(eclic);
+}
+
+static void nuclei_eclic_update_intctl(NucLeiECLICState *eclic,
+                                       int irq, int new_intctl)
+{
+    eclic->clicintctl[irq] = new_intctl;
+    update_eclic_int_info(eclic, irq);
+    nuclei_eclic_next_interrupt(eclic);
+}
+
+qemu_irq nuclei_eclic_get_irq(DeviceState *dev, int irq)
+{
+    NucLeiECLICState *eclic = NUCLEI_ECLIC(dev);
+    return eclic->irqs[irq];
+}
+
+static uint64_t nuclei_eclic_read(void *opaque, hwaddr offset, unsigned size)
+{
+    NucLeiECLICState *eclic = NUCLEI_ECLIC(opaque);
+    uint64_t value = 0;
+    uint32_t id = 0;
+    if (offset >= NUCLEI_ECLIC_REG_CLICINTIP_BASE) {
+        if ((offset - 0x1000) % 4 == 0) {
+            id = (offset - 0x1000) / 4;
+        } else if ((offset - 0x1001) % 4 == 0) {
+            id = (offset - 0x1001) / 4;
+        } else if ((offset - 0x1002) % 4 == 0) {
+            id = (offset - 0x1002) / 4;
+        } else if ((offset - 0x1003) % 4 == 0) {
+            id = (offset - 0x1003) / 4;
+        }
+        offset = offset - 4 * id;
+    }
+
+    switch (offset) {
+    case NUCLEI_ECLIC_REG_CLICCFG:
+        value = eclic->cliccfg & 0xFF;
+        break;
+    case NUCLEI_ECLIC_REG_CLICINFO:
+        value = (CLICINTCTLBITS << 21) & 0xFFFFFFFF;
+        break;
+    case NUCLEI_ECLIC_REG_MTH:
+        value = eclic->mth & 0xFF;
+        break;
+    case NUCLEI_ECLIC_REG_CLICINTIP_BASE:
+        value = eclic->clicintip[id] & 0xFF;
+        break;
+    case NUCLEI_ECLIC_REG_CLICINTIE_BASE:
+        value = eclic->clicintie[id] & 0xFF;
+        break;
+    case NUCLEI_ECLIC_REG_CLICINTATTR_BASE:
+        value = eclic->clicintattr[id] & 0xFF;
+        break;
+    case NUCLEI_ECLIC_REG_CLICINTCTL_BASE:
+        value = eclic->clicintctl[id] & 0xFF;
+        break;
+    default:
+        break;
+    }
+
+    return value;
+}
+
+static void nuclei_eclic_write(void *opaque, hwaddr offset, uint64_t value,
+                               unsigned size)
+{
+    NucLeiECLICState *eclic = NUCLEI_ECLIC(opaque);
+    uint32_t id = 0;
+    if (offset >= NUCLEI_ECLIC_REG_CLICINTIP_BASE) {
+
+        if ((offset - 0x1000) % 4 == 0) {
+            id = (offset - 0x1000) / 4;
+        } else if ((offset - 0x1001) % 4 == 0) {
+            id = (offset - 0x1001) / 4;
+        } else if ((offset - 0x1002) % 4 == 0) {
+            id = (offset - 0x1002) / 4;
+        } else if ((offset - 0x1003) % 4 == 0) {
+            id = (offset - 0x1003) / 4;
+        }
+        offset = offset - 4 * id;
+    }
+    switch (offset) {
+    case NUCLEI_ECLIC_REG_CLICCFG:
+        eclic->cliccfg = value & 0xFF;
+        for (id = 0; id < eclic->num_sources; id++) {
+            update_eclic_int_info(eclic, id);
+        }
+        break;
+    case NUCLEI_ECLIC_REG_MTH:
+        nuclei_eclic_update_intmth(eclic, id, value & 0xFF);
+        break;
+    case NUCLEI_ECLIC_REG_CLICINTIP_BASE:
+        if ((eclic->clicintlist[id].trigger & 0x1) != 0) {
+            if ((eclic->clicintip[id] == 0) && (value & 0x1) == 1) {
+                eclic->clicintip[id] = 1;
+                eclic_insert_pending_list(eclic, id);
+            } else if ((eclic->clicintip[id] == 1) && (value & 0x1) == 0) {
+                eclic->clicintip[id] = 0;
+                eclic_remove_pending_list(eclic, id);
+            }
+        }
+        nuclei_eclic_next_interrupt(eclic);
+        break;
+    case NUCLEI_ECLIC_REG_CLICINTIE_BASE:
+        nuclei_eclic_update_intie(eclic, id, value & 0xFF);
+        break;
+    case NUCLEI_ECLIC_REG_CLICINTATTR_BASE:
+        nuclei_eclic_update_intattr(eclic, id, value & 0xFF);
+        break;
+    case NUCLEI_ECLIC_REG_CLICINTCTL_BASE:
+        nuclei_eclic_update_intctl(eclic, id, value & 0xFF);
+        break;
+    default:
+        break;
+    }
+}
+
+static const MemoryRegionOps nuclei_eclic_ops = {
+    .read = nuclei_eclic_read,
+    .write = nuclei_eclic_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+void riscv_cpu_eclic_clean_pending(void *eclic_ptr, int irq)
+{
+    NucLeiECLICState *eclic = (NucLeiECLICState *)eclic_ptr;
+    if ((eclic->clicintlist[irq].trigger & 0x1) != 0 && irq >= 0) {
+        eclic->clicintip[irq] = 0;
+        eclic_remove_pending_list(eclic, irq);
+    }
+}
+
+void riscv_cpu_eclic_get_next_interrupt(void *eclic_ptr)
+{
+    NucLeiECLICState *eclic = (NucLeiECLICState *)eclic_ptr;
+    nuclei_eclic_next_interrupt(eclic);
+}
+
+
+
+static void nuclei_eclic_irq_request(void *opaque, int id, int new_intip)
+{
+    NucLeiECLICState *eclic = NUCLEI_ECLIC(opaque);
+    nuclei_eclic_update_intip(eclic, id, new_intip);
+}
+
+static void nuclei_eclic_realize(DeviceState *dev, Error **errp)
+{
+    NucLeiECLICState *eclic = NUCLEI_ECLIC(dev);
+    int id;
+
+    memory_region_init_io(&eclic->mmio, OBJECT(dev), &nuclei_eclic_ops, eclic,
+                          TYPE_NUCLEI_ECLIC, eclic->aperture_size);
+    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &eclic->mmio);
+
+    eclic->clicintip = g_new0(uint8_t, eclic->num_sources);
+    eclic->clicintlist = g_new0(ECLICPendingInterrupt, eclic->num_sources);
+    eclic->clicintie = g_new0(uint8_t, eclic->num_sources);
+    eclic->clicintattr = g_new0(uint8_t, eclic->num_sources);
+    eclic->clicintctl = g_new0(uint8_t, eclic->num_sources);
+    eclic->irqs = g_new0(qemu_irq, eclic->num_sources);
+    QLIST_INIT(&eclic->pending_list);
+    for (id = 0; id < eclic->num_sources; id++) {
+        eclic->clicintlist[id].irq = id;
+        update_eclic_int_info(eclic, id);
+    }
+    eclic->active_count = 0;
+
+    /* Init ECLIC IRQ */
+    eclic->irqs[Internal_SysTimerSW_IRQn] =
+        qemu_allocate_irq(nuclei_eclic_irq_request,
+                          eclic, Internal_SysTimerSW_IRQn);
+    eclic->irqs[Internal_SysTimer_IRQn] =
+        qemu_allocate_irq(nuclei_eclic_irq_request,
+                          eclic, Internal_SysTimer_IRQn);
+
+    for (id = Internal_Reserved_Max_IRQn; id < eclic->num_sources; id++) {
+        eclic->irqs[id] = qemu_allocate_irq(nuclei_eclic_irq_request,
+                                            eclic, id);
+    }
+
+    RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(0));
+    cpu->env.eclic = eclic;
+}
+
+static Property nuclei_eclic_properties[] = {
+    DEFINE_PROP_UINT32("aperture-size", NucLeiECLICState, aperture_size, 0),
+    DEFINE_PROP_UINT32("num-sources", NucLeiECLICState, num_sources, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void nuclei_eclic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    device_class_set_props(dc, nuclei_eclic_properties);
+    dc->realize = nuclei_eclic_realize;
+}
+
+static const TypeInfo nuclei_eclic_info = {
+    .name = TYPE_NUCLEI_ECLIC,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(NucLeiECLICState),
+    .class_init = nuclei_eclic_class_init,
+};
+
+static void nuclei_eclic_register_types(void)
+{
+    type_register_static(&nuclei_eclic_info);
+}
+
+type_init(nuclei_eclic_register_types);
+
+void nuclei_eclic_systimer_cb(DeviceState *dev)
+{
+    NucLeiECLICState *eclic = NUCLEI_ECLIC(dev);
+    nuclei_eclic_irq_request(eclic, Internal_SysTimer_IRQn, 1);
+}
+
+DeviceState *nuclei_eclic_create(hwaddr addr,
+                                 uint32_t aperture_size, uint32_t num_sources)
+{
+    DeviceState *dev = qdev_new(TYPE_NUCLEI_ECLIC);
+
+    qdev_prop_set_uint32(dev, "aperture-size", aperture_size);
+    qdev_prop_set_uint32(dev, "num-sources", num_sources);
+
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
+    return dev;
+}
diff --git a/include/hw/intc/nuclei_eclic.h b/include/hw/intc/nuclei_eclic.h
new file mode 100644
index 0000000000..18b25485b9
--- /dev/null
+++ b/include/hw/intc/nuclei_eclic.h
@@ -0,0 +1,115 @@
+/*
+ * NUCLEI ECLIC (Enhanced Core Local Interrupt Controller) interface
+ *
+ * Copyright (c) 2020 Gao ZhiYuan <alapha23@gmail.com>
+ * Copyright (c) 2020-2021 PLCT Lab.All rights reserved.
+ *
+ * This provides a parameterizable interrupt controller based on NucLei's ECLIC.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef HW_NUCLEI_ECLIC_H
+#define HW_NUCLEI_ECLIC_H
+
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+
+#define TYPE_NUCLEI_ECLIC "riscv.nuclei.eclic"
+
+#define INTERRUPT_SOURCE_MIN_ID (18)
+#define INTERRUPT_SOURCE_MAX_ID (4096)
+
+typedef struct NucLeiECLICState NucLeiECLICState;
+DECLARE_INSTANCE_CHECKER(NucLeiECLICState, NUCLEI_ECLIC,
+                         TYPE_NUCLEI_ECLIC)
+
+typedef struct ECLICPendingInterrupt {
+    int irq;
+    int prio;
+    int level;
+    int enable;
+    int trigger;
+    int sig;
+    QLIST_ENTRY(ECLICPendingInterrupt) next;
+} ECLICPendingInterrupt;
+
+#define NUCLEI_ECLIC_REG_CLICCFG          0x0000
+#define NUCLEI_ECLIC_REG_CLICINFO         0x0004
+#define NUCLEI_ECLIC_REG_MTH              0x000b
+#define NUCLEI_ECLIC_REG_CLICINTIP_BASE   0x1000
+#define NUCLEI_ECLIC_REG_CLICINTIE_BASE   0x1001
+#define NUCLEI_ECLIC_REG_CLICINTATTR_BASE 0x1002
+#define NUCLEI_ECLIC_REG_CLICINTCTL_BASE  0x1003
+
+#define CLICINTCTLBITS 0x6
+
+typedef struct NucLeiECLICState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion mmio;
+
+    uint32_t num_sources; /* 4-1024 */
+
+    /* config */
+    uint32_t sources_id;
+    uint8_t cliccfg; /*  nlbits(1~4) */
+    uint32_t clicinfo;
+    uint8_t mth; /* mth(0~7) */
+    uint8_t *clicintip;
+    uint8_t *clicintie;
+    uint8_t *clicintattr; /* shv(0) trig(1~2)*/
+    uint8_t *clicintctl;
+    ECLICPendingInterrupt *clicintlist;
+    uint32_t aperture_size;
+
+    QLIST_HEAD(, ECLICPendingInterrupt)
+    pending_list;
+    size_t active_count;
+
+    /* ECLIC IRQ handlers */
+    qemu_irq *irqs;
+
+} NucLeiECLICState;
+
+enum {
+    Internal_Reserved0_IRQn = 0,     /*!<  Internal reserved */
+    Internal_Reserved1_IRQn = 1,     /*!<  Internal reserved */
+    Internal_Reserved2_IRQn = 2,     /*!<  Internal reserved */
+    Internal_SysTimerSW_IRQn = 3,    /*!<  System Timer SW interrupt */
+    Internal_Reserved3_IRQn = 4,     /*!<  Internal reserved */
+    Internal_Reserved4_IRQn = 5,     /*!<  Internal reserved */
+    Internal_Reserved5_IRQn = 6,     /*!<  Internal reserved */
+    Internal_SysTimer_IRQn = 7,      /*!<  System Timer Interrupt */
+    Internal_Reserved6_IRQn = 8,     /*!<  Internal reserved */
+    Internal_Reserved7_IRQn = 9,     /*!<  Internal reserved */
+    Internal_Reserved8_IRQn = 10,    /*!<  Internal reserved */
+    Internal_Reserved9_IRQn = 11,    /*!<  Internal reserved */
+    Internal_Reserved10_IRQn = 12,   /*!<  Internal reserved */
+    Internal_Reserved11_IRQn = 13,   /*!<  Internal reserved */
+    Internal_Reserved12_IRQn = 14,   /*!<  Internal reserved */
+    Internal_Reserved13_IRQn = 15,   /*!<  Internal reserved */
+    Internal_Reserved14_IRQn = 16,   /*!<  Internal reserved */
+    Internal_BusError_IRQn = 17,     /*!<  Bus Error interrupt */
+    Internal_PerfMon_IRQn = 18,      /*!<  Performance Monitor */
+    Internal_Reserved_Max_IRQn = 19, /*!<  Internal reserved  Max */
+};
+
+DeviceState *nuclei_eclic_create(hwaddr addr,
+                                 uint32_t aperture_size, uint32_t num_sources);
+qemu_irq nuclei_eclic_get_irq(DeviceState *dev, int irq);
+void nuclei_eclic_systimer_cb(DeviceState *dev);
+
+#endif
-- 
2.17.1



  parent reply	other threads:[~2021-05-07 13:25 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-07  8:16 [RFC PATCH 0/5] RISC-V:support Nuclei FPGA Evaluation Kit wangjunqiang
2021-05-07  8:16 ` [RFC PATCH 1/5] target/riscv: Add Nuclei CSR and Update interrupt handling wangjunqiang
2021-05-10  2:17   ` Alistair Francis
2021-05-11  3:14     ` Wang Junqiang
2021-05-11  3:43       ` Alistair Francis
2021-05-11  4:00         ` Wang Junqiang
2021-05-11  4:03           ` Alistair Francis
2021-05-07  8:16 ` wangjunqiang [this message]
2021-05-10  2:20   ` [RFC PATCH 2/5] hw/intc: Add Nuclei ECLIC device Alistair Francis
2021-05-10  2:27     ` Bin Meng
2021-05-10  5:26       ` Bin Meng
2021-05-11  3:18         ` Wang Junqiang
2021-05-07  8:16 ` [RFC PATCH 3/5] hw/intc: Add Nuclei Systimer wangjunqiang
2021-05-07  8:16 ` [RFC PATCH 4/5] hw/char: Add Nuclei Uart wangjunqiang
2021-05-07  8:16 ` [RFC PATCH 5/5] Nuclei FPGA Evaluation Kit MCU Machine wangjunqiang
2021-05-07 13:33 ` [RFC PATCH 0/5] RISC-V:support Nuclei FPGA Evaluation Kit no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210507081654.11056-3-wangjunqiang@iscas.ac.cn \
    --to=wangjunqiang@iscas.ac.cn \
    --cc=Alistair.Francis@wdc.com \
    --cc=alapha23@gmail.com \
    --cc=bin.meng@windriver.com \
    --cc=liweiwei@iscas.ac.cn \
    --cc=palmer@dabbelt.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).