Initial commit of seabios/acpi for OVSS VM open source license compliance

Change-Id: I186679c02ccdf895390ea86f65a45b82f8344a60
diff --git a/acpi/LICENSE b/acpi/LICENSE
new file mode 100644
index 0000000..a42a477
--- /dev/null
+++ b/acpi/LICENSE
@@ -0,0 +1,406 @@
+The files in this version are derived from seabios/src/fw/acpi-dsdt.dsl which
+has the following license header:
+
+/*
+ * Bochs/QEMU ACPI DSDT ASL definition
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+The full text of the referenced license is as follows:
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public Licenses are intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.
+
+This license, the Library General Public License, applies to some specially
+designated Free Software Foundation software, and to any other libraries whose
+authors decide to use it. You can use it for your libraries, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for this service if you
+wish), that you receive source code or can get it if you want it, that you
+can change the software or use pieces of it in new free programs; and that
+you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of
+the library, or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for
+a fee, you must give the recipients all the rights that we gave you. You must
+make sure that they, too, receive or can get the source code. If you link
+a program with the library, you must provide complete object files to the
+recipients so that they can relink them with the library, after making changes
+to the library and recompiling it. And you must show them these terms so they
+know their rights.
+
+Our method of protecting your rights has two steps: (1) copyright the library,
+and (2) offer you this license which gives you legal permission to copy, distribute
+and/or modify the library.
+
+Also, for each distributor's protection, we want to make certain that everyone
+understands that there is no warranty for this free library. If the library
+is modified by someone else and passed on, we want its recipients to know
+that what they have is not the original version, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that companies distributing free software will individually
+obtain patent licenses, thus in effect transforming the program into proprietary
+software. To prevent this, we have made it clear that any patent must be licensed
+for everyone's free use or not licensed at all.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU
+General Public License, which was designed for utility programs. This license,
+the GNU Library General Public License, applies to certain designated libraries.
+This license is quite different from the ordinary one; be sure to read it
+in full, and don't assume that anything in it is the same as in the ordinary
+license.
+
+The reason we have a separate public license for some libraries is that they
+blur the distinction we usually make between modifying or adding to a program
+and simply using it. Linking a program with a library, without changing the
+library, is in some sense simply using the library, and is analogous to running
+a utility program or application program. However, in a textual and legal
+sense, the linked executable is a combined work, a derivative of the original
+library, and the ordinary General Public License treats it as such.
+
+Because of this blurred distinction, using the ordinary General Public License
+for libraries did not effectively promote software sharing, because most developers
+did not use the libraries. We concluded that weaker conditions might promote
+sharing better.
+
+However, unrestricted linking of non-free programs would deprive the users
+of those programs of all benefit from the free status of the libraries themselves.
+This Library General Public License is intended to permit developers of non-free
+programs to use free libraries, while preserving your freedom as a user of
+such programs to change the free libraries that are incorporated in them.
+(We have not seen how to achieve this as regards changes in header files,
+but we have achieved it as regards changes in the actual functions of the
+Library.) The hope is that this will lead to faster development of free libraries.
+
+The precise terms and conditions for copying, distribution and modification
+follow. Pay close attention to the difference between a "work based on the
+library" and a "work that uses the library". The former contains code derived
+from the library, while the latter only works together with the library.
+
+Note that it is possible for a library to be covered by the ordinary General
+Public License rather than by this special one.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library which contains a
+notice placed by the copyright holder or other authorized party saying it
+may be distributed under the terms of this Library General Public License
+(also called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared
+so as to be conveniently linked with application programs (which use some
+of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has
+been distributed under these terms. A "work based on the Library" means either
+the Library or any derivative work under copyright law: that is to say, a
+work containing the Library or a portion of it, either verbatim or with modifications
+and/or translated straightforwardly into another language. (Hereinafter, translation
+is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications
+to it. For a library, complete source code means all the source code for all
+modules it contains, plus any associated interface definition files, plus
+the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running a program
+using the Library is not restricted, and output from such a program is covered
+only if its contents constitute a work based on the Library (independent of
+the use of the Library in a tool for writing it). Whether that is true depends
+on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and disclaimer
+of warranty; keep intact all the notices that refer to this License and to
+the absence of any warranty; and distribute a copy of this License along with
+the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it,
+thus forming a work based on the Library, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all
+of these conditions:
+
+      a) The modified work must itself be a software library.
+
+b) You must cause the files modified to carry prominent notices stating that
+you changed the files and the date of any change.
+
+c) You must cause the whole of the work to be licensed at no charge to all
+third parties under the terms of this License.
+
+d) If a facility in the modified Library refers to a function or a table of
+data to be supplied by an application program that uses the facility, other
+than as an argument passed when the facility is invoked, then you must make
+a good faith effort to ensure that, in the event an application does not supply
+such function or table, the facility still operates, and performs whatever
+part of its purpose remains meaningful.
+
+(For example, a function in a library to compute square roots has a purpose
+that is entirely well-defined independent of the application. Therefore, Subsection
+2d requires that any application-supplied function or table used by this function
+must be optional: if the application does not supply it, the square root function
+must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Library, and can be reasonably
+considered independent and separate works in themselves, then this License,
+and its terms, do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part of a whole
+which is a work based on the Library, the distribution of the whole must be
+on the terms of this License, whose permissions for other licensees extend
+to the entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works based
+on the Library.
+
+In addition, mere aggregation of another work not based on the Library with
+the Library (or with a work based on the Library) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License
+instead of this License to a given copy of the Library. To do this, you must
+alter all the notices that refer to this License, so that they refer to the
+ordinary GNU General Public License, version 2, instead of to this License.
+(If a newer version than version 2 of the ordinary GNU General Public License
+has appeared, then you can specify that version instead if you wish.) Do not
+make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy,
+so the ordinary GNU General Public License applies to all subsequent copies
+and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library
+into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of
+it, under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you accompany it with the complete corresponding
+machine-readable source code, which must be distributed under the terms of
+Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated
+place, then offering equivalent access to copy the source code from the same
+place satisfies the requirement to distribute the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but
+is designed to work with the Library by being compiled or linked with it,
+is called a "work that uses the Library". Such a work, in isolation, is not
+a derivative work of the Library, and therefore falls outside the scope of
+this License.
+
+However, linking a "work that uses the Library" with the Library creates an
+executable that is a derivative of the Library (because it contains portions
+of the Library), rather than a "work that uses the library". The executable
+is therefore covered by this License. Section 6 states terms for distribution
+of such executables.
+
+When a "work that uses the Library" uses material from a header file that
+is part of the Library, the object code for the work may be a derivative work
+of the Library even though the source code is not. Whether this is true is
+especially significant if the work can be linked without the Library, or if
+the work is itself a library. The threshold for this to be true is not precisely
+defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts
+and accessors, and small macros and small inline functions (ten lines or less
+in length), then the use of the object file is unrestricted, regardless of
+whether it is legally a derivative work. (Executables containing this object
+code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute
+the object code for the work under the terms of Section 6. Any executables
+containing that work also fall under Section 6, whether or not they are linked
+directly with the Library itself.
+
+6. As an exception to the Sections above, you may also compile or link a "work
+that uses the Library" with the Library to produce a work containing portions
+of the Library, and distribute that work under terms of your choice, provided
+that the terms permit modification of the work for the customer's own use
+and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library
+is used in it and that the Library and its use are covered by this License.
+You must supply a copy of this License. If the work during execution displays
+copyright notices, you must include the copyright notice for the Library among
+them, as well as a reference directing the user to the copy of this License.
+Also, you must do one of these things:
+
+a) Accompany the work with the complete corresponding machine-readable source
+code for the Library including whatever changes were used in the work (which
+must be distributed under Sections 1 and 2 above); and, if the work is an
+executable linked with the Library, with the complete machine-readable "work
+that uses the Library", as object code and/or source code, so that the user
+can modify the Library and then relink to produce a modified executable containing
+the modified Library. (It is understood that the user who changes the contents
+of definitions files in the Library will not necessarily be able to recompile
+the application to use the modified definitions.)
+
+b) Accompany the work with a written offer, valid for at least three years,
+to give the same user the materials specified in Subsection 6a, above, for
+a charge no more than the cost of performing this distribution.
+
+c) If distribution of the work is made by offering access to copy from a designated
+place, offer equivalent access to copy the above specified materials from
+the same place.
+
+d) Verify that the user has already received a copy of these materials or
+that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must
+include any data and utility programs needed for reproducing the executable
+from it. However, as a special exception, the source code distributed need
+not include anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the operating
+system on which the executable runs, unless that component itself accompanies
+the executable.
+
+It may happen that this requirement contradicts the license restrictions of
+other proprietary libraries that do not normally accompany the operating system.
+Such a contradiction means you cannot use both them and the Library together
+in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side
+in a single library together with other library facilities not covered by
+this License, and distribute such a combined library, provided that the separate
+distribution of the work based on the Library and of the other library facilities
+is otherwise permitted, and provided that you do these two things:
+
+a) Accompany the combined library with a copy of the same work based on the
+Library, uncombined with any other library facilities. This must be distributed
+under the terms of the Sections above.
+
+b) Give prominent notice with the combined library of the fact that part of
+it is a work based on the Library, and explaining where to find the accompanying
+uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library
+except as expressly provided under this License. Any attempt otherwise to
+copy, modify, sublicense, link with, or distribute the Library is void, and
+will automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Library or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the Library
+(or any work based on the Library), you indicate your acceptance of this License
+to do so, and all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library),
+the recipient automatically receives a license from the original licensor
+to copy, distribute, link with or modify the Library subject to these terms
+and conditions. You may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible for enforcing
+compliance by third parties to this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement
+or for any other reason (not limited to patent issues), conditions are imposed
+on you (whether by court order, agreement or otherwise) that contradict the
+conditions of this License, they do not excuse you from the conditions of
+this License. If you cannot distribute so as to satisfy simultaneously your
+obligations under this License and any other pertinent obligations, then as
+a consequence you may not distribute the Library at all. For example, if a
+patent license would not permit royalty-free redistribution of the Library
+by all those who receive copies directly or indirectly through you, then the
+only way you could satisfy both it and this License would be to refrain entirely
+from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system which is implemented by public license practices.
+Many people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Library under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is
+permitted only in or among countries not thus excluded. In such case, this
+License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of
+the Library General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to address
+new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the
+Library does not specify a license version number, you may choose any version
+ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs
+whose distribution conditions are incompatible with these, write to the author
+to ask for permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes make exceptions
+for this. Our decision will be guided by the two goals of preserving the free
+status of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+   NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
+"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
+THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
+OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
+OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
+OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
+HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
diff --git a/acpi/README.md b/acpi/README.md
new file mode 100644
index 0000000..05a0ea6
--- /dev/null
+++ b/acpi/README.md
@@ -0,0 +1,18 @@
+# GCE ACPI Templates
+
+This is a collection of ASL-language ACPI table templates used by GCE virtual
+machines. They are derived from DSL files in the
+[Seabios](https://github.com/coreboot/seabios) project and modified for GCE's
+purposes.
+
+The contents do not comprise a usable version of the Seabios system firmware.
+They are provided here to clarify ACPI table provenance. They make explicit the
+nature of the relationship to GCE proprietary source code and maintain
+separation from the private codebase.
+
+These cannot and should not be used without correctly-calibrated text template
+processing and ASL interpretation.
+
+Corresponding source code for interpreting these files is not
+provided—**the scope of this folder is merely license clarification and
+compliance.**
diff --git a/acpi/dsdt_x86 b/acpi/dsdt_x86
new file mode 100644
index 0000000..2a9743f
--- /dev/null
+++ b/acpi/dsdt_x86
@@ -0,0 +1,1202 @@
+DefinitionBlock ("", "DSDT", 2, "Google", "GOOGDSDT", 0x00000001)
+{
+    External (_SB_.CPON, PkgObj)
+    External (_SB_.MNOT, MethodObj)    // 2 Arguments
+    External (_SB_.NTFY, MethodObj)    // 2 Arguments
+    External (_SB_.PCI0.PCNT, MethodObj)    // 2 Arguments
+    Scope (\)
+    {
+        // Debug method - use this method to send output to the BIOS debug port.
+        // This method handles strings, integers, and buffers.
+        // For example: DBUG("abc") DBUG(0x123)
+        OperationRegion (DBG, SystemIO, {{ u16max }}, One)
+        Field (DBG, ByteAcc, NoLock, Preserve)
+        {
+            DBGB,   8
+        }
+        Method (DBUG, 1, NotSerialized)
+        {
+            ToHexString (Arg0, Local0)
+            ToBuffer (Local0, Local0)
+            Local1 = (SizeOf (Local0) - One)
+            Local2 = Zero
+            While ((Local2 < Local1))
+            {
+                DBGB = DerefOf (Local0 [Local2])
+                Local2++
+            }
+            DBGB = 0x0A
+        }
+    }
+    Scope (_SB)
+    {
+        // Boolean value representing whether to add the _OSC method.
+        Name (POSC, {{ posc }})
+        // Boolean value representing whether to use zero-based regions.
+        Name (ZBR, {{ zbr }})
+        Device (PCI0)
+        {
+            Name (_HID, EisaId ("PNP0A03") /* PCI Bus */)  // _HID: Hardware ID
+            Name (_UID, One)  // _UID: Unique ID
+            Name (_BBN, Zero)  // _BBN: BIOS Bus Number
+            Name (_PXM, Zero)  // _PXM: Device Proximity
+            // The templates modified and returned by the _CRS method.
+            Name (CRES, ResourceTemplate ()
+            {
+                // PCI bus numbers
+                WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+                    0x0000,             // Granularity
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x0000,             // Translation Offset
+                    0x0000,             // Length
+                    ,, PCBN)
+                // PCI config
+                IO (Decode16,
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x01,               // Alignment
+                    0x00,               // Length
+                    PCFG)
+                // 16-bit low chunk before PCI config
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x0000,             // Granularity
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x0000,             // Translation Offset
+                    0x0000,             // Length
+                    ,, PLOW, TypeStatic, DenseTranslation)
+                // 16-bit next chunk after PCI config
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x0000,             // Granularity
+                    0x0000,             // Range Minimum
+                    0x0FFF,             // Range Maximum
+                    0x0000,             // Translation Offset
+                    0x1000,             // Length
+                    ,, PCHK, TypeStatic, DenseTranslation)
+                // 16-bit PCI I/O
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x0000,             // Granularity
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x0000,             // Translation Offset
+                    0x0000,             // Length
+                    ,, PC16, TypeStatic, DenseTranslation)
+                // Hotplug and power management legacy region
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x0000,             // Granularity
+                    0xA000,             // Range Minimum
+                    0xBFFF,             // Range Maximum
+                    0x0000,             // Translation Offset
+                    0x2000,             // Length
+                    ,, , TypeStatic, DenseTranslation)
+                // VGA framebuffer
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+                    0x00000000,         // Granularity
+                    0x00000000,         // Range Minimum
+                    0x00000000,         // Range Maximum
+                    0x00000000,         // Translation Offset
+                    0x00000000,         // Length
+                    ,, VGAF, AddressRangeMemory, TypeStatic)
+                // 32-bit PCI memory
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+                    0x00000000,         // Granularity
+                    0x00000000,         // Range Minimum
+                    0x00000000,         // Range Maximum
+                    0x00000000,         // Translation Offset
+                    0x00000000,         // Length
+                    ,, PM32, AddressRangeMemory, TypeStatic)
+            })
+            // Template to be concatenated for each active CRS allowlist entry
+            Name (CRWM, ResourceTemplate ()
+            {
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+                    0x00000000,         // Granularity
+                    0x00000000,         // Range Minimum
+                    0x00000000,         // Range Maximum
+                    0x00000000,         // Translation Offset
+                    0x00000000,         // Length
+                    ,, PC32, AddressRangeMemory, TypeStatic)
+            })
+            // 64-bit PCI memory
+            Name (CR64, ResourceTemplate ()
+            {
+                QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+                    0x0000000000000000, // Granularity
+                    0x0000000000000000, // Range Minimum
+                    0x0000000000000000, // Range Maximum
+                    0x0000000000000000, // Translation Offset
+                    0x0000000000000000, // Length
+                    ,, PC64, AddressRangeMemory, TypeStatic)
+            })
+            // The address values patched before sending the table to the VM.
+            Name (PBBS, {{ u16max }})
+            Name (PBBE, {{ u16max }})
+            Name (PBIS, {{ u16max }})
+            Name (PBIE, {{ u16max }})
+            Name (PB0S, {{ u32max }})
+            Name (PB0E, {{ u32max }})
+## for hole_index in range(11)
+            Name (PWS{{ hex(hole_index) }}, {{ u32max }})
+            Name (PWE{{ hex(hole_index) }}, {{ u32max }})
+## endfor
+            Name (PB1V, {{ u8max }})
+            Name (PB1S, {{ u64max }})
+            Name (PB1E, {{ u64max }})
+            Name (PB1L, {{ u64max }})
+            Name (PPCI, {{ u16max }})
+            Name (VGAS, {{ u32max }})
+            Name (VGAL, {{ u32max }})
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                // Fix PCI bus numbers
+                CreateWordField (CRES, ^PCBN._MIN, BS32)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^PCBN._MAX, BE32)  // _MAX: Maximum Base Address
+                CreateWordField (CRES, ^PCBN._LEN, BL32)  // _LEN: Length
+                BS32 = PBBS /* \_SB_.PCI0.PBBS */
+                BE32 = PBBE /* \_SB_.PCI0.PBBE */
+                BL32 = ((PBBE - PBBS) + One)
+                // Lowest chunk of 16-bit addresses
+                CreateWordField (CRES, ^PLOW._MIN, LMIN)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^PLOW._MAX, LMAX)  // _MAX: Maximum Base Address
+                CreateWordField (CRES, ^PLOW._LEN, LLEN)  // _LEN: Length
+                LMIN = Zero
+                LMAX = PPCI - One
+                LLEN = PPCI
+                // PCI config range
+                CreateWordField (CRES, ^PCFG._MIN, PMIN)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^PCFG._MAX, PMAX)  // _MAX: Maximum Base Address
+                CreateByteField (CRES, ^PCFG._LEN, PLEN)  // _LEN: Length
+                PMIN = PPCI
+                PMAX = PPCI
+                PLEN = 0x8
+                // Remaining 16-bit memory below 0x1000
+                CreateWordField (CRES, ^PCHK._MIN, CMIN)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^PCHK._MAX, CMAX)  // _MAX: Maximum Base Address
+                CreateWordField (CRES, ^PCHK._LEN, CLEN)  // _LEN: Length
+                CMIN = PMIN + PLEN
+                CLEN = ((CMAX - CMIN) + One)
+                // PCI 16-bit I/O range
+                CreateWordField (CRES, ^PC16._MIN, IS32)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^PC16._MAX, IE32)  // _MAX: Maximum Base Address
+                CreateWordField (CRES, ^PC16._LEN, IL32)  // _LEN: Length
+                IS32 = PBIS /* \_SB_.PCI0.PBIS */
+                IE32 = PBIE /* \_SB_.PCI0.PBIE */
+                IL32 = ((PBIE - PBIS) + One)
+                If ((!ZBR && ((IS32 == Zero) && (IE32 == Zero))))
+                {
+                    IL32 = Zero
+                }
+                // VGA framebuffer
+                CreateDWordField (CRES, ^VGAF._MIN, FMIN)  // _MIN: Minimum Base Address
+                CreateDWordField (CRES, ^VGAF._MAX, FMAX)  // _MAX: Maximum Base Address
+                CreateDWordField (CRES, ^VGAF._LEN, FLEN)  // _LEN: Length
+                FMIN = VGAS
+                FMAX = ((VGAS + VGAL) - One)
+                FLEN = VGAL
+                // PCI 32-bit range
+                CreateDWordField (CRES, ^PM32._MIN, PS32)  // _MIN: Minimum Base Address
+                CreateDWordField (CRES, ^PM32._MAX, PE32)  // _MAX: Maximum Base Address
+                CreateDWordField (CRES, ^PM32._LEN, PL32)  // _LEN: Length
+                If ((PWS0 != Zero))
+                {
+                    PS32 = PWS0 /* \_SB_.PCI0.PWS0 */
+                    PE32 = PWE0 /* \_SB_.PCI0.PWE0 */
+                    PL32 = ((PWE0 - PWS0) + One)
+                }
+                Else
+                {
+                    PS32 = PB0S /* \_SB_.PCI0.PB0S */
+                    PE32 = PB0E /* \_SB_.PCI0.PB0E */
+                    PL32 = ((PB0E - PB0S) + One)
+                }
+                If ((!ZBR && ((PS32 == Zero) && (PE32 == Zero))))
+                {
+                    PL32 = Zero
+                }
+                // Concatenate all active PCI CRS allowlist entries
+                Local0 = CRES /* \_SB_.PCI0.CRES */
+                CreateDWordField (CRWM, ^PC32._MIN, RS32)  // _MIN: Minimum Base Address
+                CreateDWordField (CRWM, ^PC32._MAX, RE32)  // _MAX: Maximum Base Address
+                CreateDWordField (CRWM, ^PC32._LEN, RL32)  // _LEN: Length
+## for hole in pci_crs_holes
+                    If (({{ hole.start }} != Zero))
+                    {
+                        RS32 = {{ hole.start }}
+                        RE32 = {{ hole.end }}
+                        RL32 = (({{ hole.end }} - {{ hole.start }}) + One)
+                        ConcatenateResTemplate (Local0, CRWM, Local0)
+                    }
+## endfor
+                // PCI 64-bit range
+                If ((PB1V == Zero))
+                {
+                    Return (Local0)
+                }
+                CreateQWordField (CR64, ^PC64._MIN, PS64)  // _MIN: Minimum Base Address
+                CreateQWordField (CR64, ^PC64._MAX, PE64)  // _MAX: Maximum Base Address
+                CreateQWordField (CR64, ^PC64._LEN, PL64)  // _LEN: Length
+                PS64 = PB1S /* \_SB_.PCI0.PB1S */
+                PE64 = PB1E /* \_SB_.PCI0.PB1E */
+                PL64 = PB1L /* \_SB_.PCI0.PB1L */
+                ConcatenateResTemplate (Local0, CR64, Local0)
+                Return (Local0)
+            }
+            // Report PCI host bridge capabilities to allow PCI hotplug
+            If (POSC)
+            {
+                Name (SUPP, Zero)
+                Name (CTRL, Zero)
+                Method (_OSC, 4, Serialized)  // _OSC: Operating System Capabilities
+                {
+                    CreateDWordField (Arg3, Zero, CDW1)
+                    If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
+                    {
+                        CreateDWordField (Arg3, 0x04, CDW2)
+                        CreateDWordField (Arg3, 0x08, CDW3)
+                        SUPP = CDW2 /* \_SB_.PCI0._OSC.CDW2 */
+                        CTRL = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
+                        CTRL &= 0x1F
+                        If ((Arg1 != One))
+                        {
+                            CDW1 |= 0x08
+                        }
+                        If ((CDW3 != CTRL))
+                        {
+                            CDW1 |= 0x10
+                        }
+                        CDW3 = CTRL /* \_SB_.PCI0.CTRL */
+                        Return (Arg3)
+                    }
+                    Else
+                    {
+                        CDW1 |= 0x04
+                        Return (Arg3)
+                    }
+                }
+            }
+            // Provides mapping from PCI interrupt pins to interrupt inputs of
+            // interrupt controllers. NOTE: Same mapping as PCI routing table
+            // from Bochs BIOS.
+            Name (_PRT, Package (0x80)  // _PRT: PCI Routing Table
+            {
+## for link in pci_links
+                Package (0x04)
+                {
+                    {{ link.address }},
+                    {{ link.pin }},
+                    // First device is power management and can only use IRQ 9 from LNKS
+                    {% if link.pin == "0" and link.address == "0x0001FFFF" %}LNKS{% else %}{{ link.name }}{% endif %},
+                    Zero
+                }{% if not loop.is_last %},{% endif %}
+## endfor
+            })
+        }
+    }
+    Scope (_SB.PCI0)
+    {
+        Device (VGA)
+        {
+            Name (_ADR, 0x00020000)  // _ADR: Address
+            OperationRegion (PCIC, PCI_Config, Zero, 0x04)
+            Field (PCIC, DWordAcc, NoLock, Preserve)
+            {
+                VEND,   32
+            }
+            Method (_S1D, 0, NotSerialized)  // _S1D: S1 Device State
+            {
+                Return (Zero)
+            }
+            Method (_S2D, 0, NotSerialized)  // _S2D: S2 Device State
+            {
+                Return (Zero)
+            }
+            Method (_S3D, 0, NotSerialized)  // _S3D: S3 Device State
+            {
+                If ((VEND == 0x01001B36))
+                {
+                    Return (0x03)
+                }
+                Else
+                {
+                    Return (Zero)
+                }
+            }
+        }
+    }
+    Scope (_SB.PCI0)
+    {
+        // PIIX4 PM
+        Device (PX13)
+        {
+            Name (_ADR, 0x00010003)  // _ADR: Address
+            OperationRegion (P13C, PCI_Config, Zero, 0xFF)
+        }
+    }
+    Scope (_SB.PCI0)
+    {
+        // PIIX3 ISA bridge
+        Device (ISA)
+        {
+            Name (_ADR, 0x00010000)  // _ADR: Address
+            // PIIX PCI to ISA IRQ remapping
+            OperationRegion (P40C, PCI_Config, 0x60, 0x04)
+            // Enable bits
+            Field (^PX13.P13C, AnyAcc, NoLock, Preserve)
+            {
+                Offset (0x5F),
+                    ,   7,
+                LPEN,   1,
+                Offset (0x67),
+                    ,   3,
+                CAEN,   1,
+                    ,   3,
+                CBEN,   1
+            }
+            Name (FDEN, Zero)
+        }
+    }
+    // Common legacy ISA style devices
+    Scope (_SB.PCI0.ISA)
+    {
+        OperationRegion (ISAE, SystemIO, {{ u16max }}, One)
+        Field (ISAE, ByteAcc, NoLock, WriteAsZeros)
+        {
+            SERA,   1,
+            SERB,   1,
+            KBDC,   1,
+            WPEN,   1,
+            SERC,   1,
+            SERD,   1,
+                ,   1,
+            LGCY,   1
+        }
+        Device (RTC)
+        {
+            Name (_HID, EisaId ("PNP0B00") /* AT Real-Time Clock */)  // _HID: Hardware ID
+            Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+            {
+                IO (Decode16,
+                    0x0070,             // Range Minimum
+                    0x0070,             // Range Maximum
+                    0x10,               // Alignment
+                    0x02,               // Length
+                    )
+                IRQNoFlags ()
+                    {8}
+                IO (Decode16,
+                    0x0072,             // Range Minimum
+                    0x0072,             // Range Maximum
+                    0x02,               // Alignment
+                    0x06,               // Length
+                    )
+            })
+        }
+        // IBM Enhanced Keyboard
+        Device (KBD)
+        {
+            Name (_HID, EisaId ("PNP0303") /* IBM Enhanced Keyboard (101/102-key, PS/2 Mouse) */)  // _HID: Hardware ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Local0 = LGCY /* \_SB_.PCI0.ISA_.LGCY */
+                If ((Local0 == Zero))
+                {
+                    Local1 = KBDC /* \_SB_.PCI0.ISA_.KBDC */
+                    If ((Local1 == Zero))
+                    {
+                        Return (Zero)
+                    }
+                    Else
+                    {
+                        Return (0x0F)
+                    }
+                }
+                Else
+                {
+                    Return (0x0F)
+                }
+            }
+            Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+            {
+                IO (Decode16,
+                    0x0060,             // Range Minimum
+                    0x0060,             // Range Maximum
+                    0x01,               // Alignment
+                    0x01,               // Length
+                    )
+                IO (Decode16,
+                    0x0064,             // Range Minimum
+                    0x0064,             // Range Maximum
+                    0x01,               // Alignment
+                    0x01,               // Length
+                    )
+                IRQNoFlags ()
+                    {1}
+            })
+        }
+        // PS/2 Mouse
+        Device (MOU)
+        {
+            Name (_HID, EisaId ("PNP0F13") /* PS/2 Mouse */)  // _HID: Hardware ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Local0 = LGCY /* \_SB_.PCI0.ISA_.LGCY */
+                If ((Local0 == Zero))
+                {
+                    Local1 = KBDC /* \_SB_.PCI0.ISA_.KBDC */
+                    If ((Local1 == Zero))
+                    {
+                        Return (Zero)
+                    }
+                    Else
+                    {
+                        Return (0x0F)
+                    }
+                }
+                Else
+                {
+                    Return (0x0F)
+                }
+            }
+            Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+            {
+                IRQNoFlags ()
+                    {12}
+            })
+        }
+        // Enhanced floppy controller
+        Device (FDC0)
+        {
+            Name (_HID, EisaId ("PNP0700"))  // _HID: Hardware ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Return (Zero)
+            }
+        }
+        // Standard LPT Parallel Port
+        Device (LPT)
+        {
+            Name (_HID, EisaId ("PNP0400") /* Standard LPT Parallel Port */)  // _HID: Hardware ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Return (Zero)
+            }
+        }
+        // Serial ports
+        Name (C1AD, {{ u16max }})
+        Name (C2AD, {{ u16max }})
+        Name (C3AD, {{ u16max }})
+        Name (C4AD, {{ u16max }})
+        Device (COM1)
+        {
+            Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */)  // _HID: Hardware ID
+            Name (_UID, One)  // _UID: Unique ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Local0 = LGCY /* \_SB_.PCI0.ISA_.LGCY */
+                If ((Local0 == Zero))
+                {
+                    Local1 = SERA /* \_SB_.PCI0.ISA_.SERA */
+                    If ((Local1 == Zero))
+                    {
+                        Return (Zero)
+                    }
+                    Else
+                    {
+                        Return (0x0F)
+                    }
+                }
+                Else
+                {
+                    Local1 = CAEN /* \_SB_.PCI0.ISA_.CAEN */
+                    If ((Local1 == Zero))
+                    {
+                        Return (Zero)
+                    }
+                    Else
+                    {
+                        Return (0x0F)
+                    }
+                }
+            }
+            Name (CRES, ResourceTemplate ()
+            {
+                IO (Decode16,
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x00,               // Alignment
+                    0x00,               // Length
+                    COIO)
+                IRQNoFlags ()
+                    {4}
+            })
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                CreateWordField (CRES, ^COIO._MIN, CMIN)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^COIO._MAX, CMAX)  // _MAX: Maximum Base Address
+                CreateByteField (CRES, ^COIO._LEN, CLEN)  // _LEN: Length
+                CMIN = C1AD
+                CMAX = C1AD
+                CLEN = 0x8
+                Return (CRES)
+            }
+        }
+        Device (COM2)
+        {
+            Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */)  // _HID: Hardware ID
+            Name (_UID, 0x02)  // _UID: Unique ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Local0 = LGCY /* \_SB_.PCI0.ISA_.LGCY */
+                If ((Local0 == Zero))
+                {
+                    Local1 = SERB /* \_SB_.PCI0.ISA_.SERB */
+                    If ((Local1 == Zero))
+                    {
+                        Return (Zero)
+                    }
+                    Else
+                    {
+                        Return (0x0F)
+                    }
+                }
+                Else
+                {
+                    Local1 = CBEN /* \_SB_.PCI0.ISA_.CBEN */
+                    If ((Local1 == Zero))
+                    {
+                        Return (Zero)
+                    }
+                    Else
+                    {
+                        Return (0x0F)
+                    }
+                }
+            }
+            Name (CRES, ResourceTemplate ()
+            {
+                IO (Decode16,
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x00,               // Alignment
+                    0x00,               // Length
+                    COIO)
+                IRQNoFlags ()
+                    {3}
+            })
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                CreateWordField (CRES, ^COIO._MIN, CMIN)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^COIO._MAX, CMAX)  // _MAX: Maximum Base Address
+                CreateByteField (CRES, ^COIO._LEN, CLEN)  // _LEN: Length
+                CMIN = C2AD
+                CMAX = C2AD
+                CLEN = 0x8
+                Return (CRES)
+            }
+        }
+        Device (COM3)
+        {
+            Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */)  // _HID: Hardware ID
+            Name (_UID, 0x03)  // _UID: Unique ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Local0 = LGCY /* \_SB_.PCI0.ISA_.LGCY */
+                If ((Local0 == Zero))
+                {
+                    Local1 = SERC /* \_SB_.PCI0.ISA_.SERC */
+                    If ((Local1 == One))
+                    {
+                        Return (0x0F)
+                    }
+                }
+                Return (Zero)
+            }
+            Name (CRES, ResourceTemplate ()
+            {
+                IO (Decode16,
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x00,               // Alignment
+                    0x00,               // Length
+                    COIO)
+                IRQNoFlags ()
+                    {6}
+            })
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                CreateWordField (CRES, ^COIO._MIN, CMIN)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^COIO._MAX, CMAX)  // _MAX: Maximum Base Address
+                CreateByteField (CRES, ^COIO._LEN, CLEN)  // _LEN: Length
+                CMIN = C3AD
+                CMAX = C3AD
+                CLEN = 0x8
+                Return (CRES)
+            }
+        }
+        Device (COM4)
+        {
+            Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */)  // _HID: Hardware ID
+            Name (_UID, 0x04)  // _UID: Unique ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Local0 = LGCY /* \_SB_.PCI0.ISA_.LGCY */
+                If ((Local0 == Zero))
+                {
+                    Local1 = SERD /* \_SB_.PCI0.ISA_.SERD */
+                    If ((Local1 == One))
+                    {
+                        Return (0x0F)
+                    }
+                }
+                Return (Zero)
+            }
+            Name (CRES, ResourceTemplate ()
+            {
+                IO (Decode16,
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x00,               // Alignment
+                    0x00,               // Length
+                    COIO)
+                IRQNoFlags ()
+                    {7}
+            })
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                CreateWordField (CRES, ^COIO._MIN, CMIN)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^COIO._MAX, CMAX)  // _MAX: Maximum Base Address
+                CreateByteField (CRES, ^COIO._LEN, CLEN)  // _LEN: Length
+                CMIN = C4AD
+                CMAX = C4AD
+                CLEN = 0x8
+                Return (CRES)
+            }
+        }
+        // Serial tablet
+        Device (PEN)
+        {
+            Name (_HID, EisaId ("WACF004"))  // _HID: Hardware ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Local0 = LGCY /* \_SB_.PCI0.ISA_.LGCY */
+                If ((Local0 == Zero))
+                {
+                    Local1 = WPEN /* \_SB_.PCI0.ISA_.WPEN */
+                    If ((Local1 == Zero))
+                    {
+                        Return (Zero)
+                    }
+                    Else
+                    {
+                        Return (0x0F)
+                    }
+                }
+                Else
+                {
+                    Return (Zero)
+                }
+            }
+            Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+            {
+                IO (Decode16,
+                    0x0200,             // Range Minimum
+                    0x0208,             // Range Maximum
+                    0x00,               // Alignment
+                    0x08,               // Length
+                    )
+                IRQNoFlags ()
+                    {7}
+            })
+        }
+    }
+    // PCI hotplug definitions
+    Scope (_SB.PCI0)
+    {
+        OperationRegion (PCST, SystemIO, 0xAE00, 0x08)
+        Field (PCST, DWordAcc, NoLock, WriteAsZeros)
+        {
+            PCIU,   32,
+            PCID,   32
+        }
+        OperationRegion (SEJ, SystemIO, {{ u16max }}, 0x04)
+        Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
+        {
+            B0EJ,   32
+        }
+        // Methods called by hotplug devices
+        Method (PCEJ, 1, NotSerialized)
+        {
+            B0EJ = (One << Arg0)
+        }
+        // PCI hotplug notify method
+        Method (PCNF, 0, NotSerialized)
+        {
+            // Local0 = iterator
+            Local0 = Zero
+            While ((Local0 < 0x1F))
+            {
+                Local0++
+                // PCNT is hotplug notification method supplied by SSDT
+                If ((PCIU & (One << Local0)))
+                {
+                    PCNT (Local0, One)
+                }
+                If ((PCID & (One << Local0)))
+                {
+                    PCNT (Local0, 0x03)
+                }
+            }
+        }
+    }
+    Scope (_SB)
+    {
+## for int in pci_interrupts
+        Device ({{ int.name }})
+        {
+            Name (_HID, EisaId ("PNP0C0F") /* PCI Interrupt Link Device */)  // _HID: Hardware ID
+            Name (_UID, {{ int.uid }})  // _UID: Unique ID
+            Name (_PRS, ResourceTemplate ()  // _PRS: Possible Resource Settings
+            {
+                Interrupt (ResourceConsumer, Level, ActiveHigh, Shared, ,, )
+                {
+                    0x00000005,
+                    0x0000000A,
+                    0x0000000B,
+                }
+            })
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Return (IQST ({{ int.reg }}))
+            }
+            Method (_DIS, 0, NotSerialized)  // _DIS: Disable Device
+            {
+                {{ int.reg }} |= 0x80
+            }
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                Return (IQCR ({{ int.reg }}))
+            }
+            Method (_SRS, 1, NotSerialized)  // _SRS: Set Resource Settings
+            {
+                CreateDWordField (Arg0, 0x05, PRRI)
+                {{ int.reg }} = PRRI
+            }
+        }
+## endfor
+        Field (PCI0.ISA.P40C, ByteAcc, NoLock, Preserve)
+        {
+            PRQ0,   8,
+            PRQ1,   8,
+            PRQ2,   8,
+            PRQ3,   8
+        }
+        Method (IQST, 1, NotSerialized)
+        {
+            If ((0x80 & Arg0))
+            {
+                Return (0x09)
+            }
+            Return (0x0B)
+        }
+        Name (PRR0, ResourceTemplate ()
+        {
+            Interrupt (ResourceConsumer, Level, ActiveHigh, Shared, ,, PR0I)
+            {
+                0x00000000,
+            }
+        })
+        Method (IQCR, 1, Serialized)
+        {
+            CreateDWordField (PRR0, ^PR0I._INT, PRRI)  // _INT: Interrupts
+            If ((Arg0 < 0x80))
+            {
+                PRRI = Arg0
+            }
+            Return (PRR0) /* \_SB_.IQCR.PRR0 */
+        }
+        Device (LNKS)
+        {
+            Name (_HID, EisaId ("PNP0C0F") /* PCI Interrupt Link Device */)  // _HID: Hardware ID
+            Name (_UID, 0x04)  // _UID: Unique ID
+            Name (_PRS, ResourceTemplate ()  // _PRS: Possible Resource Settings
+            {
+                Interrupt (ResourceConsumer, Level, ActiveHigh, Shared, ,, )
+                {
+                    0x00000009,
+                }
+            })
+            // The SCI cannot be disabled and is always attached to GSI 9, so
+            // these are no-ops. We only need this link to override the polarity
+            // to active high and match the content of the MADT.
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Return (0x0B)
+            }
+            Method (_DIS, 0, NotSerialized)  // _DIS: Disable Device
+            {
+            }
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                Return (_PRS) /* \_SB_.LNKS._PRS */
+            }
+            Method (_SRS, 1, NotSerialized)  // _SRS: Set Resource Settings
+            {
+            }
+        }
+    }
+    Scope (_SB)
+    {
+        // Boolean value which allows CPMA to always return x2APIC entries.
+        Name (MDX2, {{ madt_x2apic }})
+        // Methods called by runtime generated SSDT Processor objects
+        Method (CPMA, 1, NotSerialized)
+        {
+            // Arg0 = Processor ID = Local APIC ID
+            // Local0 = CPON flag for this CPU
+            Local0 = DerefOf (CPON [Arg0])
+            If ((MDX2) || (Arg0 >= 255))
+            {
+                // Local1 = Buffer (in MADT x2APIC form) to return
+                Local1 = Buffer (0x10)
+                    {
+                        /* 0000 */  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // ........
+                        /* 0008 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // ........
+                    }
+                // Update the processor ID, LAPIC ID, and enable/disable status
+                Local1 [0x04] = (Arg0) & 0xFF
+                Local1 [0x05] = (Arg0 >> 8) & 0xFF
+                Local1 [0x06] = (Arg0 >> 16) & 0xFF
+                Local1 [0x07] = (Arg0 >> 24) & 0xFF
+                Local1 [0x08] = Local0
+                Local1 [0x0C] = (Arg0) & 0xFF
+                Local1 [0x0D] = (Arg0 >> 8) & 0xFF
+                Local1 [0x0E] = (Arg0 >> 16) & 0xFF
+                Local1 [0x0F] = (Arg0 >> 24) & 0xFF
+                Return (Local1)
+            }
+            // Local1 = Buffer (in MADT APIC form) to return
+            Local1 = Buffer (0x08)
+                {
+                        0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // ........
+                }
+            // Update the processor ID, LAPIC ID, and enable/disable status
+            Local1 [0x02] = Arg0
+            Local1 [0x03] = Arg0
+            Local1 [0x04] = Local0
+            Return (Local1)
+        }
+        Method (CPST, 1, NotSerialized)
+        {
+            // Arg0 = Processor ID = Local APIC ID
+            // Local0 = CPON flag for this CPU
+            Local0 = DerefOf (CPON [Arg0])
+            If (Local0)
+            {
+                Return (0x0F)
+            }
+            Else
+            {
+                Return (Zero)
+            }
+        }
+        Method (CPEJ, 2, NotSerialized)
+        {
+            // Arg0 = processor index
+            // Arg1 = _EJ0 argument
+            DBUG ("CPEJ")
+            DBUG (Arg0)
+            DBUG (Arg1)
+            // Check if hot-eject is requested
+            If ((Arg1 == One))
+            {
+                // Local0 = local processor bitmap
+                // Must have same bit count as PRST field and highest CPU count
+                Local0 = Buffer (0x80){}
+                // Local1 = byte index
+                Local1 = (Arg0 >> 0x03)
+                // Local2 = bit index
+                Local2 = (Arg0 & 0x07)
+                // Local3 = bit mask
+                Local3 = (One << Local2)
+                // Write mask to local processor bitmap
+                Local0 [Local1] = Local3
+                // Write mask to operation region to request processor eject
+                PRS = Local0
+            }
+            Sleep (0xC8)
+        }
+        OperationRegion (PRST, SystemIO, {{ u16max }}, 0x80)
+        // CPU hotplug notify method
+        Field (PRST, ByteAcc, NoLock, Preserve)
+        {
+            PRS,    1024
+        }
+        Method (PRSC, 0, NotSerialized)
+        {
+            // Local5 = active CPU bitmap
+            Local5 = PRS /* \_SB_.PRS_ */
+            // Local2 = last read byte from bitmap
+            Local2 = Zero
+            // Local0 = Processor ID / APIC ID iterator
+            Local0 = Zero
+            While ((Local0 < SizeOf (CPON)))
+            {
+                // Local1 = CPON flag for this CPU
+                Local1 = DerefOf (CPON [Local0])
+                If ((Local0 & 0x07))
+                {
+                    // Shift down previously read bitmap byte
+                    Local2 >>= One
+                }
+                Else
+                {
+                    // Read next byte from CPU bitmap
+                    Local2 = DerefOf (Local5 [(Local0 >> 0x03)])
+                }
+                // Local3 = active state for this CPU
+                Local3 = (Local2 & One)
+                If ((Local1 != Local3))
+                {
+                    // State change - update CPON with new state
+                    CPON [Local0] = Local3
+                    // Do CPU notify
+                    If ((Local3 == One))
+                    {
+                        // Device check
+                        NTFY (Local0, One)
+                    }
+                    Else
+                    {
+                        // Eject Request
+                        NTFY (Local0, 0x03)
+                    }
+                }
+                Local0++
+            }
+        }
+    }
+    Scope (_SB)
+    {
+        Mutex (MMTX, 0x00)
+        OperationRegion (MOR, SystemIO, 0xAF80, 0x80)
+        Field (MOR, DWordAcc, NoLock, Preserve)
+        {
+            MHPE,   32, // Memory hotplug enable (R)
+            MCNT,   32, // Memory count          (R)
+            MSEL,   32, // Memory select         (RW)
+            MFLG,   32, // Memory flags          (RW)
+            MBL,    32, // Memory base low       (R)
+            MBH,    32, // Memory base high      (R)
+            MLL,    32, // Memory length low     (R)
+            MLH,    32, // Memory length high    (R)
+            MPDI,   32, // Memory proximity domain ID (R)
+            MOSE,   32, // Memory OSPM source event   (RW)
+            MOSC,   32  // Memory OSPM status code    (RW)
+        }
+        // MFLG:
+        //     0x00000001 : Present                  (R)
+        //     0x00000002 : Insert pending           (RW)
+        //     0x00000004 : Remove pending           (RW)
+        Method (MSTA, 1, NotSerialized)
+        {
+            // Input:
+            //     Arg0 : Memory device index
+            // Output:
+            //     Bit0 : Set if the device is present
+            //     Bit1 : Set if the device is enabled and decoding its resources
+            //     Bit2 : Set if the device should be shown in the UI
+            //     Bit3 : Set if the device is functioning properly
+            //     Bit4 : Set if the battery is present
+            Local0 = Zero
+            Acquire (MMTX, 0xFFFF)
+            MSEL = Arg0
+            If ((((MFLG & One) != Zero) && ((MFLG &
+                0x04) == Zero)))
+            {
+                Local0 = 0x0F
+            }
+            Release (MMTX)
+            Return (Local0)
+        }
+        Method (MCRS, 1, NotSerialized)
+        {
+            // Input:
+            //     Arg0 : Memory device index
+            // Output:
+            //     Resource template
+            Local0 = ResourceTemplate ()
+                {
+                    QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+                        0x0000000000000000, // Granularity
+                        0x0000000000000000, // Range Minimum
+                        0xFFFFFFFFFFFFFFFE, // Range Maximum
+                        0x0000000000000000, // Translation Offset
+                        0xFFFFFFFFFFFFFFFF, // Length
+                        ,, , AddressRangeMemory, TypeStatic)
+                }
+            CreateDWordField (Local0, 0x0E, MINL)
+            CreateDWordField (Local0, 0x12, MINH)
+            CreateDWordField (Local0, 0x16, MAXL)
+            CreateDWordField (Local0, 0x1A, MAXH)
+            CreateDWordField (Local0, 0x26, LENL)
+            CreateDWordField (Local0, 0x2A, LENH)
+            Acquire (MMTX, 0xFFFF)
+            MSEL = Arg0
+            MINL = MBL /* \_SB_.MBL_ */
+            MINH = MBH /* \_SB_.MBH_ */
+            LENL = MLL /* \_SB_.MLL_ */
+            LENH = MLH /* \_SB_.MLH_ */
+            MAXL = (MINL + LENL) /* \_SB_.MCRS.LENL */
+            MAXH = (MINH + LENH) /* \_SB_.MCRS.LENH */
+            If (((MAXL < MINL) | (MAXL < LENL)))
+            {
+                MAXH += One
+            }
+            MAXL -= One
+            If ((MAXL == Ones))
+            {
+                MAXH -= One
+            }
+            DBUG ("MCRS")
+            DBUG (Arg0)
+            DBUG (MINL)
+            DBUG (MINH)
+            DBUG (MAXL)
+            DBUG (MAXH)
+            DBUG (LENL)
+            DBUG (LENH)
+            Release (MMTX)
+            Return (Local0)
+        }
+        Method (MPXM, 1, NotSerialized)
+        {
+            // Input:
+            //     Arg0 : Memory device index
+            // Output:
+            //     Proximity domain ID
+            Acquire (MMTX, 0xFFFF)
+            MSEL = Arg0
+            Local0 = MPDI /* \_SB_.MPDI */
+            DBUG ("MPXM")
+            DBUG (Arg0)
+            DBUG (Local0)
+            Release (MMTX)
+            Return (Local0)
+        }
+        Method (MOST, 4, NotSerialized)
+        {
+            // Input:
+            //     Arg0 : Memory device index
+            //     Arg1 : OSPM source event
+            //     Arg2 : OSPM status code
+            //     Arg3 : OSPM status information
+            Acquire (MMTX, 0xFFFF)
+            MSEL = Arg0
+            MOSE = Arg1
+            MOSC = Arg2
+            DBUG ("MOST")
+            DBUG (Arg0)
+            DBUG (Arg1)
+            DBUG (Arg2)
+            DBUG (Arg3)
+            Release (MMTX)
+        }
+        Method (MEJ0, 2, NotSerialized)
+        {
+            // Input:
+            //     Arg0 : Memory device index
+            //     Arg1 : _EJ0 argument
+            Acquire (MMTX, 0xFFFF)
+            DBUG ("MEJ0")
+            DBUG (Arg0)
+            DBUG (Arg1)
+            If ((Arg1 == One))
+            {
+                MSEL = Arg0
+                MFLG = 0x04
+            }
+            Release (MMTX)
+            Sleep (0xC8)
+        }
+        Method (MSCA, 0, NotSerialized)
+        {
+            Acquire (MMTX, 0xFFFF)
+            DBUG ("MSCA")
+            Local0 = MCNT /* \_SB_.MCNT */
+            Local1 = Zero
+            While ((Local1 < Local0))
+            {
+                MSEL = Local1
+                Local2 = MFLG /* \_SB_.MFLG */
+                If (((Local2 & 0x02) != Zero))
+                {
+                    DBUG ("MSCA --> MNOT")
+                    DBUG (Local1)
+                    MNOT (Local1, One)
+                    MFLG = 0x02
+                }
+                Local1 += One
+            }
+            Release (MMTX)
+        }
+    }
+    Scope (_GPE)
+    {
+        Name (_HID, "ACPI0006" /* GPE Block Device */)  // _HID: Hardware ID
+        Method (_L00, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_E01, 0, NotSerialized)  // _Exx: Edge-Triggered GPE, xx=0x00-0xFF
+        {
+            // PCI hotplug event
+            \_SB.PCI0.PCNF ()
+        }
+        Method (_E02, 0, NotSerialized)  // _Exx: Edge-Triggered GPE, xx=0x00-0xFF
+        {
+            // CPU hotplug event
+            \_SB.PRSC ()
+        }
+        Method (_E03, 0, NotSerialized)  // _Exx: Edge-Triggered GPE, xx=0x00-0xFF
+        {
+            // Memory hotplug event
+            \_SB.MSCA ()
+        }
+        Method (_L04, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L05, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L06, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L07, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L08, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L09, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L0A, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L0B, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L0C, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L0D, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L0E, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+        Method (_L0F, 0, NotSerialized)  // _Lxx: Level-Triggered GPE, xx=0x00-0xFF
+        {
+        }
+    }
+}
diff --git a/acpi/dsdt_x86_pci_root b/acpi/dsdt_x86_pci_root
new file mode 100644
index 0000000..200990d
--- /dev/null
+++ b/acpi/dsdt_x86_pci_root
@@ -0,0 +1,199 @@
+DefinitionBlock ("", "DSPC", 2, "Google", "GOOGDSPC", 0x00000001)
+{
+    External (LNKA, DeviceObj)
+    External (LNKB, DeviceObj)
+    External (LNKC, DeviceObj)
+    External (LNKD, DeviceObj)
+    External (POSC, IntObj)
+    External (ZBR, IntObj)
+    // PCI root bus device definition
+    Scope (_SB)
+    {
+        Device (PR{{ bus_id }})
+        {
+            Name (_HID, EisaId ("PNP0A03") /* PCI Bus */)  // _HID: Hardware ID
+            Name (_UID, {{ u8max }})  // _UID: Unique ID
+            Name (_BBN, {{ u8max }})  // _BBN: BIOS Bus Number
+            Name (_PXM, {{ u8max }})  // _PXM: Device Proximity
+            Name (CRES, ResourceTemplate ()
+            {
+                // PCI bus numbers
+                WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+                    0x0000,             // Granularity
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x0000,             // Translation Offset
+                    0x0000,             // Length
+                    ,, PCBN)
+                // 16-bit PCI memory
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x0000,             // Granularity
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x0000,             // Translation Offset
+                    0x0000,             // Length
+                    ,, PC16, TypeStatic, DenseTranslation)
+                // 32-bit PCI memory
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+                    0x00000000,         // Granularity
+                    0x00000000,         // Range Minimum
+                    0x00000000,         // Range Maximum
+                    0x00000000,         // Translation Offset
+                    0x00000000,         // Length
+                    ,, PM32, AddressRangeMemory, TypeStatic)
+            })
+            // Template to be concatenated for each active CRS allowlist entry
+            Name (CRWM, ResourceTemplate ()
+            {
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+                    0x00000000,         // Granularity
+                    0x00000000,         // Range Minimum
+                    0x00000000,         // Range Maximum
+                    0x00000000,         // Translation Offset
+                    0x00000000,         // Length
+                    ,, PC32, AddressRangeMemory, TypeStatic)
+            })
+            // 64-bit PCI memory
+            Name (CR64, ResourceTemplate ()
+            {
+                QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+                    0x0000000000000000, // Granularity
+                    0x0000000000000000, // Range Minimum
+                    0x0000000000000000, // Range Maximum
+                    0x0000000000000000, // Translation Offset
+                    0x0000000000000000, // Length
+                    ,, PC64, AddressRangeMemory, TypeStatic)
+            })
+            Name (PBBS, {{ u16max }})
+            Name (PBBE, {{ u16max }})
+            Name (PBIS, {{ u16max }})
+            Name (PBIE, {{ u16max }})
+            Name (PB0S, {{ u32max }})
+            Name (PB0E, {{ u32max }})
+## for hole_index in range(11)
+            Name (PWS{{ hex(hole_index) }}, {{ u32max }})
+            Name (PWE{{ hex(hole_index) }}, {{ u32max }})
+## endfor
+            Name (PB1V, {{ u8max }})
+            Name (PB1S, {{ u64max }})
+            Name (PB1E, {{ u64max }})
+            Name (PB1L, {{ u64max }})
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                // Fix PCI bus numbers
+                CreateWordField (CRES, ^PCBN._MIN, BS32)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^PCBN._MAX, BE32)  // _MAX: Maximum Base Address
+                CreateWordField (CRES, ^PCBN._LEN, BL32)  // _LEN: Length
+                BS32 = PBBS
+                BE32 = PBBE
+                BL32 = ((PBBE - PBBS) + One)
+                // PCI 16-bit I/O range
+                CreateWordField (CRES, ^PC16._MIN, IS32)  // _MIN: Minimum Base Address
+                CreateWordField (CRES, ^PC16._MAX, IE32)  // _MAX: Maximum Base Address
+                CreateWordField (CRES, ^PC16._LEN, IL32)  // _LEN: Length
+                IS32 = PBIS
+                IE32 = PBIE
+                IL32 = ((PBIE - PBIS) + One)
+                If ((!ZBR && ((IS32 == Zero) && (IE32 == Zero))))
+                {
+                    IL32 = Zero
+                }
+                // PCI 32-bit range
+                CreateDWordField (CRES, ^PM32._MIN, PS32)  // _MIN: Minimum Base Address
+                CreateDWordField (CRES, ^PM32._MAX, PE32)  // _MAX: Maximum Base Address
+                CreateDWordField (CRES, ^PM32._LEN, PL32)  // _LEN: Length
+                If ((PWS0 != Zero))
+                {
+                    PS32 = PWS0
+                    PE32 = PWE0
+                    PL32 = ((PWE0 - PWS0) + One)
+                }
+                Else
+                {
+                    PS32 = PB0S
+                    PE32 = PB0E
+                    PL32 = ((PB0E - PB0S) + One)
+                }
+                If ((!ZBR && ((PS32 == Zero) && (PE32 == Zero))))
+                {
+                    PL32 = Zero
+                }
+                // Concatenate all active PCI CRS allowlist entries
+                Local0 = CRES
+                CreateDWordField (CRWM, ^PC32._MIN, RS32)  // _MIN: Minimum Base Address
+                CreateDWordField (CRWM, ^PC32._MAX, RE32)  // _MAX: Maximum Base Address
+                CreateDWordField (CRWM, ^PC32._LEN, RL32)  // _LEN: Length
+## for hole in pci_crs_holes
+                If (({{ hole.start }} != Zero))
+                {
+                    RS32 = {{ hole.start }}
+                    RE32 = {{ hole.end }}
+                    RL32 = (({{ hole.end }} - {{ hole.start }}) + One)
+                    ConcatenateResTemplate (Local0, CRWM, Local0)
+                }
+## endfor
+                // PCI 64-bit range
+                If ((PB1V == Zero))
+                {
+                    Return (Local0)
+                }
+                CreateQWordField (CR64, ^PC64._MIN, PS64)  // _MIN: Minimum Base Address
+                CreateQWordField (CR64, ^PC64._MAX, PE64)  // _MAX: Maximum Base Address
+                CreateQWordField (CR64, ^PC64._LEN, PL64)  // _LEN: Length
+                PS64 = PB1S
+                PE64 = PB1E
+                PL64 = PB1L
+                ConcatenateResTemplate (Local0, CR64, Local0)
+                Return (Local0)
+            }
+            // Report PCI host bridge capabilities to allow PCI hotplug
+            If (POSC)
+            {
+                Name (SUPP, Zero)
+                Name (CTRL, Zero)
+                Method (_OSC, 4, Serialized)  // _OSC: Operating System Capabilities
+                {
+                    CreateDWordField (Arg3, Zero, CDW1)
+                    If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
+                    {
+                        CreateDWordField (Arg3, 0x04, CDW2)
+                        CreateDWordField (Arg3, 0x08, CDW3)
+                        SUPP = CDW2
+                        CTRL = CDW3
+                        CTRL &= 0x1F
+                        If ((Arg1 != One))
+                        {
+                            CDW1 |= 0x08
+                        }
+                        If ((CDW3 != CTRL))
+                        {
+                            CDW1 |= 0x10
+                        }
+                        CDW3 = CTRL
+                        Return (Arg3)
+                    }
+                    Else
+                    {
+                        CDW1 |= 0x04
+                        Return (Arg3)
+                    }
+                }
+            }
+            // Provides mapping from PCI interrupt pins to interrupt inputs
+            // of interrupt controllers. NOTE: Same mapping as PCI routing
+            // table from Bochs BIOS.
+            Name (_PRT, Package (0x80)  // _PRT: PCI Routing Table
+            {
+## for link in pci_links
+                Package (0x04)
+                {
+                    {{ link.address }},
+                    {{ link.pin }},
+                    {{ link.name }},
+                    Zero
+                }{% if not loop.is_last %},{% endif %}
+## endfor
+            })
+        }
+    }
+}
diff --git a/acpi/ssdt b/acpi/ssdt
new file mode 100644
index 0000000..d522392
--- /dev/null
+++ b/acpi/ssdt
@@ -0,0 +1,155 @@
+DefinitionBlock ("", "SSDT", 1, "Google", "GOOGSSDT", 0x00000001)
+{
+    External (_SB_.PCI0, DeviceObj)
+    External (_SB_.PCI0.ISA_, DeviceObj)
+    External (_SB_.PCI0.PCEJ, MethodObj)    // 1 Arguments
+    Scope (\)
+    {
+        // S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type
+        // codes. Must match PIIX4 emulation.
+        Name (_S3, Package (0x04)  // _S3_: S3 System State
+        {
+            One,
+            One,
+            Zero,
+            Zero
+        })
+        Name (_S4, Package (0x04)  // _S4_: S4 System State
+        {
+            0x00,
+            0x00,
+            Zero,
+            Zero
+        })
+        Name (_S5, Package (0x04)  // _S5_: S5 System State
+        {
+            Zero,
+            Zero,
+            Zero,
+            Zero
+        })
+    }
+    Scope (\_SB.PCI0.ISA)
+    {
+        Device (PEVT)
+        {
+            Name (_HID, "QEMU0001")  // _HID: Hardware ID
+            Name (PEST, {{ pvpanic_port }})
+            OperationRegion (PEOR, SystemIO, PEST, One)
+            Field (PEOR, ByteAcc, NoLock, Preserve)
+            {
+                PEPT,   8
+            }
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Local0 = PEST /* \_SB_.PCI0.ISA_.PEVT.PEST */
+                If ((Local0 == Zero))
+                {
+                    Return (Zero)
+                }
+                Else
+                {
+                    Return (0x0F)
+                }
+            }
+            Method (RDPT, 0, NotSerialized)
+            {
+                Local0 = PEPT /* \_SB_.PCI0.ISA_.PEVT.PEPT */
+                Return (Local0)
+            }
+            Method (WRPT, 1, NotSerialized)
+            {
+                PEPT = Arg0
+            }
+            Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+            {
+                IO (Decode16,
+                    0x0000,             // Range Minimum
+                    0x0000,             // Range Maximum
+                    0x01,               // Alignment
+                    0x01,               // Length
+                    _Y06)
+            })
+            CreateWordField (_CRS, \_SB.PCI0.ISA.PEVT._Y06._MIN, IOMN)  // _MIN: Minimum Base Address
+            CreateWordField (_CRS, \_SB.PCI0.ISA.PEVT._Y06._MAX, IOMX)  // _MAX: Maximum Base Address
+            Method (_INI, 0, NotSerialized)  // _INI: Initialize
+            {
+                IOMN = PEST /* \_SB_.PCI0.ISA_.PEVT.PEST */
+                IOMX = PEST /* \_SB_.PCI0.ISA_.PEVT.PEST */
+            }
+        }
+    }
+    Scope (_SB)
+    {
+## for memory in memory_devices
+        Device (M{{ memory.id }})
+        {
+            Name (_HID, EisaId ("PNP0C80") /* Memory Device */)  // _HID: Hardware ID
+            Name (_UID, 0x{{ memory.id }})  // _UID: Unique ID
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Return (MSTA (_UID))
+            }
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                Return (MCRS (_UID))
+            }
+            Method (_PXM, 0, NotSerialized)  // _PXM: Device Proximity
+            {
+                Return (MPXM (_UID))
+            }
+            Method (_OST, 3, NotSerialized)  // _OST: OSPM Status Indication
+            {
+                Return (MOST (_UID, Arg0, Arg1, Arg2))
+            }
+            Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+            {
+                Return (MEJ0 (_UID, Arg0))
+            }
+        }
+## endfor
+        // Memory device notifier called by DSDT
+        Method (MNOT, 2, NotSerialized)
+        {
+## for memory in memory_devices
+                If ((Arg0 == 0x{{ memory.id }}))
+                {
+                    Notify (M{{ memory.id }}, Arg1)
+                }
+## endfor
+        }
+        // Boolean value representing whether to define PCI hotplug Devices.
+        Name (PCHP, {{ pchp }})
+        If (PCHP)
+        {
+            Scope (PCI0)
+            {
+## for device in devices
+                Device (S{{ device.id }})
+                {
+                    Name (_SUN, 0x{{ device.id }})  // _SUN: Slot User Number
+                    Name (_ADR, 0x00{{ device.id }}0000)  // _ADR: Address
+                    Method (NOEJ, 1, NotSerialized)
+                    {
+                        // Device should only eject if Arg0 is 1.
+                        // See ACPI spec v6.5: 6.3.3. _EJx (Eject)
+                        If (Arg0 == 1)
+                        {
+                            PCEJ (_SUN)
+                        }
+                    }
+                }
+## endfor
+                Method (PCNT, 2, NotSerialized)
+                {
+## for device in devices
+                    If ((Arg0 == 0x{{ device.id }}))
+                    {
+                        Notify (S{{ device.id }}, Arg1)
+                    }
+## endfor
+                }
+            }
+        }
+    }
+}
diff --git a/acpi/ssdt_cpu b/acpi/ssdt_cpu
new file mode 100644
index 0000000..aac8969
--- /dev/null
+++ b/acpi/ssdt_cpu
@@ -0,0 +1,26 @@
+DefinitionBlock ("", "SCPU", 1, "Google", "GOOGSCPU", 0x00000001)
+{
+    External (_SB_.CPEJ, MethodObj)    // 2 Arguments
+    External (_SB_.CPMA, MethodObj)    // 1 Arguments
+    External (_SB_.CPST, MethodObj)    // 1 Arguments
+    Scope (_SB)
+    {
+        Device (C000)
+        {
+            Name (_HID, "ACPI0007" /* Processor Device */)  // _HID: Hardware ID
+            Name (_UID, {{ u16max }})  // _UID: Unique ID
+            Method (_MAT, 0, NotSerialized)  // _MAT: Multiple APIC Table Entry
+            {
+                Return (CPMA (_UID))
+            }
+            Method (_STA, 0, NotSerialized)  // _STA: Status
+            {
+                Return (CPST (_UID))
+            }
+            Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+            {
+                CPEJ (_UID, Arg0)
+            }
+        }
+    }
+}
diff --git a/acpi/ssdt_cpu_cst b/acpi/ssdt_cpu_cst
new file mode 100644
index 0000000..ba1a63b
--- /dev/null
+++ b/acpi/ssdt_cpu_cst
@@ -0,0 +1,22 @@
+DefinitionBlock ("", "SCST", 1, "Google", "GOOGSCST", 0x00000001)
+{
+    Name (_CST, Package ()
+    {
+        1,
+        Package ()
+        {
+            ResourceTemplate ()
+            {
+                Register (FFixedHW,
+                    0x00,
+                    {{ u8max }},
+                    {{ u64max }},
+                    ,)
+            },
+
+            {{ u8max }},
+            {{ u16max }},
+            0
+        },
+    })
+}
\ No newline at end of file
diff --git a/acpi/ssdt_cpu_ntfy b/acpi/ssdt_cpu_ntfy
new file mode 100644
index 0000000..20b59cf
--- /dev/null
+++ b/acpi/ssdt_cpu_ntfy
@@ -0,0 +1,14 @@
+DefinitionBlock ("", "SNTF", 1, "Google", "GOOGSNTF", 0x00000001)
+{
+    External (_SB.C000, DeviceObj)
+    Scope (_SB)
+    {
+        Method (NTFY, 2, NotSerialized)
+        {
+            If ((Arg0 == {{ u16max }}))
+            {
+                Notify (C000, Arg1)
+            }
+        }
+    }
+}
diff --git a/acpi/ssdt_cpu_on b/acpi/ssdt_cpu_on
new file mode 100644
index 0000000..5627bab
--- /dev/null
+++ b/acpi/ssdt_cpu_on
@@ -0,0 +1,9 @@
+DefinitionBlock ("", "SCPO", 1, "Google", "GOOGSCPO", 0x00000001)
+{
+    Scope (_SB)
+    {
+        Name (CPON, Package ({{ u8max }})
+        {
+        })
+    }
+}