Re: [PATCH v2 03/19] hw/char/serial-pci-multi: Introduce PCI_MULTISERIAL QOM abstract parent

2023-02-12 Thread Philippe Mathieu-Daudé

On 13/2/23 08:08, Philippe Mathieu-Daudé wrote:

Introduce PCI_MULTISERIAL ("pci-serial"), QOM abstract parent of
"pci-serial-2x" and "pci-serial-4x".

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/char/serial-pci-multi.c | 35 ---
  1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index 54768d3d53..faeb0a9476 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -38,8 +38,15 @@
  
  #define PCI_SERIAL_MAX_PORTS 4
  
-typedef struct PCIMultiSerialState {

+#define TYPE_PCI_MULTISERIAL  "pci-serial"


Ouch, copy/paste mistake, this should be "pci-serial-multi".


+
+OBJECT_DECLARE_SIMPLE_TYPE(PCIMultiSerialState, PCI_MULTISERIAL)
+
+struct PCIMultiSerialState {
+/*< private >*/
  PCIDevicedev;
+/*< public >*/
+
  MemoryRegion iobar;
  uint32_t ports;
  char *name[PCI_SERIAL_MAX_PORTS];
@@ -47,7 +54,7 @@ typedef struct PCIMultiSerialState {
  uint32_t level[PCI_SERIAL_MAX_PORTS];
  qemu_irq *irqs;
  uint8_t  prog_if;
-} PCIMultiSerialState;
+};
  
  static void multi_serial_pci_exit(PCIDevice *dev)

  {
@@ -191,25 +198,23 @@ static void multi_serial_init(Object *o)
  
  static const TypeInfo multi_serial_pci_types[] = {

  {
-.name  = "pci-serial-2x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
-.class_init= multi_2x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
+.name   = TYPE_PCI_MULTISERIAL,
+.parent = TYPE_PCI_DEVICE,
+.instance_size  = sizeof(PCIMultiSerialState),
+.instance_init  = multi_serial_init,
+.abstract   = true,
+.interfaces = (InterfaceInfo[]) {
  { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  { },
  },
+}, {
+.name  = "pci-serial-2x",
+.parent= TYPE_PCI_MULTISERIAL,
+.class_init= multi_2x_serial_pci_class_initfn,
  }, {
  .name  = "pci-serial-4x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
+.parent= TYPE_PCI_MULTISERIAL,
  .class_init= multi_4x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
  }
  };
  





Re: [PATCH v2 6/9] hw/ppc: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Cédric Le Goater

On 2/13/23 08:04, Philippe Mathieu-Daudé wrote:

DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Cédric Le Goater 

Thanks,

C.


---
  hw/ppc/spapr_vio.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 9d4fec2c04..dfc5c436bd 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -382,7 +382,7 @@ static void rtas_quiesce(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
  
  static SpaprVioDevice *reg_conflict(SpaprVioDevice *dev)

  {
-SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
+SpaprVioBus *bus = SPAPR_VIO_BUS(qdev_get_parent_bus(DEVICE(dev)));
  BusChild *kid;
  SpaprVioDevice *other;
  
@@ -492,7 +492,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)

  }
  } else {
  /* Need to assign an address */
-SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
+SpaprVioBus *bus = SPAPR_VIO_BUS(qdev_get_parent_bus(DEVICE(dev)));
  
  do {

  dev->reg = bus->next_reg++;





[PATCH v2 16/19] hw/vfio/ccw: Replace DO_UPCAST(VFIOCCWDevice) by VFIO_CCW()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the VFIO_CCW() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/vfio/ccw.c | 35 ---
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 0354737666..a8aa5b48c4 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -76,8 +76,7 @@ struct VFIODeviceOps vfio_ccw_ops = {
 
 static IOInstEnding vfio_ccw_handle_request(SubchDev *sch)
 {
-S390CCWDevice *cdev = sch->driver_data;
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
 struct ccw_io_region *region = vcdev->io_region;
 int ret;
 
@@ -125,8 +124,7 @@ again:
 
 static IOInstEnding vfio_ccw_handle_store(SubchDev *sch)
 {
-S390CCWDevice *cdev = sch->driver_data;
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
 SCHIB *schib = >curr_status;
 struct ccw_schib_region *region = vcdev->schib_region;
 SCHIB *s;
@@ -170,8 +168,7 @@ static IOInstEnding vfio_ccw_handle_store(SubchDev *sch)
 
 static int vfio_ccw_handle_clear(SubchDev *sch)
 {
-S390CCWDevice *cdev = sch->driver_data;
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
 struct ccw_cmd_region *region = vcdev->async_cmd_region;
 int ret;
 
@@ -210,8 +207,7 @@ again:
 
 static int vfio_ccw_handle_halt(SubchDev *sch)
 {
-S390CCWDevice *cdev = sch->driver_data;
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
 struct ccw_cmd_region *region = vcdev->async_cmd_region;
 int ret;
 
@@ -252,8 +248,8 @@ again:
 static void vfio_ccw_reset(DeviceState *dev)
 {
 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
-S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+S390CCWDevice *cdev = S390_CCW_DEVICE(ccw_dev);
+VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
 
 ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
 }
@@ -588,9 +584,10 @@ static void vfio_ccw_put_device(VFIOCCWDevice *vcdev)
 static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev,
 Error **errp)
 {
-char *name = g_strdup_printf("%x.%x.%04x", vcdev->cdev.hostid.cssid,
- vcdev->cdev.hostid.ssid,
- vcdev->cdev.hostid.devid);
+S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
+char *name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
+ cdev->hostid.ssid,
+ cdev->hostid.devid);
 VFIODevice *vbasedev;
 
 QLIST_FOREACH(vbasedev, >device_list, next) {
@@ -611,14 +608,14 @@ static void vfio_ccw_get_device(VFIOGroup *group, 
VFIOCCWDevice *vcdev,
  */
 vcdev->vdev.ram_block_discard_allowed = true;
 
-if (vfio_get_device(group, vcdev->cdev.mdevid, >vdev, errp)) {
+if (vfio_get_device(group, cdev->mdevid, >vdev, errp)) {
 goto out_err;
 }
 
 vcdev->vdev.ops = _ccw_ops;
 vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
 vcdev->vdev.name = name;
-vcdev->vdev.dev = >cdev.parent_obj.parent_obj;
+vcdev->vdev.dev = >parent_obj.parent_obj;
 
 return;
 
@@ -657,9 +654,9 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 {
 VFIOGroup *group;
 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
-S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+S390CCWDevice *cdev = S390_CCW_DEVICE(ccw_dev);
 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
 Error *err = NULL;
 
 /* Call the class init function for subchannel. */
@@ -729,9 +726,9 @@ out_err_propagate:
 static void vfio_ccw_unrealize(DeviceState *dev)
 {
 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
-S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+S390CCWDevice *cdev = S390_CCW_DEVICE(ccw_dev);
 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
 VFIOGroup *group = vcdev->vdev.group;
 
 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
-- 
2.38.1




[PATCH v2 15/19] hw/s390x/event-facility: Replace DO_UPCAST(SCLPEvent) by SCLP_EVENT()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the SCLP_EVENT() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/s390x/event-facility.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index faa51aa4c7..6891e3cd73 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -64,8 +64,7 @@ static bool event_pending(SCLPEventFacility *ef)
 SCLPEventClass *event_class;
 
 QTAILQ_FOREACH(kid, >sbus.qbus.children, sibling) {
-DeviceState *qdev = kid->child;
-event = DO_UPCAST(SCLPEvent, qdev, qdev);
+event = SCLP_EVENT(kid->child);
 event_class = SCLP_EVENT_GET_CLASS(event);
 if (event->event_pending &&
 event_class->get_send_mask() & ef->receive_mask) {
-- 
2.38.1




[PATCH v2 12/19] hw/pci/pci: Replace DO_UPCAST(PCIBus) by PCI_BUS()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the PCI_BUS() QOM type-checking macro to avoid DO_UPCAST().

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

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 2e785e3aef..ae5c33adb6 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -391,7 +391,7 @@ void pci_device_reset(PCIDevice *dev)
  */
 static void pcibus_reset(BusState *qbus)
 {
-PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
+PCIBus *bus = PCI_BUS(qbus);
 int i;
 
 for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
-- 
2.38.1




[PATCH v2 14/19] hw/scsi/scsi-bus: Inline two uses of scsi_bus_from_device()

2023-02-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/s390x/ipl.c | 7 ++-
 hw/scsi/scsi-bus.c | 2 +-
 include/hw/scsi/scsi.h | 5 -
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 8612684d48..4f7f4e60d6 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -366,11 +366,8 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, 
int *devtype)
 ccw_dev = CCW_DEVICE(vfio_ccw_dev);
 tmp_dt = CCW_DEVTYPE_VFIO;
 } else {
-SCSIDevice *sd = (SCSIDevice *)
-object_dynamic_cast(OBJECT(dev_st),
-TYPE_SCSI_DEVICE);
-if (sd) {
-SCSIBus *sbus = scsi_bus_from_device(sd);
+if (object_dynamic_cast(OBJECT(dev_st), TYPE_SCSI_DEVICE)) {
+SCSIBus *sbus = SCSI_BUS(qdev_get_parent_bus(dev_st));
 VirtIODevice *vdev = (VirtIODevice *)
 object_dynamic_cast(OBJECT(sbus->qbus.parent),
 TYPE_VIRTIO_DEVICE);
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index c4525515ab..ee72b86b13 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -679,7 +679,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, 
SCSIDevice *d,
 uint32_t tag, uint32_t lun, void *hba_private)
 {
 SCSIRequest *req;
-SCSIBus *bus = scsi_bus_from_device(d);
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(d)));
 BusState *qbus = BUS(bus);
 const int memset_off = offsetof(SCSIRequest, sense)
+ sizeof(req->sense);
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index eb558c145a..e3263dec0d 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -175,11 +175,6 @@ static inline void scsi_bus_init(SCSIBus *bus, size_t 
bus_size,
 scsi_bus_init_named(bus, bus_size, host, info, NULL);
 }
 
-static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
-{
-return SCSI_BUS(qdev_get_parent_bus(DEVICE(d)));
-}
-
 SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
   int unit, bool removable, int bootindex,
   bool share_rw,
-- 
2.38.1




[PATCH v2 10/19] hw/net/ne2000-pci: Replace DO_UPCAST(PCINE2000State) by PCI_NE2000()

2023-02-12 Thread Philippe Mathieu-Daudé
Define TYPE_PCI_NE2000 and the QOM PCI_NE2000() macro.
Use PCI_NE2000() instead of DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/ne2000-pci.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c
index edc6689d33..0332e7f616 100644
--- a/hw/net/ne2000-pci.c
+++ b/hw/net/ne2000-pci.c
@@ -30,10 +30,16 @@
 #include "ne2000.h"
 #include "sysemu/sysemu.h"
 
-typedef struct PCINE2000State {
+#define TYPE_PCI_NE2000 "ne2k_pci"
+OBJECT_DECLARE_SIMPLE_TYPE(PCINE2000State, PCI_NE2000)
+
+struct PCINE2000State {
+/*< private >*/
 PCIDevice dev;
+/*< public >*/
+
 NE2000State ne2000;
-} PCINE2000State;
+};
 
 static const VMStateDescription vmstate_pci_ne2000 = {
 .name = "ne2000",
@@ -54,7 +60,7 @@ static NetClientInfo net_ne2000_info = {
 
 static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp)
 {
-PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+PCINE2000State *d = PCI_NE2000(pci_dev);
 NE2000State *s;
 uint8_t *pci_conf;
 
@@ -77,7 +83,7 @@ static void pci_ne2000_realize(PCIDevice *pci_dev, Error 
**errp)
 
 static void pci_ne2000_exit(PCIDevice *pci_dev)
 {
-PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+PCINE2000State *d = PCI_NE2000(pci_dev);
 NE2000State *s = >ne2000;
 
 qemu_del_nic(s->nic);
@@ -87,7 +93,7 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
 static void ne2000_instance_init(Object *obj)
 {
 PCIDevice *pci_dev = PCI_DEVICE(obj);
-PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+PCINE2000State *d = PCI_NE2000(pci_dev);
 NE2000State *s = >ne2000;
 
 device_add_bootindex_property(obj, >c.bootindex,
@@ -117,7 +123,7 @@ static void ne2000_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo ne2000_info = {
-.name  = "ne2k_pci",
+.name  = TYPE_PCI_NE2000,
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(PCINE2000State),
 .class_init= ne2000_class_init,
-- 
2.38.1




[RFC PATCH v2 19/19] hw/usb: Inline usb_bus_from_device()

2023-02-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
RFC Other devices don't use such helper. Maybe it should
be the other way around, introduce more bus_from_device()
helpers?
---
 hw/usb/bus.c| 10 +-
 hw/usb/core.c   |  6 +++---
 hw/usb/dev-hub.c|  4 ++--
 hw/usb/dev-serial.c | 10 +-
 hw/usb/hcd-xhci.c   |  2 +-
 include/hw/usb.h|  5 -
 6 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index d7c3c71435..4a1b67761c 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -427,7 +427,7 @@ void usb_unregister_port(USBBus *bus, USBPort *port)
 
 void usb_claim_port(USBDevice *dev, Error **errp)
 {
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 USBPort *port;
 USBDevice *hub;
 
@@ -473,7 +473,7 @@ void usb_claim_port(USBDevice *dev, Error **errp)
 
 void usb_release_port(USBDevice *dev)
 {
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 USBPort *port = dev->port;
 
 assert(port != NULL);
@@ -517,7 +517,7 @@ static void usb_mask_to_str(char *dest, size_t size,
 
 void usb_check_attach(USBDevice *dev, Error **errp)
 {
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 USBPort *port = dev->port;
 char devspeed[32], portspeed[32];
 
@@ -555,7 +555,7 @@ void usb_device_attach(USBDevice *dev, Error **errp)
 
 int usb_device_detach(USBDevice *dev)
 {
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 USBPort *port = dev->port;
 
 assert(port != NULL);
@@ -583,7 +583,7 @@ static const char *usb_speed(unsigned int speed)
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 {
 USBDevice *dev = USB_DEVICE(qdev);
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(qdev));
 
 monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
indent, "", bus->busnr, dev->addr,
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 975f76250a..f358f0313a 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -95,7 +95,7 @@ void usb_device_reset(USBDevice *dev)
 void usb_wakeup(USBEndpoint *ep, unsigned int stream)
 {
 USBDevice *dev = ep->dev;
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 
 if (!phase_check(PHASE_MACHINE_READY)) {
 /*
@@ -556,7 +556,7 @@ void usb_packet_check_state(USBPacket *p, USBPacketState 
expected)
 return;
 }
 dev = p->ep->dev;
-bus = usb_bus_from_device(dev);
+bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 trace_usb_packet_state_fault(bus->busnr, dev->port->path, p->ep->nr, p,
  usb_packet_state_name(p->state),
  usb_packet_state_name(expected));
@@ -567,7 +567,7 @@ void usb_packet_set_state(USBPacket *p, USBPacketState 
state)
 {
 if (p->ep) {
 USBDevice *dev = p->ep->dev;
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 trace_usb_packet_state_change(bus->busnr, dev->port->path, p->ep->nr, 
p,
   usb_packet_state_name(p->state),
   usb_packet_state_name(state));
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 4734700e3e..4a0bcc4093 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -572,7 +572,7 @@ static void usb_hub_unrealize(USBDevice *dev)
 int i;
 
 for (i = 0; i < s->num_ports; i++) {
-usb_unregister_port(usb_bus_from_device(dev),
+usb_unregister_port(USB_BUS(qdev_get_parent_bus(DEVICE(dev))),
 >ports[i].port);
 }
 
@@ -611,7 +611,7 @@ static void usb_hub_realize(USBDevice *dev, Error **errp)
 s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
 for (i = 0; i < s->num_ports; i++) {
 port = >ports[i];
-usb_register_port(usb_bus_from_device(dev),
+usb_register_port(USB_BUS(qdev_get_parent_bus(DEVICE(dev))),
   >port, s, i, _hub_port_ops,
   USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
 usb_port_location(>port, dev->port, i+1);
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 63047d79cf..0194bb541b 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -190,7 +190,7 @@ static void usb_serial_set_flow_control(USBSerialState *s,
 uint8_t flow_control)
 {
 USBDevice *dev = USB_DEVICE(s);
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 
 /* TODO: ioctl */
 s->flow_control = flow_control;
@@ -200,7 +200,7 @@ static void usb_serial_set_flow_control(USBSerialState *s,
 static void 

[PATCH v2 11/19] hw/net/tulip: Finish QOM conversion

2023-02-12 Thread Philippe Mathieu-Daudé
Use the TULIP() and DEVICE() QOM type-checking macros.
Remove uses of DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/tulip.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index 915e5fb595..990507859d 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -19,7 +19,10 @@
 #include "net/eth.h"
 
 struct TULIPState {
+/*< private >*/
 PCIDevice dev;
+/*< public >*/
+
 MemoryRegion io;
 MemoryRegion memory;
 NICConf c;
@@ -959,7 +962,7 @@ static void tulip_fill_eeprom(TULIPState *s)
 
 static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp)
 {
-TULIPState *s = DO_UPCAST(TULIPState, dev, pci_dev);
+TULIPState *s = TULIP(pci_dev);
 uint8_t *pci_conf;
 
 pci_conf = s->dev.config;
@@ -967,7 +970,7 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error 
**errp)
 
 qemu_macaddr_default_if_unset(>c.macaddr);
 
-s->eeprom = eeprom93xx_new(_dev->qdev, 64);
+s->eeprom = eeprom93xx_new(DEVICE(pci_dev), 64);
 tulip_fill_eeprom(s);
 
 memory_region_init_io(>io, OBJECT(>dev), _ops, s,
@@ -983,27 +986,26 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error 
**errp)
 
 s->nic = qemu_new_nic(_tulip_info, >c,
   object_get_typename(OBJECT(pci_dev)),
-  pci_dev->qdev.id, s);
+  DEVICE(pci_dev)->id, s);
 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
 }
 
 static void pci_tulip_exit(PCIDevice *pci_dev)
 {
-TULIPState *s = DO_UPCAST(TULIPState, dev, pci_dev);
+TULIPState *s = TULIP(pci_dev);
 
 qemu_del_nic(s->nic);
 qemu_free_irq(s->irq);
-eeprom93xx_free(_dev->qdev, s->eeprom);
+eeprom93xx_free(DEVICE(s), s->eeprom);
 }
 
 static void tulip_instance_init(Object *obj)
 {
-PCIDevice *pci_dev = PCI_DEVICE(obj);
-TULIPState *d = DO_UPCAST(TULIPState, dev, pci_dev);
+TULIPState *s = TULIP(obj);
 
-device_add_bootindex_property(obj, >c.bootindex,
+device_add_bootindex_property(obj, >c.bootindex,
   "bootindex", "/ethernet-phy@0",
-  _dev->qdev);
+  DEVICE(obj));
 }
 
 static Property tulip_properties[] = {
-- 
2.38.1




Re: [PATCH v2 9/9] qdev-monitor: Use qdev_get_parent_bus() in bus_print_dev()

2023-02-12 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> No need to pass 'dev' and 'dev->parent_bus' when we can
> retrieve 'parent_bus' with qdev_get_parent_bus().
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  softmmu/qdev-monitor.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
> index 820e7f52ad..12e4899f0d 100644
> --- a/softmmu/qdev-monitor.c
> +++ b/softmmu/qdev-monitor.c
> @@ -770,9 +770,9 @@ static void qdev_print_props(Monitor *mon, DeviceState 
> *dev, Property *props,
>  }
>  }
>  
> -static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int 
> indent)
> +static void bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
>  {
> -BusClass *bc = BUS_GET_CLASS(bus);
> +BusClass *bc = BUS_GET_CLASS(qdev_get_parent_bus(dev));
>  
>  if (bc->print_dev) {
>  bc->print_dev(mon, dev, indent);
> @@ -811,7 +811,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, 
> int indent)
>  qdev_print_props(mon, dev, DEVICE_CLASS(class)->props_, indent);
>  class = object_class_get_parent(class);
>  } while (class != object_class_by_name(TYPE_DEVICE));
> -bus_print_dev(dev->parent_bus, mon, dev, indent);
> +bus_print_dev(mon, dev, indent);
>  QLIST_FOREACH(child, >child_bus, sibling) {
>  qbus_print(mon, child, indent);
>  }

Reviewed-by: Markus Armbruster 




[PATCH v2 04/19] hw/char/serial-pci-multi: Factor multi_serial_class_initfn() out

2023-02-12 Thread Philippe Mathieu-Daudé
Extract code common to multi_2x_serial_pci_class_initfn() and
multi_4x_serial_pci_class_initfn() to multi_serial_class_initfn().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci-multi.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index faeb0a9476..cd5af24bd2 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -155,14 +155,14 @@ static Property multi_4x_serial_pci_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
-static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
+static void multi_serial_class_initfn(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
+
 pc->realize = multi_serial_pci_realize;
 pc->exit = multi_serial_pci_exit;
 pc->vendor_id = PCI_VENDOR_ID_REDHAT;
-pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL2;
 pc->revision = 1;
 pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
 dc->vmsd = _pci_multi_serial;
@@ -170,19 +170,22 @@ static void multi_2x_serial_pci_class_initfn(ObjectClass 
*klass, void *data)
 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
 
+static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
+
+pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL2;
+device_class_set_props(dc, multi_2x_serial_pci_properties);
+}
+
 static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
-pc->realize = multi_serial_pci_realize;
-pc->exit = multi_serial_pci_exit;
-pc->vendor_id = PCI_VENDOR_ID_REDHAT;
+
 pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL4;
-pc->revision = 1;
-pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
-dc->vmsd = _pci_multi_serial;
 device_class_set_props(dc, multi_4x_serial_pci_properties);
-set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
 
 static void multi_serial_init(Object *o)
@@ -202,6 +205,7 @@ static const TypeInfo multi_serial_pci_types[] = {
 .parent = TYPE_PCI_DEVICE,
 .instance_size  = sizeof(PCIMultiSerialState),
 .instance_init  = multi_serial_init,
+.class_init = multi_serial_class_initfn,
 .abstract   = true,
 .interfaces = (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
-- 
2.38.1




[PATCH v2 18/19] hw/usb: Replace DO_UPCAST(USBBus) by USB_BUS()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the USB_BUS() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/usb.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/usb.h b/include/hw/usb.h
index b2111bb1c7..f743a5e945 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -520,7 +520,7 @@ void usb_check_attach(USBDevice *dev, Error **errp);
 
 static inline USBBus *usb_bus_from_device(USBDevice *d)
 {
-return DO_UPCAST(USBBus, qbus, qdev_get_parent_bus(DEVICE(d)));
+return USB_BUS(qdev_get_parent_bus(DEVICE(d)));
 }
 
 extern const VMStateDescription vmstate_usb_device;
-- 
2.38.1




[PATCH v2 13/19] hw/scsi/scsi-bus: Replace DO_UPCAST(SCSIBus) by SCSI_BUS()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the SCSI_BUS() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/scsi/scsi-bus.c | 12 ++--
 include/hw/scsi/scsi.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 7b2a82b335..c4525515ab 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -104,7 +104,7 @@ static void scsi_device_unrealize(SCSIDevice *s)
 int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
size_t buf_len, void *hba_private)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(dev)));
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(dev)));
 int rc;
 
 assert(cmd->len == 0);
@@ -250,7 +250,7 @@ static bool scsi_bus_check_address(BusState *qbus, 
DeviceState *qdev, Error **er
 static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
 {
 SCSIDevice *dev = SCSI_DEVICE(qdev);
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(dev)));
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(qdev));
 bool is_free;
 Error *local_err = NULL;
 
@@ -705,7 +705,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, 
SCSIDevice *d,
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
   uint8_t *buf, size_t buf_len, void *hba_private)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(d)));
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(d)));
 const SCSIReqOps *ops;
 SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(d);
 SCSIRequest *req;
@@ -1353,7 +1353,7 @@ int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, 
uint8_t *buf,
 
 void scsi_device_report_change(SCSIDevice *dev, SCSISense sense)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(dev)));
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(dev)));
 
 scsi_device_set_ua(dev, sense);
 if (bus->info->change) {
@@ -1698,7 +1698,7 @@ static int put_scsi_requests(QEMUFile *f, void *pv, 
size_t size,
  const VMStateField *field, JSONWriter *vmdesc)
 {
 SCSIDevice *s = pv;
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(s)));
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(s)));
 SCSIRequest *req;
 
 QTAILQ_FOREACH(req, >requests, next) {
@@ -1726,7 +1726,7 @@ static int get_scsi_requests(QEMUFile *f, void *pv, 
size_t size,
  const VMStateField *field)
 {
 SCSIDevice *s = pv;
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(s)));
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(s)));
 int8_t sbyte;
 
 while ((sbyte = qemu_get_sbyte(f)) > 0) {
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 843dde8851..eb558c145a 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -177,7 +177,7 @@ static inline void scsi_bus_init(SCSIBus *bus, size_t 
bus_size,
 
 static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
 {
-return DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(d)));
+return SCSI_BUS(qdev_get_parent_bus(DEVICE(d)));
 }
 
 SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
-- 
2.38.1




[PATCH v2 09/19] hw/net/eepro100: Replace DO_UPCAST(EEPRO100State) by EEPRO100()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the EEPRO100() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/eepro100.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index dac42ba17b..915935a818 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -1828,7 +1828,7 @@ static const VMStateDescription vmstate_eepro100 = {
 
 static void pci_nic_uninit(PCIDevice *pci_dev)
 {
-EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
+EEPRO100State *s = EEPRO100(pci_dev);
 
 vmstate_unregister(VMSTATE_IF(_dev->qdev), s->vmstate, s);
 g_free(s->vmstate);
@@ -1844,7 +1844,7 @@ static NetClientInfo net_eepro100_info = {
 
 static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
 {
-EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
+EEPRO100State *s = EEPRO100(pci_dev);
 E100PCIDeviceInfo *info = eepro100_get_class(s);
 Error *local_err = NULL;
 
@@ -1895,7 +1895,7 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error 
**errp)
 
 static void eepro100_instance_init(Object *obj)
 {
-EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, PCI_DEVICE(obj));
+EEPRO100State *s = EEPRO100(obj);
 device_add_bootindex_property(obj, >conf.bootindex,
   "bootindex", "/ethernet-phy@0",
   DEVICE(s));
-- 
2.38.1




[PATCH v2 08/19] hw/net/eepro100: Introduce TYPE_EEPRO100 QOM abstract parent

2023-02-12 Thread Philippe Mathieu-Daudé
Have all the EEPRO100-based devices share a common (abstract)
QOM parent.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/eepro100.c | 40 ++--
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index dc07984ae9..dac42ba17b 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -235,8 +235,14 @@ typedef enum {
 ru_ready = 4
 } ru_state_t;
 
-typedef struct {
+#define TYPE_EEPRO100 "eepro100"
+OBJECT_DECLARE_SIMPLE_TYPE(EEPRO100State, EEPRO100)
+
+struct EEPRO100State {
+/*< private >*/
 PCIDevice dev;
+/*< public >*/
+
 /* Hash register (multicast mask array, multiple individual addresses). */
 uint8_t mult[8];
 MemoryRegion mmio_bar;
@@ -279,7 +285,7 @@ typedef struct {
 /* Quasi static device properties (no need to save them). */
 uint16_t stats_size;
 bool has_extended_tcb_support;
-} EEPRO100State;
+};
 
 /* Word indices in EEPROM. */
 typedef enum {
@@ -2082,21 +2088,27 @@ static void eepro100_class_init(ObjectClass *klass, 
void *data)
 k->subsystem_id = info->subsystem_id;
 }
 
+static const TypeInfo eepro100_info = {
+.name  = TYPE_EEPRO100,
+.parent= TYPE_PCI_DEVICE,
+.class_init= eepro100_class_init,
+.abstract  = true,
+.instance_size = sizeof(EEPRO100State),
+.instance_init = eepro100_instance_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+};
+
 static void eepro100_register_types(void)
 {
-size_t i;
-for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
-TypeInfo type_info = {};
-E100PCIDeviceInfo *info = _devices[i];
+type_register_static(_info);
 
-type_info.name = info->name;
-type_info.parent = TYPE_PCI_DEVICE;
-type_info.class_init = eepro100_class_init;
-type_info.instance_size = sizeof(EEPRO100State);
-type_info.instance_init = eepro100_instance_init;
-type_info.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
+for (size_t i = 0; i < ARRAY_SIZE(e100_devices); i++) {
+TypeInfo type_info = {
+.name   = e100_devices[i].name,
+.parent = TYPE_EEPRO100,
 };
 
 type_register(_info);
-- 
2.38.1




[PATCH v2 17/19] hw/usb/dev-hub: Use QOM USB_HUB() macro instead of casting

2023-02-12 Thread Philippe Mathieu-Daudé
Use the safer USB_HUB() QOM type-checking macro instead of casts.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/usb/dev-hub.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index a6b50dbc8d..4734700e3e 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -350,7 +350,7 @@ static const char *feature_name(int feature)
 static void usb_hub_handle_control(USBDevice *dev, USBPacket *p,
int request, int value, int index, int length, uint8_t *data)
 {
-USBHubState *s = (USBHubState *)dev;
+USBHubState *s = USB_HUB(dev);
 int ret;
 
 trace_usb_hub_control(s->dev.addr, request, value, index, length);
@@ -523,7 +523,7 @@ static void usb_hub_handle_control(USBDevice *dev, 
USBPacket *p,
 
 static void usb_hub_handle_data(USBDevice *dev, USBPacket *p)
 {
-USBHubState *s = (USBHubState *)dev;
+USBHubState *s = USB_HUB(dev);
 
 switch(p->pid) {
 case USB_TOKEN_IN:
@@ -568,7 +568,7 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket 
*p)
 
 static void usb_hub_unrealize(USBDevice *dev)
 {
-USBHubState *s = (USBHubState *)dev;
+USBHubState *s = USB_HUB(dev);
 int i;
 
 for (i = 0; i < s->num_ports; i++) {
-- 
2.38.1




[PATCH v2 07/19] hw/ide/qdev: Replace DO_UPCAST(IDEBus) by IDE_BUS()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the IDE_BUS() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/qdev.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 1ead62fd18..a168643266 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -90,7 +90,7 @@ static void ide_qdev_realize(DeviceState *qdev, Error **errp)
 {
 IDEDevice *dev = IDE_DEVICE(qdev);
 IDEDeviceClass *dc = IDE_DEVICE_GET_CLASS(dev);
-IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev_get_parent_bus(qdev));
+IDEBus *bus = IDE_BUS(qdev_get_parent_bus(qdev));
 
 if (dev->unit == -1) {
 dev->unit = bus->master ? 1 : 0;
@@ -139,7 +139,7 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, 
DriveInfo *drive)
 int ide_get_geometry(BusState *bus, int unit,
  int16_t *cyls, int8_t *heads, int8_t *secs)
 {
-IDEState *s = _UPCAST(IDEBus, qbus, bus)->ifs[unit];
+IDEState *s = _BUS(bus)->ifs[unit];
 
 if (s->drive_kind != IDE_HD || !s->blk) {
 return -1;
@@ -153,7 +153,7 @@ int ide_get_geometry(BusState *bus, int unit,
 
 int ide_get_bios_chs_trans(BusState *bus, int unit)
 {
-return DO_UPCAST(IDEBus, qbus, bus)->ifs[unit].chs_trans;
+return IDE_BUS(bus)->ifs[unit].chs_trans;
 }
 
 /* - */
@@ -164,7 +164,7 @@ typedef struct IDEDrive {
 
 static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
 {
-IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev_get_parent_bus(DEVICE(dev)));
+IDEBus *bus = IDE_BUS(qdev_get_parent_bus(DEVICE(dev)));
 IDEState *s = bus->ifs + dev->unit;
 int ret;
 
-- 
2.38.1




[PATCH v2 05/19] hw/char/serial-pci-multi: Replace DO_UPCAST() by PCI_MULTISERIAL()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the PCI_MULTISERIAL() QOM type-checking macro to avoid the few
DO_UPCAST(PCIMultiSerialState) calls.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci-multi.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index cd5af24bd2..6f4491210d 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -58,7 +58,7 @@ struct PCIMultiSerialState {
 
 static void multi_serial_pci_exit(PCIDevice *dev)
 {
-PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
+PCIMultiSerialState *pci = PCI_MULTISERIAL(dev);
 SerialState *s;
 int i;
 
@@ -97,11 +97,10 @@ static size_t multi_serial_get_port_count(PCIDeviceClass 
*pc)
 g_assert_not_reached();
 }
 
-
 static void multi_serial_pci_realize(PCIDevice *dev, Error **errp)
 {
 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
-PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
+PCIMultiSerialState *pci = PCI_MULTISERIAL(dev);
 SerialState *s;
 size_t i, nports = multi_serial_get_port_count(pc);
 
@@ -190,9 +189,8 @@ static void multi_4x_serial_pci_class_initfn(ObjectClass 
*klass, void *data)
 
 static void multi_serial_init(Object *o)
 {
-PCIDevice *dev = PCI_DEVICE(o);
-PCIMultiSerialState *pms = DO_UPCAST(PCIMultiSerialState, dev, dev);
-size_t i, nports = multi_serial_get_port_count(PCI_DEVICE_GET_CLASS(dev));
+PCIMultiSerialState *pms = PCI_MULTISERIAL(o);
+size_t i, nports = multi_serial_get_port_count(PCI_DEVICE_GET_CLASS(o));
 
 for (i = 0; i < nports; i++) {
 object_initialize_child(o, "serial[*]", >state[i], TYPE_SERIAL);
-- 
2.38.1




[PATCH v2 06/19] hw/ide/qdev: Replace DO_UPCAST(IDEDevice) by IDE_DEVICE()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the IDE_DEVICE() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/qdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6ae2627a56..1ead62fd18 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -133,7 +133,7 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, 
DriveInfo *drive)
 qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(drive),
 _fatal);
 qdev_realize_and_unref(dev, >qbus, _fatal);
-return DO_UPCAST(IDEDevice, qdev, dev);
+return IDE_DEVICE(dev);
 }
 
 int ide_get_geometry(BusState *bus, int unit,
-- 
2.38.1




[PATCH v2 02/19] hw/char/serial-pci-multi: Batch register types using DEFINE_TYPES macro

2023-02-12 Thread Philippe Mathieu-Daudé
See rationale in commit 38b5d79b2e ("qom: add helper
macro DEFINE_TYPES()").

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci-multi.c | 52 +-
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index f18b8dcce5..54768d3d53 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -189,34 +189,28 @@ static void multi_serial_init(Object *o)
 }
 }
 
-static const TypeInfo multi_2x_serial_pci_info = {
-.name  = "pci-serial-2x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
-.class_init= multi_2x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
+static const TypeInfo multi_serial_pci_types[] = {
+{
+.name  = "pci-serial-2x",
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(PCIMultiSerialState),
+.instance_init = multi_serial_init,
+.class_init= multi_2x_serial_pci_class_initfn,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+}, {
+.name  = "pci-serial-4x",
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(PCIMultiSerialState),
+.instance_init = multi_serial_init,
+.class_init= multi_4x_serial_pci_class_initfn,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+}
 };
 
-static const TypeInfo multi_4x_serial_pci_info = {
-.name  = "pci-serial-4x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
-.class_init= multi_4x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
-};
-
-static void multi_serial_pci_register_types(void)
-{
-type_register_static(_2x_serial_pci_info);
-type_register_static(_4x_serial_pci_info);
-}
-
-type_init(multi_serial_pci_register_types)
+DEFINE_TYPES(multi_serial_pci_types)
-- 
2.38.1




[PATCH v2 03/19] hw/char/serial-pci-multi: Introduce PCI_MULTISERIAL QOM abstract parent

2023-02-12 Thread Philippe Mathieu-Daudé
Introduce PCI_MULTISERIAL ("pci-serial"), QOM abstract parent of
"pci-serial-2x" and "pci-serial-4x".

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci-multi.c | 35 ---
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index 54768d3d53..faeb0a9476 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -38,8 +38,15 @@
 
 #define PCI_SERIAL_MAX_PORTS 4
 
-typedef struct PCIMultiSerialState {
+#define TYPE_PCI_MULTISERIAL  "pci-serial"
+
+OBJECT_DECLARE_SIMPLE_TYPE(PCIMultiSerialState, PCI_MULTISERIAL)
+
+struct PCIMultiSerialState {
+/*< private >*/
 PCIDevicedev;
+/*< public >*/
+
 MemoryRegion iobar;
 uint32_t ports;
 char *name[PCI_SERIAL_MAX_PORTS];
@@ -47,7 +54,7 @@ typedef struct PCIMultiSerialState {
 uint32_t level[PCI_SERIAL_MAX_PORTS];
 qemu_irq *irqs;
 uint8_t  prog_if;
-} PCIMultiSerialState;
+};
 
 static void multi_serial_pci_exit(PCIDevice *dev)
 {
@@ -191,25 +198,23 @@ static void multi_serial_init(Object *o)
 
 static const TypeInfo multi_serial_pci_types[] = {
 {
-.name  = "pci-serial-2x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
-.class_init= multi_2x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
+.name   = TYPE_PCI_MULTISERIAL,
+.parent = TYPE_PCI_DEVICE,
+.instance_size  = sizeof(PCIMultiSerialState),
+.instance_init  = multi_serial_init,
+.abstract   = true,
+.interfaces = (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
 { },
 },
+}, {
+.name  = "pci-serial-2x",
+.parent= TYPE_PCI_MULTISERIAL,
+.class_init= multi_2x_serial_pci_class_initfn,
 }, {
 .name  = "pci-serial-4x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
+.parent= TYPE_PCI_MULTISERIAL,
 .class_init= multi_4x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
 }
 };
 
-- 
2.38.1




[PATCH v2 01/19] hw/char/serial-pci: Replace DO_UPCAST(PCISerialState) by PCI_SERIAL()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the PCI_SERIAL() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index 801b769aba..9689645cac 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -36,7 +36,10 @@
 #include "qom/object.h"
 
 struct PCISerialState {
+/*< private >*/
 PCIDevice dev;
+/*< public >*/
+
 SerialState state;
 uint8_t prog_if;
 };
@@ -46,7 +49,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCISerialState, PCI_SERIAL)
 
 static void serial_pci_realize(PCIDevice *dev, Error **errp)
 {
-PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
+PCISerialState *pci = PCI_SERIAL(dev);
 SerialState *s = >state;
 
 if (!qdev_realize(DEVICE(s), NULL, errp)) {
@@ -63,7 +66,7 @@ static void serial_pci_realize(PCIDevice *dev, Error **errp)
 
 static void serial_pci_exit(PCIDevice *dev)
 {
-PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
+PCISerialState *pci = PCI_SERIAL(dev);
 SerialState *s = >state;
 
 qdev_unrealize(DEVICE(s));
-- 
2.38.1




[PATCH v2 00/19] hw: Use QOM macros and remove DO_UPCAST() uses

2023-02-12 Thread Philippe Mathieu-Daudé
v2: Rebased

QOM housekeeping series which replace the DO_UPCAST() macro
uses by equivalent QOM ones. Also:
- Use DEVICE() macro
- Define some TYPE_xxx
- Define some type arrays using DEFINE_TYPES() macro
- Introduce abstract QOM (QDev) parent when relevant.

Based-on: <20230213070423.76428-1-phi...@linaro.org>
  hw/qdev: Housekeeping around qdev_get_parent_bus()

Philippe Mathieu-Daudé (19):
  hw/char/serial-pci: Replace DO_UPCAST(PCISerialState) by PCI_SERIAL()
  hw/char/serial-pci-multi: Batch register types using DEFINE_TYPES
macro
  hw/char/serial-pci-multi: Introduce PCI_MULTISERIAL QOM abstract
parent
  hw/char/serial-pci-multi: Factor multi_serial_class_initfn() out
  hw/char/serial-pci-multi: Replace DO_UPCAST() by PCI_MULTISERIAL()
  hw/ide/qdev: Replace DO_UPCAST(IDEDevice) by IDE_DEVICE()
  hw/ide/qdev: Replace DO_UPCAST(IDEBus) by IDE_BUS()
  hw/net/eepro100: Introduce TYPE_EEPRO100 QOM abstract parent
  hw/net/eepro100: Replace DO_UPCAST(EEPRO100State) by EEPRO100()
  hw/net/ne2000-pci: Replace DO_UPCAST(PCINE2000State) by PCI_NE2000()
  hw/net/tulip: Finish QOM conversion
  hw/pci/pci: Replace DO_UPCAST(PCIBus) by PCI_BUS()
  hw/scsi/scsi-bus: Replace DO_UPCAST(SCSIBus) by SCSI_BUS()
  hw/scsi/scsi-bus: Inline two uses of scsi_bus_from_device()
  hw/s390x/event-facility: Replace DO_UPCAST(SCLPEvent) by SCLP_EVENT()
  hw/vfio/ccw: Replace DO_UPCAST(VFIOCCWDevice) by VFIO_CCW()
  hw/usb/dev-hub: Use QOM USB_HUB() macro instead of casting
  hw/usb: Replace DO_UPCAST(USBBus) by USB_BUS()
  hw/usb: Inline usb_bus_from_device()

 hw/char/serial-pci-multi.c | 93 +++---
 hw/char/serial-pci.c   |  7 ++-
 hw/ide/qdev.c  | 10 ++--
 hw/net/eepro100.c  | 46 ---
 hw/net/ne2000-pci.c| 18 +---
 hw/net/tulip.c | 20 
 hw/pci/pci.c   |  2 +-
 hw/s390x/event-facility.c  |  3 +-
 hw/s390x/ipl.c |  7 +--
 hw/scsi/scsi-bus.c | 14 +++---
 hw/usb/bus.c   | 10 ++--
 hw/usb/core.c  |  6 +--
 hw/usb/dev-hub.c   | 10 ++--
 hw/usb/dev-serial.c| 10 ++--
 hw/usb/hcd-xhci.c  |  2 +-
 hw/vfio/ccw.c  | 35 +++---
 include/hw/scsi/scsi.h |  5 --
 include/hw/usb.h   |  5 --
 18 files changed, 155 insertions(+), 148 deletions(-)

-- 
2.38.1




[PATCH v2 4/9] hw/net: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Philippe Mathieu-Daudé
DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/virtio-net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3ae909041a..8bc160ab59 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3423,7 +3423,7 @@ static bool failover_replug_primary(VirtIONet *n, 
DeviceState *dev,
 if (!pdev->partially_hotplugged) {
 return true;
 }
-primary_bus = dev->parent_bus;
+primary_bus = qdev_get_parent_bus(dev);
 if (!primary_bus) {
 error_setg(errp, "virtio_net: couldn't find primary bus");
 return false;
-- 
2.38.1




[PATCH v2 7/9] hw/usb: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Philippe Mathieu-Daudé
DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/usb/bus.c  |  2 +-
 hw/usb/desc.c |  2 +-
 hw/usb/dev-smartcard-reader.c | 16 
 include/hw/usb.h  |  2 +-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 92d6ed5626..d7c3c71435 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -595,7 +595,7 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState 
*qdev, int indent)
 static char *usb_get_dev_path(DeviceState *qdev)
 {
 USBDevice *dev = USB_DEVICE(qdev);
-DeviceState *hcd = qdev->parent_bus->parent;
+DeviceState *hcd = qdev_get_parent_bus(qdev)->parent;
 char *id = qdev_get_dev_path(hcd);
 
 if (id) {
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index 7f6cc2f99b..2646515e26 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -553,7 +553,7 @@ void usb_desc_set_string(USBDevice *dev, uint8_t index, 
const char *str)
  */
 void usb_desc_create_serial(USBDevice *dev)
 {
-DeviceState *hcd = dev->qdev.parent_bus->parent;
+DeviceState *hcd = qdev_get_parent_bus(DEVICE(dev))->parent;
 const USBDesc *desc = usb_device_get_usb_desc(dev);
 int index = desc->id.iSerialNumber;
 char *path, *serial;
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 28164d89be..5e94b4f64a 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1187,7 +1187,7 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card,
   uint8_t *apdu, uint32_t len)
 {
 DeviceState *qdev = DEVICE(card);
-USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
+USBDevice *dev = USB_DEVICE(qdev_get_parent_bus(qdev)->parent);
 USBCCIDState *s = USB_CCID_DEV(dev);
 Answer *answer;
 
@@ -1210,7 +1210,7 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card,
 void ccid_card_card_removed(CCIDCardState *card)
 {
 DeviceState *qdev = DEVICE(card);
-USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
+USBDevice *dev = USB_DEVICE(qdev_get_parent_bus(qdev)->parent);
 USBCCIDState *s = USB_CCID_DEV(dev);
 
 ccid_on_slot_change(s, false);
@@ -1221,7 +1221,7 @@ void ccid_card_card_removed(CCIDCardState *card)
 int ccid_card_ccid_attach(CCIDCardState *card)
 {
 DeviceState *qdev = DEVICE(card);
-USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
+USBDevice *dev = USB_DEVICE(qdev_get_parent_bus(qdev)->parent);
 USBCCIDState *s = USB_CCID_DEV(dev);
 
 DPRINTF(s, 1, "CCID Attach\n");
@@ -1231,7 +1231,7 @@ int ccid_card_ccid_attach(CCIDCardState *card)
 void ccid_card_ccid_detach(CCIDCardState *card)
 {
 DeviceState *qdev = DEVICE(card);
-USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
+USBDevice *dev = USB_DEVICE(qdev_get_parent_bus(qdev)->parent);
 USBCCIDState *s = USB_CCID_DEV(dev);
 
 DPRINTF(s, 1, "CCID Detach\n");
@@ -1244,7 +1244,7 @@ void ccid_card_ccid_detach(CCIDCardState *card)
 void ccid_card_card_error(CCIDCardState *card, uint64_t error)
 {
 DeviceState *qdev = DEVICE(card);
-USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
+USBDevice *dev = USB_DEVICE(qdev_get_parent_bus(qdev)->parent);
 USBCCIDState *s = USB_CCID_DEV(dev);
 
 s->bmCommandStatus = COMMAND_STATUS_FAILED;
@@ -1263,7 +1263,7 @@ void ccid_card_card_error(CCIDCardState *card, uint64_t 
error)
 void ccid_card_card_inserted(CCIDCardState *card)
 {
 DeviceState *qdev = DEVICE(card);
-USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
+USBDevice *dev = USB_DEVICE(qdev_get_parent_bus(qdev)->parent);
 USBCCIDState *s = USB_CCID_DEV(dev);
 
 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
@@ -1275,7 +1275,7 @@ static void ccid_card_unrealize(DeviceState *qdev)
 {
 CCIDCardState *card = CCID_CARD(qdev);
 CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
-USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
+USBDevice *dev = USB_DEVICE(qdev_get_parent_bus(qdev)->parent);
 USBCCIDState *s = USB_CCID_DEV(dev);
 
 if (ccid_card_inserted(s)) {
@@ -1291,7 +1291,7 @@ static void ccid_card_realize(DeviceState *qdev, Error 
**errp)
 {
 CCIDCardState *card = CCID_CARD(qdev);
 CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
-USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
+USBDevice *dev = USB_DEVICE(qdev_get_parent_bus(qdev)->parent);
 USBCCIDState *s = USB_CCID_DEV(dev);
 Error *local_err = NULL;
 
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 32c23a5ca2..b2111bb1c7 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -520,7 +520,7 @@ void usb_check_attach(USBDevice *dev, Error **errp);
 
 static inline USBBus *usb_bus_from_device(USBDevice *d)
 {
-return DO_UPCAST(USBBus, qbus, d->qdev.parent_bus);
+return DO_UPCAST(USBBus, qbus, qdev_get_parent_bus(DEVICE(d)));
 }
 
 

[PATCH v2 8/9] hw: Use qdev_get_parent_bus() in qdev_get_own_fw_dev_path_from_handler()

2023-02-12 Thread Philippe Mathieu-Daudé
No need to pass 'dev' and 'dev->parent_bus' when we can
retrieve 'parent_bus' with qdev_get_parent_bus().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/core/qdev-fw.c  | 9 +
 include/hw/qdev-core.h | 2 +-
 softmmu/bootdevice.c   | 2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/core/qdev-fw.c b/hw/core/qdev-fw.c
index a31958355f..c2df1f4796 100644
--- a/hw/core/qdev-fw.c
+++ b/hw/core/qdev-fw.c
@@ -41,9 +41,10 @@ static char *bus_get_fw_dev_path(BusState *bus, DeviceState 
*dev)
 return NULL;
 }
 
-static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
+static char *qdev_get_fw_dev_path_from_handler(DeviceState *dev)
 {
 Object *obj = OBJECT(dev);
+BusState *bus = qdev_get_parent_bus(dev);
 char *d = NULL;
 
 while (!d && obj->parent) {
@@ -53,11 +54,11 @@ static char *qdev_get_fw_dev_path_from_handler(BusState 
*bus, DeviceState *dev)
 return d;
 }
 
-char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
+char *qdev_get_own_fw_dev_path_from_handler(DeviceState *dev)
 {
 Object *obj = OBJECT(dev);
 
-return fw_path_provider_try_get_dev_path(obj, bus, dev);
+return fw_path_provider_try_get_dev_path(obj, qdev_get_parent_bus(dev), 
dev);
 }
 
 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
@@ -67,7 +68,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char 
*p, int size)
 if (dev && dev->parent_bus) {
 char *d;
 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
-d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
+d = qdev_get_fw_dev_path_from_handler(dev);
 if (!d) {
 d = bus_get_fw_dev_path(dev->parent_bus, dev);
 }
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index f5b3b2f89a..93718be156 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -774,7 +774,7 @@ bool bus_is_in_reset(BusState *bus);
 BusState *sysbus_get_default(void);
 
 char *qdev_get_fw_dev_path(DeviceState *dev);
-char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev);
+char *qdev_get_own_fw_dev_path_from_handler(DeviceState *dev);
 
 void device_class_set_props(DeviceClass *dc, Property *props);
 
diff --git a/softmmu/bootdevice.c b/softmmu/bootdevice.c
index 2106f1026f..7834bf 100644
--- a/softmmu/bootdevice.c
+++ b/softmmu/bootdevice.c
@@ -214,7 +214,7 @@ static char *get_boot_device_path(DeviceState *dev, bool 
ignore_suffixes,
 
 if (!ignore_suffixes) {
 if (dev) {
-d = qdev_get_own_fw_dev_path_from_handler(dev->parent_bus, dev);
+d = qdev_get_own_fw_dev_path_from_handler(dev);
 if (d) {
 assert(!suffix);
 s = d;
-- 
2.38.1




[PATCH v2 1/9] hw/qdev: Constify DeviceState* argument of qdev_get_parent_bus()

2023-02-12 Thread Philippe Mathieu-Daudé
The structure is accessed read-only by qdev_get_parent_bus().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/core/qdev.c | 2 +-
 include/hw/qdev-core.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index d759c4602c..43d863b0c5 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -330,7 +330,7 @@ bool qdev_machine_modified(void)
 return qdev_hot_added || qdev_hot_removed;
 }
 
-BusState *qdev_get_parent_bus(DeviceState *dev)
+BusState *qdev_get_parent_bus(const DeviceState *dev)
 {
 return dev->parent_bus;
 }
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 35fddb19a6..f5b3b2f89a 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -715,7 +715,7 @@ static inline void qdev_init_gpio_in_named(DeviceState *dev,
 void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
  const char *name);
 
-BusState *qdev_get_parent_bus(DeviceState *dev);
+BusState *qdev_get_parent_bus(const DeviceState *dev);
 
 /*** BUS API. ***/
 
-- 
2.38.1




[PATCH v2 9/9] qdev-monitor: Use qdev_get_parent_bus() in bus_print_dev()

2023-02-12 Thread Philippe Mathieu-Daudé
No need to pass 'dev' and 'dev->parent_bus' when we can
retrieve 'parent_bus' with qdev_get_parent_bus().

Signed-off-by: Philippe Mathieu-Daudé 
---
 softmmu/qdev-monitor.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 820e7f52ad..12e4899f0d 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -770,9 +770,9 @@ static void qdev_print_props(Monitor *mon, DeviceState 
*dev, Property *props,
 }
 }
 
-static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int 
indent)
+static void bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
 {
-BusClass *bc = BUS_GET_CLASS(bus);
+BusClass *bc = BUS_GET_CLASS(qdev_get_parent_bus(dev));
 
 if (bc->print_dev) {
 bc->print_dev(mon, dev, indent);
@@ -811,7 +811,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int 
indent)
 qdev_print_props(mon, dev, DEVICE_CLASS(class)->props_, indent);
 class = object_class_get_parent(class);
 } while (class != object_class_by_name(TYPE_DEVICE));
-bus_print_dev(dev->parent_bus, mon, dev, indent);
+bus_print_dev(mon, dev, indent);
 QLIST_FOREACH(child, >child_bus, sibling) {
 qbus_print(mon, child, indent);
 }
-- 
2.38.1




[PATCH v2 0/9] hw/qdev: Housekeeping around qdev_get_parent_bus()

2023-02-12 Thread Philippe Mathieu-Daudé
v2: Convert more qdev_get_parent_bus()

DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper. Replace most uses.

Philippe Mathieu-Daudé (9):
  hw/qdev: Constify DeviceState* argument of qdev_get_parent_bus()
  hw/audio: Replace dev->parent_bus by qdev_get_parent_bus(dev)
  hw/block: Replace dev->parent_bus by qdev_get_parent_bus(dev)
  hw/net: Replace dev->parent_bus by qdev_get_parent_bus(dev)
  hw/pci: Replace dev->parent_bus by qdev_get_parent_bus(dev)
  hw/ppc: Replace dev->parent_bus by qdev_get_parent_bus(dev)
  hw/usb: Replace dev->parent_bus by qdev_get_parent_bus(dev)
  hw: Use qdev_get_parent_bus() in
qdev_get_own_fw_dev_path_from_handler()
  qdev-monitor: Use qdev_get_parent_bus() in bus_print_dev()

 hw/audio/intel-hda.c| 10 +-
 hw/block/fdc.c  |  2 +-
 hw/block/swim.c |  2 +-
 hw/core/qdev-fw.c   |  9 +
 hw/core/qdev.c  |  2 +-
 hw/ide/qdev.c   |  6 +++---
 hw/net/virtio-net.c |  2 +-
 hw/pci-bridge/pci_expander_bridge.c |  2 +-
 hw/ppc/spapr_vio.c  |  4 ++--
 hw/scsi/scsi-bus.c  | 18 +-
 hw/usb/bus.c|  2 +-
 hw/usb/desc.c   |  2 +-
 hw/usb/dev-smartcard-reader.c   | 16 
 include/hw/qdev-core.h  |  4 ++--
 include/hw/scsi/scsi.h  |  2 +-
 include/hw/usb.h|  2 +-
 softmmu/bootdevice.c|  2 +-
 softmmu/qdev-monitor.c  |  6 +++---
 18 files changed, 47 insertions(+), 46 deletions(-)

-- 
2.38.1




[PATCH v2 6/9] hw/ppc: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Philippe Mathieu-Daudé
DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ppc/spapr_vio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 9d4fec2c04..dfc5c436bd 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -382,7 +382,7 @@ static void rtas_quiesce(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 
 static SpaprVioDevice *reg_conflict(SpaprVioDevice *dev)
 {
-SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
+SpaprVioBus *bus = SPAPR_VIO_BUS(qdev_get_parent_bus(DEVICE(dev)));
 BusChild *kid;
 SpaprVioDevice *other;
 
@@ -492,7 +492,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, 
Error **errp)
 }
 } else {
 /* Need to assign an address */
-SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
+SpaprVioBus *bus = SPAPR_VIO_BUS(qdev_get_parent_bus(DEVICE(dev)));
 
 do {
 dev->reg = bus->next_reg++;
-- 
2.38.1




[PATCH v2 5/9] hw/pci: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Philippe Mathieu-Daudé
DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-bridge/pci_expander_bridge.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci-bridge/pci_expander_bridge.c 
b/hw/pci-bridge/pci_expander_bridge.c
index e752a21292..8c0649c071 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -151,7 +151,7 @@ static char *pxb_host_ofw_unit_address(const SysBusDevice 
*dev)
 assert(position >= 0);
 
 pxb_dev_base = DEVICE(pxb_dev);
-main_host = PCI_HOST_BRIDGE(pxb_dev_base->parent_bus->parent);
+main_host = PCI_HOST_BRIDGE(qdev_get_parent_bus(pxb_dev_base)->parent);
 main_host_sbd = SYS_BUS_DEVICE(main_host);
 
 if (main_host_sbd->num_mmio > 0) {
-- 
2.38.1




[PATCH v2 3/9] hw/block: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Philippe Mathieu-Daudé
DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/fdc.c |  2 +-
 hw/block/swim.c|  2 +-
 hw/ide/qdev.c  |  6 +++---
 hw/scsi/scsi-bus.c | 18 +-
 include/hw/scsi/scsi.h |  2 +-
 5 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 64ae4a6899..31ad6f6ae0 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -466,7 +466,7 @@ static Property floppy_drive_properties[] = {
 static void floppy_drive_realize(DeviceState *qdev, Error **errp)
 {
 FloppyDrive *dev = FLOPPY_DRIVE(qdev);
-FloppyBus *bus = FLOPPY_BUS(qdev->parent_bus);
+FloppyBus *bus = FLOPPY_BUS(qdev_get_parent_bus(qdev));
 FDrive *drive;
 bool read_only;
 int ret;
diff --git a/hw/block/swim.c b/hw/block/swim.c
index 333da08ce0..64e30e9e80 100644
--- a/hw/block/swim.c
+++ b/hw/block/swim.c
@@ -157,7 +157,7 @@ static Property swim_drive_properties[] = {
 static void swim_drive_realize(DeviceState *qdev, Error **errp)
 {
 SWIMDrive *dev = SWIM_DRIVE(qdev);
-SWIMBus *bus = SWIM_BUS(qdev->parent_bus);
+SWIMBus *bus = SWIM_BUS(qdev_get_parent_bus(qdev));
 FDrive *drive;
 int ret;
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6f6c7462f3..6ae2627a56 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -81,7 +81,7 @@ static char *idebus_get_fw_dev_path(DeviceState *dev)
 char path[30];
 
 snprintf(path, sizeof(path), "%s@%x", qdev_fw_name(dev),
- ((IDEBus*)dev->parent_bus)->bus_id);
+ ((IDEBus*)qdev_get_parent_bus(dev))->bus_id);
 
 return g_strdup(path);
 }
@@ -90,7 +90,7 @@ static void ide_qdev_realize(DeviceState *qdev, Error **errp)
 {
 IDEDevice *dev = IDE_DEVICE(qdev);
 IDEDeviceClass *dc = IDE_DEVICE_GET_CLASS(dev);
-IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
+IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev_get_parent_bus(qdev));
 
 if (dev->unit == -1) {
 dev->unit = bus->master ? 1 : 0;
@@ -164,7 +164,7 @@ typedef struct IDEDrive {
 
 static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
 {
-IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
+IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev_get_parent_bus(DEVICE(dev)));
 IDEState *s = bus->ifs + dev->unit;
 int ret;
 
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index ceceafb2cd..7b2a82b335 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -104,7 +104,7 @@ static void scsi_device_unrealize(SCSIDevice *s)
 int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
size_t buf_len, void *hba_private)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(dev)));
 int rc;
 
 assert(cmd->len == 0);
@@ -250,7 +250,7 @@ static bool scsi_bus_check_address(BusState *qbus, 
DeviceState *qdev, Error **er
 static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
 {
 SCSIDevice *dev = SCSI_DEVICE(qdev);
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(dev)));
 bool is_free;
 Error *local_err = NULL;
 
@@ -705,7 +705,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, 
SCSIDevice *d,
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
   uint8_t *buf, size_t buf_len, void *hba_private)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
+SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(d)));
 const SCSIReqOps *ops;
 SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(d);
 SCSIRequest *req;
@@ -1353,7 +1353,7 @@ int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, 
uint8_t *buf,
 
 void scsi_device_report_change(SCSIDevice *dev, SCSISense sense)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qdev_get_parent_bus(DEVICE(dev)));
 
 scsi_device_set_ua(dev, sense);
 if (bus->info->change) {
@@ -1372,7 +1372,7 @@ void scsi_req_unref(SCSIRequest *req)
 {
 assert(req->refcount > 0);
 if (--req->refcount == 0) {
-BusState *qbus = req->dev->qdev.parent_bus;
+BusState *qbus = qdev_get_parent_bus(DEVICE(req->dev));
 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qbus);
 
 if (bus->info->free_request && req->hba_private) {
@@ -1444,7 +1444,7 @@ void scsi_req_print(SCSIRequest *req)
 int i;
 
 fprintf(fp, "[%s id=%d] %s",
-req->dev->qdev.parent_bus->name,
+qdev_get_parent_bus(DEVICE(req->dev))->name,
 req->dev->id,
 scsi_command_name(req->cmd.buf[0]));
 for (i = 1; i < req->cmd.len; i++) {
@@ -1671,7 +1671,7 @@ void scsi_device_purge_requests(SCSIDevice 

[PATCH v2 2/9] hw/audio: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Philippe Mathieu-Daudé
DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/audio/intel-hda.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index b9ed231fe8..ec38828da0 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -59,7 +59,7 @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, 
size_t bus_size,
 
 static void hda_codec_dev_realize(DeviceState *qdev, Error **errp)
 {
-HDACodecBus *bus = HDA_BUS(qdev->parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(qdev));
 HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev);
 HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev);
 
@@ -103,14 +103,14 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t 
cad)
 
 void hda_codec_response(HDACodecDevice *dev, bool solicited, uint32_t response)
 {
-HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(DEVICE(dev)));
 bus->response(dev, solicited, response);
 }
 
 bool hda_codec_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
 uint8_t *buf, uint32_t len)
 {
-HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(DEVICE(dev)));
 return bus->xfer(dev, stnr, output, buf, len);
 }
 
@@ -344,7 +344,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
 static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t 
response)
 {
 const MemTxAttrs attrs = { .memory = true };
-HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(DEVICE(dev)));
 IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
 hwaddr addr;
 uint32_t wp, ex;
@@ -399,7 +399,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t 
stnr, bool output,
uint8_t *buf, uint32_t len)
 {
 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
-HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(DEVICE(dev)));
 IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
 hwaddr addr;
 uint32_t s, copy, left;
-- 
2.38.1




Re: [PATCH 2/4] hw: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Philippe Mathieu-Daudé

On 12/2/23 23:47, Philippe Mathieu-Daudé wrote:

DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper. Replace all
uses in hw/ except the QDev uses in hw/core/.

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/audio/intel-hda.c|  2 +-
  hw/block/fdc.c  |  2 +-
  hw/block/swim.c |  2 +-
  hw/ide/qdev.c   |  4 ++--
  hw/net/virtio-net.c |  2 +-
  hw/pci-bridge/pci_expander_bridge.c |  2 +-
  hw/scsi/scsi-bus.c  |  2 +-
  hw/usb/bus.c|  2 +-
  hw/usb/desc.c   |  2 +-
  hw/usb/dev-smartcard-reader.c   | 16 
  10 files changed, 18 insertions(+), 18 deletions(-)


I missed:

-- >8 --
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 6bc239a981..ec38828da0 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -103,14 +103,14 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, 
uint32_t cad)


 void hda_codec_response(HDACodecDevice *dev, bool solicited, uint32_t 
response)

 {
-HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(DEVICE(dev)));
 bus->response(dev, solicited, response);
 }

 bool hda_codec_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
 uint8_t *buf, uint32_t len)
 {
-HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(DEVICE(dev)));
 return bus->xfer(dev, stnr, output, buf, len);
 }

@@ -344,7 +344,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
 static void intel_hda_response(HDACodecDevice *dev, bool solicited, 
uint32_t response)

 {
 const MemTxAttrs attrs = { .memory = true };
-HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(DEVICE(dev)));
 IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
 hwaddr addr;
 uint32_t wp, ex;
@@ -399,7 +399,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, 
uint32_t stnr, bool output,

uint8_t *buf, uint32_t len)
 {
 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
-HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(DEVICE(dev)));
 IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
 hwaddr addr;
 uint32_t s, copy, left;
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 96582ce49b..6ae2627a56 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -164,7 +164,7 @@ typedef struct IDEDrive {

 static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error 
**errp)

 {
-IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
+IDEBus *bus = DO_UPCAST(IDEBus, qbus, 
qdev_get_parent_bus(DEVICE(dev)));

 IDEState *s = bus->ifs + dev->unit;
 int ret;

diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 9d4fec2c04..dfc5c436bd 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -382,7 +382,7 @@ static void rtas_quiesce(PowerPCCPU *cpu, 
SpaprMachineState *spapr,


 static SpaprVioDevice *reg_conflict(SpaprVioDevice *dev)
 {
-SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
+SpaprVioBus *bus = SPAPR_VIO_BUS(qdev_get_parent_bus(DEVICE(dev)));
 BusChild *kid;
 SpaprVioDevice *other;

@@ -492,7 +492,7 @@ static void spapr_vio_busdev_realize(DeviceState 
*qdev, Error **errp)

 }
 } else {
 /* Need to assign an address */
-SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
+SpaprVioBus *bus = SPAPR_VIO_BUS(qdev_get_parent_bus(DEVICE(dev)));

 do {
 dev->reg = bus->next_reg++;
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 3127cd7273..7b2a82b335 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -104,7 +104,7 @@ static void scsi_device_unrealize(SCSIDevice *s)
 int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
size_t buf_len, void *hba_private)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, 
qdev_get_parent_bus(DEVICE(dev)));

 int rc;

 assert(cmd->len == 0);
@@ -250,7 +250,7 @@ static bool scsi_bus_check_address(BusState *qbus, 
DeviceState *qdev, Error **er

 static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
 {
 SCSIDevice *dev = SCSI_DEVICE(qdev);
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, 
qdev_get_parent_bus(DEVICE(dev)));

 bool is_free;
 Error *local_err = NULL;

@@ -705,7 +705,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps 
*reqops, SCSIDevice *d,

 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
   uint8_t *buf, size_t buf_len, void *hba_private)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, 

[PATCH 09/19] hw/net/eepro100: Replace DO_UPCAST(EEPRO100State) by EEPRO100()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the EEPRO100() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/eepro100.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index dac42ba17b..915935a818 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -1828,7 +1828,7 @@ static const VMStateDescription vmstate_eepro100 = {
 
 static void pci_nic_uninit(PCIDevice *pci_dev)
 {
-EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
+EEPRO100State *s = EEPRO100(pci_dev);
 
 vmstate_unregister(VMSTATE_IF(_dev->qdev), s->vmstate, s);
 g_free(s->vmstate);
@@ -1844,7 +1844,7 @@ static NetClientInfo net_eepro100_info = {
 
 static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
 {
-EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
+EEPRO100State *s = EEPRO100(pci_dev);
 E100PCIDeviceInfo *info = eepro100_get_class(s);
 Error *local_err = NULL;
 
@@ -1895,7 +1895,7 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error 
**errp)
 
 static void eepro100_instance_init(Object *obj)
 {
-EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, PCI_DEVICE(obj));
+EEPRO100State *s = EEPRO100(obj);
 device_add_bootindex_property(obj, >conf.bootindex,
   "bootindex", "/ethernet-phy@0",
   DEVICE(s));
-- 
2.38.1




[PATCH 14/19] hw/scsi/scsi-bus: Inline two uses of scsi_bus_from_device()

2023-02-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/s390x/ipl.c | 7 ++-
 hw/scsi/scsi-bus.c | 2 +-
 include/hw/scsi/scsi.h | 5 -
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 8612684d48..4f7f4e60d6 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -366,11 +366,8 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, 
int *devtype)
 ccw_dev = CCW_DEVICE(vfio_ccw_dev);
 tmp_dt = CCW_DEVTYPE_VFIO;
 } else {
-SCSIDevice *sd = (SCSIDevice *)
-object_dynamic_cast(OBJECT(dev_st),
-TYPE_SCSI_DEVICE);
-if (sd) {
-SCSIBus *sbus = scsi_bus_from_device(sd);
+if (object_dynamic_cast(OBJECT(dev_st), TYPE_SCSI_DEVICE)) {
+SCSIBus *sbus = SCSI_BUS(qdev_get_parent_bus(dev_st));
 VirtIODevice *vdev = (VirtIODevice *)
 object_dynamic_cast(OBJECT(sbus->qbus.parent),
 TYPE_VIRTIO_DEVICE);
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 29b65a9b54..802bed2abc 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -679,7 +679,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, 
SCSIDevice *d,
 uint32_t tag, uint32_t lun, void *hba_private)
 {
 SCSIRequest *req;
-SCSIBus *bus = scsi_bus_from_device(d);
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(d)));
 BusState *qbus = BUS(bus);
 const int memset_off = offsetof(SCSIRequest, sense)
+ sizeof(req->sense);
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index eb558c145a..e3263dec0d 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -175,11 +175,6 @@ static inline void scsi_bus_init(SCSIBus *bus, size_t 
bus_size,
 scsi_bus_init_named(bus, bus_size, host, info, NULL);
 }
 
-static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
-{
-return SCSI_BUS(qdev_get_parent_bus(DEVICE(d)));
-}
-
 SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
   int unit, bool removable, int bootindex,
   bool share_rw,
-- 
2.38.1




[PATCH 13/19] hw/scsi/scsi-bus: Replace DO_UPCAST(SCSIBus) by SCSI_BUS()

2023-02-12 Thread Philippe Mathieu-Daudé
Replace accesses to qdev->parent_bus by qdev_get_parent_bus(qdev).
Use the SCSI_BUS() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/scsi/scsi-bus.c | 12 ++--
 include/hw/scsi/scsi.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 3127cd7273..29b65a9b54 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -104,7 +104,7 @@ static void scsi_device_unrealize(SCSIDevice *s)
 int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
size_t buf_len, void *hba_private)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(dev)));
 int rc;
 
 assert(cmd->len == 0);
@@ -250,7 +250,7 @@ static bool scsi_bus_check_address(BusState *qbus, 
DeviceState *qdev, Error **er
 static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
 {
 SCSIDevice *dev = SCSI_DEVICE(qdev);
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(qdev));
 bool is_free;
 Error *local_err = NULL;
 
@@ -705,7 +705,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, 
SCSIDevice *d,
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
   uint8_t *buf, size_t buf_len, void *hba_private)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(d)));
 const SCSIReqOps *ops;
 SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(d);
 SCSIRequest *req;
@@ -1353,7 +1353,7 @@ int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, 
uint8_t *buf,
 
 void scsi_device_report_change(SCSIDevice *dev, SCSISense sense)
 {
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(dev)));
 
 scsi_device_set_ua(dev, sense);
 if (bus->info->change) {
@@ -1698,7 +1698,7 @@ static int put_scsi_requests(QEMUFile *f, void *pv, 
size_t size,
  const VMStateField *field, JSONWriter *vmdesc)
 {
 SCSIDevice *s = pv;
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(s)));
 SCSIRequest *req;
 
 QTAILQ_FOREACH(req, >requests, next) {
@@ -1726,7 +1726,7 @@ static int get_scsi_requests(QEMUFile *f, void *pv, 
size_t size,
  const VMStateField *field)
 {
 SCSIDevice *s = pv;
-SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
+SCSIBus *bus = SCSI_BUS(qdev_get_parent_bus(DEVICE(s)));
 int8_t sbyte;
 
 while ((sbyte = qemu_get_sbyte(f)) > 0) {
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 6ea4b64fe7..eb558c145a 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -177,7 +177,7 @@ static inline void scsi_bus_init(SCSIBus *bus, size_t 
bus_size,
 
 static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
 {
-return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
+return SCSI_BUS(qdev_get_parent_bus(DEVICE(d)));
 }
 
 SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
-- 
2.38.1




[PATCH 15/19] hw/s390x/event-facility: Replace DO_UPCAST(SCLPEvent) by SCLP_EVENT()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the SCLP_EVENT() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/s390x/event-facility.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index faa51aa4c7..6891e3cd73 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -64,8 +64,7 @@ static bool event_pending(SCLPEventFacility *ef)
 SCLPEventClass *event_class;
 
 QTAILQ_FOREACH(kid, >sbus.qbus.children, sibling) {
-DeviceState *qdev = kid->child;
-event = DO_UPCAST(SCLPEvent, qdev, qdev);
+event = SCLP_EVENT(kid->child);
 event_class = SCLP_EVENT_GET_CLASS(event);
 if (event->event_pending &&
 event_class->get_send_mask() & ef->receive_mask) {
-- 
2.38.1




[PATCH 18/19] hw/usb: Replace DO_UPCAST(USBBus) by USB_BUS()

2023-02-12 Thread Philippe Mathieu-Daudé
Replace accesses to qdev->parent_bus by qdev_get_parent_bus(qdev).
Use the USB_BUS() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/usb.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/usb.h b/include/hw/usb.h
index 32c23a5ca2..f743a5e945 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -520,7 +520,7 @@ void usb_check_attach(USBDevice *dev, Error **errp);
 
 static inline USBBus *usb_bus_from_device(USBDevice *d)
 {
-return DO_UPCAST(USBBus, qbus, d->qdev.parent_bus);
+return USB_BUS(qdev_get_parent_bus(DEVICE(d)));
 }
 
 extern const VMStateDescription vmstate_usb_device;
-- 
2.38.1




[RFC PATCH 19/19] hw/usb: Inline usb_bus_from_device()

2023-02-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
RFC Other devices don't use such helper. Maybe it should
be the other way around, introduce more bus_from_device()
helpers?
---
 hw/usb/bus.c| 10 +-
 hw/usb/core.c   |  6 +++---
 hw/usb/dev-hub.c|  4 ++--
 hw/usb/dev-serial.c | 10 +-
 hw/usb/hcd-xhci.c   |  2 +-
 include/hw/usb.h|  5 -
 6 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index d7c3c71435..4a1b67761c 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -427,7 +427,7 @@ void usb_unregister_port(USBBus *bus, USBPort *port)
 
 void usb_claim_port(USBDevice *dev, Error **errp)
 {
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 USBPort *port;
 USBDevice *hub;
 
@@ -473,7 +473,7 @@ void usb_claim_port(USBDevice *dev, Error **errp)
 
 void usb_release_port(USBDevice *dev)
 {
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 USBPort *port = dev->port;
 
 assert(port != NULL);
@@ -517,7 +517,7 @@ static void usb_mask_to_str(char *dest, size_t size,
 
 void usb_check_attach(USBDevice *dev, Error **errp)
 {
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 USBPort *port = dev->port;
 char devspeed[32], portspeed[32];
 
@@ -555,7 +555,7 @@ void usb_device_attach(USBDevice *dev, Error **errp)
 
 int usb_device_detach(USBDevice *dev)
 {
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 USBPort *port = dev->port;
 
 assert(port != NULL);
@@ -583,7 +583,7 @@ static const char *usb_speed(unsigned int speed)
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 {
 USBDevice *dev = USB_DEVICE(qdev);
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(qdev));
 
 monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
indent, "", bus->busnr, dev->addr,
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 975f76250a..f358f0313a 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -95,7 +95,7 @@ void usb_device_reset(USBDevice *dev)
 void usb_wakeup(USBEndpoint *ep, unsigned int stream)
 {
 USBDevice *dev = ep->dev;
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 
 if (!phase_check(PHASE_MACHINE_READY)) {
 /*
@@ -556,7 +556,7 @@ void usb_packet_check_state(USBPacket *p, USBPacketState 
expected)
 return;
 }
 dev = p->ep->dev;
-bus = usb_bus_from_device(dev);
+bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 trace_usb_packet_state_fault(bus->busnr, dev->port->path, p->ep->nr, p,
  usb_packet_state_name(p->state),
  usb_packet_state_name(expected));
@@ -567,7 +567,7 @@ void usb_packet_set_state(USBPacket *p, USBPacketState 
state)
 {
 if (p->ep) {
 USBDevice *dev = p->ep->dev;
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 trace_usb_packet_state_change(bus->busnr, dev->port->path, p->ep->nr, 
p,
   usb_packet_state_name(p->state),
   usb_packet_state_name(state));
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 4734700e3e..4a0bcc4093 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -572,7 +572,7 @@ static void usb_hub_unrealize(USBDevice *dev)
 int i;
 
 for (i = 0; i < s->num_ports; i++) {
-usb_unregister_port(usb_bus_from_device(dev),
+usb_unregister_port(USB_BUS(qdev_get_parent_bus(DEVICE(dev))),
 >ports[i].port);
 }
 
@@ -611,7 +611,7 @@ static void usb_hub_realize(USBDevice *dev, Error **errp)
 s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
 for (i = 0; i < s->num_ports; i++) {
 port = >ports[i];
-usb_register_port(usb_bus_from_device(dev),
+usb_register_port(USB_BUS(qdev_get_parent_bus(DEVICE(dev))),
   >port, s, i, _hub_port_ops,
   USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
 usb_port_location(>port, dev->port, i+1);
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 63047d79cf..0194bb541b 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -190,7 +190,7 @@ static void usb_serial_set_flow_control(USBSerialState *s,
 uint8_t flow_control)
 {
 USBDevice *dev = USB_DEVICE(s);
-USBBus *bus = usb_bus_from_device(dev);
+USBBus *bus = USB_BUS(qdev_get_parent_bus(DEVICE(dev)));
 
 /* TODO: ioctl */
 s->flow_control = flow_control;
@@ -200,7 +200,7 @@ static void usb_serial_set_flow_control(USBSerialState *s,
 static void 

[PATCH 11/19] hw/net/tulip: Finish QOM conversion

2023-02-12 Thread Philippe Mathieu-Daudé
Use the TULIP() and DEVICE() QOM type-checking macros.
Remove uses of DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/tulip.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index 915e5fb595..990507859d 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -19,7 +19,10 @@
 #include "net/eth.h"
 
 struct TULIPState {
+/*< private >*/
 PCIDevice dev;
+/*< public >*/
+
 MemoryRegion io;
 MemoryRegion memory;
 NICConf c;
@@ -959,7 +962,7 @@ static void tulip_fill_eeprom(TULIPState *s)
 
 static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp)
 {
-TULIPState *s = DO_UPCAST(TULIPState, dev, pci_dev);
+TULIPState *s = TULIP(pci_dev);
 uint8_t *pci_conf;
 
 pci_conf = s->dev.config;
@@ -967,7 +970,7 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error 
**errp)
 
 qemu_macaddr_default_if_unset(>c.macaddr);
 
-s->eeprom = eeprom93xx_new(_dev->qdev, 64);
+s->eeprom = eeprom93xx_new(DEVICE(pci_dev), 64);
 tulip_fill_eeprom(s);
 
 memory_region_init_io(>io, OBJECT(>dev), _ops, s,
@@ -983,27 +986,26 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error 
**errp)
 
 s->nic = qemu_new_nic(_tulip_info, >c,
   object_get_typename(OBJECT(pci_dev)),
-  pci_dev->qdev.id, s);
+  DEVICE(pci_dev)->id, s);
 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
 }
 
 static void pci_tulip_exit(PCIDevice *pci_dev)
 {
-TULIPState *s = DO_UPCAST(TULIPState, dev, pci_dev);
+TULIPState *s = TULIP(pci_dev);
 
 qemu_del_nic(s->nic);
 qemu_free_irq(s->irq);
-eeprom93xx_free(_dev->qdev, s->eeprom);
+eeprom93xx_free(DEVICE(s), s->eeprom);
 }
 
 static void tulip_instance_init(Object *obj)
 {
-PCIDevice *pci_dev = PCI_DEVICE(obj);
-TULIPState *d = DO_UPCAST(TULIPState, dev, pci_dev);
+TULIPState *s = TULIP(obj);
 
-device_add_bootindex_property(obj, >c.bootindex,
+device_add_bootindex_property(obj, >c.bootindex,
   "bootindex", "/ethernet-phy@0",
-  _dev->qdev);
+  DEVICE(obj));
 }
 
 static Property tulip_properties[] = {
-- 
2.38.1




[PATCH 17/19] hw/usb/dev-hub: Use QOM USB_HUB() macro instead of casting

2023-02-12 Thread Philippe Mathieu-Daudé
Use the safer USB_HUB() QOM type-checking macro instead of casts.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/usb/dev-hub.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index a6b50dbc8d..4734700e3e 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -350,7 +350,7 @@ static const char *feature_name(int feature)
 static void usb_hub_handle_control(USBDevice *dev, USBPacket *p,
int request, int value, int index, int length, uint8_t *data)
 {
-USBHubState *s = (USBHubState *)dev;
+USBHubState *s = USB_HUB(dev);
 int ret;
 
 trace_usb_hub_control(s->dev.addr, request, value, index, length);
@@ -523,7 +523,7 @@ static void usb_hub_handle_control(USBDevice *dev, 
USBPacket *p,
 
 static void usb_hub_handle_data(USBDevice *dev, USBPacket *p)
 {
-USBHubState *s = (USBHubState *)dev;
+USBHubState *s = USB_HUB(dev);
 
 switch(p->pid) {
 case USB_TOKEN_IN:
@@ -568,7 +568,7 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket 
*p)
 
 static void usb_hub_unrealize(USBDevice *dev)
 {
-USBHubState *s = (USBHubState *)dev;
+USBHubState *s = USB_HUB(dev);
 int i;
 
 for (i = 0; i < s->num_ports; i++) {
-- 
2.38.1




[PATCH 16/19] hw/vfio/ccw: Replace DO_UPCAST(VFIOCCWDevice) by VFIO_CCW()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the VFIO_CCW() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/vfio/ccw.c | 35 ---
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 0354737666..a8aa5b48c4 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -76,8 +76,7 @@ struct VFIODeviceOps vfio_ccw_ops = {
 
 static IOInstEnding vfio_ccw_handle_request(SubchDev *sch)
 {
-S390CCWDevice *cdev = sch->driver_data;
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
 struct ccw_io_region *region = vcdev->io_region;
 int ret;
 
@@ -125,8 +124,7 @@ again:
 
 static IOInstEnding vfio_ccw_handle_store(SubchDev *sch)
 {
-S390CCWDevice *cdev = sch->driver_data;
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
 SCHIB *schib = >curr_status;
 struct ccw_schib_region *region = vcdev->schib_region;
 SCHIB *s;
@@ -170,8 +168,7 @@ static IOInstEnding vfio_ccw_handle_store(SubchDev *sch)
 
 static int vfio_ccw_handle_clear(SubchDev *sch)
 {
-S390CCWDevice *cdev = sch->driver_data;
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
 struct ccw_cmd_region *region = vcdev->async_cmd_region;
 int ret;
 
@@ -210,8 +207,7 @@ again:
 
 static int vfio_ccw_handle_halt(SubchDev *sch)
 {
-S390CCWDevice *cdev = sch->driver_data;
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
 struct ccw_cmd_region *region = vcdev->async_cmd_region;
 int ret;
 
@@ -252,8 +248,8 @@ again:
 static void vfio_ccw_reset(DeviceState *dev)
 {
 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
-S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+S390CCWDevice *cdev = S390_CCW_DEVICE(ccw_dev);
+VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
 
 ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
 }
@@ -588,9 +584,10 @@ static void vfio_ccw_put_device(VFIOCCWDevice *vcdev)
 static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev,
 Error **errp)
 {
-char *name = g_strdup_printf("%x.%x.%04x", vcdev->cdev.hostid.cssid,
- vcdev->cdev.hostid.ssid,
- vcdev->cdev.hostid.devid);
+S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
+char *name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
+ cdev->hostid.ssid,
+ cdev->hostid.devid);
 VFIODevice *vbasedev;
 
 QLIST_FOREACH(vbasedev, >device_list, next) {
@@ -611,14 +608,14 @@ static void vfio_ccw_get_device(VFIOGroup *group, 
VFIOCCWDevice *vcdev,
  */
 vcdev->vdev.ram_block_discard_allowed = true;
 
-if (vfio_get_device(group, vcdev->cdev.mdevid, >vdev, errp)) {
+if (vfio_get_device(group, cdev->mdevid, >vdev, errp)) {
 goto out_err;
 }
 
 vcdev->vdev.ops = _ccw_ops;
 vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
 vcdev->vdev.name = name;
-vcdev->vdev.dev = >cdev.parent_obj.parent_obj;
+vcdev->vdev.dev = >parent_obj.parent_obj;
 
 return;
 
@@ -657,9 +654,9 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 {
 VFIOGroup *group;
 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
-S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+S390CCWDevice *cdev = S390_CCW_DEVICE(ccw_dev);
 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
 Error *err = NULL;
 
 /* Call the class init function for subchannel. */
@@ -729,9 +726,9 @@ out_err_propagate:
 static void vfio_ccw_unrealize(DeviceState *dev)
 {
 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
-S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
-VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+S390CCWDevice *cdev = S390_CCW_DEVICE(ccw_dev);
 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
 VFIOGroup *group = vcdev->vdev.group;
 
 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
-- 
2.38.1




[PATCH 12/19] hw/pci/pci: Replace DO_UPCAST(PCIBus) by PCI_BUS()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the PCI_BUS() QOM type-checking macro to avoid DO_UPCAST().

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

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 2e785e3aef..ae5c33adb6 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -391,7 +391,7 @@ void pci_device_reset(PCIDevice *dev)
  */
 static void pcibus_reset(BusState *qbus)
 {
-PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
+PCIBus *bus = PCI_BUS(qbus);
 int i;
 
 for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
-- 
2.38.1




[PATCH 05/19] hw/char/serial-pci-multi: Replace DO_UPCAST() by PCI_MULTISERIAL()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the PCI_MULTISERIAL() QOM type-checking macro to avoid the few
DO_UPCAST(PCIMultiSerialState) calls.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci-multi.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index cd5af24bd2..6f4491210d 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -58,7 +58,7 @@ struct PCIMultiSerialState {
 
 static void multi_serial_pci_exit(PCIDevice *dev)
 {
-PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
+PCIMultiSerialState *pci = PCI_MULTISERIAL(dev);
 SerialState *s;
 int i;
 
@@ -97,11 +97,10 @@ static size_t multi_serial_get_port_count(PCIDeviceClass 
*pc)
 g_assert_not_reached();
 }
 
-
 static void multi_serial_pci_realize(PCIDevice *dev, Error **errp)
 {
 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
-PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
+PCIMultiSerialState *pci = PCI_MULTISERIAL(dev);
 SerialState *s;
 size_t i, nports = multi_serial_get_port_count(pc);
 
@@ -190,9 +189,8 @@ static void multi_4x_serial_pci_class_initfn(ObjectClass 
*klass, void *data)
 
 static void multi_serial_init(Object *o)
 {
-PCIDevice *dev = PCI_DEVICE(o);
-PCIMultiSerialState *pms = DO_UPCAST(PCIMultiSerialState, dev, dev);
-size_t i, nports = multi_serial_get_port_count(PCI_DEVICE_GET_CLASS(dev));
+PCIMultiSerialState *pms = PCI_MULTISERIAL(o);
+size_t i, nports = multi_serial_get_port_count(PCI_DEVICE_GET_CLASS(o));
 
 for (i = 0; i < nports; i++) {
 object_initialize_child(o, "serial[*]", >state[i], TYPE_SERIAL);
-- 
2.38.1




[PATCH 07/19] hw/ide/qdev: Replace DO_UPCAST(IDEBus) by IDE_BUS()

2023-02-12 Thread Philippe Mathieu-Daudé
Replace accesses to qdev->parent_bus by qdev_get_parent_bus(qdev).
Use the IDE_BUS() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/qdev.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index c96a25e955..a168643266 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -90,7 +90,7 @@ static void ide_qdev_realize(DeviceState *qdev, Error **errp)
 {
 IDEDevice *dev = IDE_DEVICE(qdev);
 IDEDeviceClass *dc = IDE_DEVICE_GET_CLASS(dev);
-IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev_get_parent_bus(qdev));
+IDEBus *bus = IDE_BUS(qdev_get_parent_bus(qdev));
 
 if (dev->unit == -1) {
 dev->unit = bus->master ? 1 : 0;
@@ -139,7 +139,7 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, 
DriveInfo *drive)
 int ide_get_geometry(BusState *bus, int unit,
  int16_t *cyls, int8_t *heads, int8_t *secs)
 {
-IDEState *s = _UPCAST(IDEBus, qbus, bus)->ifs[unit];
+IDEState *s = _BUS(bus)->ifs[unit];
 
 if (s->drive_kind != IDE_HD || !s->blk) {
 return -1;
@@ -153,7 +153,7 @@ int ide_get_geometry(BusState *bus, int unit,
 
 int ide_get_bios_chs_trans(BusState *bus, int unit)
 {
-return DO_UPCAST(IDEBus, qbus, bus)->ifs[unit].chs_trans;
+return IDE_BUS(bus)->ifs[unit].chs_trans;
 }
 
 /* - */
@@ -164,7 +164,7 @@ typedef struct IDEDrive {
 
 static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
 {
-IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
+IDEBus *bus = IDE_BUS(qdev_get_parent_bus(DEVICE(dev)));
 IDEState *s = bus->ifs + dev->unit;
 int ret;
 
-- 
2.38.1




[PATCH 10/19] hw/net/ne2000-pci: Replace DO_UPCAST(PCINE2000State) by PCI_NE2000()

2023-02-12 Thread Philippe Mathieu-Daudé
Define TYPE_PCI_NE2000 and the QOM PCI_NE2000() macro.
Use PCI_NE2000() instead of DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/ne2000-pci.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c
index edc6689d33..0332e7f616 100644
--- a/hw/net/ne2000-pci.c
+++ b/hw/net/ne2000-pci.c
@@ -30,10 +30,16 @@
 #include "ne2000.h"
 #include "sysemu/sysemu.h"
 
-typedef struct PCINE2000State {
+#define TYPE_PCI_NE2000 "ne2k_pci"
+OBJECT_DECLARE_SIMPLE_TYPE(PCINE2000State, PCI_NE2000)
+
+struct PCINE2000State {
+/*< private >*/
 PCIDevice dev;
+/*< public >*/
+
 NE2000State ne2000;
-} PCINE2000State;
+};
 
 static const VMStateDescription vmstate_pci_ne2000 = {
 .name = "ne2000",
@@ -54,7 +60,7 @@ static NetClientInfo net_ne2000_info = {
 
 static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp)
 {
-PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+PCINE2000State *d = PCI_NE2000(pci_dev);
 NE2000State *s;
 uint8_t *pci_conf;
 
@@ -77,7 +83,7 @@ static void pci_ne2000_realize(PCIDevice *pci_dev, Error 
**errp)
 
 static void pci_ne2000_exit(PCIDevice *pci_dev)
 {
-PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+PCINE2000State *d = PCI_NE2000(pci_dev);
 NE2000State *s = >ne2000;
 
 qemu_del_nic(s->nic);
@@ -87,7 +93,7 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
 static void ne2000_instance_init(Object *obj)
 {
 PCIDevice *pci_dev = PCI_DEVICE(obj);
-PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+PCINE2000State *d = PCI_NE2000(pci_dev);
 NE2000State *s = >ne2000;
 
 device_add_bootindex_property(obj, >c.bootindex,
@@ -117,7 +123,7 @@ static void ne2000_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo ne2000_info = {
-.name  = "ne2k_pci",
+.name  = TYPE_PCI_NE2000,
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(PCINE2000State),
 .class_init= ne2000_class_init,
-- 
2.38.1




[PATCH 03/19] hw/char/serial-pci-multi: Introduce PCI_MULTISERIAL QOM abstract parent

2023-02-12 Thread Philippe Mathieu-Daudé
Introduce PCI_MULTISERIAL ("pci-serial"), QOM abstract parent of
"pci-serial-2x" and "pci-serial-4x".

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci-multi.c | 35 ---
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index 54768d3d53..faeb0a9476 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -38,8 +38,15 @@
 
 #define PCI_SERIAL_MAX_PORTS 4
 
-typedef struct PCIMultiSerialState {
+#define TYPE_PCI_MULTISERIAL  "pci-serial"
+
+OBJECT_DECLARE_SIMPLE_TYPE(PCIMultiSerialState, PCI_MULTISERIAL)
+
+struct PCIMultiSerialState {
+/*< private >*/
 PCIDevicedev;
+/*< public >*/
+
 MemoryRegion iobar;
 uint32_t ports;
 char *name[PCI_SERIAL_MAX_PORTS];
@@ -47,7 +54,7 @@ typedef struct PCIMultiSerialState {
 uint32_t level[PCI_SERIAL_MAX_PORTS];
 qemu_irq *irqs;
 uint8_t  prog_if;
-} PCIMultiSerialState;
+};
 
 static void multi_serial_pci_exit(PCIDevice *dev)
 {
@@ -191,25 +198,23 @@ static void multi_serial_init(Object *o)
 
 static const TypeInfo multi_serial_pci_types[] = {
 {
-.name  = "pci-serial-2x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
-.class_init= multi_2x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
+.name   = TYPE_PCI_MULTISERIAL,
+.parent = TYPE_PCI_DEVICE,
+.instance_size  = sizeof(PCIMultiSerialState),
+.instance_init  = multi_serial_init,
+.abstract   = true,
+.interfaces = (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
 { },
 },
+}, {
+.name  = "pci-serial-2x",
+.parent= TYPE_PCI_MULTISERIAL,
+.class_init= multi_2x_serial_pci_class_initfn,
 }, {
 .name  = "pci-serial-4x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
+.parent= TYPE_PCI_MULTISERIAL,
 .class_init= multi_4x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
 }
 };
 
-- 
2.38.1




[PATCH 06/19] hw/ide/qdev: Replace DO_UPCAST(IDEDevice) by IDE_DEVICE()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the IDE_DEVICE() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/qdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 96582ce49b..c96a25e955 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -133,7 +133,7 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, 
DriveInfo *drive)
 qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(drive),
 _fatal);
 qdev_realize_and_unref(dev, >qbus, _fatal);
-return DO_UPCAST(IDEDevice, qdev, dev);
+return IDE_DEVICE(dev);
 }
 
 int ide_get_geometry(BusState *bus, int unit,
-- 
2.38.1




[PATCH 08/19] hw/net/eepro100: Introduce TYPE_EEPRO100 QOM abstract parent

2023-02-12 Thread Philippe Mathieu-Daudé
Have all the EEPRO100-based devices share a common (abstract)
QOM parent.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/eepro100.c | 40 ++--
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index dc07984ae9..dac42ba17b 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -235,8 +235,14 @@ typedef enum {
 ru_ready = 4
 } ru_state_t;
 
-typedef struct {
+#define TYPE_EEPRO100 "eepro100"
+OBJECT_DECLARE_SIMPLE_TYPE(EEPRO100State, EEPRO100)
+
+struct EEPRO100State {
+/*< private >*/
 PCIDevice dev;
+/*< public >*/
+
 /* Hash register (multicast mask array, multiple individual addresses). */
 uint8_t mult[8];
 MemoryRegion mmio_bar;
@@ -279,7 +285,7 @@ typedef struct {
 /* Quasi static device properties (no need to save them). */
 uint16_t stats_size;
 bool has_extended_tcb_support;
-} EEPRO100State;
+};
 
 /* Word indices in EEPROM. */
 typedef enum {
@@ -2082,21 +2088,27 @@ static void eepro100_class_init(ObjectClass *klass, 
void *data)
 k->subsystem_id = info->subsystem_id;
 }
 
+static const TypeInfo eepro100_info = {
+.name  = TYPE_EEPRO100,
+.parent= TYPE_PCI_DEVICE,
+.class_init= eepro100_class_init,
+.abstract  = true,
+.instance_size = sizeof(EEPRO100State),
+.instance_init = eepro100_instance_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+};
+
 static void eepro100_register_types(void)
 {
-size_t i;
-for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
-TypeInfo type_info = {};
-E100PCIDeviceInfo *info = _devices[i];
+type_register_static(_info);
 
-type_info.name = info->name;
-type_info.parent = TYPE_PCI_DEVICE;
-type_info.class_init = eepro100_class_init;
-type_info.instance_size = sizeof(EEPRO100State);
-type_info.instance_init = eepro100_instance_init;
-type_info.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
+for (size_t i = 0; i < ARRAY_SIZE(e100_devices); i++) {
+TypeInfo type_info = {
+.name   = e100_devices[i].name,
+.parent = TYPE_EEPRO100,
 };
 
 type_register(_info);
-- 
2.38.1




[PATCH 04/19] hw/char/serial-pci-multi: Factor multi_serial_class_initfn() out

2023-02-12 Thread Philippe Mathieu-Daudé
Extract code common to multi_2x_serial_pci_class_initfn() and
multi_4x_serial_pci_class_initfn() to multi_serial_class_initfn().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci-multi.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index faeb0a9476..cd5af24bd2 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -155,14 +155,14 @@ static Property multi_4x_serial_pci_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
-static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
+static void multi_serial_class_initfn(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
+
 pc->realize = multi_serial_pci_realize;
 pc->exit = multi_serial_pci_exit;
 pc->vendor_id = PCI_VENDOR_ID_REDHAT;
-pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL2;
 pc->revision = 1;
 pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
 dc->vmsd = _pci_multi_serial;
@@ -170,19 +170,22 @@ static void multi_2x_serial_pci_class_initfn(ObjectClass 
*klass, void *data)
 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
 
+static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
+
+pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL2;
+device_class_set_props(dc, multi_2x_serial_pci_properties);
+}
+
 static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
-pc->realize = multi_serial_pci_realize;
-pc->exit = multi_serial_pci_exit;
-pc->vendor_id = PCI_VENDOR_ID_REDHAT;
+
 pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL4;
-pc->revision = 1;
-pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
-dc->vmsd = _pci_multi_serial;
 device_class_set_props(dc, multi_4x_serial_pci_properties);
-set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
 
 static void multi_serial_init(Object *o)
@@ -202,6 +205,7 @@ static const TypeInfo multi_serial_pci_types[] = {
 .parent = TYPE_PCI_DEVICE,
 .instance_size  = sizeof(PCIMultiSerialState),
 .instance_init  = multi_serial_init,
+.class_init = multi_serial_class_initfn,
 .abstract   = true,
 .interfaces = (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
-- 
2.38.1




[PATCH 02/19] hw/char/serial-pci-multi: Batch register types using DEFINE_TYPES macro

2023-02-12 Thread Philippe Mathieu-Daudé
See rationale in commit 38b5d79b2e ("qom: add helper
macro DEFINE_TYPES()").

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci-multi.c | 52 +-
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index f18b8dcce5..54768d3d53 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -189,34 +189,28 @@ static void multi_serial_init(Object *o)
 }
 }
 
-static const TypeInfo multi_2x_serial_pci_info = {
-.name  = "pci-serial-2x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
-.class_init= multi_2x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
+static const TypeInfo multi_serial_pci_types[] = {
+{
+.name  = "pci-serial-2x",
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(PCIMultiSerialState),
+.instance_init = multi_serial_init,
+.class_init= multi_2x_serial_pci_class_initfn,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+}, {
+.name  = "pci-serial-4x",
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(PCIMultiSerialState),
+.instance_init = multi_serial_init,
+.class_init= multi_4x_serial_pci_class_initfn,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+}
 };
 
-static const TypeInfo multi_4x_serial_pci_info = {
-.name  = "pci-serial-4x",
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PCIMultiSerialState),
-.instance_init = multi_serial_init,
-.class_init= multi_4x_serial_pci_class_initfn,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
-};
-
-static void multi_serial_pci_register_types(void)
-{
-type_register_static(_2x_serial_pci_info);
-type_register_static(_4x_serial_pci_info);
-}
-
-type_init(multi_serial_pci_register_types)
+DEFINE_TYPES(multi_serial_pci_types)
-- 
2.38.1




[PATCH 00/19] hw: Use QOM macros and remove DO_UPCAST() uses

2023-02-12 Thread Philippe Mathieu-Daudé
QOM housekeeping series which replace the DO_UPCAST() macro
uses by equivalent QOM ones. Also:
- Use DEVICE() macro
- Define some TYPE_xxx
- Define some type arrays using DEFINE_TYPES() macro
- Introduce abstract QOM (QDev) parent when relevant.

Based-on: <20230212224730.51438-1-phi...@linaro.org>
  hw/qdev: Housekeeping around qdev_get_parent_bus()

Philippe Mathieu-Daudé (19):
  hw/char/serial-pci: Replace DO_UPCAST(PCISerialState) by PCI_SERIAL()
  hw/char/serial-pci-multi: Batch register types using DEFINE_TYPES
macro
  hw/char/serial-pci-multi: Introduce PCI_MULTISERIAL QOM abstract
parent
  hw/char/serial-pci-multi: Factor multi_serial_class_initfn() out
  hw/char/serial-pci-multi: Replace DO_UPCAST() by PCI_MULTISERIAL()
  hw/ide/qdev: Replace DO_UPCAST(IDEDevice) by IDE_DEVICE()
  hw/ide/qdev: Replace DO_UPCAST(IDEBus) by IDE_BUS()
  hw/net/eepro100: Introduce TYPE_EEPRO100 QOM abstract parent
  hw/net/eepro100: Replace DO_UPCAST(EEPRO100State) by EEPRO100()
  hw/net/ne2000-pci: Replace DO_UPCAST(PCINE2000State) by PCI_NE2000()
  hw/net/tulip: Finish QOM conversion
  hw/pci/pci: Replace DO_UPCAST(PCIBus) by PCI_BUS()
  hw/scsi/scsi-bus: Replace DO_UPCAST(SCSIBus) by SCSI_BUS()
  hw/scsi/scsi-bus: Inline two uses of scsi_bus_from_device()
  hw/s390x/event-facility: Replace DO_UPCAST(SCLPEvent) by SCLP_EVENT()
  hw/vfio/ccw: Replace DO_UPCAST(VFIOCCWDevice) by VFIO_CCW()
  hw/usb/dev-hub: Use QOM USB_HUB() macro instead of casting
  hw/usb: Replace DO_UPCAST(USBBus) by USB_BUS()
  hw/usb: Inline usb_bus_from_device()

 hw/char/serial-pci-multi.c | 93 +++---
 hw/char/serial-pci.c   |  7 ++-
 hw/ide/qdev.c  | 10 ++--
 hw/net/eepro100.c  | 46 ---
 hw/net/ne2000-pci.c| 18 +---
 hw/net/tulip.c | 20 
 hw/pci/pci.c   |  2 +-
 hw/s390x/event-facility.c  |  3 +-
 hw/s390x/ipl.c |  7 +--
 hw/scsi/scsi-bus.c | 14 +++---
 hw/usb/bus.c   | 10 ++--
 hw/usb/core.c  |  6 +--
 hw/usb/dev-hub.c   | 10 ++--
 hw/usb/dev-serial.c| 10 ++--
 hw/usb/hcd-xhci.c  |  2 +-
 hw/vfio/ccw.c  | 35 +++---
 include/hw/scsi/scsi.h |  5 --
 include/hw/usb.h   |  5 --
 18 files changed, 155 insertions(+), 148 deletions(-)

-- 
2.38.1




[PATCH 01/19] hw/char/serial-pci: Replace DO_UPCAST(PCISerialState) by PCI_SERIAL()

2023-02-12 Thread Philippe Mathieu-Daudé
Use the PCI_SERIAL() QOM type-checking macro to avoid DO_UPCAST().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-pci.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index 801b769aba..9689645cac 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -36,7 +36,10 @@
 #include "qom/object.h"
 
 struct PCISerialState {
+/*< private >*/
 PCIDevice dev;
+/*< public >*/
+
 SerialState state;
 uint8_t prog_if;
 };
@@ -46,7 +49,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCISerialState, PCI_SERIAL)
 
 static void serial_pci_realize(PCIDevice *dev, Error **errp)
 {
-PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
+PCISerialState *pci = PCI_SERIAL(dev);
 SerialState *s = >state;
 
 if (!qdev_realize(DEVICE(s), NULL, errp)) {
@@ -63,7 +66,7 @@ static void serial_pci_realize(PCIDevice *dev, Error **errp)
 
 static void serial_pci_exit(PCIDevice *dev)
 {
-PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
+PCISerialState *pci = PCI_SERIAL(dev);
 SerialState *s = >state;
 
 qdev_unrealize(DEVICE(s));
-- 
2.38.1




[PATCH 1/4] hw/qdev: Constify DeviceState* argument of qdev_get_parent_bus()

2023-02-12 Thread Philippe Mathieu-Daudé
The structure is accessed read-only by qdev_get_parent_bus().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/core/qdev.c | 2 +-
 include/hw/qdev-core.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index d759c4602c..43d863b0c5 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -330,7 +330,7 @@ bool qdev_machine_modified(void)
 return qdev_hot_added || qdev_hot_removed;
 }
 
-BusState *qdev_get_parent_bus(DeviceState *dev)
+BusState *qdev_get_parent_bus(const DeviceState *dev)
 {
 return dev->parent_bus;
 }
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 35fddb19a6..f5b3b2f89a 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -715,7 +715,7 @@ static inline void qdev_init_gpio_in_named(DeviceState *dev,
 void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
  const char *name);
 
-BusState *qdev_get_parent_bus(DeviceState *dev);
+BusState *qdev_get_parent_bus(const DeviceState *dev);
 
 /*** BUS API. ***/
 
-- 
2.38.1




[PATCH 4/4] qdev-monitor: Use qdev_get_parent_bus() in bus_print_dev()

2023-02-12 Thread Philippe Mathieu-Daudé
No need to pass 'dev' and 'dev->parent_bus' when we can
retrieve 'parent_bus' with qdev_get_parent_bus().

Signed-off-by: Philippe Mathieu-Daudé 
---
 softmmu/qdev-monitor.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 820e7f52ad..12e4899f0d 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -770,9 +770,9 @@ static void qdev_print_props(Monitor *mon, DeviceState 
*dev, Property *props,
 }
 }
 
-static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int 
indent)
+static void bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
 {
-BusClass *bc = BUS_GET_CLASS(bus);
+BusClass *bc = BUS_GET_CLASS(qdev_get_parent_bus(dev));
 
 if (bc->print_dev) {
 bc->print_dev(mon, dev, indent);
@@ -811,7 +811,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int 
indent)
 qdev_print_props(mon, dev, DEVICE_CLASS(class)->props_, indent);
 class = object_class_get_parent(class);
 } while (class != object_class_by_name(TYPE_DEVICE));
-bus_print_dev(dev->parent_bus, mon, dev, indent);
+bus_print_dev(mon, dev, indent);
 QLIST_FOREACH(child, >child_bus, sibling) {
 qbus_print(mon, child, indent);
 }
-- 
2.38.1




[PATCH 3/4] hw: Use qdev_get_parent_bus() in qdev_get_own_fw_dev_path_from_handler()

2023-02-12 Thread Philippe Mathieu-Daudé
No need to pass 'dev' and 'dev->parent_bus' when we can
retrieve 'parent_bus' with qdev_get_parent_bus().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/core/qdev-fw.c  | 9 +
 include/hw/qdev-core.h | 2 +-
 softmmu/bootdevice.c   | 2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/core/qdev-fw.c b/hw/core/qdev-fw.c
index a31958355f..c2df1f4796 100644
--- a/hw/core/qdev-fw.c
+++ b/hw/core/qdev-fw.c
@@ -41,9 +41,10 @@ static char *bus_get_fw_dev_path(BusState *bus, DeviceState 
*dev)
 return NULL;
 }
 
-static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
+static char *qdev_get_fw_dev_path_from_handler(DeviceState *dev)
 {
 Object *obj = OBJECT(dev);
+BusState *bus = qdev_get_parent_bus(dev);
 char *d = NULL;
 
 while (!d && obj->parent) {
@@ -53,11 +54,11 @@ static char *qdev_get_fw_dev_path_from_handler(BusState 
*bus, DeviceState *dev)
 return d;
 }
 
-char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
+char *qdev_get_own_fw_dev_path_from_handler(DeviceState *dev)
 {
 Object *obj = OBJECT(dev);
 
-return fw_path_provider_try_get_dev_path(obj, bus, dev);
+return fw_path_provider_try_get_dev_path(obj, qdev_get_parent_bus(dev), 
dev);
 }
 
 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
@@ -67,7 +68,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char 
*p, int size)
 if (dev && dev->parent_bus) {
 char *d;
 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
-d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
+d = qdev_get_fw_dev_path_from_handler(dev);
 if (!d) {
 d = bus_get_fw_dev_path(dev->parent_bus, dev);
 }
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index f5b3b2f89a..93718be156 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -774,7 +774,7 @@ bool bus_is_in_reset(BusState *bus);
 BusState *sysbus_get_default(void);
 
 char *qdev_get_fw_dev_path(DeviceState *dev);
-char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev);
+char *qdev_get_own_fw_dev_path_from_handler(DeviceState *dev);
 
 void device_class_set_props(DeviceClass *dc, Property *props);
 
diff --git a/softmmu/bootdevice.c b/softmmu/bootdevice.c
index 2106f1026f..7834bf 100644
--- a/softmmu/bootdevice.c
+++ b/softmmu/bootdevice.c
@@ -214,7 +214,7 @@ static char *get_boot_device_path(DeviceState *dev, bool 
ignore_suffixes,
 
 if (!ignore_suffixes) {
 if (dev) {
-d = qdev_get_own_fw_dev_path_from_handler(dev->parent_bus, dev);
+d = qdev_get_own_fw_dev_path_from_handler(dev);
 if (d) {
 assert(!suffix);
 s = d;
-- 
2.38.1




[PATCH 2/4] hw: Replace dev->parent_bus by qdev_get_parent_bus(dev)

2023-02-12 Thread Philippe Mathieu-Daudé
DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper. Replace all
uses in hw/ except the QDev uses in hw/core/.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/audio/intel-hda.c|  2 +-
 hw/block/fdc.c  |  2 +-
 hw/block/swim.c |  2 +-
 hw/ide/qdev.c   |  4 ++--
 hw/net/virtio-net.c |  2 +-
 hw/pci-bridge/pci_expander_bridge.c |  2 +-
 hw/scsi/scsi-bus.c  |  2 +-
 hw/usb/bus.c|  2 +-
 hw/usb/desc.c   |  2 +-
 hw/usb/dev-smartcard-reader.c   | 16 
 10 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index b9ed231fe8..6bc239a981 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -59,7 +59,7 @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, 
size_t bus_size,
 
 static void hda_codec_dev_realize(DeviceState *qdev, Error **errp)
 {
-HDACodecBus *bus = HDA_BUS(qdev->parent_bus);
+HDACodecBus *bus = HDA_BUS(qdev_get_parent_bus(qdev));
 HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev);
 HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev);
 
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 64ae4a6899..31ad6f6ae0 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -466,7 +466,7 @@ static Property floppy_drive_properties[] = {
 static void floppy_drive_realize(DeviceState *qdev, Error **errp)
 {
 FloppyDrive *dev = FLOPPY_DRIVE(qdev);
-FloppyBus *bus = FLOPPY_BUS(qdev->parent_bus);
+FloppyBus *bus = FLOPPY_BUS(qdev_get_parent_bus(qdev));
 FDrive *drive;
 bool read_only;
 int ret;
diff --git a/hw/block/swim.c b/hw/block/swim.c
index 333da08ce0..64e30e9e80 100644
--- a/hw/block/swim.c
+++ b/hw/block/swim.c
@@ -157,7 +157,7 @@ static Property swim_drive_properties[] = {
 static void swim_drive_realize(DeviceState *qdev, Error **errp)
 {
 SWIMDrive *dev = SWIM_DRIVE(qdev);
-SWIMBus *bus = SWIM_BUS(qdev->parent_bus);
+SWIMBus *bus = SWIM_BUS(qdev_get_parent_bus(qdev));
 FDrive *drive;
 int ret;
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6f6c7462f3..96582ce49b 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -81,7 +81,7 @@ static char *idebus_get_fw_dev_path(DeviceState *dev)
 char path[30];
 
 snprintf(path, sizeof(path), "%s@%x", qdev_fw_name(dev),
- ((IDEBus*)dev->parent_bus)->bus_id);
+ ((IDEBus*)qdev_get_parent_bus(dev))->bus_id);
 
 return g_strdup(path);
 }
@@ -90,7 +90,7 @@ static void ide_qdev_realize(DeviceState *qdev, Error **errp)
 {
 IDEDevice *dev = IDE_DEVICE(qdev);
 IDEDeviceClass *dc = IDE_DEVICE_GET_CLASS(dev);
-IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
+IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev_get_parent_bus(qdev));
 
 if (dev->unit == -1) {
 dev->unit = bus->master ? 1 : 0;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3ae909041a..8bc160ab59 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3423,7 +3423,7 @@ static bool failover_replug_primary(VirtIONet *n, 
DeviceState *dev,
 if (!pdev->partially_hotplugged) {
 return true;
 }
-primary_bus = dev->parent_bus;
+primary_bus = qdev_get_parent_bus(dev);
 if (!primary_bus) {
 error_setg(errp, "virtio_net: couldn't find primary bus");
 return false;
diff --git a/hw/pci-bridge/pci_expander_bridge.c 
b/hw/pci-bridge/pci_expander_bridge.c
index e752a21292..8c0649c071 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -151,7 +151,7 @@ static char *pxb_host_ofw_unit_address(const SysBusDevice 
*dev)
 assert(position >= 0);
 
 pxb_dev_base = DEVICE(pxb_dev);
-main_host = PCI_HOST_BRIDGE(pxb_dev_base->parent_bus->parent);
+main_host = PCI_HOST_BRIDGE(qdev_get_parent_bus(pxb_dev_base)->parent);
 main_host_sbd = SYS_BUS_DEVICE(main_host);
 
 if (main_host_sbd->num_mmio > 0) {
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index ceceafb2cd..3127cd7273 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1671,7 +1671,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev, 
SCSISense sense)
 static char *scsibus_get_dev_path(DeviceState *dev)
 {
 SCSIDevice *d = SCSI_DEVICE(dev);
-DeviceState *hba = dev->parent_bus->parent;
+DeviceState *hba = qdev_get_parent_bus(dev)->parent;
 char *id;
 char *path;
 
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 92d6ed5626..d7c3c71435 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -595,7 +595,7 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState 
*qdev, int indent)
 static char *usb_get_dev_path(DeviceState *qdev)
 {
 USBDevice *dev = USB_DEVICE(qdev);
-DeviceState *hcd = qdev->parent_bus->parent;
+DeviceState *hcd = qdev_get_parent_bus(qdev)->parent;
 char *id = qdev_get_dev_path(hcd);
 
 

[PATCH 0/4] hw/qdev: Housekeeping around qdev_get_parent_bus()

2023-02-12 Thread Philippe Mathieu-Daudé
DeviceState::parent_bus is an internal field and should be
accessed by the qdev_get_parent_bus() helper. Replace most uses.

Philippe Mathieu-Daudé (4):
  hw/qdev: Constify DeviceState* argument of qdev_get_parent_bus()
  hw: Replace dev->parent_bus by qdev_get_parent_bus(dev)
  hw: Use qdev_get_parent_bus() in
qdev_get_own_fw_dev_path_from_handler()
  qdev-monitor: Use qdev_get_parent_bus() in bus_print_dev()

 hw/audio/intel-hda.c|  2 +-
 hw/block/fdc.c  |  2 +-
 hw/block/swim.c |  2 +-
 hw/core/qdev-fw.c   |  9 +
 hw/core/qdev.c  |  2 +-
 hw/ide/qdev.c   |  4 ++--
 hw/net/virtio-net.c |  2 +-
 hw/pci-bridge/pci_expander_bridge.c |  2 +-
 hw/scsi/scsi-bus.c  |  2 +-
 hw/usb/bus.c|  2 +-
 hw/usb/desc.c   |  2 +-
 hw/usb/dev-smartcard-reader.c   | 16 
 include/hw/qdev-core.h  |  4 ++--
 softmmu/bootdevice.c|  2 +-
 softmmu/qdev-monitor.c  |  6 +++---
 15 files changed, 30 insertions(+), 29 deletions(-)

-- 
2.38.1




[PATCH v7 15/23] hw/isa/piix4: Reuse struct PIIXState from PIIX3

2023-02-12 Thread Bernhard Beschow
PIIX4 has its own, private PIIX4State structure. PIIX3 has almost the
same structure, provided in a public header. So reuse it and add a
cpu_intr attribute which is only used by PIIX4.

Signed-off-by: Bernhard Beschow 
---
 include/hw/southbridge/piix.h |  1 +
 hw/isa/piix4.c| 62 +++
 2 files changed, 21 insertions(+), 42 deletions(-)

diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index d04b08357a..9619b08817 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -50,6 +50,7 @@ struct PIIXState {
 #endif
 uint64_t pic_levels;
 
+qemu_irq cpu_intr;
 qemu_irq *pic;
 
 /* This member isn't used. Just for save/load compatibility */
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 9edaa5de3e..df22c81cc2 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -42,33 +42,10 @@
 #include "sysemu/runstate.h"
 #include "qom/object.h"
 
-struct PIIX4State {
-PCIDevice dev;
-qemu_irq cpu_intr;
-qemu_irq *isa;
-
-RTCState rtc;
-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)
-
 static void piix4_set_irq(void *opaque, int irq_num, int level)
 {
 int i, pic_irq, pic_level;
-PIIX4State *s = opaque;
+PIIXState *s = opaque;
 PCIBus *bus = pci_get_bus(>dev);
 
 /* now we change the pic irq level according to the piix irq mappings */
@@ -82,13 +59,13 @@ 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[pic_irq], pic_level);
 }
 }
 
 static void piix4_isa_reset(DeviceState *dev)
 {
-PIIX4State *d = PIIX4_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
@@ -123,12 +100,13 @@ static void piix4_isa_reset(DeviceState *dev)
 pci_conf[0xac] = 0x00;
 pci_conf[0xae] = 0x00;
 
+d->pic_levels = 0; /* not used in PIIX4 */
 d->rcr = 0;
 }
 
 static int piix4_post_load(void *opaque, int version_id)
 {
-PIIX4State *s = opaque;
+PIIXState *s = opaque;
 
 if (version_id == 2) {
 s->rcr = 0;
@@ -143,22 +121,22 @@ static const VMStateDescription vmstate_piix4 = {
 .minimum_version_id = 2,
 .post_load = piix4_post_load,
 .fields = (VMStateField[]) {
-VMSTATE_PCI_DEVICE(dev, PIIX4State),
-VMSTATE_UINT8_V(rcr, PIIX4State, 3),
+VMSTATE_PCI_DEVICE(dev, PIIXState),
+VMSTATE_UINT8_V(rcr, PIIXState, 3),
 VMSTATE_END_OF_LIST()
 }
 };
 
 static void piix4_request_i8259_irq(void *opaque, int irq, int level)
 {
-PIIX4State *s = opaque;
+PIIXState *s = opaque;
 qemu_set_irq(s->cpu_intr, level);
 }
 
 static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
 unsigned int len)
 {
-PIIX4State *s = opaque;
+PIIXState *s = opaque;
 
 if (val & 4) {
 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
@@ -170,7 +148,7 @@ static void piix4_rcr_write(void *opaque, hwaddr addr, 
uint64_t val,
 
 static uint64_t piix4_rcr_read(void *opaque, hwaddr addr, unsigned int len)
 {
-PIIX4State *s = opaque;
+PIIXState *s = opaque;
 
 return s->rcr;
 }
@@ -187,7 +165,7 @@ static const MemoryRegionOps piix4_rcr_ops = {
 
 static void piix4_realize(PCIDevice *dev, Error **errp)
 {
-PIIX4State *s = PIIX4_PCI_DEVICE(dev);
+PIIXState *s = PIIX_PCI_DEVICE(dev);
 PCIBus *pci_bus = pci_get_bus(dev);
 ISABus *isa_bus;
 qemu_irq *i8259_out_irq;
@@ -208,10 +186,10 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 
 /* initialize i8259 pic */
 i8259_out_irq = qemu_allocate_irqs(piix4_request_i8259_irq, s, 1);
-s->isa = i8259_init(isa_bus, *i8259_out_irq);
+s->pic = i8259_init(isa_bus, *i8259_out_irq);
 
 /* initialize ISA irqs */
-isa_bus_irqs(isa_bus, s->isa);
+isa_bus_irqs(isa_bus, s->pic);
 
 /* initialize pit */
 i8254_pit_init(isa_bus, 0x40, 0, NULL);
@@ -251,7 +229,7 @@ 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, s->pic[9]);
 }
 
 pci_bus_irqs(pci_bus, piix4_set_irq, s, PIIX_NUM_PIRQS);
@@ -259,17 +237,17 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 
 static void piix4_init(Object *obj)
 {
-PIIX4State *s = PIIX4_PCI_DEVICE(obj);
+PIIXState *s = PIIX_PCI_DEVICE(obj);
 
 object_initialize_child(obj, "rtc", 

Re: [PATCH v6 00/33] Consolidate PIIX south bridges

2023-02-12 Thread Bernhard Beschow



Am 11. Februar 2023 16:23:10 UTC schrieb Bernhard Beschow :
>
>
>Am 10. Februar 2023 17:11:06 UTC schrieb "Philippe Mathieu-Daudé" 
>:
>>On 10/2/23 17:27, Bernhard Beschow wrote:
>>> 
>>> 
>>> Am 23. Januar 2023 15:51:49 UTC schrieb Bernhard Beschow 
>>> :
 
 
 Am 23. Januar 2023 09:25:51 UTC schrieb "Philippe Mathieu-Daudé" 
 :
> On 20/1/23 13:22, Bernhard Beschow wrote:
>> Am 13. Januar 2023 17:39:45 UTC schrieb Bernhard Beschow 
>> :
>>> Am 13. Januar 2023 08:46:53 UTC schrieb "Philippe Mathieu-Daudé" 
>>> :
 On 9/1/23 18:23, Bernhard Beschow wrote:
> 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.
 
> Bernhard Beschow (30):
>  hw/pci/pci: Factor out pci_bus_map_irqs() from pci_bus_irqs()
>  hw/isa/piix3: Decouple INTx-to-LNKx routing which is 
> board-specific
>  hw/isa/piix4: Decouple INTx-to-LNKx routing which is 
> board-specific
>  hw/mips/Kconfig: Track Malta's PIIX dependencies via Kconfig
>  hw/usb/hcd-uhci: Introduce TYPE_ defines for device models
>  hw/intc/i8259: Make using the isa_pic singleton more type-safe
>  hw/intc/i8259: Introduce i8259 proxy TYPE_ISA_PIC
>  hw/i386/pc: Create RTC controllers in south bridges
>  hw/i386/pc: No need for rtc_state to be an out-parameter
>  hw/i386/pc_piix: Allow for setting properties before realizing 
> PIIX3
>south bridge
>  hw/isa/piix3: Create USB controller in host device
>  hw/isa/piix3: Create power management controller in host device
>  hw/isa/piix3: Create TYPE_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: 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: Drop the "3" from PIIX base class
>  hw/isa/piix4: Make PIIX4's ACPI and USB functions optional
>  hw/isa/piix4: Remove unused inbound ISA interrupt lines
>  hw/isa/piix4: Use TYPE_ISA_PIC device
>  hw/isa/piix4: Reuse struct PIIXState from PIIX3
>  hw/isa/piix4: Rename reset control operations to match PIIX3
>  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's base class with PIIX4
> 
> Philippe Mathieu-Daudé (3):
>  hw/mips/malta: Introduce PIIX4_PCI_DEVFN definition
>  hw/mips/malta: Set PIIX4 IRQ routes in embedded bootloader
>  hw/isa/piix4: Correct IRQRC[A:D] reset values
 
 I'm queuing the first 10 patches for now to alleviate the size of this
 series, and I'll respin a v7 with the rest to avoid making you suffer
 any longer :/ Thanks for insisting in this effort and I apologize it
 is taking me so long...
>>> 
>>> Okay... What's the further plan? Is there anything missing?
>> 
>> Ping
> 
> The plan is "I'll respin a v7 with the rest".
 
 I understood that part. I wonder what the blocking issue is/was.
>>> 
>>> The first part of this series contains piix3 changes such as the ISA proxy 
>>> pic and movement of rtc. This seems the riskier part of the series to me 
>>> which I'd like to get feedback on from the field rather sooner than later. 
>>> The reason is that I can't currently forsee how fast I could react if these 
>>> changes were merged during (soft) freeze.
>>
>>What bugs me is the i8259 proxy.
>
>I agree that it smells like a workaround for some problem elsewhere.
>
>The patch introducing the proxy to piix3 could be replaced by a patch moving:
>- isa_bus_irqs() into piix3's realize method and
>- `piix3->pic = x86ms->gsi;` in front of the realize call of piix3.
>
>Would that work for you? I could respin then.
>
>A first test run with the pc machine seems promising. The Malta machine would 
>need similar treatment.

v7 is out which doesn't need a PIC proxy.


[PATCH v7 13/23] hw/isa/piix4: Make PIIX4's ACPI and USB functions optional

2023-02-12 Thread Bernhard Beschow
This aligns PIIX4 with PIIX3.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-30-shen...@gmail.com>
---
 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 de60ceef73..de4133f573 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)
@@ -234,17 +241,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, s, PIIX_NUM_PIRQS);
 }
@@ -255,13 +271,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);
@@ -280,6 +299,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 ec172b111a..db5e5fd85c 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1254,8 +1254,10 @@ void mips_malta_init(MachineState *machine)
 pci_bus_map_irqs(pci_bus, malta_pci_slot_get_pirq);
 
 /* Southbridge */
-piix4 = pci_create_simple_multifunction(pci_bus, PIIX4_PCI_DEVFN, true,
-TYPE_PIIX4_PCI_DEVICE);
+piix4 = pci_new_multifunction(PIIX4_PCI_DEVFN, 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.39.1




[PATCH v7 08/23] hw/isa/piix3: Wire up ACPI interrupt internally

2023-02-12 Thread Bernhard Beschow
Now that PIIX3 has the PIC integrated, the ACPI controller can be wired
up internally.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-18-shen...@gmail.com>
---
 hw/i386/pc_piix.c | 1 -
 hw/isa/piix3.c| 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index bd66a5682b..8af4d5aa1b 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -327,7 +327,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 dd8b712085..dfdae27daf 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -338,6 +338,7 @@ 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, d->pic[9]);
 }
 }
 
-- 
2.39.1




[PATCH v7 21/23] hw/isa/piix: Rename functions to be shared for interrupt triggering

2023-02-12 Thread Bernhard Beschow
PIIX4 will get the same optimizations which are already implemented for
PIIX3.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-40-shen...@gmail.com>
---
 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 0177be6d6f..b0f0b42dae 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[pic_irq],
- !!(piix3->pic_levels &
+qemu_set_irq(piix->pic[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)
@@ -122,29 +122,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);
 }
 }
 }
@@ -166,7 +166,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)
@@ -226,7 +226,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;
@@ -473,7 +473,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
-pci_bus_irqs(pci_bus, piix3_set_irq, piix3, PIIX_NUM_PIRQS);
+pci_bus_irqs(pci_bus, piix_set_irq, piix3, PIIX_NUM_PIRQS);
 pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
 }
 
@@ -481,7 +481,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 = 

[PATCH v7 14/23] hw/isa/piix4: Remove unused inbound ISA interrupt lines

2023-02-12 Thread Bernhard Beschow
The Malta board, which is the only user of PIIX4, doesn't connect to the
exported interrupt lines. PIIX3 doesn't expose such interrupt lines
either, so remove them for PIIX4 for simplicity and consistency.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-32-shen...@gmail.com>
---
 hw/isa/piix4.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index de4133f573..9edaa5de3e 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -155,12 +155,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)
 {
@@ -204,8 +198,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.39.1




[PATCH v7 18/23] hw/isa/piix3: Merge hw/isa/piix4.c

2023-02-12 Thread Bernhard Beschow
Now that the PIIX3 and PIIX4 device models are sufficiently consolidated,
their implementations can be merged into one file for further
consolidation.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-37-shen...@gmail.com>
---
 MAINTAINERS|   6 +-
 hw/isa/{piix3.c => piix.c} | 165 +
 hw/isa/piix4.c | 291 -
 hw/i386/Kconfig|   2 +-
 hw/isa/Kconfig |  11 +-
 hw/isa/meson.build |   3 +-
 hw/mips/Kconfig|   2 +-
 7 files changed, 172 insertions(+), 308 deletions(-)
 rename hw/isa/{piix3.c => piix.c} (74%)
 delete mode 100644 hw/isa/piix4.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e25f62ac..fb490ada4f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1250,7 +1250,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/pci-host/gt64120.c
@@ -1669,7 +1669,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
@@ -2359,7 +2359,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/hw/isa/piix3.c b/hw/isa/piix.c
similarity index 74%
rename from hw/isa/piix3.c
rename to hw/isa/piix.c
index 1d116f20f8..f904327823 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
@@ -27,9 +28,11 @@
 #include "qapi/error.h"
 #include "hw/dma/i8257.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"
+#include "hw/intc/i8259.h"
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
 #include "sysemu/runstate.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[pic_irq], pic_level);
+}
+}
+
 static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
 {
 PIIXState *piix3 = opaque;
@@ -208,6 +232,17 @@ static int piix3_post_load(void *opaque, int version_id)
 return 0;
 }
 
+static int piix4_post_load(void *opaque, int version_id)
+{
+PIIXState *s = opaque;
+
+if (version_id == 2) {
+s->rcr = 0;
+}
+
+return 0;
+}
+
 static int piix3_pre_save(void *opaque)
 {
 int i;
@@ -257,6 +292,17 @@ static const VMStateDescription vmstate_piix3 = {
 }
 };
 
+static const VMStateDescription vmstate_piix4 = {
+.name = "PIIX4",
+.version_id = 3,
+.minimum_version_id = 2,
+.post_load = piix4_post_load,
+.fields = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, PIIXState),
+VMSTATE_UINT8_V(rcr, PIIXState, 3),
+VMSTATE_END_OF_LIST()
+}
+};
 
 static void rcr_write(void *opaque, hwaddr addr, uint64_t val, unsigned len)
 {
@@ -479,11 +525,130 @@ static const TypeInfo piix3_xen_info = {
 .class_init= piix3_xen_class_init,
 };
 
+static void piix4_request_i8259_irq(void *opaque, int irq, int level)
+{
+PIIXState *s = opaque;
+qemu_set_irq(s->cpu_intr, level);
+}
+
+static void piix4_realize(PCIDevice *dev, Error **errp)
+{
+PIIXState *s = PIIX_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);
+if (!isa_bus) {
+return;
+}
+
+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);
+
+/* initialize i8259 pic */
+ 

[PATCH v7 19/23] hw/isa/piix: Harmonize names of reset control memory regions

2023-02-12 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 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-38-shen...@gmail.com>
---
 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 f904327823..4b48fe6023 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -345,7 +345,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 }
 
 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);
 
@@ -545,7 +545,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.39.1




[PATCH v7 03/23] hw/i386/pc_piix: Allow for setting properties before realizing PIIX3 south bridge

2023-02-12 Thread Bernhard Beschow
The next patches will need to take advantage of it.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Peter Maydell 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-3-shen...@gmail.com>
---
 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 a577ea2f4e..37afc01d30 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -235,7 +235,8 @@ static void pc_init1(MachineState *machine,
: pc_pci_slot_get_pirq);
 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.39.1




[PATCH v7 02/23] hw/i386/pc: No need for rtc_state to be an out-parameter

2023-02-12 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 
Reviewed-by: Michael S. Tsirkin 
Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-12-shen...@gmail.com>
---
 include/hw/i386/pc.h |  2 +-
 hw/i386/pc.c | 12 ++--
 hw/i386/pc_piix.c|  2 +-
 hw/i386/pc_q35.c |  2 +-
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 66e3d059ef..5ba814aca6 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -168,7 +168,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,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 44daa36338..16b7bd40ef 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1251,7 +1251,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)
 {
@@ -1306,17 +1306,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 8f894714e5..a577ea2f4e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -276,7 +276,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 3b1a0d0cfd..ade8c26bfd 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -294,7 +294,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 */
-- 
2.39.1




[PATCH v7 20/23] hw/isa/piix: Reuse PIIX3 base class' realize method in PIIX4

2023-02-12 Thread Bernhard Beschow
Resolves duplicate code.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-39-shen...@gmail.com>
---
 hw/isa/piix.c | 78 ---
 1 file changed, 24 insertions(+), 54 deletions(-)

diff --git a/hw/isa/piix.c b/hw/isa/piix.c
index 4b48fe6023..0177be6d6f 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -332,17 +332,11 @@ static const MemoryRegionOps rcr_ops = {
 },
 };
 
-static void pci_piix3_realize(PCIDevice *dev, Error **errp)
+static void pci_piix_realize(PCIDevice *dev, const char *uhci_type,
+ ISABus *isa_bus, Error **errp)
 {
 PIIXState *d = PIIX_PCI_DEVICE(dev);
 PCIBus *pci_bus = pci_get_bus(dev);
-ISABus *isa_bus;
-
-isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev),
-  pci_address_space_io(dev), errp);
-if (!isa_bus) {
-return;
-}
 
 memory_region_init_io(>rcr_mem, OBJECT(dev), _ops, d,
   "piix-reset-control", 1);
@@ -367,8 +361,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 
 /* USB */
 if (d->has_usb) {
-object_initialize_child(OBJECT(dev), "uhci", >uhci,
-TYPE_PIIX3_USB_UHCI);
+object_initialize_child(OBJECT(dev), "uhci", >uhci, uhci_type);
 qdev_prop_set_int32(DEVICE(>uhci), "addr", dev->devfn + 2);
 if (!qdev_realize(DEVICE(>uhci), BUS(pci_bus), errp)) {
 return;
@@ -467,8 +460,15 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 ERRP_GUARD();
 PIIXState *piix3 = PIIX_PCI_DEVICE(dev);
 PCIBus *pci_bus = pci_get_bus(dev);
+ISABus *isa_bus;
+
+isa_bus = isa_bus_new(DEVICE(dev), pci_address_space(dev),
+  pci_address_space_io(dev), errp);
+if (!isa_bus) {
+return;
+}
 
-pci_piix3_realize(dev, errp);
+pci_piix_realize(dev, TYPE_PIIX3_USB_UHCI, isa_bus, errp);
 if (*errp) {
 return;
 }
@@ -496,8 +496,15 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp)
 ERRP_GUARD();
 PIIXState *piix3 = PIIX_PCI_DEVICE(dev);
 PCIBus *pci_bus = pci_get_bus(dev);
+ISABus *isa_bus;
 
-pci_piix3_realize(dev, errp);
+isa_bus = isa_bus_new(DEVICE(dev), pci_address_space(dev),
+  pci_address_space_io(dev), errp);
+if (!isa_bus) {
+return;
+}
+
+pci_piix_realize(dev, TYPE_PIIX3_USB_UHCI, isa_bus, errp);
 if (*errp) {
 return;
 }
@@ -533,6 +540,7 @@ static void piix4_request_i8259_irq(void *opaque, int irq, 
int level)
 
 static void piix4_realize(PCIDevice *dev, Error **errp)
 {
+ERRP_GUARD();
 PIIXState *s = PIIX_PCI_DEVICE(dev);
 PCIBus *pci_bus = pci_get_bus(dev);
 ISABus *isa_bus;
@@ -544,59 +552,21 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 return;
 }
 
-memory_region_init_io(>rcr_mem, OBJECT(dev), _ops, s,
-  "piix-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->pic = i8259_init(isa_bus, *i8259_out_irq);
 
-/* initialize ISA irqs */
-isa_bus_irqs(isa_bus, s->pic);
+pci_piix_realize(dev, TYPE_PIIX4_USB_UHCI, isa_bus, errp);
+if (*errp) {
+return;
+}
 
 /* initialize pit */
 i8254_pit_init(isa_bus, 0x40, 0, NULL);
 
-/* DMA */
-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;
-}
 s->rtc.irq = s->pic[s->rtc.isairq];
 
-/* IDE */
-qdev_prop_set_int32(DEVICE(>ide), "addr", dev->devfn + 1);
-if (!qdev_realize(DEVICE(>ide), BUS(pci_bus), errp)) {
-return;
-}
-
-/* USB */
-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 */
-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->pic[9]);
-}
-
 pci_bus_irqs(pci_bus, piix4_set_irq, s, PIIX_NUM_PIRQS);
 }
 
-- 
2.39.1




[PATCH v7 05/23] hw/isa/piix3: Create power management controller in host device

2023-02-12 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 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-14-shen...@gmail.com>
---
 include/hw/southbridge/piix.h |  6 ++
 hw/i386/pc_piix.c | 24 ++--
 hw/isa/piix3.c| 14 ++
 hw/isa/Kconfig|  1 +
 4 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 762709f2fd..b1eaab1d95 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -14,6 +14,7 @@
 
 #include "hw/pci/pci_device.h"
 #include "qom/object.h"
+#include "hw/acpi/piix4.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/usb/hcd-uhci.h"
 
@@ -56,6 +57,9 @@ struct PIIXState {
 
 RTCState rtc;
 UHCIState uhci;
+PIIX4PMState pm;
+
+uint32_t smb_io_base;
 
 /* Reset Control Register contents */
 uint8_t rcr;
@@ -63,7 +67,9 @@ struct PIIXState {
 /* IO memory region for Reset Control Register (PIIX_RCR_IOPORT) */
 MemoryRegion rcr_mem;
 
+bool has_acpi;
 bool has_usb;
+bool smm_enabled;
 };
 typedef struct PIIXState PIIX3State;
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 61d8152078..5ea8d4a585 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -46,12 +46,12 @@
 #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 "hw/xen/xen.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"
@@ -97,6 +97,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;
@@ -237,15 +238,25 @@ 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;
 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"));
+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);
 
@@ -315,15 +326,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);
@@ -337,7 +341,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/piix3.c b/hw/isa/piix3.c
index 7ae031f2c5..27bd4dbf65 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -319,6 +319,17 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 return;
 }
 }
+
+/* Power Management */
+if (d->has_acpi) {
+  

[PATCH v7 23/23] hw/isa/piix: Share PIIX3's base class with PIIX4

2023-02-12 Thread Bernhard Beschow
Having a common base class will allow for substituting PIIX3 with PIIX4
and vice versa. Moreover, it makes PIIX4 implement the
acpi-dev-aml-interface.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-42-shen...@gmail.com>
---
 hw/isa/piix.c | 48 ++--
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/hw/isa/piix.c b/hw/isa/piix.c
index 0c644dc6e6..0c2d560b85 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -381,12 +381,11 @@ static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml 
*scope)
 qbus_build_aml(bus, 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, "rtc", >rtc, TYPE_MC146818_RTC);
-object_initialize_child(obj, "ide", >ide, TYPE_PIIX3_IDE);
 }
 
 static Property pci_piix_props[] = {
@@ -397,7 +396,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);
@@ -405,11 +404,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
@@ -424,9 +420,9 @@ static const TypeInfo piix_pci_type_info = {
 .name = TYPE_PIIX_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 },
@@ -456,17 +452,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_PIIX_PCI_DEVICE,
+.instance_init = piix3_init,
 .class_init= piix3_class_init,
 };
 
@@ -499,15 +507,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_PIIX_PCI_DEVICE,
+.instance_init = piix3_init,
 .class_init= piix3_xen_class_init,
 };
 
@@ -555,7 +568,6 @@ static void piix4_init(Object *obj)
 
 qdev_init_gpio_out_named(DEVICE(obj), >cpu_intr, "intr", 1);
 
-object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 object_initialize_child(obj, "ide", >ide, TYPE_PIIX4_IDE);
 }
 
@@ -566,31 +578,15 @@ 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),
+.parent= TYPE_PIIX_PCI_DEVICE,
 .instance_init = piix4_init,
 .class_init= piix4_class_init,
-.interfaces = (InterfaceInfo[]) {
-{ 

[PATCH v7 16/23] hw/isa/piix4: Create the "intr" property during init() already

2023-02-12 Thread Bernhard Beschow
Only PIIX4 provides this property while PIIX3 doesn't.

Unlike initialize() methods, init() methods allow for device-specific
quirks without having to call the parent method. So move the creation of
the property into PIIX4's init() method as a preparation of the code
merge and the subsequent cleanup of the realize methods.

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

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index df22c81cc2..7d4a66af49 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -176,9 +176,6 @@ 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),
@@ -239,6 +236,8 @@ static void piix4_init(Object *obj)
 {
 PIIXState *s = PIIX_PCI_DEVICE(obj);
 
+qdev_init_gpio_out_named(DEVICE(obj), >cpu_intr, "intr", 1);
+
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 object_initialize_child(obj, "ide", >ide, TYPE_PIIX4_IDE);
 }
-- 
2.39.1




[PATCH v7 11/23] hw/isa/piix3: Rename piix3_reset() for sharing with PIIX4

2023-02-12 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-23-shen...@gmail.com>
---
 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 cf7daf29ab..76004a25e2 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -145,7 +145,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;
@@ -385,7 +385,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.39.1




[PATCH v7 07/23] hw/isa/piix3: Create IDE controller in host device

2023-02-12 Thread Bernhard Beschow
Now that PIIX3 contains the new TYPE_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 TYPE_ISA_PIC even though the virtualization technology isn't
known yet.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-17-shen...@gmail.com>
---
 include/hw/southbridge/piix.h |  2 ++
 hw/i386/pc_piix.c | 16 +++-
 hw/isa/piix3.c|  8 
 hw/i386/Kconfig   |  1 -
 hw/isa/Kconfig|  1 +
 5 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index b1eaab1d95..f84a5d15cf 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -15,6 +15,7 @@
 #include "hw/pci/pci_device.h"
 #include "qom/object.h"
 #include "hw/acpi/piix4.h"
+#include "hw/ide/pci.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/usb/hcd-uhci.h"
 
@@ -56,6 +57,7 @@ struct PIIXState {
 int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
 
 RTCState rtc;
+PCIIDEState ide;
 UHCIState uhci;
 PIIX4PMState pm;
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index dbddc3d060..bd66a5682b 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"
@@ -98,7 +97,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];
@@ -219,6 +217,7 @@ static void pc_init1(MachineState *machine,
 gsi_state = pc_gsi_create(>gsi, pcmc->pci_enabled);
 
 if (pcmc->pci_enabled) {
+DeviceState *dev;
 PIIX3State *piix3;
 PCIDevice *pci_dev;
 const char *type = xen_enabled() ? TYPE_PIIX3_XEN_DEVICE
@@ -249,11 +248,14 @@ static void pc_init1(MachineState *machine,
 piix3->pic = x86ms->gsi;
 pci_realize_and_unref(pci_dev, pci_bus, _fatal);
 
-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"));
 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;
@@ -267,6 +269,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) {
@@ -295,12 +299,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/piix3.c b/hw/isa/piix3.c
index 007225a96e..dd8b712085 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/runstate.h"
@@ -312,6 +313,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,
@@ -360,6 +367,7 @@ static void pci_piix3_init(Object *obj)
 PIIX3State *d = PIIX3_PCI_DEVICE(obj);
 
 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/hw/i386/Kconfig b/hw/i386/Kconfig
index 1bf47b0b0b..408301fd8d 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -74,7 +74,6 @@ config I440FX
 select PC_ACPI
 select PCI_I440FX
 select PIIX3
-select IDE_PIIX
 select DIMM
 select SMBIOS
 select 

[PATCH v7 22/23] hw/isa/piix: Consolidate IRQ triggering

2023-02-12 Thread Bernhard Beschow
Speeds up PIIX4 which resolves an old TODO.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-41-shen...@gmail.com>
---
 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 b0f0b42dae..0c644dc6e6 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[pic_irq], pic_level);
-}
-}
-
 static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
 {
 PIIXState *piix3 = opaque;
@@ -240,7 +219,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)
@@ -567,7 +546,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 /* RTC */
 s->rtc.irq = s->pic[s->rtc.isairq];
 
-pci_bus_irqs(pci_bus, piix4_set_irq, s, PIIX_NUM_PIRQS);
+pci_bus_irqs(pci_bus, piix_set_irq, s, PIIX_NUM_PIRQS);
 }
 
 static void piix4_init(Object *obj)
@@ -585,6 +564,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.39.1




[PATCH v7 17/23] hw/isa/piix4: Rename reset control operations to match PIIX3

2023-02-12 Thread Bernhard Beschow
Both implementations are the same and will be shared upon merging.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-35-shen...@gmail.com>
---
 hw/isa/piix4.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 7d4a66af49..4538676ea5 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -133,8 +133,8 @@ static void piix4_request_i8259_irq(void *opaque, int irq, 
int level)
 qemu_set_irq(s->cpu_intr, level);
 }
 
-static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
-unsigned int len)
+static void rcr_write(void *opaque, hwaddr addr, uint64_t val,
+  unsigned int len)
 {
 PIIXState *s = opaque;
 
@@ -146,16 +146,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,
@@ -176,7 +176,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.39.1




[PATCH v7 10/23] hw/isa/piix3: Rename pci_piix3_props for sharing with PIIX4

2023-02-12 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-22-shen...@gmail.com>
---
 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 55835912b8..cf7daf29ab 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -371,7 +371,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_BOOL("has-acpi", PIIX3State, has_acpi, true),
 DEFINE_PROP_BOOL("has-usb", PIIX3State, has_usb, true),
@@ -398,7 +398,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.39.1




[PATCH v7 12/23] hw/isa/piix3: Drop the "3" from PIIX base class

2023-02-12 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 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-25-shen...@gmail.com>
---
 include/hw/southbridge/piix.h |  6 ++--
 hw/i386/pc_piix.c |  4 +--
 hw/isa/piix3.c| 60 +--
 3 files changed, 34 insertions(+), 36 deletions(-)

diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 096a85e384..d04b08357a 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -72,11 +72,9 @@ struct PIIXState {
 bool has_usb;
 bool smm_enabled;
 };
-typedef struct PIIXState PIIX3State;
 
-#define TYPE_PIIX3_PCI_DEVICE "pci-piix3"
-DECLARE_INSTANCE_CHECKER(PIIX3State, PIIX3_PCI_DEVICE,
- TYPE_PIIX3_PCI_DEVICE)
+#define TYPE_PIIX_PCI_DEVICE "pci-piix"
+OBJECT_DECLARE_SIMPLE_TYPE(PIIXState, PIIX_PCI_DEVICE)
 
 #define TYPE_PIIX3_DEVICE "PIIX3"
 #define TYPE_PIIX3_XEN_DEVICE "PIIX3-xen"
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 8af4d5aa1b..e7e12a039d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -218,7 +218,7 @@ static void pc_init1(MachineState *machine,
 
 if (pcmc->pci_enabled) {
 DeviceState *dev;
-PIIX3State *piix3;
+PIIXState *piix3;
 PCIDevice *pci_dev;
 const char *type = xen_enabled() ? TYPE_PIIX3_XEN_DEVICE
  : TYPE_PIIX3_DEVICE;
@@ -244,7 +244,7 @@ static void pc_init1(MachineState *machine,
 object_property_set_bool(OBJECT(pci_dev), "smm-enabled",
  x86_machine_is_smm_enabled(x86ms),
  _abort);
-piix3 = PIIX3_PCI_DEVICE(pci_dev);
+piix3 = PIIX_PCI_DEVICE(pci_dev);
 piix3->pic = x86ms->gsi;
 pci_realize_and_unref(pci_dev, pci_bus, _fatal);
 
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 76004a25e2..1d116f20f8 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[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,13 +77,13 @@ 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);
 }
 
 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;
 
@@ -98,7 +98,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;
@@ -114,7 +114,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));
@@ -147,7 +147,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 */
@@ -188,7 +188,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;
 
 /*
@@ -211,7 +211,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 < 

[PATCH v7 04/23] hw/isa/piix3: Create USB controller in host device

2023-02-12 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 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-13-shen...@gmail.com>
---
 include/hw/southbridge/piix.h |  4 
 hw/i386/pc_piix.c |  7 ++-
 hw/isa/piix3.c| 17 +
 hw/isa/Kconfig|  1 +
 4 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index b06d26fa11..762709f2fd 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -15,6 +15,7 @@
 #include "hw/pci/pci_device.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;
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 37afc01d30..61d8152078 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -52,7 +52,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"
@@ -236,6 +235,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;
@@ -314,10 +315,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/piix3.c b/hw/isa/piix3.c
index f9103ea45a..7ae031f2c5 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -288,6 +288,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),
@@ -308,6 +309,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)
@@ -338,6 +349,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);
@@ -357,6 +373,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/hw/isa/Kconfig b/hw/isa/Kconfig
index c10cbc5fc1..f01bc0dff3 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
-- 
2.39.1




[PATCH v7 06/23] hw/isa/piix3: Move ISA bus IRQ assignments into host device

2023-02-12 Thread Bernhard Beschow
Having the south bridge assign the ISA interrupts to the ISA bus itself
makes the south bridge more self contained. Furthermore, it allows ISA
interrupt wiring in pci_piix3_realize() which will be used in subsequent
patches.

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

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 5ea8d4a585..dbddc3d060 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -245,10 +245,10 @@ static void pc_init1(MachineState *machine,
 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;
+pci_realize_and_unref(pci_dev, pci_bus, _fatal);
+
 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),
@@ -259,6 +259,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);
@@ -267,7 +268,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/piix3.c b/hw/isa/piix3.c
index 27bd4dbf65..007225a96e 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -302,6 +302,8 @@ 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);
 
+isa_bus_irqs(isa_bus, d->pic);
+
 i8257_dma_init(isa_bus, 0);
 
 /* RTC */
-- 
2.39.1




[PATCH v7 09/23] hw/isa/piix3: Resolve redundant PIIX_NUM_PIC_IRQS

2023-02-12 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 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20221022150508.26830-21-shen...@gmail.com>
---
 include/hw/southbridge/piix.h | 5 ++---
 hw/isa/piix3.c| 8 
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index f84a5d15cf..096a85e384 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -31,7 +31,6 @@
  */
 #define PIIX_RCR_IOPORT 0xcf9
 
-#define PIIX_NUM_PIC_IRQS   16  /* i8259 * 2 */
 #define PIIX_NUM_PIRQS  4ULL/* PIRQ[A-D] */
 
 struct PIIXState {
@@ -43,10 +42,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;
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index dfdae27daf..55835912b8 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;
 }
 
@@ -87,7 +87,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 {
@@ -119,7 +119,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);
 }
 }
-- 
2.39.1




[PATCH v7 01/23] hw/i386/pc: Create RTC controllers in south bridges

2023-02-12 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 
Reviewed-by: Michael S. Tsirkin 
Reviewed-by: Thomas Huth 
Message-Id: <20221022150508.26830-11-shen...@gmail.com>
---
 include/hw/i386/ich9.h|  2 ++
 include/hw/southbridge/piix.h |  4 
 hw/i386/pc.c  | 12 +++-
 hw/i386/pc_piix.c |  8 
 hw/i386/pc_q35.c  |  1 +
 hw/isa/lpc_ich9.c |  8 
 hw/isa/piix3.c| 15 +++
 hw/isa/Kconfig|  2 ++
 8 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index 222781e8b9..dab309d5e3 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -7,6 +7,7 @@
 #include "hw/isa/apm.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/ich9.h"
+#include "hw/rtc/mc146818rtc.h"
 #include "qom/object.h"
 
 void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
@@ -35,6 +36,7 @@ struct ICH9LPCState {
 */
 uint8_t irr[PCI_SLOT_MAX][PCI_NUM_PINS];
 
+RTCState rtc;
 APMState apm;
 ICH9LPCPMRegs pm;
 uint32_t sci_level; /* track sci level */
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 0bf48e936d..b06d26fa11 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -13,6 +13,8 @@
 #define HW_SOUTHBRIDGE_PIIX_H
 
 #include "hw/pci/pci_device.h"
+#include "qom/object.h"
+#include "hw/rtc/mc146818rtc.h"
 
 /* PIRQRC[A:D]: PIRQx Route Control Registers */
 #define PIIX_PIRQCA 0x60
@@ -51,6 +53,8 @@ struct PIIXState {
 /* This member isn't used. Just for save/load compatibility */
 int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
 
+RTCState rtc;
+
 /* Reset Control Register contents */
 uint8_t rcr;
 
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6e592bd969..44daa36338 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1304,7 +1304,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 df64dd8dcc..8f894714e5 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"
@@ -239,10 +240,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 66cd718b70..3b1a0d0cfd 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/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 1fba3c210c..b9efae0797 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -663,6 +663,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, 

[PATCH v7 00/23] Consolidate PIIX south bridges

2023-02-12 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:

Move sub devices into the PIIX3 south bridge, like PIIX4 does already:
* hw/i386/pc: Create RTC controllers in south bridges
* hw/i386/pc: No need for rtc_state to be an out-parameter
* hw/i386/pc_piix: Allow for setting properties before realizing PIIX3 south 
bridge
* hw/isa/piix3: Create USB controller in host device
* hw/isa/piix3: Create power management controller in host device
* hw/isa/piix3: Move ISA bus IRQ assignments into host device
* hw/isa/piix3: Create IDE controller in host device
* hw/isa/piix3: Wire up ACPI interrupt internally

Make PIIX3 and PIIX4 south bridges more similar:
* 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: Drop the "3" from PIIX base class
* hw/isa/piix4: Make PIIX4's ACPI and USB functions optional
* hw/isa/piix4: Remove unused inbound ISA interrupt lines
* hw/isa/piix4: Reuse struct PIIXState from PIIX3
* hw/isa/piix4: Create the "intr" property during init() already
* hw/isa/piix4: Rename reset control operations to match PIIX3

This patch achieves the main goal of the series:
* hw/isa/piix3: Merge hw/isa/piix4.c

Perform some further consolidations which were easier to do after the merge:
* 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's base class with PIIX4

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

There are still some differences in the device models:
- PIIX4 instantiates its own PIC and PIT while PIIX3 doesn't
- PIIX4 wires up the RTC IRQ itself while PIIX3 doesn't
- Different binary layout in VM state

v7:
- Rebase onto master
- Avoid the PIC proxy (Phil)
  The motivation for the PIC proxy was to allow for wiring up ISA interrupts in
  the south bridges. ISA interrupt wiring requires the GPIO lines to be
  populated already but pc_piix assigned the interrupts only after realizing
  PIIX3. By shifting interrupt assignment before realizing, the ISA interrupts
  are already populated during PIIX3's realize phase where the ISA interrupts
  are wired up.
- New patches:
  * hw/isa/piix4: Reuse struct PIIXState from PIIX3
  * hw/isa/piix4: Create the "intr" property during init() already
- Patches with substantial changes (Reviewed-by dropped):
  * hw/isa/piix3: Move ISA bus IRQ assignments into host device

Testing done:
* `make check`
* 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=ttyS0"`
* Run HVM domU guest under Xen with manjaro-kde-21.3.2-220704-linux515.iso image

v6:
- Fix some comments about TYPE_ISA_PIC (Mark) ... and use it consistently
  within the patch series.
- Incorporate series "[PATCH v2 0/3] Decouple INTx-to-LNKx routing from south
  bridges" [2] for maintainer convenience.
- Merge v5's 'hw/i386/pc_piix: Associate pci_map_irq_fn as soon as PCI bus is
  created' into
  https://lists.nongnu.org/archive/html/qemu-devel/2022-11/msg03312.html . Do
  similar for Malta.
- Rebase onto latest master (d6271b657286 "Merge tag 'for_upstream' of
  https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging")

v5:
- Pick up Reviewed-by tags from 
https://lists.nongnu.org/archive/html/qemu-devel/2023-01/msg00116.html
- Add patch to make usage of the isa_pic global more type-safe
- Re-introduce isa-pic as PIC specific proxy (Mark)

v4:
- Rebase onto "[PATCH v2 0/3] Decouple INTx-to-LNKx routing from south bridges"
  since it is already queued via mips-next. This eliminates patches
  'hw/isa/piix3: Prefix pci_slot_get_pirq() with "piix3_"' and 'hw/isa/piix4:
  Prefix pci_slot_get_pirq() with "piix4_"'.
- Squash 'hw/isa/piix: Drop the "3" from the PIIX base class' into
  'hw/isa/piix3: Rename typedef PIIX3State to PIIXState'. I originally only
  split these patches since I wasn't sure whether renaming a type was allowed.
- Add new patch 'hw/i386/pc_piix: Associate pci_map_irq_fn as soon as PCI bus is
  created' for forther cleanup of INTx-to-LNKx route decoupling.

v3:
- Introduce one