yeahuh / rpms / qemu-kvm

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