x86: Add DSDT table for supporting ACPI on QEMU
authorSaket Sinha <saket.sinha89@gmail.com>
Sat, 22 Aug 2015 06:50:57 +0000 (12:20 +0530)
committerSimon Glass <sjg@chromium.org>
Wed, 26 Aug 2015 14:54:14 +0000 (07:54 -0700)
The DSDT table contains a bytecode that is executed by a driver in the kernel.

Signed-off-by: Saket Sinha <saket.sinha89@gmail.com>
Tested with QEMU '-M q35'
Tested-by: Bin Meng <bmeng.cn@gmail.com>
arch/x86/cpu/qemu/Makefile
arch/x86/cpu/qemu/acpi/cpu-hotplug.asl [new file with mode: 0644]
arch/x86/cpu/qemu/acpi/dbug.asl [new file with mode: 0644]
arch/x86/cpu/qemu/acpi/hpet.asl [new file with mode: 0644]
arch/x86/cpu/qemu/acpi/isa.asl [new file with mode: 0644]
arch/x86/cpu/qemu/acpi/pci-crs.asl [new file with mode: 0644]
arch/x86/cpu/qemu/dsdt.asl [new file with mode: 0644]

index 8c3884c..1c00d1d 100644 (file)
@@ -8,5 +8,5 @@ ifndef CONFIG_EFI_STUB
 obj-y += car.o dram.o
 endif
 obj-y += qemu.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o dsdt.o
 obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/cpu/qemu/acpi/cpu-hotplug.asl b/arch/x86/cpu/qemu/acpi/cpu-hotplug.asl
new file mode 100644 (file)
index 0000000..a290a4c
--- /dev/null
@@ -0,0 +1,80 @@
+/* CPU hotplug */
+
+Scope(\_SB) {
+    /* Objects filled in by run-time generated SSDT */
+    External(NTFY, MethodObj)
+    External(CPON, PkgObj)
+
+    /* Methods called by run-time generated SSDT Processor objects */
+    Method(CPMA, 1, NotSerialized) {
+           /*
+            * _MAT method - create an madt apic buffer
+            * Arg0 = Processor ID = Local APIC ID
+            * Local0 = CPON flag for this cpu
+            */
+        Store(DerefOf(Index(CPON, Arg0)), Local0)
+        /* Local1 = Buffer (in madt apic form) to return */
+        Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1)
+        /* Update the processor id, lapic id, and enable/disable status */
+        Store(Arg0, Index(Local1, 2))
+        Store(Arg0, Index(Local1, 3))
+        Store(Local0, Index(Local1, 4))
+        Return (Local1)
+    }
+    Method(CPST, 1, NotSerialized) {
+           /*
+            * _STA method - return ON status of cpu
+            * Arg0 = Processor ID = Local APIC ID
+            * Local0 = CPON flag for this cpu
+            */
+        Store(DerefOf(Index(CPON, Arg0)), Local0)
+        If (Local0) {
+            Return (0xf)
+        } Else {
+            Return (0x0)
+        }
+    }
+    Method(CPEJ, 2, NotSerialized) {
+        /* _EJ0 method - eject callback */
+        Sleep(200)
+    }
+
+    /* CPU hotplug notify method */
+    OperationRegion(PRST, SystemIO, 0xaf00, 32)
+    Field(PRST, ByteAcc, NoLock, Preserve) {
+        PRS, 256
+    }
+    Method(PRSC, 0) {
+        /* Local5 = active cpu bitmap */
+        Store(PRS, Local5)
+        /* Local2 = last read byte from bitmap */
+        Store(Zero, Local2)
+        /* Local0 = Processor ID / APIC ID iterator */
+        Store(Zero, Local0)
+        While (LLess(Local0, SizeOf(CPON))) {
+            /* Local1 = CPON flag for this cpu */
+            Store(DerefOf(Index(CPON, Local0)), Local1)
+            If (And(Local0, 0x07)) {
+                /* Shift down previously read bitmap byte */
+                ShiftRight(Local2, 1, Local2)
+            } Else {
+                /* Read next byte from cpu bitmap */
+                Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2)
+            }
+            /* Local3 = active state for this cpu */
+            Store(And(Local2, 1), Local3)
+
+            If (LNotEqual(Local1, Local3)) {
+                /* State change - update CPON with new state */
+                Store(Local3, Index(CPON, Local0))
+                /* Do CPU notify */
+                If (LEqual(Local3, 1)) {
+                    NTFY(Local0, 1)
+                } Else {
+                    NTFY(Local0, 3)
+                }
+            }
+            Increment(Local0)
+        }
+    }
+}
diff --git a/arch/x86/cpu/qemu/acpi/dbug.asl b/arch/x86/cpu/qemu/acpi/dbug.asl
new file mode 100644 (file)
index 0000000..38a6526
--- /dev/null
@@ -0,0 +1,25 @@
+/* Debugging */
+
+Scope(\) {
+    /* Debug Output */
+    OperationRegion(DBG, SystemIO, 0x0402, 0x01)
+    Field(DBG, ByteAcc, NoLock, Preserve) {
+        DBGB,   8,
+    }
+       /*
+        * Debug method - use this method to send output to the QEMU
+        * BIOS debug port.  This method handles strings, integers,
+        * and buffers.  For example: DBUG("abc") DBUG(0x123)
+        */
+    Method(DBUG, 1) {
+        ToHexString(Arg0, Local0)
+        ToBuffer(Local0, Local0)
+        Subtract(SizeOf(Local0), 1, Local1)
+        Store(Zero, Local2)
+        While (LLess(Local2, Local1)) {
+            Store(DerefOf(Index(Local0, Local2)), DBGB)
+            Increment(Local2)
+        }
+        Store(0x0a, dbgb)
+    }
+}
diff --git a/arch/x86/cpu/qemu/acpi/hpet.asl b/arch/x86/cpu/qemu/acpi/hpet.asl
new file mode 100644 (file)
index 0000000..983151e
--- /dev/null
@@ -0,0 +1,31 @@
+/* HPET */
+
+Scope(\_SB) {
+    Device(HPET) {
+        Name(_HID, EISAID("PNP0103"))
+        Name(_UID, 0)
+        OperationRegion(HPTM, SystemMemory, 0xfed00000, 0x400)
+        Field(HPTM, DWordAcc, Lock, Preserve) {
+            VEND, 32,
+            PRD, 32,
+        }
+        Method(_STA, 0, NotSerialized) {
+            Store(VEND, Local0)
+            Store(PRD, Local1)
+            ShiftRight(Local0, 16, Local0)
+            If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) {
+                Return (0x0)
+            }
+            If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) {
+                Return (0x0)
+            }
+            Return (0x0f)
+        }
+        Name(_CRS, ResourceTemplate() {
+            Memory32Fixed(ReadOnly,
+                0xfed00000,         /* Address Base */
+                0x00000400,         /* Address Length */
+                )
+        })
+    }
+}
diff --git a/arch/x86/cpu/qemu/acpi/isa.asl b/arch/x86/cpu/qemu/acpi/isa.asl
new file mode 100644 (file)
index 0000000..d6b3d9b
--- /dev/null
@@ -0,0 +1,102 @@
+/* Common legacy ISA style devices. */
+Scope(\_SB.PCI0.ISA) {
+
+    Device(RTC) {
+        Name(_HID, EisaId("PNP0B00"))
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0070, 0x0070, 0x10, 0x02)
+            IRQNoFlags() { 8 }
+            IO(Decode16, 0x0072, 0x0072, 0x02, 0x06)
+        })
+    }
+
+    Device(KBD) {
+        Name(_HID, EisaId("PNP0303"))
+        Method(_STA, 0, NotSerialized) {
+            Return (0x0f)
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0060, 0x0060, 0x01, 0x01)
+            IO(Decode16, 0x0064, 0x0064, 0x01, 0x01)
+            IRQNoFlags() { 1 }
+        })
+    }
+
+    Device(MOU) {
+        Name(_HID, EisaId("PNP0F13"))
+        Method(_STA, 0, NotSerialized) {
+            Return (0x0f)
+        }
+        Name(_CRS, ResourceTemplate() {
+            IRQNoFlags() { 12 }
+        })
+    }
+
+    Device(FDC0) {
+        Name(_HID, EisaId("PNP0700"))
+        Method(_STA, 0, NotSerialized) {
+            Store(FDEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0f)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x03f2, 0x03f2, 0x00, 0x04)
+            IO(Decode16, 0x03f7, 0x03f7, 0x00, 0x01)
+            IRQNoFlags() { 6 }
+            DMA(Compatibility, NotBusMaster, Transfer8) { 2 }
+        })
+    }
+
+    Device(LPT) {
+        Name(_HID, EisaId("PNP0400"))
+        Method(_STA, 0, NotSerialized) {
+            Store(LPEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0f)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0378, 0x0378, 0x08, 0x08)
+            IRQNoFlags() { 7 }
+        })
+    }
+
+    Device(COM1) {
+        Name(_HID, EisaId("PNP0501"))
+        Name(_UID, 0x01)
+        Method(_STA, 0, NotSerialized) {
+            Store(CAEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0f)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x03f8, 0x03f8, 0x00, 0x08)
+            IRQNoFlags() { 4 }
+        })
+    }
+
+    Device(COM2) {
+        Name(_HID, EisaId("PNP0501"))
+        Name(_UID, 0x02)
+        Method(_STA, 0, NotSerialized) {
+            Store(CBEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0f)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x02f8, 0x02f8, 0x00, 0x08)
+            IRQNoFlags() { 3 }
+        })
+    }
+}
diff --git a/arch/x86/cpu/qemu/acpi/pci-crs.asl b/arch/x86/cpu/qemu/acpi/pci-crs.asl
new file mode 100644 (file)
index 0000000..a336dce
--- /dev/null
@@ -0,0 +1,61 @@
+/* PCI CRS (current resources) definition. */
+Scope(\_SB.PCI0) {
+
+    Name(CRES, ResourceTemplate() {
+        WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
+            0x0000,             /* Address Space Granularity */
+            0x0000,             /* Address Range Minimum */
+            0x00ff,             /* Address Range Maximum */
+            0x0000,             /* Address Translation Offset */
+            0x0100,             /* Address Length */
+            ,, )
+        IO(Decode16,
+            0x0cf8,             /* Address Range Minimum */
+            0x0cf8,             /* Address Range Maximum */
+            0x01,               /* Address Alignment */
+            0x08,               /* Address Length */
+            )
+        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+            0x0000,             /* Address Space Granularity */
+            0x0000,             /* Address Range Minimum */
+            0x0cf7,             /* Address Range Maximum */
+            0x0000,             /* Address Translation Offset */
+            0x0cf8,             /* Address Length */
+            ,, , TypeStatic)
+        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+            0x0000,             /* Address Space Granularity */
+            0x0d00,             /* Address Range Minimum */
+            0xffff,             /* Address Range Maximum */
+            0x0000,             /* Address Translation Offset */
+            0xf300,             /* Address Length */
+            ,, , TypeStatic)
+        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+            0x00000000,         /* Address Space Granularity */
+            0x000a0000,         /* Address Range Minimum */
+            0x000bffff,         /* Address Range Maximum */
+            0x00000000,         /* Address Translation Offset */
+            0x00020000,         /* Address Length */
+            ,, , AddressRangeMemory, TypeStatic)
+        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+            0x00000000,         /* Address Space Granularity */
+            0xe0000000,         /* Address Range Minimum */
+            0xfebfffff,         /* Address Range Maximum */
+            0x00000000,         /* Address Translation Offset */
+            0x1ec00000,         /* Address Length */
+            ,, PW32, AddressRangeMemory, TypeStatic)
+    })
+
+    Name(CR64, ResourceTemplate() {
+        QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+            0x00000000,          /* Address Space Granularity */
+            0x80000000,        /* Address Range Minimum */
+            0xffffffff,        /* Address Range Maximum */
+            0x00000000,          /* Address Translation Offset */
+            0x80000000,        /* Address Length */
+            ,, PW64, AddressRangeMemory, TypeStatic)
+    })
+
+    Method(_CRS, 0) {
+        Return (CRES)
+    }
+}
diff --git a/arch/x86/cpu/qemu/dsdt.asl b/arch/x86/cpu/qemu/dsdt.asl
new file mode 100644 (file)
index 0000000..2b10f90
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * QEMU ACPI DSDT ASL definition
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * Copyright (c) 2010 Isaku Yamahata
+ *                    yamahata at valinux co jp
+ * Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
+ */
+
+DefinitionBlock (
+    "dsdt.aml",         /* Output Filename */
+    "DSDT",             /* Signature */
+    0x01,               /* DSDT Compliance Revision */
+    "UBOO",             /* OEMID */
+    "UBOOT   ",         /* TABLE ID */
+    0x2                 /* OEM Revision */
+    )
+{
+
+#include "acpi/dbug.asl"
+
+    Scope(\_SB) {
+        OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
+        OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
+        Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
+            PCIB, 8,
+        }
+    }
+
+
+/* PCI Bus definition */
+
+    Scope(\_SB) {
+        Device(PCI0) {
+            Name(_HID, EisaId("PNP0A08"))
+            Name(_CID, EisaId("PNP0A03"))
+            Name(_ADR, 0x00)
+            Name(_UID, 1)
+
+            /* _OSC: based on sample of ACPI3.0b spec */
+            Name(SUPP, 0) /* PCI _OSC Support Field value */
+            Name(CTRL, 0) /* PCI _OSC Control Field value */
+            Method(_OSC, 4) {
+                /* Create DWORD-addressable fields from Capabilities Buffer */
+                CreateDWordField(Arg3, 0, CDW1)
+
+                /* Check for proper UUID */
+                If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
+                        {
+                /* Create DWORD-addressable fields from Capabilities Buffer */
+                    CreateDWordField(Arg3, 4, CDW2)
+                    CreateDWordField(Arg3, 8, CDW3)
+
+                    /* Save Capabilities DWORD2 & 3 */
+                    Store(CDW2, SUPP)
+                    Store(CDW3, CTRL)
+
+                               /*
+                                * Always allow native PME, AER (no dependencies)
+                                * Never allow SHPC (no SHPC controller in this system)
+                                */
+                    And(CTRL, 0x1d, CTRL)
+
+                    If (LNotEqual(Arg1, One)) {
+                        /* Unknown revision */
+                        Or(CDW1, 0x08, CDW1)
+                    }
+                    If (LNotEqual(CDW3, CTRL)) {
+                        /* Capabilities bits were masked */
+                        Or(CDW1, 0x10, CDW1)
+                    }
+                    /* Update DWORD3 in the buffer */
+                    Store(CTRL, CDW3)
+                } Else {
+                    Or(CDW1, 4, CDW1) /* Unrecognized UUID */
+                }
+                Return (Arg3)
+            }
+        }
+    }
+
+#include "acpi/pci-crs.asl"
+#include "acpi/hpet.asl"
+
+
+/* VGA */
+
+    Scope(\_SB.PCI0) {
+        Device(VGA) {
+            Name(_ADR, 0x00010000)
+            Method(_S1D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S2D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S3D, 0, NotSerialized) {
+                Return (0x00)
+            }
+        }
+    }
+
+
+/* LPC ISA bridge */
+
+    Scope(\_SB.PCI0) {
+        /* PCI D31:f0 LPC ISA bridge */
+        Device(ISA) {
+            /* PCI D31:f0 */
+            Name(_ADR, 0x001f0000)
+
+            /* ICH9 PCI to ISA irq remapping */
+            OperationRegion(PIRQ, PCI_Config, 0x60, 0x0c)
+
+            OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
+            Field(LPCD, AnyAcc, NoLock, Preserve) {
+                COMA,   3,
+                    ,   1,
+                COMB,   3,
+
+                Offset(0x01),
+                LPTD,   2,
+                    ,   2,
+                FDCD,   2
+            }
+            OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
+            Field(LPCE, AnyAcc, NoLock, Preserve) {
+                CAEN,   1,
+                CBEN,   1,
+                LPEN,   1,
+                FDEN,   1
+            }
+        }
+    }
+
+#include "acpi/isa.asl"
+
+
+/* PCI IRQs */
+
+    /* Zero => PIC mode, One => APIC Mode */
+    Name(\PICF, Zero)
+    Method(\_PIC, 1, NotSerialized) {
+        Store(Arg0, \PICF)
+    }
+
+    Scope(\_SB) {
+        Scope(PCI0) {
+#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3)  \
+    Package() { nr##ffff, 0, lnk0, 0 },           \
+    Package() { nr##ffff, 1, lnk1, 0 },           \
+    Package() { nr##ffff, 2, lnk2, 0 },           \
+    Package() { nr##ffff, 3, lnk3, 0 }
+
+#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
+#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
+#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
+#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
+
+#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
+#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
+#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
+#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
+
+            Name(PRTP, Package() {
+                prt_slot_lnkE(0x0000),
+                prt_slot_lnkF(0x0001),
+                prt_slot_lnkG(0x0002),
+                prt_slot_lnkH(0x0003),
+                prt_slot_lnkE(0x0004),
+                prt_slot_lnkF(0x0005),
+                prt_slot_lnkG(0x0006),
+                prt_slot_lnkH(0x0007),
+                prt_slot_lnkE(0x0008),
+                prt_slot_lnkF(0x0009),
+                prt_slot_lnkG(0x000a),
+                prt_slot_lnkH(0x000b),
+                prt_slot_lnkE(0x000c),
+                prt_slot_lnkF(0x000d),
+                prt_slot_lnkG(0x000e),
+                prt_slot_lnkH(0x000f),
+                prt_slot_lnkE(0x0010),
+                prt_slot_lnkF(0x0011),
+                prt_slot_lnkG(0x0012),
+                prt_slot_lnkH(0x0013),
+                prt_slot_lnkE(0x0014),
+                prt_slot_lnkF(0x0015),
+                prt_slot_lnkG(0x0016),
+                prt_slot_lnkH(0x0017),
+                prt_slot_lnkE(0x0018),
+
+                /* INTA -> PIRQA for slot 25 - 31
+                   see the default value of D<N>IR */
+                prt_slot_lnkA(0x0019),
+                prt_slot_lnkA(0x001a),
+                prt_slot_lnkA(0x001b),
+                prt_slot_lnkA(0x001c),
+                prt_slot_lnkA(0x001d),
+
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
+                prt_slot_lnkE(0x001e),
+
+                prt_slot_lnkA(0x001f)
+            })
+
+#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3)  \
+    Package() { nr##ffff, 0, gsi0, 0 },           \
+    Package() { nr##ffff, 1, gsi1, 0 },           \
+    Package() { nr##ffff, 2, gsi2, 0 },           \
+    Package() { nr##ffff, 3, gsi3, 0 }
+
+#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
+#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
+#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
+#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
+
+#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
+#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
+#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
+#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
+
+            Name(PRTA, Package() {
+                prt_slot_gsiE(0x0000),
+                prt_slot_gsiF(0x0001),
+                prt_slot_gsiG(0x0002),
+                prt_slot_gsiH(0x0003),
+                prt_slot_gsiE(0x0004),
+                prt_slot_gsiF(0x0005),
+                prt_slot_gsiG(0x0006),
+                prt_slot_gsiH(0x0007),
+                prt_slot_gsiE(0x0008),
+                prt_slot_gsiF(0x0009),
+                prt_slot_gsiG(0x000a),
+                prt_slot_gsiH(0x000b),
+                prt_slot_gsiE(0x000c),
+                prt_slot_gsiF(0x000d),
+                prt_slot_gsiG(0x000e),
+                prt_slot_gsiH(0x000f),
+                prt_slot_gsiE(0x0010),
+                prt_slot_gsiF(0x0011),
+                prt_slot_gsiG(0x0012),
+                prt_slot_gsiH(0x0013),
+                prt_slot_gsiE(0x0014),
+                prt_slot_gsiF(0x0015),
+                prt_slot_gsiG(0x0016),
+                prt_slot_gsiH(0x0017),
+                prt_slot_gsiE(0x0018),
+
+                       /*
+                        * INTA -> PIRQA for slot 25 - 31, but 30
+                        * see the default value of D<N>IR
+                        */
+                prt_slot_gsiA(0x0019),
+                prt_slot_gsiA(0x001a),
+                prt_slot_gsiA(0x001b),
+                prt_slot_gsiA(0x001c),
+                prt_slot_gsiA(0x001d),
+
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
+                prt_slot_gsiE(0x001e),
+
+                prt_slot_gsiA(0x001f)
+            })
+
+            Method(_PRT, 0, NotSerialized) {
+                         /*
+                          * PCI IRQ routing table,
+                          * example from ACPI 2.0a
+                          * specification, section 6.2.8.1
+                          * Note: we provide the same info
+                          * as the PCI routing table
+                          * of the Bochs BIOS
+                          */
+                If (LEqual(\PICF, Zero)) {
+                    Return (PRTP)
+                } Else {
+                    Return (PRTA)
+                }
+            }
+        }
+
+        Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
+            PRQA,   8,
+            PRQB,   8,
+            PRQC,   8,
+            PRQD,   8,
+
+            Offset(0x08),
+            PRQE,   8,
+            PRQF,   8,
+            PRQG,   8,
+            PRQH,   8
+        }
+
+        Method(IQST, 1, NotSerialized) {
+            /* _STA method - get status */
+            If (And(0x80, Arg0)) {
+                Return (0x09)
+            }
+            Return (0x0b)
+        }
+        Method(IQCR, 1, NotSerialized) {
+            /* _CRS method - get current settings */
+            Name(PRR0, ResourceTemplate() {
+                Interrupt(, Level, ActiveHigh, Shared) { 0 }
+            })
+            CreateDWordField(PRR0, 0x05, PRRI)
+            Store(And(Arg0, 0x0f), PRRI)
+            Return (PRR0)
+        }
+
+#define define_link(link, uid, reg)                             \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    5, 10, 11                                   \
+                }                                               \
+            })                                                  \
+            Method(_STA, 0, NotSerialized) {                    \
+                Return (IQST(reg))                              \
+            }                                                   \
+            Method(_DIS, 0, NotSerialized) {                    \
+                Or(reg, 0x80, reg)                              \
+            }                                                   \
+            Method(_CRS, 0, NotSerialized) {                    \
+                Return (IQCR(reg))                              \
+            }                                                   \
+            Method(_SRS, 1, NotSerialized) {                    \
+                CreateDWordField(Arg0, 0x05, PRRI)              \
+                Store(PRRI, reg)                                \
+            }                                                   \
+        }
+
+        define_link(LNKA, 0, PRQA)
+        define_link(LNKB, 1, PRQB)
+        define_link(LNKC, 2, PRQC)
+        define_link(LNKD, 3, PRQD)
+        define_link(LNKE, 4, PRQE)
+        define_link(LNKF, 5, PRQF)
+        define_link(LNKG, 6, PRQG)
+        define_link(LNKH, 7, PRQH)
+
+#define define_gsi_link(link, uid, gsi)                         \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    gsi                                         \
+                }                                               \
+            })                                                  \
+            Name(_CRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    gsi                                         \
+                }                                               \
+            })                                                  \
+            Method(_SRS, 1, NotSerialized) {                    \
+            }                                                   \
+        }
+
+        define_gsi_link(GSIA, 0, 0x10)
+        define_gsi_link(GSIB, 0, 0x11)
+        define_gsi_link(GSIC, 0, 0x12)
+        define_gsi_link(GSID, 0, 0x13)
+        define_gsi_link(GSIE, 0, 0x14)
+        define_gsi_link(GSIF, 0, 0x15)
+        define_gsi_link(GSIG, 0, 0x16)
+        define_gsi_link(GSIH, 0, 0x17)
+    }
+
+/* General purpose events */
+
+    Scope(\_GPE) {
+        Name(_HID, "ACPI0006")
+
+        Method(_L00) {
+        }
+        Method(_L01) {
+        }
+        Method(_L02) {
+        }
+        Method(_L03) {
+        }
+        Method(_L04) {
+        }
+        Method(_L05) {
+        }
+        Method(_L06) {
+        }
+        Method(_L07) {
+        }
+        Method(_L08) {
+        }
+        Method(_L09) {
+        }
+        Method(_L0A) {
+        }
+        Method(_L0B) {
+        }
+        Method(_L0C) {
+        }
+        Method(_L0D) {
+        }
+        Method(_L0E) {
+        }
+        Method(_L0F) {
+        }
+    }
+}