All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object
@ 2020-11-27 22:51 Peter Maydell
  2020-11-27 22:51 ` [PATCH 1/3] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs Peter Maydell
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Peter Maydell @ 2020-11-27 22:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stafford Horne, Jia Liu

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.

The main aim of this patch series is to make that refactoring,
which fixes a trivial memory leak reported by Coverity of the IRQs
allocated in cpu_openrisc_pic_init(), and removes one callsite of
the qemu_allocate_irqs() function.

Patch 1 is a minor bugfix noticed along the way; patch 2 is
there to make the change in patch 3 simpler and clearer to review.

Tested with 'make check' and 'make check-acceptance'.

thanks
-- PMM

Peter Maydell (3):
  hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to
    multiple CPUs
  hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y"
  target/openrisc: Move pic_cpu code into CPU object proper

 target/openrisc/cpu.h      |  1 -
 hw/openrisc/openrisc_sim.c | 46 +++++++++++++++++-----------
 hw/openrisc/pic_cpu.c      | 61 --------------------------------------
 target/openrisc/cpu.c      | 32 ++++++++++++++++++++
 hw/openrisc/Kconfig        |  1 +
 hw/openrisc/meson.build    |  2 +-
 6 files changed, 63 insertions(+), 80 deletions(-)
 delete mode 100644 hw/openrisc/pic_cpu.c

-- 
2.20.1



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/3] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs
  2020-11-27 22:51 [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object Peter Maydell
@ 2020-11-27 22:51 ` Peter Maydell
  2020-11-29 11:59   ` Stafford Horne
  2020-11-27 22:51 ` [PATCH 2/3] hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y" Peter Maydell
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2020-11-27 22:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stafford Horne, Jia Liu

openrisc_sim_net_init() attempts to connect the IRQ line from the
ethernet device to both CPUs in an SMP configuration by simply caling
sysbus_connect_irq() for it twice.  This doesn't work, because the
second connection simply overrides the first.

Fix this by creating a TYPE_SPLIT_IRQ to split the IRQ in the SMP
case.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/openrisc/openrisc_sim.c | 13 +++++++++++--
 hw/openrisc/Kconfig        |  1 +
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index d752282e675..a8adf6b70d7 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -34,6 +34,7 @@
 #include "hw/sysbus.h"
 #include "sysemu/qtest.h"
 #include "sysemu/reset.h"
+#include "hw/core/split-irq.h"
 
 #define KERNEL_LOAD_ADDR 0x100
 
@@ -64,8 +65,16 @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
 
     s = SYS_BUS_DEVICE(dev);
     sysbus_realize_and_unref(s, &error_fatal);
-    for (i = 0; i < num_cpus; i++) {
-        sysbus_connect_irq(s, 0, cpu_irqs[i][irq_pin]);
+    if (num_cpus > 1) {
+        DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
+        qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
+        qdev_realize_and_unref(splitter, NULL, &error_fatal);
+        for (i = 0; i < num_cpus; i++) {
+            qdev_connect_gpio_out(splitter, i, cpu_irqs[i][irq_pin]);
+        }
+        sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
+    } else {
+        sysbus_connect_irq(s, 0, cpu_irqs[0][irq_pin]);
     }
     sysbus_mmio_map(s, 0, base);
     sysbus_mmio_map(s, 1, descriptors);
diff --git a/hw/openrisc/Kconfig b/hw/openrisc/Kconfig
index 6c1e86884e2..8f284f3ba04 100644
--- a/hw/openrisc/Kconfig
+++ b/hw/openrisc/Kconfig
@@ -3,3 +3,4 @@ config OR1K_SIM
     select SERIAL
     select OPENCORES_ETH
     select OMPIC
+    select SPLIT_IRQ
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/3] hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y"
  2020-11-27 22:51 [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object Peter Maydell
  2020-11-27 22:51 ` [PATCH 1/3] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs Peter Maydell
@ 2020-11-27 22:51 ` Peter Maydell
  2020-11-29 12:01   ` Stafford Horne
  2020-11-27 22:51 ` [PATCH 3/3] target/openrisc: Move pic_cpu code into CPU object proper Peter Maydell
  2020-12-11 13:57 ` [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object Peter Maydell
  3 siblings, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2020-11-27 22:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stafford Horne, Jia Liu

We're about to refactor the OpenRISC pic_cpu code in a way that means
that just grabbing the whole qemu_irq[] array of inbound IRQs for a
CPU won't be possible any more.  Abstract out a function for "return
the qemu_irq for IRQ x input of CPU y" so we can more easily replace
the implementation.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/openrisc/openrisc_sim.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index a8adf6b70d7..75ba0f47444 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -52,8 +52,13 @@ static void main_cpu_reset(void *opaque)
     cpu_set_pc(cs, boot_info.bootstrap_pc);
 }
 
+static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
+{
+    return cpus[cpunum]->env.irq[irq_pin];
+}
+
 static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
-                                  int num_cpus, qemu_irq **cpu_irqs,
+                                  int num_cpus, OpenRISCCPU *cpus[],
                                   int irq_pin, NICInfo *nd)
 {
     DeviceState *dev;
@@ -70,18 +75,18 @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
         qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
         qdev_realize_and_unref(splitter, NULL, &error_fatal);
         for (i = 0; i < num_cpus; i++) {
-            qdev_connect_gpio_out(splitter, i, cpu_irqs[i][irq_pin]);
+            qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
         }
         sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
     } else {
-        sysbus_connect_irq(s, 0, cpu_irqs[0][irq_pin]);
+        sysbus_connect_irq(s, 0, get_cpu_irq(cpus, 0, irq_pin));
     }
     sysbus_mmio_map(s, 0, base);
     sysbus_mmio_map(s, 1, descriptors);
 }
 
 static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
-                                    qemu_irq **cpu_irqs, int irq_pin)
+                                    OpenRISCCPU *cpus[], int irq_pin)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -93,7 +98,7 @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
     s = SYS_BUS_DEVICE(dev);
     sysbus_realize_and_unref(s, &error_fatal);
     for (i = 0; i < num_cpus; i++) {
-        sysbus_connect_irq(s, i, cpu_irqs[i][irq_pin]);
+        sysbus_connect_irq(s, i, get_cpu_irq(cpus, i, irq_pin));
     }
     sysbus_mmio_map(s, 0, base);
 }
@@ -136,26 +141,24 @@ static void openrisc_sim_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
     const char *kernel_filename = machine->kernel_filename;
-    OpenRISCCPU *cpu = NULL;
+    OpenRISCCPU *cpus[2] = {};
     MemoryRegion *ram;
-    qemu_irq *cpu_irqs[2];
     qemu_irq serial_irq;
     int n;
     unsigned int smp_cpus = machine->smp.cpus;
 
     assert(smp_cpus >= 1 && smp_cpus <= 2);
     for (n = 0; n < smp_cpus; n++) {
-        cpu = OPENRISC_CPU(cpu_create(machine->cpu_type));
-        if (cpu == NULL) {
+        cpus[n] = OPENRISC_CPU(cpu_create(machine->cpu_type));
+        if (cpus[n] == NULL) {
             fprintf(stderr, "Unable to find CPU definition!\n");
             exit(1);
         }
-        cpu_openrisc_pic_init(cpu);
-        cpu_irqs[n] = (qemu_irq *) cpu->env.irq;
+        cpu_openrisc_pic_init(cpus[n]);
 
-        cpu_openrisc_clock_init(cpu);
+        cpu_openrisc_clock_init(cpus[n]);
 
-        qemu_register_reset(main_cpu_reset, cpu);
+        qemu_register_reset(main_cpu_reset, cpus[n]);
     }
 
     ram = g_malloc(sizeof(*ram));
@@ -164,15 +167,16 @@ static void openrisc_sim_init(MachineState *machine)
 
     if (nd_table[0].used) {
         openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
-                              cpu_irqs, 4, nd_table);
+                              cpus, 4, nd_table);
     }
 
     if (smp_cpus > 1) {
-        openrisc_sim_ompic_init(0x98000000, smp_cpus, cpu_irqs, 1);
+        openrisc_sim_ompic_init(0x98000000, smp_cpus, cpus, 1);
 
-        serial_irq = qemu_irq_split(cpu_irqs[0][2], cpu_irqs[1][2]);
+        serial_irq = qemu_irq_split(get_cpu_irq(cpus, 0, 2),
+                                    get_cpu_irq(cpus, 1, 2));
     } else {
-        serial_irq = cpu_irqs[0][2];
+        serial_irq = get_cpu_irq(cpus, 0, 2);
     }
 
     serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/3] target/openrisc: Move pic_cpu code into CPU object proper
  2020-11-27 22:51 [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object Peter Maydell
  2020-11-27 22:51 ` [PATCH 1/3] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs Peter Maydell
  2020-11-27 22:51 ` [PATCH 2/3] hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y" Peter Maydell
@ 2020-11-27 22:51 ` Peter Maydell
  2020-11-29 12:03   ` Stafford Horne
  2020-12-11 13:57 ` [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object Peter Maydell
  3 siblings, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2020-11-27 22:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stafford Horne, Jia Liu

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>
---
 target/openrisc/cpu.h      |  1 -
 hw/openrisc/openrisc_sim.c |  3 +-
 hw/openrisc/pic_cpu.c      | 61 --------------------------------------
 target/openrisc/cpu.c      | 32 ++++++++++++++++++++
 hw/openrisc/meson.build    |  2 +-
 5 files changed, 34 insertions(+), 65 deletions(-)
 delete mode 100644 hw/openrisc/pic_cpu.c

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index bd42faf144f..82cbaeb4f84 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;
 
 /**
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 75ba0f47444..39f1d344ae9 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -54,7 +54,7 @@ static void main_cpu_reset(void *opaque)
 
 static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
 {
-    return cpus[cpunum]->env.irq[irq_pin];
+    return qdev_get_gpio_in_named(DEVICE(cpus[cpunum]), "IRQ", irq_pin);
 }
 
 static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
@@ -154,7 +154,6 @@ static void openrisc_sim_init(MachineState *machine)
             fprintf(stderr, "Unable to find CPU definition!\n");
             exit(1);
         }
-        cpu_openrisc_pic_init(cpus[n]);
 
         cpu_openrisc_clock_init(cpus[n]);
 
diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c
deleted file mode 100644
index 36f93508309..00000000000
--- a/hw/openrisc/pic_cpu.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * OpenRISC Programmable Interrupt Controller support.
- *
- * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
- *                         Feng Gao <gf91597@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/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "cpu.h"
-
-/* OpenRISC pic handler */
-static void openrisc_pic_cpu_handler(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;
-    }
-}
-
-void cpu_openrisc_pic_init(OpenRISCCPU *cpu)
-{
-    int i;
-    qemu_irq *qi;
-    qi = qemu_allocate_irqs(openrisc_pic_cpu_handler, cpu, NR_IRQS);
-
-    for (i = 0; i < NR_IRQS; i++) {
-        cpu->env.irq[i] = qi[i];
-    }
-}
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 5528c0918f4..b0bdfbe4fe2 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/hw/openrisc/meson.build b/hw/openrisc/meson.build
index 57c42558e18..947f63ee087 100644
--- a/hw/openrisc/meson.build
+++ b/hw/openrisc/meson.build
@@ -1,5 +1,5 @@
 openrisc_ss = ss.source_set()
-openrisc_ss.add(files('pic_cpu.c', 'cputimer.c'))
+openrisc_ss.add(files('cputimer.c'))
 openrisc_ss.add(when: 'CONFIG_OR1K_SIM', if_true: files('openrisc_sim.c'))
 
 hw_arch += {'openrisc': openrisc_ss}
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/3] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs
  2020-11-27 22:51 ` [PATCH 1/3] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs Peter Maydell
@ 2020-11-29 11:59   ` Stafford Horne
  0 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2020-11-29 11:59 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Jia Liu

On Fri, Nov 27, 2020 at 10:51:25PM +0000, Peter Maydell wrote:
> openrisc_sim_net_init() attempts to connect the IRQ line from the
> ethernet device to both CPUs in an SMP configuration by simply caling
> sysbus_connect_irq() for it twice.  This doesn't work, because the
> second connection simply overrides the first.
> 
> Fix this by creating a TYPE_SPLIT_IRQ to split the IRQ in the SMP
> case.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/openrisc/openrisc_sim.c | 13 +++++++++++--
>  hw/openrisc/Kconfig        |  1 +
>  2 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> index d752282e675..a8adf6b70d7 100644
> --- a/hw/openrisc/openrisc_sim.c
> +++ b/hw/openrisc/openrisc_sim.c
> @@ -34,6 +34,7 @@
>  #include "hw/sysbus.h"
>  #include "sysemu/qtest.h"
>  #include "sysemu/reset.h"
> +#include "hw/core/split-irq.h"
>  
>  #define KERNEL_LOAD_ADDR 0x100
>  
> @@ -64,8 +65,16 @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
>  
>      s = SYS_BUS_DEVICE(dev);
>      sysbus_realize_and_unref(s, &error_fatal);
> -    for (i = 0; i < num_cpus; i++) {
> -        sysbus_connect_irq(s, 0, cpu_irqs[i][irq_pin]);
> +    if (num_cpus > 1) {
> +        DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
> +        qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
> +        qdev_realize_and_unref(splitter, NULL, &error_fatal);
> +        for (i = 0; i < num_cpus; i++) {
> +            qdev_connect_gpio_out(splitter, i, cpu_irqs[i][irq_pin]);
> +        }
> +        sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
> +    } else {
> +        sysbus_connect_irq(s, 0, cpu_irqs[0][irq_pin]);
>      }
>      sysbus_mmio_map(s, 0, base);
>      sysbus_mmio_map(s, 1, descriptors);
> diff --git a/hw/openrisc/Kconfig b/hw/openrisc/Kconfig
> index 6c1e86884e2..8f284f3ba04 100644
> --- a/hw/openrisc/Kconfig
> +++ b/hw/openrisc/Kconfig
> @@ -3,3 +3,4 @@ config OR1K_SIM
>      select SERIAL
>      select OPENCORES_ETH
>      select OMPIC
> +    select SPLIT_IRQ
> -- 
> 2.20.1


This looks good to me, I don't think I ever tested networking with SMP.  Thanks
for the fix!

Reviewed-by: Stafford Horne <shorne@gmail.com>

Can you help merge the patch? I am not working a queue right now.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3] hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y"
  2020-11-27 22:51 ` [PATCH 2/3] hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y" Peter Maydell
@ 2020-11-29 12:01   ` Stafford Horne
  0 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2020-11-29 12:01 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Jia Liu

On Fri, Nov 27, 2020 at 10:51:26PM +0000, Peter Maydell wrote:
> We're about to refactor the OpenRISC pic_cpu code in a way that means
> that just grabbing the whole qemu_irq[] array of inbound IRQs for a
> CPU won't be possible any more.  Abstract out a function for "return
> the qemu_irq for IRQ x input of CPU y" so we can more easily replace
> the implementation.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/openrisc/openrisc_sim.c | 38 +++++++++++++++++++++-----------------
>  1 file changed, 21 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> index a8adf6b70d7..75ba0f47444 100644
> --- a/hw/openrisc/openrisc_sim.c
> +++ b/hw/openrisc/openrisc_sim.c
> @@ -52,8 +52,13 @@ static void main_cpu_reset(void *opaque)
>      cpu_set_pc(cs, boot_info.bootstrap_pc);
>  }
>  
> +static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
> +{
> +    return cpus[cpunum]->env.irq[irq_pin];
> +}
> +
>  static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
> -                                  int num_cpus, qemu_irq **cpu_irqs,
> +                                  int num_cpus, OpenRISCCPU *cpus[],
>                                    int irq_pin, NICInfo *nd)
>  {
>      DeviceState *dev;
> @@ -70,18 +75,18 @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
>          qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
>          qdev_realize_and_unref(splitter, NULL, &error_fatal);
>          for (i = 0; i < num_cpus; i++) {
> -            qdev_connect_gpio_out(splitter, i, cpu_irqs[i][irq_pin]);
> +            qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
>          }
>          sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
>      } else {
> -        sysbus_connect_irq(s, 0, cpu_irqs[0][irq_pin]);
> +        sysbus_connect_irq(s, 0, get_cpu_irq(cpus, 0, irq_pin));
>      }
>      sysbus_mmio_map(s, 0, base);
>      sysbus_mmio_map(s, 1, descriptors);
>  }
>  
>  static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
> -                                    qemu_irq **cpu_irqs, int irq_pin)
> +                                    OpenRISCCPU *cpus[], int irq_pin)
>  {
>      DeviceState *dev;
>      SysBusDevice *s;
> @@ -93,7 +98,7 @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
>      s = SYS_BUS_DEVICE(dev);
>      sysbus_realize_and_unref(s, &error_fatal);
>      for (i = 0; i < num_cpus; i++) {
> -        sysbus_connect_irq(s, i, cpu_irqs[i][irq_pin]);
> +        sysbus_connect_irq(s, i, get_cpu_irq(cpus, i, irq_pin));
>      }
>      sysbus_mmio_map(s, 0, base);
>  }
> @@ -136,26 +141,24 @@ static void openrisc_sim_init(MachineState *machine)
>  {
>      ram_addr_t ram_size = machine->ram_size;
>      const char *kernel_filename = machine->kernel_filename;
> -    OpenRISCCPU *cpu = NULL;
> +    OpenRISCCPU *cpus[2] = {};
>      MemoryRegion *ram;
> -    qemu_irq *cpu_irqs[2];
>      qemu_irq serial_irq;
>      int n;
>      unsigned int smp_cpus = machine->smp.cpus;
>  
>      assert(smp_cpus >= 1 && smp_cpus <= 2);
>      for (n = 0; n < smp_cpus; n++) {
> -        cpu = OPENRISC_CPU(cpu_create(machine->cpu_type));
> -        if (cpu == NULL) {
> +        cpus[n] = OPENRISC_CPU(cpu_create(machine->cpu_type));
> +        if (cpus[n] == NULL) {
>              fprintf(stderr, "Unable to find CPU definition!\n");
>              exit(1);
>          }
> -        cpu_openrisc_pic_init(cpu);
> -        cpu_irqs[n] = (qemu_irq *) cpu->env.irq;
> +        cpu_openrisc_pic_init(cpus[n]);
>  
> -        cpu_openrisc_clock_init(cpu);
> +        cpu_openrisc_clock_init(cpus[n]);
>  
> -        qemu_register_reset(main_cpu_reset, cpu);
> +        qemu_register_reset(main_cpu_reset, cpus[n]);
>      }
>  
>      ram = g_malloc(sizeof(*ram));
> @@ -164,15 +167,16 @@ static void openrisc_sim_init(MachineState *machine)
>  
>      if (nd_table[0].used) {
>          openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
> -                              cpu_irqs, 4, nd_table);
> +                              cpus, 4, nd_table);
>      }
>  
>      if (smp_cpus > 1) {
> -        openrisc_sim_ompic_init(0x98000000, smp_cpus, cpu_irqs, 1);
> +        openrisc_sim_ompic_init(0x98000000, smp_cpus, cpus, 1);
>  
> -        serial_irq = qemu_irq_split(cpu_irqs[0][2], cpu_irqs[1][2]);
> +        serial_irq = qemu_irq_split(get_cpu_irq(cpus, 0, 2),
> +                                    get_cpu_irq(cpus, 1, 2));
>      } else {
> -        serial_irq = cpu_irqs[0][2];
> +        serial_irq = get_cpu_irq(cpus, 0, 2);
>      }
>  
>      serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
> -- 
> 2.20.1

This looks good to me.

Reviewed-by: Stafford Horne <shorne@gmail.com>

Again, if there is no problem please feel free to merge.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] target/openrisc: Move pic_cpu code into CPU object proper
  2020-11-27 22:51 ` [PATCH 3/3] target/openrisc: Move pic_cpu code into CPU object proper Peter Maydell
@ 2020-11-29 12:03   ` Stafford Horne
  0 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2020-11-29 12:03 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Jia Liu

On Fri, Nov 27, 2020 at 10:51:27PM +0000, Peter Maydell wrote:
> 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>
> ---
>  target/openrisc/cpu.h      |  1 -
>  hw/openrisc/openrisc_sim.c |  3 +-
>  hw/openrisc/pic_cpu.c      | 61 --------------------------------------
>  target/openrisc/cpu.c      | 32 ++++++++++++++++++++
>  hw/openrisc/meson.build    |  2 +-
>  5 files changed, 34 insertions(+), 65 deletions(-)
>  delete mode 100644 hw/openrisc/pic_cpu.c
> 
> diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
> index bd42faf144f..82cbaeb4f84 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;
>  
>  /**
> diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> index 75ba0f47444..39f1d344ae9 100644
> --- a/hw/openrisc/openrisc_sim.c
> +++ b/hw/openrisc/openrisc_sim.c
> @@ -54,7 +54,7 @@ static void main_cpu_reset(void *opaque)
>  
>  static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
>  {
> -    return cpus[cpunum]->env.irq[irq_pin];
> +    return qdev_get_gpio_in_named(DEVICE(cpus[cpunum]), "IRQ", irq_pin);
>  }
>  
>  static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
> @@ -154,7 +154,6 @@ static void openrisc_sim_init(MachineState *machine)
>              fprintf(stderr, "Unable to find CPU definition!\n");
>              exit(1);
>          }
> -        cpu_openrisc_pic_init(cpus[n]);
>  
>          cpu_openrisc_clock_init(cpus[n]);
>  
> diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c
> deleted file mode 100644
> index 36f93508309..00000000000
> --- a/hw/openrisc/pic_cpu.c
> +++ /dev/null
> @@ -1,61 +0,0 @@
> -/*
> - * OpenRISC Programmable Interrupt Controller support.
> - *
> - * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
> - *                         Feng Gao <gf91597@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/>.
> - */
> -
> -#include "qemu/osdep.h"
> -#include "hw/irq.h"
> -#include "cpu.h"
> -
> -/* OpenRISC pic handler */
> -static void openrisc_pic_cpu_handler(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;
> -    }
> -}
> -
> -void cpu_openrisc_pic_init(OpenRISCCPU *cpu)
> -{
> -    int i;
> -    qemu_irq *qi;
> -    qi = qemu_allocate_irqs(openrisc_pic_cpu_handler, cpu, NR_IRQS);
> -
> -    for (i = 0; i < NR_IRQS; i++) {
> -        cpu->env.irq[i] = qi[i];
> -    }
> -}
> diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
> index 5528c0918f4..b0bdfbe4fe2 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/hw/openrisc/meson.build b/hw/openrisc/meson.build
> index 57c42558e18..947f63ee087 100644
> --- a/hw/openrisc/meson.build
> +++ b/hw/openrisc/meson.build
> @@ -1,5 +1,5 @@
>  openrisc_ss = ss.source_set()
> -openrisc_ss.add(files('pic_cpu.c', 'cputimer.c'))
> +openrisc_ss.add(files('cputimer.c'))
>  openrisc_ss.add(when: 'CONFIG_OR1K_SIM', if_true: files('openrisc_sim.c'))
>  
>  hw_arch += {'openrisc': openrisc_ss}
> -- 
> 2.20.1

This is nice, thanks for the patch.

Reviewed-by: Stafford Horne <shorne@gmail.com>

Please feel free to merge.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object
  2020-11-27 22:51 [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object Peter Maydell
                   ` (2 preceding siblings ...)
  2020-11-27 22:51 ` [PATCH 3/3] target/openrisc: Move pic_cpu code into CPU object proper Peter Maydell
@ 2020-12-11 13:57 ` Peter Maydell
  3 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2020-12-11 13:57 UTC (permalink / raw)
  To: QEMU Developers; +Cc: Stafford Horne, Jia Liu

On Fri, 27 Nov 2020 at 22:51, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> 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.
>
> The main aim of this patch series is to make that refactoring,
> which fixes a trivial memory leak reported by Coverity of the IRQs
> allocated in cpu_openrisc_pic_init(), and removes one callsite of
> the qemu_allocate_irqs() function.
>
> Patch 1 is a minor bugfix noticed along the way; patch 2 is
> there to make the change in patch 3 simpler and clearer to review.
>
> Tested with 'make check' and 'make check-acceptance'.

Now the tree is open for 6.0 development, I'll take this
via target-arm.next, since Stafford doesn't have any other
openrisc patches in a queue currently.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-12-11 13:58 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-27 22:51 [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object Peter Maydell
2020-11-27 22:51 ` [PATCH 1/3] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs Peter Maydell
2020-11-29 11:59   ` Stafford Horne
2020-11-27 22:51 ` [PATCH 2/3] hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y" Peter Maydell
2020-11-29 12:01   ` Stafford Horne
2020-11-27 22:51 ` [PATCH 3/3] target/openrisc: Move pic_cpu code into CPU object proper Peter Maydell
2020-11-29 12:03   ` Stafford Horne
2020-12-11 13:57 ` [PATCH 0/3] target/openrisc: Move pic_cpu code into CPU object Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.