diff mbox series

[RFC,1/2] target/alpha: Expose TMR and SMP IRQ lines via QDev

Message ID 20240220192625.17944-2-philmd@linaro.org
State New
Headers show
Series hw: Replace cpu_interrupt() calls by qemu_irq(QDev GPIO) | expand

Commit Message

Philippe Mathieu-Daudé Feb. 20, 2024, 7:26 p.m. UTC
In order to remove calls to cpu_interrupt() from hw/ code,
expose the TMR and SMP interrupts via QDev as named GPIOs.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/alpha/cpu.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Comments

Peter Maydell Feb. 23, 2024, 6:58 p.m. UTC | #1
On Tue, 20 Feb 2024 at 19:28, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>
> In order to remove calls to cpu_interrupt() from hw/ code,
> expose the TMR and SMP interrupts via QDev as named GPIOs.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>  target/alpha/cpu.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>
> diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
> index bf70173a25..619cd54593 100644
> --- a/target/alpha/cpu.c
> +++ b/target/alpha/cpu.c
> @@ -25,6 +25,31 @@
>  #include "cpu.h"
>  #include "exec/exec-all.h"
>
> +#ifndef CONFIG_USER_ONLY
> +static void alpha_cpu_tmr_irq(void *opaque, int irq, int level)
> +{
> +    DeviceState *dev = opaque;
> +    CPUState *cs = CPU(dev);
> +
> +    if (level) {
> +        cs->interrupt_request |= CPU_INTERRUPT_TIMER;
> +    } else {
> +        cs->interrupt_request &= ~CPU_INTERRUPT_TIMER;
> +    }

These should call cpu_interrupt(), because otherwise you
lose the logic that does a cpu-kick if one CPU triggers
an interrupt on another. (Also you lose the handling for
non-TCG accelerators, not that that's an issue for Alpha.)
Compare arm_cpu_set_irq().

thanks
-- PMM
diff mbox series

Patch

diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index bf70173a25..619cd54593 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -25,6 +25,31 @@ 
 #include "cpu.h"
 #include "exec/exec-all.h"
 
+#ifndef CONFIG_USER_ONLY
+static void alpha_cpu_tmr_irq(void *opaque, int irq, int level)
+{
+    DeviceState *dev = opaque;
+    CPUState *cs = CPU(dev);
+
+    if (level) {
+        cs->interrupt_request |= CPU_INTERRUPT_TIMER;
+    } else {
+        cs->interrupt_request &= ~CPU_INTERRUPT_TIMER;
+    }
+}
+
+static void alpha_cpu_smp_irq(void *opaque, int irq, int level)
+{
+    DeviceState *dev = opaque;
+    CPUState *cs = CPU(dev);
+
+    if (level) {
+        cs->interrupt_request |= CPU_INTERRUPT_SMP;
+    } else {
+        cs->interrupt_request &= ~CPU_INTERRUPT_SMP;
+    }
+}
+#endif
 
 static void alpha_cpu_set_pc(CPUState *cs, vaddr value)
 {
@@ -89,6 +114,11 @@  static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
 
     qemu_init_vcpu(cs);
 
+#ifndef CONFIG_USER_ONLY
+    qdev_init_gpio_in_named(dev, alpha_cpu_tmr_irq, "TMR", 1);
+    qdev_init_gpio_in_named(dev, alpha_cpu_smp_irq, "SMP", 1);
+#endif
+
     acc->parent_realize(dev, errp);
 }