WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH V4 6/6] piix4acpi: change in ACPI to match the change

To: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH V4 6/6] piix4acpi: change in ACPI to match the change in the BIOS.
From: anthony.perard@xxxxxxxxxx
Date: Fri, 29 Oct 2010 16:39:40 +0100
Cc: anthony.perard@xxxxxxxxxx
Delivery-date: Fri, 29 Oct 2010 08:51:21 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1288366780-10174-1-git-send-email-anthony.perard@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1288366780-10174-1-git-send-email-anthony.perard@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
From: Anthony PERARD <anthony.perard@xxxxxxxxxx>

Some change have been introduced in the firmware to match QEMU's BIOS.
So this patch adds the new sleep state values and handle old and new
ACPI IOPort mapping.

QEMU-Xen uses new ioport by default, but if it's a saved state with old
firmware, it unmaps the new ioport and maps the old one.

Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
 hw/piix4acpi.c |   99 ++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
index 1efa77d..92e728e 100644
--- a/hw/piix4acpi.c
+++ b/hw/piix4acpi.c
@@ -52,9 +52,12 @@
 
 /* Sleep state type codes as defined by the \_Sx objects in the DSDT. */
 /* These must be kept in sync with the DSDT (hvmloader/acpi/dsdt.asl) */
-#define SLP_TYP_S4        (6 << 10)
-#define SLP_TYP_S3        (5 << 10)
-#define SLP_TYP_S5        (7 << 10)
+#define SLP_TYP_S4_OLD    (6 << 10)
+#define SLP_TYP_S3_OLD    (5 << 10)
+#define SLP_TYP_S5_OLD    (7 << 10)
+#define SLP_TYP_S4        (0 << 10)
+#define SLP_TYP_S3        (1 << 10)
+#define SLP_TYP_S5        (0 << 10)
 
 #define ACPI_DBG_IO_ADDR  0xb044
 #define ACPI_PHP_IO_ADDR  0x10c0
@@ -75,12 +78,15 @@
 typedef struct PCIAcpiState {
     PCIDevice dev;
     uint16_t pm1_control; /* pm1a_ECNT_BLK */
+
+    /* if true, use old ioport of the firmware. */
+    uint8_t use_old_ioport;
 } PCIAcpiState;
 
 typedef struct GPEState {
     /* GPE0 block */
-    uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN / 2];
-    uint8_t gpe0_en[ACPI_GPE0_BLK_LEN / 2];
+    uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN_OLD / 2];
+    uint8_t gpe0_en[ACPI_GPE0_BLK_LEN_OLD / 2];
 
     /* CPU bitmap */
     uint8_t cpus_sts[32];
@@ -88,6 +94,8 @@ typedef struct GPEState {
     /* SCI IRQ level */
     uint8_t sci_asserted;
 
+    /* if true, use old ioport of the firmware. */
+    uint8_t use_old_ioport;
 } GPEState;
 
 static GPEState gpe_state;
@@ -100,6 +108,9 @@ typedef struct PHPDevFn {
                                       * PSTB in ASL */
 } PHPDevFn;
 
+static void acpi_map(PCIDevice *pci_dev, int region_num,
+                     uint32_t addr, uint32_t size, int type);
+
 static PHPDevFn php_devfn;
 int s3_shutdown_flag;
 static qemu_irq sci_irq;
@@ -138,18 +149,36 @@ static void piix4acpi_save(QEMUFile *f, void *opaque)
     PCIAcpiState *s = opaque;
     pci_device_save(&s->dev, f);
     qemu_put_be16s(f, &s->pm1_control);
+    qemu_put_8s(f, &s->use_old_ioport);
 }
 
 static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id)
 {
     PCIAcpiState *s = opaque;
     int ret;
-    if (version_id > 1) 
+
+    if (version_id > 2)
         return -EINVAL;
     ret = pci_device_load(&s->dev, f);
     if (ret < 0)
         return ret;
     qemu_get_be16s(f, &s->pm1_control);
+
+    if (version_id <= 1) {
+        /* map to old ioport instead of the new one */
+        s->use_old_ioport = 1;
+    } else {
+        qemu_get_8s(f, &s->use_old_ioport);
+    }
+
+    if (s->use_old_ioport) {
+        PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "ACPI: Use old firmware 
IOPorts.\n");
+        /* unmap new ioport to use old ioport */
+        isa_unassign_ioport(ACPI_PM1A_EVT_BLK_ADDRESS + 4, 2);
+        acpi_map((PCIDevice *)s, 0, ACPI_PM1A_EVT_BLK_ADDRESS_OLD, 0x10, 
PCI_ADDRESS_SPACE_IO);
+    } else {
+        PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "ACPI: Keep new firmware 
IOPorts.\n");
+    }
     return 0;
 }
 
@@ -172,6 +201,7 @@ static void acpi_shutdown(uint32_t val)
         return;
 
     switch (val & SLP_TYP_Sx) {
+    case SLP_TYP_S3_OLD:
     case SLP_TYP_S3:
         s3_shutdown_flag = 1;
         qemu_system_reset();
@@ -179,7 +209,8 @@ static void acpi_shutdown(uint32_t val)
         cmos_set_s3_resume();
         xc_set_hvm_param(xc_handle, domid, HVM_PARAM_ACPI_S_STATE, 3);
         break;
-    case SLP_TYP_S4:
+    case SLP_TYP_S4_OLD:
+    case SLP_TYP_S5_OLD:
     case SLP_TYP_S5:
         qemu_system_shutdown_request();
         break;
@@ -403,7 +434,10 @@ static uint32_t gpe_sts_read(void *opaque, uint32_t addr)
 {
     GPEState *s = opaque;
 
-    return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS];
+    if (s->use_old_ioport)
+        return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS_OLD];
+    else
+        return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS];
 }
 
 /* write 1 to clear specific GPE bits */
@@ -415,7 +449,10 @@ static void gpe_sts_write(void *opaque, uint32_t addr, 
uint32_t val)
     PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "gpe_sts_write: addr=0x%x, 
val=0x%x.\n", addr, val);
 
     hotplugged = test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT);
-    s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val;
+    if (s->use_old_ioport)
+        s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS_OLD] &= ~val;
+    else
+        s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val;
     if ( s->sci_asserted &&
          hotplugged &&
          !test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT)) {
@@ -429,7 +466,10 @@ static uint32_t gpe_en_read(void *opaque, uint32_t addr)
 {
     GPEState *s = opaque;
 
-    return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2)];
+    if (s->use_old_ioport)
+        return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS_OLD + 
ACPI_GPE0_BLK_LEN_OLD / 2)];
+    else
+        return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 
2)];
 }
 
 /* write 0 to clear en bit */
@@ -439,7 +479,10 @@ static void gpe_en_write(void *opaque, uint32_t addr, 
uint32_t val)
     int reg_count;
 
     PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "gpe_en_write: addr=0x%x, val=0x%x.\n", 
addr, val);
-    reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2);
+    if (s->use_old_ioport)
+        reg_count = addr - (ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD 
/ 2);
+    else
+        reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2);
     s->gpe0_en[reg_count] = val;
     /* If disable GPE bit right after generating SCI on it, 
      * need deassert the intr to avoid redundant intrs
@@ -459,7 +502,7 @@ static void gpe_save(QEMUFile* f, void* opaque)
     GPEState *s = (GPEState*)opaque;
     int i;
 
-    for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) {
+    for ( i = 0; i < ACPI_GPE0_BLK_LEN_OLD / 2; i++ ) {
         qemu_put_8s(f, &s->gpe0_sts[i]);
         qemu_put_8s(f, &s->gpe0_en[i]);
     }
@@ -468,21 +511,43 @@ static void gpe_save(QEMUFile* f, void* opaque)
     if ( s->sci_asserted ) {
         PIIX4ACPI_LOG(PIIX4ACPI_LOG_INFO, "gpe_save with sci asserted!\n");
     }
+
+    qemu_put_8s(f, &s->use_old_ioport);
 }
 
 static int gpe_load(QEMUFile* f, void* opaque, int version_id)
 {
     GPEState *s = (GPEState*)opaque;
     int i;
-    if (version_id != 1)
+    if (version_id > 2)
         return -EINVAL;
 
-    for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) {
+    for ( i = 0; i < ACPI_GPE0_BLK_LEN_OLD / 2; i++ ) {
         qemu_get_8s(f, &s->gpe0_sts[i]);
         qemu_get_8s(f, &s->gpe0_en[i]);
     }
 
     qemu_get_8s(f, &s->sci_asserted);
+
+    if (version_id <= 1) {
+        s->use_old_ioport = 1;
+    } else {
+        qemu_get_8s(f, &s->use_old_ioport);
+    }
+
+    if (s->use_old_ioport) {
+        isa_unassign_ioport(ACPI_GPE0_BLK_ADDRESS, ACPI_GPE0_BLK_LEN);
+
+        register_ioport_read(ACPI_GPE0_BLK_ADDRESS_OLD, ACPI_GPE0_BLK_LEN_OLD 
/ 2,
+                             1, gpe_sts_read, s);
+        register_ioport_read(ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD 
/ 2,
+                             ACPI_GPE0_BLK_LEN_OLD / 2, 1, gpe_en_read, s);
+        register_ioport_write(ACPI_GPE0_BLK_ADDRESS_OLD, ACPI_GPE0_BLK_LEN_OLD 
/ 2,
+                              1, gpe_sts_write, s);
+        register_ioport_write(ACPI_GPE0_BLK_ADDRESS_OLD + 
ACPI_GPE0_BLK_LEN_OLD / 2,
+                              ACPI_GPE0_BLK_LEN_OLD / 2, 1, gpe_en_write, s);
+    }
+
     return 0;
 }
 
@@ -551,7 +616,7 @@ static void gpe_acpi_init(void)
                           gpe_en_write,
                           s);
 
-    register_savevm("gpe", 0, 1, gpe_save, gpe_load, s);
+    register_savevm("gpe", 0, 2, gpe_save, gpe_load, s);
 }
 
 #ifdef CONFIG_PASSTHROUGH
@@ -703,7 +768,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t 
smb_io_base,
     pci_conf[0x43] = 0x00;
     d->pm1_control = SCI_EN;
 
-    acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
+    acpi_map((PCIDevice *)d, 0, ACPI_PM1A_EVT_BLK_ADDRESS, 0x10, 
PCI_ADDRESS_SPACE_IO);
 
     gpe_acpi_init();
 #ifdef CONFIG_PASSTHROUGH
@@ -711,7 +776,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t 
smb_io_base,
 #endif
     register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, d);
 
-    register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d);
+    register_savevm("piix4acpi", 0, 2, piix4acpi_save, piix4acpi_load, d);
 
     return NULL;
 }
-- 
1.7.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel