We cannot specify a pin-GSI connection for the SCI directly in the _PRT
because that implies ActiveLow polarity, clashing with both qemu and the
MADT we prepare.

With this patch the RHEL-6 guest logs the following:

    ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
    ACPI: PCI Interrupt Link [LNKS] (IRQs *9)
    ACPI: PCI Interrupt Link [LNKA] (IRQs 5 10 *11)
    ACPI: PCI Interrupt Link [LNKB] (IRQs 5 10 *11)
    ACPI: PCI Interrupt Link [LNKC] (IRQs 5 *10 11)
    ACPI: PCI Interrupt Link [LNKD] (IRQs 5 *10 11)

The patch amends svn rev 13625. Testing it in a RHEL-6 guest, the problems
described in
<http://sourceforge.net/mailarchive/message.php?msg_id=29660862> do not
reappear.

The code is derived from Paolo Bonzini's patch (originally appearing as
SeaBIOS commit f64a472a, "acpi: reintroduce LNKS"). Said original patch is
copyrighted by Red Hat (our common employer), and it has been relicensed
<http://sourceforge.net/mailarchive/message.php?msg_id=30393854> to form
the basis of this derived patch for edk2. The latter is therefore

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <ler...@redhat.com>
---
 OvmfPkg/AcpiTables/Dsdt.asl |   47 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/AcpiTables/Dsdt.asl b/OvmfPkg/AcpiTables/Dsdt.asl
index 12a4f14..6258dd9 100644
--- a/OvmfPkg/AcpiTables/Dsdt.asl
+++ b/OvmfPkg/AcpiTables/Dsdt.asl
@@ -203,10 +203,28 @@ DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF   
 ", 4) {
             Package () {0x0000FFFF, 0x02, \_SB.PCI0.LPC.LNKB, 0x00},
             Package () {0x0000FFFF, 0x03, \_SB.PCI0.LPC.LNKC, 0x00},
 
-            Package () {0x0001FFFF, 0x00, 0x00, 0x09},
             //
-            // list of IRQs occupied thus far: 9
+            // Bus 0, Device 1, Pin 0 (INTA) is special; it corresponds to the
+            // internally generated SCI (System Control Interrupt), which is
+            // always routed to GSI 9. By setting the third (= Source) field to
+            // zero, we could use the fourth (= Source Index) field to hardwire
+            // the pin to GSI 9 directly.
+            //
+            // That way however, in accordance with the ACPI spec's description
+            // of SCI, the interrupt would be treated as "active low,
+            // shareable, level", and that doesn't match qemu.
             //
+            // In QemuInstallAcpiMadtTable() [OvmfPkg/AcpiPlatformDxe/Qemu.c]
+            // we install an Interrupt Override Structure for the identity
+            // mapped IRQ#9 / GSI 9 (the corresponding bit being set in
+            // Pcd8259LegacyModeEdgeLevel), which describes the correct
+            // polarity (active high). As a consequence, some OS'en (eg. Linux)
+            // override the default (active low) polarity originating from the
+            // _PRT; others (eg. FreeBSD) don't. Therefore we need a separate
+            // link device just to specify a polarity that matches the MADT.
+            //
+            Package () {0x0001FFFF, 0x00, \_SB.PCI0.LPC.LNKS, 0x00},
+
             Package () {0x0001FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
             Package () {0x0001FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
             Package () {0x0001FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
@@ -292,6 +310,31 @@ DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF    
", 4) {
         Name (_ADR, 0x00010000)
 
         //
+        // The SCI cannot be rerouted or disabled with PIRQRC[A:D]; we only
+        // need this link device in order to specify the polarity.
+        //
+        Device (LNKS) {
+          Name (_HID, EISAID("PNP0C0F"))
+          Name (_UID, 0)
+
+          Method (_STA, 0, NotSerialized) {
+            Return (0xB) // 0x1: device present
+                         // 0x2: enabled and decoding resources
+                         // 0x8: functioning properly
+          }
+          Method (_SRS, 1, NotSerialized) { /* no-op */ }
+          Method (_DIS, 0, NotSerialized) { /* no-op */ }
+
+          Name (_PRS, ResourceTemplate () {
+            Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { 9 }
+            //
+            // list of IRQs occupied thus far: 9
+            //
+          })
+          Method (_CRS, 0, NotSerialized) { Return (_PRS) }
+        }
+
+        //
         // PCI Interrupt Routing Configuration Registers, PIRQRC[A:D]
         //
         OperationRegion (PRR0, PCI_Config, 0x60, 0x04)
-- 
1.7.1


------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. ON SALE this month only -- learn more at:
http://p.sf.net/sfu/learnnow-d2d
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to