summaryrefslogtreecommitdiff
path: root/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c
diff options
context:
space:
mode:
Diffstat (limited to 'Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c')
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c631
1 files changed, 631 insertions, 0 deletions
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c
new file mode 100644
index 0000000000..6f28e1e7d4
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c
@@ -0,0 +1,631 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Platform.h>
+#include <Register/PchRegsUsb.h>
+#include <PchLimits.h>
+#include <PchPolicyCommon.h>
+#include <IioBifurcationSlotTable.h>
+
+VOID
+SetBifurcations(
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_BIFURCATION_ENTRY *BifurcationTable,
+ IN UINT8 BifurcationEntries
+)
+{
+ UINT8 Socket;
+ UINT8 Iou;
+ UINT8 Index;
+
+ for (Index = 0; Index < BifurcationEntries ; Index++) {
+ Socket = BifurcationTable[Index].Socket;
+ Iou = BifurcationTable[Index].IouNumber;
+ switch (Iou) {
+ case Iio_Iou0:
+ if (IioGlobalData->SetupData.ConfigIOU0[Socket]==IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigIOU0[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ case Iio_Iou1:
+ if (IioGlobalData->SetupData.ConfigIOU1[Socket] == IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigIOU1[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ case Iio_Iou2:
+ if (IioGlobalData->SetupData.ConfigIOU2[Socket]==IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigIOU2[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ case Iio_Mcp0:
+ if (IioGlobalData->SetupData.ConfigMCP0[Socket] == IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigMCP0[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ case Iio_Mcp1:
+ if (IioGlobalData->SetupData.ConfigMCP1[Socket] == IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigMCP1[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ default:
+ DEBUG((EFI_D_ERROR, "Invalid bifurcation table: Bad Iou (%d)", Iou));
+ ASSERT(Iou);
+ break;
+ }
+ }
+}
+
+VOID
+EnableHotPlug (
+ 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.VppEnable[Port]= ENABLE;
+ 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"));
+ }
+}
+
+VOID
+ConfigSlots (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_SLOT_CONFIG_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(IioGlobalData, Port, Slot[Index].VppPort, Slot[Index].VppAddress, REGULAR_PCIE_OWNERSHIP);
+ }
+ }
+ }
+}
+
+/**
+ 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 shoudl be implemented or not
+ based on the IOUX bifurcation settings in case user want to do an
+ override and VMD is enabled.
+
+**/
+BOOLEAN
+SlotImplemented(
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN UINT8 Port
+ ){
+ UINT8 IioIndex;
+ UINT8 PortIndex;
+ UINT8 Stack;
+ BOOLEAN SlotImp = FALSE;
+
+ IioIndex = Port/NUMBER_PORTS_PER_SOCKET;
+ PortIndex = (Port - (NUMBER_PORTS_PER_SOCKET * IioIndex));
+ // Stack = (((PortIndex + 3)/4) - 1) + (IioIndex*VMD_STACK_PER_SOCKET);
+ Stack = IioGlobalData->IioVar.IioVData.StackPerPort[IioIndex][PortIndex];
+ DEBUG((DEBUG_INFO, "SlotImplemented:IioIndex = %x, Stack = %x, Port = %x, PortIndex =%x\n", IioIndex, Stack, Port, PortIndex));
+
+ switch(Stack){
+ case IIO_PSTACK0:
+ if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_x4x4x4x4){
+ SlotImp = TRUE;
+ } else if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_x4x4xxx8){
+ if ((PortIndex == PORT_1D_INDEX) || (PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_xxx8x4x4){
+ if ((PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1B_INDEX) || (PortIndex == PORT_1A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_xxx8xxx8){
+ if ((PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_xxxxxx16){
+ if (PortIndex == PORT_1A_INDEX){
+ SlotImp = TRUE;
+ }
+ }
+ break;
+ case IIO_PSTACK1:
+ if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_x4x4x4x4){
+ SlotImp = TRUE;
+ } else if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_x4x4xxx8){
+ if ((PortIndex == PORT_2D_INDEX) || (PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_xxx8x4x4){
+ if ((PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2B_INDEX) || (PortIndex == PORT_2A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_xxx8xxx8){
+ if ((PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_xxxxxx16){
+ if (PortIndex == PORT_2A_INDEX){
+ SlotImp = TRUE;
+ }
+ }
+ break;
+ case IIO_PSTACK2:
+ if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_x4x4x4x4){
+ SlotImp = TRUE;
+ } else if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_x4x4xxx8){
+ if ((PortIndex == PORT_3D_INDEX) || (PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_xxx8x4x4){
+ if ((PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3B_INDEX) || (PortIndex == PORT_3A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_xxx8xxx8){
+ if ((PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_xxxxxx16){
+ if (PortIndex == PORT_3A_INDEX){
+ SlotImp = TRUE;
+ }
+ }
+ break;
+ }
+ DEBUG((DEBUG_INFO, "SlotImplemented: = %x\n", SlotImp));
+ return SlotImp;
+}
+
+/**
+ Verify if VMD is enabled and override Slot conofgiration
+ based on the VMD settings
+
+ @param IioGlobalData Pointer to Iio Globals.
+ @param Slot - Slot configuarion settings
+ @param SlotEntries - Number of slot entries
+
+ @retval None
+
+**/
+VOID
+OverrideConfigSlots (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_SLOT_CONFIG_ENTRY *Slot,
+ IN UINT8 SlotEntries
+ )
+{
+ UINT8 Index;
+ UINT8 Port;
+ UINT8 IioIndex;
+ UINT8 VmdPort;
+ UINT8 Stack;
+
+ 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/NUMBER_PORTS_PER_SOCKET;
+ Stack = ((((Port - (NUMBER_PORTS_PER_SOCKET * IioIndex))+ 3)/4) - 1) + (IioIndex*VMD_STACK_PER_SOCKET);
+ DEBUG((DEBUG_INFO, "Stack = %x, Port = %x\n", Stack, Port));
+
+ //
+ // check if VMD will own Pcie Root Port
+ //
+ if(IioGlobalData->SetupData.VMDEnabled[Stack]){
+ VmdPort = ((IioIndex * VMD_PORTS_PER_SOCKET) + (Port - (NUMBER_PORTS_PER_SOCKET * IioIndex))) - 1;
+ if (IioGlobalData->SetupData.VMDPortEnable[VmdPort]){
+ IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] = VMD_OWNERSHIP;
+ }
+ } else {
+
+ DEBUG((DEBUG_INFO, "IioGlobalData->SetupData.PcieAICEnabled[%x] = %x\n",Stack, IioGlobalData->SetupData.PcieAICEnabled[Stack]));
+ //
+ // Check if Pcie AIC Card will be present on Pcie Root Port
+ //
+ if(IioGlobalData->SetupData.PcieAICEnabled[Stack]){
+ //
+ // Force to have this port enabled by default for hot-plug.
+ //
+ IioGlobalData->SetupData.PciePortDisable[(IioIndex * NUMBER_PORTS_PER_SOCKET) + Port] = ENABLE;
+ IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] = PCIEAIC_OCL_OWNERSHIP;
+ DEBUG((DEBUG_ERROR, "Port = %x, PciePortDisable = %x\n",Port,IioGlobalData->SetupData.PciePortDisable[(IioIndex * NUMBER_PORTS_PER_SOCKET) + 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(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[%x] = %x\n",Stack,IioGlobalData->SetupData.VMDHotPlugEnable[Stack]));
+ DEBUG((DEBUG_INFO, "IioGlobalData->SetupData.PcieAICHotPlugEnable[%x] = %x\n",Stack,IioGlobalData->SetupData.PcieAICHotPlugEnable[Stack]));
+ // Check if hot-plug is enabled for VMD or PCIeAIC case.
+ if (((IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] == VMD_OWNERSHIP) && (IioGlobalData->SetupData.VMDHotPlugEnable[Stack])) ||
+ ((IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] == PCIEAIC_OCL_OWNERSHIP) && (IioGlobalData->SetupData.PcieAICHotPlugEnable[Stack]))) {
+ EnableHotPlug(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 VMD own the Pcie Root Port
+ //
+ IioGlobalData->SetupData.PEXPHIDE[Port]= NOT_HIDE;
+ }// PcieSSDSupport
+ }// PcieSSDCapable
+ }// Per Slot
+}
+
+
+/**
+ 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.
+
+ @retval None
+
+**/
+VOID
+CalculatePEXPHideFromIouBif (
+ IN UINT8 Iou,
+ IN UINT8 IioIndex,
+ IN OUT IIO_GLOBALS *IioGlobalData
+)
+{
+
+ UINT8 *PXPHide, *HidePEXPMenu;
+ UINT8 CurrentIOUConfigValue;
+ UINT8 PXPOffset;
+ PXPHide = IioGlobalData->SetupData.PEXPHIDE;
+ HidePEXPMenu = IioGlobalData->SetupData.HidePEXPMenu;
+ CurrentIOUConfigValue =0;
+
+ PXPOffset=IioIndex * NUMBER_PORTS_PER_SOCKET;
+
+ switch (Iou) {
+ case Iio_Iou0:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigIOU0[IioIndex];
+ PXPOffset+= PORT_1A_INDEX;
+ break;
+ case Iio_Iou1:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigIOU1[IioIndex];
+ PXPOffset+= PORT_2A_INDEX;
+ break;
+ case Iio_Iou2:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigIOU2[IioIndex];
+ PXPOffset+= PORT_3A_INDEX;
+ break;
+ case Iio_Mcp0:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigMCP0[IioIndex];
+ PXPOffset+= PORT_4A_INDEX;
+ break;
+ case Iio_Mcp1:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigMCP1[IioIndex];
+ PXPOffset += PORT_5A_INDEX;
+ 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 ConfigIOUx/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) {
+ switch (Iou) {
+ case Iio_Iou0:
+ IioGlobalData->SetupData.ConfigIOU0[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ case Iio_Iou1:
+ IioGlobalData->SetupData.ConfigIOU1[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ case Iio_Iou2:
+ IioGlobalData->SetupData.ConfigIOU2[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ case Iio_Mcp0:
+ IioGlobalData->SetupData.ConfigMCP0[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ case Iio_Mcp1:
+ IioGlobalData->SetupData.ConfigMCP1[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+VOID
+DumpPort(
+ 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(
+ IN UINT8 iio,
+ IN IIO_GLOBALS *IioGlobalData
+)
+{
+ UINT8 Iou;
+ UINT8 PortIndex;
+ UINT8 Bifurcation;
+ UINT8 IouPorts;
+ PortIndex = iio * NUMBER_PORTS_PER_SOCKET;
+ /// 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(IioGlobalData, PortIndex, 1);
+ }
+ IouPorts=4;
+ /// Dump IOU bifurcations:
+ for (Iou = Iio_Iou0; Iou< Iio_IouMax; Iou ++) {
+ /// Reset port index.
+ PortIndex = iio * NUMBER_PORTS_PER_SOCKET;
+ // Get the bifurcation
+ switch (Iou) {
+ case Iio_Iou0:
+ Bifurcation = IioGlobalData->SetupData.ConfigIOU0[iio];
+ PortIndex += PORT_1A_INDEX;
+ DEBUG((EFI_D_INFO, "IUO0: Root Port 1, Bifurcation: %d\n", Bifurcation));
+ break;
+ case Iio_Iou1:
+ Bifurcation = IioGlobalData->SetupData.ConfigIOU1[iio];
+ PortIndex += PORT_2A_INDEX;
+ DEBUG((EFI_D_INFO, "IUO1: Root Port 2, Bifurcation: %d\n", Bifurcation));
+ break;
+ case Iio_Iou2:
+ Bifurcation = IioGlobalData->SetupData.ConfigIOU2[iio];
+ PortIndex += PORT_3A_INDEX;
+ DEBUG((EFI_D_INFO, "IUO2: Root Port 3, Bifurcation: %d\n", Bifurcation));
+ break;
+ case Iio_Mcp0:
+ Bifurcation = IioGlobalData->SetupData.ConfigMCP0[iio];
+ PortIndex += PORT_4A_INDEX;
+ DEBUG((EFI_D_INFO, "MCP0, Bifurcation: %d\n", Bifurcation));
+ break;
+ case Iio_Mcp1:
+ Bifurcation = IioGlobalData->SetupData.ConfigMCP1[iio];
+ PortIndex += PORT_5A_INDEX;
+ DEBUG((EFI_D_INFO, "MCP1, Bifurcation: %d\n", Bifurcation));
+ break;
+ default:
+ DEBUG((EFI_D_INFO, "Iou no detected = %d",Iou));
+ break;
+ }
+ DumpPort(IioGlobalData, PortIndex, IouPorts);
+ }
+
+}
+
+UINT8
+GetUplinkPortInformationCommon (
+ IN UINT8 IioIndex
+)
+{
+ UINT8 UplinkPortIndex = 0xFF;
+
+ if (IioIndex == 0) {
+ UplinkPortIndex = PcdGet8(PcdOemSkuUplinkPortIndex);
+ }
+
+ return UplinkPortIndex;
+}
+/**
+
+ 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 (
+ IIO_GLOBALS *IioGlobalData,
+ IIO_BIFURCATION_ENTRY **BifurcationTable,
+ UINT8 *BifurcationEntries,
+ IIO_SLOT_CONFIG_ENTRY **SlotTable,
+ UINT8 *SlotEntries
+)
+{
+
+ UINT8 PortIndex;//, iio;
+
+ /// 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.
+
+ for (PortIndex = 0; PortIndex < MAX_SOCKET*NUMBER_PORTS_PER_SOCKET; PortIndex++) {
+ IioGlobalData->SetupData.PEXPHIDE[PortIndex] = 0;
+ IioGlobalData->SetupData.HidePEXPMenu[PortIndex] = 0;
+ }
+
+ *BifurcationEntries = 0;
+ *SlotEntries = 0;
+
+ *BifurcationTable = (IIO_BIFURCATION_ENTRY *)(UINTN)PcdGet64 (PcdIioBifurcationTable);
+ *BifurcationEntries = PcdGet8 (PcdIioBifurcationTableEntries);
+ *SlotTable = (IIO_SLOT_CONFIG_ENTRY *)(UINTN)PcdGet64 (PcdIioSlotTable);
+ *SlotEntries = PcdGet8 (PcdIioSlotTableEntries);
+}
+
+VOID
+SystemHideIioPortsCommon(
+ IIO_GLOBALS *IioGlobalData,
+ UINT8 IioIndex
+)
+{
+ CalculatePEXPHideFromIouBif(Iio_Iou0, IioIndex, IioGlobalData);
+ CalculatePEXPHideFromIouBif(Iio_Iou1, IioIndex, IioGlobalData);
+ CalculatePEXPHideFromIouBif(Iio_Iou2, IioIndex, IioGlobalData);
+ CalculatePEXPHideFromIouBif(Iio_Mcp0, IioIndex, IioGlobalData);
+ CalculatePEXPHideFromIouBif(Iio_Mcp1, IioIndex, IioGlobalData);
+ DumpIioConfiguration(IioIndex, IioGlobalData);
+}