Index: ioemu/Makefile.target
===================================================================
--- ioemu.orig/Makefile.target	2007-05-03 15:06:42.000000000 +0100
+++ ioemu/Makefile.target	2007-05-03 15:07:21.000000000 +0100
@@ -358,6 +358,7 @@
 VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
 VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
 VL_OBJS+= usb-uhci.o
+VL_OBJS+= piix4acpi.o
 DEFINES += -DHAS_AUDIO
 endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
Index: ioemu/hw/pc.c
===================================================================
--- ioemu.orig/hw/pc.c	2007-05-03 15:06:42.000000000 +0100
+++ ioemu/hw/pc.c	2007-05-03 15:07:21.000000000 +0100
@@ -873,13 +873,19 @@
 
     cmos_init(ram_size, boot_device, bs_table);
 
+    /* using PIIX4 acpi model */
+    if (pci_enabled && acpi_enabled)
+        pci_piix4_acpi_init(pci_bus, piix3_devfn + 2);
+
     if (pci_enabled && usb_enabled) {
-        usb_uhci_init(pci_bus, piix3_devfn + 2);
+        usb_uhci_init(pci_bus, piix3_devfn + (acpi_enabled ? 3 : 2));
     }
 
+#ifndef CONFIG_DM
     if (pci_enabled && acpi_enabled) {
         piix4_pm_init(pci_bus, piix3_devfn + 3);
     }
+#endif /* !CONFIG_DM */
 
 #if 0
     /* ??? Need to figure out some way for the user to
@@ -902,8 +908,10 @@
     /* XXX: should be done in the Bochs BIOS */
     if (pci_enabled) {
         pci_bios_init();
+#ifndef CONFIG_DM
         if (acpi_enabled)
             acpi_bios_init();
+#endif /* !CONFIG_DM */
     }
 }
 
Index: ioemu/hw/piix4acpi.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ioemu/hw/piix4acpi.c	2007-05-03 15:07:31.000000000 +0100
@@ -0,0 +1,186 @@
+/*
+ * PIIX4 ACPI controller emulation
+ *
+ * Winston liwen Wang, winston.l.wang@intel.com
+ * Copyright (c) 2006 , Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "vl.h"
+#define FREQUENCE_PMTIMER  3753425
+/* acpi register bit define here  */
+
+/* PM1_STS 						*/
+#define TMROF_STS 	  (1 << 0)
+#define BM_STS 	  	  (1 << 4)
+#define GBL_STS 	  (1 << 5)
+#define PWRBTN_STS 	  (1 << 8)
+#define RTC_STS 	  (1 << 10)
+#define PRBTNOR_STS       (1 << 11)
+#define WAK_STS 	  (1 << 15)
+/* PM1_EN						*/
+#define TMROF_EN          (1 << 0)
+#define GBL_EN            (1 << 5)
+#define PWRBTN_EN         (1 << 8)
+#define RTC_EN   	  (1 << 10)
+/* PM1_CNT						*/
+#define SCI_EN            (1 << 0)
+#define GBL_RLS           (1 << 2)
+#define SLP_EN   	  (1 << 13)
+
+typedef struct AcpiDeviceState AcpiDeviceState;
+AcpiDeviceState *acpi_device_table;
+
+typedef struct PCIAcpiState {
+    PCIDevice dev;
+    uint16_t pm1_control; /* pm1a_ECNT_BLK */
+} PCIAcpiState;
+
+static inline void acpi_set_irq(PCIAcpiState *s)
+{
+/* no real SCI event need for now, so comment the following line out */
+/*  pic_set_irq(s->irq, 1); */
+    printf("acpi_set_irq: s->irq %x \n",s->irq);
+}
+
+static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIAcpiState *s = opaque;
+
+    s->pm1_control = (s->pm1_control & 0xff00) | (val & 0xff);
+/*  printf("acpiPm1Control_writeb \n addr %x val:%x\n", addr, val); */
+
+}
+
+static uint32_t acpiPm1Control_readb(void *opaque, uint32_t addr)
+{
+    PCIAcpiState *s = opaque;
+    uint32_t val;
+
+    /* Mask out the write-only bits */
+    val = s->pm1_control & ~(GBL_RLS|SLP_EN) & 0xff;
+/*    printf("acpiPm1Control_readb \n addr %x val:%x\n", addr, val); */
+
+    return val;
+}
+
+static void acpiPm1ControlP1_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIAcpiState *s = opaque;
+
+    s->pm1_control = (s->pm1_control & 0xff) | (val << 8);
+/*    printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
+
+} 
+
+static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
+{
+    PCIAcpiState *s = opaque;
+    uint32_t val;
+
+    /* Mask out the write-only bits */
+    val = (s->pm1_control & ~(GBL_RLS|SLP_EN)) >> 8;
+/*    printf("acpiPm1ControlP1_readb \n addr %x val:%x\n", addr, val); */
+
+    return val;
+}
+
+
+/* word access   */
+
+static void acpiPm1Control_writew(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIAcpiState *s = opaque;
+
+    s->pm1_control = val;
+/*    printf("acpiPm1Control_writew \n addr %x val:%x\n", addr, val); */
+
+} 
+
+static uint32_t acpiPm1Control_readw(void *opaque, uint32_t addr)
+{
+    PCIAcpiState *s = opaque;
+    uint32_t val;
+
+    /* Mask out the write-only bits */
+    val = s->pm1_control & ~(GBL_RLS|SLP_EN);
+/*    printf("acpiPm1Control_readw \n addr %x val:%x\n", addr, val);  */
+
+    return val;
+}
+
+
+static void acpi_map(PCIDevice *pci_dev, int region_num,
+                    uint32_t addr, uint32_t size, int type)
+{
+    PCIAcpiState *d = (PCIAcpiState *)pci_dev;
+
+    printf("register acpi io \n");
+
+    /* Byte access */
+    register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
+    register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d);
+    register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d);
+    register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);
+
+    /* Word access */
+    register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
+    register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
+}
+
+/* PIIX4 acpi pci configuration space, func 2 */
+void pci_piix4_acpi_init(PCIBus *bus, int devfn)
+{
+    PCIAcpiState *d;
+    uint8_t *pci_conf;
+
+    /* register a function 2 of PIIX4 */
+    d = (PCIAcpiState *)pci_register_device(
+        bus, "PIIX4 ACPI", sizeof(PCIAcpiState),
+        devfn, NULL, NULL);
+
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = 0x86;  /* Intel */
+    pci_conf[0x01] = 0x80;
+    pci_conf[0x02] = 0x13;
+    pci_conf[0x03] = 0x71;
+    pci_conf[0x08] = 0x01;  /* B0 stepping */
+    pci_conf[0x09] = 0x00;  /* base class */
+    pci_conf[0x0a] = 0x80;  /* Sub class */
+    pci_conf[0x0b] = 0x06;
+    pci_conf[0x0e] = 0x00;
+    pci_conf[0x3d] = 0x01;  /* Hardwired to PIRQA is used */
+
+
+    /* PMBA POWER MANAGEMENT BASE ADDRESS, hardcoded to 0x1f40 
+     * to make shutdown work for IPF, due to IPF Guest Firmware 
+     * will enumerate pci devices. 
+     *
+     * TODO:  if Guest Firmware or Guest OS will change this PMBA,
+     * More logic will be added.
+     */
+    pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
+    pci_conf[0x41] = 0x1f;
+    pci_conf[0x42] = 0x00;
+    pci_conf[0x43] = 0x00;
+    d->pm1_control = SCI_EN;
+
+    acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
+}
Index: ioemu/vl.c
===================================================================
--- ioemu.orig/vl.c	2007-05-03 15:06:42.000000000 +0100
+++ ioemu/vl.c	2007-05-03 15:07:21.000000000 +0100
@@ -157,7 +157,7 @@
 #else
 #define MAX_CPUS 1
 #endif
-int acpi_enabled = 1;
+int acpi_enabled = 0;
 int fd_bootchk = 1;
 
 extern int vcpus;
@@ -5415,6 +5415,7 @@
 #endif
            "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
 	   "-vnc display    start a VNC server on display\n"
+           "-acpi           disable or enable ACPI of HVM domain \n"
            "\n"
            "During emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"
@@ -5499,6 +5500,7 @@
 
     QEMU_OPTION_d,
     QEMU_OPTION_vcpus,
+    QEMU_OPTION_acpi,
 };
 
 typedef struct QEMUOption {
@@ -5581,6 +5583,7 @@
     
     { "d", HAS_ARG, QEMU_OPTION_d },
     { "vcpus", 1, QEMU_OPTION_vcpus },
+    { "acpi", 0, QEMU_OPTION_acpi },
     { NULL },
 };
 
@@ -6322,6 +6325,9 @@
                 vcpus = atoi(optarg);
                 fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
                 break;
+            case QEMU_OPTION_acpi:
+                acpi_enabled = 1;
+                break;
             }
         }
     }
Index: ioemu/vl.h
===================================================================
--- ioemu.orig/vl.h	2007-05-03 15:06:42.000000000 +0100
+++ ioemu/vl.h	2007-05-03 15:07:21.000000000 +0100
@@ -168,6 +168,7 @@
 extern int kqemu_allowed;
 extern int win2k_install_hack;
 extern int usb_enabled;
+extern int acpi_enabled;
 extern int smp_cpus;
 
 /* XXX: make it dynamic */
@@ -924,6 +925,9 @@
 void piix4_pm_init(PCIBus *bus, int devfn);
 void acpi_bios_init(void);
 
+/* piix4acpi.c */
+extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
+
 /* pc.c */
 extern QEMUMachine pc_machine;
 extern QEMUMachine isapc_machine;
Index: ioemu/hw/piix_pci.c
===================================================================
--- ioemu.orig/hw/piix_pci.c	2007-05-03 15:06:42.000000000 +0100
+++ ioemu/hw/piix_pci.c	2007-05-03 15:07:13.000000000 +0100
@@ -241,7 +241,7 @@
 static uint32_t pci_bios_io_addr;
 static uint32_t pci_bios_mem_addr;
 /* host irqs corresponding to PCI irqs A-D */
-static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
+static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
 
 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
 {
@@ -336,6 +336,18 @@
             pci_set_io_region_addr(d, 3, 0x374);
         }
         break;
+    case 0x0680:
+        if (vendor_id == 0x8086 && device_id == 0x7113) {
+            /*
+             * PIIX4 ACPI PM.
+             * Special device with special PCI config space. No ordinary BARs.
+             */
+            pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
+            pci_config_writew(d, 0x22, 0x0000);
+            pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
+            pci_config_writew(d, 0x3d, 0x0001);
+        }
+        break;
     case 0x0300:
         if (vendor_id != 0x1234)
             goto default_map;
