TbtCommonLib.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /** @file
  2. PeiTbtInit library implementition with empty functions.
  3. Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Library/DebugLib.h>
  7. #include <Uefi/UefiBaseType.h>
  8. #include <Library/PchPcieRpLib.h>
  9. #include <Library/TbtCommonLib.h>
  10. #include <Library/PciSegmentLib.h>
  11. #include <Library/TimerLib.h>
  12. #include <Library/BaseLib.h>
  13. #include <Library/GpioLib.h>
  14. /**
  15. Selects the proper TBT Root port to assign resources
  16. based on the user input value
  17. @param[in] SetupData Pointer to Setup data
  18. @retval TbtSelectorChosen Rootport number.
  19. **/
  20. VOID
  21. GetRootporttoSetResourcesforTbt (
  22. IN UINTN RpIndex,
  23. OUT UINT8 *RsvdExtraBusNum,
  24. OUT UINT16 *RsvdPcieMegaMem,
  25. OUT UINT8 *PcieMemAddrRngMax,
  26. OUT UINT16 *RsvdPciePMegaMem,
  27. OUT UINT8 *PciePMemAddrRngMax,
  28. OUT BOOLEAN *SetResourceforTbt
  29. )
  30. {
  31. UINTN TbtRpNumber;
  32. TbtRpNumber = (UINTN) PcdGet8 (PcdDTbtPcieRpNumber);
  33. if (RpIndex == (TbtRpNumber - 1)) {
  34. *RsvdExtraBusNum = PcdGet8 (PcdDTbtPcieExtraBusRsvd);
  35. *RsvdPcieMegaMem = PcdGet16 (PcdDTbtPcieMemRsvd);
  36. *PcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax);
  37. *RsvdPciePMegaMem = PcdGet16 (PcdDTbtPciePMemRsvd);
  38. *PciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax);
  39. *SetResourceforTbt = TRUE;
  40. }
  41. else {
  42. *SetResourceforTbt = FALSE;
  43. }
  44. }
  45. /**
  46. Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
  47. @param[in] CommandOffsetAddress Tbt2Pcie Register Address
  48. @param[in] TimeOut Time out with 100 ms garnularity
  49. @param[in] Tbt2PcieDone Wait condition (wait for Bit to Clear/Set)
  50. @param[out] *Tbt2PcieValue Function Register value
  51. **/
  52. BOOLEAN
  53. InternalWaitforCommandCompletion(
  54. IN UINT64 CommandOffsetAddress,
  55. IN UINT32 TimeOut,
  56. IN BOOLEAN Tbt2PcieDone,
  57. OUT UINT32 *Tbt2PcieValue
  58. )
  59. {
  60. BOOLEAN ReturnFlag;
  61. UINT32 Tbt2PcieCheck;
  62. ReturnFlag = FALSE;
  63. while (TimeOut-- > 0) {
  64. *Tbt2PcieValue = PciSegmentRead32 (CommandOffsetAddress);
  65. if (0xFFFFFFFF == *Tbt2PcieValue ) {
  66. //
  67. // Device is not here return now
  68. //
  69. ReturnFlag = FALSE;
  70. break;
  71. }
  72. if(Tbt2PcieDone) {
  73. Tbt2PcieCheck = *Tbt2PcieValue & TBT2PCIE_DON_R;
  74. } else {
  75. Tbt2PcieCheck = !(*Tbt2PcieValue & TBT2PCIE_DON_R);
  76. }
  77. if (Tbt2PcieCheck) {
  78. ReturnFlag = TRUE;
  79. break;
  80. }
  81. MicroSecondDelay(TBT_MAIL_BOX_DELAY);
  82. }
  83. return ReturnFlag;
  84. }
  85. /**
  86. Get Security Level.
  87. @param[in] Bus Bus number Host Router (DTBT)
  88. @param[in] Device Device number for Host Router (DTBT)
  89. @param[in] Function Function number for Host Router (DTBT)
  90. @param[in] Command Command for Host Router (DTBT)
  91. @param[in] Timeout Time out with 100 ms garnularity
  92. **/
  93. UINT8
  94. GetSecLevel (
  95. IN UINT8 Bus,
  96. IN UINT8 Device,
  97. IN UINT8 Function,
  98. IN UINT8 Command,
  99. IN UINT32 Timeout
  100. )
  101. {
  102. UINT64 Pcie2Tbt;
  103. UINT64 Tbt2Pcie;
  104. UINT32 RegisterValue;
  105. UINT8 ReturnFlag;
  106. ReturnFlag = 0xFF;
  107. DEBUG ((DEBUG_INFO, "GetSecLevel() \n"));
  108. GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
  109. GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
  110. PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
  111. if(InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue)) {
  112. ReturnFlag = (UINT8) (0xFF & (RegisterValue >> 8));
  113. }
  114. PciSegmentWrite32 (Pcie2Tbt, 0);
  115. InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
  116. DEBUG ((DEBUG_INFO, "Security Level configured to %x \n", ReturnFlag));
  117. return ReturnFlag;
  118. }
  119. /**
  120. Set Security Level.
  121. @param[in] Data Security State
  122. @param[in] Bus Bus number for Host Router (DTBT)
  123. @param[in] Device Device number for Host Router (DTBT)
  124. @param[in] Function Function number for Host Router (DTBT)
  125. @param[in] Command Command for Host Router (DTBT)
  126. @param[in] Timeout Time out with 100 ms garnularity
  127. **/
  128. BOOLEAN
  129. SetSecLevel (
  130. IN UINT8 Data,
  131. IN UINT8 Bus,
  132. IN UINT8 Device,
  133. IN UINT8 Function,
  134. IN UINT8 Command,
  135. IN UINT32 Timeout
  136. )
  137. {
  138. UINT64 Pcie2Tbt;
  139. UINT64 Tbt2Pcie;
  140. UINT32 RegisterValue;
  141. BOOLEAN ReturnFlag;
  142. ReturnFlag = FALSE;
  143. DEBUG ((DEBUG_INFO, "SetSecLevel() \n"));
  144. GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
  145. GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
  146. PciSegmentWrite32 (Pcie2Tbt, (Data << 8) | Command | PCIE2TBT_VLD_B);
  147. ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
  148. DEBUG ((DEBUG_INFO, "RegisterValue %x \n", RegisterValue));
  149. PciSegmentWrite32 (Pcie2Tbt, 0);
  150. InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
  151. DEBUG ((DEBUG_INFO, "Return value %x \n", ReturnFlag));
  152. return ReturnFlag;
  153. }
  154. /**
  155. Based on the Security Mode Selection, BIOS drives FORCE_PWR.
  156. @param[in] GpioNumber
  157. @param[in] Value
  158. **/
  159. VOID
  160. ForceDtbtPower(
  161. IN UINT8 GpioAccessType,
  162. IN UINT8 Expander,
  163. IN UINT32 GpioNumber,
  164. IN BOOLEAN Value
  165. )
  166. {
  167. if (GpioAccessType == 0x01) {
  168. // PCH
  169. GpioSetOutputValue (GpioNumber, (UINT32)Value);
  170. } else if (GpioAccessType == 0x02) {
  171. // IoExpander {TCA6424A}
  172. GpioExpSetOutput (Expander, (UINT8)GpioNumber, (UINT8)Value);
  173. }
  174. }
  175. /**
  176. Execute TBT Mail Box Command
  177. @param[in] Command TBT Command
  178. @param[in] Bus Bus number for Host Router (DTBT)
  179. @param[in] Device Device number for Host Router (DTBT)
  180. @param[in] Function Function number for Host Router (DTBT)
  181. @param[in] Timeout Time out with 100 ms garnularity
  182. @Retval true if command executes succesfully
  183. **/
  184. BOOLEAN
  185. TbtSetPcie2TbtCommand(
  186. IN UINT8 Command,
  187. IN UINT8 Bus,
  188. IN UINT8 Device,
  189. IN UINT8 Function,
  190. IN UINT32 Timeout
  191. )
  192. {
  193. UINT64 Pcie2Tbt;
  194. UINT64 Tbt2Pcie;
  195. UINT32 RegisterValue;
  196. BOOLEAN ReturnFlag;
  197. GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
  198. GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
  199. PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
  200. ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
  201. PciSegmentWrite32(Pcie2Tbt, 0);
  202. return ReturnFlag;
  203. }
  204. /**
  205. Get Pch/Peg Pcie Root Port Device and Function Number for TBT by Root Port physical Number
  206. @param[in] RpNumber Root port physical number. (0-based)
  207. @param[out] RpDev Return corresponding root port device number.
  208. @param[out] RpFun Return corresponding root port function number.
  209. @retval EFI_SUCCESS Root port device and function is retrieved
  210. @retval EFI_INVALID_PARAMETER If Invalid Root Port Number or TYPE is Passed
  211. **/
  212. EFI_STATUS
  213. EFIAPI
  214. GetDTbtRpDevFun (
  215. IN BOOLEAN Type,
  216. IN UINTN RpNumber,
  217. OUT UINTN *RpDev,
  218. OUT UINTN *RpFunc
  219. )
  220. {
  221. EFI_STATUS Status;
  222. UINTN TbtRpDev;
  223. UINTN TbtRpFunc;
  224. Status = EFI_INVALID_PARAMETER; // Update the Status to EFI_SUCCESS if valid input found.
  225. //
  226. // CNL PCH-H can support up to 24 root ports. PEG0,PEG1 and PEG2 will be
  227. // with device number 0x1 and Function number 0,1 and 2 respectively.
  228. //
  229. if (Type == DTBT_TYPE_PEG)
  230. {
  231. //
  232. // PEG Rootport
  233. //
  234. if (RpNumber <= 2) {
  235. *RpDev = 0x01;
  236. *RpFunc = RpNumber;
  237. Status = EFI_SUCCESS;
  238. }
  239. }
  240. if (Type == DTBT_TYPE_PCH)
  241. {
  242. //
  243. // PCH Rootport
  244. //
  245. if (RpNumber <= 23) {
  246. Status = GetPchPcieRpDevFun (RpNumber, &TbtRpDev, &TbtRpFunc);
  247. *RpDev = TbtRpDev;
  248. *RpFunc = TbtRpFunc;
  249. }
  250. }
  251. ASSERT_EFI_ERROR (Status);
  252. return Status;
  253. }
  254. BOOLEAN
  255. IsTbtHostRouter (
  256. IN UINT16 DeviceID
  257. )
  258. {
  259. switch (DeviceID) {
  260. case AR_HR_2C:
  261. case AR_HR_4C:
  262. case AR_HR_LP:
  263. case AR_HR_C0_2C:
  264. case AR_HR_C0_4C:
  265. case TR_HR_2C:
  266. case TR_HR_4C:
  267. return TRUE;
  268. }
  269. return FALSE;
  270. } // IsTbtHostRouter