/** @file Install Iio Port Bifurcation Init Data. This is depreciated version of the code used for PLATFORM_IIO_CONFIG_UPDATE_VERSION == 1 @copyright Copyright 2020 - 2021 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "PeiCommonBoardInitLib.h" #include #include #include #include #include #include #include #include "IioBifurcationSlotTable.h" #include #include #include #include #include #include #include /** Function returns the board ID from running HW @return BoardId **/ UINT8 EFIAPI SystemBoardIdValue ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; EFI_PLATFORM_INFO *mPlatformInfo; GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid); ASSERT (GuidHob != NULL); if (GuidHob == NULL) { return TypePlatformUnknown; } mPlatformInfo = GET_GUID_HOB_DATA (GuidHob); return mPlatformInfo->BoardId; } /** DVP/Neon City platform support BW5 bifurcation card in socket0 and socket1 Lightning Ridge platform support BW5 bifurcation card in socket1, socket2 and socket3 The bifurcation info stored at I/O Expander (PCA9555) which BIOS can get through Smbus read. PCA9555 SMBus slave Address: 0x4C ---------------------------------- Neon ---------------------------------- data0 = BW5 socket0 iio2 data1 = BW5 socket1 iio0 data2 = BW5 socket1 iio3 ---------------------------------- Lighting Ridge ---------------------------------- data1 = BW5 socket1 iio2 data2 = BW5 socket2 iio1 data3 = BW5 socket3 iio3 The bifurcation encoding is [2:0]: BW5_BIFURCATE_x4x4x4x4 x 0 0 0 BW5_BIFURCATE_xxx8x4x4 x 0 0 1 BW5_BIFURCATE_x4x4xxx8 x 0 1 0 BW5_BIFURCATE_xxx8xxx8 x 0 1 1 No BW5 x 1 1 1 @param IioGlobalData - Pointer to IioGlobals @param Bw5Id - Pointer to BW5ID @retval None **/ VOID GetBw5Id ( IN IIO_GLOBALS *IioGlobalData, IN OUT BW5_BIFURCATION_DATA_STRUCT *Bw5Id ) { CONST EFI_PEI_SERVICES **PeiServices; EFI_STATUS Status; EFI_SMBUS_DEVICE_ADDRESS SmbusDeviceAddress; EFI_SMBUS_DEVICE_COMMAND SmbusCommand; EFI_PEI_SMBUS2_PPI *Smbus = NULL; UINT16 SmbusData = 0; UINT8 RetryCount; UINTN SmbusLength = 2; UINT8 Index; PeiServices = GetPeiServicesTablePointer (); Status = (**PeiServices).LocatePpi ( PeiServices, &gEfiPeiSmbus2PpiGuid, 0, NULL, &Smbus ); // Initialize Bw5Id to not present for (Index = 0; Index < BW5_CARDS_PRESENT; Index++){ Bw5Id[Index].Data = BW5_CARD_NOT_PRESENT; } if (Status != EFI_SUCCESS || Smbus == NULL) { DEBUG ((EFI_D_INFO, "!!!!Get SMBus protocol error %x\n", Status)); } else { // Read Socket 0 HP Controller SmbusDeviceAddress.SmbusDeviceAddress = (BW5_SMBUS_ADDRESS >> 1); for (RetryCount = 0; RetryCount < NUM_OF_RETRIES; RetryCount++) { // // Read the current I/O pins Config for Port0 // SmbusCommand = PCA9555_COMMAND_CONFIG_PORT0_REG; Status = Smbus->Execute ( Smbus, SmbusDeviceAddress, SmbusCommand, EfiSmbusReadWord, FALSE, &SmbusLength, &SmbusData ); if (!EFI_ERROR(Status)) { // // Configure the direction of I/O pins for Port0/Port1 as Input. // SmbusData = SmbusData | BW5_CONFIG_REG_MASK; Status = Smbus->Execute ( Smbus, SmbusDeviceAddress, SmbusCommand, EfiSmbusWriteWord, FALSE, &SmbusLength, &SmbusData ); if (!EFI_ERROR(Status)) { // // Read Input Port0/Port1 register to identify BW5 Id // SmbusCommand = PCA9555_COMMAND_INPUT_PORT0_REG; Status = Smbus->Execute( Smbus, SmbusDeviceAddress, SmbusCommand, EfiSmbusReadWord, FALSE, &SmbusLength, &SmbusData ); if (!EFI_ERROR(Status)){ DEBUG ((EFI_D_INFO, "SmbusData Port0/1 %x\n", SmbusData)); // // Mask the Input Port0/1 register data [15:0] to get BW5 ID. // Bw5Id[0].Data = (SmbusData & BW5_0_ID_MASK); Bw5Id[1].Data = (SmbusData & BW5_1_ID_MASK) >> 4; Bw5Id[2].Data = (SmbusData & BW5_2_ID_MASK) >> 8; Bw5Id[3].Data = (SmbusData & BW5_3_ID_MASK) >> 12; break; // Break Loop if read was successfully. } // Read Port0 } // Configure Port0 } // Read Port0 Config } //RetryCount } // (Status != EFI_SUCCESS || Smbus == NULL) return; } EFI_STATUS InternalPlatformGetSlotTableData2 ( IN OUT IIO_BROADWAY_ADDRESS_DATA_ENTRY **BroadwayTable, IN OUT UINT8 *IOU0Setting, IN OUT UINT8 *FlagValue, IN OUT UINT8 *IOU2Setting, IN UINT8 SkuPersonalityType ) { EFI_STATUS Status; UBA_CONFIG_DATABASE_PPI *UbaConfigPpi = NULL; PLATFORM_SLOT_UPDATE_TABLE2 IioSlotTable; UINTN TableSize; Status = PeiServicesLocatePpi ( &gUbaConfigDatabasePpiGuid, 0, NULL, &UbaConfigPpi ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } TableSize = sizeof(IioSlotTable); if ((SkuPersonalityType == 1) || (SkuPersonalityType == 3)) { Status = UbaConfigPpi->GetData ( UbaConfigPpi, &gPlatformSlotDataGuid2_1, &IioSlotTable, &TableSize ); } else { Status = UbaConfigPpi->GetData ( UbaConfigPpi, &gPlatformSlotDataGuid2, &IioSlotTable, &TableSize ); } if (EFI_ERROR(Status)) { return Status; } ASSERT (IioSlotTable.Signature == PLATFORM_SLOT_UPDATE_SIGNATURE); ASSERT (IioSlotTable.Version == PLATFORM_SLOT_UPDATE_VERSION); *BroadwayTable = IioSlotTable.BroadwayTablePtr; *IOU0Setting = IioSlotTable.GetIOU0Setting (*IOU0Setting); *FlagValue = IioSlotTable.FlagValue; *IOU2Setting = IioSlotTable.GetIOU2Setting (SkuPersonalityType, *IOU2Setting); return Status; } EFI_STATUS InternalPlatformIioConfigInit2 ( IN UINT8 SkuPersonalityType, IN OUT IIO_BIFURCATION_DATA_ENTRY **BifurcationTable, IN OUT UINT8 *BifurcationEntries, IN OUT IIO_SLOT_CONFIG_DATA_ENTRY **SlotTable, IN OUT UINT8 *SlotEntries ) { EFI_STATUS Status = EFI_SUCCESS; UBA_CONFIG_DATABASE_PPI *UbaConfigPpi = NULL; PLATFORM_IIO_CONFIG_UPDATE_TABLE IioConfigTable; UINTN TableSize; Status = PeiServicesLocatePpi ( &gUbaConfigDatabasePpiGuid, 0, NULL, &UbaConfigPpi ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } TableSize = sizeof(IioConfigTable); if (SkuPersonalityType == 1) { Status = UbaConfigPpi->GetData ( UbaConfigPpi, &gPlatformIioConfigDataGuid_1, &IioConfigTable, &TableSize ); } else if (SkuPersonalityType == 2) { Status = UbaConfigPpi->GetData ( UbaConfigPpi, &gPlatformIioConfigDataGuid_2, &IioConfigTable, &TableSize ); } else if (SkuPersonalityType == 3) { Status = UbaConfigPpi->GetData ( UbaConfigPpi, &gPlatformIioConfigDataGuid_3, &IioConfigTable, &TableSize ); } else { Status = UbaConfigPpi->GetData ( UbaConfigPpi, &gPlatformIioConfigDataGuid, &IioConfigTable, &TableSize ); } if (EFI_ERROR(Status)) { return Status; } ASSERT (IioConfigTable.Signature == PLATFORM_IIO_CONFIG_UPDATE_SIGNATURE); ASSERT (IioConfigTable.Version == PLATFORM_IIO_CONFIG_UPDATE_VERSION); *BifurcationTable = IioConfigTable.IioBifurcationTablePtr; *BifurcationEntries = (UINT8) (IioConfigTable.IioBifurcationTableSize / sizeof(IIO_BIFURCATION_DATA_ENTRY)); *SlotTable = IioConfigTable.IioSlotTablePtr; *SlotEntries = (UINT8) (IioConfigTable.IioSlotTableSize / sizeof(IIO_SLOT_CONFIG_DATA_ENTRY)); return Status; } VOID EnableHotPlug_SKX ( IN OUT IIO_GLOBALS *IioGlobalData, IN UINT8 Port, IN UINT8 VppPort, IN UINT8 VppAddress, IN UINT8 PortOwnership ) { IioGlobalData->SetupData.SLOTHPCAP[Port]= ENABLE; IioGlobalData->SetupData.SLOTAIP[Port] = ENABLE; // Attention Indicator Present IioGlobalData->SetupData.SLOTPIP[Port] = ENABLE; // Power Indicator Present IioGlobalData->SetupData.SLOTMRLSP[Port]= ENABLE; // MRL Sensor Present IioGlobalData->SetupData.SLOTABP[Port] = ENABLE; // Attention Button Present IioGlobalData->SetupData.SLOTPCP[Port] = ENABLE; // Power Controlled Present if (PortOwnership == PCIEAIC_OCL_OWNERSHIP){ IioGlobalData->SetupData.SLOTAIP[Port] = DISABLE; // Attention Indicator Present IioGlobalData->SetupData.SLOTPIP[Port] = DISABLE; // Power Indicator Present } if (PortOwnership == VMD_OWNERSHIP){ IioGlobalData->SetupData.SLOTABP[Port] = DISABLE; IioGlobalData->SetupData.SLOTPCP[Port] = DISABLE; IioGlobalData->SetupData.SLOTMRLSP[Port]= DISABLE; } // // Set SLTCAP settings based on VMD/PCIe SSD Ownership // if ((PortOwnership == PCIEAIC_OCL_OWNERSHIP) || (PortOwnership == VMD_OWNERSHIP)){ IioGlobalData->SetupData.SLOTHPSUP[Port]= ENABLE; // HotPlug Surprise } if (VppPort!= VPP_PORT_MAX) { IioGlobalData->SetupData.VppEnabled[Port]= TRUE; IioGlobalData->SetupData.VppPort[Port]= VppPort; IioGlobalData->SetupData.VppAddress[Port] = VppAddress; } else { DEBUG((EFI_D_ERROR, "PCIE HOT Plug. Missing VPP values on slot table\n")); } } /** Auto determine which PCIe Root port to be hidden if its lanes are assigned to its preceding root port...use the Setup option variable of ConfigIOU to determine which ports are to be hidden on each IOU for corresponding IIO @param IOUx - IOUx Index @param IioIndex - Index to Iio @param IioGlobalData Pointer to Iio Globals. **/ VOID CalculatePEXPHideFromIouBif_SKX ( IN UINT8 Iou, IN UINT8 IioIndex, IN OUT IIO_GLOBALS *IioGlobalData ) { UINT8 *PXPHide, *HidePEXPMenu; UINT8 CurrentIOUConfigValue; UINT8 PXPOffset; UINT8 MaxPortNumberPerSocket; if (IioIndex >= MaxIIO || Iou >= NELEMENTS (IioGlobalData->SetupData.ConfigIOU[IioIndex])) { DEBUG ((DEBUG_ERROR, "[IIO] ERROR: %a: IIO instance %d or IOU %d out of range", __FUNCTION__, IioIndex, Iou)); ASSERT (FALSE); return; } PXPHide = IioGlobalData->SetupData.PEXPHIDE; HidePEXPMenu = IioGlobalData->SetupData.HidePEXPMenu; MaxPortNumberPerSocket = IioGlobalData->IioVar.IioOutData.MaxPciePortNumberPerSocket[IioIndex]; PXPOffset = IioIndex * MaxPortNumberPerSocket; CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigIOU[IioIndex][Iou]; switch (Iou) { case Iio_Iou0: PXPOffset += PORT_1A_INDEX; break; case Iio_Iou1: PXPOffset += PORT_2A_INDEX; break; case Iio_Iou2: PXPOffset += PORT_3A_INDEX; break; case Iio_Iou3: PXPOffset += PORT_4A_INDEX; break; case Iio_Iou4: PXPOffset += PORT_5A_INDEX; break; default: break; } switch (CurrentIOUConfigValue) { case IIO_BIFURCATE_xxxxxxxx: PXPHide[PXPOffset + Iio_PortA] = HIDE; // hide A PXPHide[PXPOffset + Iio_PortB] = HIDE; // hide B PXPHide[PXPOffset + Iio_PortC] = HIDE; // hide C PXPHide[PXPOffset + Iio_PortD] = HIDE; // hide D HidePEXPMenu[PXPOffset + Iio_PortA] = HIDE; // hide the Setup menu for A HidePEXPMenu[PXPOffset + Iio_PortB] = HIDE; // hide the Setup menu for B HidePEXPMenu[PXPOffset + Iio_PortC] = HIDE; // hide the Setup menu for C HidePEXPMenu[PXPOffset + Iio_PortD] = HIDE; // hide the Setup menu for D break; case IIO_BIFURCATE_x4x4xxx8: PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A PXPHide[PXPOffset + Iio_PortB] = HIDE; // hide B PXPHide[PXPOffset + Iio_PortC] = NOT_HIDE; // show C PXPHide[PXPOffset + Iio_PortD] = NOT_HIDE; // show D HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for B HidePEXPMenu[PXPOffset + Iio_PortB] = HIDE; // hide the Setup menu for B HidePEXPMenu[PXPOffset + Iio_PortC] = NOT_HIDE; // show the Setup menu for D HidePEXPMenu[PXPOffset + Iio_PortD] = NOT_HIDE; // show the Setup menu for B break; case IIO_BIFURCATE_xxx8x4x4: PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A PXPHide[PXPOffset + Iio_PortB] = NOT_HIDE; // show B PXPHide[PXPOffset + Iio_PortC] = NOT_HIDE; // show C PXPHide[PXPOffset + Iio_PortD] = HIDE; // hide port D HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for A HidePEXPMenu[PXPOffset + Iio_PortB] = NOT_HIDE; // show the Setup menu for B HidePEXPMenu[PXPOffset + Iio_PortC] = NOT_HIDE; // show the Setup menu for C HidePEXPMenu[PXPOffset + Iio_PortD] = HIDE; // hide the Setup menu for D break; case IIO_BIFURCATE_xxx8xxx8: PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A PXPHide[PXPOffset + Iio_PortB] = HIDE; // hide B PXPHide[PXPOffset + Iio_PortC] = NOT_HIDE; // show C PXPHide[PXPOffset + Iio_PortD] = HIDE; // hide D HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for A HidePEXPMenu[PXPOffset + Iio_PortB] = HIDE; // hide the Setup menu for B HidePEXPMenu[PXPOffset + Iio_PortC] = NOT_HIDE; // show the Setup menu for C HidePEXPMenu[PXPOffset + Iio_PortD] = HIDE; // hide the Setup menu for D break; case IIO_BIFURCATE_xxxxxx16: PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A PXPHide[PXPOffset + Iio_PortB] = HIDE; // hide B PXPHide[PXPOffset + Iio_PortC] = HIDE; // hide C PXPHide[PXPOffset + Iio_PortD] = HIDE; // hide D HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for A HidePEXPMenu[PXPOffset + Iio_PortB] = HIDE; // hide the Setup menu for B HidePEXPMenu[PXPOffset + Iio_PortC] = HIDE; // hide the Setup menu for C HidePEXPMenu[PXPOffset + Iio_PortD] = HIDE; // hide the Setup menu for D break; default: PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A PXPHide[PXPOffset + Iio_PortB] = NOT_HIDE; // show B PXPHide[PXPOffset + Iio_PortC] = NOT_HIDE; // show C PXPHide[PXPOffset + Iio_PortD] = NOT_HIDE; // show port D HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for A HidePEXPMenu[PXPOffset + Iio_PortB] = NOT_HIDE; // show the Setup menu for B HidePEXPMenu[PXPOffset + Iio_PortC] = NOT_HIDE; // show the Setup menu for C HidePEXPMenu[PXPOffset + Iio_PortD] = NOT_HIDE; // show the Setup menu for D break; } // // Change PEXPHIDE setting to hide all PCIe port of a IOU if IIO_BIFURCATE_xxxxxxxx is set. // And set ConfigIOU/ConfigMCPx to default bifucation control value // Bifurcation_Control[2:0] in IOU Bifurcation Control (PCIE_IOU_BIF_CTRL) register should be 000b ~ 100b. // if (CurrentIOUConfigValue == IIO_BIFURCATE_xxxxxxxx) { IioGlobalData->SetupData.ConfigIOU[IioIndex][Iou] = IIO_BIFURCATE_x4x4x4x4; } } VOID DumpPort_SKX( IIO_GLOBALS *IioGlobalData, UINT8 Port, UINT8 NumberOfPorts ) { UINT8 Index; DEBUG((EFI_D_INFO, "IDX, Port Hide, Slot Impl, Slot Number, HotPlug, PcieSSD, VppPort, VppAddress, Interlock\n")); for (Index = Port; Index < (Port + NumberOfPorts); Index++ ) { DEBUG((EFI_D_INFO, "%3d| %2d | %2d | %3d | %3d | %3d | 0x%02x | 0x%02x | %2d \n", \ Index, \ IioGlobalData->SetupData.PEXPHIDE[Index], \ IioGlobalData->SetupData.SLOTIMP[Index], \ IioGlobalData->SetupData.SLOTPSP[Index], \ IioGlobalData->SetupData.SLOTHPCAP[Index], \ IioGlobalData->IioVar.IioOutData.PciePortOwnership[Index], \ IioGlobalData->SetupData.VppPort[Index], \ IioGlobalData->SetupData.VppAddress[Index],\ IioGlobalData->SetupData.SLOTEIP[Index])); } } /// Dump iio configuration. Dump the current IIO configuration to the serial /// log. VOID DumpIioConfiguration_SKX( IN UINT8 iio, IN IIO_GLOBALS *IioGlobalData ) { UINT8 Iou; UINT8 PortIndex; UINT8 MaxPortNumberPerSocket; UINT8 Bifurcation; UINT8 IouPorts; MaxPortNumberPerSocket = IioGlobalData->IioVar.IioOutData.MaxPciePortNumberPerSocket[iio]; PortIndex = iio * MaxPortNumberPerSocket; /// First dump the socket number; DEBUG((EFI_D_INFO, "Socket number: %d \n", iio)); /// Dump DMI configuration: if ((iio == 0) && (PortIndex == 0)){ DEBUG((EFI_D_INFO, "PORT 0: DMI Port\n")); } else { DEBUG((EFI_D_INFO, "PORT 0: DMI Port working as PCIE\n")); DumpPort_SKX(IioGlobalData, PortIndex, 1); } IouPorts=4; /// Dump IOU bifurcations: for (Iou = Iio_Iou0; Iou< Iio_IouMax; Iou ++) { /// Reset port index. PortIndex = iio * MaxPortNumberPerSocket; // Get the bifurcation switch (Iou) { case Iio_Iou0: Bifurcation = IioGlobalData->SetupData.ConfigIOU[iio][0]; PortIndex += PORT_1A_INDEX; DEBUG((EFI_D_INFO, "IUO0: Root Port 1, Bifurcation: %d\n", Bifurcation)); break; case Iio_Iou1: Bifurcation = IioGlobalData->SetupData.ConfigIOU[iio][1]; PortIndex += PORT_2A_INDEX; DEBUG((EFI_D_INFO, "IUO1: Root Port 2, Bifurcation: %d\n", Bifurcation)); break; case Iio_Iou2: Bifurcation = IioGlobalData->SetupData.ConfigIOU[iio][2]; PortIndex += PORT_3A_INDEX; DEBUG((EFI_D_INFO, "IUO2: Root Port 3, Bifurcation: %d\n", Bifurcation)); break; case Iio_Iou3: Bifurcation = IioGlobalData->SetupData.ConfigIOU[iio][3]; PortIndex += PORT_4A_INDEX; DEBUG((EFI_D_INFO, "IOU3, Bifurcation: %d\n", Bifurcation)); break; case Iio_Iou4: Bifurcation = IioGlobalData->SetupData.ConfigIOU[iio][4]; PortIndex += PORT_5A_INDEX; DEBUG((EFI_D_INFO, "IOU4, Bifurcation: %d\n", Bifurcation)); break; default: DEBUG((EFI_D_INFO, "Iou no detected = %d",Iou)); break; } DumpPort_SKX(IioGlobalData, PortIndex, IouPorts); } } VOID SystemHideIioPortsCommon_SKX( IIO_GLOBALS *IioGlobalData, UINT8 IioIndex ) { CalculatePEXPHideFromIouBif_SKX(Iio_Iou0, IioIndex, IioGlobalData); CalculatePEXPHideFromIouBif_SKX(Iio_Iou1, IioIndex, IioGlobalData); CalculatePEXPHideFromIouBif_SKX(Iio_Iou2, IioIndex, IioGlobalData); CalculatePEXPHideFromIouBif_SKX(Iio_Iou3, IioIndex, IioGlobalData); CalculatePEXPHideFromIouBif_SKX(Iio_Iou4, IioIndex, IioGlobalData); DumpIioConfiguration_SKX(IioIndex, IioGlobalData); } /** Verify if and Slot should be implemented based on IOUX bifurcation settings. @param IioGlobalData Pointer to Iio Globals. @param Port - Port Index @retval TRUE/FALSE to determine if an slot should be implemented or not based on the IOUX bifurcation settings in case user want to do an override and VMD is enabled. **/ BOOLEAN SlotImplemented_SKX ( IN OUT IIO_GLOBALS *IioGlobalData, IN UINT8 Port ) { UINT8 IioIndex; UINT8 MaxPortNumberPerSocket; UINT8 PortIndex; UINT8 Stack; BOOLEAN SlotImp = FALSE; MaxPortNumberPerSocket = IioGlobalData->IioVar.IioOutData.MaxPciePortNumberPerSocket[0]; IioIndex = Port/MaxPortNumberPerSocket; PortIndex = (Port - (MaxPortNumberPerSocket * IioIndex)); Stack = IioGlobalData->IioVar.IioVData.StackPerPort[IioIndex][PortIndex]; DEBUG ((DEBUG_INFO, "SlotImplemented_SKX:IioIndex = %x, Stack = %x, Port = %x, PortIndex =%x\n", IioIndex, Stack, Port, PortIndex)); switch (Stack) { case IIO_PSTACK0: if (IioGlobalData->SetupData.ConfigIOU[IioIndex][0] == IIO_BIFURCATE_x4x4x4x4) { SlotImp = TRUE; } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][0] == IIO_BIFURCATE_x4x4xxx8){ if ((PortIndex == PORT_1D_INDEX) || (PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][0] == IIO_BIFURCATE_xxx8x4x4) { if ((PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1B_INDEX) || (PortIndex == PORT_1A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][0] == IIO_BIFURCATE_xxx8xxx8) { if ((PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1A_INDEX)){ SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][0] == IIO_BIFURCATE_xxxxxx16) { if (PortIndex == PORT_1A_INDEX) { SlotImp = TRUE; } } break; case IIO_PSTACK1: if (IioGlobalData->SetupData.ConfigIOU[IioIndex][1] == IIO_BIFURCATE_x4x4x4x4) { SlotImp = TRUE; } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][1] == IIO_BIFURCATE_x4x4xxx8) { if ((PortIndex == PORT_2D_INDEX) || (PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][1] == IIO_BIFURCATE_xxx8x4x4){ if ((PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2B_INDEX) || (PortIndex == PORT_2A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][1] == IIO_BIFURCATE_xxx8xxx8) { if ((PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][1] == IIO_BIFURCATE_xxxxxx16) { if (PortIndex == PORT_2A_INDEX) { SlotImp = TRUE; } } break; case IIO_PSTACK2: if (IioGlobalData->SetupData.ConfigIOU[IioIndex][2] == IIO_BIFURCATE_x4x4x4x4){ SlotImp = TRUE; } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][2] == IIO_BIFURCATE_x4x4xxx8) { if ((PortIndex == PORT_3D_INDEX) || (PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][2] == IIO_BIFURCATE_xxx8x4x4) { if ((PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3B_INDEX) || (PortIndex == PORT_3A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][2] == IIO_BIFURCATE_xxx8xxx8) { if ((PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3A_INDEX)){ SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][2] == IIO_BIFURCATE_xxxxxx16) { if (PortIndex == PORT_3A_INDEX) { SlotImp = TRUE; } } break; case IIO_PSTACK3: if (IioGlobalData->SetupData.ConfigIOU[IioIndex][3] == IIO_BIFURCATE_x4x4x4x4){ SlotImp = TRUE; } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][3] == IIO_BIFURCATE_x4x4xxx8) { if ((PortIndex == PORT_4D_INDEX) || (PortIndex == PORT_4C_INDEX) || (PortIndex == PORT_4A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][3] == IIO_BIFURCATE_xxx8x4x4) { if ((PortIndex == PORT_4C_INDEX) || (PortIndex == PORT_4B_INDEX) || (PortIndex == PORT_4A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][3] == IIO_BIFURCATE_xxx8xxx8) { if ((PortIndex == PORT_4C_INDEX) || (PortIndex == PORT_4A_INDEX)){ SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][3] == IIO_BIFURCATE_xxxxxx16) { if (PortIndex == PORT_4A_INDEX) { SlotImp = TRUE; } } break; case IIO_PSTACK4: if (IioGlobalData->SetupData.ConfigIOU[IioIndex][4] == IIO_BIFURCATE_x4x4x4x4){ SlotImp = TRUE; } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][4] == IIO_BIFURCATE_x4x4xxx8) { if ((PortIndex == PORT_5D_INDEX) || (PortIndex == PORT_5C_INDEX) || (PortIndex == PORT_5A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][4] == IIO_BIFURCATE_xxx8x4x4) { if ((PortIndex == PORT_5C_INDEX) || (PortIndex == PORT_5B_INDEX) || (PortIndex == PORT_5A_INDEX)) { SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][4] == IIO_BIFURCATE_xxx8xxx8) { if ((PortIndex == PORT_5C_INDEX) || (PortIndex == PORT_5A_INDEX)){ SlotImp = TRUE; } } else if (IioGlobalData->SetupData.ConfigIOU[IioIndex][4] == IIO_BIFURCATE_xxxxxx16) { if (PortIndex == PORT_5A_INDEX) { SlotImp = TRUE; } } break; default: DEBUG ((EFI_D_INFO, "default case.\n")); //Auto added. Please review. break; } DEBUG ((DEBUG_INFO, "SlotImplemented_SKX: = %x\n", SlotImp)); return SlotImp; } VOID ConfigSlots_SKX ( IN OUT IIO_GLOBALS *IioGlobalData, IN IIO_SLOT_CONFIG_DATA_ENTRY *Slot, IN UINT8 SlotEntries ) { UINT8 Index; UINT8 Port; for (Index =0; Index < SlotEntries; Index ++) { Port=Slot[Index].PortIndex; if (Slot[Index].Hidden != NOT_HIDE) { IioGlobalData->SetupData.HidePEXPMenu[Port] = HIDE; IioGlobalData->SetupData.PEXPHIDE[Port]= HIDE; } /// Check if slot is assigned. if (Slot[Index].SlotNumber!= NO_SLT_IMP){ IioGlobalData->SetupData.SLOTIMP[Port]= SLT_IMP; IioGlobalData->SetupData.SLOTPSP[Port]=Slot[Index].SlotNumber; IioGlobalData->SetupData.SLOTEIP[Port]=Slot[Index].InterLockPresent; if (Slot[Index].SlotPowerLimitScale!= PWR_SCL_MAX) { IioGlobalData->SetupData.SLOTSPLS[Port] = Slot[Index].SlotPowerLimitScale; IioGlobalData->SetupData.SLOTSPLV[Port] = Slot[Index].SlotPowerLimitValue; } if (Slot[Index].HotPlugCapable != DISABLE) { EnableHotPlug_SKX(IioGlobalData, Port, Slot[Index].VppPort, Slot[Index].VppAddress, REGULAR_PCIE_OWNERSHIP); } } } } EFI_STATUS PlatformUpdateIioConfig ( IN IIO_GLOBALS *IioGlobalData ) { EFI_STATUS Status; UBA_CONFIG_DATABASE_PPI *UbaConfigPpi = NULL; PLATFORM_IIO_CONFIG_UPDATE_TABLE IioConfigTable; UINTN TableSize; Status = PeiServicesLocatePpi ( &gUbaConfigDatabasePpiGuid, 0, NULL, &UbaConfigPpi ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } TableSize = sizeof(IioConfigTable); Status = UbaConfigPpi->GetData ( UbaConfigPpi, &gPlatformIioConfigDataGuid, &IioConfigTable, &TableSize ); if (EFI_ERROR(Status)) { return Status; } ASSERT (IioConfigTable.Signature == PLATFORM_IIO_CONFIG_UPDATE_SIGNATURE); ASSERT (IioConfigTable.Version == PLATFORM_IIO_CONFIG_UPDATE_VERSION); Status = IioConfigTable.CallUpdate (IioGlobalData); if (EFI_ERROR(Status)) { return Status; } return Status; } VOID OverrideDefaultBifSlots_SKX ( IN IIO_GLOBALS *IioGlobalData, IN UINT8 BoardId, IN BOOLEAN *AutoBifEnable ) { EFI_STATUS Status; UINT32 QATGpio; PCIE_RISER_ID RightRiser; PCIE_RISER_ID LeftRiser; UINT32 RiserBit; UINT8 Index; BW5_BIFURCATION_DATA_STRUCT Bw5id[4]= {{{0,0,0,0,0}}, {{0,0,0,0,0,}}, {{0,0,0,0,0}}, {{0,0,0,0,0}}}; // Default, no BW card. IIO_BROADWAY_ADDRESS_ENTRY *BroadwayTable; IIO_BROADWAY_ADDRESS_DATA_ENTRY *BroadwayTableTemp; UINT8 IOU0Setting; UINT8 IOU2Setting; UINT8 FlagValue = 0; UINT8 SkuPersonality = 0; DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi = NULL; BroadwayTable = NULL; IOU0Setting = IioGlobalData->SetupData.ConfigIOU[Iio_Socket0][0]; IOU2Setting = IioGlobalData->SetupData.ConfigIOU[Iio_Socket0][2]; // // Specific platform overrides. // // Changes because GPIO (QAT, Riser Cards, etc). // Read QAT and riser card GPIOs. // // Purley platforms need to read the QAT bit // Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return; } Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_B3, &QATGpio); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_B3 Failed\n")); return; } DEBUG ((EFI_D_INFO, "QAT GPIO: %d\n", QATGpio)); if ((IioGlobalData->IioVar.IioVData.SkuPersonality[0] == TYPE_FPGA) &&\ (IioGlobalData->IioVar.IioVData.SkuPersonality[1] == TYPE_FPGA)) { SkuPersonality = 1; } else if ((IioGlobalData->IioVar.IioVData.SkuPersonality[0] == TYPE_FPGA) &&\ (IioGlobalData->IioVar.IioVData.SkuPersonality[1] != TYPE_FPGA)) { SkuPersonality = 2; } else if ((IioGlobalData->IioVar.IioVData.SkuPersonality[0] != TYPE_FPGA) &&\ (IioGlobalData->IioVar.IioVData.SkuPersonality[1] == TYPE_FPGA)) { SkuPersonality = 3; } else { SkuPersonality = 0; } DEBUG((DEBUG_INFO, "SKU Personality Type: %d\n", SkuPersonality)); BroadwayTableTemp = (IIO_BROADWAY_ADDRESS_DATA_ENTRY *) BroadwayTable; InternalPlatformGetSlotTableData2 (&BroadwayTableTemp, &IOU0Setting, &FlagValue, &IOU2Setting, SkuPersonality); BroadwayTable = (IIO_BROADWAY_ADDRESS_ENTRY *)BroadwayTableTemp; // if no platform definition, BroadwayTable will be NULL if (AutoBifEnable[(Iio_Socket0 * Iio_IouMax) + Iio_Iou2] == TRUE) { IioGlobalData->SetupData.ConfigIOU[Iio_Socket0][2] = IOU2Setting; } if (FlagValue == 1) { // // Right riser // Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_B4, &RiserBit); // PresentSignal if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_B4 Failed\n")); return; } RightRiser.Bits.PresentSignal = (UINT8) RiserBit; Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_C15, &RiserBit); // HotPlugConf if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_C15 Failed\n")); return; } RightRiser.Bits.HPConf = (UINT8) RiserBit; Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_C16, &RiserBit); // WingConf if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_C16 Failed\n")); return; } RightRiser.Bits.WingConf = (UINT8) RiserBit; Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_C17, &RiserBit); // Slot9En if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_C17 Failed\n")); return; } RightRiser.Bits.Slot9En = (UINT8) RiserBit; DEBUG ((EFI_D_INFO, "GPIO Right riser information: PresentSignal=%x, HotPlugConf=%x, WingConf=%x, Slot9En=%x\n", RightRiser.Bits.PresentSignal, RightRiser.Bits.HPConf, RightRiser.Bits.WingConf, RightRiser.Bits.Slot9En)); // // Left riser // Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_B5, &RiserBit); // PresentSignal if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_B5 Failed\n")); return; } LeftRiser.Bits.PresentSignal = (UINT8) RiserBit; Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_C18, &RiserBit); // HotPlugConf if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_C18 Failed\n")); return; } LeftRiser.Bits.HPConf = (UINT8) RiserBit; Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_C19, &RiserBit); // WingConf if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_C19 Failed\n")); return; } LeftRiser.Bits.WingConf = (UINT8) RiserBit; Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_B21, &RiserBit); // Slot9En if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Get GPIO_SKL_H_GPP_B21 Failed\n")); return; } LeftRiser.Bits.Slot9En = (UINT8) RiserBit; DEBUG ((EFI_D_INFO, "GPIO Left riser information: PresentSignal=%x, HotPlugConf=%x, WingConf=%x, Slot9En=%x\n", LeftRiser.Bits.PresentSignal, LeftRiser.Bits.HPConf, LeftRiser.Bits.WingConf, LeftRiser.Bits.Slot9En)); } if (QATGpio == QAT_ENABLED) { // So Configuration of IUO0 is: // 1A-1B - QAT xxx8 // 1C - SSD x4 // 1D - SSD x4 if (AutoBifEnable[(Iio_Socket0 * Iio_IouMax) + Iio_Iou0] == TRUE) { IioGlobalData->SetupData.ConfigIOU[Iio_Socket0][0] = IOU0Setting; } } if (FlagValue == 1) { if (QATGpio != QAT_ENABLED) { if ((RightRiser.Bits.Slot9En == RISER_SLOT9_DISABLE) && (LeftRiser.Bits.Slot9En == RISER_SLOT9_DISABLE)) { // // SLOT 9 is disabled. SSDs are present. // Change configuration to x4x4x4x4. // if (AutoBifEnable[(Iio_Socket0 * Iio_IouMax) + Iio_Iou0] == TRUE) { IioGlobalData->SetupData.ConfigIOU[Iio_Socket0][0] = IIO_BIFURCATE_x4x4x4x4; IioGlobalData->IioVar.IioOutData.PciePortOwnership[SOCKET_0_INDEX + PORT_1A_INDEX] = PCIEAIC_OCL_OWNERSHIP; IioGlobalData->IioVar.IioOutData.PciePortOwnership[SOCKET_0_INDEX + PORT_1B_INDEX] = PCIEAIC_OCL_OWNERSHIP; IioGlobalData->IioVar.IioOutData.PciePortOwnership[SOCKET_0_INDEX + PORT_1C_INDEX] = PCIEAIC_OCL_OWNERSHIP; IioGlobalData->IioVar.IioOutData.PciePortOwnership[SOCKET_0_INDEX + PORT_1D_INDEX] = PCIEAIC_OCL_OWNERSHIP; } } else if (RightRiser.Bits.PresentSignal == RISER_PRESENT) { // // Slot 9 is enabled. Keep the xxxxxx16 configuration (default) and // enable slot 9. Slot 9 supports HP. // IioGlobalData->SetupData.SLOTIMP[SOCKET_0_INDEX + PORT_1A_INDEX] = 1; IioGlobalData->SetupData.SLOTPSP[SOCKET_0_INDEX + PORT_1A_INDEX] = 9; } // End of RISER_PRESENT } // End of QAT_ENABLED if (RightRiser.Bits.PresentSignal == RISER_PRESENT) { IioGlobalData->SetupData.SLOTIMP[SOCKET_0_INDEX + PORT_3A_INDEX] = 1; #if MAX_SOCKET > 2 IioGlobalData->SetupData.SLOTIMP[SOCKET_3_INDEX + PORT_2A_INDEX] = 1; IioGlobalData->SetupData.SLOTIMP[SOCKET_3_INDEX + PORT_3A_INDEX] = 1; #endif // MAX_SOCKET > 2 if (RightRiser.Bits.WingConf == RISER_WINGED_IN) { IioGlobalData->SetupData.SLOTPSP[SOCKET_0_INDEX + PORT_3A_INDEX] = 1; #if MAX_SOCKET > 2 IioGlobalData->SetupData.SLOTPSP[SOCKET_3_INDEX + PORT_2A_INDEX] = 4; IioGlobalData->SetupData.SLOTPSP[SOCKET_3_INDEX + PORT_3A_INDEX] = 2; #endif // MAX_SOCKET > 2 } else { // RISER_WINGED_OUT IioGlobalData->SetupData.SLOTPSP[SOCKET_0_INDEX + PORT_3A_INDEX] = 2; #if MAX_SOCKET > 2 IioGlobalData->SetupData.SLOTPSP[SOCKET_3_INDEX + PORT_2A_INDEX] = 3; IioGlobalData->SetupData.SLOTPSP[SOCKET_3_INDEX + PORT_3A_INDEX] = 1; #endif // MAX_SOCKET > 2 if (RightRiser.Bits.HPConf == RISER_HP_EN) { // // PCIe Hot Plug is supported on Winged-out riser only // EnableHotPlug_SKX(IioGlobalData, SOCKET_0_INDEX + PORT_3A_INDEX, VPP_PORT_0, 0x40, REGULAR_PCIE_OWNERSHIP); #if MAX_SOCKET > 2 EnableHotPlug_SKX(IioGlobalData, SOCKET_3_INDEX + PORT_2A_INDEX, VPP_PORT_1, 0x40, REGULAR_PCIE_OWNERSHIP); EnableHotPlug_SKX(IioGlobalData, SOCKET_3_INDEX + PORT_3A_INDEX, VPP_PORT_0, 0x40, REGULAR_PCIE_OWNERSHIP); #endif // MAX_SOCKET > 2 } // End of RISER_HP_EN } // End of RISER_WINGED_IN } // End of RISER_PRESENT if (LeftRiser.Bits.PresentSignal == RISER_PRESENT) { IioGlobalData->SetupData.SLOTIMP[SOCKET_1_INDEX + PORT_1A_INDEX] = 1; IioGlobalData->SetupData.SLOTIMP[SOCKET_1_INDEX + PORT_2A_INDEX] = 1; IioGlobalData->SetupData.SLOTIMP[SOCKET_2_INDEX + PORT_1A_INDEX] = 1; IioGlobalData->SetupData.SLOTIMP[SOCKET_2_INDEX + PORT_3A_INDEX] = 1; if (LeftRiser.Bits.WingConf == RISER_WINGED_IN) { IioGlobalData->SetupData.SLOTPSP[SOCKET_1_INDEX + PORT_1A_INDEX] = 7; IioGlobalData->SetupData.SLOTPSP[SOCKET_1_INDEX + PORT_2A_INDEX] = 5; IioGlobalData->SetupData.SLOTPSP[SOCKET_2_INDEX + PORT_1A_INDEX] = 6; IioGlobalData->SetupData.SLOTPSP[SOCKET_2_INDEX + PORT_3A_INDEX] = 8; } else { // RISER_WINGED_OUT IioGlobalData->SetupData.SLOTPSP[SOCKET_1_INDEX + PORT_1A_INDEX] = 5; IioGlobalData->SetupData.SLOTPSP[SOCKET_1_INDEX + PORT_2A_INDEX] = 7; IioGlobalData->SetupData.SLOTPSP[SOCKET_2_INDEX + PORT_1A_INDEX] = 8; IioGlobalData->SetupData.SLOTPSP[SOCKET_2_INDEX + PORT_3A_INDEX] = 6; if (LeftRiser.Bits.HPConf == RISER_HP_EN) { // // PCIe Hot Plug is supported on Winged-out riser only // EnableHotPlug_SKX(IioGlobalData, SOCKET_1_INDEX + PORT_1A_INDEX, VPP_PORT_0, 0x42, REGULAR_PCIE_OWNERSHIP); EnableHotPlug_SKX(IioGlobalData, SOCKET_1_INDEX + PORT_2A_INDEX, VPP_PORT_1, 0x42, REGULAR_PCIE_OWNERSHIP); EnableHotPlug_SKX(IioGlobalData, SOCKET_2_INDEX + PORT_1A_INDEX, VPP_PORT_1, 0x42, REGULAR_PCIE_OWNERSHIP); EnableHotPlug_SKX(IioGlobalData, SOCKET_2_INDEX + PORT_3A_INDEX, VPP_PORT_0, 0x42, REGULAR_PCIE_OWNERSHIP); } // End of RISER_HP_EN } // End of RISER_WINGED_IN } // End of RISER_PRESENT } // End of FlagValue == 1 /// Broadway overrides. if (BroadwayTable != NULL) { GetBw5Id (IioGlobalData, Bw5id); DEBUG ((EFI_D_INFO,"Broadway Config: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", Bw5id[Bw5_Addr_0].Data, Bw5id[Bw5_Addr_1].Data, Bw5id[Bw5_Addr_2].Data, Bw5id[Bw5_Addr_3].Data)); for (Index = 0; Index < 3; Index ++) { // // Check if BW5 is present before override IOUx Bifurcation // if (BroadwayTable->BroadwayAddress == Bw5_Addr_Max) { break; } if (Bw5id[BroadwayTable->BroadwayAddress].Bits.BifBits != BW5_CARD_NOT_PRESENT){ if (AutoBifEnable[(BroadwayTable->Socket * Iio_IouMax) + BroadwayTable->IouNumber] == TRUE) { switch (BroadwayTable->IouNumber) { case Iio_Iou0: IioGlobalData->SetupData.ConfigIOU[BroadwayTable->Socket][0] = Bw5id[BroadwayTable->BroadwayAddress].Bits.BifBits; DEBUG ((DEBUG_ERROR,"IioGlobalData->SetupData.ConfigIOU[%x][0] = %x\n",BroadwayTable->Socket, IioGlobalData->SetupData.ConfigIOU[BroadwayTable->Socket][0])); break; case Iio_Iou1: IioGlobalData->SetupData.ConfigIOU[BroadwayTable->Socket][1] = Bw5id[BroadwayTable->BroadwayAddress].Bits.BifBits; DEBUG ((DEBUG_ERROR,"IioGlobalData->SetupData.ConfigIOU[%x][1] = %x\n",BroadwayTable->Socket, IioGlobalData->SetupData.ConfigIOU[BroadwayTable->Socket][1])); break; case Iio_Iou2: IioGlobalData->SetupData.ConfigIOU[BroadwayTable->Socket][2] = Bw5id[BroadwayTable->BroadwayAddress].Bits.BifBits; DEBUG ((DEBUG_ERROR,"IioGlobalData->SetupData.ConfigIOU[%x][2] = %x\n",BroadwayTable->Socket,IioGlobalData->SetupData.ConfigIOU[BroadwayTable->Socket][2])); break; default: break; } // BroadwayTable->IouNumber } // AutoBifEnable == TRUE } // No BW5 present BroadwayTable ++; } // for Index } // BroadwayTable != NULL if (DynamicSiLibraryPpi->IsCpuAndRevision (CPU_SKX, REV_ALL) || DynamicSiLibraryPpi->IsCpuAndRevision (CPU_CLX, REV_ALL) || DynamicSiLibraryPpi->IsCpuAndRevision (CPU_CPX, REV_ALL) ) { PlatformUpdateIioConfig (IioGlobalData); } } /** Verify if VMD is enabled and override Slot configuration based on the VMD settings @param IioGlobalData Pointer to Iio Globals. @param Slot - Slot configuration settings @param SlotEntries - Number of slot entries @retval None **/ VOID OverrideConfigSlots_SKX ( IN OUT IIO_GLOBALS *IioGlobalData, IN IIO_SLOT_CONFIG_DATA_ENTRY *Slot, IN UINT8 SlotEntries ) { UINT8 Index; UINT8 Port; UINT8 MaxPortNumberPerSocket; UINT8 IioIndex; UINT8 Stack; UINT8 PortIndex; MaxPortNumberPerSocket = IioGlobalData->IioVar.IioOutData.MaxPciePortNumberPerSocket[0]; for (Index =0; Index < SlotEntries; Index ++) { Port = Slot[Index].PortIndex; // // Check if Slot is capable of PcieSSD Solution and override the SLOT Config values // if (Slot[Index].PcieSSDCapable) { IioIndex = Port/MaxPortNumberPerSocket; PortIndex = (Port - (MaxPortNumberPerSocket * IioIndex)); Stack = IioGlobalData->IioVar.IioVData.StackPerPort[IioIndex][PortIndex]; DEBUG ((DEBUG_INFO, "Stack = %x, Port = %x, PortIndex = %x\n", Stack, Port, PortIndex)); // // check if VMD will own Pcie Root Port // if (IioGlobalData->SetupData.VMDEnabled[IioIndex][Stack]) { if (IioGlobalData->SetupData.VMDPortEnable[IioIndex][PortIndex]) { IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] = VMD_OWNERSHIP; } } else { DEBUG ((DEBUG_INFO, "IioGlobalData->SetupData.PcieAICEnabled[%x] = %x\n", Stack, IioGlobalData->SetupData.PcieAICEnabled[(IioIndex * MAX_STACKS_PER_SOCKET) + Stack])); // // Check if Pcie AIC Card will be present on Pcie Root Port // if (IioGlobalData->SetupData.PcieAICEnabled[(IioIndex * MAX_STACKS_PER_SOCKET) + Stack]) { // // Force to have this port enabled by default for hot-plug. // IioGlobalData->SetupData.IioPcieConfig.PciePortEnable[(IioIndex * MaxPortNumberPerSocket) + Port] = ENABLE; IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] = PCIEAIC_OCL_OWNERSHIP; DEBUG ((DEBUG_ERROR, "Port = %x, PciePortEnable = %x\n", Port, IioGlobalData->SetupData.IioPcieConfig.PciePortEnable[(IioIndex * MaxPortNumberPerSocket) + Port])); } } // No _VMD Ownership DEBUG ((DEBUG_INFO, "PciePortOwnerShip[%x] = %x\n",Port, IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port])); // if PcieSSDSupport required do slot override settings accordingly if ((IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] != REGULAR_PCIE_OWNERSHIP) && (SlotImplemented_SKX(IioGlobalData, Port) == TRUE)) { IioGlobalData->SetupData.SLOTIMP[Port] = SLT_IMP; IioGlobalData->SetupData.SLOTPSP[Port] = 0x50 + Port; // Just program a value for PCIEACI_OCL/VMD IioGlobalData->SetupData.SLOTEIP[Port] = DISABLE; if (Slot[Index].SlotPowerLimitScale != PWR_SCL_MAX) { IioGlobalData->SetupData.SLOTSPLS[Port] = Slot[Index].SlotPowerLimitScale; IioGlobalData->SetupData.SLOTSPLV[Port] = Slot[Index].SlotPowerLimitValue; } DEBUG ((DEBUG_INFO,"Slot[Index].PcieSSDVppPort = %x\n", Slot[Index].PcieSSDVppPort)); // Enable hot-plug if slot/port supports it if (Slot[Index].PcieSSDVppPort != VPP_PORT_MAX) { DEBUG ((DEBUG_INFO, "IioGlobalData->SetupData.VMDHotPlugEnable[%d][%x] = %x\n", IioIndex, Stack, IioGlobalData->SetupData.VMDHotPlugEnable[IioIndex][Stack])); DEBUG ((DEBUG_INFO, "IioGlobalData->SetupData.PcieAICHotPlugEnable[%x] = %x\n",Stack,IioGlobalData->SetupData.PcieAICHotPlugEnable[(IioIndex * MAX_STACKS_PER_SOCKET) + Stack])); // Check if hot-plug is enabled for VMD or PCIeAIC case. if (((IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] == VMD_OWNERSHIP) && (IioGlobalData->SetupData.VMDHotPlugEnable[IioIndex][Stack])) || ((IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] == PCIEAIC_OCL_OWNERSHIP) && (IioGlobalData->SetupData.PcieAICHotPlugEnable[(IioIndex * MAX_STACKS_PER_SOCKET) + Stack]))) { EnableHotPlug_SKX(IioGlobalData, Port, Slot[Index].PcieSSDVppPort, Slot[Index].PcieSSDVppAddress, IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port]); DEBUG((DEBUG_INFO,"Enable HotPlug Done\n")); } } // // Unhide the port in order to get configured and it will be hide later for VMDLateSetup if MD own the Pcie Root Port // IioGlobalData->SetupData.PEXPHIDE[Port] = NOT_HIDE; }// PcieSSDSupport }// PcieSSDCapable }// Per Slot } VOID SetBifurcations_SKX( IN OUT IIO_GLOBALS *IioGlobalData, IN IIO_BIFURCATION_DATA_ENTRY *BifurcationTable, IN UINT8 BifurcationEntries, IN BOOLEAN *AutoBifEnable ) { UINT8 Socket; UINT8 Iou; UINT8 Index; for (Index = 0; Index < BifurcationEntries ; Index++) { Socket = BifurcationTable[Index].Socket; Iou = BifurcationTable[Index].IouNumber; if (AutoBifEnable[(Socket * Iio_IouMax) + Iou] == TRUE) { switch (Iou) { case Iio_Iou0: IioGlobalData->SetupData.ConfigIOU[Socket][0] = BifurcationTable[Index].Bifurcation; break; case Iio_Iou1: IioGlobalData->SetupData.ConfigIOU[Socket][1] = BifurcationTable[Index].Bifurcation; break; case Iio_Iou2: IioGlobalData->SetupData.ConfigIOU[Socket][2] = BifurcationTable[Index].Bifurcation; break; case Iio_Iou3: IioGlobalData->SetupData.ConfigIOU[Socket][3] = BifurcationTable[Index].Bifurcation; break; case Iio_Iou4: IioGlobalData->SetupData.ConfigIOU[Socket][4] = BifurcationTable[Index].Bifurcation; break; default: DEBUG ((EFI_D_ERROR, "Invalid bifurcation table: Bad Iou (%d)", Iou)); ASSERT(Iou); break; } } } } /** SystemIioPortBifurcationInit - Program the UDS data structure with OEM IIO init values for SLOTs and Bifurcation. @param mSB - pointer to this protocol @param IioUds - Pointer to the IIO UDS datastructure. @retval EFI_SUCCESS **/ VOID SystemIioPortBifurcationInitCommon_SKX ( UINT8 BoardId, IIO_GLOBALS *IioGlobalData, IIO_BIFURCATION_DATA_ENTRY **BifurcationTable, UINT8 *BifurcationEntries, IIO_SLOT_CONFIG_DATA_ENTRY **SlotTable, UINT8 *SlotEntries ) { UINT8 PortIndex;//, iio; IIO_BIFURCATION_DATA_ENTRY **BifurcationTableTemp; IIO_SLOT_CONFIG_DATA_ENTRY **SlotTableTemp; UINT8 SkuPersonalityType = 0; UINT8 MaxPortNumberPerSocket; /// This function outline: //// 1 Based on platform apply the default bifurcation and slot configuration. //// 2 Apply dynamic overrides based on GPIO and other configurations. //// 3 Hide unused ports due bifurcation. MaxPortNumberPerSocket = IioGlobalData->IioVar.IioOutData.MaxPciePortNumberPerSocket[0]; for (PortIndex = 0; PortIndex < MAX_SOCKET*MaxPortNumberPerSocket; PortIndex++) { IioGlobalData->SetupData.PEXPHIDE[PortIndex] = 0; IioGlobalData->SetupData.HidePEXPMenu[PortIndex] = 0; } *BifurcationEntries = 0; *SlotEntries = 0; BifurcationTableTemp = (IIO_BIFURCATION_DATA_ENTRY **) BifurcationTable; SlotTableTemp = (IIO_SLOT_CONFIG_DATA_ENTRY **) SlotTable; if ((IioGlobalData->IioVar.IioVData.SkuPersonality[0] == TYPE_FPGA) &&\ (IioGlobalData->IioVar.IioVData.SkuPersonality[1] == TYPE_FPGA)) { SkuPersonalityType = 1; } else if ((IioGlobalData->IioVar.IioVData.SkuPersonality[0] == TYPE_FPGA) &&\ (IioGlobalData->IioVar.IioVData.SkuPersonality[1] != TYPE_FPGA)) { SkuPersonalityType = 2; } else if ((IioGlobalData->IioVar.IioVData.SkuPersonality[0] != TYPE_FPGA) &&\ (IioGlobalData->IioVar.IioVData.SkuPersonality[1] == TYPE_FPGA)) { SkuPersonalityType = 3; } else { SkuPersonalityType = 0; } InternalPlatformIioConfigInit2 (SkuPersonalityType, BifurcationTableTemp, BifurcationEntries, SlotTableTemp, SlotEntries); BifurcationTable = (IIO_BIFURCATION_DATA_ENTRY **) BifurcationTableTemp; SlotTable = (IIO_SLOT_CONFIG_DATA_ENTRY **) SlotTableTemp; } /** This function prepare the data for silicon initialization based on bifuraction and slots table This function is for tables in version PLATFORM_IIO_CONFIG_UPDATE_VERSION = 1 */ VOID IioPortBifurcationInitVer1 ( IN IIO_GLOBALS *IioGlobalData ) { UINT8 IioIndex; IIO_BIFURCATION_DATA_ENTRY *BifurcationTable = NULL; UINT8 BifurcationEntries; IIO_SLOT_CONFIG_DATA_ENTRY *SlotTable = NULL; UINT8 SlotEntries; BOOLEAN AutoBifEnable[MaxIIO * Iio_IouMax]; UINT8 BoardId; BoardId = SystemBoardIdValue(); SetMem ((VOID *)AutoBifEnable, MaxIIO * Iio_IouMax, FALSE); for (IioIndex = Iio_Socket0; IioIndex < MaxIIO; IioIndex++) { if (IioGlobalData->SetupData.ConfigIOU[IioIndex][0] == IIO_BIFURCATE_AUTO) { AutoBifEnable[(IioIndex * Iio_IouMax) + Iio_Iou0] = TRUE; } if (IioGlobalData->SetupData.ConfigIOU[IioIndex][1] == IIO_BIFURCATE_AUTO) { AutoBifEnable[(IioIndex * Iio_IouMax) + Iio_Iou1] = TRUE; } if (IioGlobalData->SetupData.ConfigIOU[IioIndex][2] == IIO_BIFURCATE_AUTO) { AutoBifEnable[(IioIndex * Iio_IouMax) + Iio_Iou2] = TRUE; } if (IioGlobalData->SetupData.ConfigIOU[IioIndex][3] == IIO_BIFURCATE_AUTO) { AutoBifEnable[(IioIndex * Iio_IouMax) + Iio_Iou3] = TRUE; } if (IioGlobalData->SetupData.ConfigIOU[IioIndex][4] == IIO_BIFURCATE_AUTO) { AutoBifEnable[(IioIndex * Iio_IouMax) + Iio_Iou4] = TRUE; } } // This function outline: // 1. Based on platform apply the default bifurcation and slot configuration. // 2. Apply dynamic overrides based on GPIO and other configurations. // 3. Hide unused ports due bifurcation. // Set the default bifurcations for this platform. SystemIioPortBifurcationInitCommon_SKX (BoardId, IioGlobalData, &BifurcationTable, &BifurcationEntries, &SlotTable, &SlotEntries); SetBifurcations_SKX (IioGlobalData, BifurcationTable, BifurcationEntries, AutoBifEnable); ConfigSlots_SKX (IioGlobalData, SlotTable, SlotEntries); if (BoardId <= TypePlatformMax) { OverrideDefaultBifSlots_SKX (IioGlobalData, BoardId, AutoBifEnable); } OverrideConfigSlots_SKX (IioGlobalData, SlotTable, SlotEntries); // All overrides have been applied now. // Hide root ports whose lanes are assigned preceding ports. for (IioIndex = Iio_Socket0; IioIndex < MaxIIO; IioIndex++) { if (IioGlobalData->IioVar.IioVData.SocketPresent[IioIndex]) { SystemHideIioPortsCommon_SKX (IioGlobalData, IioIndex); } } }