From c4101c5340988caa68da87066a88d3871c8c4bf1 Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Mon, 14 Jun 2010 22:27:49 -0300
Subject: [PATCH 2/4] acpi_piix4: save gpe and pci hotplug slot status

RH-Author: Alex Williamson <alex.williamson@redhat.com>
Message-id: <20100614222741.11497.41064.stgit@localhost.localdomain>
Patchwork-id: 9911
O-Subject: [RHEL6.0 qemu-kvm PATCH] acpi_piix4: save gpe and pci hotplug slot
	status
Bugzilla: 598022
RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>

Bugzilla: 598022
Upstream status: qemu.git 4cf3e6f3d85492f20a773dd6c9068ab89ba24a18
RHEL: Modified to move gpe and pci0_status in PIIX4PMState to match upstream

PCI hotplug currently doesn't work after a migration because
we don't migrate the enable bits of the GPE state.  Pull hotplug
structs into vmstate.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---

 hw/acpi.c |  100 ++++++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 65 insertions(+), 35 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/acpi.c |  100 +++++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 65 insertions(+), 35 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index ec049a2..83bcc44 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -33,6 +33,22 @@
 
 #define ACPI_DBG_IO_ADDR  0xb044
 
+#define GPE_BASE 0xafe0
+#define PROC_BASE 0xaf00
+#define PCI_BASE 0xae00
+#define PCI_EJ_BASE 0xae08
+
+struct gpe_regs {
+    uint16_t sts; /* status */
+    uint16_t en;  /* enabled */
+    uint8_t cpus_sts[32];
+};
+
+struct pci_status {
+    uint32_t up;
+    uint32_t down;
+};
+
 typedef struct PIIX4PMState {
     PCIDevice dev;
     uint16_t pmsts;
@@ -52,6 +68,10 @@ typedef struct PIIX4PMState {
     uint8_t smb_data[32];
     uint8_t smb_index;
     qemu_irq irq;
+
+    /* for pci hotplug */
+    struct gpe_regs gpe;
+    struct pci_status pci0_status;
 } PIIX4PMState;
 
 #define RSM_STS (1 << 15)
@@ -451,9 +471,33 @@ static int vmstate_acpi_post_load(void *opaque, int version_id)
     return 0;
 }
 
+static const VMStateDescription vmstate_gpe = {
+    .name = "gpe",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT16(sts, struct gpe_regs),
+        VMSTATE_UINT16(en, struct gpe_regs),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_pci_status = {
+    .name = "pci_status",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT32(up, struct pci_status),
+        VMSTATE_UINT32(down, struct pci_status),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_acpi = {
     .name = "piix4_pm",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .post_load = vmstate_acpi_post_load,
@@ -466,6 +510,9 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_UINT8(apms, PIIX4PMState),
         VMSTATE_TIMER(tmr_timer, PIIX4PMState),
         VMSTATE_INT64(tmr_overflow_time, PIIX4PMState),
+        VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, struct gpe_regs),
+        VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
+                       struct pci_status),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -567,25 +614,6 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
     return s->smbus;
 }
 
-#define GPE_BASE 0xafe0
-#define PROC_BASE 0xaf00
-#define PCI_BASE 0xae00
-#define PCI_EJ_BASE 0xae08
-
-struct gpe_regs {
-    uint16_t sts; /* status */
-    uint16_t en;  /* enabled */
-    uint8_t cpus_sts[32];
-};
-
-struct pci_status {
-    uint32_t up;
-    uint32_t down;
-};
-
-static struct gpe_regs gpe;
-static struct pci_status pci0_status;
-
 static uint32_t gpe_read_val(uint16_t val, uint32_t addr)
 {
     if (addr & 1)
@@ -738,19 +766,21 @@ static int piix4_device_hotplug(PCIDevice *dev, int state);
 void piix4_acpi_system_hot_add_init(PCIBus *bus, const char *cpu_model)
 {
     int i = 0, cpus = smp_cpus;
+    struct gpe_regs *gpe = &pm_state->gpe;
+    struct pci_status *pci0_status = &pm_state->pci0_status;
 
     while (cpus > 0) {
-        gpe.cpus_sts[i++] = (cpus < 8) ? (1 << cpus) - 1 : 0xff;
+        gpe->cpus_sts[i++] = (cpus < 8) ? (1 << cpus) - 1 : 0xff;
         cpus -= 8;
     }
-    register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
-    register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, &gpe);
+    register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, gpe);
+    register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, gpe);
 
-    register_ioport_write(PROC_BASE, 32, 1, gpe_writeb, &gpe);
-    register_ioport_read(PROC_BASE, 32, 1,  gpe_readb, &gpe);
+    register_ioport_write(PROC_BASE, 32, 1, gpe_writeb, gpe);
+    register_ioport_read(PROC_BASE, 32, 1,  gpe_readb, gpe);
 
-    register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
-    register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, &pci0_status);
+    register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
+    register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, pci0_status);
 
     register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus);
     register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, bus);
@@ -787,10 +817,10 @@ void qemu_system_cpu_hot_add(int cpu, int state)
     }
 
     if (state)
-        enable_processor(&gpe, cpu);
+        enable_processor(&pm_state->gpe, cpu);
     else
-        disable_processor(&gpe, cpu);
-    if (gpe.en & 4) {
+        disable_processor(&pm_state->gpe, cpu);
+    if (pm_state->gpe.en & 4) {
         qemu_set_irq(pm_state->irq, 1);
         qemu_set_irq(pm_state->irq, 0);
     }
@@ -813,13 +843,13 @@ static int piix4_device_hotplug(PCIDevice *dev, int state)
 {
     int slot = PCI_SLOT(dev->devfn);
 
-    pci0_status.up = 0;
-    pci0_status.down = 0;
+    pm_state->pci0_status.up = 0;
+    pm_state->pci0_status.down = 0;
     if (state)
-        enable_device(&pci0_status, &gpe, slot);
+        enable_device(&pm_state->pci0_status, &pm_state->gpe, slot);
     else
-        disable_device(&pci0_status, &gpe, slot);
-    if (gpe.en & 2) {
+        disable_device(&pm_state->pci0_status, &pm_state->gpe, slot);
+    if (pm_state->gpe.en & 2) {
         qemu_set_irq(pm_state->irq, 1);
         qemu_set_irq(pm_state->irq, 0);
     }
-- 
1.7.0.3

