Update PCIe Root Port _PRT to handle re-mapped functions

The chipset enforces static-defined interrupt swizzling on PCIe root
ports so if a port is remapped to a different function it needs to
still report the proper interrupt map to the OS instead of assuming
that function number is equivalent to root port number.

This change also includes an update to the PCH function disable
register which was incorrect for CPT/PPT and would cause unpredictable
behavior if used.

The kernel command line was changed to add 'nomsi' in order to force
PCIe devices to use IO-APIC assigned interrupts and not MSI to ensure
that the mapping is correct.

LUMPY current:

  00:1c.0 PCI bridge: Intel Corporation Device 1c10 (rev b5)
  00:1c.3 PCI bridge: Intel Corporation Device 1c16 (rev b5)

  16:   41518   0   0   0   IO-APIC-fasteoi   i915, ahci, ath9k
  19:     720   0   0   0   IO-APIC-fasteoi   ehci_hcd:usb2, eth0

LUMPY with PCIe port coalesce enabled:

  00:1c.0 PCI bridge: Intel Corporation Device 1c10 (rev b5)
  00:1c.1 PCI bridge: Intel Corporation Device 1c16 (rev b5)

  16:   38988   0   0   0   IO-APIC-fasteoi   i915, ahci, ath9k
  19:     347   0   0   0   IO-APIC-fasteoi   ehci_hcd:usb2, eth0

Change-Id: Ia5f6bb8888b5c38a5dbc88bb25ecdf1fca41ee3e
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: http://review.coreboot.org/978
Tested-by: build bot (Jenkins)
This commit is contained in:
Duncan Laurie 2012-04-27 09:55:45 -07:00 committed by Stefan Reinauer
parent 2c41c4027f
commit c323036884
3 changed files with 196 additions and 176 deletions

View File

@ -211,26 +211,32 @@ Scope(\)
, 5,
HPTE, 1, // Address Enable
Offset(0x3418), // FD (Function Disable)
, 2, // Reserved
SATD, 1, // SATA disable
, 1, // Reserved
PCID, 1, // PCI bridge disable
SA1D, 1, // SATA1 disable
SMBD, 1, // SMBUS disable
HDAD, 1, // Azalia disable
, 2, // Reserved
ILND, 1, // Internal LAN disable
US1D, 1, // UHCI #1 disable
US2D, 1, // UHCI #2 disable
US3D, 1, // UHCI #3 disable
US4D, 1, // UHCI #4 disable
, 2, // Reserved
, 8, // Reserved
EH2D, 1, // EHCI #2 disable
LPBD, 1, // LPC bridge disable
EHCD, 1, // EHCI disable
Offset(0x341a), // FD Root Ports
EH1D, 1, // EHCI #1 disable
RP1D, 1, // Root Port 1 disable
RP2D, 1, // Root Port 2 disable
RP3D, 1, // Root Port 3 disable
RP4D, 1 // Root Port 4 disable
RP4D, 1, // Root Port 4 disable
RP5D, 1, // Root Port 5 disable
RP6D, 1, // Root Port 6 disable
RP7D, 1, // Root Port 7 disable
RP8D, 1, // Root Port 8 disable
TTRD, 1, // Thermal sensor registers disable
SA2D, 1, // SATA2 disable
Offset(0x3428), // FD2 (Function Disable 2)
BDFD, 1, // Display BDF
ME1D, 1, // ME Interface 1 disable
ME2D, 1, // ME Interface 2 disable
IDRD, 1, // IDE redirect disable
KTCT, 1, // Keyboard Text redirect disable
}
}
// High Definition Audio (Azalia) 0:1b.0

View File

@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2012 The Chromium OS Authors. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -19,216 +20,199 @@
* MA 02110-1301 USA
*/
/* Intel Cougar Point PCH PCIe support */
/* Intel 6/7 Series PCH PCIe support */
// PCI Express Ports
Device (RP01)
{
NAME(_ADR, 0x001c0000) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Method(_PRT)
{
If (PICM) {
Return (Package() {
Method (IRQM, 1, Serialized) {
/* Interrupt Map INTA->INTA, INTB->INTB, INTC->INTC, INTD->INTD */
Name (IQAA, Package() {
Package() { 0x0000ffff, 0, 0, 16 },
Package() { 0x0000ffff, 1, 0, 17 },
Package() { 0x0000ffff, 2, 0, 18 },
Package() { 0x0000ffff, 3, 0, 19 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 3, 0, 19 } })
Name (IQAP, Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
})
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 } })
/* Interrupt Map INTA->INTB, INTB->INTC, INTC->INTD, INTD->INTA */
Name (IQBA, Package() {
Package() { 0x0000ffff, 0, 0, 17 },
Package() { 0x0000ffff, 1, 0, 18 },
Package() { 0x0000ffff, 2, 0, 19 },
Package() { 0x0000ffff, 3, 0, 16 } })
Name (IQBP, Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 } })
/* Interrupt Map INTA->INTC, INTB->INTD, INTC->INTA, INTD->INTB */
Name (IQCA, Package() {
Package() { 0x0000ffff, 0, 0, 18 },
Package() { 0x0000ffff, 1, 0, 19 },
Package() { 0x0000ffff, 2, 0, 16 },
Package() { 0x0000ffff, 3, 0, 17 } })
Name (IQCP, Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKB, 0 } })
/* Interrupt Map INTA->INTD, INTB->INTA, INTC->INTB, INTD->INTC */
Name (IQDA, Package() {
Package() { 0x0000ffff, 0, 0, 19 },
Package() { 0x0000ffff, 1, 0, 16 },
Package() { 0x0000ffff, 2, 0, 17 },
Package() { 0x0000ffff, 3, 0, 18 } })
Name (IQDP, Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKC, 0 } })
Switch (ToInteger (Arg0)) {
/* PCIe Root Port 1 and 5 */
Case (Package() { 1, 5 }) {
If (PICM) {
Return (IQAA)
} Else {
Return (IQAP)
}
}
/* PCIe Root Port 2 and 6 */
Case (Package() { 2, 6 }) {
If (PICM) {
Return (IQBA)
} Else {
Return (IQBP)
}
}
/* PCIe Root Port 3 and 7 */
Case (Package() { 3, 7 }) {
If (PICM) {
Return (IQCA)
} Else {
Return (IQCP)
}
}
/* PCIe Root Port 4 and 8 */
Case (Package() { 4, 8 }) {
If (PICM) {
Return (IQDA)
} Else {
Return (IQDP)
}
}
Default {
If (PICM) {
Return (IQDA)
} Else {
Return (IQDP)
}
}
}
}
Device (RP01)
{
Name (_ADR, 0x001c0000)
#include "pcie_port.asl"
Method (_PRT)
{
Return (IRQM (RPPN))
}
}
Device (RP02)
{
NAME(_ADR, 0x001c0001) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Name (_ADR, 0x001c0001)
#include "pcie_port.asl"
Method (_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 17 },
Package() { 0x0000ffff, 1, 0, 18 },
Package() { 0x0000ffff, 2, 0, 19 },
Package() { 0x0000ffff, 3, 0, 16 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
})
}
Return (IRQM (RPPN))
}
}
Device (RP03)
{
NAME(_ADR, 0x001c0002) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Name (_ADR, 0x001c0002)
#include "pcie_port.asl"
Method (_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 18 },
Package() { 0x0000ffff, 1, 0, 19 },
Package() { 0x0000ffff, 2, 0, 16 },
Package() { 0x0000ffff, 3, 0, 17 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKB, 0 }
})
}
Return (IRQM (RPPN))
}
}
Device (RP04)
{
NAME(_ADR, 0x001c0003) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Name (_ADR, 0x001c0003)
#include "pcie_port.asl"
Method (_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 17 },
Package() { 0x0000ffff, 1, 0, 18 },
Package() { 0x0000ffff, 2, 0, 19 },
Package() { 0x0000ffff, 3, 0, 16 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
})
}
Return (IRQM (RPPN))
}
}
Device (RP05)
{
NAME(_ADR, 0x001c0004) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Name (_ADR, 0x001c0004)
#include "pcie_port.asl"
Method (_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 16 },
Package() { 0x0000ffff, 1, 0, 17 },
Package() { 0x0000ffff, 2, 0, 18 },
Package() { 0x0000ffff, 3, 0, 19 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
})
}
Return (IRQM (RPPN))
}
}
Device (RP06)
{
NAME(_ADR, 0x001c0005) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Name (_ADR, 0x001c0005)
#include "pcie_port.asl"
Method (_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 17 },
Package() { 0x0000ffff, 1, 0, 18 },
Package() { 0x0000ffff, 2, 0, 19 },
Package() { 0x0000ffff, 3, 0, 16 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
})
}
Return (IRQM (RPPN))
}
}
Device (RP07)
{
NAME(_ADR, 0x001c0006) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Name (_ADR, 0x001c0006)
#include "pcie_port.asl"
Method (_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 18 },
Package() { 0x0000ffff, 1, 0, 19 },
Package() { 0x0000ffff, 2, 0, 16 },
Package() { 0x0000ffff, 3, 0, 17 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKB, 0 }
})
}
Return (IRQM (RPPN))
}
}
Device (RP08)
{
NAME(_ADR, 0x001c0007) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Name (_ADR, 0x001c0007)
#include "pcie_port.asl"
Method (_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 19 },
Package() { 0x0000ffff, 1, 0, 16 },
Package() { 0x0000ffff, 2, 0, 17 },
Package() { 0x0000ffff, 3, 0, 18 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKC, 0 }
})
}
Return (IRQM (RPPN))
}
}

View File

@ -0,0 +1,30 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2012 The Chromium OS Authors. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
/* Included in each PCIe Root Port device */
OperationRegion (RPCS, PCI_Config, 0x00, 0xFF)
Field (RPCS, AnyAcc, NoLock, Preserve)
{
Offset (0x4c), // Link Capabilities
, 24,
RPPN, 8, // Root Port Number
}