BoardInitPreMemLib.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /** @file
  2. Platform Hook Library instances
  3. @copyright
  4. Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <Base.h>
  8. #include <PiPei.h>
  9. #include <Platform.h>
  10. #include <Guid/SetupVariable.h>
  11. #include <Guid/SocketVariable.h>
  12. #include <PchSetupVariable.h>
  13. #include <Register/PchRegsPmc.h>
  14. #include <Ppi/FirmwareVolumeInfo.h>
  15. #include <Ppi/ReadOnlyVariable2.h>
  16. #include <Ppi/DynamicSiLibraryPpi.h>
  17. #include <Guid/GlobalVariable.h>
  18. #include <Guid/PlatformInfo.h>
  19. #include <Guid/FirmwareFileSystem3.h>
  20. #include <Library/MemoryAllocationLib.h>
  21. #include <Library/PeiServicesLib.h>
  22. #include <Library/PeiPlatformHooklib.h>
  23. #include <Library/ReportStatusCodeLib.h>
  24. #include <Library/PeiServicesTablePointerLib.h>
  25. #include <Library/BaseLib.h>
  26. #include <Library/IoLib.h>
  27. #include <Library/HobLib.h>
  28. #include <Library/BoardInitLib.h>
  29. #include <Library/PcdLib.h>
  30. #include <Library/DebugLib.h>
  31. #include <Library/IoLib.h>
  32. #include <Library/BaseMemoryLib.h>
  33. #include <SioRegs.h>
  34. EFI_STATUS
  35. UpdatePlatformInfo (
  36. IN SYSTEM_CONFIGURATION *SystemConfiguration,
  37. IN SOCKET_PROCESSORCORE_CONFIGURATION *SocketProcessorCoreConfig,
  38. IN SOCKET_IIO_CONFIGURATION *SocketIioConfig
  39. );
  40. EFI_STATUS
  41. EFIAPI
  42. BoardDetect (
  43. VOID
  44. )
  45. {
  46. return EFI_SUCCESS;
  47. }
  48. EFI_STATUS
  49. EFIAPI
  50. BoardDebugInit (
  51. VOID
  52. )
  53. {
  54. return EFI_SUCCESS;
  55. }
  56. EFI_BOOT_MODE
  57. EFIAPI
  58. BoardBootModeDetect (
  59. VOID
  60. )
  61. {
  62. return BOOT_WITH_FULL_CONFIGURATION;
  63. }
  64. VOID
  65. EarlyPlatformPchInit (
  66. VOID
  67. )
  68. {
  69. UINT16 Data16;
  70. UINT8 Data8;
  71. UINTN SpiBaseAddress;
  72. UINTN P2sbBase;
  73. EFI_STATUS Status = EFI_SUCCESS;
  74. DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi = NULL;
  75. DEBUG((DEBUG_INFO, "EarlyPlatformPchInit - Start\n"));
  76. Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, (VOID **) &DynamicSiLibraryPpi);
  77. if (EFI_ERROR (Status)) {
  78. ASSERT_EFI_ERROR (Status);
  79. return;
  80. }
  81. SpiBaseAddress = DynamicSiLibraryPpi->MmPciBase (
  82. DEFAULT_PCI_BUS_NUMBER_PCH,
  83. PCI_DEVICE_NUMBER_PCH_SPI,
  84. PCI_FUNCTION_NUMBER_PCH_SPI
  85. );
  86. //
  87. // Program bar
  88. //
  89. P2sbBase = DynamicSiLibraryPpi->MmPciBase (
  90. DEFAULT_PCI_BUS_NUMBER_PCH,
  91. PCI_DEVICE_NUMBER_PCH_P2SB,
  92. PCI_FUNCTION_NUMBER_PCH_P2SB
  93. );
  94. MmioWrite32 (P2sbBase + R_P2SB_CFG_SBREG_BAR, PCH_PCR_BASE_ADDRESS);
  95. MmioOr8 (P2sbBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
  96. //
  97. // LPC I/O Configuration
  98. //
  99. DynamicSiLibraryPpi->PchLpcIoDecodeRangesSet (
  100. (V_LPC_CFG_IOD_LPT_378 << N_LPC_CFG_IOD_LPT) |
  101. (V_LPC_CFG_IOD_COMB_3E8 << N_LPC_CFG_IOD_COMB) |
  102. (V_LPC_CFG_IOD_COMA_3F8 << N_LPC_CFG_IOD_COMA)
  103. );
  104. DynamicSiLibraryPpi->PchLpcIoEnableDecodingSet (
  105. B_LPC_CFG_IOE_ME2 |
  106. B_LPC_CFG_IOE_SE |
  107. B_LPC_CFG_IOE_ME1 |
  108. B_LPC_CFG_IOE_KE |
  109. B_LPC_CFG_IOE_HGE |
  110. B_LPC_CFG_IOE_LGE |
  111. B_LPC_CFG_IOE_FDE |
  112. B_LPC_CFG_IOE_PPE |
  113. B_LPC_CFG_IOE_CBE |
  114. B_LPC_CFG_IOE_CAE
  115. );
  116. //
  117. // Enable the upper 128-byte bank of RTC RAM
  118. //
  119. DynamicSiLibraryPpi->PchPcrAndThenOr32 (PID_RTC_HOST, R_RTC_PCR_CONF, (UINT32)~0, B_RTC_PCR_CONF_UCMOS_EN);
  120. //
  121. // Disable the Watchdog timer expiration from causing a system reset
  122. //
  123. DynamicSiLibraryPpi->PchPcrAndThenOr32 (PID_ITSS, R_ITSS_PCR_GIC, (UINT32)~0, B_ITSS_PCR_GIC_AME);
  124. //
  125. // Halt the TCO timer
  126. //
  127. Data16 = IoRead16 (PCH_TCO_BASE_ADDRESS + R_TCO_IO_TCO1_CNT);
  128. Data16 |= B_TCO_IO_TCO1_CNT_TMR_HLT;
  129. IoWrite16 (PCH_TCO_BASE_ADDRESS + R_TCO_IO_TCO1_CNT, Data16);
  130. //
  131. // Read the Second TO status bit
  132. //
  133. Data8 = IoRead8 (PCH_TCO_BASE_ADDRESS + R_TCO_IO_TCO2_STS);
  134. if ((Data8 & B_TCO_IO_TCO2_STS_SECOND_TO) == B_TCO_IO_TCO2_STS_SECOND_TO) {
  135. DEBUG ((EFI_D_INFO, "EarlyPlatformPchInit - TCO Second TO status bit is set. This might be a TCO reboot\n"));
  136. }
  137. //
  138. // Clear the Second TO status bit
  139. //
  140. Data8 |= (UINT8) B_TCO_IO_TCO2_STS_SECOND_TO;
  141. Data8 &= (UINT8) ~B_TCO_IO_TCO2_STS_INTRD_DET;
  142. IoWrite8 (PCH_TCO_BASE_ADDRESS + R_TCO_IO_TCO2_STS, Data8);
  143. //
  144. // Disable SERR NMI and IOCHK# NMI in port 61
  145. //
  146. Data8 = IoRead8 (R_PCH_IO_NMI_SC);
  147. Data8 |= (B_PCH_IO_NMI_SC_PCI_SERR_EN | B_PCH_IO_NMI_SC_IOCHK_NMI_EN);
  148. IoWrite8 (R_PCH_IO_NMI_SC, Data8);
  149. DynamicSiLibraryPpi->PchPcrAndThenOr32 (PID_ITSS, R_ITSS_PCR_GIC, (UINT32)~B_ITSS_PCR_GIC_AME, 0);
  150. //
  151. // Clear EISS bit to allow for SPI use
  152. //
  153. MmioAnd8 (SpiBaseAddress + R_SPI_CFG_BC, (UINT8)~B_SPI_CFG_BC_EISS);
  154. //
  155. // Enable LPC decode at 0xCA0 for BMC
  156. //
  157. DynamicSiLibraryPpi->PchLpcGenIoRangeSet ((IPMI_DEFAULT_SMM_IO_BASE & 0xFF0), 0x10);
  158. DEBUG ((EFI_D_INFO, "[IPMI_DEBUG]: PchLpcGenIoRangeSet 0x%x!\n", IPMI_DEFAULT_SMM_IO_BASE));
  159. DEBUG((DEBUG_INFO, "EarlyPlatformPchInit - End\n"));
  160. }
  161. EFI_STATUS
  162. EFIAPI
  163. BoardInitBeforeMemoryInit (
  164. VOID
  165. )
  166. {
  167. SYSTEM_CONFIGURATION SysSetupData;
  168. SOCKET_PROCESSORCORE_CONFIGURATION SocketProcessorCoreSetupData;
  169. SOCKET_IIO_CONFIGURATION SocketIioSetupData;
  170. PCH_SETUP PchSetupData;
  171. UINT16 ABase;
  172. UINT16 Pm1Sts = 0;
  173. UINT32 Pm1Cnt;
  174. EFI_STATUS Status;
  175. DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi = NULL;
  176. Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, (VOID **) &DynamicSiLibraryPpi);
  177. if (EFI_ERROR (Status)) {
  178. ASSERT_EFI_ERROR (Status);
  179. return Status;
  180. }
  181. //
  182. // Get Setup Data
  183. //
  184. ZeroMem (&SysSetupData, sizeof(SYSTEM_CONFIGURATION));
  185. ZeroMem (&SocketProcessorCoreSetupData, sizeof(SOCKET_PROCESSORCORE_CONFIGURATION));
  186. ZeroMem (&SocketIioSetupData, sizeof(SOCKET_IIO_CONFIGURATION));
  187. ZeroMem (&PchSetupData, sizeof(PCH_SETUP));
  188. CopyMem (&PchSetupData, PcdGetPtr(PcdPchSetup), sizeof(PCH_SETUP));
  189. CopyMem (&SysSetupData, PcdGetPtr(PcdSetup), sizeof(SYSTEM_CONFIGURATION));
  190. CopyMem (&SocketProcessorCoreSetupData, PcdGetPtr(PcdSocketProcessorCoreConfig), sizeof(SOCKET_PROCESSORCORE_CONFIGURATION));
  191. CopyMem (&SocketIioSetupData, PcdGetPtr(PcdSocketIioConfig), sizeof(SOCKET_IIO_CONFIGURATION));
  192. //
  193. // Configure GPIO
  194. //
  195. Status = BoardInit ();
  196. EarlyPlatformPchInit ();
  197. ///
  198. /// Set what state (S0/S5) to go to when power is re-applied after a power failure (G3 state)
  199. ///
  200. DynamicSiLibraryPpi->PmcSetPlatformStateAfterPowerFailure (PchSetupData.StateAfterG3);
  201. //
  202. // Check PWR FLR
  203. //
  204. if (DynamicSiLibraryPpi->PmcIsPowerFailureDetected ()) {
  205. DynamicSiLibraryPpi->PmcClearPowerFailureStatus ();
  206. }
  207. ///----------------------------------------------------------------------------------
  208. ///
  209. /// Clear PWR_BTN_STS if set. BIOS should check the WAK_STS bit in PM1_STS[15] (PCH register ABASE+00h) before memory
  210. /// initialization to determine if ME has reset the system while the Host was in a sleep state.
  211. /// If WAK_STS is not set, BIOS should ensure a non-sleep exit path is taken by overwriting
  212. /// PM1_CNT[12:10] (PCH register ABASE+04h) to 111b to force an s5 exit.
  213. ///
  214. ABase = DynamicSiLibraryPpi->PmcGetAcpiBase ();
  215. Pm1Sts = IoRead16 (ABase + R_ACPI_IO_PM1_STS);
  216. if ((Pm1Sts & B_ACPI_IO_PM1_STS_PWRBTN) == B_ACPI_IO_PM1_STS_PWRBTN) {
  217. IoWrite16 (ABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN);
  218. }
  219. if ((Pm1Sts & B_ACPI_IO_PM1_STS_WAK) == 0) {
  220. Pm1Cnt = IoRead32 (ABase + R_ACPI_IO_PM1_CNT);
  221. Pm1Cnt |= V_ACPI_IO_PM1_CNT_S5;
  222. IoWrite32 (ABase + R_ACPI_IO_PM1_CNT, Pm1Cnt);
  223. }
  224. //
  225. // Update Platform Info
  226. //
  227. UpdatePlatformInfo (&SysSetupData,&SocketProcessorCoreSetupData,&SocketIioSetupData);
  228. return EFI_SUCCESS;
  229. }
  230. EFI_STATUS
  231. EFIAPI
  232. BoardInitAfterMemoryInit (
  233. VOID
  234. )
  235. {
  236. EFI_STATUS Status;
  237. EFI_BOOT_MODE BootMode;
  238. UINT16 Pm1Cnt;
  239. DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi = NULL;
  240. Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, (VOID **) &DynamicSiLibraryPpi);
  241. if (EFI_ERROR (Status)) {
  242. ASSERT_EFI_ERROR (Status);
  243. return Status;
  244. }
  245. Status = PeiServicesGetBootMode (&BootMode);
  246. ASSERT_EFI_ERROR (Status);
  247. //
  248. // Check if user wants to turn off in PEI phase
  249. //
  250. if (BootMode != BOOT_ON_S3_RESUME) {
  251. DynamicSiLibraryPpi->CheckPowerOffNow ();
  252. } else {
  253. Pm1Cnt = IoRead16 (PCH_ACPI_BASE_ADDRESS + R_ACPI_IO_PM1_CNT);
  254. Pm1Cnt &= ~B_ACPI_IO_PM1_CNT_SLP_TYP;
  255. IoWrite16 (PCH_ACPI_BASE_ADDRESS + R_ACPI_IO_PM1_CNT, Pm1Cnt);
  256. }
  257. return EFI_SUCCESS;
  258. }
  259. EFI_STATUS
  260. EFIAPI
  261. BoardInitBeforeTempRamExit (
  262. VOID
  263. )
  264. {
  265. return EFI_SUCCESS;
  266. }
  267. EFI_STATUS
  268. EFIAPI
  269. BoardInitAfterTempRamExit (
  270. VOID
  271. )
  272. {
  273. return EFI_SUCCESS;
  274. }
  275. /**
  276. Initialize POC register by Variable.
  277. @param *SystemConfiguration - Pointer to SystemConfiguration variables.
  278. @retval EFI_SUCCESS - Success.
  279. **/
  280. EFI_STATUS
  281. UpdatePlatformInfo (
  282. IN SYSTEM_CONFIGURATION *SystemConfiguration,
  283. IN SOCKET_PROCESSORCORE_CONFIGURATION *SocketProcessorCoreConfig,
  284. IN SOCKET_IIO_CONFIGURATION *SocketIioConfig
  285. )
  286. {
  287. EFI_PLATFORM_INFO *PlatformInfo;
  288. EFI_HOB_GUID_TYPE *GuidHob;
  289. //
  290. // Update the PCIE base and 32/64bit PCI resource support
  291. //
  292. GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
  293. ASSERT (GuidHob != NULL);
  294. if (GuidHob == NULL) {
  295. return EFI_NOT_FOUND;
  296. }
  297. PlatformInfo = GET_GUID_HOB_DATA(GuidHob);
  298. PlatformInfo->SysData.SysIoApicEnable = PCH_IOAPIC;
  299. #if MAX_SOCKET <= 4
  300. if (SocketIioConfig->DevPresIoApicIio[0]) {
  301. PlatformInfo->SysData.SysIoApicEnable |= (PC00_IOAPIC);
  302. }
  303. if (SocketIioConfig->DevPresIoApicIio[1]) {
  304. PlatformInfo->SysData.SysIoApicEnable |= (PC01_IOAPIC);
  305. }
  306. if (SocketIioConfig->DevPresIoApicIio[2]) {
  307. PlatformInfo->SysData.SysIoApicEnable |= (PC02_IOAPIC);
  308. }
  309. if (SocketIioConfig->DevPresIoApicIio[3]) {
  310. PlatformInfo->SysData.SysIoApicEnable |= (PC03_IOAPIC);
  311. }
  312. if (SocketIioConfig->DevPresIoApicIio[4]) {
  313. PlatformInfo->SysData.SysIoApicEnable |= (PC04_IOAPIC);
  314. }
  315. if (SocketIioConfig->DevPresIoApicIio[5]) {
  316. PlatformInfo->SysData.SysIoApicEnable |= (PC05_IOAPIC);
  317. }
  318. if (SocketIioConfig->DevPresIoApicIio[6]) {
  319. PlatformInfo->SysData.SysIoApicEnable |= (PC06_IOAPIC);
  320. }
  321. if (SocketIioConfig->DevPresIoApicIio[7]) {
  322. PlatformInfo->SysData.SysIoApicEnable |= (PC07_IOAPIC);
  323. }
  324. if (SocketIioConfig->DevPresIoApicIio[8]) {
  325. PlatformInfo->SysData.SysIoApicEnable |= (PC08_IOAPIC);
  326. }
  327. if (SocketIioConfig->DevPresIoApicIio[9]) {
  328. PlatformInfo->SysData.SysIoApicEnable |= (PC09_IOAPIC);
  329. }
  330. if (SocketIioConfig->DevPresIoApicIio[10]) {
  331. PlatformInfo->SysData.SysIoApicEnable |= (PC10_IOAPIC);
  332. }
  333. if (SocketIioConfig->DevPresIoApicIio[11]) {
  334. PlatformInfo->SysData.SysIoApicEnable |= (PC11_IOAPIC);
  335. }
  336. if (SocketIioConfig->DevPresIoApicIio[12]) {
  337. PlatformInfo->SysData.SysIoApicEnable |= (PC12_IOAPIC);
  338. }
  339. if (SocketIioConfig->DevPresIoApicIio[13]) {
  340. PlatformInfo->SysData.SysIoApicEnable |= (PC13_IOAPIC);
  341. }
  342. if (SocketIioConfig->DevPresIoApicIio[14]) {
  343. PlatformInfo->SysData.SysIoApicEnable |= (PC14_IOAPIC);
  344. }
  345. if (SocketIioConfig->DevPresIoApicIio[15]) {
  346. PlatformInfo->SysData.SysIoApicEnable |= (PC15_IOAPIC);
  347. }
  348. if (SocketIioConfig->DevPresIoApicIio[16]) {
  349. PlatformInfo->SysData.SysIoApicEnable |= (PC16_IOAPIC);
  350. }
  351. if (SocketIioConfig->DevPresIoApicIio[17]) {
  352. PlatformInfo->SysData.SysIoApicEnable |= (PC17_IOAPIC);
  353. }
  354. if (SocketIioConfig->DevPresIoApicIio[18]) {
  355. PlatformInfo->SysData.SysIoApicEnable |= (PC18_IOAPIC);
  356. }
  357. if (SocketIioConfig->DevPresIoApicIio[19]) {
  358. PlatformInfo->SysData.SysIoApicEnable |= (PC19_IOAPIC);
  359. }
  360. if (SocketIioConfig->DevPresIoApicIio[20]) {
  361. PlatformInfo->SysData.SysIoApicEnable |= (PC20_IOAPIC);
  362. }
  363. if (SocketIioConfig->DevPresIoApicIio[21]) {
  364. PlatformInfo->SysData.SysIoApicEnable |= (PC21_IOAPIC);
  365. }
  366. if (SocketIioConfig->DevPresIoApicIio[22]) {
  367. PlatformInfo->SysData.SysIoApicEnable |= (PC22_IOAPIC);
  368. }
  369. if (SocketIioConfig->DevPresIoApicIio[23]) {
  370. PlatformInfo->SysData.SysIoApicEnable |= (PC23_IOAPIC);
  371. }
  372. #else
  373. // Enable all 32 IOxAPIC
  374. PlatformInfo->SysData.SysIoApicEnable = 0xFFFFFFFF;
  375. #endif
  376. //
  377. // Check to make sure TsegSize is in range, if not use default.
  378. //
  379. if (SocketProcessorCoreConfig->TsegSize > MAX_PROCESSOR_TSEG) {
  380. SocketProcessorCoreConfig->TsegSize = MAX_PROCESSOR_TSEG; // if out of range make default 64M
  381. }
  382. PlatformInfo->MemData.MemTsegSize = (0x400000 << SocketProcessorCoreConfig->TsegSize);
  383. PlatformInfo->MemData.MemIedSize = PcdGet32 (PcdCpuIEDRamSize);
  384. //
  385. // Minimum SMM range in TSEG should be larger than 3M
  386. //
  387. ASSERT (PlatformInfo->MemData.MemTsegSize - PlatformInfo->MemData.MemIedSize >= 0x300000);
  388. return EFI_SUCCESS;
  389. }