/** @file PeiTbtInit library implementition with empty functions. Copyright (c) 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include /** Selects the proper TBT Root port to assign resources based on the user input value @param[in] SetupData Pointer to Setup data @retval TbtSelectorChosen Rootport number. **/ VOID GetRootporttoSetResourcesforTbt ( IN UINTN RpIndex, OUT UINT8 *RsvdExtraBusNum, OUT UINT16 *RsvdPcieMegaMem, OUT UINT8 *PcieMemAddrRngMax, OUT UINT16 *RsvdPciePMegaMem, OUT UINT8 *PciePMemAddrRngMax, OUT BOOLEAN *SetResourceforTbt ) { UINTN TbtRpNumber; TbtRpNumber = (UINTN) PcdGet8 (PcdDTbtPcieRpNumber); if (RpIndex == (TbtRpNumber - 1)) { *RsvdExtraBusNum = PcdGet8 (PcdDTbtPcieExtraBusRsvd); *RsvdPcieMegaMem = PcdGet16 (PcdDTbtPcieMemRsvd); *PcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax); *RsvdPciePMegaMem = PcdGet16 (PcdDTbtPciePMemRsvd); *PciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax); *SetResourceforTbt = TRUE; } else { *SetResourceforTbt = FALSE; } } /** Internal function to Wait for Tbt2PcieDone Bit.to Set or clear @param[in] CommandOffsetAddress Tbt2Pcie Register Address @param[in] TimeOut Time out with 100 ms garnularity @param[in] Tbt2PcieDone Wait condition (wait for Bit to Clear/Set) @param[out] *Tbt2PcieValue Function Register value **/ BOOLEAN InternalWaitforCommandCompletion( IN UINT64 CommandOffsetAddress, IN UINT32 TimeOut, IN BOOLEAN Tbt2PcieDone, OUT UINT32 *Tbt2PcieValue ) { BOOLEAN ReturnFlag; UINT32 Tbt2PcieCheck; ReturnFlag = FALSE; while (TimeOut-- > 0) { *Tbt2PcieValue = PciSegmentRead32 (CommandOffsetAddress); if (0xFFFFFFFF == *Tbt2PcieValue ) { // // Device is not here return now // ReturnFlag = FALSE; break; } if(Tbt2PcieDone) { Tbt2PcieCheck = *Tbt2PcieValue & TBT2PCIE_DON_R; } else { Tbt2PcieCheck = !(*Tbt2PcieValue & TBT2PCIE_DON_R); } if (Tbt2PcieCheck) { ReturnFlag = TRUE; break; } MicroSecondDelay(TBT_MAIL_BOX_DELAY); } return ReturnFlag; } /** Get Security Level. @param[in] Bus Bus number Host Router (DTBT) @param[in] Device Device number for Host Router (DTBT) @param[in] Function Function number for Host Router (DTBT) @param[in] Command Command for Host Router (DTBT) @param[in] Timeout Time out with 100 ms garnularity **/ UINT8 GetSecLevel ( IN UINT8 Bus, IN UINT8 Device, IN UINT8 Function, IN UINT8 Command, IN UINT32 Timeout ) { UINT64 Pcie2Tbt; UINT64 Tbt2Pcie; UINT32 RegisterValue; UINT8 ReturnFlag; ReturnFlag = 0xFF; DEBUG ((DEBUG_INFO, "GetSecLevel() \n")); GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie) GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt) PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B); if(InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue)) { ReturnFlag = (UINT8) (0xFF & (RegisterValue >> 8)); } PciSegmentWrite32 (Pcie2Tbt, 0); InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue); DEBUG ((DEBUG_INFO, "Security Level configured to %x \n", ReturnFlag)); return ReturnFlag; } /** Set Security Level. @param[in] Data Security State @param[in] Bus Bus number for Host Router (DTBT) @param[in] Device Device number for Host Router (DTBT) @param[in] Function Function number for Host Router (DTBT) @param[in] Command Command for Host Router (DTBT) @param[in] Timeout Time out with 100 ms garnularity **/ BOOLEAN SetSecLevel ( IN UINT8 Data, IN UINT8 Bus, IN UINT8 Device, IN UINT8 Function, IN UINT8 Command, IN UINT32 Timeout ) { UINT64 Pcie2Tbt; UINT64 Tbt2Pcie; UINT32 RegisterValue; BOOLEAN ReturnFlag; ReturnFlag = FALSE; DEBUG ((DEBUG_INFO, "SetSecLevel() \n")); GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie) GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt) PciSegmentWrite32 (Pcie2Tbt, (Data << 8) | Command | PCIE2TBT_VLD_B); ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue); DEBUG ((DEBUG_INFO, "RegisterValue %x \n", RegisterValue)); PciSegmentWrite32 (Pcie2Tbt, 0); InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue); DEBUG ((DEBUG_INFO, "Return value %x \n", ReturnFlag)); return ReturnFlag; } /** Based on the Security Mode Selection, BIOS drives FORCE_PWR. @param[in] GpioNumber @param[in] Value **/ VOID ForceDtbtPower( IN UINT8 GpioAccessType, IN UINT8 Expander, IN UINT32 GpioNumber, IN BOOLEAN Value ) { if (GpioAccessType == 0x01) { // PCH GpioSetOutputValue (GpioNumber, (UINT32)Value); } else if (GpioAccessType == 0x02) { // IoExpander {TCA6424A} GpioExpSetOutput (Expander, (UINT8)GpioNumber, (UINT8)Value); } } /** Execute TBT Mail Box Command @param[in] Command TBT Command @param[in] Bus Bus number for Host Router (DTBT) @param[in] Device Device number for Host Router (DTBT) @param[in] Function Function number for Host Router (DTBT) @param[in] Timeout Time out with 100 ms garnularity @Retval true if command executes succesfully **/ BOOLEAN TbtSetPcie2TbtCommand( IN UINT8 Command, IN UINT8 Bus, IN UINT8 Device, IN UINT8 Function, IN UINT32 Timeout ) { UINT64 Pcie2Tbt; UINT64 Tbt2Pcie; UINT32 RegisterValue; BOOLEAN ReturnFlag; GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie) GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt) PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B); ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue); PciSegmentWrite32(Pcie2Tbt, 0); return ReturnFlag; } /** Get Pch/Peg Pcie Root Port Device and Function Number for TBT by Root Port physical Number @param[in] RpNumber Root port physical number. (0-based) @param[out] RpDev Return corresponding root port device number. @param[out] RpFun Return corresponding root port function number. @retval EFI_SUCCESS Root port device and function is retrieved @retval EFI_INVALID_PARAMETER If Invalid Root Port Number or TYPE is Passed **/ EFI_STATUS EFIAPI GetDTbtRpDevFun ( IN BOOLEAN Type, IN UINTN RpNumber, OUT UINTN *RpDev, OUT UINTN *RpFunc ) { EFI_STATUS Status; UINTN TbtRpDev; UINTN TbtRpFunc; Status = EFI_INVALID_PARAMETER; // Update the Status to EFI_SUCCESS if valid input found. // // PCH-H can support up to 24 root ports. PEG0,PEG1 and PEG2 will be // with device number 0x1 and Function number 0,1 and 2 respectively. // if (Type == DTBT_TYPE_PEG) { // // PEG Rootport // if (RpNumber <= 2) { *RpDev = 0x01; *RpFunc = RpNumber; Status = EFI_SUCCESS; } } if (Type == DTBT_TYPE_PCH) { // // PCH Rootport // if (RpNumber <= 23) { Status = GetPchPcieRpDevFun (RpNumber, &TbtRpDev, &TbtRpFunc); *RpDev = TbtRpDev; *RpFunc = TbtRpFunc; } } ASSERT_EFI_ERROR (Status); return Status; } BOOLEAN IsTbtHostRouter ( IN UINT16 DeviceID ) { switch (DeviceID) { case AR_HR_2C: case AR_HR_4C: case AR_HR_LP: case AR_HR_C0_2C: case AR_HR_C0_4C: case TR_HR_2C: case TR_HR_4C: return TRUE; } return FALSE; } // IsTbtHostRouter