pcieb_x86.c revision 870de8c6fab3eadbb9685bc2a5f97dc7d14be288
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* x86 specific code used by the pcieb driver */
#include <sys/sysmacros.h>
#include <sys/pcie_impl.h>
#include <sys/pcie_acpi.h>
/* Flag to turn off intel error handling workarounds */
int pcieb_intel_workaround_disable = 0;
void
}
int
{
}
/* x86 specific workarounds needed at the end of pcieb attach */
void
{
/* Must apply workaround only after all initialization is done */
}
/* Workarounds to enable error handling on certain Intel chipsets */
void
{
}
int
{
}
/* shpc is not supported on x86 */
/*ARGSUSED*/
int
{
return (DDI_FAILURE);
}
/*
* Dummy functions to get around the fact that there's no shpc module on x86
* today
*/
/*ARGSUSED*/
int
{
return (DDI_FAILURE);
}
/*ARGSUSED*/
int
{
return (DDI_FAILURE);
}
/*ARGSUSED*/
int
{
return (DDI_INTR_UNCLAIMED);
}
/*ARGSUSED*/
{
/* Always disable on x86 */
return (B_TRUE);
}
{
/*
* Intel ESB2 switches have a errata which prevents using MSIs
* for hotplug.
*/
return (((vendor_id == INTEL_VENDOR_ID) &&
}
void
{
/*
* _OSC initialization needs to be done before interrupts are
* initialized.
*/
}
void
{
struct ddi_parent_private_data *pdptr;
-1) != -1) {
} else
}
void
{
struct ddi_parent_private_data *pdptr;
}
/* _OSC related */
void
/*
* Call _OSC method for 2 reasons:
* 1. Hotplug: To determine if it is native or ACPI mode.
*
* 2. Error handling: Inform firmware that OS can support AER error
* handling. Currently we don't care for what the BIOS response was
* and instead setup interrupts for error handling as if it were
* supported.
*
* For hotpluggable slots the _OSC method has already been called as
* part of the hotplug initialization.
* For non-hotpluggable slots we need to call the _OSC method only for
* Root Ports (for AER support).
*/
}
/*
* Intel chip specific workarounds. Right now they're limited to the 5000, 5400
* and 7300 series chipsets.
*/
typedef struct x86_error_reg {
typedef struct x86_error_tbl {
int error_regs_len;
/*
* Chipset and device specific settings that are required for error handling
* (reporting, fowarding, and response at the RC) beyond the standard
* registers in the PCIE and AER caps.
*
* The Northbridge Root Port settings also apply to the ESI port. The ESI
* port is a special leaf device but functions like a root port connected
* to the Southbridge and receives all the onboard Southbridge errors
* including those from Southbridge Root Ports. However, this does not
* include the Southbridge Switch Ports which act like normal switch ports
* and is connected to the Northbridge through a separate link.
*
* PCIE errors from the ESB2 Southbridge RPs are simply fowarded to the ESI
* port on the Northbridge.
*
* If MSIs don't work we want UEs (Fatal and Non-Fatal) to panic the system,
* except for URs. We do this by having the Root Ports respond with a System
* Error and having that trigger a Machine Check (MCE).
*/
/*
* 7300 Northbridge Root Ports
*/
static x86_error_reg_t intel_7300_rp_regs[] = {
/* Command Register - Enable SERR */
/* AER UE Mask - Mask UR */
/* PEXCTRL[21] check for certain malformed TLP types and MSI enable */
{0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000},
/* PEXCTRL3[7]. MSI RAS error enable */
{0x4D, 32, 0xFFFFFFFF, 0x1, 0x0},
/* PEX_ERR_DOCMD[7:0] */
{0x144, 8, 0x0, 0x0, 0xF0},
/* EMASK_UNCOR_PEX[21:0] UE mask */
/* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */
{0x150, 8, 0x0, 0x0, 0x1},
};
#define INTEL_7300_RP_REGS_LEN \
(sizeof (intel_7300_rp_regs) / sizeof (x86_error_reg_t))
/*
* 5000 Northbridge Root Ports
*/
static x86_error_reg_t intel_5000_rp_regs[] = {
/* Command Register - Enable SERR */
/* AER UE Mask - Mask UR */
/* PEXCTRL[21] check for certain malformed TLP type */
{0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000},
/* PEXCTRL3[7]. MSI RAS error enable. */
{0x4D, 32, 0xFFFFFFFF, 0x1, 0x0},
/* PEX_ERR_DOCMD[7:0] */
{0x144, 8, 0x0, 0x0, 0xF0},
/* EMASK_UNCOR_PEX[21:0] UE mask */
/* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */
{0x150, 8, 0x0, 0x0, 0x1},
};
#define INTEL_5000_RP_REGS_LEN \
(sizeof (intel_5000_rp_regs) / sizeof (x86_error_reg_t))
/*
* 5400 Northbridge Root Ports.
*/
static x86_error_reg_t intel_5400_rp_regs[] = {
/* Command Register - Enable SERR */
/* AER UE Mask - Mask UR */
/* PEXCTRL[21] check for certain malformed TLP types */
{0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000},
/* PEXCTRL3. MSI RAS error enable. */
{0x4E, 8, 0x0, 0x1, 0x0},
/* PEX_ERR_DOCMD[11:0] */
{0x144, 16, 0x0, 0x0, 0xFF0},
/* PEX_ERR_PIN_MASK[4:0] do not mask ERR[2:0] pins used by DOCMD */
{0x146, 16, 0x0, 0x10, 0x10},
/* EMASK_UNCOR_PEX[21:0] UE mask */
/* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */
{0x150, 8, 0x0, 0x0, 0x1},
};
#define INTEL_5400_RP_REGS_LEN \
(sizeof (intel_5400_rp_regs) / sizeof (x86_error_reg_t))
/*
* ESB2 Southbridge Root Ports
*/
static x86_error_reg_t intel_esb2_rp_regs[] = {
/* Command Register - Enable SERR */
/* UEM[20:0] UE mask (write-once) */
};
#define INTEL_ESB2_RP_REGS_LEN \
(sizeof (intel_esb2_rp_regs) / sizeof (x86_error_reg_t))
/*
* ESB2 Southbridge Switch Ports
*/
static x86_error_reg_t intel_esb2_sw_regs[] = {
/* Command Register - Enable SERR */
/* AER UE Mask - Mask UR */
};
#define INTEL_ESB2_SW_REGS_LEN \
(sizeof (intel_esb2_sw_regs) / sizeof (x86_error_reg_t))
/* Intel 7300: 3600 = ESI, 3604-360A = NB root ports */
{0x8086, 0x3600, 0x3600, 0x0, 0xFF,
{0x8086, 0x3604, 0x360A, 0x0, 0xFF,
/* Intel 5000: 25C0, 25D0, 25D4, 25D8 = ESI */
{0x8086, 0x25C0, 0x25C0, 0x0, 0xFF,
{0x8086, 0x25D0, 0x25D0, 0x0, 0xFF,
{0x8086, 0x25D4, 0x25D4, 0x0, 0xFF,
{0x8086, 0x25D8, 0x25D8, 0x0, 0xFF,
/* Intel 5000: 25E2-25E7 and 25F7-25FA = NB root ports */
{0x8086, 0x25E2, 0x25E7, 0x0, 0xFF,
{0x8086, 0x25F7, 0x25FA, 0x0, 0xFF,
/* Intel 5400: 4000-4001, 4003 = ESI and 4021-4029 = NB root ports */
{0x8086, 0x4000, 0x4001, 0x0, 0xFF,
{0x8086, 0x4003, 0x4003, 0x0, 0xFF,
{0x8086, 0x4021, 0x4029, 0x0, 0xFF,
/* Intel 631xESB/632xESB aka ESB2: 2690-2697 = SB root ports */
{0x8086, 0x2690, 0x2697, 0x0, 0xFF,
/* Intel Switches on esb2: 3500-3503, 3510-351B */
{0x8086, 0x3500, 0x3503, 0x0, 0xFF,
{0x8086, 0x3510, 0x351B, 0x0, 0xFF,
/* XXX Intel PCIe-PCIx on esb2: 350C */
};
static int x86_error_init_tbl_len =
sizeof (x86_error_init_tbl) / sizeof (x86_error_tbl_t);
/*
* The main goal of this workaround is to set chipset specific settings if
* MSIs happen to be enabled on this device. Otherwise make the system
*/
void
{
int i, j;
return;
for (i = 0; i < x86_error_init_tbl_len; i++, tbl++) {
continue;
case 32:
break;
case 16:
break;
case 8:
break;
}
"off:0x%x mask:0x%x value:0x%x + orig:0x%x -> "
}
}
}
/*
* For devices that support Role Base Errors, make several UE have a FATAL
* severity. That way a Fatal Message will be sent instead of a Correctable
* Message. Without full FMA support, CEs will be ignored.
*/
void
{
return;
/*
* Check Root Port's machinecheck setting to determine if this
* workaround is needed or not.
*/
if (!pcie_get_rber_fatal(dip))
return;
return;
if (!rber)
return;
}
/*
* The Intel 5000 Chipset has an errata that requires read completion
* coalescing to be disabled if the Max Payload Size is set to 256 bytes.
*/
void
{
/*
* Turn off coalescing (bit 10)
*/
}
}
/*
* Workaround for certain switches regardless of platform
*/
void
{
return;
return;
/*
* Intel and PLX switches require SERR in CMD reg to foward error
* messages, though this is not PCIE spec-compliant behavior.
* To prevent the switches themselves from reporting errors on URs
* when the CMD reg has SERR enabled (which is expected according to
* the PCIE spec) we rely on masking URs in the AER cap.
*/
}
}
int
{
struct detachspec *ds;
struct attachspec *as;
switch (ctlop) {
case DDI_CTLOPS_DETACH:
case DDI_POST:
return (DDI_FAILURE);
}
break;
default:
break;
}
break;
case DDI_CTLOPS_ATTACH:
case DDI_PRE:
return (DDI_FAILURE);
}
break;
case DDI_POST:
/*
* For leaf devices supporting RBER and AER, we
* need to apply this workaround on them after
* attach to be notified of UEs that would
* otherwise be ignored as CEs on Intel chipsets
* currently
*/
break;
default:
break;
}
break;
default:
break;
}
return (DDI_SUCCESS);
}
void
{
/*
* like in attach, since hotplugging can change error registers,
* we need to ensure that the proper bits are set on this port
* after a configure operation
*/
}