aboutsummaryrefslogtreecommitdiff
path: root/target/openrisc
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-11-27 22:51:27 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-12-15 12:04:30 +0000
commit71b3254dd227f4c5e0a1a4005175a98e0a2cdc19 (patch)
treead123d831762600e09163a4a9e3303ef05af4a3f /target/openrisc
parenteaca43a0f7a3548a527e74b7d14d69eeb31dc339 (diff)
target/openrisc: Move pic_cpu code into CPU object proper
The openrisc code uses an old style of interrupt handling, where a separate standalone set of qemu_irqs invoke a function openrisc_pic_cpu_handler() which signals the interrupt to the CPU proper by directly calling cpu_interrupt() and cpu_reset_interrupt(). Because CPU objects now inherit (indirectly) from TYPE_DEVICE, they can have GPIO input lines themselves, and the neater modern way to implement this is to simply have the CPU object itself provide the input IRQ lines. Create GPIO inputs to the OpenRISC CPU object, and make the only user of cpu_openrisc_pic_init() wire up directly to those instead. This allows us to delete the hw/openrisc/pic_cpu.c file entirely. This fixes a trivial memory leak reported by Coverity of the IRQs allocated in cpu_openrisc_pic_init(). Fixes: Coverity CID 1421934 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Stafford Horne <shorne@gmail.com> Message-id: 20201127225127.14770-4-peter.maydell@linaro.org
Diffstat (limited to 'target/openrisc')
-rw-r--r--target/openrisc/cpu.c32
-rw-r--r--target/openrisc/cpu.h1
2 files changed, 32 insertions, 1 deletions
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 5528c0918f..b0bdfbe4fe 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -65,6 +65,34 @@ static void openrisc_cpu_reset(DeviceState *dev)
#endif
}
+#ifndef CONFIG_USER_ONLY
+static void openrisc_cpu_set_irq(void *opaque, int irq, int level)
+{
+ OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
+ CPUState *cs = CPU(cpu);
+ uint32_t irq_bit;
+
+ if (irq > 31 || irq < 0) {
+ return;
+ }
+
+ irq_bit = 1U << irq;
+
+ if (level) {
+ cpu->env.picsr |= irq_bit;
+ } else {
+ cpu->env.picsr &= ~irq_bit;
+ }
+
+ if (cpu->env.picsr & cpu->env.picmr) {
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+ } else {
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+ cpu->env.picsr = 0;
+ }
+}
+#endif
+
static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -88,6 +116,10 @@ static void openrisc_cpu_initfn(Object *obj)
OpenRISCCPU *cpu = OPENRISC_CPU(obj);
cpu_set_cpustate_pointers(cpu);
+
+#ifndef CONFIG_USER_ONLY
+ qdev_init_gpio_in_named(DEVICE(cpu), openrisc_cpu_set_irq, "IRQ", NR_IRQS);
+#endif
}
/* CPU models */
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index bd42faf144..82cbaeb4f8 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -293,7 +293,6 @@ typedef struct CPUOpenRISCState {
uint32_t picmr; /* Interrupt mask register */
uint32_t picsr; /* Interrupt contrl register*/
#endif
- void *irq[32]; /* Interrupt irq input */
} CPUOpenRISCState;
/**