Re: [PATCH v2 22/43] hw/isa/piix3: Rename piix3_reset() for sharing with PIIX4

2022-10-23 Thread Philippe Mathieu-Daudé

On 22/10/22 17:04, Bernhard Beschow wrote:

Signed-off-by: Bernhard Beschow 
---
  hw/isa/piix3.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v2 22/43] hw/isa/piix3: Rename piix3_reset() for sharing with PIIX4

2022-10-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix3.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 8dbf22eaab..5214a75891 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -156,7 +156,7 @@ static void piix3_write_config_xen(PCIDevice *dev,
 piix3_write_config(dev, address, val, len);
 }
 
-static void piix3_reset(DeviceState *dev)
+static void piix_reset(DeviceState *dev)
 {
 PIIX3State *d = PIIX3_PCI_DEVICE(dev);
 uint8_t *pci_conf = d->dev.config;
@@ -399,7 +399,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
 
-dc->reset   = piix3_reset;
+dc->reset   = piix_reset;
 dc->desc= "ISA bridge";
 dc->vmsd= _piix3;
 dc->hotpluggable   = false;
-- 
2.38.1




[PATCH v2 39/43] hw/isa/piix: Rename functions to be shared for interrupt triggering

2022-10-23 Thread Bernhard Beschow
PIIX4 will get the same optimizations which are already implemented for
PIIX3.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix.c | 56 +--
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/hw/isa/piix.c b/hw/isa/piix.c
index 9e7b11bcdd..446105a7a1 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -41,47 +41,47 @@
 
 #define XEN_PIIX_NUM_PIRQS  128ULL
 
-static void piix3_set_irq_pic(PIIXState *piix3, int pic_irq)
+static void piix_set_irq_pic(PIIXState *piix, int pic_irq)
 {
-qemu_set_irq(piix3->pic.in_irqs[pic_irq],
- !!(piix3->pic_levels &
+qemu_set_irq(piix->pic.in_irqs[pic_irq],
+ !!(piix->pic_levels &
 (((1ULL << PIIX_NUM_PIRQS) - 1) <<
  (pic_irq * PIIX_NUM_PIRQS;
 }
 
-static void piix3_set_irq_level_internal(PIIXState *piix3, int pirq, int level)
+static void piix_set_irq_level_internal(PIIXState *piix, int pirq, int level)
 {
 int pic_irq;
 uint64_t mask;
 
-pic_irq = piix3->dev.config[PIIX_PIRQCA + pirq];
+pic_irq = piix->dev.config[PIIX_PIRQCA + pirq];
 if (pic_irq >= ISA_NUM_IRQS) {
 return;
 }
 
 mask = 1ULL << ((pic_irq * PIIX_NUM_PIRQS) + pirq);
-piix3->pic_levels &= ~mask;
-piix3->pic_levels |= mask * !!level;
+piix->pic_levels &= ~mask;
+piix->pic_levels |= mask * !!level;
 }
 
-static void piix3_set_irq_level(PIIXState *piix3, int pirq, int level)
+static void piix_set_irq_level(PIIXState *piix, int pirq, int level)
 {
 int pic_irq;
 
-pic_irq = piix3->dev.config[PIIX_PIRQCA + pirq];
+pic_irq = piix->dev.config[PIIX_PIRQCA + pirq];
 if (pic_irq >= ISA_NUM_IRQS) {
 return;
 }
 
-piix3_set_irq_level_internal(piix3, pirq, level);
+piix_set_irq_level_internal(piix, pirq, level);
 
-piix3_set_irq_pic(piix3, pic_irq);
+piix_set_irq_pic(piix, pic_irq);
 }
 
-static void piix3_set_irq(void *opaque, int pirq, int level)
+static void piix_set_irq(void *opaque, int pirq, int level)
 {
-PIIXState *piix3 = opaque;
-piix3_set_irq_level(piix3, pirq, level);
+PIIXState *piix = opaque;
+piix_set_irq_level(piix, pirq, level);
 }
 
 static void piix4_set_irq(void *opaque, int irq_num, int level)
@@ -158,29 +158,29 @@ static PCIINTxRoute piix3_route_intx_pin_to_irq(void 
*opaque, int pin)
 }
 
 /* irq routing is changed. so rebuild bitmap */
-static void piix3_update_irq_levels(PIIXState *piix3)
+static void piix_update_irq_levels(PIIXState *piix)
 {
-PCIBus *bus = pci_get_bus(>dev);
+PCIBus *bus = pci_get_bus(>dev);
 int pirq;
 
-piix3->pic_levels = 0;
+piix->pic_levels = 0;
 for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
-piix3_set_irq_level(piix3, pirq, pci_bus_get_irq_level(bus, pirq));
+piix_set_irq_level(piix, pirq, pci_bus_get_irq_level(bus, pirq));
 }
 }
 
-static void piix3_write_config(PCIDevice *dev,
-   uint32_t address, uint32_t val, int len)
+static void piix_write_config(PCIDevice *dev, uint32_t address, uint32_t val,
+  int len)
 {
 pci_default_write_config(dev, address, val, len);
 if (ranges_overlap(address, len, PIIX_PIRQCA, 4)) {
-PIIXState *piix3 = PIIX_PCI_DEVICE(dev);
+PIIXState *piix = PIIX_PCI_DEVICE(dev);
 int pic_irq;
 
-pci_bus_fire_intx_routing_notifier(pci_get_bus(>dev));
-piix3_update_irq_levels(piix3);
+pci_bus_fire_intx_routing_notifier(pci_get_bus(>dev));
+piix_update_irq_levels(piix);
 for (pic_irq = 0; pic_irq < ISA_NUM_IRQS; pic_irq++) {
-piix3_set_irq_pic(piix3, pic_irq);
+piix_set_irq_pic(piix, pic_irq);
 }
 }
 }
@@ -202,7 +202,7 @@ static void piix3_write_config_xen(PCIDevice *dev,
 }
 }
 
-piix3_write_config(dev, address, val, len);
+piix_write_config(dev, address, val, len);
 }
 
 static void piix_reset(DeviceState *dev)
@@ -262,7 +262,7 @@ static int piix3_post_load(void *opaque, int version_id)
  */
 piix3->pic_levels = 0;
 for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
-piix3_set_irq_level_internal(piix3, pirq,
+piix_set_irq_level_internal(piix3, pirq,
 pci_bus_get_irq_level(pci_get_bus(>dev), pirq));
 }
 return 0;
@@ -512,7 +512,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
-pci_bus_irqs(pci_bus, piix3_set_irq, piix3_pci_slot_get_pirq,
+pci_bus_irqs(pci_bus, piix_set_irq, piix3_pci_slot_get_pirq,
  piix3, PIIX_NUM_PIRQS);
 pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
 }
@@ -521,7 +521,7 @@ static void piix3_class_init(ObjectClass *klass, void *data)
 {
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-k->config_write = piix3_write_config;
+k->config_write = piix_write_config;
 k->realize = piix3_realize;
 }
 
-- 
2.38.1




Re: [PATCH v2 24/43] hw/isa/piix3: Rename typedef PIIX3State to PIIXState

2022-10-23 Thread Philippe Mathieu-Daudé

On 22/10/22 17:04, Bernhard Beschow wrote:

This commit marks the finalization of the PIIX3 preparations
to be merged with PIIX4. In particular, PIIXState is prepared
to be reused in piix4.c.

Signed-off-by: Bernhard Beschow 
---
  hw/isa/piix3.c| 58 +--
  include/hw/southbridge/piix.h |  4 +--
  2 files changed, 31 insertions(+), 31 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v2 19/43] hw/isa/piix3: Allow board to provide PCI interrupt routes

2022-10-23 Thread Bernhard Beschow
PIIX3 initializes the PIRQx route control registers to the default
values as described in the 82371AB PCI-TO-ISA/IDE XCELERATOR (PIIX4)
April 1997 manual. PIIX4, however, initializes the routes according to
the Malta™ User’s Manual, ch 6.6, which are IRQs 10 and 11. In order to
allow the reset methods to be consolidated, allow board code to specify
the routes.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix3.c| 12 
 include/hw/southbridge/piix.h |  1 +
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index aa32f43e4a..c6a8f1f27d 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -168,10 +168,10 @@ static void piix3_reset(DeviceState *dev)
 pci_conf[0x4c] = 0x4d;
 pci_conf[0x4e] = 0x03;
 pci_conf[0x4f] = 0x00;
-pci_conf[0x60] = 0x80;
-pci_conf[0x61] = 0x80;
-pci_conf[0x62] = 0x80;
-pci_conf[0x63] = 0x80;
+pci_conf[PIIX_PIRQCA] = d->pci_irq_reset_mappings[0];
+pci_conf[PIIX_PIRQCB] = d->pci_irq_reset_mappings[1];
+pci_conf[PIIX_PIRQCC] = d->pci_irq_reset_mappings[2];
+pci_conf[PIIX_PIRQCD] = d->pci_irq_reset_mappings[3];
 pci_conf[0x69] = 0x02;
 pci_conf[0x70] = 0x80;
 pci_conf[0x76] = 0x0c;
@@ -383,6 +383,10 @@ static void pci_piix3_init(Object *obj)
 
 static Property pci_piix3_props[] = {
 DEFINE_PROP_UINT32("smb_io_base", PIIX3State, smb_io_base, 0),
+DEFINE_PROP_UINT8("pirqa", PIIX3State, pci_irq_reset_mappings[0], 0x80),
+DEFINE_PROP_UINT8("pirqb", PIIX3State, pci_irq_reset_mappings[1], 0x80),
+DEFINE_PROP_UINT8("pirqc", PIIX3State, pci_irq_reset_mappings[2], 0x80),
+DEFINE_PROP_UINT8("pirqd", PIIX3State, pci_irq_reset_mappings[3], 0x80),
 DEFINE_PROP_BOOL("has-acpi", PIIX3State, has_acpi, true),
 DEFINE_PROP_BOOL("has-usb", PIIX3State, has_usb, true),
 DEFINE_PROP_BOOL("smm-enabled", PIIX3State, smm_enabled, false),
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 1f22eb1444..df3e0084c5 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -54,6 +54,7 @@ struct PIIXState {
 
 /* This member isn't used. Just for save/load compatibility */
 int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
+uint8_t pci_irq_reset_mappings[PIIX_NUM_PIRQS];
 
 ISAPICState pic;
 RTCState rtc;
-- 
2.38.1




Re: [PATCH v2 18/43] hw/isa/piix3: Remove unused include

2022-10-23 Thread Philippe Mathieu-Daudé

On 22/10/22 17:04, Bernhard Beschow wrote:

Ammends commit 988fb613215993dd0ce642b89ca8182c479d39dd.

Signed-off-by: Bernhard Beschow 
---
  hw/isa/piix3.c | 1 -
  1 file changed, 1 deletion(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v2 34/43] hw/isa/piix4: Rename reset control operations to match PIIX3

2022-10-23 Thread Bernhard Beschow
Both implementations are the same and will be shared upon merging.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix4.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index a7d52c5294..2f5b6fc934 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -152,7 +152,7 @@ static const VMStateDescription vmstate_piix4 = {
 }
 };
 
-static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
+static void rcr_write(void *opaque, hwaddr addr, uint64_t val,
 unsigned int len)
 {
 PIIXState *s = opaque;
@@ -165,16 +165,16 @@ static void piix4_rcr_write(void *opaque, hwaddr addr, 
uint64_t val,
 s->rcr = val & 2; /* keep System Reset type only */
 }
 
-static uint64_t piix4_rcr_read(void *opaque, hwaddr addr, unsigned int len)
+static uint64_t rcr_read(void *opaque, hwaddr addr, unsigned int len)
 {
 PIIXState *s = opaque;
 
 return s->rcr;
 }
 
-static const MemoryRegionOps piix4_rcr_ops = {
-.read = piix4_rcr_read,
-.write = piix4_rcr_write,
+static const MemoryRegionOps rcr_ops = {
+.read = rcr_read,
+.write = rcr_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
@@ -194,7 +194,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
-memory_region_init_io(>rcr_mem, OBJECT(dev), _rcr_ops, s,
+memory_region_init_io(>rcr_mem, OBJECT(dev), _ops, s,
   "reset-control", 1);
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
 PIIX_RCR_IOPORT, >rcr_mem, 1);
-- 
2.38.1




[PATCH v2 08/43] hw/ide/piix: Introduce TYPE_ macros for PIIX IDE controllers

2022-10-23 Thread Bernhard Beschow
Suggested-by: Mark Cave-Ayland 
Signed-off-by: Bernhard Beschow 
---
 hw/i386/pc_piix.c | 3 ++-
 hw/ide/piix.c | 5 +++--
 hw/isa/piix4.c| 3 ++-
 include/hw/ide/piix.h | 7 +++
 4 files changed, 14 insertions(+), 4 deletions(-)
 create mode 100644 include/hw/ide/piix.h

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 5caef9bfc9..e26509a935 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -40,6 +40,7 @@
 #include "hw/usb.h"
 #include "net/net.h"
 #include "hw/ide/pci.h"
+#include "hw/ide/piix.h"
 #include "hw/irq.h"
 #include "sysemu/kvm.h"
 #include "hw/kvm/clock.h"
@@ -260,7 +261,7 @@ static void pc_init1(MachineState *machine,
 if (pcmc->pci_enabled) {
 PCIDevice *dev;
 
-dev = pci_create_simple(pci_bus, piix3_devfn + 1, "piix3-ide");
+dev = pci_create_simple(pci_bus, piix3_devfn + 1, TYPE_PIIX3_IDE);
 pci_ide_create_devs(dev);
 idebus[0] = qdev_get_child_bus(>qdev, "ide.0");
 idebus[1] = qdev_get_child_bus(>qdev, "ide.1");
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index de1f4f0efb..267dbf37db 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -36,6 +36,7 @@
 #include "sysemu/blockdev.h"
 #include "sysemu/dma.h"
 
+#include "hw/ide/piix.h"
 #include "hw/ide/pci.h"
 #include "trace.h"
 
@@ -202,7 +203,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo piix3_ide_info = {
-.name  = "piix3-ide",
+.name  = TYPE_PIIX3_IDE,
 .parent= TYPE_PCI_IDE,
 .class_init= piix3_ide_class_init,
 };
@@ -224,7 +225,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo piix4_ide_info = {
-.name  = "piix4-ide",
+.name  = TYPE_PIIX4_IDE,
 .parent= TYPE_PCI_IDE,
 .class_init= piix4_ide_class_init,
 };
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index c88d3bf3bf..e05e65d3bc 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -28,6 +28,7 @@
 #include "hw/irq.h"
 #include "hw/southbridge/piix.h"
 #include "hw/pci/pci.h"
+#include "hw/ide/piix.h"
 #include "hw/isa/isa.h"
 #include "hw/intc/i8259.h"
 #include "hw/dma/i8257.h"
@@ -277,7 +278,7 @@ static void piix4_init(Object *obj)
 PIIX4State *s = PIIX4_PCI_DEVICE(obj);
 
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
-object_initialize_child(obj, "ide", >ide, "piix4-ide");
+object_initialize_child(obj, "ide", >ide, TYPE_PIIX4_IDE);
 object_initialize_child(obj, "uhci", >uhci, "piix4-usb-uhci");
 
 object_initialize_child(obj, "pm", >pm, TYPE_PIIX4_PM);
diff --git a/include/hw/ide/piix.h b/include/hw/ide/piix.h
new file mode 100644
index 00..ef3ef3d62d
--- /dev/null
+++ b/include/hw/ide/piix.h
@@ -0,0 +1,7 @@
+#ifndef HW_IDE_PIIX_H
+#define HW_IDE_PIIX_H
+
+#define TYPE_PIIX3_IDE "piix3-ide"
+#define TYPE_PIIX4_IDE "piix4-ide"
+
+#endif /* HW_IDE_PIIX_H */
-- 
2.38.1




Re: [RFC v3 2/2] virtio-blk: add zoned storage emulation for zoned devices

2022-10-23 Thread Sam Li
Dmitry Fomichev  于2022年10月23日周日 10:08写道:
>
> On Tue, 2022-10-18 at 16:56 +0800, Sam Li wrote:
> > Dmitry Fomichev  于2022年10月17日周一 09:01写道:
> > >
> > > On Sun, 2022-10-16 at 23:05 +0800, Sam Li wrote:
> > > > This patch extends virtio-blk emulation to handle zoned device commands
> > > > by calling the new block layer APIs to perform zoned device I/O on
> > > > behalf of the guest. It supports Report Zone, four zone oparations 
> > > > (open,
> > > > close, finish, reset), and Append Zone.
> > > >
> > > > The VIRTIO_BLK_F_ZONED feature bit will only be set if the host does
> > > > support zoned block devices. Regular block devices(conventional zones)
> > > > will not be set.
> > > >
> > > > Then the guest os can use blkzone(8) to test those commands on zoned
> > > > devices.
> > > > Furthermore, using zonefs to test zone append write is also supported.
> > > >
> > > > Signed-off-by: Sam Li 
> > > > ---
> > > >  hw/block/virtio-blk-common.c   |   2 +
> > > >  hw/block/virtio-blk.c  | 412 -
> > > >  include/hw/virtio/virtio-blk.h |  11 +-
> > > >  3 files changed, 422 insertions(+), 3 deletions(-)
> > > >
> > > > diff --git a/hw/block/virtio-blk-common.c b/hw/block/virtio-blk-common.c
> > > > index ac52d7c176..e2f8e2f6da 100644
> > > > --- a/hw/block/virtio-blk-common.c
> > > > +++ b/hw/block/virtio-blk-common.c
> > > > @@ -29,6 +29,8 @@ static const VirtIOFeature feature_sizes[] = {
> > > >   .end = endof(struct virtio_blk_config, discard_sector_alignment)},
> > > >  {.flags = 1ULL << VIRTIO_BLK_F_WRITE_ZEROES,
> > > >   .end = endof(struct virtio_blk_config, write_zeroes_may_unmap)},
> > > > +{.flags = 1ULL << VIRTIO_BLK_F_ZONED,
> > > > + .end = endof(struct virtio_blk_config, zoned)},
> > > >  {}
> > > >  };
> > > >
> > > > diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> > > > index 8131ec2dbc..58891aea31 100644
> > > > --- a/hw/block/virtio-blk.c
> > > > +++ b/hw/block/virtio-blk.c
> > > > @@ -26,6 +26,9 @@
> > > >  #include "hw/virtio/virtio-blk.h"
> > > >  #include "dataplane/virtio-blk.h"
> > > >  #include "scsi/constants.h"
> > > > +#if defined(CONFIG_BLKZONED)
> > > > +#include 
> > > > +#endif
> > > >  #ifdef __linux__
> > > >  # include 
> > > >  #endif
> > > > @@ -55,10 +58,29 @@ static void virtio_blk_req_complete(VirtIOBlockReq
> > > > *req,
> > > > unsigned char status)
> > > >  {
> > > >  VirtIOBlock *s = req->dev;
> > > >  VirtIODevice *vdev = VIRTIO_DEVICE(s);
> > > > +int64_t inhdr_len, n;
> > > > +void *buf;
> > > >
> > > >  trace_virtio_blk_req_complete(vdev, req, status);
> > > >
> > > > -stb_p(>in->status, status);
> > > > +iov_discard_undo(>inhdr_undo);
> > > > +if (virtio_ldl_p(vdev, >out.type) == 
> > > > VIRTIO_BLK_T_ZONE_APPEND) {
> > > > +inhdr_len = sizeof(struct virtio_blk_zone_append_inhdr);
> > > > +req->in.in_hdr->status = status;
> > > > +buf = req->in.in_hdr;
> > > > +} else {
> > > > +inhdr_len = sizeof(struct virtio_blk_inhdr);
> > > > +req->in.zone_append_inhdr->status = status;
> > > > +buf = req->in.zone_append_inhdr;
> > > > +}
> > > > +
> > > > +n = iov_from_buf(req->elem.in_sg, req->elem.in_num,
> > > > + req->in_len - inhdr_len, buf, inhdr_len);
> > > > +if (n != inhdr_len) {
> > > > +virtio_error(vdev, "Driver provided input buffer less than 
> > > > size of
> > > > "
> > > > + "in header");
> > > > +}
> > > > +
> > > >  iov_discard_undo(>inhdr_undo);
> > > >  iov_discard_undo(>outhdr_undo);
> > > >  virtqueue_push(req->vq, >elem, req->in_len);
> > > > @@ -592,6 +614,334 @@ err:
> > > >  return err_status;
> > > >  }
> > > >
> > > > +typedef struct ZoneCmdData {
> > > > +VirtIOBlockReq *req;
> > > > +union {
> > > > +struct {
> > > > +unsigned int nr_zones;
> > > > +BlockZoneDescriptor *zones;
> > > > +} zone_report_data;
> > > > +struct {
> > > > +int64_t offset;
> > > > +} zone_append_data;
> > > > +};
> > > > +} ZoneCmdData;
> > > > +
> > > > +/*
> > > > + * check zoned_request: error checking before issuing requests. If all
> > > > checks
> > > > + * passed, return true.
> > > > + * append: true if only zone append requests issued.
> > > > + */
> > > > +static bool check_zoned_request(VirtIOBlock *s, int64_t offset, int64_t
> > > > len,
> > > > + bool append, uint8_t *status) {
> > > > +BlockDriverState *bs = blk_bs(s->blk);
> > > > +int index = offset / bs->bl.zone_size;
> > > > +
> > > > +if (offset < 0 || len < 0 || offset > bs->bl.capacity - len) {
> > > > +*status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
> > > > +return false;
> > > > +}
> > > > +
> > > > +if (!virtio_has_feature(s->host_features, VIRTIO_BLK_F_ZONED)) {
> > > > +*status = VIRTIO_BLK_S_UNSUPP;
> > > > +

Re: [PATCH v3 2/2] error handling: Use RETRY_ON_EINTR() macro where applicable

2022-10-23 Thread Nikita Ivanov
Hi!
Thanks for clarification! Corrected it in v4.

On Wed, Oct 19, 2022 at 6:24 PM Christian Schoenebeck <
qemu_...@crudebyte.com> wrote:

> On Tuesday, October 18, 2022 10:43:41 AM CEST Nikita Ivanov wrote:
> > There is a defined RETRY_ON_EINTR() macro in qemu/osdep.h
> > which handles the same while loop.
> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/415
> >
> > Signed-off-by: Nikita Ivanov 
> > ---
> >  block/file-posix.c| 37 -
> >  chardev/char-pty.c|  4 +---
> >  hw/9pfs/9p-local.c|  8 ++--
> >  net/l2tpv3.c  | 17 +
> >  net/socket.c  | 16 +++-
> >  net/tap.c |  8 ++--
> >  qga/commands-posix.c  |  4 +---
> >  semihosting/syscalls.c|  4 +---
> >  tests/qtest/libqtest.c| 12 +---
> >  tests/vhost-user-bridge.c |  4 +---
> >  util/main-loop.c  |  4 +---
> >  util/osdep.c  |  4 +---
> >  util/vfio-helpers.c   | 12 ++--
> >  13 files changed, 49 insertions(+), 85 deletions(-)
> >
> > diff --git a/block/file-posix.c b/block/file-posix.c
> > index 23acffb9a4..8f7a22e3e4 100644
> > --- a/block/file-posix.c
> > +++ b/block/file-posix.c
> > @@ -1229,9 +1229,7 @@ static int hdev_get_max_segments(int fd, struct
> stat *st)
> >  ret = -errno;
> >  goto out;
> >  }
> > -do {
> > -ret = read(sysfd, buf, sizeof(buf) - 1);
> > -} while (ret == -1 && errno == EINTR);
> > +ret = RETRY_ON_EINTR(read(sysfd, buf, sizeof(buf) - 1));
> >  if (ret < 0) {
> >  ret = -errno;
> >  goto out;
> > @@ -1379,9 +1377,9 @@ static int handle_aiocb_ioctl(void *opaque)
> >  RawPosixAIOData *aiocb = opaque;
> >  int ret;
> >
> > -do {
> > -ret = ioctl(aiocb->aio_fildes, aiocb->ioctl.cmd,
> aiocb->ioctl.buf);
> > -} while (ret == -1 && errno == EINTR);
> > +ret = RETRY_ON_EINTR(
> > +ioctl(aiocb->aio_fildes, aiocb->ioctl.cmd, aiocb->ioctl.buf)
> > +);
> >  if (ret == -1) {
> >  return -errno;
> >  }
> > @@ -1463,18 +1461,17 @@ static ssize_t
> handle_aiocb_rw_vector(RawPosixAIOData *aiocb)
> >  {
> >  ssize_t len;
> >
> > -do {
> > -if (aiocb->aio_type & QEMU_AIO_WRITE)
> > -len = qemu_pwritev(aiocb->aio_fildes,
> > -   aiocb->io.iov,
> > -   aiocb->io.niov,
> > -   aiocb->aio_offset);
> > - else
> > -len = qemu_preadv(aiocb->aio_fildes,
> > -  aiocb->io.iov,
> > -  aiocb->io.niov,
> > -  aiocb->aio_offset);
> > -} while (len == -1 && errno == EINTR);
> > +len = RETRY_ON_EINTR(
> > +(aiocb->aio_type & QEMU_AIO_WRITE) ?
> > +qemu_pwritev(aiocb->aio_fildes,
> > +   aiocb->io.iov,
> > +   aiocb->io.niov,
> > +   aiocb->aio_offset) :
> > +qemu_preadv(aiocb->aio_fildes,
> > +  aiocb->io.iov,
> > +  aiocb->io.niov,
> > +  aiocb->aio_offset)
> > +);
> >
> >  if (len == -1) {
> >  return -errno;
> > @@ -1899,9 +1896,7 @@ static int allocate_first_block(int fd, size_t
> max_size)
> >  buf = qemu_memalign(max_align, write_size);
> >  memset(buf, 0, write_size);
> >
> > -do {
> > -n = pwrite(fd, buf, write_size, 0);
> > -} while (n == -1 && errno == EINTR);
> > +n = RETRY_ON_EINTR(pwrite(fd, buf, write_size, 0));
> >
> >  ret = (n == -1) ? -errno : 0;
> >
> > diff --git a/chardev/char-pty.c b/chardev/char-pty.c
> > index 53f25c6bbd..92fd33c854 100644
> > --- a/chardev/char-pty.c
> > +++ b/chardev/char-pty.c
> > @@ -93,9 +93,7 @@ static void pty_chr_update_read_handler(Chardev *chr)
> >  pfd.fd = fioc->fd;
> >  pfd.events = G_IO_OUT;
> >  pfd.revents = 0;
> > -do {
> > -rc = g_poll(, 1, 0);
> > -} while (rc == -1 && errno == EINTR);
> > +rc = RETRY_ON_EINTR(g_poll(, 1, 0));
> >  assert(rc >= 0);
> >
> >  if (pfd.revents & G_IO_HUP) {
> > diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
> > index d42ce6d8b8..bb3187244f 100644
> > --- a/hw/9pfs/9p-local.c
> > +++ b/hw/9pfs/9p-local.c
> > @@ -470,9 +470,7 @@ static ssize_t local_readlink(FsContext *fs_ctx,
> V9fsPath *fs_path,
> >  if (fd == -1) {
> >  return -1;
> >  }
> > -do {
> > -tsize = read(fd, (void *)buf, bufsz);
> > -} while (tsize == -1 && errno == EINTR);
> > +tsize = RETRY_ON_EINTR(read(fd, (void *)buf, bufsz));
> >  close_preserve_errno(fd);
> >  } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
> > (fs_ctx->export_flags & V9FS_SM_NONE)) {
> > @@ -908,9 +906,7 @@ static int local_symlink(FsContext 

[PATCH v2 02/43] hw/i386/pc_piix: Allow for setting properties before realizing PIIX3 south bridge

2022-10-23 Thread Bernhard Beschow
The next patches will need to take advantage of it.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Peter Maydell 
---
 hw/i386/pc_piix.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7a55b9ca8e..5caef9bfc9 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -217,7 +217,8 @@ static void pc_init1(MachineState *machine,
   pci_memory, ram_memory);
 pcms->bus = pci_bus;
 
-pci_dev = pci_create_simple_multifunction(pci_bus, -1, true, type);
+pci_dev = pci_new_multifunction(-1, true, type);
+pci_realize_and_unref(pci_dev, pci_bus, _fatal);
 piix3 = PIIX3_PCI_DEVICE(pci_dev);
 piix3->pic = x86ms->gsi;
 piix3_devfn = piix3->dev.devfn;
-- 
2.38.1




Re: [PATCH v12 6/7] qemu-iotests: test new zone operations

2022-10-23 Thread Dmitry Fomichev
On Tue, 2022-10-18 at 16:41 +0800, Sam Li wrote:
> Dmitry Fomichev  于2022年10月17日周一 08:57写道:
> > 
> > On Sun, 2022-10-16 at 22:51 +0800, Sam Li wrote:
> > > We have added new block layer APIs of zoned block devices.
> > > Test it with:
> > > Create a null_blk device, run each zone operation on it and see
> > > whether reporting right zone information.
> > 
> > change this to "whether the logs show the correct zone information"?
> > 
> > > 
> > 
> > Could you please describe how to run this specific set of tests
> > in more detail?
> 
> I just run this script on the terminal directly and redirect the
> result to the output file.
> 
> Maybe?
> + Run each zone operation on a newly created null_blk device and see
> + whether the logs show the correct zone information.

Yes, this is fine. And specify the exact command line that you are using
to run the test.

> 
> > 
> > > 
> > > Signed-off-by: Sam Li 
> > > Reviewed-by: Stefan Hajnoczi 
> > > ---
> > >  tests/qemu-iotests/tests/zoned.out | 53 ++
> > >  tests/qemu-iotests/tests/zoned.sh  | 86 ++
> > >  2 files changed, 139 insertions(+)
> > >  create mode 100644 tests/qemu-iotests/tests/zoned.out
> > >  create mode 100755 tests/qemu-iotests/tests/zoned.sh
> > > 
> > > diff --git a/tests/qemu-iotests/tests/zoned.out b/tests/qemu-
> > > iotests/tests/zoned.out
> > > new file mode 100644
> > > index 00..0c8f96deb9
> > > --- /dev/null
> > > +++ b/tests/qemu-iotests/tests/zoned.out
> > > @@ -0,0 +1,53 @@
> > > +QA output created by zoned.sh
> > > +Testing a null_blk device:
> > > +Simple cases: if the operations work
> > > +(1) report the first zone:
> > > +start: 0x0, len 0x8, cap 0x8, wptr 0x0, zcond:1, [type: 2]
> > > +
> > > +report the first 10 zones
> > > +start: 0x0, len 0x8, cap 0x8, wptr 0x0, zcond:1, [type: 2]
> > > +start: 0x8, len 0x8, cap 0x8, wptr 0x8, zcond:1, [type: 
> > > 2]
> > > +start: 0x10, len 0x8, cap 0x8, wptr 0x10, zcond:1, [type:
> > > 2]
> > > +start: 0x18, len 0x8, cap 0x8, wptr 0x18, zcond:1, [type:
> > > 2]
> > > +start: 0x20, len 0x8, cap 0x8, wptr 0x20, zcond:1, [type:
> > > 2]
> > > +start: 0x28, len 0x8, cap 0x8, wptr 0x28, zcond:1, [type:
> > > 2]
> > > +start: 0x30, len 0x8, cap 0x8, wptr 0x30, zcond:1, [type:
> > > 2]
> > > +start: 0x38, len 0x8, cap 0x8, wptr 0x38, zcond:1, [type:
> > > 2]
> > > +start: 0x40, len 0x8, cap 0x8, wptr 0x40, zcond:1, [type:
> > > 2]
> > > +start: 0x48, len 0x8, cap 0x8, wptr 0x48, zcond:1, [type:
> > > 2]
> > > +
> > > +report the last zone:
> > > +start: 0x1f38, len 0x8, cap 0x8, wptr 0x1f38, zcond:1,
> > > [type:
> > > 2]
> > > +
> > > +
> > > +(2) opening the first zone
> > > +report after:
> > > +start: 0x0, len 0x8, cap 0x8, wptr 0x0, zcond:3, [type: 2]
> > > +
> > > +opening the second zone
> > > +report after:
> > > +start: 0x8, len 0x8, cap 0x8, wptr 0x8, zcond:3, [type: 
> > > 2]
> > > +
> > > +opening the last zone
> > > +report after:
> > > +start: 0x1f38, len 0x8, cap 0x8, wptr 0x1f38, zcond:3,
> > > [type:
> > > 2]
> > > +
> > > +
> > > +(3) closing the first zone
> > > +report after:
> > > +start: 0x0, len 0x8, cap 0x8, wptr 0x0, zcond:1, [type: 2]
> > > +
> > > +closing the last zone
> > > +report after:
> > > +start: 0x1f38, len 0x8, cap 0x8, wptr 0x1f38, zcond:1,
> > > [type:
> > > 2]
> > > +
> > > +
> > > +(4) finishing the second zone
> > > +After finishing a zone:
> > > +start: 0x8, len 0x8, cap 0x8, wptr 0x10, zcond:14, [type:
> > > 2]
> > > +
> > > +
> > > +(5) resetting the second zone
> > > +After resetting a zone:
> > > +start: 0x8, len 0x8, cap 0x8, wptr 0x8, zcond:1, [type: 
> > > 2]
> > > +*** done
> > > diff --git a/tests/qemu-iotests/tests/zoned.sh b/tests/qemu-
> > > iotests/tests/zoned.sh
> > > new file mode 100755
> > > index 00..fced0194c5
> > > --- /dev/null
> > > +++ b/tests/qemu-iotests/tests/zoned.sh
> > > @@ -0,0 +1,86 @@
> > > +#!/usr/bin/env bash
> > > +#
> > > +# Test zone management operations.
> > > +#
> > > +
> > > +seq="$(basename $0)"
> > > +echo "QA output created by $seq"
> > > +status=1 # failure is the default!
> > > +
> > > +_cleanup()
> > > +{
> > > +  _cleanup_test_img
> > > +  sudo rmmod null_blk
> > > +}
> > > +trap "_cleanup; exit \$status" 0 1 2 3 15
> > > +
> > > +# get standard environment, filters and checks
> > > +. ./common.rc
> > > +. ./common.filter
> > > +. ./common.qemu
> > > +
> > > +# This test only runs on Linux hosts with raw image files.
> > > +_supported_fmt raw
> > > +_supported_proto file
> > > +_supported_os Linux
> > > +
> > > +QEMU_IO="build/qemu-io"
> > > +IMG="--image-opts -n driver=zoned_host_device,filename=/dev/nullb0"
> > > +QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
> > > +
> > > +echo 

[PATCH v2 37/43] hw/isa/piix: Harmonize names of reset control memory regions

2022-10-23 Thread Bernhard Beschow
There is no need for having different names here. Having the same name
further allows code to be shared between PIIX3 and PIIX4.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix.c b/hw/isa/piix.c
index 5123474fab..55ed997b2c 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -388,7 +388,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 isa_bus_irqs(isa_bus, d->pic.in_irqs);
 
 memory_region_init_io(>rcr_mem, OBJECT(dev), _ops, d,
-  "piix3-reset-control", 1);
+  "piix-reset-control", 1);
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
 PIIX_RCR_IOPORT, >rcr_mem, 1);
 
@@ -579,7 +579,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 }
 
 memory_region_init_io(>rcr_mem, OBJECT(dev), _ops, s,
-  "reset-control", 1);
+  "piix-reset-control", 1);
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
 PIIX_RCR_IOPORT, >rcr_mem, 1);
 
-- 
2.38.1




[PATCH v2 23/43] hw/isa/piix3: Prefix pci_slot_get_pirq() with "piix3_"

2022-10-23 Thread Bernhard Beschow
The additional prefix aligns the function name with both other
piix3-internal functions as well as QEMU conventions. Furthermore, it
will help to distinguish the function from its PIIX4 counterpart once
merged.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix3.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 5214a75891..8878d71465 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -85,7 +85,7 @@ static void piix3_set_irq(void *opaque, int pirq, int level)
  * Return the global irq number corresponding to a given device irq
  * pin. We could also use the bus number to have a more precise mapping.
  */
-static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
+static int piix3_pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
 {
 int slot_addend;
 slot_addend = PCI_SLOT(pci_dev->devfn) - 1;
@@ -441,7 +441,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
-pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq,
+pci_bus_irqs(pci_bus, piix3_set_irq, piix3_pci_slot_get_pirq,
  piix3, PIIX_NUM_PIRQS);
 pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
 }
-- 
2.38.1




[PATCH v2 20/43] hw/isa/piix3: Resolve redundant PIIX_NUM_PIC_IRQS

2022-10-23 Thread Bernhard Beschow
PIIX_NUM_PIC_IRQS is assumed to be the same as ISA_NUM_IRQS, otherwise
inconsistencies can occur.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix3.c| 8 
 include/hw/southbridge/piix.h | 5 ++---
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index c6a8f1f27d..9de7287589 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -52,7 +52,7 @@ static void piix3_set_irq_level_internal(PIIX3State *piix3, 
int pirq, int level)
 uint64_t mask;
 
 pic_irq = piix3->dev.config[PIIX_PIRQCA + pirq];
-if (pic_irq >= PIIX_NUM_PIC_IRQS) {
+if (pic_irq >= ISA_NUM_IRQS) {
 return;
 }
 
@@ -66,7 +66,7 @@ static void piix3_set_irq_level(PIIX3State *piix3, int pirq, 
int level)
 int pic_irq;
 
 pic_irq = piix3->dev.config[PIIX_PIRQCA + pirq];
-if (pic_irq >= PIIX_NUM_PIC_IRQS) {
+if (pic_irq >= ISA_NUM_IRQS) {
 return;
 }
 
@@ -98,7 +98,7 @@ static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, 
int pin)
 int irq = piix3->dev.config[PIIX_PIRQCA + pin];
 PCIINTxRoute route;
 
-if (irq < PIIX_NUM_PIC_IRQS) {
+if (irq < ISA_NUM_IRQS) {
 route.mode = PCI_INTX_ENABLED;
 route.irq = irq;
 } else {
@@ -130,7 +130,7 @@ static void piix3_write_config(PCIDevice *dev,
 
 pci_bus_fire_intx_routing_notifier(pci_get_bus(>dev));
 piix3_update_irq_levels(piix3);
-for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
+for (pic_irq = 0; pic_irq < ISA_NUM_IRQS; pic_irq++) {
 piix3_set_irq_pic(piix3, pic_irq);
 }
 }
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index df3e0084c5..ae3b49fe93 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -32,7 +32,6 @@
  */
 #define PIIX_RCR_IOPORT 0xcf9
 
-#define PIIX_NUM_PIC_IRQS   16  /* i8259 * 2 */
 #define PIIX_NUM_PIRQS  4ULL/* PIRQ[A-D] */
 
 struct PIIXState {
@@ -44,10 +43,10 @@ struct PIIXState {
  * So one PIC level is tracked by PIIX_NUM_PIRQS bits.
  *
  * PIRQ is mapped to PIC pins, we track it by
- * PIIX_NUM_PIRQS * PIIX_NUM_PIC_IRQS = 64 bits with
+ * PIIX_NUM_PIRQS * ISA_NUM_IRQS = 64 bits with
  * pic_irq * PIIX_NUM_PIRQS + pirq
  */
-#if PIIX_NUM_PIC_IRQS * PIIX_NUM_PIRQS > 64
+#if ISA_NUM_IRQS * PIIX_NUM_PIRQS > 64
 #error "unable to encode pic state in 64bit in pic_levels."
 #endif
 uint64_t pic_levels;
-- 
2.38.1




[PATCH v2 17/43] hw/isa/piix3: Wire up ACPI interrupt internally

2022-10-23 Thread Bernhard Beschow
Now that PIIX3 has the PIC integrated, the ACPI controller can be wired
up internally.

Signed-off-by: Bernhard Beschow 
---
 hw/i386/pc_piix.c | 1 -
 hw/isa/piix3.c| 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 19fe07a13b..dd4e89acf9 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -313,7 +313,6 @@ static void pc_init1(MachineState *machine,
 if (piix4_pm) {
 smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
 
-qdev_connect_gpio_out(DEVICE(piix4_pm), 0, x86ms->gsi[9]);
 qdev_connect_gpio_out_named(DEVICE(piix4_pm), "smi-irq", 0, smi_irq);
 pcms->smbus = I2C_BUS(qdev_get_child_bus(DEVICE(piix4_pm), "i2c"));
 /* TODO: Populate SPD eeprom data.  */
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index bbd1dfc373..59599558a1 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -355,6 +355,8 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 if (!qdev_realize(DEVICE(>pm), BUS(pci_bus), errp)) {
 return;
 }
+qdev_connect_gpio_out(DEVICE(>pm), 0,
+  qdev_get_gpio_in(DEVICE(>pic), 9));
 }
 }
 
-- 
2.38.1




[PATCH v2 05/43] hw/isa/piix3: Modernize reset handling

2022-10-23 Thread Bernhard Beschow
Rather than registering the reset handler via a function which
appends the handler to a global list, prefer to implement it as
a virtual method - PIIX4 does the same already.

Note that this means that piix3_reset can now also be called writing to
the relevant configuration space register on a PCI bridge.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 72dbf688d9..723ad0a896 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -31,7 +31,6 @@
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
 #include "sysemu/xen.h"
-#include "sysemu/reset.h"
 #include "sysemu/runstate.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/acpi_aml_interface.h"
@@ -156,9 +155,9 @@ static void piix3_write_config_xen(PCIDevice *dev,
 piix3_write_config(dev, address, val, len);
 }
 
-static void piix3_reset(void *opaque)
+static void piix3_reset(DeviceState *dev)
 {
-PIIX3State *d = opaque;
+PIIX3State *d = PIIX3_PCI_DEVICE(dev);
 uint8_t *pci_conf = d->dev.config;
 
 pci_conf[0x04] = 0x07; /* master, memory and I/O */
@@ -313,8 +312,6 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
 PIIX_RCR_IOPORT, >rcr_mem, 1);
 
-qemu_register_reset(piix3_reset, d);
-
 i8257_dma_init(isa_bus, 0);
 }
 
@@ -337,6 +334,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
 
+dc->reset   = piix3_reset;
 dc->desc= "ISA bridge";
 dc->vmsd= _piix3;
 dc->hotpluggable   = false;
-- 
2.38.1




[PATCH v2 43/43] hw/i386/acpi-build: Resolve PIIX ISA bridge rather than ACPI controller

2022-10-23 Thread Bernhard Beschow
Resolving the PIIX ISA bridge rather than the PIIX ACPI controller mirrors
the ICH9 code one line below.

Signed-off-by: Bernhard Beschow 
---
 hw/i386/acpi-build.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index c006db72e8..d705ff6f3d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -288,7 +288,7 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 
 static void acpi_get_misc_info(AcpiMiscInfo *info)
 {
-Object *piix = object_resolve_type_unambiguous(TYPE_PIIX4_PM);
+Object *piix = object_resolve_type_unambiguous(TYPE_PIIX_PCI_DEVICE);
 Object *lpc = object_resolve_type_unambiguous(TYPE_ICH9_LPC_DEVICE);
 assert(!!piix != !!lpc);
 
-- 
2.38.1




[PATCH v2 29/43] hw/isa/piix4: Make PIIX4's ACPI and USB functions optional

2022-10-23 Thread Bernhard Beschow
This aligns PIIX4 with PIIX3.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix4.c  | 44 
 hw/mips/malta.c |  6 --
 2 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index a7389ff193..fc698c23be 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -51,9 +51,16 @@ struct PIIX4State {
 PCIIDEState ide;
 UHCIState uhci;
 PIIX4PMState pm;
+
+uint32_t smb_io_base;
+
 /* Reset Control Register */
 MemoryRegion rcr_mem;
 uint8_t rcr;
+
+bool has_acpi;
+bool has_usb;
+bool smm_enabled;
 };
 
 OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_PCI_DEVICE)
@@ -259,17 +266,26 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 }
 
 /* USB */
-qdev_prop_set_int32(DEVICE(>uhci), "addr", dev->devfn + 2);
-if (!qdev_realize(DEVICE(>uhci), BUS(pci_bus), errp)) {
-return;
+if (s->has_usb) {
+object_initialize_child(OBJECT(dev), "uhci", >uhci,
+TYPE_PIIX4_USB_UHCI);
+qdev_prop_set_int32(DEVICE(>uhci), "addr", dev->devfn + 2);
+if (!qdev_realize(DEVICE(>uhci), BUS(pci_bus), errp)) {
+return;
+}
 }
 
 /* ACPI controller */
-qdev_prop_set_int32(DEVICE(>pm), "addr", dev->devfn + 3);
-if (!qdev_realize(DEVICE(>pm), BUS(pci_bus), errp)) {
-return;
+if (s->has_acpi) {
+object_initialize_child(OBJECT(s), "pm", >pm, TYPE_PIIX4_PM);
+qdev_prop_set_int32(DEVICE(>pm), "addr", dev->devfn + 3);
+qdev_prop_set_uint32(DEVICE(>pm), "smb_io_base", s->smb_io_base);
+qdev_prop_set_bit(DEVICE(>pm), "smm-enabled", s->smm_enabled);
+if (!qdev_realize(DEVICE(>pm), BUS(pci_bus), errp)) {
+return;
+}
+qdev_connect_gpio_out(DEVICE(>pm), 0, s->isa[9]);
 }
-qdev_connect_gpio_out(DEVICE(>pm), 0, s->isa[9]);
 
 pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS);
 }
@@ -280,13 +296,16 @@ static void piix4_init(Object *obj)
 
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 object_initialize_child(obj, "ide", >ide, TYPE_PIIX4_IDE);
-object_initialize_child(obj, "uhci", >uhci, TYPE_PIIX4_USB_UHCI);
-
-object_initialize_child(obj, "pm", >pm, TYPE_PIIX4_PM);
-qdev_prop_set_uint32(DEVICE(>pm), "smb_io_base", 0x1100);
-qdev_prop_set_bit(DEVICE(>pm), "smm-enabled", 0);
 }
 
+static Property piix4_props[] = {
+DEFINE_PROP_UINT32("smb_io_base", PIIX4State, smb_io_base, 0),
+DEFINE_PROP_BOOL("has-acpi", PIIX4State, has_acpi, true),
+DEFINE_PROP_BOOL("has-usb", PIIX4State, has_usb, true),
+DEFINE_PROP_BOOL("smm-enabled", PIIX4State, smm_enabled, false),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void piix4_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -305,6 +324,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
  */
 dc->user_creatable = false;
 dc->hotpluggable = false;
+device_class_set_props(dc, piix4_props);
 }
 
 static const TypeInfo piix4_info = {
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index a4b866a2cf..6339b0d66c 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1400,8 +1400,10 @@ void mips_malta_init(MachineState *machine)
 empty_slot_init("GT64120", 0, 0x2000);
 
 /* Southbridge */
-piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true,
-TYPE_PIIX4_PCI_DEVICE);
+piix4 = pci_new_multifunction(PCI_DEVFN(10, 0), true,
+  TYPE_PIIX4_PCI_DEVICE);
+qdev_prop_set_uint32(DEVICE(piix4), "smb_io_base", 0x1100);
+pci_realize_and_unref(piix4, pci_bus, _fatal);
 isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0"));
 
 dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "ide"));
-- 
2.38.1




[PATCH v2 15/43] hw/isa/piix3: Create ISA PIC in host device

2022-10-23 Thread Bernhard Beschow
Use the newly introduced i8259 proxy "isa-pic" which allows for wiring
up devices in the southbridge where the virtualization technology used
(KVM, TCG, Xen) is not yet known.

Signed-off-by: Bernhard Beschow 
---
 hw/i386/pc_piix.c | 15 +--
 hw/isa/Kconfig|  1 +
 hw/isa/piix3.c| 10 +-
 include/hw/southbridge/piix.h |  4 ++--
 4 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index c96d989636..f81e91220f 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -207,10 +207,11 @@ static void pc_init1(MachineState *machine,
 gsi_state = pc_gsi_create(>gsi, pcmc->pci_enabled);
 
 if (pcmc->pci_enabled) {
-PIIX3State *piix3;
+DeviceState *dev;
 PCIDevice *pci_dev;
 const char *type = xen_enabled() ? TYPE_PIIX3_XEN_DEVICE
  : TYPE_PIIX3_DEVICE;
+int i;
 
 pci_bus = i440fx_init(pci_type,
   i440fx_host,
@@ -231,10 +232,12 @@ static void pc_init1(MachineState *machine,
  x86_machine_is_smm_enabled(x86ms),
  _abort);
 pci_realize_and_unref(pci_dev, pci_bus, _fatal);
-piix3 = PIIX3_PCI_DEVICE(pci_dev);
-piix3->pic = x86ms->gsi;
-piix3_devfn = piix3->dev.devfn;
-isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
+dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "pic"));
+for (i = 0; i < ISA_NUM_IRQS; i++) {
+qdev_connect_gpio_out(dev, i, x86ms->gsi[i]);
+}
+piix3_devfn = pci_dev->devfn;
+isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci_dev), "isa.0"));
 rtc_state = ISA_DEVICE(object_resolve_path_component(OBJECT(pci_dev),
  "rtc"));
 piix4_pm = object_resolve_path_component(OBJECT(pci_dev), "pm");
@@ -243,6 +246,7 @@ static void pc_init1(MachineState *machine,
 piix4_pm = NULL;
 isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
   _abort);
+isa_bus_irqs(isa_bus, x86ms->gsi);
 
 rtc_state = isa_new(TYPE_MC146818_RTC);
 qdev_prop_set_int32(DEVICE(rtc_state), "base_year", 2000);
@@ -251,7 +255,6 @@ static void pc_init1(MachineState *machine,
 i8257_dma_init(isa_bus, 0);
 pcms->hpet_enabled = false;
 }
-isa_bus_irqs(isa_bus, x86ms->gsi);
 
 if (x86ms->pic == ON_OFF_AUTO_ON || x86ms->pic == ON_OFF_AUTO_AUTO) {
 pc_i8259_create(isa_bus, gsi_state->i8259_irq);
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index f10daa26bc..24e79a9a41 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -35,6 +35,7 @@ config PIIX3
 bool
 select ACPI_PIIX4
 select I8257
+select I8259
 select ISA_BUS
 select MC146818RTC
 select USB_UHCI
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index a4b8ebd5f5..ce3ec84e22 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -40,7 +40,7 @@
 
 static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
 {
-qemu_set_irq(piix3->pic[pic_irq],
+qemu_set_irq(piix3->pic.in_irqs[pic_irq],
  !!(piix3->pic_levels &
 (((1ULL << PIIX_NUM_PIRQS) - 1) <<
  (pic_irq * PIIX_NUM_PIRQS;
@@ -309,6 +309,13 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
+/* PIC */
+if (!qdev_realize(DEVICE(>pic), BUS(isa_bus), errp)) {
+return;
+}
+
+isa_bus_irqs(isa_bus, d->pic.in_irqs);
+
 memory_region_init_io(>rcr_mem, OBJECT(dev), _ops, d,
   "piix3-reset-control", 1);
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
@@ -361,6 +368,7 @@ static void pci_piix3_init(Object *obj)
 {
 PIIX3State *d = PIIX3_PCI_DEVICE(obj);
 
+object_initialize_child(obj, "pic", >pic, TYPE_ISA_PIC);
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 }
 
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 1c291cc954..7178147b75 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -15,6 +15,7 @@
 #include "hw/pci/pci.h"
 #include "qom/object.h"
 #include "hw/acpi/piix4.h"
+#include "hw/intc/i8259.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/usb/hcd-uhci.h"
 
@@ -50,11 +51,10 @@ struct PIIXState {
 #endif
 uint64_t pic_levels;
 
-qemu_irq *pic;
-
 /* This member isn't used. Just for save/load compatibility */
 int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
 
+ISAPICState pic;
 RTCState rtc;
 UHCIState uhci;
 PIIX4PMState pm;
-- 
2.38.1




[PATCH v2 00/43] Consolidate PIIX south bridges

2022-10-23 Thread Bernhard Beschow
This series consolidates the implementations of the PIIX3 and PIIX4 south
bridges and is an extended version of [1]. The motivation is to share as much
code as possible and to bring both device models to feature parity such that
perhaps PIIX4 can become a drop-in-replacement for PIIX3 in the pc machine. This
could resolve the "Frankenstein" PIIX4-PM problem in PIIX3 discussed on this
list before.

The series is structured as follows: First, PIIX3 is changed to instantiate
internal devices itself, like PIIX4 does already. Second, PIIX3 gets prepared
for the merge with PIIX4 which includes some fixes, cleanups, and renamings.
Third, the same is done for PIIX4. In step four the implementations are merged.
Since some consolidations could be done easier with merged implementations, the
consolidation continues in step five which concludes the series.

One particular challenge in this series was that the PIC of PIIX3 used to be
instantiated outside of the south bridge while some sub functions require a PIC
with populated qemu_irqs. This has been solved by introducing a proxy PIC which
furthermore allows PIIX3 to be agnostic towards the virtualization technology
used (KVM, TCG, Xen). Due to consolidation PIIX4 gained the PIC as well,
possibly allowing the Malta board to gain KVM capabilities in the future.

Another challenge was dealing with optional devices where Peter already gave
advice in [1] which this series implements.

A challenge still remains with consolidating PCI interrupt handling. There are
still board-specific piix3_pci_slot_get_pirq() and piix4_pci_slot_get_pirq()
which are implemented in isa/piix.c. Any advice how to resolve these would be
highly appreaciated.

Last but not least there might be some opportunity to consolidate VM state
handling, probably by reusing the one from PIIX3. Since I'm not very familiar
with the requirements I didn't touch it so far.

Testing done:
* make check
* make check-avocado
* Boot live CD:
  * `qemu-system-x86_64 -M pc -m 2G -accel kvm -cpu host -cdrom 
manjaro-kde-21.3.2-220704-linux515.iso`
  * `qemu-system-x86_64 -M q35 -m 2G -accel kvm -cpu host -cdrom 
manjaro-kde-21.3.2-220704-linux515.iso`
* 'qemu-system-mips64el -M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda 
debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"`

[1] https://lists.nongnu.org/archive/html/qemu-devel/2022-07/msg02348.html

v2:
- Introduce TYPE_ defines for IDE and USB device models (Mark)
- Omit unexporting of PIIXState (Mark)
- Improve commit message of patch 5 to mention reset triggering through PCI
  configuration space (Mark)
- Move reviewed patches w/o dependencies to the bottom of the series for early
  upstreaming -> @Michael?

Bernhard Beschow (43):
  hw/i386/pc: Create DMA controllers in south bridges
  hw/i386/pc_piix: Allow for setting properties before realizing PIIX3
south bridge
  hw/isa/piix3: Remove extra ';' outside of functions
  hw/isa/piix3: Add size constraints to rcr_ops
  hw/isa/piix3: Modernize reset handling
  hw/isa/piix3: Prefer pci_address_space() over get_system_memory()
  hw/isa/piix4: Rename wrongly named method
  hw/ide/piix: Introduce TYPE_ macros for PIIX IDE controllers
  hw/usb/hcd-uhci: Introduce TYPE_ defines for device models
  hw/i386/pc: Create RTC controllers in south bridges
  hw/i386/pc: No need for rtc_state to be an out-parameter
  hw/isa/piix3: Create USB controller in host device
  hw/isa/piix3: Create power management controller in host device
  hw/intc/i8259: Introduce i8259 proxy "isa-pic"
  hw/isa/piix3: Create ISA PIC in host device
  hw/isa/piix3: Create IDE controller in host device
  hw/isa/piix3: Wire up ACPI interrupt internally
  hw/isa/piix3: Remove unused include
  hw/isa/piix3: Allow board to provide PCI interrupt routes
  hw/isa/piix3: Resolve redundant PIIX_NUM_PIC_IRQS
  hw/isa/piix3: Rename pci_piix3_props for sharing with PIIX4
  hw/isa/piix3: Rename piix3_reset() for sharing with PIIX4
  hw/isa/piix3: Prefix pci_slot_get_pirq() with "piix3_"
  hw/isa/piix3: Rename typedef PIIX3State to PIIXState
  hw/mips/malta: Reuse dev variable
  meson: Fix dependencies of piix4 southbridge
  hw/isa/piix4: Add missing initialization
  hw/isa/piix4: Move pci_ide_create_devs() call to board code
  hw/isa/piix4: Make PIIX4's ACPI and USB functions optional
  hw/isa/piix4: Allow board to provide PCI interrupt routes
  hw/isa/piix4: Remove unused code
  hw/isa/piix4: Use ISA PIC device
  hw/isa/piix4: Reuse struct PIIXState from PIIX3
  hw/isa/piix4: Rename reset control operations to match PIIX3
  hw/isa/piix4: Prefix pci_slot_get_pirq() with "piix4_"
  hw/isa/piix3: Merge hw/isa/piix4.c
  hw/isa/piix: Harmonize names of reset control memory regions
  hw/isa/piix: Reuse PIIX3 base class' realize method in PIIX4
  hw/isa/piix: Rename functions to be shared for interrupt triggering
  hw/isa/piix: Consolidate IRQ triggering
  hw/isa/piix: Share PIIX3 base class with PIIX4
  hw/isa/piix: Drop the "3" from the PIIX base 

[PATCH v2 31/43] hw/isa/piix4: Remove unused code

2022-10-23 Thread Bernhard Beschow
The Malta board, which is the only user of PIIX4, doesn't connect to the
exported interrupt lines.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix4.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 57b0b98bef..d65f486008 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -182,12 +182,6 @@ static void piix4_request_i8259_irq(void *opaque, int irq, 
int level)
 qemu_set_irq(s->cpu_intr, level);
 }
 
-static void piix4_set_i8259_irq(void *opaque, int irq, int level)
-{
-PIIX4State *s = opaque;
-qemu_set_irq(s->isa[irq], level);
-}
-
 static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
 unsigned int len)
 {
@@ -231,8 +225,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
-qdev_init_gpio_in_named(DEVICE(dev), piix4_set_i8259_irq,
-"isa", ISA_NUM_IRQS);
 qdev_init_gpio_out_named(DEVICE(dev), >cpu_intr,
  "intr", 1);
 
-- 
2.38.1




[PATCH v2 28/43] hw/isa/piix4: Move pci_ide_create_devs() call to board code

2022-10-23 Thread Bernhard Beschow
For the VIA south bridges there was a comment to have the call in board code.
Move it there for PIIX4 as well for consistency.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c  |  1 -
 hw/mips/malta.c | 10 ++
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 4b8dece257..a7389ff193 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -257,7 +257,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 if (!qdev_realize(DEVICE(>ide), BUS(pci_bus), errp)) {
 return;
 }
-pci_ide_create_devs(PCI_DEVICE(>ide));
 
 /* USB */
 qdev_prop_set_int32(DEVICE(>uhci), "addr", dev->devfn + 2);
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 0ec2ac2eaf..a4b866a2cf 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -39,7 +39,7 @@
 #include "hw/pci/pci.h"
 #include "qemu/log.h"
 #include "hw/mips/bios.h"
-#include "hw/ide.h"
+#include "hw/ide/pci.h"
 #include "hw/irq.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -1402,11 +1402,13 @@ void mips_malta_init(MachineState *machine)
 /* Southbridge */
 piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true,
 TYPE_PIIX4_PCI_DEVICE);
-dev = DEVICE(piix4);
-isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0"));
+
+dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "ide"));
+pci_ide_create_devs(PCI_DEVICE(dev));
 
 /* Interrupt controller */
-qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
+qdev_connect_gpio_out_named(DEVICE(piix4), "intr", 0, i8259_irq);
 
 /* generate SPD EEPROM data */
 dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
-- 
2.38.1




[PATCH v2 11/43] hw/i386/pc: No need for rtc_state to be an out-parameter

2022-10-23 Thread Bernhard Beschow
Now that the RTC is created as part of the southbridges it doesn't need
to be an out-parameter any longer.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Peter Maydell 
---
 hw/i386/pc.c | 12 ++--
 hw/i386/pc_piix.c|  2 +-
 hw/i386/pc_q35.c |  2 +-
 include/hw/i386/pc.h |  2 +-
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 8f72aedea4..8619a295f2 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1248,7 +1248,7 @@ static void pc_superio_init(ISABus *isa_bus, bool 
create_fdctrl,
 
 void pc_basic_device_init(struct PCMachineState *pcms,
   ISABus *isa_bus, qemu_irq *gsi,
-  ISADevice **rtc_state,
+  ISADevice *rtc_state,
   bool create_fdctrl,
   uint32_t hpet_irqs)
 {
@@ -1303,17 +1303,17 @@ void pc_basic_device_init(struct PCMachineState *pcms,
 }
 
 if (rtc_irq) {
-qdev_connect_gpio_out(DEVICE(*rtc_state), 0, rtc_irq);
+qdev_connect_gpio_out(DEVICE(rtc_state), 0, rtc_irq);
 } else {
-uint32_t irq = object_property_get_uint(OBJECT(*rtc_state),
+uint32_t irq = object_property_get_uint(OBJECT(rtc_state),
 "irq",
 _fatal);
-isa_connect_gpio_out(*rtc_state, 0, irq);
+isa_connect_gpio_out(rtc_state, 0, irq);
 }
-object_property_add_alias(OBJECT(pcms), "rtc-time", OBJECT(*rtc_state),
+object_property_add_alias(OBJECT(pcms), "rtc-time", OBJECT(rtc_state),
   "date");
 
-qemu_register_boot_set(pc_boot_set, *rtc_state);
+qemu_register_boot_set(pc_boot_set, rtc_state);
 
 if (!xen_enabled() &&
 (x86ms->pit == ON_OFF_AUTO_AUTO || x86ms->pit == ON_OFF_AUTO_ON)) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7de2f1092b..b97bff5674 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -262,7 +262,7 @@ static void pc_init1(MachineState *machine,
 }
 
 /* init basic PC hardware */
-pc_basic_device_init(pcms, isa_bus, x86ms->gsi, _state, true,
+pc_basic_device_init(pcms, isa_bus, x86ms->gsi, rtc_state, true,
  0x4);
 
 pc_nic_init(pcmc, isa_bus, pci_bus);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index bf0888db97..bee932fb8f 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -293,7 +293,7 @@ static void pc_q35_init(MachineState *machine)
 }
 
 /* init basic PC hardware */
-pc_basic_device_init(pcms, isa_bus, x86ms->gsi, _state, !mc->no_floppy,
+pc_basic_device_init(pcms, isa_bus, x86ms->gsi, rtc_state, !mc->no_floppy,
  0xff0104);
 
 /* connect pm stuff to lpc */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index c95333514e..0cf3ccdf0d 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -169,7 +169,7 @@ uint64_t pc_pci_hole64_start(void);
 DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
 void pc_basic_device_init(struct PCMachineState *pcms,
   ISABus *isa_bus, qemu_irq *gsi,
-  ISADevice **rtc_state,
+  ISADevice *rtc_state,
   bool create_fdctrl,
   uint32_t hpet_irqs);
 void pc_cmos_init(PCMachineState *pcms,
-- 
2.38.1




[PATCH v2 42/43] hw/isa/piix: Drop the "3" from the PIIX base class

2022-10-23 Thread Bernhard Beschow
Now that the base class is used for both PIIX3 and PIIX4, the "3"
became misleading.

Signed-off-by: Bernhard Beschow 
---
 hw/i386/acpi-build.c  | 2 +-
 hw/isa/piix.c | 8 
 include/hw/southbridge/piix.h | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4f54b61904..c006db72e8 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1298,7 +1298,7 @@ static void build_piix4_isa_bridge(Aml *table)
  * once PCI is converted to AcpiDevAmlIf and would be ble to generate
  * AML for bridge itself
  */
-obj = object_resolve_path_type("", TYPE_PIIX3_PCI_DEVICE, );
+obj = object_resolve_path_type("", TYPE_PIIX_PCI_DEVICE, );
 assert(obj && !ambiguous);
 
 scope =  aml_scope("_SB.PCI0");
diff --git a/hw/isa/piix.c b/hw/isa/piix.c
index c8c1a99bf1..a361261940 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -463,7 +463,7 @@ static void pci_piix_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo piix_pci_type_info = {
-.name = TYPE_PIIX3_PCI_DEVICE,
+.name = TYPE_PIIX_PCI_DEVICE,
 .parent = TYPE_PCI_DEVICE,
 .instance_size = sizeof(PIIXState),
 .instance_init = pci_piix_init,
@@ -513,7 +513,7 @@ static void piix3_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo piix3_info = {
 .name  = TYPE_PIIX3_DEVICE,
-.parent= TYPE_PIIX3_PCI_DEVICE,
+.parent= TYPE_PIIX_PCI_DEVICE,
 .instance_init = piix3_init,
 .class_init= piix3_class_init,
 };
@@ -553,7 +553,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void 
*data)
 
 static const TypeInfo piix3_xen_info = {
 .name  = TYPE_PIIX3_XEN_DEVICE,
-.parent= TYPE_PIIX3_PCI_DEVICE,
+.parent= TYPE_PIIX_PCI_DEVICE,
 .instance_init = piix3_init,
 .class_init= piix3_xen_class_init,
 };
@@ -602,7 +602,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo piix4_info = {
 .name  = TYPE_PIIX4_PCI_DEVICE,
-.parent= TYPE_PIIX3_PCI_DEVICE,
+.parent= TYPE_PIIX_PCI_DEVICE,
 .instance_init = piix4_init,
 .class_init= piix4_class_init,
 };
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index c9fa0f1aa6..c21b69e2be 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -75,9 +75,9 @@ struct PIIXState {
 };
 typedef struct PIIXState PIIXState;
 
-#define TYPE_PIIX3_PCI_DEVICE "pci-piix3"
+#define TYPE_PIIX_PCI_DEVICE "pci-piix"
 DECLARE_INSTANCE_CHECKER(PIIXState, PIIX_PCI_DEVICE,
- TYPE_PIIX3_PCI_DEVICE)
+ TYPE_PIIX_PCI_DEVICE)
 
 #define TYPE_PIIX3_DEVICE "PIIX3"
 #define TYPE_PIIX3_XEN_DEVICE "PIIX3-xen"
-- 
2.38.1




[PATCH v2 16/43] hw/isa/piix3: Create IDE controller in host device

2022-10-23 Thread Bernhard Beschow
Now that PIIX3 contains the new isa-pic, it is possible to instantiate
PIIX3 IDE in the PIIX3 southbridge. PIIX3 IDE wires up its interrupts to
the ISA bus in its realize method which requires the interrupt
controller to provide fully populated qemu_irqs. This is the case for
isa-pic even though the virtualization technology not known yet.

Signed-off-by: Bernhard Beschow 
---
 hw/i386/Kconfig   |  1 -
 hw/i386/pc_piix.c | 15 ++-
 hw/isa/Kconfig|  1 +
 hw/isa/piix3.c|  8 
 include/hw/southbridge/piix.h |  2 ++
 5 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index d22ac4a4b9..dd247f215c 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -74,7 +74,6 @@ config I440FX
 select ACPI_SMBUS
 select PCI_I440FX
 select PIIX3
-select IDE_PIIX
 select DIMM
 select SMBIOS
 select FW_CFG_DMA
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index f81e91220f..19fe07a13b 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -41,7 +41,6 @@
 #include "hw/usb.h"
 #include "net/net.h"
 #include "hw/ide/pci.h"
-#include "hw/ide/piix.h"
 #include "hw/irq.h"
 #include "sysemu/kvm.h"
 #include "hw/kvm/clock.h"
@@ -86,7 +85,6 @@ static void pc_init1(MachineState *machine,
 PCIBus *pci_bus;
 ISABus *isa_bus;
 Object *piix4_pm;
-int piix3_devfn = -1;
 qemu_irq smi_irq;
 GSIState *gsi_state;
 BusState *idebus[MAX_IDE_BUS];
@@ -236,11 +234,14 @@ static void pc_init1(MachineState *machine,
 for (i = 0; i < ISA_NUM_IRQS; i++) {
 qdev_connect_gpio_out(dev, i, x86ms->gsi[i]);
 }
-piix3_devfn = pci_dev->devfn;
 isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci_dev), "isa.0"));
 rtc_state = ISA_DEVICE(object_resolve_path_component(OBJECT(pci_dev),
  "rtc"));
 piix4_pm = object_resolve_path_component(OBJECT(pci_dev), "pm");
+dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
+pci_ide_create_devs(PCI_DEVICE(dev));
+idebus[0] = qdev_get_child_bus(dev, "ide.0");
+idebus[1] = qdev_get_child_bus(dev, "ide.1");
 } else {
 pci_bus = NULL;
 piix4_pm = NULL;
@@ -254,6 +255,8 @@ static void pc_init1(MachineState *machine,
 
 i8257_dma_init(isa_bus, 0);
 pcms->hpet_enabled = false;
+idebus[0] = NULL;
+idebus[1] = NULL;
 }
 
 if (x86ms->pic == ON_OFF_AUTO_ON || x86ms->pic == ON_OFF_AUTO_AUTO) {
@@ -282,12 +285,6 @@ static void pc_init1(MachineState *machine,
 pc_nic_init(pcmc, isa_bus, pci_bus);
 
 if (pcmc->pci_enabled) {
-PCIDevice *dev;
-
-dev = pci_create_simple(pci_bus, piix3_devfn + 1, TYPE_PIIX3_IDE);
-pci_ide_create_devs(dev);
-idebus[0] = qdev_get_child_bus(>qdev, "ide.0");
-idebus[1] = qdev_get_child_bus(>qdev, "ide.1");
 pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
 }
 #ifdef CONFIG_IDE_ISA
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 24e79a9a41..a021e1cbfc 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -36,6 +36,7 @@ config PIIX3
 select ACPI_PIIX4
 select I8257
 select I8259
+select IDE_PIIX
 select ISA_BUS
 select MC146818RTC
 select USB_UHCI
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index ce3ec84e22..bbd1dfc373 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -29,6 +29,7 @@
 #include "hw/southbridge/piix.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/ide/piix.h"
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
 #include "sysemu/xen.h"
@@ -329,6 +330,12 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
+/* IDE */
+qdev_prop_set_int32(DEVICE(>ide), "addr", dev->devfn + 1);
+if (!qdev_realize(DEVICE(>ide), BUS(pci_bus), errp)) {
+return;
+}
+
 /* USB */
 if (d->has_usb) {
 object_initialize_child(OBJECT(dev), "uhci", >uhci,
@@ -370,6 +377,7 @@ static void pci_piix3_init(Object *obj)
 
 object_initialize_child(obj, "pic", >pic, TYPE_ISA_PIC);
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
+object_initialize_child(obj, "ide", >ide, TYPE_PIIX3_IDE);
 }
 
 static Property pci_piix3_props[] = {
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 7178147b75..1f22eb1444 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -15,6 +15,7 @@
 #include "hw/pci/pci.h"
 #include "qom/object.h"
 #include "hw/acpi/piix4.h"
+#include "hw/ide/pci.h"
 #include "hw/intc/i8259.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/usb/hcd-uhci.h"
@@ -56,6 +57,7 @@ struct PIIXState {
 
 ISAPICState pic;
 RTCState rtc;
+PCIIDEState ide;
 UHCIState uhci;
 PIIX4PMState pm;
 
-- 
2.38.1




[PATCH v2 26/43] meson: Fix dependencies of piix4 southbridge

2022-10-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 configs/devices/mips-softmmu/common.mak | 1 -
 hw/isa/Kconfig  | 6 ++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/configs/devices/mips-softmmu/common.mak 
b/configs/devices/mips-softmmu/common.mak
index d2202c839e..416161f833 100644
--- a/configs/devices/mips-softmmu/common.mak
+++ b/configs/devices/mips-softmmu/common.mak
@@ -23,7 +23,6 @@ CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
-CONFIG_IDE_PIIX=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_I8259=y
 CONFIG_MC146818RTC=y
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index a021e1cbfc..1aa10f84f2 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -45,7 +45,13 @@ config PIIX4
 bool
 # For historical reasons, SuperIO devices are created in the board
 # for PIIX4.
+select ACPI_PIIX4
+select I8254
+select I8257
+select I8259
+select IDE_PIIX
 select ISA_BUS
+select MC146818RTC
 select USB_UHCI
 
 config VT82C686
-- 
2.38.1




Re: [PATCH v4 0/7] ppc/e500: Add support for two types of flash, cleanup

2022-10-23 Thread Bernhard Beschow
Am 18. Oktober 2022 21:01:39 UTC schrieb Bernhard Beschow :
>Cover letter:
>
>~
>
>
>
>This series adds support for -pflash and direct SD card access to the
>
>PPC e500 boards. The idea is to increase compatibility with "real" firmware
>
>images where only the bare minimum of drivers is compiled in.
>
>
>
>The series is structured as follows:
>
>
>
>Patches 1-4 perform some general cleanup which paves the way for the rest of
>
>the series.
>
>
>
>Patch 5 adds -pflash handling where memory-mapped flash can be added on
>
>user's behalf. That is, the flash memory region in the eLBC is only added if
>
>the -pflash argument is supplied. Note that the cfi01 device model becomes
>
>stricter in checking the size of the emulated flash space.
>
>
>
>Patches 6 and 7 add a new device model - the Freescale eSDHC - to the e500
>
>boards which was missing so far.
>
>
>
>User documentation is also added as the new features become available.
>
>
>
>Tesing done:
>
>* `qemu-system-ppc -M ppce500 -cpu e500mc -m 256 -kernel uImage -append
>
>"console=ttyS0 rootwait root=/dev/mtdblock0 nokaslr" -drive
>
>if=pflash,file=rootfs.ext2,format=raw`
>
>* `qemu-system-ppc -M ppce500 -cpu e500mc -m 256 -kernel uImage -append
>
>"console=ttyS0 rootwait root=/dev/mmcblk0" -device sd-card,drive=mydrive -drive
>
>id=mydrive,if=none,file=rootfs.ext2,format=raw`
>
>
>
>The load was created using latest Buildroot with `make
>
>qemu_ppc_e500mc_defconfig` where the rootfs was configured to be of ext2 type.
>
>In both cases it was possible to log in and explore the root file system.
>
>
>
>v4:
>
>~~~
>
>Zoltan:
>
>- Don't suggest presence of qemu-system-ppc32 in documentation
>
>
>
>Bin:
>
>- New patch: docs/system/ppc/ppce500: Use qemu-system-ppc64 across the board(s)
>
>
>
>Peter:
>
>- Inline pflash_cfi01_register() rather than modify it (similar to v2)
>

Ping

>
>
>v3:
>
>~~~
>
>Phil:
>
>- Also add power-of-2 fix to pflash_cfi02
>
>- Resolve cfi01-specific assertion in e500 code
>
>- Resolve unused define in eSDHC device model
>
>- Resolve redundant alignment checks in eSDHC device model
>
>
>
>Bin:
>
>- Add dedicated flash chapter to documentation
>
>
>
>Bernhard:
>
>- Use is_power_of_2() instead of ctpop64() for better readability
>
>- Only instantiate eSDHC device model in ppce500 (not used in MPC8544DS)
>
>- Rebase onto gitlab.com/danielhb/qemu/tree/ppc-next
>
>
>
>v2:
>
>~~~
>
>Bin:
>
>- Add source for MPC8544DS platform bus' memory map in commit message.
>
>- Keep "ESDHC" in comment referring to Linux driver.
>
>- Use "qemu-system-ppc{64|32} in documentation.
>
>- Use g_autofree in device tree code.
>
>- Remove unneeded device tree properties.
>
>- Error out if pflash size doesn't fit into eLBC memory window.
>
>- Remove unused ESDHC defines.
>
>- Define macro ESDHC_WML for register offset with magic constant.
>
>- Fix some whitespace issues when adding eSDHC device to e500.
>
>
>
>Phil:
>
>- Fix tense in commit message.
>
>
>
>Bernhard Beschow (7):
>
>  docs/system/ppc/ppce500: Use qemu-system-ppc64 across the board(s)
>
>  hw/block/pflash_cfi0{1,2}: Error out if device length isn't a power of
>
>two
>
>  hw/sd/sdhci-internal: Unexport ESDHC defines
>
>  hw/sd/sdhci: Rename ESDHC_* defines to USDHC_*
>
>  hw/ppc/e500: Implement pflash handling
>
>  hw/sd/sdhci: Implement Freescale eSDHC device model
>
>  hw/ppc/e500: Add Freescale eSDHC to e500plat
>
>
>
> docs/system/ppc/ppce500.rst |  38 +++-
>
> hw/block/pflash_cfi01.c |   8 +-
>
> hw/block/pflash_cfi02.c |   5 +
>
> hw/ppc/Kconfig  |   2 +
>
> hw/ppc/e500.c   | 114 +-
>
> hw/ppc/e500.h   |   1 +
>
> hw/ppc/e500plat.c   |   1 +
>
> hw/sd/sdhci-internal.h  |  20 
>
> hw/sd/sdhci.c   | 183 +++-
>
> include/hw/sd/sdhci.h   |   3 +
>
> 10 files changed, 324 insertions(+), 51 deletions(-)
>
>
>
>-- >
>2.38.0
>
>
>




[PATCH v2 07/43] hw/isa/piix4: Rename wrongly named method

2022-10-23 Thread Bernhard Beschow
This method post-loads the southbridge, not the IDE device.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 15f344dbb7..c88d3bf3bf 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -141,7 +141,7 @@ static void piix4_isa_reset(DeviceState *dev)
 pci_conf[0xae] = 0x00;
 }
 
-static int piix4_ide_post_load(void *opaque, int version_id)
+static int piix4_post_load(void *opaque, int version_id)
 {
 PIIX4State *s = opaque;
 
@@ -156,7 +156,7 @@ static const VMStateDescription vmstate_piix4 = {
 .name = "PIIX4",
 .version_id = 3,
 .minimum_version_id = 2,
-.post_load = piix4_ide_post_load,
+.post_load = piix4_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_PCI_DEVICE(dev, PIIX4State),
 VMSTATE_UINT8_V(rcr, PIIX4State, 3),
-- 
2.38.1




[PATCH v2 06/43] hw/isa/piix3: Prefer pci_address_space() over get_system_memory()

2022-10-23 Thread Bernhard Beschow
get_system_memory() accesses global state while pci_address_space() uses
whatever has been passed to the device instance, so avoid the global.
Moreover, PIIX4 uses pci_address_space() here as well.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 723ad0a896..0bea4aefe7 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -301,7 +301,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 PIIX3State *d = PIIX3_PCI_DEVICE(dev);
 ISABus *isa_bus;
 
-isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
+isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev),
   pci_address_space_io(dev), errp);
 if (!isa_bus) {
 return;
-- 
2.38.1




[PATCH v2 10/43] hw/i386/pc: Create RTC controllers in south bridges

2022-10-23 Thread Bernhard Beschow
Just like in the real hardware (and in PIIX4), create the RTC
controllers in the south bridges.

Signed-off-by: Bernhard Beschow 
---
 hw/i386/pc.c  | 12 +++-
 hw/i386/pc_piix.c |  8 
 hw/i386/pc_q35.c  |  1 +
 hw/isa/Kconfig|  2 ++
 hw/isa/lpc_ich9.c |  8 
 hw/isa/piix3.c| 15 +++
 include/hw/i386/ich9.h|  2 ++
 include/hw/southbridge/piix.h |  3 +++
 8 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b39ecd4d0c..8f72aedea4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1301,7 +1301,17 @@ void pc_basic_device_init(struct PCMachineState *pcms,
 pit_alt_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_PIT_INT);
 rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT);
 }
-*rtc_state = mc146818_rtc_init(isa_bus, 2000, rtc_irq);
+
+if (rtc_irq) {
+qdev_connect_gpio_out(DEVICE(*rtc_state), 0, rtc_irq);
+} else {
+uint32_t irq = object_property_get_uint(OBJECT(*rtc_state),
+"irq",
+_fatal);
+isa_connect_gpio_out(*rtc_state, 0, irq);
+}
+object_property_add_alias(OBJECT(pcms), "rtc-time", OBJECT(*rtc_state),
+  "date");
 
 qemu_register_boot_set(pc_boot_set, *rtc_state);
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index caa983d76e..7de2f1092b 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -32,6 +32,7 @@
 #include "hw/i386/pc.h"
 #include "hw/i386/apic.h"
 #include "hw/pci-host/i440fx.h"
+#include "hw/rtc/mc146818rtc.h"
 #include "hw/southbridge/piix.h"
 #include "hw/display/ramfb.h"
 #include "hw/firmware/smbios.h"
@@ -225,10 +226,17 @@ static void pc_init1(MachineState *machine,
 piix3->pic = x86ms->gsi;
 piix3_devfn = piix3->dev.devfn;
 isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
+rtc_state = ISA_DEVICE(object_resolve_path_component(OBJECT(pci_dev),
+ "rtc"));
 } else {
 pci_bus = NULL;
 isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
   _abort);
+
+rtc_state = isa_new(TYPE_MC146818_RTC);
+qdev_prop_set_int32(DEVICE(rtc_state), "base_year", 2000);
+isa_realize_and_unref(rtc_state, isa_bus, _fatal);
+
 i8257_dma_init(isa_bus, 0);
 pcms->hpet_enabled = false;
 }
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index fa24b5ef66..bf0888db97 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -239,6 +239,7 @@ static void pc_q35_init(MachineState *machine)
 lpc = pci_create_simple_multifunction(host_bus, PCI_DEVFN(ICH9_LPC_DEV,
   ICH9_LPC_FUNC), true,
   TYPE_ICH9_LPC_DEVICE);
+rtc_state = ISA_DEVICE(object_resolve_path_component(OBJECT(lpc), "rtc"));
 
 object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
  TYPE_HOTPLUG_HANDLER,
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index c65d2d2666..6e8f9cac54 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -35,6 +35,7 @@ config PIIX3
 bool
 select I8257
 select ISA_BUS
+select MC146818RTC
 
 config PIIX4
 bool
@@ -72,3 +73,4 @@ config LPC_ICH9
 select ISA_BUS
 select ACPI_SMBUS
 select ACPI_X86_ICH
+select MC146818RTC
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 8694e58b21..0051fa66ab 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -660,6 +660,8 @@ static void ich9_lpc_initfn(Object *obj)
 static const uint8_t acpi_enable_cmd = ICH9_APM_ACPI_ENABLE;
 static const uint8_t acpi_disable_cmd = ICH9_APM_ACPI_DISABLE;
 
+object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
+
 object_property_add_uint8_ptr(obj, ACPI_PM_PROP_SCI_INT,
   >sci_gsi, OBJ_PROP_FLAG_READ);
 object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_ENABLE_CMD,
@@ -725,6 +727,12 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
 isa_bus_irqs(isa_bus, lpc->gsi);
 
 i8257_dma_init(isa_bus, 0);
+
+/* RTC */
+qdev_prop_set_int32(DEVICE(>rtc), "base_year", 2000);
+if (!qdev_realize(DEVICE(>rtc), BUS(isa_bus), errp)) {
+return;
+}
 }
 
 static bool ich9_rst_cnt_needed(void *opaque)
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 0bea4aefe7..75c6370e33 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -28,6 +28,7 @@
 #include "hw/dma/i8257.h"
 #include "hw/southbridge/piix.h"
 #include "hw/irq.h"
+#include "hw/qdev-properties.h"
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
 #include "sysemu/xen.h"
@@ -313,6 +314,12 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)

[PATCH v2 01/43] hw/i386/pc: Create DMA controllers in south bridges

2022-10-23 Thread Bernhard Beschow
Just like in the real hardware (and in PIIX4), create the DMA
controllers in the south bridges.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c  | 3 ---
 hw/i386/pc_piix.c | 2 ++
 hw/isa/Kconfig| 2 ++
 hw/isa/lpc_ich9.c | 3 +++
 hw/isa/piix3.c| 9 +++--
 5 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 768982ae9a..b39ecd4d0c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -47,7 +47,6 @@
 #include "multiboot.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/intc/i8259.h"
-#include "hw/dma/i8257.h"
 #include "hw/timer/i8254.h"
 #include "hw/input/i8042.h"
 #include "hw/irq.h"
@@ -1320,8 +1319,6 @@ void pc_basic_device_init(struct PCMachineState *pcms,
 pcspk_init(pcms->pcspk, isa_bus, pit);
 }
 
-i8257_dma_init(isa_bus, 0);
-
 /* Super I/O */
 pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled,
 pcms->vmport != ON_OFF_AUTO_ON);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 0b1a79c0fa..7a55b9ca8e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -26,6 +26,7 @@
 #include CONFIG_DEVICES
 
 #include "qemu/units.h"
+#include "hw/dma/i8257.h"
 #include "hw/loader.h"
 #include "hw/i386/x86.h"
 #include "hw/i386/pc.h"
@@ -225,6 +226,7 @@ static void pc_init1(MachineState *machine,
 pci_bus = NULL;
 isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
   _abort);
+i8257_dma_init(isa_bus, 0);
 pcms->hpet_enabled = false;
 }
 isa_bus_irqs(isa_bus, x86ms->gsi);
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index d42143a991..c65d2d2666 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -33,6 +33,7 @@ config PC87312
 
 config PIIX3
 bool
+select I8257
 select ISA_BUS
 
 config PIIX4
@@ -67,6 +68,7 @@ config LPC_ICH9
 bool
 # For historical reasons, SuperIO devices are created in the board
 # for ICH9.
+select I8257
 select ISA_BUS
 select ACPI_SMBUS
 select ACPI_X86_ICH
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 4553b5925b..8694e58b21 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -34,6 +34,7 @@
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "qemu/range.h"
+#include "hw/dma/i8257.h"
 #include "hw/isa/isa.h"
 #include "migration/vmstate.h"
 #include "hw/irq.h"
@@ -722,6 +723,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
 qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS);
 
 isa_bus_irqs(isa_bus, lpc->gsi);
+
+i8257_dma_init(isa_bus, 0);
 }
 
 static bool ich9_rst_cnt_needed(void *opaque)
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 48f9ab1096..44a9998752 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "qemu/range.h"
 #include "qapi/error.h"
+#include "hw/dma/i8257.h"
 #include "hw/southbridge/piix.h"
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
@@ -295,9 +296,11 @@ static const MemoryRegionOps rcr_ops = {
 static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 {
 PIIX3State *d = PIIX3_PCI_DEVICE(dev);
+ISABus *isa_bus;
 
-if (!isa_bus_new(DEVICE(d), get_system_memory(),
- pci_address_space_io(dev), errp)) {
+isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
+  pci_address_space_io(dev), errp);
+if (!isa_bus) {
 return;
 }
 
@@ -307,6 +310,8 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 PIIX_RCR_IOPORT, >rcr_mem, 1);
 
 qemu_register_reset(piix3_reset, d);
+
+i8257_dma_init(isa_bus, 0);
 }
 
 static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope)
-- 
2.38.1




[PATCH v2 14/43] hw/intc/i8259: Introduce i8259 proxy "isa-pic"

2022-10-23 Thread Bernhard Beschow
Having an i8259 proxy allows for ISA PICs to be created and wired up in
southbridges. This is especially interesting for PIIX3 for two reasons:
First, the southbridge doesn't need to care about the virtualization
technology used (KVM, TCG, Xen) due to in-IRQs (where devices get
attached) and out-IRQs (which will trigger the IRQs of the respective
virtzalization technology) are separated. Second, since the in-IRQs are
populated with fully initialized qemu_irq's, they can already be wired
up inside PIIX3.

Signed-off-by: Bernhard Beschow 
---
 hw/intc/i8259.c | 27 +++
 include/hw/intc/i8259.h | 14 ++
 2 files changed, 41 insertions(+)

diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c
index cc4e21ffec..531f6cca53 100644
--- a/hw/intc/i8259.c
+++ b/hw/intc/i8259.c
@@ -458,9 +458,36 @@ static const TypeInfo i8259_info = {
 .class_size = sizeof(PICClass),
 };
 
+static void isapic_set_irq(void *opaque, int irq, int level)
+{
+ISAPICState *s = opaque;
+
+qemu_set_irq(s->out_irqs[irq], level);
+}
+
+static void isapic_init(Object *obj)
+{
+ISAPICState *s = ISA_PIC(obj);
+
+qdev_init_gpio_in(DEVICE(s), isapic_set_irq, ISA_NUM_IRQS);
+qdev_init_gpio_out(DEVICE(s), s->out_irqs, ISA_NUM_IRQS);
+
+for (int i = 0; i < ISA_NUM_IRQS; ++i) {
+s->in_irqs[i] = qdev_get_gpio_in(DEVICE(s), i);
+}
+}
+
+static const TypeInfo isapic_info = {
+.name  = TYPE_ISA_PIC,
+.parent= TYPE_ISA_DEVICE,
+.instance_size = sizeof(ISAPICState),
+.instance_init = isapic_init,
+};
+
 static void pic_register_types(void)
 {
 type_register_static(_info);
+type_register_static(_info);
 }
 
 type_init(pic_register_types)
diff --git a/include/hw/intc/i8259.h b/include/hw/intc/i8259.h
index e2b1e8c59a..0246ab6ac6 100644
--- a/include/hw/intc/i8259.h
+++ b/include/hw/intc/i8259.h
@@ -1,6 +1,20 @@
 #ifndef HW_I8259_H
 #define HW_I8259_H
 
+#include "qom/object.h"
+#include "hw/isa/isa.h"
+#include "qemu/typedefs.h"
+
+#define TYPE_ISA_PIC "isa-pic"
+OBJECT_DECLARE_SIMPLE_TYPE(ISAPICState, ISA_PIC)
+
+struct ISAPICState {
+ISADevice parent_obj;
+
+qemu_irq in_irqs[ISA_NUM_IRQS];
+qemu_irq out_irqs[ISA_NUM_IRQS];
+};
+
 /* i8259.c */
 
 extern DeviceState *isa_pic;
-- 
2.38.1




[PATCH v2 09/43] hw/usb/hcd-uhci: Introduce TYPE_ defines for device models

2022-10-23 Thread Bernhard Beschow
Suggested-by: Mark Cave-Ayland 
Signed-off-by: Bernhard Beschow 
---
 hw/i386/pc_piix.c |  3 ++-
 hw/i386/pc_q35.c  | 13 +++--
 hw/isa/piix4.c|  2 +-
 hw/usb/hcd-uhci.c | 16 
 hw/usb/hcd-uhci.h |  9 +
 5 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index e26509a935..caa983d76e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -50,6 +50,7 @@
 #include "exec/memory.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/piix4.h"
+#include "hw/usb/hcd-uhci.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "sysemu/xen.h"
@@ -291,7 +292,7 @@ static void pc_init1(MachineState *machine,
 #endif
 
 if (pcmc->pci_enabled && machine_usb(machine)) {
-pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
+pci_create_simple(pci_bus, piix3_devfn + 2, TYPE_PIIX3_USB_UHCI);
 }
 
 if (pcmc->pci_enabled && x86_machine_is_acpi_enabled(X86_MACHINE(pcms))) {
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index a496bd6e74..fa24b5ef66 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -48,6 +48,7 @@
 #include "hw/ide/pci.h"
 #include "hw/ide/ahci.h"
 #include "hw/usb.h"
+#include "hw/usb/hcd-uhci.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "sysemu/numa.h"
@@ -65,15 +66,15 @@ struct ehci_companions {
 };
 
 static const struct ehci_companions ich9_1d[] = {
-{ .name = "ich9-usb-uhci1", .func = 0, .port = 0 },
-{ .name = "ich9-usb-uhci2", .func = 1, .port = 2 },
-{ .name = "ich9-usb-uhci3", .func = 2, .port = 4 },
+{ .name = TYPE_ICH9_USB_UHCI1, .func = 0, .port = 0 },
+{ .name = TYPE_ICH9_USB_UHCI2, .func = 1, .port = 2 },
+{ .name = TYPE_ICH9_USB_UHCI3, .func = 2, .port = 4 },
 };
 
 static const struct ehci_companions ich9_1a[] = {
-{ .name = "ich9-usb-uhci4", .func = 0, .port = 0 },
-{ .name = "ich9-usb-uhci5", .func = 1, .port = 2 },
-{ .name = "ich9-usb-uhci6", .func = 2, .port = 4 },
+{ .name = TYPE_ICH9_USB_UHCI4, .func = 0, .port = 0 },
+{ .name = TYPE_ICH9_USB_UHCI5, .func = 1, .port = 2 },
+{ .name = TYPE_ICH9_USB_UHCI6, .func = 2, .port = 4 },
 };
 
 static int ehci_create_ich9_with_companions(PCIBus *bus, int slot)
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index e05e65d3bc..83b50c3a9b 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -279,7 +279,7 @@ static void piix4_init(Object *obj)
 
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 object_initialize_child(obj, "ide", >ide, TYPE_PIIX4_IDE);
-object_initialize_child(obj, "uhci", >uhci, "piix4-usb-uhci");
+object_initialize_child(obj, "uhci", >uhci, TYPE_PIIX4_USB_UHCI);
 
 object_initialize_child(obj, "pm", >pm, TYPE_PIIX4_PM);
 qdev_prop_set_uint32(DEVICE(>pm), "smb_io_base", 0x1100);
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index d1b5657d72..0ec4cfaa52 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1292,56 +1292,56 @@ void uhci_data_class_init(ObjectClass *klass, void 
*data)
 
 static UHCIInfo uhci_info[] = {
 {
-.name   = "piix3-usb-uhci",
+.name  = TYPE_PIIX3_USB_UHCI,
 .vendor_id = PCI_VENDOR_ID_INTEL,
 .device_id = PCI_DEVICE_ID_INTEL_82371SB_2,
 .revision  = 0x01,
 .irq_pin   = 3,
 .unplug= true,
 },{
-.name  = "piix4-usb-uhci",
+.name  = TYPE_PIIX4_USB_UHCI,
 .vendor_id = PCI_VENDOR_ID_INTEL,
 .device_id = PCI_DEVICE_ID_INTEL_82371AB_2,
 .revision  = 0x01,
 .irq_pin   = 3,
 .unplug= true,
 },{
-.name  = "ich9-usb-uhci1", /* 00:1d.0 */
+.name  = TYPE_ICH9_USB_UHCI1, /* 00:1d.0 */
 .vendor_id = PCI_VENDOR_ID_INTEL,
 .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
 .revision  = 0x03,
 .irq_pin   = 0,
 .unplug= false,
 },{
-.name  = "ich9-usb-uhci2", /* 00:1d.1 */
+.name  = TYPE_ICH9_USB_UHCI2, /* 00:1d.1 */
 .vendor_id = PCI_VENDOR_ID_INTEL,
 .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
 .revision  = 0x03,
 .irq_pin   = 1,
 .unplug= false,
 },{
-.name  = "ich9-usb-uhci3", /* 00:1d.2 */
+.name  = TYPE_ICH9_USB_UHCI3, /* 00:1d.2 */
 .vendor_id = PCI_VENDOR_ID_INTEL,
 .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
 .revision  = 0x03,
 .irq_pin   = 2,
 .unplug= false,
 },{
-.name  = "ich9-usb-uhci4", /* 00:1a.0 */
+.name  = TYPE_ICH9_USB_UHCI4, /* 00:1a.0 */
 .vendor_id = PCI_VENDOR_ID_INTEL,
 .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI4,
 .revision  = 0x03,
 .irq_pin   = 0,
 .unplug= false,
 },{
-.name  = "ich9-usb-uhci5", /* 00:1a.1 */
+.name  = TYPE_ICH9_USB_UHCI5, /* 00:1a.1 */
 .vendor_id = 

[PATCH v2 25/43] hw/mips/malta: Reuse dev variable

2022-10-23 Thread Bernhard Beschow
While at it, move the assignments closer to where they are used.

Signed-off-by: Bernhard Beschow 
---
 hw/mips/malta.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 0e932988e0..0ec2ac2eaf 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1239,7 +1239,6 @@ void mips_malta_init(MachineState *machine)
 MaltaState *s;
 PCIDevice *piix4;
 DeviceState *dev;
-DeviceState *pm_dev;
 
 s = MIPS_MALTA(qdev_new(TYPE_MIPS_MALTA));
 sysbus_realize_and_unref(SYS_BUS_DEVICE(s), _fatal);
@@ -1405,13 +1404,13 @@ void mips_malta_init(MachineState *machine)
 TYPE_PIIX4_PCI_DEVICE);
 dev = DEVICE(piix4);
 isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
-pm_dev = DEVICE(object_resolve_path_component(OBJECT(dev), "pm"));
-smbus = I2C_BUS(qdev_get_child_bus(pm_dev, "i2c"));
 
 /* Interrupt controller */
 qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
 
 /* generate SPD EEPROM data */
+dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
+smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
 generate_eeprom_spd(_eeprom_buf[0 * 256], ram_size);
 generate_eeprom_serial(_eeprom_buf[6 * 256]);
 smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
-- 
2.38.1




[PATCH v2 36/43] hw/isa/piix3: Merge hw/isa/piix4.c

2022-10-23 Thread Bernhard Beschow
Now that the PIIX3 and PIIX4 device models are sufficiently consolidated

Signed-off-by: Bernhard Beschow 
---
 MAINTAINERS |   6 +-
 configs/devices/mips-softmmu/common.mak |   2 +-
 hw/i386/Kconfig |   2 +-
 hw/isa/Kconfig  |  12 +-
 hw/isa/meson.build  |   3 +-
 hw/isa/{piix3.c => piix.c}  | 185 ++
 hw/isa/piix4.c  | 315 
 7 files changed, 192 insertions(+), 333 deletions(-)
 rename hw/isa/{piix3.c => piix.c} (73%)
 delete mode 100644 hw/isa/piix4.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e3d5b7e09c..f08f095222 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1228,7 +1228,7 @@ Malta
 M: Philippe Mathieu-Daudé 
 R: Aurelien Jarno 
 S: Odd Fixes
-F: hw/isa/piix4.c
+F: hw/isa/piix.c
 F: hw/acpi/piix4.c
 F: hw/mips/malta.c
 F: hw/mips/gt64xxx_pci.c
@@ -1643,7 +1643,7 @@ F: hw/pci-host/pam.c
 F: include/hw/pci-host/i440fx.h
 F: include/hw/pci-host/q35.h
 F: include/hw/pci-host/pam.h
-F: hw/isa/piix3.c
+F: hw/isa/piix.c
 F: hw/isa/lpc_ich9.c
 F: hw/i2c/smbus_ich9.c
 F: hw/acpi/piix4.c
@@ -2314,7 +2314,7 @@ PIIX4 South Bridge (i82371AB)
 M: Hervé Poussineau 
 M: Philippe Mathieu-Daudé 
 S: Maintained
-F: hw/isa/piix4.c
+F: hw/isa/piix.c
 F: include/hw/southbridge/piix.h
 
 Firmware configuration (fw_cfg)
diff --git a/configs/devices/mips-softmmu/common.mak 
b/configs/devices/mips-softmmu/common.mak
index 416161f833..ef3b7390a6 100644
--- a/configs/devices/mips-softmmu/common.mak
+++ b/configs/devices/mips-softmmu/common.mak
@@ -21,7 +21,7 @@ CONFIG_ACPI=y
 CONFIG_ACPI_PIIX4=y
 CONFIG_APM=y
 CONFIG_I8257=y
-CONFIG_PIIX4=y
+CONFIG_PIIX=y
 CONFIG_IDE_ISA=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_I8259=y
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index dd247f215c..295693b32b 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -73,7 +73,7 @@ config I440FX
 select PC_ACPI
 select ACPI_SMBUS
 select PCI_I440FX
-select PIIX3
+select PIIX
 select DIMM
 select SMBIOS
 select FW_CFG_DMA
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 1aa10f84f2..000c2312ab 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -31,17 +31,7 @@ config PC87312
 select FDC_ISA
 select IDE_ISA
 
-config PIIX3
-bool
-select ACPI_PIIX4
-select I8257
-select I8259
-select IDE_PIIX
-select ISA_BUS
-select MC146818RTC
-select USB_UHCI
-
-config PIIX4
+config PIIX
 bool
 # For historical reasons, SuperIO devices are created in the board
 # for PIIX4.
diff --git a/hw/isa/meson.build b/hw/isa/meson.build
index 8bf678ca0a..314bbd0860 100644
--- a/hw/isa/meson.build
+++ b/hw/isa/meson.build
@@ -3,8 +3,7 @@ softmmu_ss.add(when: 'CONFIG_I82378', if_true: 
files('i82378.c'))
 softmmu_ss.add(when: 'CONFIG_ISA_BUS', if_true: files('isa-bus.c'))
 softmmu_ss.add(when: 'CONFIG_ISA_SUPERIO', if_true: files('isa-superio.c'))
 softmmu_ss.add(when: 'CONFIG_PC87312', if_true: files('pc87312.c'))
-softmmu_ss.add(when: 'CONFIG_PIIX3', if_true: files('piix3.c'))
-softmmu_ss.add(when: 'CONFIG_PIIX4', if_true: files('piix4.c'))
+softmmu_ss.add(when: 'CONFIG_PIIX', if_true: files('piix.c'))
 softmmu_ss.add(when: 'CONFIG_SMC37C669', if_true: files('smc37c669-superio.c'))
 softmmu_ss.add(when: 'CONFIG_VT82C686', if_true: files('vt82c686.c'))
 
diff --git a/hw/isa/piix3.c b/hw/isa/piix.c
similarity index 73%
rename from hw/isa/piix3.c
rename to hw/isa/piix.c
index b02a91c8eb..5123474fab 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix.c
@@ -2,6 +2,7 @@
  * QEMU PIIX PCI ISA Bridge Emulation
  *
  * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2018 Hervé Poussineau
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
@@ -26,7 +27,9 @@
 #include "qemu/range.h"
 #include "qapi/error.h"
 #include "hw/dma/i8257.h"
+#include "hw/intc/i8259.h"
 #include "hw/southbridge/piix.h"
+#include "hw/timer/i8254.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
 #include "hw/ide/piix.h"
@@ -81,6 +84,27 @@ static void piix3_set_irq(void *opaque, int pirq, int level)
 piix3_set_irq_level(piix3, pirq, level);
 }
 
+static void piix4_set_irq(void *opaque, int irq_num, int level)
+{
+int i, pic_irq, pic_level;
+PIIXState *s = opaque;
+PCIBus *bus = pci_get_bus(>dev);
+
+/* now we change the pic irq level according to the piix irq mappings */
+/* XXX: optimize */
+pic_irq = s->dev.config[PIIX_PIRQCA + irq_num];
+if (pic_irq < ISA_NUM_IRQS) {
+/* The pic level is the logical OR of all the PCI irqs mapped to it. */
+pic_level = 0;
+for (i = 0; i < PIIX_NUM_PIRQS; i++) {
+if (pic_irq == s->dev.config[PIIX_PIRQCA + i]) {
+pic_level |= pci_bus_get_irq_level(bus, i);
+}
+}
+qemu_set_irq(s->pic.in_irqs[pic_irq], 

[PATCH v2 27/43] hw/isa/piix4: Add missing initialization

2022-10-23 Thread Bernhard Beschow
PIIX3 clears its reset control register, so do the same in PIIX4.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix4.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 83b50c3a9b..4b8dece257 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -140,6 +140,8 @@ static void piix4_isa_reset(DeviceState *dev)
 pci_conf[0xab] = 0x00;
 pci_conf[0xac] = 0x00;
 pci_conf[0xae] = 0x00;
+
+d->rcr = 0;
 }
 
 static int piix4_post_load(void *opaque, int version_id)
-- 
2.38.1




[PATCH v2 40/43] hw/isa/piix: Consolidate IRQ triggering

2022-10-23 Thread Bernhard Beschow
Speeds up PIIX4 which resolves an old TODO.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix.c | 26 +++---
 1 file changed, 3 insertions(+), 23 deletions(-)

diff --git a/hw/isa/piix.c b/hw/isa/piix.c
index 446105a7a1..4ced9995f9 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -84,27 +84,6 @@ static void piix_set_irq(void *opaque, int pirq, int level)
 piix_set_irq_level(piix, pirq, level);
 }
 
-static void piix4_set_irq(void *opaque, int irq_num, int level)
-{
-int i, pic_irq, pic_level;
-PIIXState *s = opaque;
-PCIBus *bus = pci_get_bus(>dev);
-
-/* now we change the pic irq level according to the piix irq mappings */
-/* XXX: optimize */
-pic_irq = s->dev.config[PIIX_PIRQCA + irq_num];
-if (pic_irq < ISA_NUM_IRQS) {
-/* The pic level is the logical OR of all the PCI irqs mapped to it. */
-pic_level = 0;
-for (i = 0; i < PIIX_NUM_PIRQS; i++) {
-if (pic_irq == s->dev.config[PIIX_PIRQCA + i]) {
-pic_level |= pci_bus_get_irq_level(bus, i);
-}
-}
-qemu_set_irq(s->pic.in_irqs[pic_irq], pic_level);
-}
-}
-
 /*
  * Return the global irq number corresponding to a given device irq
  * pin. We could also use the bus number to have a more precise mapping.
@@ -276,7 +255,7 @@ static int piix4_post_load(void *opaque, int version_id)
 s->rcr = 0;
 }
 
-return 0;
+return piix3_post_load(opaque, version_id);
 }
 
 static int piix3_pre_save(void *opaque)
@@ -586,7 +565,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 /* RTC */
 s->rtc.irq = qdev_get_gpio_in(DEVICE(>pic), s->rtc.isairq);
 
-pci_bus_irqs(pci_bus, piix4_set_irq, piix4_pci_slot_get_pirq, s,
+pci_bus_irqs(pci_bus, piix_set_irq, piix4_pci_slot_get_pirq, s,
  PIIX_NUM_PIRQS);
 }
 
@@ -604,6 +583,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
+k->config_write = piix_write_config;
 k->realize = piix4_realize;
 k->vendor_id = PCI_VENDOR_ID_INTEL;
 k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
-- 
2.38.1




[PATCH v2 30/43] hw/isa/piix4: Allow board to provide PCI interrupt routes

2022-10-23 Thread Bernhard Beschow
PIIX3 initializes the PIRQx route control registers to the default
values as described in the 82371AB PCI-TO-ISA/IDE XCELERATOR (PIIX4)
April 1997 manual. PIIX4, however, initializes the routes according to
the Malta™ User’s Manual, ch 6.6, which are IRQs 10 and 11. In order to
allow the reset methods to be consolidated, allow board code to specify
the routes.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c  | 14 ++
 hw/mips/malta.c |  4 
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index fc698c23be..57b0b98bef 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -58,6 +58,8 @@ struct PIIX4State {
 MemoryRegion rcr_mem;
 uint8_t rcr;
 
+uint8_t pci_irq_reset_mappings[PIIX_NUM_PIRQS];
+
 bool has_acpi;
 bool has_usb;
 bool smm_enabled;
@@ -123,10 +125,10 @@ static void piix4_isa_reset(DeviceState *dev)
 pci_conf[0x4c] = 0x4d;
 pci_conf[0x4e] = 0x03;
 pci_conf[0x4f] = 0x00;
-pci_conf[0x60] = 0x0a; // PCI A -> IRQ 10
-pci_conf[0x61] = 0x0a; // PCI B -> IRQ 10
-pci_conf[0x62] = 0x0b; // PCI C -> IRQ 11
-pci_conf[0x63] = 0x0b; // PCI D -> IRQ 11
+pci_conf[PIIX_PIRQCA] = d->pci_irq_reset_mappings[0];
+pci_conf[PIIX_PIRQCB] = d->pci_irq_reset_mappings[1];
+pci_conf[PIIX_PIRQCC] = d->pci_irq_reset_mappings[2];
+pci_conf[PIIX_PIRQCD] = d->pci_irq_reset_mappings[3];
 pci_conf[0x69] = 0x02;
 pci_conf[0x70] = 0x80;
 pci_conf[0x76] = 0x0c;
@@ -300,6 +302,10 @@ static void piix4_init(Object *obj)
 
 static Property piix4_props[] = {
 DEFINE_PROP_UINT32("smb_io_base", PIIX4State, smb_io_base, 0),
+DEFINE_PROP_UINT8("pirqa", PIIX4State, pci_irq_reset_mappings[0], 0x80),
+DEFINE_PROP_UINT8("pirqb", PIIX4State, pci_irq_reset_mappings[1], 0x80),
+DEFINE_PROP_UINT8("pirqc", PIIX4State, pci_irq_reset_mappings[2], 0x80),
+DEFINE_PROP_UINT8("pirqd", PIIX4State, pci_irq_reset_mappings[3], 0x80),
 DEFINE_PROP_BOOL("has-acpi", PIIX4State, has_acpi, true),
 DEFINE_PROP_BOOL("has-usb", PIIX4State, has_usb, true),
 DEFINE_PROP_BOOL("smm-enabled", PIIX4State, smm_enabled, false),
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 6339b0d66c..44b6b14f3d 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1403,6 +1403,10 @@ void mips_malta_init(MachineState *machine)
 piix4 = pci_new_multifunction(PCI_DEVFN(10, 0), true,
   TYPE_PIIX4_PCI_DEVICE);
 qdev_prop_set_uint32(DEVICE(piix4), "smb_io_base", 0x1100);
+qdev_prop_set_uint8(DEVICE(piix4), "pirqa", 10);
+qdev_prop_set_uint8(DEVICE(piix4), "pirqb", 10);
+qdev_prop_set_uint8(DEVICE(piix4), "pirqc", 11);
+qdev_prop_set_uint8(DEVICE(piix4), "pirqd", 11);
 pci_realize_and_unref(piix4, pci_bus, _fatal);
 isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0"));
 
-- 
2.38.1




[PATCH v2 41/43] hw/isa/piix: Share PIIX3 base class with PIIX4

2022-10-23 Thread Bernhard Beschow
Having a common base class allows for substituting PIIX3 with PIIX4
and vice versa. Moreover, it makes PIIX4 implement the
acpi-dev-aml-interface.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix.c | 53 +++
 1 file changed, 24 insertions(+), 29 deletions(-)

diff --git a/hw/isa/piix.c b/hw/isa/piix.c
index 4ced9995f9..c8c1a99bf1 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -422,13 +422,12 @@ static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml 
*scope)
 }
 }
 
-static void pci_piix3_init(Object *obj)
+static void pci_piix_init(Object *obj)
 {
 PIIXState *d = PIIX_PCI_DEVICE(obj);
 
 object_initialize_child(obj, "pic", >pic, TYPE_ISA_PIC);
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
-object_initialize_child(obj, "ide", >ide, TYPE_PIIX3_IDE);
 }
 
 static Property pci_piix_props[] = {
@@ -443,7 +442,7 @@ static Property pci_piix_props[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
-static void pci_piix3_class_init(ObjectClass *klass, void *data)
+static void pci_piix_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -451,11 +450,8 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
 
 dc->reset   = piix_reset;
 dc->desc= "ISA bridge";
-dc->vmsd= _piix3;
 dc->hotpluggable   = false;
 k->vendor_id= PCI_VENDOR_ID_INTEL;
-/* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
-k->device_id= PCI_DEVICE_ID_INTEL_82371SB_0;
 k->class_id = PCI_CLASS_BRIDGE_ISA;
 /*
  * Reason: part of PIIX3 southbridge, needs to be wired up by
@@ -466,13 +462,13 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
 adevc->build_dev_aml = build_pci_isa_aml;
 }
 
-static const TypeInfo piix3_pci_type_info = {
+static const TypeInfo piix_pci_type_info = {
 .name = TYPE_PIIX3_PCI_DEVICE,
 .parent = TYPE_PCI_DEVICE,
 .instance_size = sizeof(PIIXState),
-.instance_init = pci_piix3_init,
+.instance_init = pci_piix_init,
 .abstract = true,
-.class_init = pci_piix3_class_init,
+.class_init = pci_piix_class_init,
 .interfaces = (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
 { TYPE_ACPI_DEV_AML_IF },
@@ -496,17 +492,29 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
 }
 
+static void piix3_init(Object *obj)
+{
+PIIXState *d = PIIX_PCI_DEVICE(obj);
+
+object_initialize_child(obj, "ide", >ide, TYPE_PIIX3_IDE);
+}
+
 static void piix3_class_init(ObjectClass *klass, void *data)
 {
+DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
 k->config_write = piix_write_config;
 k->realize = piix3_realize;
+/* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
+k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0;
+dc->vmsd = _piix3;
 }
 
 static const TypeInfo piix3_info = {
 .name  = TYPE_PIIX3_DEVICE,
 .parent= TYPE_PIIX3_PCI_DEVICE,
+.instance_init = piix3_init,
 .class_init= piix3_class_init,
 };
 
@@ -533,15 +541,20 @@ static void piix3_xen_realize(PCIDevice *dev, Error 
**errp)
 
 static void piix3_xen_class_init(ObjectClass *klass, void *data)
 {
+DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
 k->config_write = piix3_write_config_xen;
 k->realize = piix3_xen_realize;
+/* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
+k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0;
+dc->vmsd = _piix3;
 }
 
 static const TypeInfo piix3_xen_info = {
 .name  = TYPE_PIIX3_XEN_DEVICE,
 .parent= TYPE_PIIX3_PCI_DEVICE,
+.instance_init = piix3_init,
 .class_init= piix3_xen_class_init,
 };
 
@@ -573,8 +586,6 @@ static void piix4_init(Object *obj)
 {
 PIIXState *s = PIIX_PCI_DEVICE(obj);
 
-object_initialize_child(obj, "pic", >pic, TYPE_ISA_PIC);
-object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 object_initialize_child(obj, "ide", >ide, TYPE_PIIX4_IDE);
 }
 
@@ -585,36 +596,20 @@ static void piix4_class_init(ObjectClass *klass, void 
*data)
 
 k->config_write = piix_write_config;
 k->realize = piix4_realize;
-k->vendor_id = PCI_VENDOR_ID_INTEL;
 k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
-k->class_id = PCI_CLASS_BRIDGE_ISA;
-dc->reset = piix_reset;
-dc->desc = "ISA bridge";
 dc->vmsd = _piix4;
-/*
- * Reason: part of PIIX4 southbridge, needs to be wired up,
- * e.g. by mips_malta_init()
- */
-dc->user_creatable = false;
-dc->hotpluggable = false;
-device_class_set_props(dc, pci_piix_props);
 }
 
 static const TypeInfo piix4_info = {
 .name  = TYPE_PIIX4_PCI_DEVICE,
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PIIXState),
+

[PATCH v2 24/43] hw/isa/piix3: Rename typedef PIIX3State to PIIXState

2022-10-23 Thread Bernhard Beschow
This commit marks the finalization of the PIIX3 preparations
to be merged with PIIX4. In particular, PIIXState is prepared
to be reused in piix4.c.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix3.c| 58 +--
 include/hw/southbridge/piix.h |  4 +--
 2 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 8878d71465..b02a91c8eb 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -38,7 +38,7 @@
 
 #define XEN_PIIX_NUM_PIRQS  128ULL
 
-static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
+static void piix3_set_irq_pic(PIIXState *piix3, int pic_irq)
 {
 qemu_set_irq(piix3->pic.in_irqs[pic_irq],
  !!(piix3->pic_levels &
@@ -46,7 +46,7 @@ static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
  (pic_irq * PIIX_NUM_PIRQS;
 }
 
-static void piix3_set_irq_level_internal(PIIX3State *piix3, int pirq, int 
level)
+static void piix3_set_irq_level_internal(PIIXState *piix3, int pirq, int level)
 {
 int pic_irq;
 uint64_t mask;
@@ -61,7 +61,7 @@ static void piix3_set_irq_level_internal(PIIX3State *piix3, 
int pirq, int level)
 piix3->pic_levels |= mask * !!level;
 }
 
-static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
+static void piix3_set_irq_level(PIIXState *piix3, int pirq, int level)
 {
 int pic_irq;
 
@@ -77,7 +77,7 @@ static void piix3_set_irq_level(PIIX3State *piix3, int pirq, 
int level)
 
 static void piix3_set_irq(void *opaque, int pirq, int level)
 {
-PIIX3State *piix3 = opaque;
+PIIXState *piix3 = opaque;
 piix3_set_irq_level(piix3, pirq, level);
 }
 
@@ -94,7 +94,7 @@ static int piix3_pci_slot_get_pirq(PCIDevice *pci_dev, int 
pci_intx)
 
 static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
 {
-PIIX3State *piix3 = opaque;
+PIIXState *piix3 = opaque;
 int irq = piix3->dev.config[PIIX_PIRQCA + pin];
 PCIINTxRoute route;
 
@@ -109,7 +109,7 @@ static PCIINTxRoute piix3_route_intx_pin_to_irq(void 
*opaque, int pin)
 }
 
 /* irq routing is changed. so rebuild bitmap */
-static void piix3_update_irq_levels(PIIX3State *piix3)
+static void piix3_update_irq_levels(PIIXState *piix3)
 {
 PCIBus *bus = pci_get_bus(>dev);
 int pirq;
@@ -125,7 +125,7 @@ static void piix3_write_config(PCIDevice *dev,
 {
 pci_default_write_config(dev, address, val, len);
 if (ranges_overlap(address, len, PIIX_PIRQCA, 4)) {
-PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
+PIIXState *piix3 = PIIX_PCI_DEVICE(dev);
 int pic_irq;
 
 pci_bus_fire_intx_routing_notifier(pci_get_bus(>dev));
@@ -158,7 +158,7 @@ static void piix3_write_config_xen(PCIDevice *dev,
 
 static void piix_reset(DeviceState *dev)
 {
-PIIX3State *d = PIIX3_PCI_DEVICE(dev);
+PIIXState *d = PIIX_PCI_DEVICE(dev);
 uint8_t *pci_conf = d->dev.config;
 
 pci_conf[0x04] = 0x07; /* master, memory and I/O */
@@ -199,7 +199,7 @@ static void piix_reset(DeviceState *dev)
 
 static int piix3_post_load(void *opaque, int version_id)
 {
-PIIX3State *piix3 = opaque;
+PIIXState *piix3 = opaque;
 int pirq;
 
 /*
@@ -222,7 +222,7 @@ static int piix3_post_load(void *opaque, int version_id)
 static int piix3_pre_save(void *opaque)
 {
 int i;
-PIIX3State *piix3 = opaque;
+PIIXState *piix3 = opaque;
 
 for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) {
 piix3->pci_irq_levels_vmstate[i] =
@@ -234,7 +234,7 @@ static int piix3_pre_save(void *opaque)
 
 static bool piix3_rcr_needed(void *opaque)
 {
-PIIX3State *piix3 = opaque;
+PIIXState *piix3 = opaque;
 
 return (piix3->rcr != 0);
 }
@@ -245,7 +245,7 @@ static const VMStateDescription vmstate_piix3_rcr = {
 .minimum_version_id = 1,
 .needed = piix3_rcr_needed,
 .fields = (VMStateField[]) {
-VMSTATE_UINT8(rcr, PIIX3State),
+VMSTATE_UINT8(rcr, PIIXState),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -257,8 +257,8 @@ static const VMStateDescription vmstate_piix3 = {
 .post_load = piix3_post_load,
 .pre_save = piix3_pre_save,
 .fields = (VMStateField[]) {
-VMSTATE_PCI_DEVICE(dev, PIIX3State),
-VMSTATE_INT32_ARRAY_V(pci_irq_levels_vmstate, PIIX3State,
+VMSTATE_PCI_DEVICE(dev, PIIXState),
+VMSTATE_INT32_ARRAY_V(pci_irq_levels_vmstate, PIIXState,
   PIIX_NUM_PIRQS, 3),
 VMSTATE_END_OF_LIST()
 },
@@ -271,7 +271,7 @@ static const VMStateDescription vmstate_piix3 = {
 
 static void rcr_write(void *opaque, hwaddr addr, uint64_t val, unsigned len)
 {
-PIIX3State *d = opaque;
+PIIXState *d = opaque;
 
 if (val & 4) {
 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
@@ -282,7 +282,7 @@ static void rcr_write(void *opaque, hwaddr addr, uint64_t 
val, unsigned len)
 
 static uint64_t rcr_read(void *opaque, hwaddr addr, unsigned len)
 {
-PIIX3State *d = opaque;
+  

[PATCH v2 13/43] hw/isa/piix3: Create power management controller in host device

2022-10-23 Thread Bernhard Beschow
The power management controller is an integral part of PIIX3 (function
3). So create it as part of the south bridge.

Note that the ACPI function is optional in QEMU. This is why it gets
object_initialize_child()'ed in realize rather than in instance_init.

Signed-off-by: Bernhard Beschow 
---
 hw/i386/pc_piix.c | 23 +--
 hw/isa/Kconfig|  1 +
 hw/isa/piix3.c| 14 ++
 include/hw/southbridge/piix.h |  6 ++
 4 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 22c1c5404c..c96d989636 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -46,11 +46,11 @@
 #include "sysemu/kvm.h"
 #include "hw/kvm/clock.h"
 #include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/xen/xen-x86.h"
 #include "exec/memory.h"
 #include "hw/acpi/acpi.h"
-#include "hw/acpi/piix4.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "sysemu/xen.h"
@@ -85,6 +85,7 @@ static void pc_init1(MachineState *machine,
 MemoryRegion *system_io = get_system_io();
 PCIBus *pci_bus;
 ISABus *isa_bus;
+Object *piix4_pm;
 int piix3_devfn = -1;
 qemu_irq smi_irq;
 GSIState *gsi_state;
@@ -222,6 +223,13 @@ static void pc_init1(MachineState *machine,
 pci_dev = pci_new_multifunction(-1, true, type);
 object_property_set_bool(OBJECT(pci_dev), "has-usb",
  machine_usb(machine), _abort);
+object_property_set_bool(OBJECT(pci_dev), "has-acpi",
+ x86_machine_is_acpi_enabled(x86ms),
+ _abort);
+qdev_prop_set_uint32(DEVICE(pci_dev), "smb_io_base", 0xb100);
+object_property_set_bool(OBJECT(pci_dev), "smm-enabled",
+ x86_machine_is_smm_enabled(x86ms),
+ _abort);
 pci_realize_and_unref(pci_dev, pci_bus, _fatal);
 piix3 = PIIX3_PCI_DEVICE(pci_dev);
 piix3->pic = x86ms->gsi;
@@ -229,8 +237,10 @@ static void pc_init1(MachineState *machine,
 isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
 rtc_state = ISA_DEVICE(object_resolve_path_component(OBJECT(pci_dev),
  "rtc"));
+piix4_pm = object_resolve_path_component(OBJECT(pci_dev), "pm");
 } else {
 pci_bus = NULL;
+piix4_pm = NULL;
 isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
   _abort);
 
@@ -300,15 +310,8 @@ static void pc_init1(MachineState *machine,
 }
 #endif
 
-if (pcmc->pci_enabled && x86_machine_is_acpi_enabled(X86_MACHINE(pcms))) {
-PCIDevice *piix4_pm;
-
+if (piix4_pm) {
 smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
-piix4_pm = pci_new(piix3_devfn + 3, TYPE_PIIX4_PM);
-qdev_prop_set_uint32(DEVICE(piix4_pm), "smb_io_base", 0xb100);
-qdev_prop_set_bit(DEVICE(piix4_pm), "smm-enabled",
-  x86_machine_is_smm_enabled(x86ms));
-pci_realize_and_unref(piix4_pm, pci_bus, _fatal);
 
 qdev_connect_gpio_out(DEVICE(piix4_pm), 0, x86ms->gsi[9]);
 qdev_connect_gpio_out_named(DEVICE(piix4_pm), "smi-irq", 0, smi_irq);
@@ -322,7 +325,7 @@ static void pc_init1(MachineState *machine,
  object_property_allow_set_link,
  OBJ_PROP_LINK_STRONG);
 object_property_set_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
- OBJECT(piix4_pm), _abort);
+ piix4_pm, _abort);
 }
 
 if (machine->nvdimms_state->is_enabled) {
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index f02eca3c3e..f10daa26bc 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -33,6 +33,7 @@ config PC87312
 
 config PIIX3
 bool
+select ACPI_PIIX4
 select I8257
 select ISA_BUS
 select MC146818RTC
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 2f227fde0e..a4b8ebd5f5 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -331,6 +331,17 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 return;
 }
 }
+
+/* Power Management */
+if (d->has_acpi) {
+object_initialize_child(OBJECT(d), "pm", >pm, TYPE_PIIX4_PM);
+qdev_prop_set_int32(DEVICE(>pm), "addr", dev->devfn + 3);
+qdev_prop_set_uint32(DEVICE(>pm), "smb_io_base", d->smb_io_base);
+qdev_prop_set_bit(DEVICE(>pm), "smm-enabled", d->smm_enabled);
+if (!qdev_realize(DEVICE(>pm), BUS(pci_bus), errp)) {
+return;
+}
+}
 }
 
 static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope)
@@ -354,7 +365,10 @@ static void pci_piix3_init(Object *obj)
 }
 
 static Property pci_piix3_props[] = {
+DEFINE_PROP_UINT32("smb_io_base", PIIX3State, 

[PATCH v2 21/43] hw/isa/piix3: Rename pci_piix3_props for sharing with PIIX4

2022-10-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix3.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 9de7287589..8dbf22eaab 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -381,7 +381,7 @@ static void pci_piix3_init(Object *obj)
 object_initialize_child(obj, "ide", >ide, TYPE_PIIX3_IDE);
 }
 
-static Property pci_piix3_props[] = {
+static Property pci_piix_props[] = {
 DEFINE_PROP_UINT32("smb_io_base", PIIX3State, smb_io_base, 0),
 DEFINE_PROP_UINT8("pirqa", PIIX3State, pci_irq_reset_mappings[0], 0x80),
 DEFINE_PROP_UINT8("pirqb", PIIX3State, pci_irq_reset_mappings[1], 0x80),
@@ -412,7 +412,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
  * pc_piix.c's pc_init1()
  */
 dc->user_creatable = false;
-device_class_set_props(dc, pci_piix3_props);
+device_class_set_props(dc, pci_piix_props);
 adevc->build_dev_aml = build_pci_isa_aml;
 }
 
-- 
2.38.1




[PATCH v2 32/43] hw/isa/piix4: Use ISA PIC device

2022-10-23 Thread Bernhard Beschow
Aligns the code with PIIX3 such that PIIXState can be used in PIIX4,
too.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix4.c  | 28 ++--
 hw/mips/malta.c | 11 +--
 2 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index d65f486008..8ddff23116 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -44,9 +44,8 @@
 
 struct PIIX4State {
 PCIDevice dev;
-qemu_irq cpu_intr;
-qemu_irq *isa;
 
+ISAPICState pic;
 RTCState rtc;
 PCIIDEState ide;
 UHCIState uhci;
@@ -84,7 +83,7 @@ static void piix4_set_irq(void *opaque, int irq_num, int 
level)
 pic_level |= pci_bus_get_irq_level(bus, i);
 }
 }
-qemu_set_irq(s->isa[pic_irq], pic_level);
+qemu_set_irq(s->pic.in_irqs[pic_irq], pic_level);
 }
 }
 
@@ -176,12 +175,6 @@ static const VMStateDescription vmstate_piix4 = {
 }
 };
 
-static void piix4_request_i8259_irq(void *opaque, int irq, int level)
-{
-PIIX4State *s = opaque;
-qemu_set_irq(s->cpu_intr, level);
-}
-
 static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
 unsigned int len)
 {
@@ -217,7 +210,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 PIIX4State *s = PIIX4_PCI_DEVICE(dev);
 PCIBus *pci_bus = pci_get_bus(dev);
 ISABus *isa_bus;
-qemu_irq *i8259_out_irq;
 
 isa_bus = isa_bus_new(DEVICE(dev), pci_address_space(dev),
   pci_address_space_io(dev), errp);
@@ -225,20 +217,18 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
-qdev_init_gpio_out_named(DEVICE(dev), >cpu_intr,
- "intr", 1);
-
 memory_region_init_io(>rcr_mem, OBJECT(dev), _rcr_ops, s,
   "reset-control", 1);
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
 PIIX_RCR_IOPORT, >rcr_mem, 1);
 
 /* initialize i8259 pic */
-i8259_out_irq = qemu_allocate_irqs(piix4_request_i8259_irq, s, 1);
-s->isa = i8259_init(isa_bus, *i8259_out_irq);
+if (!qdev_realize(DEVICE(>pic), BUS(isa_bus), errp)) {
+return;
+}
 
 /* initialize ISA irqs */
-isa_bus_irqs(isa_bus, s->isa);
+isa_bus_irqs(isa_bus, s->pic.in_irqs);
 
 /* initialize pit */
 i8254_pit_init(isa_bus, 0x40, 0, NULL);
@@ -251,7 +241,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 if (!qdev_realize(DEVICE(>rtc), BUS(isa_bus), errp)) {
 return;
 }
-s->rtc.irq = isa_get_irq(ISA_DEVICE(>rtc), s->rtc.isairq);
+s->rtc.irq = qdev_get_gpio_in(DEVICE(>pic), s->rtc.isairq);
 
 /* IDE */
 qdev_prop_set_int32(DEVICE(>ide), "addr", dev->devfn + 1);
@@ -278,7 +268,8 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 if (!qdev_realize(DEVICE(>pm), BUS(pci_bus), errp)) {
 return;
 }
-qdev_connect_gpio_out(DEVICE(>pm), 0, s->isa[9]);
+qdev_connect_gpio_out(DEVICE(>pm), 0,
+  qdev_get_gpio_in(DEVICE(>pic), 9));
 }
 
 pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS);
@@ -288,6 +279,7 @@ static void piix4_init(Object *obj)
 {
 PIIX4State *s = PIIX4_PCI_DEVICE(obj);
 
+object_initialize_child(obj, "pic", >pic, TYPE_ISA_PIC);
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 object_initialize_child(obj, "ide", >ide, TYPE_PIIX4_IDE);
 }
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 44b6b14f3d..68e800b00f 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -28,6 +28,7 @@
 #include "qemu/datadir.h"
 #include "hw/clock.h"
 #include "hw/southbridge/piix.h"
+#include "hw/intc/i8259.h"
 #include "hw/isa/superio.h"
 #include "hw/char/serial.h"
 #include "net/net.h"
@@ -1232,10 +1233,11 @@ void mips_malta_init(MachineState *machine)
 PCIBus *pci_bus;
 ISABus *isa_bus;
 qemu_irq cbus_irq, i8259_irq;
+qemu_irq *i8259;
 I2CBus *smbus;
 DriveInfo *dinfo;
 int fl_idx = 0;
-int be;
+int be, i;
 MaltaState *s;
 PCIDevice *piix4;
 DeviceState *dev;
@@ -1414,7 +1416,12 @@ void mips_malta_init(MachineState *machine)
 pci_ide_create_devs(PCI_DEVICE(dev));
 
 /* Interrupt controller */
-qdev_connect_gpio_out_named(DEVICE(piix4), "intr", 0, i8259_irq);
+dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pic"));
+i8259 = i8259_init(isa_bus, i8259_irq);
+for (i = 0; i < ISA_NUM_IRQS; i++) {
+qdev_connect_gpio_out(dev, i, i8259[i]);
+}
+g_free(i8259);
 
 /* generate SPD EEPROM data */
 dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
-- 
2.38.1




[PATCH v2 18/43] hw/isa/piix3: Remove unused include

2022-10-23 Thread Bernhard Beschow
Ammends commit 988fb613215993dd0ce642b89ca8182c479d39dd.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix3.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 59599558a1..aa32f43e4a 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -32,7 +32,6 @@
 #include "hw/ide/piix.h"
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
-#include "sysemu/xen.h"
 #include "sysemu/runstate.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/acpi_aml_interface.h"
-- 
2.38.1




[PATCH v2 12/43] hw/isa/piix3: Create USB controller in host device

2022-10-23 Thread Bernhard Beschow
The USB controller is an integral part of PIIX3 (function 2). So create
it as part of the south bridge.

Note that the USB function is optional in QEMU. This is why it gets
object_initialize_child()'ed in realize rather than in instance_init.

Signed-off-by: Bernhard Beschow 
---
 hw/i386/pc_piix.c |  7 ++-
 hw/isa/Kconfig|  1 +
 hw/isa/piix3.c| 17 +
 include/hw/southbridge/piix.h |  4 
 4 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index b97bff5674..22c1c5404c 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -51,7 +51,6 @@
 #include "exec/memory.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/piix4.h"
-#include "hw/usb/hcd-uhci.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "sysemu/xen.h"
@@ -221,6 +220,8 @@ static void pc_init1(MachineState *machine,
 pcms->bus = pci_bus;
 
 pci_dev = pci_new_multifunction(-1, true, type);
+object_property_set_bool(OBJECT(pci_dev), "has-usb",
+ machine_usb(machine), _abort);
 pci_realize_and_unref(pci_dev, pci_bus, _fatal);
 piix3 = PIIX3_PCI_DEVICE(pci_dev);
 piix3->pic = x86ms->gsi;
@@ -299,10 +300,6 @@ static void pc_init1(MachineState *machine,
 }
 #endif
 
-if (pcmc->pci_enabled && machine_usb(machine)) {
-pci_create_simple(pci_bus, piix3_devfn + 2, TYPE_PIIX3_USB_UHCI);
-}
-
 if (pcmc->pci_enabled && x86_machine_is_acpi_enabled(X86_MACHINE(pcms))) {
 PCIDevice *piix4_pm;
 
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 6e8f9cac54..f02eca3c3e 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -36,6 +36,7 @@ config PIIX3
 select I8257
 select ISA_BUS
 select MC146818RTC
+select USB_UHCI
 
 config PIIX4
 bool
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 75c6370e33..2f227fde0e 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -300,6 +300,7 @@ static const MemoryRegionOps rcr_ops = {
 static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 {
 PIIX3State *d = PIIX3_PCI_DEVICE(dev);
+PCIBus *pci_bus = pci_get_bus(dev);
 ISABus *isa_bus;
 
 isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev),
@@ -320,6 +321,16 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 if (!qdev_realize(DEVICE(>rtc), BUS(isa_bus), errp)) {
 return;
 }
+
+/* USB */
+if (d->has_usb) {
+object_initialize_child(OBJECT(dev), "uhci", >uhci,
+TYPE_PIIX3_USB_UHCI);
+qdev_prop_set_int32(DEVICE(>uhci), "addr", dev->devfn + 2);
+if (!qdev_realize(DEVICE(>uhci), BUS(pci_bus), errp)) {
+return;
+}
+}
 }
 
 static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope)
@@ -342,6 +353,11 @@ static void pci_piix3_init(Object *obj)
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 }
 
+static Property pci_piix3_props[] = {
+DEFINE_PROP_BOOL("has-usb", PIIX3State, has_usb, true),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pci_piix3_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -361,6 +377,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
  * pc_piix.c's pc_init1()
  */
 dc->user_creatable = false;
+device_class_set_props(dc, pci_piix3_props);
 adevc->build_dev_aml = build_pci_isa_aml;
 }
 
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index b1fa08dd2b..5367917182 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -15,6 +15,7 @@
 #include "hw/pci/pci.h"
 #include "qom/object.h"
 #include "hw/rtc/mc146818rtc.h"
+#include "hw/usb/hcd-uhci.h"
 
 /* PIRQRC[A:D]: PIRQx Route Control Registers */
 #define PIIX_PIRQCA 0x60
@@ -54,12 +55,15 @@ struct PIIXState {
 int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
 
 RTCState rtc;
+UHCIState uhci;
 
 /* Reset Control Register contents */
 uint8_t rcr;
 
 /* IO memory region for Reset Control Register (PIIX_RCR_IOPORT) */
 MemoryRegion rcr_mem;
+
+bool has_usb;
 };
 typedef struct PIIXState PIIX3State;
 
-- 
2.38.1




[PATCH v2 03/43] hw/isa/piix3: Remove extra ';' outside of functions

2022-10-23 Thread Bernhard Beschow
Fixes the "extra-semi" clang-tidy check.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 44a9998752..04895ce2e5 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -375,7 +375,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq,
  piix3, PIIX_NUM_PIRQS);
 pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
-};
+}
 
 static void piix3_class_init(ObjectClass *klass, void *data)
 {
@@ -410,7 +410,7 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp)
  */
 pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq,
  piix3, XEN_PIIX_NUM_PIRQS);
-};
+}
 
 static void piix3_xen_class_init(ObjectClass *klass, void *data)
 {
@@ -418,7 +418,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void 
*data)
 
 k->config_write = piix3_write_config_xen;
 k->realize = piix3_xen_realize;
-};
+}
 
 static const TypeInfo piix3_xen_info = {
 .name  = TYPE_PIIX3_XEN_DEVICE,
-- 
2.38.1