PeiCometlakeURvpInitPreMemLib.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /** @file
  2. Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <PiPei.h>
  6. #include <SaPolicyCommon.h>
  7. #include <Library/DebugLib.h>
  8. #include <Library/BaseMemoryLib.h>
  9. #include <Library/IoLib.h>
  10. #include <Library/HobLib.h>
  11. #include <Library/PcdLib.h>
  12. #include <Library/PchCycleDecodingLib.h>
  13. #include <Library/PciLib.h>
  14. #include <Library/PcdLib.h>
  15. #include <Library/BaseMemoryLib.h>
  16. #include <Library/PeiSaPolicyLib.h>
  17. #include <Library/BoardInitLib.h>
  18. #include <PchAccess.h>
  19. #include <Library/GpioNativeLib.h>
  20. #include <Library/GpioLib.h>
  21. #include <GpioPinsSklLp.h>
  22. #include <GpioPinsSklH.h>
  23. #include <Library/GpioExpanderLib.h>
  24. #include <SioRegs.h>
  25. #include <Library/PchPcrLib.h>
  26. #include "CometlakeURvpInit.h"
  27. #include <ConfigBlock.h>
  28. #include <ConfigBlock/MemoryConfig.h>
  29. #include <Library/PeiServicesLib.h>
  30. #include <Library/PchPcrLib.h>
  31. #include <Library/PchInfoLib.h>
  32. #include <Register/PchRegsPcr.h>
  33. #include <Library/PchResetLib.h>
  34. #include <Register/PchRegsLpc.h>
  35. #include <Library/StallPpiLib.h>
  36. #include <Library/PeiPolicyInitLib.h>
  37. #include <Ppi/Reset.h>
  38. #include <PlatformBoardConfig.h>
  39. #include <GpioPinsCnlLp.h>
  40. #include <Library/PmcLib.h>
  41. #include <Library/PciSegmentLib.h>
  42. #include <PeiPlatformHookLib.h>
  43. #include <FirwmareConfigurations.h>
  44. #include <Library/OcWdtLib.h>
  45. ///
  46. /// Reset Generator I/O Port
  47. ///
  48. #define RESET_GENERATOR_PORT 0xCF9
  49. typedef struct {
  50. EFI_PHYSICAL_ADDRESS BaseAddress;
  51. UINT64 Length;
  52. } MEMORY_MAP;
  53. //
  54. // Reference RCOMP resistors on motherboard - for WHL RVP1
  55. //
  56. GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
  57. //
  58. // RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk - for WHL RVP1
  59. //
  60. GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 };
  61. GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_MAP MmioMap[] = {
  62. { FixedPcdGet64 (PcdApicLocalAddress), FixedPcdGet32 (PcdApicLocalMmioSize) },
  63. { FixedPcdGet64 (PcdMchBaseAddress), FixedPcdGet32 (PcdMchMmioSize) },
  64. { FixedPcdGet64 (PcdDmiBaseAddress), FixedPcdGet32 (PcdDmiMmioSize) },
  65. { FixedPcdGet64 (PcdEpBaseAddress), FixedPcdGet32 (PcdEpMmioSize) },
  66. { FixedPcdGet64 (PcdGdxcBaseAddress), FixedPcdGet32 (PcdGdxcMmioSize) }
  67. };
  68. EFI_STATUS
  69. MrcConfigInit (
  70. IN UINT16 BoardId
  71. );
  72. EFI_STATUS
  73. SaGpioConfigInit (
  74. IN UINT16 BoardId
  75. );
  76. EFI_STATUS
  77. SaMiscConfigInit (
  78. IN UINT16 BoardId
  79. );
  80. EFI_STATUS
  81. RootPortClkInfoInit (
  82. IN UINT16 BoardId
  83. );
  84. EFI_STATUS
  85. UsbConfigInit (
  86. IN UINT16 BoardId
  87. );
  88. EFI_STATUS
  89. GpioGroupTierInit (
  90. IN UINT16 BoardId
  91. );
  92. EFI_STATUS
  93. GpioTablePreMemInit (
  94. IN UINT16 BoardId
  95. );
  96. EFI_STATUS
  97. PchPmConfigInit (
  98. IN UINT16 BoardId
  99. );
  100. EFI_STATUS
  101. SaDisplayConfigInit (
  102. IN UINT16 BoardId
  103. );
  104. EFI_STATUS
  105. BoardFunctionInitPreMem (
  106. IN UINT16 BoardId
  107. );
  108. EFI_STATUS
  109. EFIAPI
  110. PlatformInitPreMemCallBack (
  111. IN CONST EFI_PEI_SERVICES **PeiServices,
  112. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  113. IN VOID *Ppi
  114. );
  115. EFI_STATUS
  116. EFIAPI
  117. MemoryDiscoveredPpiNotify (
  118. IN CONST EFI_PEI_SERVICES **PeiServices,
  119. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  120. IN VOID *Ppi
  121. );
  122. EFI_STATUS
  123. EFIAPI
  124. PchReset (
  125. IN CONST EFI_PEI_SERVICES **PeiServices
  126. );
  127. static EFI_PEI_RESET_PPI mResetPpi = {
  128. PchReset
  129. };
  130. static EFI_PEI_PPI_DESCRIPTOR mPreMemPpiList[] = {
  131. {
  132. (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  133. &gEfiPeiResetPpiGuid,
  134. &mResetPpi
  135. }
  136. };
  137. static EFI_PEI_NOTIFY_DESCRIPTOR mPreMemNotifyList = {
  138. (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  139. &gEfiPeiReadOnlyVariable2PpiGuid,
  140. (EFI_PEIM_NOTIFY_ENTRY_POINT)PlatformInitPreMemCallBack
  141. };
  142. static EFI_PEI_NOTIFY_DESCRIPTOR mMemDiscoveredNotifyList = {
  143. (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  144. &gEfiPeiMemoryDiscoveredPpiGuid,
  145. (EFI_PEIM_NOTIFY_ENTRY_POINT)MemoryDiscoveredPpiNotify
  146. };
  147. /**
  148. Board misc init function for PEI pre-memory phase.
  149. @param[in] BoardId An unsigned integer represent the board id.
  150. @retval EFI_SUCCESS The function completed successfully.
  151. **/
  152. EFI_STATUS
  153. BoardMiscInitPreMem (
  154. IN UINT16 BoardId
  155. )
  156. {
  157. PCD64_BLOB PcdData;
  158. //
  159. // RecoveryMode GPIO
  160. //
  161. PcdData.Blob = 0;
  162. PcdData.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
  163. switch (BoardId) {
  164. case BoardIdCometLakeULpddr3Rvp:
  165. PcdData.BoardGpioConfig.Type = BoardGpioTypePch;
  166. PcdData.BoardGpioConfig.u.Pin = GPIO_CNL_LP_GPP_F10;
  167. break;
  168. default:
  169. break;
  170. }
  171. //
  172. // Configure WWAN Full Card Power Off and reset pins
  173. //
  174. switch (BoardId) {
  175. case BoardIdCometLakeULpddr3Rvp:
  176. //
  177. // According to board default settings, GPP_D16 is used to enable/disable modem
  178. // power. An alternative way to contol modem power is to toggle FCP_OFF via GPP_D13
  179. // but board rework is required.
  180. //
  181. PcdSet32S (PcdWwanFullCardPowerOffGpio, GPIO_CNL_LP_GPP_D16);
  182. PcdSet32S (PcdWwanBbrstGpio, GPIO_CNL_LP_GPP_F1);
  183. PcdSet32S (PcdWwanPerstGpio, GPIO_CNL_LP_GPP_E15);
  184. PcdSet8S (PcdWwanPerstGpioPolarity, 1);
  185. break;
  186. default:
  187. break;
  188. }
  189. PcdSet64S (PcdRecoveryModeGpio, PcdData.Blob);
  190. //
  191. // Pc8374SioKbc Present
  192. //
  193. PcdSetBoolS (PcdPc8374SioKbcPresent, FALSE);
  194. return EFI_SUCCESS;
  195. }
  196. /**
  197. Board configuration initialization in the pre-memory boot phase.
  198. **/
  199. VOID
  200. BoardConfigInitPreMem (
  201. VOID
  202. )
  203. {
  204. EFI_STATUS Status;
  205. UINT16 BoardId;
  206. BoardId = BoardIdCometLakeULpddr3Rvp;
  207. Status = MrcConfigInit (BoardId);
  208. ASSERT_EFI_ERROR (Status);
  209. Status = SaGpioConfigInit (BoardId);
  210. ASSERT_EFI_ERROR (Status);
  211. Status = SaMiscConfigInit (BoardId);
  212. ASSERT_EFI_ERROR (Status);
  213. Status = RootPortClkInfoInit (BoardId);
  214. ASSERT_EFI_ERROR (Status);
  215. Status = UsbConfigInit (BoardId);
  216. ASSERT_EFI_ERROR (Status);
  217. Status = GpioGroupTierInit (BoardId);
  218. ASSERT_EFI_ERROR (Status);
  219. Status = GpioTablePreMemInit (BoardId);
  220. ASSERT_EFI_ERROR (Status);
  221. Status = PchPmConfigInit (BoardId);
  222. ASSERT_EFI_ERROR (Status);
  223. Status = BoardMiscInitPreMem (BoardId);
  224. ASSERT_EFI_ERROR (Status);
  225. Status = SaDisplayConfigInit (BoardId);
  226. ASSERT_EFI_ERROR (Status);
  227. Status = BoardFunctionInitPreMem (BoardId);
  228. ASSERT_EFI_ERROR (Status);
  229. }
  230. /**
  231. This function handles PlatformInit task after PeiReadOnlyVariable2 PPI produced
  232. @param[in] PeiServices Pointer to PEI Services Table.
  233. @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
  234. caused this function to execute.
  235. @param[in] Ppi Pointer to the PPI data associated with this function.
  236. @retval EFI_SUCCESS The function completes successfully
  237. @retval others Failure
  238. **/
  239. EFI_STATUS
  240. EFIAPI
  241. PlatformInitPreMemCallBack (
  242. IN CONST EFI_PEI_SERVICES **PeiServices,
  243. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  244. IN VOID *Ppi
  245. )
  246. {
  247. EFI_STATUS Status;
  248. UINT8 FwConfig;
  249. //
  250. // Init Board Config Pcd.
  251. //
  252. BoardConfigInitPreMem ();
  253. DEBUG ((DEBUG_ERROR, "Fail to get System Configuration and set the configuration to production mode!\n"));
  254. FwConfig = FwConfigProduction;
  255. PcdSetBoolS (PcdPcieWwanEnable, FALSE);
  256. PcdSetBoolS (PcdWwanResetWorkaround, FALSE);
  257. //
  258. // Early Board Configuration before memory is ready.
  259. //
  260. Status = BoardInitEarlyPreMem ();
  261. ASSERT_EFI_ERROR (Status);
  262. ///
  263. /// If there was unexpected reset but no WDT expiration and no resume from S3/S4,
  264. /// clear unexpected reset status and enforce expiration. This is to inform Firmware
  265. /// which has no access to unexpected reset status bit, that something went wrong.
  266. ///
  267. OcWdtResetCheck ();
  268. Status = OcWdtInit ();
  269. ASSERT_EFI_ERROR (Status);
  270. //
  271. // Initialize Intel PEI Platform Policy
  272. //
  273. PeiPolicyInitPreMem (FwConfig);
  274. ///
  275. /// Configure GPIO and SIO
  276. ///
  277. Status = BoardInitPreMem ();
  278. ASSERT_EFI_ERROR (Status);
  279. ///
  280. /// Install Pre Memory PPIs
  281. ///
  282. Status = PeiServicesInstallPpi (&mPreMemPpiList[0]);
  283. ASSERT_EFI_ERROR (Status);
  284. return Status;
  285. }
  286. /**
  287. Provide hard reset PPI service.
  288. To generate full hard reset, write 0x0E to PCH RESET_GENERATOR_PORT (0xCF9).
  289. @param[in] PeiServices General purpose services available to every PEIM.
  290. @retval Not return System reset occured.
  291. @retval EFI_DEVICE_ERROR Device error, could not reset the system.
  292. **/
  293. EFI_STATUS
  294. EFIAPI
  295. PchReset (
  296. IN CONST EFI_PEI_SERVICES **PeiServices
  297. )
  298. {
  299. DEBUG ((DEBUG_INFO, "Perform Cold Reset\n"));
  300. IoWrite8 (RESET_GENERATOR_PORT, 0x0E);
  301. CpuDeadLoop ();
  302. ///
  303. /// System reset occured, should never reach at this line.
  304. ///
  305. ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
  306. return EFI_DEVICE_ERROR;
  307. }
  308. /**
  309. Install Firmware Volume Hob's once there is main memory
  310. @param[in] PeiServices General purpose services available to every PEIM.
  311. @param[in] NotifyDescriptor Notify that this module published.
  312. @param[in] Ppi PPI that was installed.
  313. @retval EFI_SUCCESS The function completed successfully.
  314. **/
  315. EFI_STATUS
  316. EFIAPI
  317. MemoryDiscoveredPpiNotify (
  318. IN CONST EFI_PEI_SERVICES **PeiServices,
  319. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  320. IN VOID *Ppi
  321. )
  322. {
  323. EFI_STATUS Status;
  324. EFI_BOOT_MODE BootMode;
  325. UINTN Index;
  326. UINT8 PhysicalAddressBits;
  327. UINT32 RegEax;
  328. MEMORY_MAP PcieMmioMap;
  329. Index = 0;
  330. Status = PeiServicesGetBootMode (&BootMode);
  331. ASSERT_EFI_ERROR (Status);
  332. AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
  333. if (RegEax >= 0x80000008) {
  334. AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
  335. PhysicalAddressBits = (UINT8)RegEax;
  336. }
  337. else {
  338. PhysicalAddressBits = 36;
  339. }
  340. ///
  341. /// Create a CPU hand-off information
  342. ///
  343. BuildCpuHob (PhysicalAddressBits, 16);
  344. ///
  345. /// Build Memory Mapped IO Resource which is used to build E820 Table in LegacyBios.
  346. ///
  347. PcieMmioMap.BaseAddress = FixedPcdGet64 (PcdPciExpressBaseAddress);
  348. PcieMmioMap.Length = PcdGet32 (PcdPciExpressRegionLength);
  349. BuildResourceDescriptorHob (
  350. EFI_RESOURCE_MEMORY_MAPPED_IO,
  351. (EFI_RESOURCE_ATTRIBUTE_PRESENT |
  352. EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
  353. EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
  354. PcieMmioMap.BaseAddress,
  355. PcieMmioMap.Length
  356. );
  357. BuildMemoryAllocationHob (
  358. PcieMmioMap.BaseAddress,
  359. PcieMmioMap.Length,
  360. EfiMemoryMappedIO
  361. );
  362. for (Index = 0; Index < sizeof(MmioMap) / (sizeof(MEMORY_MAP)); Index++) {
  363. BuildResourceDescriptorHob (
  364. EFI_RESOURCE_MEMORY_MAPPED_IO,
  365. (EFI_RESOURCE_ATTRIBUTE_PRESENT |
  366. EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
  367. EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
  368. MmioMap[Index].BaseAddress,
  369. MmioMap[Index].Length
  370. );
  371. BuildMemoryAllocationHob (
  372. MmioMap[Index].BaseAddress,
  373. MmioMap[Index].Length,
  374. EfiMemoryMappedIO
  375. );
  376. }
  377. //
  378. // Report resource HOB for flash FV
  379. //
  380. BuildResourceDescriptorHob (
  381. EFI_RESOURCE_MEMORY_MAPPED_IO,
  382. (EFI_RESOURCE_ATTRIBUTE_PRESENT |
  383. EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
  384. EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
  385. (UINTN) FixedPcdGet32 (PcdFlashAreaBaseAddress),
  386. (UINTN) FixedPcdGet32 (PcdFlashAreaSize)
  387. );
  388. BuildMemoryAllocationHob (
  389. (UINTN) FixedPcdGet32 (PcdFlashAreaBaseAddress),
  390. (UINTN) FixedPcdGet32 (PcdFlashAreaSize),
  391. EfiMemoryMappedIO
  392. );
  393. BuildFvHob (
  394. (UINTN)FixedPcdGet32 (PcdFlashAreaBaseAddress),
  395. (UINTN)FixedPcdGet32 (PcdFlashAreaSize)
  396. );
  397. return Status;
  398. }
  399. /**
  400. Board configuration init function for PEI pre-memory phase.
  401. @retval EFI_SUCCESS The function completed successfully.
  402. @retval EFI_INVALID_PARAMETER The parameter is NULL.
  403. **/
  404. EFI_STATUS
  405. EFIAPI
  406. CometlakeURvpInitPreMem (
  407. VOID
  408. )
  409. {
  410. EFI_STATUS Status;
  411. ///
  412. /// Install Stall PPI
  413. ///
  414. Status = InstallStallPpi ();
  415. ASSERT_EFI_ERROR (Status);
  416. //
  417. // Install PCH RESET PPI and EFI RESET2 PeiService
  418. //
  419. Status = PchInitializeReset ();
  420. ASSERT_EFI_ERROR (Status);
  421. ///
  422. /// Performing PlatformInitPreMemCallBack after PeiReadOnlyVariable2 PPI produced
  423. ///
  424. Status = PeiServicesNotifyPpi (&mPreMemNotifyList);
  425. ///
  426. /// After code reorangized, memorycallback will run because the PPI is already
  427. /// installed when code run to here, it is supposed that the InstallEfiMemory is
  428. /// done before.
  429. ///
  430. Status = PeiServicesNotifyPpi (&mMemDiscoveredNotifyList);
  431. return EFI_SUCCESS;
  432. }
  433. /**
  434. Configure GPIO and SIO before memory ready
  435. @retval EFI_SUCCESS Operation success.
  436. **/
  437. EFI_STATUS
  438. EFIAPI
  439. CometlakeURvpBoardInitBeforeMemoryInit(
  440. VOID
  441. )
  442. {
  443. ///
  444. /// Do basic PCH init
  445. ///
  446. SiliconInit ();
  447. CometlakeURvpInitPreMem();
  448. return EFI_SUCCESS;
  449. }
  450. EFI_STATUS
  451. EFIAPI
  452. CometlakeURvpBoardDebugInit(
  453. VOID
  454. )
  455. {
  456. ///
  457. /// Do Early PCH init
  458. ///
  459. EarlySiliconInit ();
  460. return EFI_SUCCESS;
  461. }
  462. EFI_BOOT_MODE
  463. EFIAPI
  464. CometlakeURvpBoardBootModeDetect(
  465. VOID
  466. )
  467. {
  468. return BOOT_WITH_FULL_CONFIGURATION;
  469. }