/** @file ;****************************************************************************** ;* Copyright 2021 Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corp. ;* ;****************************************************************************** */ /** @file Do Platform Stage TBT initialization. @copyright INTEL CONFIDENTIAL Copyright 2017 - 2021 Intel Corporation. The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material may contain trade secrets and proprietary and confidential information of Intel Corporation and its suppliers and licensors, and is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel's prior express written permission. No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing. Unless otherwise agreed by Intel in writing, you may not remove or alter this notice or any other notice embedded in Materials by Intel or Intel's suppliers or licensors in any way. This file contains a 'Sample Driver' and is licensed as such under the terms of your license agreement with Intel or your vendor. This file may be modified by the user, subject to the additional terms of the license agreement. @par Specification Reference: **/ #include "PeiTbtPolicyUpdate.h" #include #include #include #include #include #include #if FixedPcdGetBool (PcdDTbtEnable) == 1 #include #endif #include #include #include #include #include #if FixedPcdGetBool (PcdDTbtEnable) == 1 #include #endif #include #include #if FixedPcdGetBool (PcdITbtEnable) == 1 #include #include #endif #if FixedPcdGet8 (PcdFspModeSelection) == 1 #include #endif //[-start-210527-IB16740141-add]// #include #include //[-end-210527-IB16740141-add]// /** UpdatePeiTbtPolicy performs TBT PEI Policy initialization @retval EFI_SUCCESS The policy is installed and initialized. **/ EFI_STATUS EFIAPI UpdatePeiTbtPolicy ( VOID ) { EFI_STATUS Status; UINTN VarSize; SETUP_DATA SystemConfiguration; #if ( FixedPcdGetBool(PcdITbtEnable) == 1 ) || ( FixedPcdGetBool (PcdDTbtEnable) == 1 ) UINT8 Index; #endif EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices; UINT8 Usb4CmMode; UINT8 OsCmMode; UINT8 InitSetupFlag; #if FixedPcdGetBool (PcdITbtEnable) == 1 TCSS_DATA_HOB *TcssHob; SA_SETUP SaSetup; #endif #if FixedPcdGet8 (PcdFspModeSelection) == 1 VOID *FspsUpd; #else SI_POLICY_PPI *SiPolicy; #if FixedPcdGetBool (PcdITbtEnable) == 1 PEI_ITBT_CONFIG *PeiITbtConfig; #endif #endif #if FixedPcdGetBool (PcdDTbtEnable) == 1 PEI_DTBT_POLICY *PeiDTbtConfig; #endif DEBUG ((DEBUG_INFO, "Update PeiTbtPolicyUpdate Pos-Mem Start\n")); #if FixedPcdGetBool (PcdITbtEnable) == 1 TcssHob = NULL; #endif #if FixedPcdGet8 (PcdFspModeSelection) == 1 FspsUpd = NULL; #else SiPolicy = NULL; Status = EFI_NOT_FOUND; #endif #if FixedPcdGetBool (PcdDTbtEnable) == 1 PeiDTbtConfig = NULL; #endif #if FixedPcdGet8 (PcdFspModeSelection) == 1 FspsUpd = (FSPS_UPD *) PcdGet32 (PcdFspsUpdDataAddress); ASSERT (FspsUpd != NULL); #else // // Get requisite IP Config Blocks which needs to be used here // Status = PeiServicesLocatePpi (&gSiPolicyPpiGuid, 0, NULL, (VOID **) &SiPolicy); ASSERT_EFI_ERROR (Status); #if FixedPcdGetBool (PcdITbtEnable) == 1 PeiITbtConfig = NULL; Status = GetConfigBlock ((VOID *) SiPolicy, &gPeiITbtConfigGuid, (VOID *) &PeiITbtConfig); ASSERT_EFI_ERROR (Status); #endif #endif #if FixedPcdGetBool (PcdDTbtEnable) == 1 Status = PeiServicesLocatePpi ( &gPeiDTbtPolicyPpiGuid, 0, NULL, (VOID **) &PeiDTbtConfig ); #endif Status = PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices ); if (Status != EFI_SUCCESS) { return Status; } VarSize = sizeof (SETUP_DATA); Status = VariableServices->GetVariable ( VariableServices, L"Setup", &gSetupVariableGuid, NULL, &VarSize, &SystemConfiguration ); if (Status != EFI_SUCCESS) { return Status; } // // SETUP_OPTION_USB4_CM_MODE_FW : TBT FW should be set to Firmware CM mode. Connect Topology command should be sent. // SETUP_OPTION_USB4_CM_MODE_SW : TBT FW should be set to Pass Through mode and Software CM should be executed. // SETUP_OPTION_USB4_CM_MODE_OS : CM mode saved in platform settings should be applied. // SETUP_OPTION_USB4_CM_MODE_PASS_THROUGH : TBT FW should be set to Pass Through mode without Software CM execution. // switch (SystemConfiguration.Usb4CmMode) { case SETUP_OPTION_USB4_CM_MODE_FW: Usb4CmMode = USB4_CM_MODE_FW_CM; break; // // CMOS will only be used when the SystemConfiguration.Usb4CmMode is SETUP_OPTION_USB4_CM_MODE_OS // case SETUP_OPTION_USB4_CM_MODE_OS: VarSize = sizeof (InitSetupFlag); Status = VariableServices->GetVariable ( VariableServices, L"InitSetupVariable", &gSetupVariableGuid, NULL, &VarSize, &InitSetupFlag); if (Status == EFI_NOT_FOUND || (VarSize != sizeof (InitSetupFlag))) { DEBUG ((DEBUG_INFO, "First boot, Init SW CM CMOS\n")); //[-start-210527-IB16740141-modify]// // CmosWrite8 (CMOS_USB4_CM_MODE_REG, USB4_CM_MODE_SW_CM); WriteExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, CMOS_USB4_CM_MODE_REG_CHP, USB4_CM_MODE_SW_CM); //[-end-210527-IB16740141-modify]// } //[-start-210527-IB16740141-modify]// // OsCmMode = CmosRead8 (CMOS_USB4_CM_MODE_REG); OsCmMode = ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, CMOS_USB4_CM_MODE_REG_CHP); //[-end-210527-IB16740141-modify]// if ((OsCmMode != USB4_CM_MODE_SW_CM) && (OsCmMode != USB4_CM_MODE_FW_CM)) { DEBUG ((DEBUG_ERROR, "Unsupported OS CM mode 0x%X, default set to SW CM mode\n", OsCmMode)); Usb4CmMode = USB4_CM_MODE_SW_CM; } else { Usb4CmMode = OsCmMode; } break; case SETUP_OPTION_USB4_CM_MODE_SW: case SETUP_OPTION_USB4_CM_MODE_THROUGH: default: Usb4CmMode = USB4_CM_MODE_SW_CM; break; } DEBUG ((DEBUG_INFO, "Usb4CmMode setup option = 0x%0x\n", SystemConfiguration.Usb4CmMode)); DEBUG ((DEBUG_INFO, "USB4 CM mode is 0x%X\n", Usb4CmMode)); #if FixedPcdGetBool (PcdITbtEnable) == 1 VarSize = sizeof (SA_SETUP); Status = VariableServices->GetVariable ( VariableServices, L"SaSetup", &gSaSetupVariableGuid, NULL, &VarSize, &SaSetup ); if (Status != EFI_SUCCESS) { DEBUG ((DEBUG_ERROR, "Get SaSetup variable failure, %r\n", Status)); return Status; } if ((SaSetup.TcssDma0En == 0) && (SaSetup.TcssDma1En == 0)) { Usb4CmMode = USB4_CM_MODE_FW_CM; DEBUG ((DEBUG_INFO, "TCSS DMA controllers are disabled, CM mode is set to FW CM\n")); } // // Get status of each iTBT PCIe RP is enabled or not from Tcss Hob. // TcssHob = (TCSS_DATA_HOB *) GetFirstGuidHob (&gTcssHobGuid); // // Update ITBT Policy // for (Index = 0; Index < MAX_ITBT_PCIE_PORT; Index++) { COMPARE_AND_UPDATE_POLICY (((FSPS_UPD *) FspsUpd)->FspsConfig.ITbtPcieRootPortEn[Index], PeiITbtConfig->ITbtRootPortConfig[Index].ITbtPcieRootPortEn, SystemConfiguration.ITbtRootPort[Index], Index); // // Set/Clear ITBT Policy for ITbtPcieRootPortEn depending upon each iTBT PCIe RP is enabled or not. // if (TcssHob != NULL) { AND_POLICY (((FSPS_UPD *) FspsUpd)->FspsConfig.ITbtPcieRootPortEn[Index], PeiITbtConfig->ITbtRootPortConfig[Index].ITbtPcieRootPortEn, TcssHob->TcssData.ItbtPcieRpEn[Index]); } } COMPARE_AND_UPDATE_POLICY (((FSPS_UPD *) FspsUpd)->FspsConfig.Usb4CmMode, PeiITbtConfig->ITbtGenericConfig.Usb4CmMode, Usb4CmMode, NullIndex); COMPARE_AND_UPDATE_POLICY (((FSPS_UPD *) FspsUpd)->FspsConfig.ITbtForcePowerOnTimeoutInMs, PeiITbtConfig->ITbtGenericConfig.ITbtForcePowerOnTimeoutInMs, SystemConfiguration.ITbtForcePowerOnTimeoutInMs, NullIndex); COMPARE_AND_UPDATE_POLICY (((FSPS_UPD *) FspsUpd)->FspsConfig.ITbtConnectTopologyTimeoutInMs, PeiITbtConfig->ITbtGenericConfig.ITbtConnectTopologyTimeoutInMs, SystemConfiguration.ITbtConnectTopologyTimeoutInMs, NullIndex); COMPARE_AND_UPDATE_POLICY (((FSPS_UPD *) FspsUpd)->FspsConfig.ITbtPcieTunnelingForUsb4, PeiITbtConfig->ITbtGenericConfig.ITbtPcieTunnelingForUsb4, SystemConfiguration.EnablePcieTunnelingOverUsb4, NullIndex); #endif #if FixedPcdGetBool (PcdDTbtEnable) == 1 // // Update DTBT Policy // if (PeiDTbtConfig != NULL) { for (Index = 0; Index < MAX_DTBT_CONTROLLER_NUMBER; Index++) { PeiDTbtConfig->DTbtControllerConfig[Index].DTbtControllerEn = SystemConfiguration.DTbtController[Index]; if ((SystemConfiguration.TbtSetupDTbtPegTypeSupport) && (SystemConfiguration.DTbtControllerType[Index] == PCIE_RP_TYPE_CPU)) { PeiDTbtConfig->DTbtControllerConfig[Index].Type = (UINT8) PCIE_RP_TYPE_CPU; PeiDTbtConfig->DTbtControllerConfig[Index].PcieRpNumber = 1; // PEG RP 1 (Function no. 0) } } PeiDTbtConfig->DTbtGenericConfig.TbtBootOn = SystemConfiguration.TbtBootOn; PeiDTbtConfig->DTbtGenericConfig.TbtUsbOn = 0;// Deprecated function if (SystemConfiguration.EnablePcieTunnelingOverUsb4 == 1) { PeiDTbtConfig->DTbtGenericConfig.SecurityLevel = 0; } else { PeiDTbtConfig->DTbtGenericConfig.SecurityLevel = 5; } // // Update USB4 CM mode if CM mode switch is supported by platform // if (!(PeiDTbtConfig->DTbtGenericConfig.Usb4CmMode & USB4_CM_MODE_SWITCH_UNSUPPORTED)) { DEBUG ((DEBUG_INFO, "DTBT CM mode switch is supported, Usb4CmMode = %x\n", Usb4CmMode)); PeiDTbtConfig->DTbtGenericConfig.Usb4CmMode = Usb4CmMode; } else { DEBUG ((DEBUG_INFO, "DTBT CM mode switch is not supported, FW CM is applied\n")); } } DTbtPrintPeiPolicyConfig (); #endif return EFI_SUCCESS; }