summaryrefslogtreecommitdiff
path: root/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c
diff options
context:
space:
mode:
Diffstat (limited to 'Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c')
-rw-r--r--Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c544
1 files changed, 544 insertions, 0 deletions
diff --git a/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c
new file mode 100644
index 0000000..34540d7
--- /dev/null
+++ b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c
@@ -0,0 +1,544 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.c 6 5/16/14 5:56p Barretlin $
+//
+// $Revision: 6 $
+//
+// $Date: 5/16/14 5:56p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.c $
+//
+// 6 5/16/14 5:56p Barretlin
+// [TAG] EIP165410
+// [Category] Improvement
+// [Description] Support Thunderbolt AIC at NB PCIE slot
+// [Files] PciHotplug.c
+//
+// 5 5/14/14 1:15p Barretlin
+// [TAG] EIP165410
+// [Category] New Feature
+// [Description] Support Thunderbolt AIC at NB PCIE slot
+// [Files] PciHotPlug.c
+//
+// 4 4/24/13 5:02a Scottyang
+//
+// 3 9/12/12 5:15a Victortu
+// [TAG] None
+// [Category] Improvement
+// [Description] Modify for Thunderbolt support.
+// [Files] GetSetupData.c, SB.sdl, SB.sd, SB.uni, SbSetupData.h,
+// PciHotPlug.c
+//
+// 2 5/03/12 6:30a Victortu
+// [TAG] None
+// [Category] Improvement
+// [Description] Modify to support Thunderbolt.
+// [Files] SB.sd; SB.uni; SB.sdl; SbSetupData.h; PciHotPlug.c
+//
+// 1 2/08/12 8:37a Yurenlai
+// Intel Lynx Point/SB eChipset initially releases.
+//
+//*************************************************************************
+
+//
+// Statements that include other files
+//
+#include "PciHotPlug.h"
+#include <token.h>
+
+#define PCIE_NUM (11)
+
+//
+// Instantiation of Driver private data.
+//
+PCIE_HOT_PLUG_DEVICE_PATH mPcieList[PCIE_NUM] = {
+ {
+ ACPI,
+ PCI(0x1C, 0),
+ END
+ }, // PCI Express 0
+ {
+ ACPI,
+ PCI(0x1C, 1),
+ END
+ }, // PCI Express 1
+ {
+ ACPI,
+ PCI(0x1C, 2),
+ END
+ }, // PCI Express 2
+ {
+ ACPI,
+ PCI(0x1C, 3),
+ END
+ }, // PCI Express 3
+ {
+ ACPI,
+ PCI(0x1C, 4),
+ END
+ }, // PCI Express 4
+ {
+ ACPI,
+ PCI(0x1C, 5),
+ END
+ }, // PCI Express 5
+ {
+ ACPI,
+ PCI(0x1C, 6),
+ END
+ }, // PCI Express 6
+ {
+ ACPI,
+ PCI(0x1C, 7),
+ END
+ }, // PCI Express 7
+ {
+ ACPI,
+ PCI(0x01, 0),
+ END
+ }, // NB PCI Express 0
+ {
+ ACPI,
+ PCI(0x01, 1),
+ END
+ }, // NB PCI Express 1
+ {
+ ACPI,
+ PCI(0x01, 2),
+ END
+ }, // NB PCI Express 2
+};
+
+EFI_HPC_LOCATION mPcieLocation[PCIE_NUM] = {
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[0],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[0]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[1],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[1]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[2],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[2]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[3],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[3]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[4],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[4]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[5],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[5]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[6],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[6]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[7],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[7]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[8],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[8]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[9],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[9]
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[10],
+ (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[10]
+ },
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciHotPlug
+//
+// Description: This routine reads the PlatformType GPI on FWH and produces a protocol
+// to be consumed by the chipset driver to effect those settings.
+//
+// Input: ImageHandle An image handle.
+// SystemTable A pointer to the system table.
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PciHotPlug (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ PCI_HOT_PLUG_INSTANCE *PciHotPlug;
+
+
+ PciHotPlug = AllocatePool (sizeof (PCI_HOT_PLUG_INSTANCE));
+ ASSERT (PciHotPlug != NULL);
+
+ //
+ // Initialize driver private data.
+ //
+ ZeroMem (PciHotPlug, sizeof (PCI_HOT_PLUG_INSTANCE));
+
+ PciHotPlug->Signature = PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE;
+ PciHotPlug->HotPlugInitProtocol.GetRootHpcList = GetRootHpcList;
+ PciHotPlug->HotPlugInitProtocol.InitializeRootHpc = InitializeRootHpc;
+ PciHotPlug->HotPlugInitProtocol.GetResourcePadding = GetResourcePadding;
+
+ Status = gBS->InstallProtocolInterface (
+ &PciHotPlug->Handle,
+ &gEfiPciHotPlugInitProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &PciHotPlug->HotPlugInitProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetRootHpcList
+//
+// Description: This procedure returns a list of Root Hot Plug controllers
+// that require initialization during boot process
+//
+// Input: This The pointer to the instance of the
+// EFI_PCI_HOT_PLUG_INIT protocol.
+// HpcCount The number of Root HPCs returned.
+// HpcList The list of Root HPCs. HpcCount defines the
+// number of elements in this list.
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetRootHpcList (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ OUT UINTN *HpcCount,
+ OUT EFI_HPC_LOCATION **HpcList
+ )
+{
+
+ *HpcCount = PCIE_NUM;
+ *HpcList = mPcieLocation;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InitializeRootHpc
+//
+// Description: This procedure Initializes one Root Hot Plug Controller
+// This process may casue initialization of its subordinate buses
+//
+// Input: This The pointer to the instance of the
+// EFI_PCI_HOT_PLUG_INIT protocol.
+// HpcDevicePath The Device Path to the HPC that is being initialized.
+// HpcPciAddress The address of the Hot Plug Controller function
+// on the PCI bus.
+// Event The event that should be signaled when the Hot
+// Plug Controller initialization is complete.
+// Set to NULL if the caller wants to wait until
+// the entire initialization process is complete.
+// The event must be of the type EFI_EVT_SIGNAL.
+// HpcState The state of the Hot Plug Controller hardware.
+// The type EFI_Hpc_STATE is defined in section 3.1.
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+InitializeRootHpc (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ IN UINT64 HpcPciAddress,
+ IN EFI_EVENT Event, OPTIONAL
+ OUT EFI_HPC_STATE *HpcState
+ )
+{
+ if (Event) {
+ gBS->SignalEvent (Event);
+ }
+
+ *HpcState = EFI_HPC_STATE_INITIALIZED;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetResourcePadding
+//
+// Description: Returns the resource padding required by the PCI bus that is
+// controlled by the specified Hot Plug Controller.
+//
+// Input: This The pointer to the instance of the
+// EFI_PCI_HOT_PLUG_INIT protocol.
+// HpcDevicePath The Device Path to the HPC that is being initialized.
+// HpcPciAddress The address of the Hot Plug Controller function
+// on the PCI bus.
+// HpcState The state of the Hot Plug Controller hardware.
+// The type EFI_Hpc_STATE is defined in section 3.1.
+// Padding This is the amount of resource padding required
+// by the PCI bus under the control of the specified Hpc.
+// Since the caller does not know the size of this buffer,
+// this buffer is allocated by the callee and freed by the
+// caller.
+// Attribute Describes how padding is accounted for.
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetResourcePadding (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ IN UINT64 HpcPciAddress,
+ OUT EFI_HPC_STATE *HpcState,
+ OUT VOID **Padding,
+ OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes
+ )
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *PaddingResource;
+ EFI_STATUS Status;
+ UINT8 FindRP;
+ UINT8 RsvdExtraBusNum = 0;
+ // (SB082311A)>
+ UINT16 RsvdPcieMegaMem = 0;
+ UINT8 RsvdPcieKiloIo = 0;
+ UINT16 RsvdPcieMegaPFMem = 0;
+ UINT8 RsvdPcieMegaMemalig = 0;
+ UINT8 RsvdPcieMegaPFMemalig = 0;
+ // <(SB082311A)
+ UINTN VariableSize;
+ SETUP_DATA SetupData;
+ EFI_GUID SetupGuid = SETUP_GUID;
+ UINT32 RPFN; //Root Port Function Number
+ UINT8 SwRPFN;
+
+ PaddingResource = AllocatePool (PCIE_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+ ASSERT (PaddingResource != NULL);
+
+ *Padding = (VOID *) PaddingResource;
+
+ RPFN = MmioRead32(SB_RCRB_BASE_ADDRESS + R_PCH_RCRB_RPFN);
+ DEBUG((EFI_D_INFO, "\nRCBA RPFN = %x\n", RPFN));
+ //
+ // Check if PCIe Root Hob Controller need to reserve bus for docking downstream P2P hotplug
+ //
+
+ VariableSize = sizeof(SETUP_DATA);
+ Status = gRT->GetVariable(L"Setup",
+ &SetupGuid,
+ NULL,
+ &VariableSize,
+ &SetupData);
+
+ for (FindRP = 0; FindRP < PCIE_NUM; FindRP ++) {
+ if (HpcPciAddress == EFI_PCI_ADDRESS(0, 0x1C, FindRP, 0)) {
+ if (!EFI_ERROR(Status)) {
+ switch (FindRP){
+ case 0:
+ SwRPFN = (UINT8)(RPFN & B_PCH_RCRB_RPFN_RP1FN);
+ break;
+ case 1:
+ SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP2FN) >> 4);
+ break;
+ case 2:
+ SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP3FN) >> 8);
+ break;
+ case 3:
+ SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP4FN) >> 12);
+ break;
+ case 4:
+ SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP5FN) >> 16);
+ break;
+ case 5:
+ SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP6FN) >> 20);
+ break;
+ case 6:
+ SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP7FN) >> 24);
+ break;
+ case 7:
+ SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP8FN) >> 28);
+ break;
+ default:
+ ASSERT_EFI_ERROR(EFI_DEVICE_ERROR);
+ }
+ DEBUG((EFI_D_INFO, "FindRP = %x\nSwRPFN = %x\n", FindRP, SwRPFN));
+#if (defined SB_SETUP_SUPPORT && SB_SETUP_SUPPORT) || \
+ (defined OEM_SB_SETUP_SUPPORT && OEM_SB_SETUP_SUPPORT)
+ if (SwRPFN == FindRP) {
+ DEBUG((EFI_D_INFO, "PCIE Root Port#%x does not swap...\n", FindRP));
+ if (SetupData.PcieRootPortHPE[FindRP]){
+ RsvdExtraBusNum = SetupData.ExtraBusRsvd[FindRP];
+ RsvdPcieMegaMem = SetupData.PcieMemRsvd[FindRP];
+ RsvdPcieMegaPFMem = SetupData.PciePFMemRsvd[FindRP];
+ RsvdPcieKiloIo = SetupData.PcieIoRsvd[FindRP];
+ RsvdPcieMegaMemalig = SetupData.PcieMemRsvdalig[FindRP];
+ RsvdPcieMegaPFMemalig = SetupData.PciePFMemRsvdalig[FindRP];
+ }
+ }
+ else{
+ DEBUG((EFI_D_INFO, "PCIE Root Port#%x is mapping to PCIE slot#%x...\n", FindRP, SwRPFN));
+ if (SetupData.PcieRootPortHPE[SwRPFN]){
+ RsvdExtraBusNum = SetupData.ExtraBusRsvd[SwRPFN];
+ RsvdPcieMegaMem = SetupData.PcieMemRsvd[SwRPFN];
+ RsvdPcieMegaPFMem = SetupData.PciePFMemRsvd[SwRPFN];
+ RsvdPcieKiloIo = SetupData.PcieIoRsvd[SwRPFN];
+ RsvdPcieMegaMemalig = SetupData.PcieMemRsvdalig[SwRPFN];
+ RsvdPcieMegaPFMemalig = SetupData.PciePFMemRsvdalig[SwRPFN];
+ }
+ }
+#endif
+ }
+ break;
+ } // SB PCIE root port
+#if defined Thunderbolt_SUPPORT && Thunderbolt_SUPPORT == 1
+ if (HpcPciAddress == EFI_PCI_ADDRESS(0, 0x01, (FindRP - 8), 0)) {
+ if (!EFI_ERROR(Status)) {
+ DEBUG((EFI_D_INFO, "Hotplug root port is NB PCIE root port\n"));
+ if ((SetupData.TbtEnable != 0) && (SetupData.TbtHostLocation >= 0x20) && (SetupData.TbtHostLocation < 0x23)){
+ DEBUG((EFI_D_INFO, "Update resource for NB PCIE root port\n"));
+ RsvdExtraBusNum = TBT_DEFAULT_EXTRA_BUS_RESERVED;
+ RsvdPcieMegaMem = TBT_DEFAULT_PCIE_MEM_RESERVED;
+ RsvdPcieMegaPFMem = TBT_DEFAULT_PCIE_PF_MEM_RESERVED;
+ RsvdPcieKiloIo = TBT_DEFAULT_PCIE_IO_RESERVED;
+ RsvdPcieMegaMemalig = 26;
+ RsvdPcieMegaPFMemalig = 28;
+ }
+ }
+ } // NB PCIE root port
+#endif
+ } // for loop
+
+ //
+ // Padding for bus
+ //
+ ZeroMem (PaddingResource, PCIE_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+ *Attributes = EfiPaddingPciBus;
+
+ PaddingResource->Desc = 0x8A;
+ PaddingResource->Len = 0x2B;
+ PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
+ PaddingResource->GenFlag = 0x0;
+ PaddingResource->SpecificFlag = 0;
+ PaddingResource->AddrRangeMin = 0;
+ PaddingResource->AddrRangeMax = 0;
+ PaddingResource->AddrLen = RsvdExtraBusNum;
+
+ //
+ // Padding for non-prefetchable memory
+ //
+ PaddingResource++;
+ PaddingResource->Desc = 0x8A;
+ PaddingResource->Len = 0x2B;
+ PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ PaddingResource->GenFlag = 0x0;
+ PaddingResource->AddrSpaceGranularity = 32;
+ PaddingResource->SpecificFlag = 0;
+ //
+ // Pad non-prefetchable
+ //
+ PaddingResource->AddrRangeMin = 0;
+ PaddingResource->AddrLen = RsvdPcieMegaMem * 0x100000;
+ PaddingResource->AddrRangeMax = (1 << RsvdPcieMegaMemalig) - 1; // 0x3FFFFFF
+
+ //
+ // Padding for prefetchable memory
+ //
+ PaddingResource++;
+ PaddingResource->Desc = 0x8A;
+ PaddingResource->Len = 0x2B;
+ PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ PaddingResource->GenFlag = 0x0;
+ PaddingResource->AddrSpaceGranularity = 32;
+ PaddingResource->SpecificFlag = 06;
+ //
+ // Padding for prefetchable memory
+ //
+ PaddingResource->AddrRangeMin = 0;
+ PaddingResource->AddrLen = RsvdPcieMegaPFMem * 0x100000;
+ //
+ // Pad 16 MB of MEM
+ //
+ PaddingResource->AddrRangeMax = (1 << RsvdPcieMegaPFMemalig) - 1; // 0xfffffff
+ //
+ // Alignment
+ //
+ // Padding for I/O
+ //
+ PaddingResource++;
+ PaddingResource->Desc = 0x8A;
+ PaddingResource->Len = 0x2B;
+ PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
+ PaddingResource->GenFlag = 0x0;
+ PaddingResource->SpecificFlag = 0;
+ PaddingResource->AddrRangeMin = 0;
+ PaddingResource->AddrLen = RsvdPcieKiloIo * 0x400;
+ //
+ // Pad 4K of IO
+ //
+ PaddingResource->AddrRangeMax = 1;
+ //
+ // Alignment
+ //
+ // Terminate the entries.
+ //
+ PaddingResource++;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Desc = ACPI_END_TAG_DESCRIPTOR;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Checksum = 0x0;
+
+ *HpcState = EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED;
+
+ return EFI_SUCCESS;
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+