cryptospore / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
0a122b
From 4d111d7b23baba92ce5a2f7deb7d33f4088d8342 Mon Sep 17 00:00:00 2001
0a122b
Message-Id: <4d111d7b23baba92ce5a2f7deb7d33f4088d8342.1387298827.git.minovotn@redhat.com>
0a122b
In-Reply-To: <3ed0fb61a3dc912ef036d7ef450bed192090709e.1387298827.git.minovotn@redhat.com>
0a122b
References: <3ed0fb61a3dc912ef036d7ef450bed192090709e.1387298827.git.minovotn@redhat.com>
0a122b
From: "Michael S. Tsirkin" <mst@redhat.com>
0a122b
Date: Tue, 17 Dec 2013 15:18:12 +0100
0a122b
Subject: [PATCH 32/56] i386: add ACPI table files from seabios
0a122b
0a122b
RH-Author: Michael S. Tsirkin <mst@redhat.com>
0a122b
Message-id: <1387293161-4085-33-git-send-email-mst@redhat.com>
0a122b
Patchwork-id: 56338
0a122b
O-Subject: [PATCH qemu-kvm RHEL7.0 v2 32/57] i386: add ACPI table files from seabios
0a122b
Bugzilla: 1034876
0a122b
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
0a122b
RH-Acked-by: Marcel Apfelbaum <marcel.a@redhat.com>
0a122b
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
0a122b
0a122b
This adds ASL code as well as scripts for processing it,
0a122b
imported from seabios git tree
0a122b
commit 51684b7ced75fb76776e8ee84833fcfb6ecf12dd
0a122b
0a122b
Will be used for runtime acpi table generation.
0a122b
0a122b
Note:
0a122b
This patch reuses some code from SeaBIOS, which was originally under
0a122b
LGPLv2 and then relicensed to GPLv3 or LGPLv3, in QEMU under GPLv2+. This
0a122b
relicensing has been acked by all contributors that had contributed to the
0a122b
code since the v2->v3 relicense. ACKs approving the v2+ relicensing are
0a122b
listed below. The list might include ACKs from people not holding
0a122b
copyright on any parts of the reused code, but it's better to err on the
0a122b
side of caution and include them.
0a122b
0a122b
Affected SeaBIOS files (GPLv2+ license headers added)
0a122b
<http://thread.gmane.org/gmane.comp.bios.coreboot.seabios/5949>:
0a122b
0a122b
 src/acpi-dsdt-cpu-hotplug.dsl
0a122b
 src/acpi-dsdt-dbug.dsl
0a122b
 src/acpi-dsdt-hpet.dsl
0a122b
 src/acpi-dsdt-isa.dsl
0a122b
 src/acpi-dsdt-pci-crs.dsl
0a122b
 src/acpi.c
0a122b
 src/acpi.h
0a122b
 src/ssdt-misc.dsl
0a122b
 src/ssdt-pcihp.dsl
0a122b
 src/ssdt-proc.dsl
0a122b
 tools/acpi_extract.py
0a122b
 tools/acpi_extract_preprocess.py
0a122b
0a122b
Each one of the listed people agreed to the following:
0a122b
0a122b
> If you allow the use of your contribution in QEMU under the
0a122b
> terms of GPLv2 or later as proposed by this patch,
0a122b
> please respond to this mail including the line:
0a122b
>
0a122b
> Acked-by: Name <email address>
0a122b
0a122b
  Acked-by: Gerd Hoffmann <kraxel@redhat.com>
0a122b
  Acked-by: Jan Kiszka <jan.kiszka@siemens.com>
0a122b
  Acked-by: Jason Baron <jbaron@akamai.com>
0a122b
  Acked-by: David Woodhouse <David.Woodhouse@intel.com>
0a122b
  Acked-by: Gleb Natapov <gleb@redhat.com>
0a122b
  Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
0a122b
  Acked-by: Dave Frodin <dave.frodin@se-eng.com>
0a122b
  Acked-by: Paolo Bonzini <pbonzini@redhat.com>
0a122b
  Acked-by: Kevin O'Connor <kevin@koconnor.net>
0a122b
  Acked-by: Laszlo Ersek <lersek@redhat.com>
0a122b
  Acked-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
0a122b
  Acked-by: Isaku Yamahata <yamahata@valinux.co.jp>
0a122b
  Acked-by: Magnus Christensson <magnus.christensson@intel.com>
0a122b
  Acked-by: Hu Tao <hutao@cn.fujitsu.com>
0a122b
  Acked-by: Eduardo Habkost <ehabkost@redhat.com>
0a122b
0a122b
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
0a122b
Reviewed-by: Hu Tao <hutao@cn.fujitsu.com>
0a122b
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
0a122b
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
0a122b
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
0a122b
Tested-by: Igor Mammedov <imammedo@redhat.com>
0a122b
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
0a122b
(cherry picked from commit 74523b850189afc23b608918c458b9242757f6d9)
0a122b
---
0a122b
 hw/i386/acpi-dsdt-cpu-hotplug.dsl  |  93 ++++++++
0a122b
 hw/i386/acpi-dsdt-dbug.dsl         |  41 ++++
0a122b
 hw/i386/acpi-dsdt-hpet.dsl         |  51 +++++
0a122b
 hw/i386/acpi-dsdt-isa.dsl          | 117 ++++++++++
0a122b
 hw/i386/acpi-dsdt-pci-crs.dsl      | 105 +++++++++
0a122b
 hw/i386/acpi-dsdt.dsl              | 343 ++++++++++++++++++++++++++++
0a122b
 hw/i386/q35-acpi-dsdt.dsl          | 452 +++++++++++++++++++++++++++++++++++++
0a122b
 hw/i386/ssdt-misc.dsl              | 119 ++++++++++
0a122b
 hw/i386/ssdt-pcihp.dsl             |  51 +++++
0a122b
 hw/i386/ssdt-proc.dsl              |  63 ++++++
0a122b
 scripts/acpi_extract.py            | 362 +++++++++++++++++++++++++++++
0a122b
 scripts/acpi_extract_preprocess.py |  51 +++++
0a122b
 12 files changed, 1848 insertions(+)
0a122b
 create mode 100644 hw/i386/acpi-dsdt-cpu-hotplug.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt-dbug.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt-hpet.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt-isa.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt-pci-crs.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt.dsl
0a122b
 create mode 100644 hw/i386/q35-acpi-dsdt.dsl
0a122b
 create mode 100644 hw/i386/ssdt-misc.dsl
0a122b
 create mode 100644 hw/i386/ssdt-pcihp.dsl
0a122b
 create mode 100644 hw/i386/ssdt-proc.dsl
0a122b
 create mode 100755 scripts/acpi_extract.py
0a122b
 create mode 100755 scripts/acpi_extract_preprocess.py
0a122b
0a122b
Signed-off-by: Michal Novotny <minovotn@redhat.com>
0a122b
---
0a122b
 hw/i386/acpi-dsdt-cpu-hotplug.dsl  |  93 ++++++++
0a122b
 hw/i386/acpi-dsdt-dbug.dsl         |  41 ++++
0a122b
 hw/i386/acpi-dsdt-hpet.dsl         |  51 +++++
0a122b
 hw/i386/acpi-dsdt-isa.dsl          | 117 ++++++++++
0a122b
 hw/i386/acpi-dsdt-pci-crs.dsl      | 105 +++++++++
0a122b
 hw/i386/acpi-dsdt.dsl              | 343 ++++++++++++++++++++++++++++
0a122b
 hw/i386/q35-acpi-dsdt.dsl          | 452 +++++++++++++++++++++++++++++++++++++
0a122b
 hw/i386/ssdt-misc.dsl              | 119 ++++++++++
0a122b
 hw/i386/ssdt-pcihp.dsl             |  51 +++++
0a122b
 hw/i386/ssdt-proc.dsl              |  63 ++++++
0a122b
 scripts/acpi_extract.py            | 362 +++++++++++++++++++++++++++++
0a122b
 scripts/acpi_extract_preprocess.py |  51 +++++
0a122b
 12 files changed, 1848 insertions(+)
0a122b
 create mode 100644 hw/i386/acpi-dsdt-cpu-hotplug.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt-dbug.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt-hpet.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt-isa.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt-pci-crs.dsl
0a122b
 create mode 100644 hw/i386/acpi-dsdt.dsl
0a122b
 create mode 100644 hw/i386/q35-acpi-dsdt.dsl
0a122b
 create mode 100644 hw/i386/ssdt-misc.dsl
0a122b
 create mode 100644 hw/i386/ssdt-pcihp.dsl
0a122b
 create mode 100644 hw/i386/ssdt-proc.dsl
0a122b
 create mode 100755 scripts/acpi_extract.py
0a122b
 create mode 100755 scripts/acpi_extract_preprocess.py
0a122b
0a122b
diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
0a122b
new file mode 100644
0a122b
index 0000000..c96ac42
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
0a122b
@@ -0,0 +1,93 @@
0a122b
+/*
0a122b
+ * This program is free software; you can redistribute it and/or modify
0a122b
+ * it under the terms of the GNU General Public License as published by
0a122b
+ * the Free Software Foundation; either version 2 of the License, or
0a122b
+ * (at your option) any later version.
0a122b
+
0a122b
+ * This program is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+ * GNU General Public License for more details.
0a122b
+
0a122b
+ * You should have received a copy of the GNU General Public License along
0a122b
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+ */
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * CPU hotplug
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+Scope(\_SB) {
0a122b
+    /* Objects filled in by run-time generated SSDT */
0a122b
+    External(NTFY, MethodObj)
0a122b
+    External(CPON, PkgObj)
0a122b
+
0a122b
+    /* Methods called by run-time generated SSDT Processor objects */
0a122b
+    Method(CPMA, 1, NotSerialized) {
0a122b
+        // _MAT method - create an madt apic buffer
0a122b
+        // Arg0 = Processor ID = Local APIC ID
0a122b
+        // Local0 = CPON flag for this cpu
0a122b
+        Store(DerefOf(Index(CPON, Arg0)), Local0)
0a122b
+        // Local1 = Buffer (in madt apic form) to return
0a122b
+        Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1)
0a122b
+        // Update the processor id, lapic id, and enable/disable status
0a122b
+        Store(Arg0, Index(Local1, 2))
0a122b
+        Store(Arg0, Index(Local1, 3))
0a122b
+        Store(Local0, Index(Local1, 4))
0a122b
+        Return (Local1)
0a122b
+    }
0a122b
+    Method(CPST, 1, NotSerialized) {
0a122b
+        // _STA method - return ON status of cpu
0a122b
+        // Arg0 = Processor ID = Local APIC ID
0a122b
+        // Local0 = CPON flag for this cpu
0a122b
+        Store(DerefOf(Index(CPON, Arg0)), Local0)
0a122b
+        If (Local0) {
0a122b
+            Return (0xF)
0a122b
+        } Else {
0a122b
+            Return (0x0)
0a122b
+        }
0a122b
+    }
0a122b
+    Method(CPEJ, 2, NotSerialized) {
0a122b
+        // _EJ0 method - eject callback
0a122b
+        Sleep(200)
0a122b
+    }
0a122b
+
0a122b
+    /* CPU hotplug notify method */
0a122b
+    OperationRegion(PRST, SystemIO, 0xaf00, 32)
0a122b
+    Field(PRST, ByteAcc, NoLock, Preserve) {
0a122b
+        PRS, 256
0a122b
+    }
0a122b
+    Method(PRSC, 0) {
0a122b
+        // Local5 = active cpu bitmap
0a122b
+        Store(PRS, Local5)
0a122b
+        // Local2 = last read byte from bitmap
0a122b
+        Store(Zero, Local2)
0a122b
+        // Local0 = Processor ID / APIC ID iterator
0a122b
+        Store(Zero, Local0)
0a122b
+        While (LLess(Local0, SizeOf(CPON))) {
0a122b
+            // Local1 = CPON flag for this cpu
0a122b
+            Store(DerefOf(Index(CPON, Local0)), Local1)
0a122b
+            If (And(Local0, 0x07)) {
0a122b
+                // Shift down previously read bitmap byte
0a122b
+                ShiftRight(Local2, 1, Local2)
0a122b
+            } Else {
0a122b
+                // Read next byte from cpu bitmap
0a122b
+                Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2)
0a122b
+            }
0a122b
+            // Local3 = active state for this cpu
0a122b
+            Store(And(Local2, 1), Local3)
0a122b
+
0a122b
+            If (LNotEqual(Local1, Local3)) {
0a122b
+                // State change - update CPON with new state
0a122b
+                Store(Local3, Index(CPON, Local0))
0a122b
+                // Do CPU notify
0a122b
+                If (LEqual(Local3, 1)) {
0a122b
+                    NTFY(Local0, 1)
0a122b
+                } Else {
0a122b
+                    NTFY(Local0, 3)
0a122b
+                }
0a122b
+            }
0a122b
+            Increment(Local0)
0a122b
+        }
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/acpi-dsdt-dbug.dsl b/hw/i386/acpi-dsdt-dbug.dsl
0a122b
new file mode 100644
0a122b
index 0000000..86230f7
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/acpi-dsdt-dbug.dsl
0a122b
@@ -0,0 +1,41 @@
0a122b
+/*
0a122b
+ * This program is free software; you can redistribute it and/or modify
0a122b
+ * it under the terms of the GNU General Public License as published by
0a122b
+ * the Free Software Foundation; either version 2 of the License, or
0a122b
+ * (at your option) any later version.
0a122b
+
0a122b
+ * This program is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+ * GNU General Public License for more details.
0a122b
+
0a122b
+ * You should have received a copy of the GNU General Public License along
0a122b
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+ */
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * Debugging
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+Scope(\) {
0a122b
+    /* Debug Output */
0a122b
+    OperationRegion(DBG, SystemIO, 0x0402, 0x01)
0a122b
+    Field(DBG, ByteAcc, NoLock, Preserve) {
0a122b
+        DBGB,   8,
0a122b
+    }
0a122b
+
0a122b
+    /* Debug method - use this method to send output to the QEMU
0a122b
+     * BIOS debug port.  This method handles strings, integers,
0a122b
+     * and buffers.  For example: DBUG("abc") DBUG(0x123) */
0a122b
+    Method(DBUG, 1) {
0a122b
+        ToHexString(Arg0, Local0)
0a122b
+        ToBuffer(Local0, Local0)
0a122b
+        Subtract(SizeOf(Local0), 1, Local1)
0a122b
+        Store(Zero, Local2)
0a122b
+        While (LLess(Local2, Local1)) {
0a122b
+            Store(DerefOf(Index(Local0, Local2)), DBGB)
0a122b
+            Increment(Local2)
0a122b
+        }
0a122b
+        Store(0x0A, DBGB)
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/acpi-dsdt-hpet.dsl b/hw/i386/acpi-dsdt-hpet.dsl
0a122b
new file mode 100644
0a122b
index 0000000..dfde174
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/acpi-dsdt-hpet.dsl
0a122b
@@ -0,0 +1,51 @@
0a122b
+/*
0a122b
+ * This program is free software; you can redistribute it and/or modify
0a122b
+ * it under the terms of the GNU General Public License as published by
0a122b
+ * the Free Software Foundation; either version 2 of the License, or
0a122b
+ * (at your option) any later version.
0a122b
+
0a122b
+ * This program is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+ * GNU General Public License for more details.
0a122b
+
0a122b
+ * You should have received a copy of the GNU General Public License along
0a122b
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+ */
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * HPET
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+Scope(\_SB) {
0a122b
+    Device(HPET) {
0a122b
+        Name(_HID, EISAID("PNP0103"))
0a122b
+        Name(_UID, 0)
0a122b
+        OperationRegion(HPTM, SystemMemory, 0xFED00000, 0x400)
0a122b
+        Field(HPTM, DWordAcc, Lock, Preserve) {
0a122b
+            VEND, 32,
0a122b
+            PRD, 32,
0a122b
+        }
0a122b
+        Method(_STA, 0, NotSerialized) {
0a122b
+            Store(VEND, Local0)
0a122b
+            Store(PRD, Local1)
0a122b
+            ShiftRight(Local0, 16, Local0)
0a122b
+            If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) {
0a122b
+                Return (0x0)
0a122b
+            }
0a122b
+            If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) {
0a122b
+                Return (0x0)
0a122b
+            }
0a122b
+            Return (0x0F)
0a122b
+        }
0a122b
+        Name(_CRS, ResourceTemplate() {
0a122b
+#if 0       /* This makes WinXP BSOD for not yet figured reasons. */
0a122b
+            IRQNoFlags() {2, 8}
0a122b
+#endif
0a122b
+            Memory32Fixed(ReadOnly,
0a122b
+                0xFED00000,         // Address Base
0a122b
+                0x00000400,         // Address Length
0a122b
+                )
0a122b
+        })
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl
0a122b
new file mode 100644
0a122b
index 0000000..89caa16
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/acpi-dsdt-isa.dsl
0a122b
@@ -0,0 +1,117 @@
0a122b
+/*
0a122b
+ * This program is free software; you can redistribute it and/or modify
0a122b
+ * it under the terms of the GNU General Public License as published by
0a122b
+ * the Free Software Foundation; either version 2 of the License, or
0a122b
+ * (at your option) any later version.
0a122b
+
0a122b
+ * This program is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+ * GNU General Public License for more details.
0a122b
+
0a122b
+ * You should have received a copy of the GNU General Public License along
0a122b
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+ */
0a122b
+
0a122b
+/* Common legacy ISA style devices. */
0a122b
+Scope(\_SB.PCI0.ISA) {
0a122b
+
0a122b
+    Device(RTC) {
0a122b
+        Name(_HID, EisaId("PNP0B00"))
0a122b
+        Name(_CRS, ResourceTemplate() {
0a122b
+            IO(Decode16, 0x0070, 0x0070, 0x10, 0x02)
0a122b
+            IRQNoFlags() { 8 }
0a122b
+            IO(Decode16, 0x0072, 0x0072, 0x02, 0x06)
0a122b
+        })
0a122b
+    }
0a122b
+
0a122b
+    Device(KBD) {
0a122b
+        Name(_HID, EisaId("PNP0303"))
0a122b
+        Method(_STA, 0, NotSerialized) {
0a122b
+            Return (0x0f)
0a122b
+        }
0a122b
+        Name(_CRS, ResourceTemplate() {
0a122b
+            IO(Decode16, 0x0060, 0x0060, 0x01, 0x01)
0a122b
+            IO(Decode16, 0x0064, 0x0064, 0x01, 0x01)
0a122b
+            IRQNoFlags() { 1 }
0a122b
+        })
0a122b
+    }
0a122b
+
0a122b
+    Device(MOU) {
0a122b
+        Name(_HID, EisaId("PNP0F13"))
0a122b
+        Method(_STA, 0, NotSerialized) {
0a122b
+            Return (0x0f)
0a122b
+        }
0a122b
+        Name(_CRS, ResourceTemplate() {
0a122b
+            IRQNoFlags() { 12 }
0a122b
+        })
0a122b
+    }
0a122b
+
0a122b
+    Device(FDC0) {
0a122b
+        Name(_HID, EisaId("PNP0700"))
0a122b
+        Method(_STA, 0, NotSerialized) {
0a122b
+            Store(FDEN, Local0)
0a122b
+            If (LEqual(Local0, 0)) {
0a122b
+                Return (0x00)
0a122b
+            } Else {
0a122b
+                Return (0x0F)
0a122b
+            }
0a122b
+        }
0a122b
+        Name(_CRS, ResourceTemplate() {
0a122b
+            IO(Decode16, 0x03F2, 0x03F2, 0x00, 0x04)
0a122b
+            IO(Decode16, 0x03F7, 0x03F7, 0x00, 0x01)
0a122b
+            IRQNoFlags() { 6 }
0a122b
+            DMA(Compatibility, NotBusMaster, Transfer8) { 2 }
0a122b
+        })
0a122b
+    }
0a122b
+
0a122b
+    Device(LPT) {
0a122b
+        Name(_HID, EisaId("PNP0400"))
0a122b
+        Method(_STA, 0, NotSerialized) {
0a122b
+            Store(LPEN, Local0)
0a122b
+            If (LEqual(Local0, 0)) {
0a122b
+                Return (0x00)
0a122b
+            } Else {
0a122b
+                Return (0x0F)
0a122b
+            }
0a122b
+        }
0a122b
+        Name(_CRS, ResourceTemplate() {
0a122b
+            IO(Decode16, 0x0378, 0x0378, 0x08, 0x08)
0a122b
+            IRQNoFlags() { 7 }
0a122b
+        })
0a122b
+    }
0a122b
+
0a122b
+    Device(COM1) {
0a122b
+        Name(_HID, EisaId("PNP0501"))
0a122b
+        Name(_UID, 0x01)
0a122b
+        Method(_STA, 0, NotSerialized) {
0a122b
+            Store(CAEN, Local0)
0a122b
+            If (LEqual(Local0, 0)) {
0a122b
+                Return (0x00)
0a122b
+            } Else {
0a122b
+                Return (0x0F)
0a122b
+            }
0a122b
+        }
0a122b
+        Name(_CRS, ResourceTemplate() {
0a122b
+            IO(Decode16, 0x03F8, 0x03F8, 0x00, 0x08)
0a122b
+            IRQNoFlags() { 4 }
0a122b
+        })
0a122b
+    }
0a122b
+
0a122b
+    Device(COM2) {
0a122b
+        Name(_HID, EisaId("PNP0501"))
0a122b
+        Name(_UID, 0x02)
0a122b
+        Method(_STA, 0, NotSerialized) {
0a122b
+            Store(CBEN, Local0)
0a122b
+            If (LEqual(Local0, 0)) {
0a122b
+                Return (0x00)
0a122b
+            } Else {
0a122b
+                Return (0x0F)
0a122b
+            }
0a122b
+        }
0a122b
+        Name(_CRS, ResourceTemplate() {
0a122b
+            IO(Decode16, 0x02F8, 0x02F8, 0x00, 0x08)
0a122b
+            IRQNoFlags() { 3 }
0a122b
+        })
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/acpi-dsdt-pci-crs.dsl b/hw/i386/acpi-dsdt-pci-crs.dsl
0a122b
new file mode 100644
0a122b
index 0000000..b375a19
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/acpi-dsdt-pci-crs.dsl
0a122b
@@ -0,0 +1,105 @@
0a122b
+/*
0a122b
+ * This program is free software; you can redistribute it and/or modify
0a122b
+ * it under the terms of the GNU General Public License as published by
0a122b
+ * the Free Software Foundation; either version 2 of the License, or
0a122b
+ * (at your option) any later version.
0a122b
+
0a122b
+ * This program is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+ * GNU General Public License for more details.
0a122b
+
0a122b
+ * You should have received a copy of the GNU General Public License along
0a122b
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+ */
0a122b
+
0a122b
+/* PCI CRS (current resources) definition. */
0a122b
+Scope(\_SB.PCI0) {
0a122b
+
0a122b
+    Name(CRES, ResourceTemplate() {
0a122b
+        WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
0a122b
+            0x0000,             // Address Space Granularity
0a122b
+            0x0000,             // Address Range Minimum
0a122b
+            0x00FF,             // Address Range Maximum
0a122b
+            0x0000,             // Address Translation Offset
0a122b
+            0x0100,             // Address Length
0a122b
+            ,, )
0a122b
+        IO(Decode16,
0a122b
+            0x0CF8,             // Address Range Minimum
0a122b
+            0x0CF8,             // Address Range Maximum
0a122b
+            0x01,               // Address Alignment
0a122b
+            0x08,               // Address Length
0a122b
+            )
0a122b
+        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0a122b
+            0x0000,             // Address Space Granularity
0a122b
+            0x0000,             // Address Range Minimum
0a122b
+            0x0CF7,             // Address Range Maximum
0a122b
+            0x0000,             // Address Translation Offset
0a122b
+            0x0CF8,             // Address Length
0a122b
+            ,, , TypeStatic)
0a122b
+        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0a122b
+            0x0000,             // Address Space Granularity
0a122b
+            0x0D00,             // Address Range Minimum
0a122b
+            0xFFFF,             // Address Range Maximum
0a122b
+            0x0000,             // Address Translation Offset
0a122b
+            0xF300,             // Address Length
0a122b
+            ,, , TypeStatic)
0a122b
+        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0a122b
+            0x00000000,         // Address Space Granularity
0a122b
+            0x000A0000,         // Address Range Minimum
0a122b
+            0x000BFFFF,         // Address Range Maximum
0a122b
+            0x00000000,         // Address Translation Offset
0a122b
+            0x00020000,         // Address Length
0a122b
+            ,, , AddressRangeMemory, TypeStatic)
0a122b
+        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
0a122b
+            0x00000000,         // Address Space Granularity
0a122b
+            0xE0000000,         // Address Range Minimum
0a122b
+            0xFEBFFFFF,         // Address Range Maximum
0a122b
+            0x00000000,         // Address Translation Offset
0a122b
+            0x1EC00000,         // Address Length
0a122b
+            ,, PW32, AddressRangeMemory, TypeStatic)
0a122b
+    })
0a122b
+
0a122b
+    Name(CR64, ResourceTemplate() {
0a122b
+        QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0a122b
+            0x00000000,          // Address Space Granularity
0a122b
+            0x8000000000,        // Address Range Minimum
0a122b
+            0xFFFFFFFFFF,        // Address Range Maximum
0a122b
+            0x00000000,          // Address Translation Offset
0a122b
+            0x8000000000,        // Address Length
0a122b
+            ,, PW64, AddressRangeMemory, TypeStatic)
0a122b
+    })
0a122b
+
0a122b
+    Method(_CRS, 0) {
0a122b
+        /* Fields provided by dynamically created ssdt */
0a122b
+        External(P0S, IntObj)
0a122b
+        External(P0E, IntObj)
0a122b
+        External(P1V, IntObj)
0a122b
+        External(P1S, BuffObj)
0a122b
+        External(P1E, BuffObj)
0a122b
+        External(P1L, BuffObj)
0a122b
+
0a122b
+        /* fixup 32bit pci io window */
0a122b
+        CreateDWordField(CRES, \_SB.PCI0.PW32._MIN, PS32)
0a122b
+        CreateDWordField(CRES, \_SB.PCI0.PW32._MAX, PE32)
0a122b
+        CreateDWordField(CRES, \_SB.PCI0.PW32._LEN, PL32)
0a122b
+        Store(P0S, PS32)
0a122b
+        Store(P0E, PE32)
0a122b
+        Store(Add(Subtract(P0E, P0S), 1), PL32)
0a122b
+
0a122b
+        If (LEqual(P1V, Zero)) {
0a122b
+            Return (CRES)
0a122b
+        }
0a122b
+
0a122b
+        /* fixup 64bit pci io window */
0a122b
+        CreateQWordField(CR64, \_SB.PCI0.PW64._MIN, PS64)
0a122b
+        CreateQWordField(CR64, \_SB.PCI0.PW64._MAX, PE64)
0a122b
+        CreateQWordField(CR64, \_SB.PCI0.PW64._LEN, PL64)
0a122b
+        Store(P1S, PS64)
0a122b
+        Store(P1E, PE64)
0a122b
+        Store(P1L, PL64)
0a122b
+        /* add window and return result */
0a122b
+        ConcatenateResTemplate(CRES, CR64, Local0)
0a122b
+        Return (Local0)
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
0a122b
new file mode 100644
0a122b
index 0000000..90efce0
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/acpi-dsdt.dsl
0a122b
@@ -0,0 +1,343 @@
0a122b
+/*
0a122b
+ * Bochs/QEMU ACPI DSDT ASL definition
0a122b
+ *
0a122b
+ * Copyright (c) 2006 Fabrice Bellard
0a122b
+ *
0a122b
+ * This library is free software; you can redistribute it and/or
0a122b
+ * modify it under the terms of the GNU Lesser General Public
0a122b
+ * License version 2 as published by the Free Software Foundation.
0a122b
+ *
0a122b
+ * This library is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0a122b
+ * Lesser General Public License for more details.
0a122b
+ *
0a122b
+ * You should have received a copy of the GNU Lesser General Public
0a122b
+ * License along with this library; if not, write to the Free Software
0a122b
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0a122b
+ */
0a122b
+
0a122b
+ACPI_EXTRACT_ALL_CODE AcpiDsdtAmlCode
0a122b
+
0a122b
+DefinitionBlock (
0a122b
+    "acpi-dsdt.aml",    // Output Filename
0a122b
+    "DSDT",             // Signature
0a122b
+    0x01,               // DSDT Compliance Revision
0a122b
+    "BXPC",             // OEMID
0a122b
+    "BXDSDT",           // TABLE ID
0a122b
+    0x1                 // OEM Revision
0a122b
+    )
0a122b
+{
0a122b
+
0a122b
+#include "acpi-dsdt-dbug.dsl"
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PCI Bus definition
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB) {
0a122b
+        Device(PCI0) {
0a122b
+            Name(_HID, EisaId("PNP0A03"))
0a122b
+            Name(_ADR, 0x00)
0a122b
+            Name(_UID, 1)
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+#include "acpi-dsdt-pci-crs.dsl"
0a122b
+#include "acpi-dsdt-hpet.dsl"
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * VGA
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB.PCI0) {
0a122b
+        Device(VGA) {
0a122b
+            Name(_ADR, 0x00020000)
0a122b
+            OperationRegion(PCIC, PCI_Config, Zero, 0x4)
0a122b
+            Field(PCIC, DWordAcc, NoLock, Preserve) {
0a122b
+                VEND, 32
0a122b
+            }
0a122b
+            Method(_S1D, 0, NotSerialized) {
0a122b
+                Return (0x00)
0a122b
+            }
0a122b
+            Method(_S2D, 0, NotSerialized) {
0a122b
+                Return (0x00)
0a122b
+            }
0a122b
+            Method(_S3D, 0, NotSerialized) {
0a122b
+                If (LEqual(VEND, 0x1001b36)) {
0a122b
+                    Return (0x03)           // QXL
0a122b
+                } Else {
0a122b
+                    Return (0x00)
0a122b
+                }
0a122b
+            }
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PIIX4 PM
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB.PCI0) {
0a122b
+        Device(PX13) {
0a122b
+            Name(_ADR, 0x00010003)
0a122b
+            OperationRegion(P13C, PCI_Config, 0x00, 0xff)
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PIIX3 ISA bridge
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB.PCI0) {
0a122b
+        Device(ISA) {
0a122b
+            Name(_ADR, 0x00010000)
0a122b
+
0a122b
+            /* PIIX PCI to ISA irq remapping */
0a122b
+            OperationRegion(P40C, PCI_Config, 0x60, 0x04)
0a122b
+
0a122b
+            /* enable bits */
0a122b
+            Field(\_SB.PCI0.PX13.P13C, AnyAcc, NoLock, Preserve) {
0a122b
+                Offset(0x5f),
0a122b
+                , 7,
0a122b
+                LPEN, 1,         // LPT
0a122b
+                Offset(0x67),
0a122b
+                , 3,
0a122b
+                CAEN, 1,         // COM1
0a122b
+                , 3,
0a122b
+                CBEN, 1,         // COM2
0a122b
+            }
0a122b
+            Name(FDEN, 1)
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+#include "acpi-dsdt-isa.dsl"
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PCI hotplug
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB.PCI0) {
0a122b
+        OperationRegion(PCST, SystemIO, 0xae00, 0x08)
0a122b
+        Field(PCST, DWordAcc, NoLock, WriteAsZeros) {
0a122b
+            PCIU, 32,
0a122b
+            PCID, 32,
0a122b
+        }
0a122b
+
0a122b
+        OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
0a122b
+        Field(SEJ, DWordAcc, NoLock, WriteAsZeros) {
0a122b
+            B0EJ, 32,
0a122b
+        }
0a122b
+
0a122b
+        /* Methods called by bulk generated PCI devices below */
0a122b
+
0a122b
+        /* Methods called by hotplug devices */
0a122b
+        Method(PCEJ, 1, NotSerialized) {
0a122b
+            // _EJ0 method - eject callback
0a122b
+            Store(ShiftLeft(1, Arg0), B0EJ)
0a122b
+            Return (0x0)
0a122b
+        }
0a122b
+
0a122b
+        /* Hotplug notification method supplied by SSDT */
0a122b
+        External(\_SB.PCI0.PCNT, MethodObj)
0a122b
+
0a122b
+        /* PCI hotplug notify method */
0a122b
+        Method(PCNF, 0) {
0a122b
+            // Local0 = iterator
0a122b
+            Store(Zero, Local0)
0a122b
+            While (LLess(Local0, 31)) {
0a122b
+                Increment(Local0)
0a122b
+                If (And(PCIU, ShiftLeft(1, Local0))) {
0a122b
+                    PCNT(Local0, 1)
0a122b
+                }
0a122b
+                If (And(PCID, ShiftLeft(1, Local0))) {
0a122b
+                    PCNT(Local0, 3)
0a122b
+                }
0a122b
+            }
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PCI IRQs
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB) {
0a122b
+        Scope(PCI0) {
0a122b
+            Name(_PRT, Package() {
0a122b
+                /* PCI IRQ routing table, example from ACPI 2.0a specification,
0a122b
+                   section 6.2.8.1 */
0a122b
+                /* Note: we provide the same info as the PCI routing
0a122b
+                   table of the Bochs BIOS */
0a122b
+
0a122b
+#define prt_slot(nr, lnk0, lnk1, lnk2, lnk3) \
0a122b
+    Package() { nr##ffff, 0, lnk0, 0 }, \
0a122b
+    Package() { nr##ffff, 1, lnk1, 0 }, \
0a122b
+    Package() { nr##ffff, 2, lnk2, 0 }, \
0a122b
+    Package() { nr##ffff, 3, lnk3, 0 }
0a122b
+
0a122b
+#define prt_slot0(nr) prt_slot(nr, LNKD, LNKA, LNKB, LNKC)
0a122b
+#define prt_slot1(nr) prt_slot(nr, LNKA, LNKB, LNKC, LNKD)
0a122b
+#define prt_slot2(nr) prt_slot(nr, LNKB, LNKC, LNKD, LNKA)
0a122b
+#define prt_slot3(nr) prt_slot(nr, LNKC, LNKD, LNKA, LNKB)
0a122b
+
0a122b
+                prt_slot0(0x0000),
0a122b
+                /* Device 1 is power mgmt device, and can only use irq 9 */
0a122b
+                prt_slot(0x0001, LNKS, LNKB, LNKC, LNKD),
0a122b
+                prt_slot2(0x0002),
0a122b
+                prt_slot3(0x0003),
0a122b
+                prt_slot0(0x0004),
0a122b
+                prt_slot1(0x0005),
0a122b
+                prt_slot2(0x0006),
0a122b
+                prt_slot3(0x0007),
0a122b
+                prt_slot0(0x0008),
0a122b
+                prt_slot1(0x0009),
0a122b
+                prt_slot2(0x000a),
0a122b
+                prt_slot3(0x000b),
0a122b
+                prt_slot0(0x000c),
0a122b
+                prt_slot1(0x000d),
0a122b
+                prt_slot2(0x000e),
0a122b
+                prt_slot3(0x000f),
0a122b
+                prt_slot0(0x0010),
0a122b
+                prt_slot1(0x0011),
0a122b
+                prt_slot2(0x0012),
0a122b
+                prt_slot3(0x0013),
0a122b
+                prt_slot0(0x0014),
0a122b
+                prt_slot1(0x0015),
0a122b
+                prt_slot2(0x0016),
0a122b
+                prt_slot3(0x0017),
0a122b
+                prt_slot0(0x0018),
0a122b
+                prt_slot1(0x0019),
0a122b
+                prt_slot2(0x001a),
0a122b
+                prt_slot3(0x001b),
0a122b
+                prt_slot0(0x001c),
0a122b
+                prt_slot1(0x001d),
0a122b
+                prt_slot2(0x001e),
0a122b
+                prt_slot3(0x001f),
0a122b
+            })
0a122b
+        }
0a122b
+
0a122b
+        Field(PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) {
0a122b
+            PRQ0,   8,
0a122b
+            PRQ1,   8,
0a122b
+            PRQ2,   8,
0a122b
+            PRQ3,   8
0a122b
+        }
0a122b
+
0a122b
+        Method(IQST, 1, NotSerialized) {
0a122b
+            // _STA method - get status
0a122b
+            If (And(0x80, Arg0)) {
0a122b
+                Return (0x09)
0a122b
+            }
0a122b
+            Return (0x0B)
0a122b
+        }
0a122b
+        Method(IQCR, 1, NotSerialized) {
0a122b
+            // _CRS method - get current settings
0a122b
+            Name(PRR0, ResourceTemplate() {
0a122b
+                Interrupt(, Level, ActiveHigh, Shared) { 0 }
0a122b
+            })
0a122b
+            CreateDWordField(PRR0, 0x05, PRRI)
0a122b
+            If (LLess(Arg0, 0x80)) {
0a122b
+                Store(Arg0, PRRI)
0a122b
+            }
0a122b
+            Return (PRR0)
0a122b
+        }
0a122b
+
0a122b
+#define define_link(link, uid, reg)                             \
0a122b
+        Device(link) {                                          \
0a122b
+            Name(_HID, EISAID("PNP0C0F"))                       \
0a122b
+            Name(_UID, uid)                                     \
0a122b
+            Name(_PRS, ResourceTemplate() {                     \
0a122b
+                Interrupt(, Level, ActiveHigh, Shared) {        \
0a122b
+                    5, 10, 11                                   \
0a122b
+                }                                               \
0a122b
+            })                                                  \
0a122b
+            Method(_STA, 0, NotSerialized) {                    \
0a122b
+                Return (IQST(reg))                              \
0a122b
+            }                                                   \
0a122b
+            Method(_DIS, 0, NotSerialized) {                    \
0a122b
+                Or(reg, 0x80, reg)                              \
0a122b
+            }                                                   \
0a122b
+            Method(_CRS, 0, NotSerialized) {                    \
0a122b
+                Return (IQCR(reg))                              \
0a122b
+            }                                                   \
0a122b
+            Method(_SRS, 1, NotSerialized) {                    \
0a122b
+                CreateDWordField(Arg0, 0x05, PRRI)              \
0a122b
+                Store(PRRI, reg)                                \
0a122b
+            }                                                   \
0a122b
+        }
0a122b
+
0a122b
+        define_link(LNKA, 0, PRQ0)
0a122b
+        define_link(LNKB, 1, PRQ1)
0a122b
+        define_link(LNKC, 2, PRQ2)
0a122b
+        define_link(LNKD, 3, PRQ3)
0a122b
+
0a122b
+        Device(LNKS) {
0a122b
+            Name(_HID, EISAID("PNP0C0F"))
0a122b
+            Name(_UID, 4)
0a122b
+            Name(_PRS, ResourceTemplate() {
0a122b
+                Interrupt(, Level, ActiveHigh, Shared) { 9 }
0a122b
+            })
0a122b
+
0a122b
+            // The SCI cannot be disabled and is always attached to GSI 9,
0a122b
+            // so these are no-ops.  We only need this link to override the
0a122b
+            // polarity to active high and match the content of the MADT.
0a122b
+            Method(_STA, 0, NotSerialized) { Return (0x0b) }
0a122b
+            Method(_DIS, 0, NotSerialized) { }
0a122b
+            Method(_CRS, 0, NotSerialized) { Return (_PRS) }
0a122b
+            Method(_SRS, 1, NotSerialized) { }
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+#include "acpi-dsdt-cpu-hotplug.dsl"
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * General purpose events
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_GPE) {
0a122b
+        Name(_HID, "ACPI0006")
0a122b
+
0a122b
+        Method(_L00) {
0a122b
+        }
0a122b
+        Method(_E01) {
0a122b
+            // PCI hotplug event
0a122b
+            \_SB.PCI0.PCNF()
0a122b
+        }
0a122b
+        Method(_E02) {
0a122b
+            // CPU hotplug event
0a122b
+            \_SB.PRSC()
0a122b
+        }
0a122b
+        Method(_L03) {
0a122b
+        }
0a122b
+        Method(_L04) {
0a122b
+        }
0a122b
+        Method(_L05) {
0a122b
+        }
0a122b
+        Method(_L06) {
0a122b
+        }
0a122b
+        Method(_L07) {
0a122b
+        }
0a122b
+        Method(_L08) {
0a122b
+        }
0a122b
+        Method(_L09) {
0a122b
+        }
0a122b
+        Method(_L0A) {
0a122b
+        }
0a122b
+        Method(_L0B) {
0a122b
+        }
0a122b
+        Method(_L0C) {
0a122b
+        }
0a122b
+        Method(_L0D) {
0a122b
+        }
0a122b
+        Method(_L0E) {
0a122b
+        }
0a122b
+        Method(_L0F) {
0a122b
+        }
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
0a122b
new file mode 100644
0a122b
index 0000000..21c89b0
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/q35-acpi-dsdt.dsl
0a122b
@@ -0,0 +1,452 @@
0a122b
+/*
0a122b
+ * Bochs/QEMU ACPI DSDT ASL definition
0a122b
+ *
0a122b
+ * Copyright (c) 2006 Fabrice Bellard
0a122b
+ *
0a122b
+ * This library is free software; you can redistribute it and/or
0a122b
+ * modify it under the terms of the GNU Lesser General Public
0a122b
+ * License version 2 as published by the Free Software Foundation.
0a122b
+ *
0a122b
+ * This library is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0a122b
+ * Lesser General Public License for more details.
0a122b
+ *
0a122b
+ * You should have received a copy of the GNU Lesser General Public
0a122b
+ * License along with this library; if not, write to the Free Software
0a122b
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
0a122b
+ */
0a122b
+/*
0a122b
+ * Copyright (c) 2010 Isaku Yamahata
0a122b
+ *                    yamahata at valinux co jp
0a122b
+ * Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
0a122b
+ */
0a122b
+
0a122b
+ACPI_EXTRACT_ALL_CODE Q35AcpiDsdtAmlCode
0a122b
+
0a122b
+DefinitionBlock (
0a122b
+    "q35-acpi-dsdt.aml",// Output Filename
0a122b
+    "DSDT",             // Signature
0a122b
+    0x01,               // DSDT Compliance Revision
0a122b
+    "BXPC",             // OEMID
0a122b
+    "BXDSDT",           // TABLE ID
0a122b
+    0x2                 // OEM Revision
0a122b
+    )
0a122b
+{
0a122b
+
0a122b
+#include "acpi-dsdt-dbug.dsl"
0a122b
+
0a122b
+    Scope(\_SB) {
0a122b
+        OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
0a122b
+        OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
0a122b
+        Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
0a122b
+            PCIB, 8,
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PCI Bus definition
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB) {
0a122b
+        Device(PCI0) {
0a122b
+            Name(_HID, EisaId("PNP0A08"))
0a122b
+            Name(_CID, EisaId("PNP0A03"))
0a122b
+            Name(_ADR, 0x00)
0a122b
+            Name(_UID, 1)
0a122b
+
0a122b
+            // _OSC: based on sample of ACPI3.0b spec
0a122b
+            Name(SUPP, 0) // PCI _OSC Support Field value
0a122b
+            Name(CTRL, 0) // PCI _OSC Control Field value
0a122b
+            Method(_OSC, 4) {
0a122b
+                // Create DWORD-addressable fields from the Capabilities Buffer
0a122b
+                CreateDWordField(Arg3, 0, CDW1)
0a122b
+
0a122b
+                // Check for proper UUID
0a122b
+                If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
0a122b
+                    // Create DWORD-addressable fields from the Capabilities Buffer
0a122b
+                    CreateDWordField(Arg3, 4, CDW2)
0a122b
+                    CreateDWordField(Arg3, 8, CDW3)
0a122b
+
0a122b
+                    // Save Capabilities DWORD2 & 3
0a122b
+                    Store(CDW2, SUPP)
0a122b
+                    Store(CDW3, CTRL)
0a122b
+
0a122b
+                    // Always allow native PME, AER (no dependencies)
0a122b
+                    // Never allow SHPC (no SHPC controller in this system)
0a122b
+                    And(CTRL, 0x1D, CTRL)
0a122b
+
0a122b
+#if 0 // For now, nothing to do
0a122b
+                    If (Not(And(CDW1, 1))) { // Query flag clear?
0a122b
+                        // Disable GPEs for features granted native control.
0a122b
+                        If (And(CTRL, 0x01)) { // Hot plug control granted?
0a122b
+                            Store(0, HPCE) // clear the hot plug SCI enable bit
0a122b
+                            Store(1, HPCS) // clear the hot plug SCI status bit
0a122b
+                        }
0a122b
+                        If (And(CTRL, 0x04)) { // PME control granted?
0a122b
+                            Store(0, PMCE) // clear the PME SCI enable bit
0a122b
+                            Store(1, PMCS) // clear the PME SCI status bit
0a122b
+                        }
0a122b
+                        If (And(CTRL, 0x10)) { // OS restoring PCI Express cap structure?
0a122b
+                            // Set status to not restore PCI Express cap structure
0a122b
+                            // upon resume from S3
0a122b
+                            Store(1, S3CR)
0a122b
+                        }
0a122b
+                    }
0a122b
+#endif
0a122b
+                    If (LNotEqual(Arg1, One)) {
0a122b
+                        // Unknown revision
0a122b
+                        Or(CDW1, 0x08, CDW1)
0a122b
+                    }
0a122b
+                    If (LNotEqual(CDW3, CTRL)) {
0a122b
+                        // Capabilities bits were masked
0a122b
+                        Or(CDW1, 0x10, CDW1)
0a122b
+                    }
0a122b
+                    // Update DWORD3 in the buffer
0a122b
+                    Store(CTRL, CDW3)
0a122b
+                } Else {
0a122b
+                    Or(CDW1, 4, CDW1) // Unrecognized UUID
0a122b
+                }
0a122b
+                Return (Arg3)
0a122b
+            }
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+#include "acpi-dsdt-pci-crs.dsl"
0a122b
+#include "acpi-dsdt-hpet.dsl"
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * VGA
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB.PCI0) {
0a122b
+        Device(VGA) {
0a122b
+            Name(_ADR, 0x00010000)
0a122b
+            Method(_S1D, 0, NotSerialized) {
0a122b
+                Return (0x00)
0a122b
+            }
0a122b
+            Method(_S2D, 0, NotSerialized) {
0a122b
+                Return (0x00)
0a122b
+            }
0a122b
+            Method(_S3D, 0, NotSerialized) {
0a122b
+                Return (0x00)
0a122b
+            }
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * LPC ISA bridge
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_SB.PCI0) {
0a122b
+        /* PCI D31:f0 LPC ISA bridge */
0a122b
+        Device(ISA) {
0a122b
+            /* PCI D31:f0 */
0a122b
+            Name(_ADR, 0x001f0000)
0a122b
+
0a122b
+            /* ICH9 PCI to ISA irq remapping */
0a122b
+            OperationRegion(PIRQ, PCI_Config, 0x60, 0x0C)
0a122b
+
0a122b
+            OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
0a122b
+            Field(LPCD, AnyAcc, NoLock, Preserve) {
0a122b
+                COMA,   3,
0a122b
+                    ,   1,
0a122b
+                COMB,   3,
0a122b
+
0a122b
+                Offset(0x01),
0a122b
+                LPTD,   2,
0a122b
+                    ,   2,
0a122b
+                FDCD,   2
0a122b
+            }
0a122b
+            OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
0a122b
+            Field(LPCE, AnyAcc, NoLock, Preserve) {
0a122b
+                CAEN,   1,
0a122b
+                CBEN,   1,
0a122b
+                LPEN,   1,
0a122b
+                FDEN,   1
0a122b
+            }
0a122b
+        }
0a122b
+    }
0a122b
+
0a122b
+#include "acpi-dsdt-isa.dsl"
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PCI IRQs
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    /* Zero => PIC mode, One => APIC Mode */
0a122b
+    Name(\PICF, Zero)
0a122b
+    Method(\_PIC, 1, NotSerialized) {
0a122b
+        Store(Arg0, \PICF)
0a122b
+    }
0a122b
+
0a122b
+    Scope(\_SB) {
0a122b
+        Scope(PCI0) {
0a122b
+#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3)  \
0a122b
+    Package() { nr##ffff, 0, lnk0, 0 },           \
0a122b
+    Package() { nr##ffff, 1, lnk1, 0 },           \
0a122b
+    Package() { nr##ffff, 2, lnk2, 0 },           \
0a122b
+    Package() { nr##ffff, 3, lnk3, 0 }
0a122b
+
0a122b
+#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
0a122b
+#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
0a122b
+#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
0a122b
+#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
0a122b
+
0a122b
+#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
0a122b
+#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
0a122b
+#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
0a122b
+#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
0a122b
+
0a122b
+            Name(PRTP, package() {
0a122b
+                prt_slot_lnkE(0x0000),
0a122b
+                prt_slot_lnkF(0x0001),
0a122b
+                prt_slot_lnkG(0x0002),
0a122b
+                prt_slot_lnkH(0x0003),
0a122b
+                prt_slot_lnkE(0x0004),
0a122b
+                prt_slot_lnkF(0x0005),
0a122b
+                prt_slot_lnkG(0x0006),
0a122b
+                prt_slot_lnkH(0x0007),
0a122b
+                prt_slot_lnkE(0x0008),
0a122b
+                prt_slot_lnkF(0x0009),
0a122b
+                prt_slot_lnkG(0x000a),
0a122b
+                prt_slot_lnkH(0x000b),
0a122b
+                prt_slot_lnkE(0x000c),
0a122b
+                prt_slot_lnkF(0x000d),
0a122b
+                prt_slot_lnkG(0x000e),
0a122b
+                prt_slot_lnkH(0x000f),
0a122b
+                prt_slot_lnkE(0x0010),
0a122b
+                prt_slot_lnkF(0x0011),
0a122b
+                prt_slot_lnkG(0x0012),
0a122b
+                prt_slot_lnkH(0x0013),
0a122b
+                prt_slot_lnkE(0x0014),
0a122b
+                prt_slot_lnkF(0x0015),
0a122b
+                prt_slot_lnkG(0x0016),
0a122b
+                prt_slot_lnkH(0x0017),
0a122b
+                prt_slot_lnkE(0x0018),
0a122b
+
0a122b
+                /* INTA -> PIRQA for slot 25 - 31
0a122b
+                   see the default value of D<N>IR */
0a122b
+                prt_slot_lnkA(0x0019),
0a122b
+                prt_slot_lnkA(0x001a),
0a122b
+                prt_slot_lnkA(0x001b),
0a122b
+                prt_slot_lnkA(0x001c),
0a122b
+                prt_slot_lnkA(0x001d),
0a122b
+
0a122b
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
0a122b
+                prt_slot_lnkE(0x001e),
0a122b
+
0a122b
+                prt_slot_lnkA(0x001f)
0a122b
+            })
0a122b
+
0a122b
+#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3)  \
0a122b
+    Package() { nr##ffff, 0, gsi0, 0 },           \
0a122b
+    Package() { nr##ffff, 1, gsi1, 0 },           \
0a122b
+    Package() { nr##ffff, 2, gsi2, 0 },           \
0a122b
+    Package() { nr##ffff, 3, gsi3, 0 }
0a122b
+
0a122b
+#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
0a122b
+#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
0a122b
+#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
0a122b
+#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
0a122b
+
0a122b
+#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
0a122b
+#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
0a122b
+#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
0a122b
+#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
0a122b
+
0a122b
+            Name(PRTA, package() {
0a122b
+                prt_slot_gsiE(0x0000),
0a122b
+                prt_slot_gsiF(0x0001),
0a122b
+                prt_slot_gsiG(0x0002),
0a122b
+                prt_slot_gsiH(0x0003),
0a122b
+                prt_slot_gsiE(0x0004),
0a122b
+                prt_slot_gsiF(0x0005),
0a122b
+                prt_slot_gsiG(0x0006),
0a122b
+                prt_slot_gsiH(0x0007),
0a122b
+                prt_slot_gsiE(0x0008),
0a122b
+                prt_slot_gsiF(0x0009),
0a122b
+                prt_slot_gsiG(0x000a),
0a122b
+                prt_slot_gsiH(0x000b),
0a122b
+                prt_slot_gsiE(0x000c),
0a122b
+                prt_slot_gsiF(0x000d),
0a122b
+                prt_slot_gsiG(0x000e),
0a122b
+                prt_slot_gsiH(0x000f),
0a122b
+                prt_slot_gsiE(0x0010),
0a122b
+                prt_slot_gsiF(0x0011),
0a122b
+                prt_slot_gsiG(0x0012),
0a122b
+                prt_slot_gsiH(0x0013),
0a122b
+                prt_slot_gsiE(0x0014),
0a122b
+                prt_slot_gsiF(0x0015),
0a122b
+                prt_slot_gsiG(0x0016),
0a122b
+                prt_slot_gsiH(0x0017),
0a122b
+                prt_slot_gsiE(0x0018),
0a122b
+
0a122b
+                /* INTA -> PIRQA for slot 25 - 31, but 30
0a122b
+                   see the default value of D<N>IR */
0a122b
+                prt_slot_gsiA(0x0019),
0a122b
+                prt_slot_gsiA(0x001a),
0a122b
+                prt_slot_gsiA(0x001b),
0a122b
+                prt_slot_gsiA(0x001c),
0a122b
+                prt_slot_gsiA(0x001d),
0a122b
+
0a122b
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
0a122b
+                prt_slot_gsiE(0x001e),
0a122b
+
0a122b
+                prt_slot_gsiA(0x001f)
0a122b
+            })
0a122b
+
0a122b
+            Method(_PRT, 0, NotSerialized) {
0a122b
+                /* PCI IRQ routing table, example from ACPI 2.0a specification,
0a122b
+                   section 6.2.8.1 */
0a122b
+                /* Note: we provide the same info as the PCI routing
0a122b
+                   table of the Bochs BIOS */
0a122b
+                If (LEqual(\PICF, Zero)) {
0a122b
+                    Return (PRTP)
0a122b
+                } Else {
0a122b
+                    Return (PRTA)
0a122b
+                }
0a122b
+            }
0a122b
+        }
0a122b
+
0a122b
+        Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
0a122b
+            PRQA,   8,
0a122b
+            PRQB,   8,
0a122b
+            PRQC,   8,
0a122b
+            PRQD,   8,
0a122b
+
0a122b
+            Offset(0x08),
0a122b
+            PRQE,   8,
0a122b
+            PRQF,   8,
0a122b
+            PRQG,   8,
0a122b
+            PRQH,   8
0a122b
+        }
0a122b
+
0a122b
+        Method(IQST, 1, NotSerialized) {
0a122b
+            // _STA method - get status
0a122b
+            If (And(0x80, Arg0)) {
0a122b
+                Return (0x09)
0a122b
+            }
0a122b
+            Return (0x0B)
0a122b
+        }
0a122b
+        Method(IQCR, 1, NotSerialized) {
0a122b
+            // _CRS method - get current settings
0a122b
+            Name(PRR0, ResourceTemplate() {
0a122b
+                Interrupt(, Level, ActiveHigh, Shared) { 0 }
0a122b
+            })
0a122b
+            CreateDWordField(PRR0, 0x05, PRRI)
0a122b
+            Store(And(Arg0, 0x0F), PRRI)
0a122b
+            Return (PRR0)
0a122b
+        }
0a122b
+
0a122b
+#define define_link(link, uid, reg)                             \
0a122b
+        Device(link) {                                          \
0a122b
+            Name(_HID, EISAID("PNP0C0F"))                       \
0a122b
+            Name(_UID, uid)                                     \
0a122b
+            Name(_PRS, ResourceTemplate() {                     \
0a122b
+                Interrupt(, Level, ActiveHigh, Shared) {        \
0a122b
+                    5, 10, 11                                   \
0a122b
+                }                                               \
0a122b
+            })                                                  \
0a122b
+            Method(_STA, 0, NotSerialized) {                    \
0a122b
+                Return (IQST(reg))                              \
0a122b
+            }                                                   \
0a122b
+            Method(_DIS, 0, NotSerialized) {                    \
0a122b
+                Or(reg, 0x80, reg)                              \
0a122b
+            }                                                   \
0a122b
+            Method(_CRS, 0, NotSerialized) {                    \
0a122b
+                Return (IQCR(reg))                              \
0a122b
+            }                                                   \
0a122b
+            Method(_SRS, 1, NotSerialized) {                    \
0a122b
+                CreateDWordField(Arg0, 0x05, PRRI)              \
0a122b
+                Store(PRRI, reg)                                \
0a122b
+            }                                                   \
0a122b
+        }
0a122b
+
0a122b
+        define_link(LNKA, 0, PRQA)
0a122b
+        define_link(LNKB, 1, PRQB)
0a122b
+        define_link(LNKC, 2, PRQC)
0a122b
+        define_link(LNKD, 3, PRQD)
0a122b
+        define_link(LNKE, 4, PRQE)
0a122b
+        define_link(LNKF, 5, PRQF)
0a122b
+        define_link(LNKG, 6, PRQG)
0a122b
+        define_link(LNKH, 7, PRQH)
0a122b
+
0a122b
+#define define_gsi_link(link, uid, gsi)                         \
0a122b
+        Device(link) {                                          \
0a122b
+            Name(_HID, EISAID("PNP0C0F"))                       \
0a122b
+            Name(_UID, uid)                                     \
0a122b
+            Name(_PRS, ResourceTemplate() {                     \
0a122b
+                Interrupt(, Level, ActiveHigh, Shared) {        \
0a122b
+                    gsi                                         \
0a122b
+                }                                               \
0a122b
+            })                                                  \
0a122b
+            Name(_CRS, ResourceTemplate() {                     \
0a122b
+                Interrupt(, Level, ActiveHigh, Shared) {        \
0a122b
+                    gsi                                         \
0a122b
+                }                                               \
0a122b
+            })                                                  \
0a122b
+            Method(_SRS, 1, NotSerialized) {                    \
0a122b
+            }                                                   \
0a122b
+        }
0a122b
+
0a122b
+        define_gsi_link(GSIA, 0, 0x10)
0a122b
+        define_gsi_link(GSIB, 0, 0x11)
0a122b
+        define_gsi_link(GSIC, 0, 0x12)
0a122b
+        define_gsi_link(GSID, 0, 0x13)
0a122b
+        define_gsi_link(GSIE, 0, 0x14)
0a122b
+        define_gsi_link(GSIF, 0, 0x15)
0a122b
+        define_gsi_link(GSIG, 0, 0x16)
0a122b
+        define_gsi_link(GSIH, 0, 0x17)
0a122b
+    }
0a122b
+
0a122b
+#include "acpi-dsdt-cpu-hotplug.dsl"
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * General purpose events
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\_GPE) {
0a122b
+        Name(_HID, "ACPI0006")
0a122b
+
0a122b
+        Method(_L00) {
0a122b
+        }
0a122b
+        Method(_L01) {
0a122b
+            // CPU hotplug event
0a122b
+            \_SB.PRSC()
0a122b
+        }
0a122b
+        Method(_L02) {
0a122b
+        }
0a122b
+        Method(_L03) {
0a122b
+        }
0a122b
+        Method(_L04) {
0a122b
+        }
0a122b
+        Method(_L05) {
0a122b
+        }
0a122b
+        Method(_L06) {
0a122b
+        }
0a122b
+        Method(_L07) {
0a122b
+        }
0a122b
+        Method(_L08) {
0a122b
+        }
0a122b
+        Method(_L09) {
0a122b
+        }
0a122b
+        Method(_L0A) {
0a122b
+        }
0a122b
+        Method(_L0B) {
0a122b
+        }
0a122b
+        Method(_L0C) {
0a122b
+        }
0a122b
+        Method(_L0D) {
0a122b
+        }
0a122b
+        Method(_L0E) {
0a122b
+        }
0a122b
+        Method(_L0F) {
0a122b
+        }
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
0a122b
new file mode 100644
0a122b
index 0000000..a4484b8
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/ssdt-misc.dsl
0a122b
@@ -0,0 +1,119 @@
0a122b
+/*
0a122b
+ * This program is free software; you can redistribute it and/or modify
0a122b
+ * it under the terms of the GNU General Public License as published by
0a122b
+ * the Free Software Foundation; either version 2 of the License, or
0a122b
+ * (at your option) any later version.
0a122b
+
0a122b
+ * This program is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+ * GNU General Public License for more details.
0a122b
+
0a122b
+ * You should have received a copy of the GNU General Public License along
0a122b
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+ */
0a122b
+
0a122b
+ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
0a122b
+
0a122b
+DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
0a122b
+{
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PCI memory ranges
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\) {
0a122b
+       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start
0a122b
+       Name(P0S, 0x12345678)
0a122b
+       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end
0a122b
+       Name(P0E, 0x12345678)
0a122b
+       ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid
0a122b
+       Name(P1V, 0x12)
0a122b
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start
0a122b
+       Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
0a122b
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end
0a122b
+       Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
0a122b
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
0a122b
+       Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
0a122b
+    }
0a122b
+
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * Suspend
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    Scope(\) {
0a122b
+    /*
0a122b
+     * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
0a122b
+     * must match piix4 emulation.
0a122b
+     */
0a122b
+
0a122b
+        ACPI_EXTRACT_NAME_STRING acpi_s3_name
0a122b
+        Name(_S3, Package(0x04) {
0a122b
+            One,  /* PM1a_CNT.SLP_TYP */
0a122b
+            One,  /* PM1b_CNT.SLP_TYP */
0a122b
+            Zero,  /* reserved */
0a122b
+            Zero   /* reserved */
0a122b
+        })
0a122b
+        ACPI_EXTRACT_NAME_STRING acpi_s4_name
0a122b
+        ACPI_EXTRACT_PKG_START acpi_s4_pkg
0a122b
+        Name(_S4, Package(0x04) {
0a122b
+            0x2,  /* PM1a_CNT.SLP_TYP */
0a122b
+            0x2,  /* PM1b_CNT.SLP_TYP */
0a122b
+            Zero,  /* reserved */
0a122b
+            Zero   /* reserved */
0a122b
+        })
0a122b
+        Name(_S5, Package(0x04) {
0a122b
+            Zero,  /* PM1a_CNT.SLP_TYP */
0a122b
+            Zero,  /* PM1b_CNT.SLP_TYP */
0a122b
+            Zero,  /* reserved */
0a122b
+            Zero   /* reserved */
0a122b
+        })
0a122b
+    }
0a122b
+
0a122b
+    External(\_SB.PCI0, DeviceObj)
0a122b
+    External(\_SB.PCI0.ISA, DeviceObj)
0a122b
+
0a122b
+    Scope(\_SB.PCI0.ISA) {
0a122b
+        Device(PEVT) {
0a122b
+            Name(_HID, "QEMU0001")
0a122b
+            /* PEST will be patched to be Zero if no such device */
0a122b
+            ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest
0a122b
+            Name(PEST, 0xFFFF)
0a122b
+            OperationRegion(PEOR, SystemIO, PEST, 0x01)
0a122b
+            Field(PEOR, ByteAcc, NoLock, Preserve) {
0a122b
+                PEPT,   8,
0a122b
+            }
0a122b
+
0a122b
+            Method(_STA, 0, NotSerialized) {
0a122b
+                Store(PEST, Local0)
0a122b
+                If (LEqual(Local0, Zero)) {
0a122b
+                    Return (0x00)
0a122b
+                } Else {
0a122b
+                    Return (0x0F)
0a122b
+                }
0a122b
+            }
0a122b
+
0a122b
+            Method(RDPT, 0, NotSerialized) {
0a122b
+                Store(PEPT, Local0)
0a122b
+                Return (Local0)
0a122b
+            }
0a122b
+
0a122b
+            Method(WRPT, 1, NotSerialized) {
0a122b
+                Store(Arg0, PEPT)
0a122b
+            }
0a122b
+
0a122b
+            Name(_CRS, ResourceTemplate() {
0a122b
+                IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO)
0a122b
+            })
0a122b
+
0a122b
+            CreateWordField(_CRS, IO._MIN, IOMN)
0a122b
+            CreateWordField(_CRS, IO._MAX, IOMX)
0a122b
+
0a122b
+            Method(_INI, 0, NotSerialized) {
0a122b
+                Store(PEST, IOMN)
0a122b
+                Store(PEST, IOMX)
0a122b
+            }
0a122b
+        }
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/ssdt-pcihp.dsl b/hw/i386/ssdt-pcihp.dsl
0a122b
new file mode 100644
0a122b
index 0000000..d29a5b9
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/ssdt-pcihp.dsl
0a122b
@@ -0,0 +1,51 @@
0a122b
+/*
0a122b
+ * This program is free software; you can redistribute it and/or modify
0a122b
+ * it under the terms of the GNU General Public License as published by
0a122b
+ * the Free Software Foundation; either version 2 of the License, or
0a122b
+ * (at your option) any later version.
0a122b
+
0a122b
+ * This program is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+ * GNU General Public License for more details.
0a122b
+
0a122b
+ * You should have received a copy of the GNU General Public License along
0a122b
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+ */
0a122b
+
0a122b
+ACPI_EXTRACT_ALL_CODE ssdp_pcihp_aml
0a122b
+
0a122b
+DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
0a122b
+{
0a122b
+
0a122b
+/****************************************************************
0a122b
+ * PCI hotplug
0a122b
+ ****************************************************************/
0a122b
+
0a122b
+    /* Objects supplied by DSDT */
0a122b
+    External(\_SB.PCI0, DeviceObj)
0a122b
+    External(\_SB.PCI0.PCEJ, MethodObj)
0a122b
+
0a122b
+    Scope(\_SB.PCI0) {
0a122b
+
0a122b
+        /* Bulk generated PCI hotplug devices */
0a122b
+        ACPI_EXTRACT_DEVICE_START ssdt_pcihp_start
0a122b
+        ACPI_EXTRACT_DEVICE_END ssdt_pcihp_end
0a122b
+        ACPI_EXTRACT_DEVICE_STRING ssdt_pcihp_name
0a122b
+
0a122b
+        // Method _EJ0 can be patched by BIOS to EJ0_
0a122b
+        // at runtime, if the slot is detected to not support hotplug.
0a122b
+        // Extract the offset of the address dword and the
0a122b
+        // _EJ0 name to allow this patching.
0a122b
+        Device(SAA) {
0a122b
+            ACPI_EXTRACT_NAME_BYTE_CONST ssdt_pcihp_id
0a122b
+            Name(_SUN, 0xAA)
0a122b
+            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcihp_adr
0a122b
+            Name(_ADR, 0xAA0000)
0a122b
+            ACPI_EXTRACT_METHOD_STRING ssdt_pcihp_ej0
0a122b
+            Method(_EJ0, 1) {
0a122b
+                Return (PCEJ(_SUN))
0a122b
+            }
0a122b
+        }
0a122b
+    }
0a122b
+}
0a122b
diff --git a/hw/i386/ssdt-proc.dsl b/hw/i386/ssdt-proc.dsl
0a122b
new file mode 100644
0a122b
index 0000000..58333c7
0a122b
--- /dev/null
0a122b
+++ b/hw/i386/ssdt-proc.dsl
0a122b
@@ -0,0 +1,63 @@
0a122b
+/*
0a122b
+ * This program is free software; you can redistribute it and/or modify
0a122b
+ * it under the terms of the GNU General Public License as published by
0a122b
+ * the Free Software Foundation; either version 2 of the License, or
0a122b
+ * (at your option) any later version.
0a122b
+
0a122b
+ * This program is distributed in the hope that it will be useful,
0a122b
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+ * GNU General Public License for more details.
0a122b
+
0a122b
+ * You should have received a copy of the GNU General Public License along
0a122b
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+ */
0a122b
+
0a122b
+/* This file is the basis for the ssdt table generated in src/acpi.c.
0a122b
+ * It defines the contents of the per-cpu Processor() object.  At
0a122b
+ * runtime, a dynamically generated SSDT will contain one copy of this
0a122b
+ * AML snippet for every possible cpu in the system.  The objects will
0a122b
+ * be placed in the \_SB_ namespace.
0a122b
+ *
0a122b
+ * In addition to the aml code generated from this file, the
0a122b
+ * src/acpi.c file creates a NTFY method with an entry for each cpu:
0a122b
+ *     Method(NTFY, 2) {
0a122b
+ *         If (LEqual(Arg0, 0x00)) { Notify(CP00, Arg1) }
0a122b
+ *         If (LEqual(Arg0, 0x01)) { Notify(CP01, Arg1) }
0a122b
+ *         ...
0a122b
+ *     }
0a122b
+ * and a CPON array with the list of active and inactive cpus:
0a122b
+ *     Name(CPON, Package() { One, One, ..., Zero, Zero, ... })
0a122b
+ */
0a122b
+
0a122b
+ACPI_EXTRACT_ALL_CODE ssdp_proc_aml
0a122b
+
0a122b
+DefinitionBlock ("ssdt-proc.aml", "SSDT", 0x01, "BXPC", "BXSSDT", 0x1)
0a122b
+{
0a122b
+    ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start
0a122b
+    ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end
0a122b
+    ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name
0a122b
+    Processor(CPAA, 0xAA, 0x0000b010, 0x06) {
0a122b
+        ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id
0a122b
+        Name(ID, 0xAA)
0a122b
+/*
0a122b
+ * The src/acpi.c code requires the above ACP_EXTRACT tags so that it can update
0a122b
+ * CPAA and 0xAA with the appropriate CPU id (see
0a122b
+ * SD_OFFSET_CPUHEX/CPUID1/CPUID2).  Don't change the above without
0a122b
+ * also updating the C code.
0a122b
+ */
0a122b
+        Name(_HID, "ACPI0007")
0a122b
+        External(CPMA, MethodObj)
0a122b
+        External(CPST, MethodObj)
0a122b
+        External(CPEJ, MethodObj)
0a122b
+        Method(_MAT, 0) {
0a122b
+            Return (CPMA(ID))
0a122b
+        }
0a122b
+        Method(_STA, 0) {
0a122b
+            Return (CPST(ID))
0a122b
+        }
0a122b
+        Method(_EJ0, 1, NotSerialized) {
0a122b
+            CPEJ(ID, Arg0)
0a122b
+        }
0a122b
+    }
0a122b
+}
0a122b
diff --git a/scripts/acpi_extract.py b/scripts/acpi_extract.py
0a122b
new file mode 100755
0a122b
index 0000000..22ea468
0a122b
--- /dev/null
0a122b
+++ b/scripts/acpi_extract.py
0a122b
@@ -0,0 +1,362 @@
0a122b
+#!/usr/bin/python
0a122b
+# Copyright (C) 2011 Red Hat, Inc., Michael S. Tsirkin <mst@redhat.com>
0a122b
+#
0a122b
+# This program is free software; you can redistribute it and/or modify
0a122b
+# it under the terms of the GNU General Public License as published by
0a122b
+# the Free Software Foundation; either version 2 of the License, or
0a122b
+# (at your option) any later version.
0a122b
+#
0a122b
+# This program is distributed in the hope that it will be useful,
0a122b
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+# GNU General Public License for more details.
0a122b
+#
0a122b
+# You should have received a copy of the GNU General Public License along
0a122b
+# with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+
0a122b
+# Process mixed ASL/AML listing (.lst file) produced by iasl -l
0a122b
+# Locate and execute ACPI_EXTRACT directives, output offset info
0a122b
+#
0a122b
+# Documentation of ACPI_EXTRACT_* directive tags:
0a122b
+#
0a122b
+# These directive tags output offset information from AML for BIOS runtime
0a122b
+# table generation.
0a122b
+# Each directive is of the form:
0a122b
+# ACPI_EXTRACT_<TYPE> <array_name> <Operator> (...)
0a122b
+# and causes the extractor to create an array
0a122b
+# named <array_name> with offset, in the generated AML,
0a122b
+# of an object of a given type in the following <Operator>.
0a122b
+#
0a122b
+# A directive must fit on a single code line.
0a122b
+#
0a122b
+# Object type in AML is verified, a mismatch causes a build failure.
0a122b
+#
0a122b
+# Directives and operators currently supported are:
0a122b
+# ACPI_EXTRACT_NAME_DWORD_CONST - extract a Dword Const object from Name()
0a122b
+# ACPI_EXTRACT_NAME_WORD_CONST - extract a Word Const object from Name()
0a122b
+# ACPI_EXTRACT_NAME_BYTE_CONST - extract a Byte Const object from Name()
0a122b
+# ACPI_EXTRACT_METHOD_STRING - extract a NameString from Method()
0a122b
+# ACPI_EXTRACT_NAME_STRING - extract a NameString from Name()
0a122b
+# ACPI_EXTRACT_PROCESSOR_START - start of Processor() block
0a122b
+# ACPI_EXTRACT_PROCESSOR_STRING - extract a NameString from Processor()
0a122b
+# ACPI_EXTRACT_PROCESSOR_END - offset at last byte of Processor() + 1
0a122b
+# ACPI_EXTRACT_PKG_START - start of Package block
0a122b
+#
0a122b
+# ACPI_EXTRACT_ALL_CODE - create an array storing the generated AML bytecode
0a122b
+#
0a122b
+# ACPI_EXTRACT is not allowed anywhere else in code, except in comments.
0a122b
+
0a122b
+import re;
0a122b
+import sys;
0a122b
+import fileinput;
0a122b
+
0a122b
+aml = []
0a122b
+asl = []
0a122b
+output = {}
0a122b
+debug = ""
0a122b
+
0a122b
+class asl_line:
0a122b
+    line = None
0a122b
+    lineno = None
0a122b
+    aml_offset = None
0a122b
+
0a122b
+def die(diag):
0a122b
+    sys.stderr.write("Error: %s; %s\n" % (diag, debug))
0a122b
+    sys.exit(1)
0a122b
+
0a122b
+#Store an ASL command, matching AML offset, and input line (for debugging)
0a122b
+def add_asl(lineno, line):
0a122b
+    l = asl_line()
0a122b
+    l.line = line
0a122b
+    l.lineno = lineno
0a122b
+    l.aml_offset = len(aml)
0a122b
+    asl.append(l)
0a122b
+
0a122b
+#Store an AML byte sequence
0a122b
+#Verify that offset output by iasl matches # of bytes so far
0a122b
+def add_aml(offset, line):
0a122b
+    o = int(offset, 16);
0a122b
+    # Sanity check: offset must match size of code so far
0a122b
+    if (o != len(aml)):
0a122b
+        die("Offset 0x%x != 0x%x" % (o, len(aml)))
0a122b
+    # Strip any trailing dots and ASCII dump after "
0a122b
+    line = re.sub(r'\s*\.*\s*".*$',"", line)
0a122b
+    # Strip traling whitespace
0a122b
+    line = re.sub(r'\s+$',"", line)
0a122b
+    # Strip leading whitespace
0a122b
+    line = re.sub(r'^\s+',"", line)
0a122b
+    # Split on whitespace
0a122b
+    code = re.split(r'\s+', line)
0a122b
+    for c in code:
0a122b
+        # Require a legal hex number, two digits
0a122b
+        if (not(re.search(r'^[0-9A-Fa-f][0-9A-Fa-f]$', c))):
0a122b
+            die("Unexpected octet %s" % c);
0a122b
+        aml.append(int(c, 16));
0a122b
+
0a122b
+# Process aml bytecode array, decoding AML
0a122b
+def aml_pkglen_bytes(offset):
0a122b
+    # PkgLength can be multibyte. Bits 8-7 give the # of extra bytes.
0a122b
+    pkglenbytes = aml[offset] >> 6;
0a122b
+    return pkglenbytes + 1
0a122b
+
0a122b
+def aml_pkglen(offset):
0a122b
+    pkgstart = offset
0a122b
+    pkglenbytes = aml_pkglen_bytes(offset)
0a122b
+    pkglen = aml[offset] & 0x3F
0a122b
+    # If multibyte, first nibble only uses bits 0-3
0a122b
+    if ((pkglenbytes > 1) and (pkglen & 0x30)):
0a122b
+        die("PkgLen bytes 0x%x but first nibble 0x%x expected 0x0X" %
0a122b
+            (pkglen, pkglen))
0a122b
+    offset += 1
0a122b
+    pkglenbytes -= 1
0a122b
+    for i in range(pkglenbytes):
0a122b
+        pkglen |= aml[offset + i] << (i * 8 + 4)
0a122b
+    if (len(aml) < pkgstart + pkglen):
0a122b
+        die("PckgLen 0x%x at offset 0x%x exceeds AML size 0x%x" %
0a122b
+            (pkglen, offset, len(aml)))
0a122b
+    return pkglen
0a122b
+
0a122b
+# Given method offset, find its NameString offset
0a122b
+def aml_method_string(offset):
0a122b
+    #0x14 MethodOp PkgLength NameString MethodFlags TermList
0a122b
+    if (aml[offset] != 0x14):
0a122b
+        die( "Method offset 0x%x: expected 0x14 actual 0x%x" %
0a122b
+             (offset, aml[offset]));
0a122b
+    offset += 1;
0a122b
+    pkglenbytes = aml_pkglen_bytes(offset)
0a122b
+    offset += pkglenbytes;
0a122b
+    return offset;
0a122b
+
0a122b
+# Given name offset, find its NameString offset
0a122b
+def aml_name_string(offset):
0a122b
+    #0x08 NameOp NameString DataRef
0a122b
+    if (aml[offset] != 0x08):
0a122b
+        die( "Name offset 0x%x: expected 0x08 actual 0x%x" %
0a122b
+             (offset, aml[offset]));
0a122b
+    offset += 1
0a122b
+    # Block Name Modifier. Skip it.
0a122b
+    if (aml[offset] == 0x5c or aml[offset] == 0x5e):
0a122b
+        offset += 1
0a122b
+    return offset;
0a122b
+
0a122b
+# Given data offset, find 8 byte buffer offset
0a122b
+def aml_data_buffer8(offset):
0a122b
+    #0x08 NameOp NameString DataRef
0a122b
+    expect = [0x11, 0x0B, 0x0A, 0x08]
0a122b
+    if (aml[offset:offset+4] != expect):
0a122b
+        die( "Name offset 0x%x: expected %s actual %s" %
0a122b
+             (offset, aml[offset:offset+4], expect))
0a122b
+    return offset + len(expect)
0a122b
+
0a122b
+# Given data offset, find dword const offset
0a122b
+def aml_data_dword_const(offset):
0a122b
+    #0x08 NameOp NameString DataRef
0a122b
+    if (aml[offset] != 0x0C):
0a122b
+        die( "Name offset 0x%x: expected 0x0C actual 0x%x" %
0a122b
+             (offset, aml[offset]));
0a122b
+    return offset + 1;
0a122b
+
0a122b
+# Given data offset, find word const offset
0a122b
+def aml_data_word_const(offset):
0a122b
+    #0x08 NameOp NameString DataRef
0a122b
+    if (aml[offset] != 0x0B):
0a122b
+        die( "Name offset 0x%x: expected 0x0B actual 0x%x" %
0a122b
+             (offset, aml[offset]));
0a122b
+    return offset + 1;
0a122b
+
0a122b
+# Given data offset, find byte const offset
0a122b
+def aml_data_byte_const(offset):
0a122b
+    #0x08 NameOp NameString DataRef
0a122b
+    if (aml[offset] != 0x0A):
0a122b
+        die( "Name offset 0x%x: expected 0x0A actual 0x%x" %
0a122b
+             (offset, aml[offset]));
0a122b
+    return offset + 1;
0a122b
+
0a122b
+# Find name'd buffer8
0a122b
+def aml_name_buffer8(offset):
0a122b
+    return aml_data_buffer8(aml_name_string(offset) + 4)
0a122b
+
0a122b
+# Given name offset, find dword const offset
0a122b
+def aml_name_dword_const(offset):
0a122b
+    return aml_data_dword_const(aml_name_string(offset) + 4)
0a122b
+
0a122b
+# Given name offset, find word const offset
0a122b
+def aml_name_word_const(offset):
0a122b
+    return aml_data_word_const(aml_name_string(offset) + 4)
0a122b
+
0a122b
+# Given name offset, find byte const offset
0a122b
+def aml_name_byte_const(offset):
0a122b
+    return aml_data_byte_const(aml_name_string(offset) + 4)
0a122b
+
0a122b
+def aml_device_start(offset):
0a122b
+    #0x5B 0x82 DeviceOp PkgLength NameString
0a122b
+    if ((aml[offset] != 0x5B) or (aml[offset + 1] != 0x82)):
0a122b
+        die( "Name offset 0x%x: expected 0x5B 0x82 actual 0x%x 0x%x" %
0a122b
+             (offset, aml[offset], aml[offset + 1]));
0a122b
+    return offset
0a122b
+
0a122b
+def aml_device_string(offset):
0a122b
+    #0x5B 0x82 DeviceOp PkgLength NameString
0a122b
+    start = aml_device_start(offset)
0a122b
+    offset += 2
0a122b
+    pkglenbytes = aml_pkglen_bytes(offset)
0a122b
+    offset += pkglenbytes
0a122b
+    return offset
0a122b
+
0a122b
+def aml_device_end(offset):
0a122b
+    start = aml_device_start(offset)
0a122b
+    offset += 2
0a122b
+    pkglenbytes = aml_pkglen_bytes(offset)
0a122b
+    pkglen = aml_pkglen(offset)
0a122b
+    return offset + pkglen
0a122b
+
0a122b
+def aml_processor_start(offset):
0a122b
+    #0x5B 0x83 ProcessorOp PkgLength NameString ProcID
0a122b
+    if ((aml[offset] != 0x5B) or (aml[offset + 1] != 0x83)):
0a122b
+        die( "Name offset 0x%x: expected 0x5B 0x83 actual 0x%x 0x%x" %
0a122b
+             (offset, aml[offset], aml[offset + 1]));
0a122b
+    return offset
0a122b
+
0a122b
+def aml_processor_string(offset):
0a122b
+    #0x5B 0x83 ProcessorOp PkgLength NameString ProcID
0a122b
+    start = aml_processor_start(offset)
0a122b
+    offset += 2
0a122b
+    pkglenbytes = aml_pkglen_bytes(offset)
0a122b
+    offset += pkglenbytes
0a122b
+    return offset
0a122b
+
0a122b
+def aml_processor_end(offset):
0a122b
+    start = aml_processor_start(offset)
0a122b
+    offset += 2
0a122b
+    pkglenbytes = aml_pkglen_bytes(offset)
0a122b
+    pkglen = aml_pkglen(offset)
0a122b
+    return offset + pkglen
0a122b
+
0a122b
+def aml_package_start(offset):
0a122b
+    offset = aml_name_string(offset) + 4
0a122b
+    # 0x12 PkgLength NumElements PackageElementList
0a122b
+    if (aml[offset] != 0x12):
0a122b
+        die( "Name offset 0x%x: expected 0x12 actual 0x%x" %
0a122b
+             (offset, aml[offset]));
0a122b
+    offset += 1
0a122b
+    return offset + aml_pkglen_bytes(offset) + 1
0a122b
+
0a122b
+lineno = 0
0a122b
+for line in fileinput.input():
0a122b
+    # Strip trailing newline
0a122b
+    line = line.rstrip();
0a122b
+    # line number and debug string to output in case of errors
0a122b
+    lineno = lineno + 1
0a122b
+    debug = "input line %d: %s" % (lineno, line)
0a122b
+    #ASL listing: space, then line#, then ...., then code
0a122b
+    pasl = re.compile('^\s+([0-9]+)(:\s\s|\.\.\.\.)\s*')
0a122b
+    m = pasl.search(line)
0a122b
+    if (m):
0a122b
+        add_asl(lineno, pasl.sub("", line));
0a122b
+    # AML listing: offset in hex, then ...., then code
0a122b
+    paml = re.compile('^([0-9A-Fa-f]+)(:\s\s|\.\.\.\.)\s*')
0a122b
+    m = paml.search(line)
0a122b
+    if (m):
0a122b
+        add_aml(m.group(1), paml.sub("", line))
0a122b
+
0a122b
+# Now go over code
0a122b
+# Track AML offset of a previous non-empty ASL command
0a122b
+prev_aml_offset = -1
0a122b
+for i in range(len(asl)):
0a122b
+    debug = "input line %d: %s" % (asl[i].lineno, asl[i].line)
0a122b
+
0a122b
+    l = asl[i].line
0a122b
+
0a122b
+    # skip if not an extract directive
0a122b
+    a = len(re.findall(r'ACPI_EXTRACT', l))
0a122b
+    if (not a):
0a122b
+        # If not empty, store AML offset. Will be used for sanity checks
0a122b
+        # IASL seems to put {}. at random places in the listing.
0a122b
+        # Ignore any non-words for the purpose of this test.
0a122b
+        m = re.search(r'\w+', l)
0a122b
+        if (m):
0a122b
+                prev_aml_offset = asl[i].aml_offset
0a122b
+        continue
0a122b
+
0a122b
+    if (a > 1):
0a122b
+        die("Expected at most one ACPI_EXTRACT per line, actual %d" % a)
0a122b
+
0a122b
+    mext = re.search(r'''
0a122b
+                      ^\s* # leading whitespace
0a122b
+                      /\*\s* # start C comment
0a122b
+                      (ACPI_EXTRACT_\w+) # directive: group(1)
0a122b
+                      \s+ # whitspace separates directive from array name
0a122b
+                      (\w+) # array name: group(2)
0a122b
+                      \s*\*/ # end of C comment
0a122b
+                      \s*$ # trailing whitespace
0a122b
+                      ''', l, re.VERBOSE)
0a122b
+    if (not mext):
0a122b
+        die("Stray ACPI_EXTRACT in input")
0a122b
+
0a122b
+    # previous command must have produced some AML,
0a122b
+    # otherwise we are in a middle of a block
0a122b
+    if (prev_aml_offset == asl[i].aml_offset):
0a122b
+        die("ACPI_EXTRACT directive in the middle of a block")
0a122b
+
0a122b
+    directive = mext.group(1)
0a122b
+    array = mext.group(2)
0a122b
+    offset = asl[i].aml_offset
0a122b
+
0a122b
+    if (directive == "ACPI_EXTRACT_ALL_CODE"):
0a122b
+        if array in output:
0a122b
+            die("%s directive used more than once" % directive)
0a122b
+        output[array] = aml
0a122b
+        continue
0a122b
+    if (directive == "ACPI_EXTRACT_NAME_BUFFER8"):
0a122b
+        offset = aml_name_buffer8(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_NAME_DWORD_CONST"):
0a122b
+        offset = aml_name_dword_const(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_NAME_WORD_CONST"):
0a122b
+        offset = aml_name_word_const(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_NAME_BYTE_CONST"):
0a122b
+        offset = aml_name_byte_const(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_NAME_STRING"):
0a122b
+        offset = aml_name_string(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_METHOD_STRING"):
0a122b
+        offset = aml_method_string(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_DEVICE_START"):
0a122b
+        offset = aml_device_start(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_DEVICE_STRING"):
0a122b
+        offset = aml_device_string(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_DEVICE_END"):
0a122b
+        offset = aml_device_end(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_PROCESSOR_START"):
0a122b
+        offset = aml_processor_start(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_PROCESSOR_STRING"):
0a122b
+        offset = aml_processor_string(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_PROCESSOR_END"):
0a122b
+        offset = aml_processor_end(offset)
0a122b
+    elif (directive == "ACPI_EXTRACT_PKG_START"):
0a122b
+        offset = aml_package_start(offset)
0a122b
+    else:
0a122b
+        die("Unsupported directive %s" % directive)
0a122b
+
0a122b
+    if array not in output:
0a122b
+        output[array] = []
0a122b
+    output[array].append(offset)
0a122b
+
0a122b
+debug = "at end of file"
0a122b
+
0a122b
+def get_value_type(maxvalue):
0a122b
+    #Use type large enough to fit the table
0a122b
+    if (maxvalue >= 0x10000):
0a122b
+            return "int"
0a122b
+    elif (maxvalue >= 0x100):
0a122b
+            return "short"
0a122b
+    else:
0a122b
+            return "char"
0a122b
+
0a122b
+# Pretty print output
0a122b
+for array in output.keys():
0a122b
+    otype = get_value_type(max(output[array]))
0a122b
+    odata = []
0a122b
+    for value in output[array]:
0a122b
+        odata.append("0x%x" % value)
0a122b
+    sys.stdout.write("static unsigned %s %s[] = {\n" % (otype, array))
0a122b
+    sys.stdout.write(",\n".join(odata))
0a122b
+    sys.stdout.write('\n};\n');
0a122b
diff --git a/scripts/acpi_extract_preprocess.py b/scripts/acpi_extract_preprocess.py
0a122b
new file mode 100755
0a122b
index 0000000..69d10d6
0a122b
--- /dev/null
0a122b
+++ b/scripts/acpi_extract_preprocess.py
0a122b
@@ -0,0 +1,51 @@
0a122b
+#!/usr/bin/python
0a122b
+# Copyright (C) 2011 Red Hat, Inc., Michael S. Tsirkin <mst@redhat.com>
0a122b
+#
0a122b
+# This program is free software; you can redistribute it and/or modify
0a122b
+# it under the terms of the GNU General Public License as published by
0a122b
+# the Free Software Foundation; either version 2 of the License, or
0a122b
+# (at your option) any later version.
0a122b
+#
0a122b
+# This program is distributed in the hope that it will be useful,
0a122b
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
0a122b
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0a122b
+# GNU General Public License for more details.
0a122b
+#
0a122b
+# You should have received a copy of the GNU General Public License along
0a122b
+# with this program; if not, see <http://www.gnu.org/licenses/>.
0a122b
+
0a122b
+# Read a preprocessed ASL listing and put each ACPI_EXTRACT
0a122b
+# directive in a comment, to make iasl skip it.
0a122b
+# We also put each directive on a new line, the machinery
0a122b
+# in tools/acpi_extract.py requires this.
0a122b
+
0a122b
+import re;
0a122b
+import sys;
0a122b
+import fileinput;
0a122b
+
0a122b
+def die(diag):
0a122b
+    sys.stderr.write("Error: %s\n" % (diag))
0a122b
+    sys.exit(1)
0a122b
+
0a122b
+# Note: () around pattern make split return matched string as part of list
0a122b
+psplit = re.compile(r''' (
0a122b
+                          \b # At word boundary
0a122b
+                          ACPI_EXTRACT_\w+ # directive
0a122b
+                          \s+ # some whitespace
0a122b
+                          \w+ # array name
0a122b
+                         )''', re.VERBOSE);
0a122b
+
0a122b
+lineno = 0
0a122b
+for line in fileinput.input():
0a122b
+    # line number and debug string to output in case of errors
0a122b
+    lineno = lineno + 1
0a122b
+    debug = "input line %d: %s" % (lineno, line.rstrip())
0a122b
+
0a122b
+    s = psplit.split(line);
0a122b
+    # The way split works, each odd item is the matching ACPI_EXTRACT directive.
0a122b
+    # Put each in a comment, and on a line by itself.
0a122b
+    for i in range(len(s)):
0a122b
+        if (i % 2):
0a122b
+            sys.stdout.write("\n/* %s */\n" % s[i])
0a122b
+        else:
0a122b
+            sys.stdout.write(s[i])
0a122b
-- 
0a122b
1.7.11.7
0a122b