Re: [PATCH v10 6/7] hw/pci-host: Add emulation of Marvell MV64361 PPC system controller

2021-03-24 Thread David Gibson
On Wed, Mar 24, 2021 at 12:11:50PM +0100, BALATON Zoltan wrote:
> On Wed, 24 Mar 2021, David Gibson wrote:
> > On Tue, Mar 23, 2021 at 02:31:07PM +0100, BALATON Zoltan wrote:
> > > On Tue, 23 Mar 2021, David Gibson wrote:
> > > > On Wed, Mar 17, 2021 at 02:17:51AM +0100, BALATON Zoltan wrote:
> > [snip]
> > > > > +static void setup_mem_windows(MV64361State *s, uint32_t val)
> > > > > +{
> > > > > +MV64361PCIState *p;
> > > > > +MemoryRegion *mr;
> > > > > +uint32_t mask;
> > > > > +int i;
> > > > > +
> > > > > +val &= 0x1f;
> > > > > +for (mask = 1, i = 0; i < 21; i++, mask <<= 1) {
> > > > 
> > > > Having a loop, where nearly the entire body is a switch over the loop
> > > > variable seems a rather odd choice to me, compared to just unrolling
> > > > the whole thing.  Or alternatively, maybe more can be be factored out
> > > > of the switch into common body code.
> > > 
> > > The loop is really over the bits in val that say which memory regions to
> > 
> > I see that, but it doesn't change the point.
> > 
> > > enable so depending on this we need to touch different mem regions. For
> > > selecting those memory regions and what to do with them a switch seems to 
> > > be
> > > obvious choice. I probably can't factor out anything as these lines in
> > > switch cases are similar but all differ in some little details (like which
> > > PCI bus, name of the region, etc.). Unrolling could be possible but would
> > > just add lines between cases that's now in the loop head so I really don't
> > 
> > I see only 2 common lines, which basically balances about the case and
> > break lines in every switchcase.
> 
> Not sure what you mean by that. To me that means that these cannot be
> factored out as they are in the middle so can't put them neither before nor
> after the switch (without adding more local variables that would just make
> the result longer than it is now).

I'm saying that I don't think unrolling would actually make things
longer, because the small amount of duplication would balanced by
removing the switch boilerplate.

> Does that mean you prefer this to be unrolled then (written without a for
> just repeating the if ((val & mask) != (s->base_addr_enable & mask)) at
> every case)? That would also be longer by about 20 lines as we also log
> regions that are not in the switch that would need their enable bits checked
> separately if it's unrolled. Basically the trace is the common part of the
> loop and handling of the individual regions are branching out from the
> switch as they are different enough that factoring out the common parts is
> not shorter than this way due to then needing local variables to hold the
> different parts (name, address, size, base) the assigning of which are as
> many or more lines than the map_pci_region call that could be factored out
> that way.
> 
> I don't see why it is a problem to have a switch in a loop. If you insist I
> can try to turn the switch into if else but I don't see how would that be
> any better. Please explain a bit more what would you prefer here as I'm not
> sure what to do with this. To me this is the shortest and simplest way to
> write this.

Hmm... you know, it still seems kinda weird to me, but I am getting
too hung up on details here.  It's good enough, go with it.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH v10 6/7] hw/pci-host: Add emulation of Marvell MV64361 PPC system controller

2021-03-24 Thread BALATON Zoltan

On Wed, 24 Mar 2021, David Gibson wrote:

On Tue, Mar 23, 2021 at 02:31:07PM +0100, BALATON Zoltan wrote:

On Tue, 23 Mar 2021, David Gibson wrote:

On Wed, Mar 17, 2021 at 02:17:51AM +0100, BALATON Zoltan wrote:

[snip]

+static void setup_mem_windows(MV64361State *s, uint32_t val)
+{
+MV64361PCIState *p;
+MemoryRegion *mr;
+uint32_t mask;
+int i;
+
+val &= 0x1f;
+for (mask = 1, i = 0; i < 21; i++, mask <<= 1) {


Having a loop, where nearly the entire body is a switch over the loop
variable seems a rather odd choice to me, compared to just unrolling
the whole thing.  Or alternatively, maybe more can be be factored out
of the switch into common body code.


The loop is really over the bits in val that say which memory regions to


I see that, but it doesn't change the point.


enable so depending on this we need to touch different mem regions. For
selecting those memory regions and what to do with them a switch seems to be
obvious choice. I probably can't factor out anything as these lines in
switch cases are similar but all differ in some little details (like which
PCI bus, name of the region, etc.). Unrolling could be possible but would
just add lines between cases that's now in the loop head so I really don't


I see only 2 common lines, which basically balances about the case and
break lines in every switchcase.


Not sure what you mean by that. To me that means that these cannot be 
factored out as they are in the middle so can't put them neither before 
nor after the switch (without adding more local variables that would just 
make the result longer than it is now).


Does that mean you prefer this to be unrolled then (written without a for 
just repeating the if ((val & mask) != (s->base_addr_enable & mask)) at 
every case)? That would also be longer by about 20 lines as we also log 
regions that are not in the switch that would need their enable bits 
checked separately if it's unrolled. Basically the trace is the common 
part of the loop and handling of the individual regions are branching out 
from the switch as they are different enough that factoring out the common 
parts is not shorter than this way due to then needing local variables to 
hold the different parts (name, address, size, base) the assigning of 
which are as many or more lines than the map_pci_region call that could be 
factored out that way.


I don't see why it is a problem to have a switch in a loop. If you insist 
I can try to turn the switch into if else but I don't see how would that 
be any better. Please explain a bit more what would you prefer here as I'm 
not sure what to do with this. To me this is the shortest and simplest way 
to write this.


Regards,
BALATON Zoltan


see why would that be better. Maybe renaming the loop variable from i to
something that makes the intent clearer could help but I don't know what
you'd like better. Can you suggest something?


+if ((val & mask) != (s->base_addr_enable & mask)) {
+trace_mv64361_region_enable(!(val & mask) ? "enable" : "disable", 
i);
+switch (i) {
+/*
+ * 0-3 are SDRAM chip selects but we map all RAM directly
+ * 4-7 are device chip selects (not sure what those are)
+ * 8 is Boot device (ROM) chip select but we map that directly too
+ */
+case 9:
+p = >pci[0];
+mr = >cpu_win[i];
+unmap_region(mr);
+if (!(val & mask)) {
+map_pci_region(mr, >io, OBJECT(s), "pci0-io-win",
+   p->remap[4], (p->io_size + 1) << 16,
+   (p->io_base & 0xf) << 16);
+}
+break;
+case 10:
+p = >pci[0];
+mr = >cpu_win[i];
+unmap_region(mr);
+if (!(val & mask)) {
+map_pci_region(mr, >mem, OBJECT(s), "pci0-mem0-win",
+   p->remap[0], (p->mem_size[0] + 1) << 16,
+   (p->mem_base[0] & 0xf) << 16);
+}
+break;
+case 11:
+p = >pci[0];
+mr = >cpu_win[i];
+unmap_region(mr);
+if (!(val & mask)) {
+map_pci_region(mr, >mem, OBJECT(s), "pci0-mem1-win",
+   p->remap[1], (p->mem_size[1] + 1) << 16,
+   (p->mem_base[1] & 0xf) << 16);
+}
+break;
+case 12:
+p = >pci[0];
+mr = >cpu_win[i];
+unmap_region(mr);
+if (!(val & mask)) {
+map_pci_region(mr, >mem, OBJECT(s), "pci0-mem2-win",
+   p->remap[2], (p->mem_size[2] + 1) << 16,
+   (p->mem_base[2] & 0xf) << 

Re: [PATCH v10 6/7] hw/pci-host: Add emulation of Marvell MV64361 PPC system controller

2021-03-23 Thread David Gibson
On Tue, Mar 23, 2021 at 02:31:07PM +0100, BALATON Zoltan wrote:
> On Tue, 23 Mar 2021, David Gibson wrote:
> > On Wed, Mar 17, 2021 at 02:17:51AM +0100, BALATON Zoltan wrote:
[snip]
> > > +static void setup_mem_windows(MV64361State *s, uint32_t val)
> > > +{
> > > +MV64361PCIState *p;
> > > +MemoryRegion *mr;
> > > +uint32_t mask;
> > > +int i;
> > > +
> > > +val &= 0x1f;
> > > +for (mask = 1, i = 0; i < 21; i++, mask <<= 1) {
> > 
> > Having a loop, where nearly the entire body is a switch over the loop
> > variable seems a rather odd choice to me, compared to just unrolling
> > the whole thing.  Or alternatively, maybe more can be be factored out
> > of the switch into common body code.
> 
> The loop is really over the bits in val that say which memory regions to

I see that, but it doesn't change the point.

> enable so depending on this we need to touch different mem regions. For
> selecting those memory regions and what to do with them a switch seems to be
> obvious choice. I probably can't factor out anything as these lines in
> switch cases are similar but all differ in some little details (like which
> PCI bus, name of the region, etc.). Unrolling could be possible but would
> just add lines between cases that's now in the loop head so I really don't

I see only 2 common lines, which basically balances about the case and
break lines in every switchcase.

> see why would that be better. Maybe renaming the loop variable from i to
> something that makes the intent clearer could help but I don't know what
> you'd like better. Can you suggest something?
> 
> > > +if ((val & mask) != (s->base_addr_enable & mask)) {
> > > +trace_mv64361_region_enable(!(val & mask) ? "enable" : 
> > > "disable", i);
> > > +switch (i) {
> > > +/*
> > > + * 0-3 are SDRAM chip selects but we map all RAM directly
> > > + * 4-7 are device chip selects (not sure what those are)
> > > + * 8 is Boot device (ROM) chip select but we map that 
> > > directly too
> > > + */
> > > +case 9:
> > > +p = >pci[0];
> > > +mr = >cpu_win[i];
> > > +unmap_region(mr);
> > > +if (!(val & mask)) {
> > > +map_pci_region(mr, >io, OBJECT(s), "pci0-io-win",
> > > +   p->remap[4], (p->io_size + 1) << 16,
> > > +   (p->io_base & 0xf) << 16);
> > > +}
> > > +break;
> > > +case 10:
> > > +p = >pci[0];
> > > +mr = >cpu_win[i];
> > > +unmap_region(mr);
> > > +if (!(val & mask)) {
> > > +map_pci_region(mr, >mem, OBJECT(s), 
> > > "pci0-mem0-win",
> > > +   p->remap[0], (p->mem_size[0] + 1) << 
> > > 16,
> > > +   (p->mem_base[0] & 0xf) << 16);
> > > +}
> > > +break;
> > > +case 11:
> > > +p = >pci[0];
> > > +mr = >cpu_win[i];
> > > +unmap_region(mr);
> > > +if (!(val & mask)) {
> > > +map_pci_region(mr, >mem, OBJECT(s), 
> > > "pci0-mem1-win",
> > > +   p->remap[1], (p->mem_size[1] + 1) << 
> > > 16,
> > > +   (p->mem_base[1] & 0xf) << 16);
> > > +}
> > > +break;
> > > +case 12:
> > > +p = >pci[0];
> > > +mr = >cpu_win[i];
> > > +unmap_region(mr);
> > > +if (!(val & mask)) {
> > > +map_pci_region(mr, >mem, OBJECT(s), 
> > > "pci0-mem2-win",
> > > +   p->remap[2], (p->mem_size[2] + 1) << 
> > > 16,
> > > +   (p->mem_base[2] & 0xf) << 16);
> > > +}
> > > +break;
> > > +case 13:
> > > +p = >pci[0];
> > > +mr = >cpu_win[i];
> > > +unmap_region(mr);
> > > +if (!(val & mask)) {
> > > +map_pci_region(mr, >mem, OBJECT(s), 
> > > "pci0-mem3-win",
> > > +   p->remap[3], (p->mem_size[3] + 1) << 
> > > 16,
> > > +   (p->mem_base[3] & 0xf) << 16);
> > > +}
> > > +break;
> > > +case 14:
> > > +p = >pci[1];
> > > +mr = >cpu_win[i];
> > > +unmap_region(mr);
> > > +if (!(val & mask)) {
> > > +map_pci_region(mr, >io, OBJECT(s), "pci1-io-win",
> > > +   p->remap[4], (p->io_size + 1) << 16,
> > > +   (p->io_base & 0xf) << 16);
> > > +

Re: [PATCH v10 6/7] hw/pci-host: Add emulation of Marvell MV64361 PPC system controller

2021-03-23 Thread BALATON Zoltan

On Tue, 23 Mar 2021, David Gibson wrote:

On Wed, Mar 17, 2021 at 02:17:51AM +0100, BALATON Zoltan wrote:

The Marvell Discovery II aka. MV64361 is a PowerPC system controller
chip that is used on the pegasos2 PPC board. This adds emulation of it
that models the device enough to boot guests on this board. The
mv643xx.h header with register definitions is taken from Linux 4.15.10
only fixing white space errors, removing not needed parts and changing
formatting for QEMU coding style.

Signed-off-by: BALATON Zoltan 
---
 hw/pci-host/Kconfig   |   4 +
 hw/pci-host/meson.build   |   2 +
 hw/pci-host/mv64361.c | 966 ++
 hw/pci-host/mv643xx.h | 918 
 hw/pci-host/trace-events  |   6 +
 include/hw/pci-host/mv64361.h |   8 +
 include/hw/pci/pci_ids.h  |   1 +
 7 files changed, 1905 insertions(+)
 create mode 100644 hw/pci-host/mv64361.c
 create mode 100644 hw/pci-host/mv643xx.h
 create mode 100644 include/hw/pci-host/mv64361.h


Adding yourself to MAINTAINERS for this would be good.



diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index 2ccc96f02c..79c20bf28b 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -72,3 +72,7 @@ config REMOTE_PCIHOST
 config SH_PCI
 bool
 select PCI
+
+config MV64361
+bool
+select PCI
diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
index 87a896973e..34b3538beb 100644
--- a/hw/pci-host/meson.build
+++ b/hw/pci-host/meson.build
@@ -19,6 +19,8 @@ pci_ss.add(when: 'CONFIG_GRACKLE_PCI', if_true: 
files('grackle.c'))
 pci_ss.add(when: 'CONFIG_UNIN_PCI', if_true: files('uninorth.c'))
 # PowerPC E500 boards
 pci_ss.add(when: 'CONFIG_PPCE500_PCI', if_true: files('ppce500.c'))
+# Pegasos2
+pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c'))

 # ARM devices
 pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c'))
diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
new file mode 100644
index 00..d71402f8b5
--- /dev/null
+++ b/hw/pci-host/mv64361.c
@@ -0,0 +1,966 @@
+/*
+ * Marvell Discovery II MV64361 System Controller for
+ * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
+ *
+ * Copyright (c) 2018-2020 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/intc/i8259.h"
+#include "hw/qdev-properties.h"
+#include "exec/address-spaces.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "trace.h"
+#include "hw/pci-host/mv64361.h"
+#include "mv643xx.h"
+
+#define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge"
+
+static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k->vendor_id = PCI_VENDOR_ID_MARVELL;
+k->device_id = PCI_DEVICE_ID_MARVELL_MV6436X;
+k->class_id = PCI_CLASS_BRIDGE_HOST;
+/*
+ * PCI-facing part of the host bridge,
+ * not usable without the host-facing part
+ */
+dc->user_creatable = false;
+}
+
+static const TypeInfo mv64361_pcibridge_info = {
+.name  = TYPE_MV64361_PCI_BRIDGE,
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(PCIDevice),
+.class_init= mv64361_pcibridge_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+};
+
+
+#define TYPE_MV64361_PCI "mv64361-pcihost"
+OBJECT_DECLARE_SIMPLE_TYPE(MV64361PCIState, MV64361_PCI)
+
+struct MV64361PCIState {
+PCIHostState parent_obj;
+
+uint8_t index;
+MemoryRegion io;
+MemoryRegion mem;
+qemu_irq irq[PCI_NUM_PINS];
+
+uint32_t io_base;
+uint32_t io_size;
+uint32_t mem_base[4];
+uint32_t mem_size[4];
+uint64_t remap[5];
+};
+
+static int mv64361_pcihost_map_irq(PCIDevice *pci_dev, int n)
+{
+return (n + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
+}
+
+static void mv64361_pcihost_set_irq(void *opaque, int n, int level)
+{
+MV64361PCIState *s = opaque;
+qemu_set_irq(s->irq[n], level);
+}
+
+static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
+{
+MV64361PCIState *s = MV64361_PCI(dev);
+PCIHostState *h = PCI_HOST_BRIDGE(dev);
+char *name;
+
+name = g_strdup_printf("pci%d-io", s->index);
+memory_region_init(>io, OBJECT(dev), name, 0x1);
+g_free(name);
+name = g_strdup_printf("pci%d-mem", s->index);
+memory_region_init(>mem, OBJECT(dev), name, 1ULL << 32);
+g_free(name);
+name = g_strdup_printf("pci.%d", s->index);
+h->bus = pci_register_root_bus(dev, name, mv64361_pcihost_set_irq,
+   mv64361_pcihost_map_irq, dev,
+

Re: [PATCH v10 6/7] hw/pci-host: Add emulation of Marvell MV64361 PPC system controller

2021-03-22 Thread David Gibson
On Wed, Mar 17, 2021 at 02:17:51AM +0100, BALATON Zoltan wrote:
> The Marvell Discovery II aka. MV64361 is a PowerPC system controller
> chip that is used on the pegasos2 PPC board. This adds emulation of it
> that models the device enough to boot guests on this board. The
> mv643xx.h header with register definitions is taken from Linux 4.15.10
> only fixing white space errors, removing not needed parts and changing
> formatting for QEMU coding style.
> 
> Signed-off-by: BALATON Zoltan 
> ---
>  hw/pci-host/Kconfig   |   4 +
>  hw/pci-host/meson.build   |   2 +
>  hw/pci-host/mv64361.c | 966 ++
>  hw/pci-host/mv643xx.h | 918 
>  hw/pci-host/trace-events  |   6 +
>  include/hw/pci-host/mv64361.h |   8 +
>  include/hw/pci/pci_ids.h  |   1 +
>  7 files changed, 1905 insertions(+)
>  create mode 100644 hw/pci-host/mv64361.c
>  create mode 100644 hw/pci-host/mv643xx.h
>  create mode 100644 include/hw/pci-host/mv64361.h

Adding yourself to MAINTAINERS for this would be good.

> 
> diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
> index 2ccc96f02c..79c20bf28b 100644
> --- a/hw/pci-host/Kconfig
> +++ b/hw/pci-host/Kconfig
> @@ -72,3 +72,7 @@ config REMOTE_PCIHOST
>  config SH_PCI
>  bool
>  select PCI
> +
> +config MV64361
> +bool
> +select PCI
> diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
> index 87a896973e..34b3538beb 100644
> --- a/hw/pci-host/meson.build
> +++ b/hw/pci-host/meson.build
> @@ -19,6 +19,8 @@ pci_ss.add(when: 'CONFIG_GRACKLE_PCI', if_true: 
> files('grackle.c'))
>  pci_ss.add(when: 'CONFIG_UNIN_PCI', if_true: files('uninorth.c'))
>  # PowerPC E500 boards
>  pci_ss.add(when: 'CONFIG_PPCE500_PCI', if_true: files('ppce500.c'))
> +# Pegasos2
> +pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c'))
>  
>  # ARM devices
>  pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c'))
> diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
> new file mode 100644
> index 00..d71402f8b5
> --- /dev/null
> +++ b/hw/pci-host/mv64361.c
> @@ -0,0 +1,966 @@
> +/*
> + * Marvell Discovery II MV64361 System Controller for
> + * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
> + *
> + * Copyright (c) 2018-2020 BALATON Zoltan
> + *
> + * This work is licensed under the GNU GPL license version 2 or later.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "qemu/units.h"
> +#include "qapi/error.h"
> +#include "hw/hw.h"
> +#include "hw/sysbus.h"
> +#include "hw/pci/pci.h"
> +#include "hw/pci/pci_host.h"
> +#include "hw/irq.h"
> +#include "hw/intc/i8259.h"
> +#include "hw/qdev-properties.h"
> +#include "exec/address-spaces.h"
> +#include "qemu/log.h"
> +#include "qemu/error-report.h"
> +#include "trace.h"
> +#include "hw/pci-host/mv64361.h"
> +#include "mv643xx.h"
> +
> +#define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge"
> +
> +static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(klass);
> +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> +k->vendor_id = PCI_VENDOR_ID_MARVELL;
> +k->device_id = PCI_DEVICE_ID_MARVELL_MV6436X;
> +k->class_id = PCI_CLASS_BRIDGE_HOST;
> +/*
> + * PCI-facing part of the host bridge,
> + * not usable without the host-facing part
> + */
> +dc->user_creatable = false;
> +}
> +
> +static const TypeInfo mv64361_pcibridge_info = {
> +.name  = TYPE_MV64361_PCI_BRIDGE,
> +.parent= TYPE_PCI_DEVICE,
> +.instance_size = sizeof(PCIDevice),
> +.class_init= mv64361_pcibridge_class_init,
> +.interfaces = (InterfaceInfo[]) {
> +{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
> +{ },
> +},
> +};
> +
> +
> +#define TYPE_MV64361_PCI "mv64361-pcihost"
> +OBJECT_DECLARE_SIMPLE_TYPE(MV64361PCIState, MV64361_PCI)
> +
> +struct MV64361PCIState {
> +PCIHostState parent_obj;
> +
> +uint8_t index;
> +MemoryRegion io;
> +MemoryRegion mem;
> +qemu_irq irq[PCI_NUM_PINS];
> +
> +uint32_t io_base;
> +uint32_t io_size;
> +uint32_t mem_base[4];
> +uint32_t mem_size[4];
> +uint64_t remap[5];
> +};
> +
> +static int mv64361_pcihost_map_irq(PCIDevice *pci_dev, int n)
> +{
> +return (n + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
> +}
> +
> +static void mv64361_pcihost_set_irq(void *opaque, int n, int level)
> +{
> +MV64361PCIState *s = opaque;
> +qemu_set_irq(s->irq[n], level);
> +}
> +
> +static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
> +{
> +MV64361PCIState *s = MV64361_PCI(dev);
> +PCIHostState *h = PCI_HOST_BRIDGE(dev);
> +char *name;
> +
> +name = g_strdup_printf("pci%d-io", s->index);
> +memory_region_init(>io, OBJECT(dev), name, 0x1);
> +g_free(name);
> +name = g_strdup_printf("pci%d-mem", s->index);
> +memory_region_init(>mem,