aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--hw/intc/meson.build1
-rw-r--r--hw/intc/nios2_iic.c95
-rw-r--r--hw/nios2/10m50_devboard.c13
-rw-r--r--hw/nios2/cpu_pic.c31
-rw-r--r--target/nios2/cpu.c30
-rw-r--r--target/nios2/cpu.h1
7 files changed, 32 insertions, 140 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 062074e47c..99293a5e02 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -259,7 +259,6 @@ M: Marek Vasut <marex@denx.de>
S: Maintained
F: target/nios2/
F: hw/nios2/
-F: hw/intc/nios2_iic.c
F: disas/nios2.c
F: default-configs/nios2-softmmu.mak
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 3f82cc230a..7c3e9daf58 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -37,7 +37,6 @@ specific_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_plic.c'))
specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: files('loongson_liointc.c'))
specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
-specific_ss.add(when: 'CONFIG_NIOS2', if_true: files('nios2_iic.c'))
specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_intc.c'))
specific_ss.add(when: 'CONFIG_OMPIC', if_true: files('ompic.c'))
specific_ss.add(when: 'CONFIG_OPENPIC_KVM', if_true: files('openpic_kvm.c'))
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
deleted file mode 100644
index 216db67059..0000000000
--- a/hw/intc/nios2_iic.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * QEMU Altera Internal Interrupt Controller.
- *
- * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see
- * <http://www.gnu.org/licenses/lgpl-2.1.html>
- */
-
-#include "qemu/osdep.h"
-#include "qemu/module.h"
-#include "qapi/error.h"
-
-#include "hw/irq.h"
-#include "hw/sysbus.h"
-#include "cpu.h"
-#include "qom/object.h"
-
-#define TYPE_ALTERA_IIC "altera,iic"
-OBJECT_DECLARE_SIMPLE_TYPE(AlteraIIC, ALTERA_IIC)
-
-struct AlteraIIC {
- SysBusDevice parent_obj;
- void *cpu;
- qemu_irq parent_irq;
-};
-
-static void update_irq(AlteraIIC *pv)
-{
- CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
-
- qemu_set_irq(pv->parent_irq,
- env->regs[CR_IPENDING] & env->regs[CR_IENABLE]);
-}
-
-static void irq_handler(void *opaque, int irq, int level)
-{
- AlteraIIC *pv = opaque;
- CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
-
- env->regs[CR_IPENDING] &= ~(1 << irq);
- env->regs[CR_IPENDING] |= !!level << irq;
-
- update_irq(pv);
-}
-
-static void altera_iic_init(Object *obj)
-{
- AlteraIIC *pv = ALTERA_IIC(obj);
-
- qdev_init_gpio_in(DEVICE(pv), irq_handler, 32);
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &pv->parent_irq);
-}
-
-static void altera_iic_realize(DeviceState *dev, Error **errp)
-{
- struct AlteraIIC *pv = ALTERA_IIC(dev);
-
- pv->cpu = object_property_get_link(OBJECT(dev), "cpu", &error_abort);
-}
-
-static void altera_iic_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- /* Reason: needs to be wired up, e.g. by nios2_10m50_ghrd_init() */
- dc->user_creatable = false;
- dc->realize = altera_iic_realize;
-}
-
-static TypeInfo altera_iic_info = {
- .name = TYPE_ALTERA_IIC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(AlteraIIC),
- .instance_init = altera_iic_init,
- .class_init = altera_iic_class_init,
-};
-
-static void altera_iic_register(void)
-{
- type_register_static(&altera_iic_info);
-}
-
-type_init(altera_iic_register)
diff --git a/hw/nios2/10m50_devboard.c b/hw/nios2/10m50_devboard.c
index 5c13b74306..a14fc31e86 100644
--- a/hw/nios2/10m50_devboard.c
+++ b/hw/nios2/10m50_devboard.c
@@ -52,7 +52,7 @@ static void nios2_10m50_ghrd_init(MachineState *machine)
ram_addr_t tcm_size = 0x1000; /* 1 kiB, but QEMU limit is 4 kiB */
ram_addr_t ram_base = 0x08000000;
ram_addr_t ram_size = 0x08000000;
- qemu_irq *cpu_irq, irq[32];
+ qemu_irq irq[32];
int i;
/* Physical TCM (tb_ram_1k) with alias at 0xc0000000 */
@@ -75,17 +75,8 @@ static void nios2_10m50_ghrd_init(MachineState *machine)
/* Create CPU -- FIXME */
cpu = NIOS2_CPU(cpu_create(TYPE_NIOS2_CPU));
-
- /* Register: CPU interrupt controller (PIC) */
- cpu_irq = nios2_cpu_pic_init(cpu);
-
- /* Register: Internal Interrupt Controller (IIC) */
- dev = qdev_new("altera,iic");
- object_property_add_const_link(OBJECT(dev), "cpu", OBJECT(cpu));
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
for (i = 0; i < 32; i++) {
- irq[i] = qdev_get_gpio_in(dev, i);
+ irq[i] = qdev_get_gpio_in_named(DEVICE(cpu), "IRQ", i);
}
/* Register: Altera 16550 UART */
diff --git a/hw/nios2/cpu_pic.c b/hw/nios2/cpu_pic.c
index 5ea7e52ab8..3fb621c5c8 100644
--- a/hw/nios2/cpu_pic.c
+++ b/hw/nios2/cpu_pic.c
@@ -26,32 +26,6 @@
#include "boot.h"
-static void nios2_pic_cpu_handler(void *opaque, int irq, int level)
-{
- Nios2CPU *cpu = opaque;
- CPUNios2State *env = &cpu->env;
- CPUState *cs = CPU(cpu);
- int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD;
-
- if (type == CPU_INTERRUPT_HARD) {
- env->irq_pending = level;
-
- if (level && (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
- env->irq_pending = 0;
- cpu_interrupt(cs, type);
- } else if (!level) {
- env->irq_pending = 0;
- cpu_reset_interrupt(cs, type);
- }
- } else {
- if (level) {
- cpu_interrupt(cs, type);
- } else {
- cpu_reset_interrupt(cs, type);
- }
- }
-}
-
void nios2_check_interrupts(CPUNios2State *env)
{
if (env->irq_pending &&
@@ -60,8 +34,3 @@ void nios2_check_interrupts(CPUNios2State *env)
cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HARD);
}
}
-
-qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu)
-{
- return qemu_allocate_irqs(nios2_pic_cpu_handler, cpu, 2);
-}
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 8f7011fcb9..52ebda89ca 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -64,6 +64,27 @@ static void nios2_cpu_reset(DeviceState *dev)
#endif
}
+#ifndef CONFIG_USER_ONLY
+static void nios2_cpu_set_irq(void *opaque, int irq, int level)
+{
+ Nios2CPU *cpu = opaque;
+ CPUNios2State *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+
+ env->regs[CR_IPENDING] &= ~(1 << irq);
+ env->regs[CR_IPENDING] |= !!level << irq;
+
+ env->irq_pending = env->regs[CR_IPENDING] & env->regs[CR_IENABLE];
+
+ if (env->irq_pending && (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
+ env->irq_pending = 0;
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+ } else if (!env->irq_pending) {
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+ }
+}
+#endif
+
static void nios2_cpu_initfn(Object *obj)
{
Nios2CPU *cpu = NIOS2_CPU(obj);
@@ -72,6 +93,15 @@ static void nios2_cpu_initfn(Object *obj)
#if !defined(CONFIG_USER_ONLY)
mmu_init(&cpu->env);
+
+ /*
+ * These interrupt lines model the IIC (internal interrupt
+ * controller). QEMU does not currently support the EIC
+ * (external interrupt controller) -- if we did it would be
+ * a separate device in hw/intc with a custom interface to
+ * the CPU, and boards using it would not wire up these IRQ lines.
+ */
+ qdev_init_gpio_in_named(DEVICE(cpu), nios2_cpu_set_irq, "IRQ", 32);
#endif
}
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index 86bbe1d867..b7efb54ba7 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -201,7 +201,6 @@ void nios2_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr);
-qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu);
void nios2_check_interrupts(CPUNios2State *env);
void do_nios2_semihosting(CPUNios2State *env);