Skip to contentSkip to conversation

piix_pci cleanup

PATCH Superseded Juan Quintela 1 participant 14 messages Aug 24, 2009 Kbuild

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v2 cover piix_pci cleanup

Hi

v2:
- bit the bullet, change irq_opaque to void *, instead of qemu_irq * that allows us to pass anything there.
- Rearrange piix_pci to be able to add piix3_dev to the irq_state
- Once rearrangmente is fixed, make sane SaveVM *_load/_save() functions. We can still load old state, but we only write the sane one.

mips_malta can do a similar cleanup, it is not difficult to do. But I can't test it.

About irq_state in i440fx_init(). It would have been easier, if there were a way to create i440FX-pcihost giving it the already allocated variable. Basically:

pci_bus = pci_register_bus() -> needs irq_state
i440fx = pci_create_simple(pci_bus, ..) -> needs pci_bus piix3 = pci_create_simple (pci_bus, ...) -> needs pci_bus

irq_state -> needs piix3

We have a nice circular dependency here. to fix it, I just create an empty irq_state, passed it to pci_register_bus() and fill it later.

It would have been a bit cleaner if there were a finction like i440fx = pci_create_simple_here(..., &i440fx).

Later, Juan.

v1:
- split piix4 from piix_pci. The only shared code where piix_save/load, i.e. almost nothing. Once there, compile piix4.o only for mips (it was not used anywhere else).
- Move global variables to PCII440FXState. Nice and clean until....
- pci_irq_levels: This is great:
* it is saved/loaded from i440fx
* it is cleaned during reset in piix3
* it is used in piix3_set_irq, that don't receive neither i440fx nor piix state, it needs to be a global variable. (created a global link until a better solution appear).

I looked where to "hide" pci_irq_levels and piix3_dev (both needed in piix3_set_irq), and didn't found where to pass them, out of:
- hack i8259 to hide it into PicState2 (that one got passed through the pic) ugly for words, but will work
- try to add <something> at setup_irq time, but at that point we have:
* opaque -> pci_dev of device that we are working with
* from there we can get to the bus that the device is attached to, but no way to go from there to the Host bridge (that is what we wanted in the 1st place)

Later, Juan.

*** BLURB HERE ***

Juan Quintela (13):
piix4 don't use pci_irq_levels at all
Split piix4 support from piix_pci.c
low_set_irq is not used anywhere
Use PCII440FXState instead of generic PCIDevice Move smm_enabled and isa_memory_mappings to PCII440FXState We want the argument pass to set_irq to be opaque Create PIIX3State instead of using PCIDevice for PIIX3 Introduce PIIX3IrqState for piix3 irq's state Fold piix3_init() intto i440fx_init
We can add piix3_dev now to PIIX3IrqState
Save irq_state into PCII440FXState pci_irq_levels[] belong to PIIX3State
Update SaveVM versions

 Makefile.target    |    2 +-
 hw/apb_pci.c       |    4 +-
 hw/grackle_pci.c   |    4 +-
 hw/gt64xxx.c       |    3 +-
 hw/pc.c            |    5 +-
 hw/pc.h            |   11 ++-
 hw/pci.c           |    8 +-
 hw/pci.h           |    6 +-
 hw/piix4.c         |  127 +++++++++++++++++++++++++++
 hw/piix_pci.c      |  246 +++++++++++++++++++++-------------------------------
 hw/ppc4xx_pci.c    |    4 +-
 hw/ppce500_pci.c   |    4 +-
 hw/prep_pci.c      |    4 +-
 hw/r2d.c           |    4 +-
 hw/sh_pci.c        |    4 +-
 hw/unin_pci.c      |    4 +-
 hw/versatile_pci.c |    4 +-
 17 files changed, 270 insertions(+), 174 deletions(-)
 create mode 100644 hw/piix4.c
#1 lore raw

PATCH v2 1/13 piix4 don't use pci_irq_levels at all

---
 hw/piix_pci.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)
hw/piix_pci.c +0 -2
index e2ddf4b..7cf1d99 100644
@@ -321,8 +321,6 @@ static void piix4_reset(void *opaque)
     pci_conf[0xab] = 0x00;
     pci_conf[0xac] = 0x00;
     pci_conf[0xae] = 0x00;
-
-    memset(pci_irq_levels, 0, sizeof(pci_irq_levels));
 }
 
 static void piix_save(QEMUFile* f, void *opaque)
Signature · 1 line
1.6.2.5
#2 lore raw

PATCH v2 2/13 Split piix4 support from piix_pci.c

In reply to Juan Quintela

Now mips_malta uses piix4 and pc's use piix_pci definitions

---
 Makefile.target |    2 +-
 hw/pc.h         |    1 +
 hw/piix4.c      |  127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/piix_pci.c   |   71 -------------------------------
 4 files changed, 129 insertions(+), 72 deletions(-)
 create mode 100644 hw/piix4.c
Makefile.target +1 -1
index 595c88b..2f628f6 100644
@@ -217,7 +217,7 @@ obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o rc4030.o
 obj-mips-y += g364fb.o jazz_led.o dp8393x.o
 obj-mips-y += ide.o gt64xxx.o pckbd.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
-obj-mips-y += piix_pci.o parallel.o cirrus_vga.o isa-bus.o pcspk.o $(sound-obj-y)
+obj-mips-y += piix4.o parallel.o cirrus_vga.o isa-bus.o pcspk.o $(sound-obj-y)
 obj-mips-y += mipsnet.o
 obj-mips-y += pflash_cfi01.o
 obj-mips-y += vmware_vga.o
hw/pc.h +1 -0
index 58d569b..bfa52d6 100644
@@ -124,6 +124,7 @@ void i440fx_set_smm(PCIDevice *d, int val);
 int piix3_init(PCIBus *bus, int devfn);
 void i440fx_init_memory_mappings(PCIDevice *d);
 
+/* piix4.c */
 extern PCIDevice *piix4_dev;
 int piix4_init(PCIBus *bus, int devfn);
 
hw/piix4.c new file +127 -0

127 lines not on this page · raw message

hw/piix_pci.c +0 -71

101 lines not on this page · raw message

Signature · 1 line
1.6.2.5
#3 lore raw

PATCH v2 3/13 low_set_irq is not used anywhere

In reply to Juan Quintela
---
 hw/pci.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)
hw/pci.c +0 -2
index 27eac04..e209ceb 100644
@@ -41,8 +41,6 @@ struct PCIBus {
     pci_set_irq_fn set_irq;
     pci_map_irq_fn map_irq;
     uint32_t config_reg; /* XXX: suppress */
-    /* low level pic */
-    SetIRQFunc *low_set_irq;
     qemu_irq *irq_opaque;
     PCIDevice *devices[256];
     PCIDevice *parent_dev;
Signature · 1 line
1.6.2.5
#4 lore raw

PATCH v2 4/13 Use PCII440FXState instead of generic PCIDevice

In reply to Juan Quintela
---
 hw/pc.c       |    2 +-
 hw/pc.h       |    9 ++++++---
 hw/piix_pci.c |   54 +++++++++++++++++++++++++++++++-----------------------
 3 files changed, 38 insertions(+), 27 deletions(-)
hw/pc.c +1 -1
index cc6e7e8..a908f8b 100644
@@ -61,7 +61,7 @@ static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PITState *pit;
 static IOAPICState *ioapic;
-static PCIDevice *i440fx_state;
+static PCII440FXState *i440fx_state;
 
 typedef struct rom_reset_data {
     uint8_t *data;
hw/pc.h +6 -3
index bfa52d6..7733d1a 100644
@@ -119,10 +119,13 @@ void pcspk_init(PITState *);
 int pcspk_audio_init(qemu_irq *pic);
 
 /* piix_pci.c */
-PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic);
-void i440fx_set_smm(PCIDevice *d, int val);
+struct PCII440FXState;
+typedef struct PCII440FXState PCII440FXState;
+
+PCIBus *i440fx_init(PCII440FXState **pi440fx_state, qemu_irq *pic);
+void i440fx_set_smm(PCII440FXState *d, int val);
 int piix3_init(PCIBus *bus, int devfn);
-void i440fx_init_memory_mappings(PCIDevice *d);
+void i440fx_init_memory_mappings(PCII440FXState *d);
 
 /* piix4.c */
 extern PCIDevice *piix4_dev;
hw/piix_pci.c +31 -23

142 lines not on this page · raw message

Signature · 1 line
1.6.2.5
#5 lore raw

PATCH v2 5/13 Move smm_enabled and isa_memory_mappings to PCII440FXState

In reply to Juan Quintela
---
 hw/piix_pci.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)
hw/piix_pci.c +10 -10
index 2450c31..d8aeeec 100644
@@ -35,6 +35,8 @@ typedef PCIHostState I440FXState;
 
 struct PCII440FXState {
     PCIDevice dev;
+    target_phys_addr_t isa_page_descs[384 / 4];
+    uint8_t smm_enabled;
 };
 
 static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
@@ -61,8 +63,6 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
     return (irq_num + slot_addend) & 3;
 }
 
-static target_phys_addr_t isa_page_descs[384 / 4];
-static uint8_t smm_enabled;
 static int pci_irq_levels[4];
 
 static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r)
@@ -86,7 +86,7 @@ static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r)
         /* XXX: should distinguish read/write cases */
         for(addr = start; addr < end; addr += 4096) {
             cpu_register_physical_memory(addr, 4096,
-                                         isa_page_descs[(addr - 0xa0000) >> 12]);
+                                         d->isa_page_descs[(addr - 0xa0000) >> 12]);
         }
         break;
     }
@@ -103,12 +103,12 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
         update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r);
     }
     smram = d->dev.config[0x72];
-    if ((smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
+    if ((d->smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
         cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000);
     } else {
         for(addr = 0xa0000; addr < 0xc0000; addr += 4096) {
             cpu_register_physical_memory(addr, 4096,
-                                         isa_page_descs[(addr - 0xa0000) >> 12]);
+                                         d->isa_page_descs[(addr - 0xa0000) >> 12]);
         }
     }
 }
@@ -116,8 +116,8 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
 void i440fx_set_smm(PCII440FXState *d, int val)
 {
     val = (val != 0);
-    if (smm_enabled != val) {
-        smm_enabled = val;
+    if (d->smm_enabled != val) {
+        d->smm_enabled = val;
         i440fx_update_memory_mappings(d);
     }
 }
@@ -130,7 +130,7 @@ void i440fx_init_memory_mappings(PCII440FXState *d)
 {
     int i;
     for(i = 0; i < 96; i++) {
-        isa_page_descs[i] = cpu_get_physical_page_desc(0xa0000 + i * 0x1000);
+        d->isa_page_descs[i] = cpu_get_physical_page_desc(0xa0000 + i * 0x1000);
     }
 }
 
@@ -151,7 +151,7 @@ static void i440fx_save(QEMUFile* f, void *opaque)
     int i;
 
     pci_device_save(&d->dev, f);
-    qemu_put_8s(f, &smm_enabled);
+    qemu_put_8s(f, &d->smm_enabled);
 
     for (i = 0; i < 4; i++)
         qemu_put_be32(f, pci_irq_levels[i]);
@@ -168,7 +168,7 @@ static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
     if (ret < 0)
         return ret;
     i440fx_update_memory_mappings(d);
-    qemu_get_8s(f, &smm_enabled);
+    qemu_get_8s(f, &d->smm_enabled);
 
     if (version_id >= 2)
         for (i = 0; i < 4; i++)
Signature · 1 line
1.6.2.5
#6 lore raw

PATCH v2 6/13 We want the argument pass to set_irq to be opaque

In reply to Juan Quintela

piix_pci want to pass more things that the pic

---
 hw/apb_pci.c       |    4 +++-
 hw/grackle_pci.c   |    4 +++-
 hw/gt64xxx.c       |    3 ++-
 hw/pci.c           |    6 +++---
 hw/pci.h           |    6 +++---
 hw/piix_pci.c      |    5 +++--
 hw/ppc4xx_pci.c    |    4 +++-
 hw/ppce500_pci.c   |    4 +++-
 hw/prep_pci.c      |    4 +++-
 hw/r2d.c           |    4 +++-
 hw/sh_pci.c        |    4 ++--
 hw/unin_pci.c      |    4 +++-
 hw/versatile_pci.c |    4 +++-
 13 files changed, 37 insertions(+), 19 deletions(-)
hw/apb_pci.c +3 -1
index 8b42fa8..869e230 100644
@@ -218,8 +218,10 @@ static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
     return bus_offset + irq_num;
 }
 
-static void pci_apb_set_irq(qemu_irq *pic, int irq_num, int level)
+static void pci_apb_set_irq(void *opaque, int irq_num, int level)
 {
+    qemu_irq *pic = opaque;
+
     /* PCI IRQ map onto the first 32 INO.  */
     qemu_set_irq(pic[irq_num], level);
 }
hw/grackle_pci.c +3 -1
index b893ebe..49cca56 100644
@@ -102,8 +102,10 @@ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num)
     return (irq_num + (pci_dev->devfn >> 3)) & 3;
 }
 
-static void pci_grackle_set_irq(qemu_irq *pic, int irq_num, int level)
+static void pci_grackle_set_irq(void *opaque, int irq_num, int level)
 {
+    qemu_irq *pic = opaque;
+
     GRACKLE_DPRINTF("set_irq num %d level %d\n", irq_num, level);
     qemu_set_irq(pic[irq_num + 0x15], level);
 }
hw/gt64xxx.c +2 -1
index 3b44fc9..6f982e9 100644
@@ -893,9 +893,10 @@ static int pci_gt64120_map_irq(PCIDevice *pci_dev, int irq_num)
 
 static int pci_irq_levels[4];
 
-static void pci_gt64120_set_irq(qemu_irq *pic, int irq_num, int level)
+static void pci_gt64120_set_irq(void *opaque, int irq_num, int level)
 {
     int i, pic_irq, pic_level;
+    qemu_irq *pic = opaque;
 
     pci_irq_levels[irq_num] = level;
 
hw/pci.c +3 -3
index e209ceb..c37a732 100644
@@ -41,7 +41,7 @@ struct PCIBus {
     pci_set_irq_fn set_irq;
     pci_map_irq_fn map_irq;
     uint32_t config_reg; /* XXX: suppress */
-    qemu_irq *irq_opaque;
+    void *irq_opaque;
     PCIDevice *devices[256];
     PCIDevice *parent_dev;
     PCIBus *next;
@@ -119,7 +119,7 @@ static void pci_bus_reset(void *opaque)
 
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         qemu_irq *pic, int devfn_min, int nirq)
+                         void *irq_opaque, int devfn_min, int nirq)
 {
     PCIBus *bus;
     static int nbus = 0;
@@ -127,7 +127,7 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
     bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, parent, name));
     bus->set_irq = set_irq;
     bus->map_irq = map_irq;
-    bus->irq_opaque = pic;
+    bus->irq_opaque = irq_opaque;
     bus->devfn_min = devfn_min;
     bus->nirq = nirq;
     bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
hw/pci.h +3 -3
index a2ec16a..10c9733 100644
@@ -237,11 +237,11 @@ void pci_default_write_config(PCIDevice *d,
 void pci_device_save(PCIDevice *s, QEMUFile *f);
 int pci_device_load(PCIDevice *s, QEMUFile *f);
 
-typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level);
+typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         qemu_irq *pic, int devfn_min, int nirq);
+                         void *irq_opaque, int devfn_min, int nirq);
 
 PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
                         const char *default_devaddr);
@@ -351,6 +351,6 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
 
 /* sh_pci.c */
 PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                            qemu_irq *pic, int devfn_min, int nirq);
+                            void *pic, int devfn_min, int nirq);
 
 #endif
hw/piix_pci.c +3 -2
index d8aeeec..4739604 100644
@@ -51,7 +51,7 @@ static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr)
     return s->config_reg;
 }
 
-static void piix3_set_irq(qemu_irq *pic, int irq_num, int level);
+static void piix3_set_irq(void *opaque, int irq_num, int level);
 
 /* return the global irq number corresponding to a given device irq
    pin. We could also use the bus number to have a more precise
@@ -231,9 +231,10 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, qemu_irq *pic)
 
 static PCIDevice *piix3_dev;
 
-static void piix3_set_irq(qemu_irq *pic, int irq_num, int level)
+static void piix3_set_irq(void *opaque, int irq_num, int level)
 {
     int i, pic_irq, pic_level;
+    qemu_irq *pic = opaque;
 
     pci_irq_levels[irq_num] = level;
 
hw/ppc4xx_pci.c +3 -1
index 077ae70..3295eba 100644
@@ -304,8 +304,10 @@ static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
     return slot - 1;
 }
 
-static void ppc4xx_pci_set_irq(qemu_irq *pci_irqs, int irq_num, int level)
+static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
 {
+    qemu_irq *pci_irqs = opaque;
+
     DPRINTF("%s: PCI irq %d\n", __func__, irq_num);
     qemu_set_irq(pci_irqs[irq_num], level);
 }
hw/ppce500_pci.c +3 -1
index 5b4673a..7cb1fd9 100644
@@ -253,8 +253,10 @@ static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
     return ret;
 }
 
-static void mpc85xx_pci_set_irq(qemu_irq *pic, int irq_num, int level)
+static void mpc85xx_pci_set_irq(void *opaque, int irq_num, int level)
 {
+    qemu_irq *pic = opaque;
+
     pci_debug("%s: PCI irq %d, level:%d\n", __func__, irq_num, level);
 
     qemu_set_irq(pic[irq_num], level);
hw/prep_pci.c +3 -1
index 80058b1..816c0cc 100644
@@ -124,8 +124,10 @@ static int prep_map_irq(PCIDevice *pci_dev, int irq_num)
     return (irq_num + (pci_dev->devfn >> 3)) & 1;
 }
 
-static void prep_set_irq(qemu_irq *pic, int irq_num, int level)
+static void prep_set_irq(void *opaque, int irq_num, int level)
 {
+    qemu_irq *pic = opaque;
+
     qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
 }
 
hw/r2d.c +3 -1
index 697bcb6..7e509da 100644
@@ -182,8 +182,10 @@ static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
     return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
 }
 
-static void r2d_pci_set_irq(qemu_irq *p, int n, int l)
+static void r2d_pci_set_irq(void *opaque, int n, int l)
 {
+    qemu_irq *p = opaque;
+
     qemu_set_irq(p[n], l);
 }
 
hw/sh_pci.c +2 -2
index 1b148ab..5f9b062 100644
@@ -168,14 +168,14 @@ static MemOp sh_pci_iop = {
 };
 
 PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                            qemu_irq *pic, int devfn_min, int nirq)
+                            void *opaque, int devfn_min, int nirq)
 {
     SHPCIC *p;
     int mem, reg, iop;
 
     p = qemu_mallocz(sizeof(SHPCIC));
     p->bus = pci_register_bus(NULL, "pci",
-                              set_irq, map_irq, pic, devfn_min, nirq);
+                              set_irq, map_irq, opaque, devfn_min, nirq);
 
     p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
                                  -1, NULL, NULL);
hw/unin_pci.c +3 -1
index 73944af..d2415da 100644
@@ -141,8 +141,10 @@ static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
     return (irq_num + (pci_dev->devfn >> 3)) & 3;
 }
 
-static void pci_unin_set_irq(qemu_irq *pic, int irq_num, int level)
+static void pci_unin_set_irq(void *opaque, int irq_num, int level)
 {
+    qemu_irq *pic = opaque;
+
     qemu_set_irq(pic[irq_num + 8], level);
 }
 
hw/versatile_pci.c +3 -1
index 5eb2625..fa1288c 100644
@@ -90,8 +90,10 @@ static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
     return irq_num;
 }
 
-static void pci_vpb_set_irq(qemu_irq *pic, int irq_num, int level)
+static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
 {
+    qemu_irq *pic = opaque;
+
     qemu_set_irq(pic[irq_num], level);
 }
 
Signature · 1 line
1.6.2.5
#7 lore raw

PATCH v2 7/13 Create PIIX3State instead of using PCIDevice for PIIX3

In reply to Juan Quintela
---
 hw/piix_pci.c |   23 ++++++++++++++---------
 1 files changed, 14 insertions(+), 9 deletions(-)
hw/piix_pci.c +14 -9
index 4739604..29bd92c 100644
@@ -33,6 +33,10 @@ typedef uint32_t pci_addr_t;
 
 typedef PCIHostState I440FXState;
 
+typedef struct PIIX3State {
+    PCIDevice dev;
+} PIIX3State;
+
 struct PCII440FXState {
     PCIDevice dev;
     target_phys_addr_t isa_page_descs[384 / 4];
@@ -229,7 +233,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, qemu_irq *pic)
 
 /* PIIX3 PCI to ISA bridge */
 
-static PCIDevice *piix3_dev;
+static PIIX3State *piix3_dev;
 
 static void piix3_set_irq(void *opaque, int irq_num, int level)
 {
@@ -240,13 +244,13 @@ static void piix3_set_irq(void *opaque, int irq_num, int level)
 
     /* now we change the pic irq level according to the piix irq mappings */
     /* XXX: optimize */
-    pic_irq = piix3_dev->config[0x60 + irq_num];
+    pic_irq = piix3_dev->dev.config[0x60 + irq_num];
     if (pic_irq < 16) {
         /* The pic level is the logical OR of all the PCI irqs mapped
            to it */
         pic_level = 0;
         for (i = 0; i < 4; i++) {
-            if (pic_irq == piix3_dev->config[0x60 + i])
+            if (pic_irq == piix3_dev->dev.config[0x60 + i])
                 pic_level |= pci_irq_levels[i];
         }
         qemu_set_irq(pic[pic_irq], pic_level);
@@ -255,8 +259,8 @@ static void piix3_set_irq(void *opaque, int irq_num, int level)
 
 static void piix3_reset(void *opaque)
 {
-    PCIDevice *d = opaque;
-    uint8_t *pci_conf = d->config;
+    PIIX3State *d = opaque;
+    uint8_t *pci_conf = d->dev.config;
 
     pci_conf[0x04] = 0x07; // master, memory and I/O
     pci_conf[0x05] = 0x00;
@@ -307,14 +311,15 @@ static int piix_load(QEMUFile* f, void *opaque, int version_id)
     return pci_device_load(d, f);
 }
 
-static void piix3_initfn(PCIDevice *d)
+static void piix3_initfn(PCIDevice *dev)
 {
+    PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev);
     uint8_t *pci_conf;
 
-    isa_bus_new(&d->qdev);
+    isa_bus_new(&d->dev.qdev);
     register_savevm("PIIX3", 0, 2, piix_save, piix_load, d);
 
-    pci_conf = d->config;
+    pci_conf = d->dev.config;
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_0); // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
     pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
@@ -345,7 +350,7 @@ static PCIDeviceInfo i440fx_info[] = {
     },{
         .qdev.name    = "PIIX3",
         .qdev.desc    = "ISA bridge",
-        .qdev.size    = sizeof(PCIDevice),
+        .qdev.size    = sizeof(PIIX3State),
         .qdev.no_user = 1,
         .init         = piix3_initfn,
     },{
Signature · 1 line
1.6.2.5
#8 lore raw

PATCH v2 8/13 Introduce PIIX3IrqState for piix3 irq's state

In reply to Juan Quintela
---
 hw/piix_pci.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
hw/piix_pci.c +9 -3
index 29bd92c..0443a1d 100644
@@ -37,6 +37,10 @@ typedef struct PIIX3State {
     PCIDevice dev;
 } PIIX3State;
 
+typedef struct PIIX3IrqState {
+    qemu_irq *pic;
+} PIIX3IrqState;
+
 struct PCII440FXState {
     PCIDevice dev;
     target_phys_addr_t isa_page_descs[384 / 4];
@@ -217,11 +221,13 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, qemu_irq *pic)
     PCIBus *b;
     PCIDevice *d;
     I440FXState *s;
+    PIIX3IrqState *irq_state = qemu_malloc(sizeof(*irq_state));
 
+    irq_state->pic = pic;
     dev = qdev_create(NULL, "i440FX-pcihost");
     s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
     b = pci_register_bus(&s->busdev.qdev, "pci.0",
-                         piix3_set_irq, pci_slot_get_pirq, pic, 0, 4);
+                         piix3_set_irq, pci_slot_get_pirq, irq_state, 0, 4);
     s->bus = b;
     qdev_init(dev);
 
@@ -238,7 +244,7 @@ static PIIX3State *piix3_dev;
 static void piix3_set_irq(void *opaque, int irq_num, int level)
 {
     int i, pic_irq, pic_level;
-    qemu_irq *pic = opaque;
+    PIIX3IrqState *irq_state = opaque;
 
     pci_irq_levels[irq_num] = level;
 
@@ -253,7 +259,7 @@ static void piix3_set_irq(void *opaque, int irq_num, int level)
             if (pic_irq == piix3_dev->dev.config[0x60 + i])
                 pic_level |= pci_irq_levels[i];
         }
-        qemu_set_irq(pic[pic_irq], pic_level);
+        qemu_set_irq(irq_state->pic[pic_irq], pic_level);
     }
 }
 
Signature · 1 line
1.6.2.5
#9 lore raw

PATCH v2 9/13 Fold piix3_init() into i440fx_init

In reply to Juan Quintela

i440fx_init will now work properly if we don't setup piix3

---
 hw/pc.c       |    3 +--
 hw/pc.h       |    3 +--
 hw/piix_pci.c |   18 ++++++------------
 3 files changed, 8 insertions(+), 16 deletions(-)
hw/pc.c +1 -2
index a908f8b..74b6829 100644
@@ -1268,8 +1268,7 @@ static void pc_init1(ram_addr_t ram_size,
     ferr_irq = i8259[13];
 
     if (pci_enabled) {
-        pci_bus = i440fx_init(&i440fx_state, i8259);
-        piix3_devfn = piix3_init(pci_bus, -1);
+        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, i8259);
     } else {
         pci_bus = NULL;
     }
hw/pc.h +1 -2
index 7733d1a..fd148fb 100644
@@ -122,9 +122,8 @@ int pcspk_audio_init(qemu_irq *pic);
 struct PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 
-PCIBus *i440fx_init(PCII440FXState **pi440fx_state, qemu_irq *pic);
+PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic);
 void i440fx_set_smm(PCII440FXState *d, int val);
-int piix3_init(PCIBus *bus, int devfn);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 
 /* piix4.c */
hw/piix_pci.c +6 -12
index 0443a1d..66aeb72 100644
@@ -215,7 +215,9 @@ static void i440fx_initfn(PCIDevice *dev)
     register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d);
 }
 
-PCIBus *i440fx_init(PCII440FXState **pi440fx_state, qemu_irq *pic)
+static PIIX3State *piix3_dev;
+
+PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic)
 {
     DeviceState *dev;
     PCIBus *b;
@@ -234,13 +236,14 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, qemu_irq *pic)
     d = pci_create_simple(b, 0, "i440FX");
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
 
+    piix3_dev = DO_UPCAST(PIIX3State, dev, pci_create_simple(b, -1, "PIIX3"));
+    *piix3_devfn = piix3_dev->dev.devfn;
+
     return b;
 }
 
 /* PIIX3 PCI to ISA bridge */
 
-static PIIX3State *piix3_dev;
-
 static void piix3_set_irq(void *opaque, int irq_num, int level)
 {
     int i, pic_irq, pic_level;
@@ -332,19 +335,10 @@ static void piix3_initfn(PCIDevice *dev)
     pci_conf[PCI_HEADER_TYPE] =
         PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic
 
-    piix3_dev = d;
     piix3_reset(d);
     qemu_register_reset(piix3_reset, d);
 }
 
-int piix3_init(PCIBus *bus, int devfn)
-{
-    PCIDevice *d;
-
-    d = pci_create_simple(bus, devfn, "PIIX3");
-    return d->devfn;
-}
-
 static PCIDeviceInfo i440fx_info[] = {
     {
         .qdev.name    = "i440FX",
Signature · 1 line
1.6.2.5
#10 lore raw

PATCH v2 10/13 We can add piix3_dev now to PIIX3IrqState

In reply to Juan Quintela
---
 hw/piix_pci.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)
hw/piix_pci.c +6 -6
index 66aeb72..d77c6e6 100644
@@ -38,6 +38,7 @@ typedef struct PIIX3State {
 } PIIX3State;
 
 typedef struct PIIX3IrqState {
+    PIIX3State *piix3;
     qemu_irq *pic;
 } PIIX3IrqState;
 
@@ -215,8 +216,6 @@ static void i440fx_initfn(PCIDevice *dev)
     register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d);
 }
 
-static PIIX3State *piix3_dev;
-
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic)
 {
     DeviceState *dev;
@@ -236,8 +235,9 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
     d = pci_create_simple(b, 0, "i440FX");
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
 
-    piix3_dev = DO_UPCAST(PIIX3State, dev, pci_create_simple(b, -1, "PIIX3"));
-    *piix3_devfn = piix3_dev->dev.devfn;
+    irq_state->piix3 = DO_UPCAST(PIIX3State, dev,
+                                 pci_create_simple(b, -1, "PIIX3"));
+    *piix3_devfn = irq_state->piix3->dev.devfn;
 
     return b;
 }
@@ -253,13 +253,13 @@ static void piix3_set_irq(void *opaque, int irq_num, int level)
 
     /* now we change the pic irq level according to the piix irq mappings */
     /* XXX: optimize */
-    pic_irq = piix3_dev->dev.config[0x60 + irq_num];
+    pic_irq = irq_state->piix3->dev.config[0x60 + irq_num];
     if (pic_irq < 16) {
         /* The pic level is the logical OR of all the PCI irqs mapped
            to it */
         pic_level = 0;
         for (i = 0; i < 4; i++) {
-            if (pic_irq == piix3_dev->dev.config[0x60 + i])
+            if (pic_irq == irq_state->piix3->dev.config[0x60 + i])
                 pic_level |= pci_irq_levels[i];
         }
         qemu_set_irq(irq_state->pic[pic_irq], pic_level);
Signature · 1 line
1.6.2.5
#11 lore raw

PATCH v2 11/13 Save irq_state into PCII440FXState

In reply to Juan Quintela
---
 hw/piix_pci.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
hw/piix_pci.c +2 -0
index d77c6e6..8e01a52 100644
@@ -46,6 +46,7 @@ struct PCII440FXState {
     PCIDevice dev;
     target_phys_addr_t isa_page_descs[384 / 4];
     uint8_t smm_enabled;
+    PIIX3IrqState *irq_state;
 };
 
 static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
@@ -234,6 +235,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
 
     d = pci_create_simple(b, 0, "i440FX");
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
+    (*pi440fx_state)->irq_state = irq_state;
 
     irq_state->piix3 = DO_UPCAST(PIIX3State, dev,
                                  pci_create_simple(b, -1, "PIIX3"));
Signature · 1 line
1.6.2.5
#12 lore raw

PATCH v2 12/13 pci_irq_levels[] belong to PIIX3State

In reply to Juan Quintela

With previous cleanups, now it is possible to put it where it belongs

---
 hw/piix_pci.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)
hw/piix_pci.c +6 -7
index 8e01a52..580c987 100644
@@ -35,6 +35,7 @@ typedef PCIHostState I440FXState;
 
 typedef struct PIIX3State {
     PCIDevice dev;
+    int pci_irq_levels[4];
 } PIIX3State;
 
 typedef struct PIIX3IrqState {
@@ -73,8 +74,6 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
     return (irq_num + slot_addend) & 3;
 }
 
-static int pci_irq_levels[4];
-
 static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r)
 {
     uint32_t addr;
@@ -164,7 +163,7 @@ static void i440fx_save(QEMUFile* f, void *opaque)
     qemu_put_8s(f, &d->smm_enabled);
 
     for (i = 0; i < 4; i++)
-        qemu_put_be32(f, pci_irq_levels[i]);
+        qemu_put_be32(f, d->irq_state->piix3->pci_irq_levels[i]);
 }
 
 static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
@@ -182,7 +181,7 @@ static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
 
     if (version_id >= 2)
         for (i = 0; i < 4; i++)
-            pci_irq_levels[i] = qemu_get_be32(f);
+            d->irq_state->piix3->pci_irq_levels[i] = qemu_get_be32(f);
 
     return 0;
 }
@@ -251,7 +250,7 @@ static void piix3_set_irq(void *opaque, int irq_num, int level)
     int i, pic_irq, pic_level;
     PIIX3IrqState *irq_state = opaque;
 
-    pci_irq_levels[irq_num] = level;
+    irq_state->piix3->pci_irq_levels[irq_num] = level;
 
     /* now we change the pic irq level according to the piix irq mappings */
     /* XXX: optimize */
@@ -262,7 +261,7 @@ static void piix3_set_irq(void *opaque, int irq_num, int level)
         pic_level = 0;
         for (i = 0; i < 4; i++) {
             if (pic_irq == irq_state->piix3->dev.config[0x60 + i])
-                pic_level |= pci_irq_levels[i];
+                pic_level |= irq_state->piix3->pci_irq_levels[i];
         }
         qemu_set_irq(irq_state->pic[pic_irq], pic_level);
     }
@@ -305,7 +304,7 @@ static void piix3_reset(void *opaque)
     pci_conf[0xac] = 0x00;
     pci_conf[0xae] = 0x00;
 
-    memset(pci_irq_levels, 0, sizeof(pci_irq_levels));
+    memset(d->pci_irq_levels, 0, sizeof(d->pci_irq_levels));
 }
 
 static void piix_save(QEMUFile* f, void *opaque)
Signature · 1 line
1.6.2.5
#13 lore raw

PATCH v2 13/13 Update SaveVM versions

In reply to Juan Quintela

Now that we have all fields belonging to a PCIDevice, save each field on the device that it belongs. This means moving pci_irq_levels from PCII440FXState to PIIX3State.
Old formats are loaded, but we only save on the new saner format.

---
 hw/piix_pci.c |   40 +++++++++++++++++++++++++---------------
 1 files changed, 25 insertions(+), 15 deletions(-)
hw/piix_pci.c +25 -15
index 580c987..49852e1 100644
@@ -157,13 +157,9 @@ static void i440fx_write_config(PCIDevice *dev,
 static void i440fx_save(QEMUFile* f, void *opaque)
 {
     PCII440FXState *d = opaque;
-    int i;
 
     pci_device_save(&d->dev, f);
     qemu_put_8s(f, &d->smm_enabled);
-
-    for (i = 0; i < 4; i++)
-        qemu_put_be32(f, d->irq_state->piix3->pci_irq_levels[i]);
 }
 
 static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
@@ -171,7 +167,7 @@ static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
     PCII440FXState *d = opaque;
     int ret, i;
 
-    if (version_id > 2)
+    if (version_id > 3)
         return -EINVAL;
     ret = pci_device_load(&d->dev, f);
     if (ret < 0)
@@ -179,7 +175,7 @@ static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
     i440fx_update_memory_mappings(d);
     qemu_get_8s(f, &d->smm_enabled);
 
-    if (version_id >= 2)
+    if (version_id == 2)
         for (i = 0; i < 4; i++)
             d->irq_state->piix3->pci_irq_levels[i] = qemu_get_be32(f);
 
@@ -213,7 +209,7 @@ static void i440fx_initfn(PCIDevice *dev)
 
     d->dev.config[0x72] = 0x02; /* SMRAM */
 
-    register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d);
+    register_savevm("I440FX", 0, 3, i440fx_save, i440fx_load, d);
 }
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic)
@@ -307,18 +303,32 @@ static void piix3_reset(void *opaque)
     memset(d->pci_irq_levels, 0, sizeof(d->pci_irq_levels));
 }
 
-static void piix_save(QEMUFile* f, void *opaque)
+static void piix3_save(QEMUFile* f, void *opaque)
 {
-    PCIDevice *d = opaque;
-    pci_device_save(d, f);
+    PIIX3State *d = opaque;
+    int i;
+
+    pci_device_save(&d->dev, f);
+
+    for (i = 0; i < 4; i++)
+        qemu_put_be32(f, d->pci_irq_levels[i]);
 }
 
-static int piix_load(QEMUFile* f, void *opaque, int version_id)
+static int piix3_load(QEMUFile* f, void *opaque, int version_id)
 {
-    PCIDevice *d = opaque;
-    if (version_id != 2)
+    PIIX3State *d = opaque;
+    int i, ret;
+
+    if (version_id > 3 || version_id < 2)
         return -EINVAL;
-    return pci_device_load(d, f);
+    ret = pci_device_load(&d->dev, f);
+    if (ret < 0)
+        return ret;
+    if (version_id >= 3) {
+        for (i = 0; i < 4; i++)
+            d->pci_irq_levels[i] = qemu_get_be32(f);
+    }
+    return 0;
 }
 
 static void piix3_initfn(PCIDevice *dev)
@@ -327,7 +337,7 @@ static void piix3_initfn(PCIDevice *dev)
     uint8_t *pci_conf;
 
     isa_bus_new(&d->dev.qdev);
-    register_savevm("PIIX3", 0, 2, piix_save, piix_load, d);
+    register_savevm("PIIX3", 0, 3, piix3_save, piix3_load, d);
 
     pci_conf = d->dev.config;
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
Signature · 1 line
1.6.2.5