PchInitPeim.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. /** @file
  2. Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. Module Name:
  5. PchInitPeim.c
  6. Abstract:
  7. Do Early PCH platform initialization.
  8. --*/
  9. #include "PlatformEarlyInit.h"
  10. #include "Ppi/PchPlatformPolicy.h"
  11. #include "PchRegs.h"
  12. #include <Ppi/PchUsbPolicy.h>
  13. #include "Ppi/PchInit.h"
  14. #include <Library/PcdLib.h>
  15. EFI_GUID gPchPlatformPolicyPpiGuid = PCH_PLATFORM_POLICY_PPI_GUID;
  16. #define MC_PMSTS_OFFSET 0xC
  17. #define DEFAULT_BUS_INFO 0x2020
  18. #define PCI_LPC_BASE (0x8000F800)
  19. #define PCI_LPC_REG(x) (PCI_LPC_BASE + (x))
  20. #define PCIEX_BASE_ADDRESS 0xE0000000
  21. #define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
  22. VOID
  23. PchPolicySetupInit (
  24. IN CONST EFI_PEI_SERVICES **PeiServices,
  25. IN SYSTEM_CONFIGURATION *SystemConfiguration
  26. );
  27. VOID
  28. PchInitInterrupt (
  29. IN SYSTEM_CONFIGURATION *SystemConfiguration
  30. );
  31. EFI_STATUS
  32. InstallPeiPchUsbPolicy (
  33. IN CONST EFI_PEI_SERVICES **PeiServices
  34. );
  35. #ifndef __GNUC__
  36. #pragma warning (push)
  37. #pragma warning (disable : 4245)
  38. #pragma warning (pop)
  39. #endif
  40. UINT8
  41. ReadCmosBank1Byte (
  42. IN UINT8 Address
  43. )
  44. {
  45. UINT8 Data;
  46. IoWrite8(R_PCH_RTC_EXT_INDEX, Address);
  47. Data = IoRead8 (R_PCH_RTC_EXT_TARGET);
  48. return Data;
  49. }
  50. VOID
  51. WriteCmosBank1Byte (
  52. IN UINT8 Address,
  53. IN UINT8 Data
  54. )
  55. {
  56. IoWrite8(R_PCH_RTC_EXT_INDEX, Address);
  57. IoWrite8(R_PCH_RTC_EXT_TARGET, Data);
  58. }
  59. /**
  60. Turn off system if needed.
  61. @retval None.
  62. **/
  63. VOID
  64. CheckPowerOffNow (
  65. VOID
  66. )
  67. {
  68. UINT16 Pm1Sts;
  69. //
  70. // Read and check the ACPI registers
  71. //
  72. Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
  73. if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) == B_PCH_ACPI_PM1_STS_PWRBTN) {
  74. IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN);
  75. IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5);
  76. IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5 + B_PCH_ACPI_PM1_CNT_SLP_EN);
  77. //
  78. // Should not return
  79. //
  80. CpuDeadLoop();
  81. }
  82. }
  83. VOID
  84. ClearPowerState (
  85. IN SYSTEM_CONFIGURATION *SystemConfiguration
  86. )
  87. {
  88. UINT8 Data8;
  89. UINT16 Data16;
  90. UINT32 Data32;
  91. //
  92. // Check for PowerState option for AC power loss and program the chipset
  93. //
  94. //
  95. // Clear PWROK (Set to Clear)
  96. //
  97. MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_PWROK_FLR);
  98. //
  99. // Clear Power Failure Bit (Set to Clear)
  100. //
  101. // TODO: Check if it is OK to clear here
  102. //
  103. MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR);
  104. //
  105. // Clear the GPE and PM enable
  106. //
  107. IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_EN, (UINT16) 0x00);
  108. IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_EN, (UINT32) 0x00);
  109. //
  110. // Halt the TCO timer
  111. //
  112. Data16 = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT);
  113. Data16 |= B_PCH_TCO_CNT_TMR_HLT;
  114. IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT, Data16);
  115. //
  116. // if NMI_NOW_STS is set
  117. // NMI NOW bit is "Write '1' to clear"
  118. //
  119. Data8 = MmioRead8(ILB_BASE_ADDRESS + R_PCH_ILB_GNMI);
  120. if ((Data8 & B_PCH_ILB_GNMI_NMINS) == B_PCH_ILB_GNMI_NMINS) {
  121. MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_GNMI, B_PCH_ILB_GNMI_NMIN);
  122. }
  123. //
  124. // Before we clear the TO status bit here we need to save the results in a CMOS bit for later use.
  125. //
  126. Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);
  127. if ((Data32 & B_PCH_TCO_STS_SECOND_TO) == B_PCH_TCO_STS_SECOND_TO)
  128. {
  129. #if (defined(HW_WATCHDOG_TIMER_SUPPORT) && (HW_WATCHDOG_TIMER_SUPPORT != 0))
  130. WriteCmosBank1Byte (
  131. EFI_CMOS_PERFORMANCE_FLAGS,
  132. ReadCmosBank1Byte (EFI_CMOS_PERFORMANCE_FLAGS) | B_CMOS_TCO_WDT_RESET
  133. );
  134. #endif
  135. }
  136. }
  137. /*++
  138. Clear any SMI status or wake status left over from boot.
  139. **/
  140. VOID
  141. ClearSmiAndWake (
  142. VOID
  143. )
  144. {
  145. UINT16 Pm1Sts;
  146. UINT32 Gpe0Sts;
  147. UINT32 SmiSts;
  148. //
  149. // Read the ACPI registers
  150. //
  151. Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
  152. Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS);
  153. SmiSts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS);
  154. //
  155. // Register Wake up reason for S4. This information is used to notify
  156. // WinXp of wake up reason because S4 wake up path doesn't keep SCI.
  157. // This is important for Viiv(Quick resume) platform.
  158. //
  159. //
  160. // First Clear CMOS S4 Wake up flag.
  161. //
  162. WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 0);
  163. //
  164. // Check wake up reason and set CMOS accordingly. Currently checks
  165. // Power button, USB, PS/2.
  166. // Note : PS/2 wake up is using GPI13 (IO_PME). This must be changed depending
  167. // on board design.
  168. //
  169. if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) || (Gpe0Sts & (B_PCH_ACPI_GPE0a_STS_CORE_GPIO | B_PCH_ACPI_GPE0a_STS_SUS_GPIO))) {
  170. WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 1);
  171. }
  172. //
  173. // Clear any SMI or wake state from the boot
  174. //
  175. Pm1Sts = (B_PCH_ACPI_PM1_STS_PRBTNOR | B_PCH_ACPI_PM1_STS_PWRBTN);
  176. Gpe0Sts |=
  177. (
  178. B_PCH_ACPI_GPE0a_STS_CORE_GPIO |
  179. B_PCH_ACPI_GPE0a_STS_SUS_GPIO |
  180. B_PCH_ACPI_GPE0a_STS_PME_B0 |
  181. B_PCH_ACPI_GPE0a_STS_BATLOW |
  182. B_PCH_ACPI_GPE0a_STS_PCI_EXP |
  183. B_PCH_ACPI_GPE0a_STS_GUNIT_SCI |
  184. B_PCH_ACPI_GPE0a_STS_PUNIT_SCI |
  185. B_PCH_ACPI_GPE0a_STS_SWGPE |
  186. B_PCH_ACPI_GPE0a_STS_HOT_PLUG
  187. );
  188. SmiSts |=
  189. (
  190. B_PCH_SMI_STS_SMBUS |
  191. B_PCH_SMI_STS_PERIODIC |
  192. B_PCH_SMI_STS_TCO |
  193. B_PCH_SMI_STS_SWSMI_TMR |
  194. B_PCH_SMI_STS_APM |
  195. B_PCH_SMI_STS_ON_SLP_EN |
  196. B_PCH_SMI_STS_BIOS
  197. );
  198. //
  199. // Write them back
  200. //
  201. IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, Pm1Sts);
  202. IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS, Gpe0Sts);
  203. IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS, SmiSts);
  204. }
  205. /**
  206. Issue PCI-E Secondary Bus Reset
  207. @param Bus Bus number of the bridge
  208. @param Dev Devices number of the bridge
  209. @param Fun Function number of the bridge
  210. @retval EFI_SUCCESS
  211. **/
  212. EFI_STATUS
  213. PcieSecondaryBusReset (
  214. IN CONST EFI_PEI_SERVICES **PeiServices,
  215. IN UINT8 Bus,
  216. IN UINT8 Dev,
  217. IN UINT8 Fun
  218. )
  219. {
  220. EFI_PEI_STALL_PPI *PeiStall;
  221. EFI_STATUS Status;
  222. Status = (**PeiServices).LocatePpi (
  223. PeiServices,
  224. &gEfiPeiStallPpiGuid,
  225. 0,
  226. NULL,
  227. (void **)&PeiStall
  228. );
  229. ASSERT_EFI_ERROR (Status);
  230. //
  231. // Issue secondary bus reset
  232. //
  233. MmPci16Or(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS);
  234. //
  235. // Wait 1ms
  236. //
  237. PeiStall->Stall (PeiServices, PeiStall, 1000);
  238. //
  239. // Clear the reset bit
  240. // Note: The PCIe spec suggests 100ms delay between clearing this bit and accessing
  241. // the device's config space. Since we will not access the config space until we enter DXE
  242. // we don't put delay expressly here.
  243. //
  244. MmPci16And(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, ~(EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS));
  245. return EFI_SUCCESS;
  246. }
  247. /**
  248. Provide hard reset PPI service.
  249. To generate full hard reset, write 0x0E to ICH RESET_GENERATOR_PORT (0xCF9).
  250. @param PeiServices General purpose services available to every PEIM.
  251. @retval Not return System reset occured.
  252. @retval EFI_DEVICE_ERROR Device error, could not reset the system.
  253. **/
  254. EFI_STATUS
  255. EFIAPI
  256. IchReset (
  257. IN CONST EFI_PEI_SERVICES **PeiServices
  258. )
  259. {
  260. IoWrite8 (
  261. R_PCH_RST_CNT,
  262. V_PCH_RST_CNT_HARDSTARTSTATE
  263. );
  264. IoWrite8 (
  265. R_PCH_RST_CNT,
  266. V_PCH_RST_CNT_HARDRESET
  267. );
  268. //
  269. // System reset occured, should never reach at this line.
  270. //
  271. ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
  272. CpuDeadLoop();
  273. return EFI_DEVICE_ERROR;
  274. }
  275. VOID
  276. PchPlatformLpcInit (
  277. IN CONST EFI_PEI_SERVICES **PeiServices,
  278. IN SYSTEM_CONFIGURATION *SystemConfiguration
  279. )
  280. {
  281. EFI_BOOT_MODE BootMode;
  282. UINT8 Data8;
  283. UINT16 Data16;
  284. (*PeiServices)->GetBootMode(PeiServices, &BootMode);
  285. if ((BootMode != BOOT_ON_S3_RESUME)) {
  286. //
  287. // Clear all pending SMI. On S3 clear power button enable so it wll not generate an SMI
  288. //
  289. ClearSmiAndWake ();
  290. }
  291. ClearPowerState (SystemConfiguration);
  292. //
  293. // Need to set and clear SET bit (RTC_REGB Bit 7) as requested by the ICH EDS
  294. // early in POST after each power up directly after coin-cell battery insertion.
  295. // This is to avoid the UIP bit (RTC_REGA Bit 7) from stuck at "1".
  296. // The UIP bit status may be polled by software (i.e ME FW) during POST.
  297. //
  298. if (MmioRead8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1) & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
  299. //
  300. // Set and clear SET bit in RTC_REGB
  301. //
  302. IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);
  303. Data8 = IoRead8(R_PCH_RTC_TARGET);
  304. Data8 |= B_PCH_RTC_REGISTERB_SET;
  305. IoWrite8(R_PCH_RTC_TARGET, Data8);
  306. IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);
  307. Data8 &= (~B_PCH_RTC_REGISTERB_SET);
  308. IoWrite8(R_PCH_RTC_TARGET, Data8);
  309. //
  310. // Clear the UIP bit in RTC_REGA
  311. //
  312. IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERA);
  313. IoWrite8(R_PCH_RTC_TARGET, 0x00);
  314. }
  315. //
  316. // Disable SERR NMI and IOCHK# NMI in port 61
  317. //
  318. Data8 = IoRead8 (R_PCH_NMI_SC);
  319. IoWrite8(R_PCH_NMI_SC, (UINT8) (Data8 | B_PCH_NMI_SC_PCI_SERR_EN | B_PCH_NMI_SC_IOCHK_NMI_EN));
  320. //
  321. // Enable Bus Master, I/O, Mem, and SERR on LPC bridge
  322. //
  323. Data16 = PchLpcPciCfg16 (R_PCH_LPC_COMMAND);
  324. MmioWrite16 (
  325. MmPciAddress (0,
  326. DEFAULT_PCI_BUS_NUMBER_PCH,
  327. PCI_DEVICE_NUMBER_PCH_LPC,
  328. PCI_FUNCTION_NUMBER_PCH_LPC,
  329. R_PCH_LPC_COMMAND
  330. ),
  331. (Data16 |
  332. B_PCH_LPC_COMMAND_IOSE |
  333. B_PCH_LPC_COMMAND_MSE |
  334. B_PCH_LPC_COMMAND_BME |
  335. B_PCH_LPC_COMMAND_SERR_EN)
  336. );
  337. //
  338. // Set Stretch S4 to 1-2s per marketing request.
  339. // Note: This register is powered by RTC well.
  340. //
  341. MmioAndThenOr8 (
  342. PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 ,
  343. (UINT8) (~B_PCH_PMC_GEN_PMCON_SLP_S4_MAW),
  344. (UINT8) (B_PCH_PMC_GEN_PMCON_SLP_S4_ASE | V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_4S)
  345. );
  346. }
  347. #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable
  348. VOID
  349. UARTInit (
  350. IN SYSTEM_CONFIGURATION *SystemConfiguration
  351. )
  352. {
  353. if (0) { // for fix cr4 issue
  354. //
  355. // Program and enable PMC Base.
  356. //
  357. IoWrite32 (0xCF8, PCI_LPC_REG(R_PCH_LPC_PMC_BASE));
  358. IoWrite32 (0xCFC, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN));
  359. if( (SystemConfiguration->PcuUart1 == 1) &&
  360. (SystemConfiguration->LpssHsuart0Enabled == 0)){
  361. //
  362. // Enable COM1 for debug message output.
  363. //
  364. MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, BIT24);
  365. //
  366. //Enable internal UART3 port(COM1)
  367. //
  368. MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
  369. MmioOr32 (IO_BASE_ADDRESS + 0x0520, 0x01); // UART3_RXD-L
  370. MmioOr32 (IO_BASE_ADDRESS + 0x0530, 0x01); // UART3_TXD-0
  371. MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN);
  372. } else {
  373. //
  374. //Disable UART3(COM1)
  375. //
  376. MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
  377. MmioAnd32 (IO_BASE_ADDRESS + 0x0520, ~(UINT32)0x07);
  378. MmioAnd32 (IO_BASE_ADDRESS + 0x0530, ~(UINT32)0x07);
  379. MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN);
  380. if (SystemConfiguration->LpssHsuart0Enabled == 1){
  381. //
  382. //Valleyview BIOS Specification Vol2,17.2
  383. //LPSS_UART1 C set each pad PAD_CONF0.Func_Pin_Mux to function 1:
  384. //
  385. MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07);
  386. MmioOr8 (IO_BASE_ADDRESS + 0x0090, 0x01);
  387. MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07);
  388. MmioOr8 (IO_BASE_ADDRESS + 0x00D0, 0x01);
  389. }
  390. }
  391. DEBUG ((EFI_D_ERROR, "EnableInternalUart\n"));
  392. } else {
  393. //
  394. // If SIO UART interface selected
  395. //Disable internal UART port(COM1)
  396. //
  397. if (0) {; // For fix CR4 issue
  398. MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
  399. MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07);
  400. MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07);
  401. MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN);
  402. }
  403. }
  404. }
  405. VOID
  406. IchRcrbInit (
  407. IN CONST EFI_PEI_SERVICES **PeiServices,
  408. IN SYSTEM_CONFIGURATION *SystemConfiguration
  409. )
  410. {
  411. EFI_BOOT_MODE BootMode;
  412. (*PeiServices)->GetBootMode(PeiServices, &BootMode);
  413. //
  414. // If not recovery or flash update boot path. set the BIOS interface lock down bit.
  415. // It locks the top swap bit and BIOS boot strap bits from being changed.
  416. //
  417. if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
  418. MmioOr8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS, B_PCH_RCRB_GCS_BILD);
  419. }
  420. //
  421. // Disable the Watchdog timer expiration from causing a system reset
  422. //
  423. MmioOr8 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG, B_PCH_PMC_PM_CFG_NO_REBOOT);
  424. //
  425. // Initial RCBA according to the PeiRCBA table
  426. //
  427. if (BootMode == BOOT_ON_S3_RESUME) {
  428. //
  429. // We are resuming from S3
  430. // Enable HPET if enabled in Setup
  431. // ICH Config register Offset 0x3404 bit 7 (Enable) = 1,
  432. // Bit 1:0 (Mem I/O address) = 0 (0xFED00000)
  433. //
  434. MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);
  435. }
  436. }
  437. EFI_STATUS
  438. PlatformPchInit (
  439. IN SYSTEM_CONFIGURATION *SystemConfiguration,
  440. IN CONST EFI_PEI_SERVICES **PeiServices,
  441. IN UINT16 PlatformType
  442. )
  443. {
  444. EFI_STATUS Status;
  445. EFI_BOOT_MODE BootMode;
  446. Status = PeiServicesGetBootMode (&BootMode);
  447. ASSERT_EFI_ERROR (Status);
  448. IchRcrbInit (PeiServices, SystemConfiguration);
  449. if (BootMode == BOOT_IN_RECOVERY_MODE) {
  450. InstallPeiPchUsbPolicy(PeiServices);
  451. }
  452. //
  453. // PCH Policy Initialization based on Setup variable.
  454. //
  455. PchPolicySetupInit (PeiServices, SystemConfiguration);
  456. UARTInit(SystemConfiguration);
  457. PchPlatformLpcInit (PeiServices, SystemConfiguration);
  458. return EFI_SUCCESS;
  459. }
  460. /**
  461. Returns the state of A16 inversion
  462. @retval TRUE A16 is inverted
  463. @retval FALSE A16 is not inverted
  464. **/
  465. BOOLEAN
  466. IsA16Inverted (
  467. )
  468. {
  469. UINT8 Data;
  470. Data = MmioRead8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS);
  471. return (Data & B_PCH_RCRB_GCS_TS) ? TRUE : FALSE;
  472. }
  473. VOID
  474. PchPolicySetupInit (
  475. IN CONST EFI_PEI_SERVICES **PeiServices,
  476. IN SYSTEM_CONFIGURATION *SystemConfiguration
  477. )
  478. {
  479. EFI_STATUS Status;
  480. EFI_PEI_PPI_DESCRIPTOR *PchPlatformPolicyPpiDesc;
  481. PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi;
  482. PCH_HPET_CONFIG *HpetConfig;
  483. PCH_PCIE_CONFIG *PcieConfig;
  484. UINT8 Index;
  485. PCH_IOAPIC_CONFIG *IoApicConfig;
  486. PCH_LPSS_CONFIG *LpssConfig;
  487. UINT32 SpiHsfsReg;
  488. UINT32 SpiFdodReg;
  489. //
  490. // Disable codec ALC-262
  491. //
  492. UINT32 IoBase;
  493. //
  494. // Install Pch Platform Policy PPI. As we depend on Pch Init PPI so we are executed after
  495. // PchInit PEIM. Thus we can insure PCH Initialization is performed when we install the Pch Platform Policy PPI,
  496. // as PchInit PEIM registered a notification function on our policy PPI.
  497. //
  498. // --cr-- For better code structure / modularity, we should use a notification function on Pch Init PPI to perform
  499. // actions that depend on PchInit PEIM's initialization.
  500. //
  501. //Todo: confirm if we need update to PCH_PLATFORM_POLICY_PPI_REVISION_5
  502. //
  503. DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - Start\n"));
  504. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), (void **)&PchPlatformPolicyPpiDesc);
  505. ASSERT_EFI_ERROR (Status);
  506. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PLATFORM_POLICY_PPI), (void **)&PchPlatformPolicyPpi);
  507. ASSERT_EFI_ERROR (Status);
  508. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_HPET_CONFIG), (void **)&HpetConfig);
  509. ASSERT_EFI_ERROR (Status);
  510. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PCIE_CONFIG), (void **)&PcieConfig);
  511. ASSERT_EFI_ERROR (Status);
  512. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_IOAPIC_CONFIG), (void **)&IoApicConfig);
  513. ASSERT_EFI_ERROR (Status);
  514. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_LPSS_CONFIG), (void **)&LpssConfig);
  515. ASSERT_EFI_ERROR (Status);
  516. PchPlatformPolicyPpi->Revision = PCH_PLATFORM_POLICY_PPI_REVISION_1;
  517. PchPlatformPolicyPpi->BusNumber = DEFAULT_PCI_BUS_NUMBER_PCH;
  518. PchPlatformPolicyPpi->SpiBase = SPI_BASE_ADDRESS;
  519. PchPlatformPolicyPpi->PmcBase = PMC_BASE_ADDRESS;
  520. PchPlatformPolicyPpi->IoBase = IO_BASE_ADDRESS;
  521. PchPlatformPolicyPpi->IlbBase = ILB_BASE_ADDRESS;
  522. PchPlatformPolicyPpi->PUnitBase = PUNIT_BASE_ADDRESS;
  523. PchPlatformPolicyPpi->MphyBase = MPHY_BASE_ADDRESS;
  524. PchPlatformPolicyPpi->Rcba = RCBA_BASE_ADDRESS;
  525. PchPlatformPolicyPpi->AcpiBase = ACPI_BASE_ADDRESS;
  526. PchPlatformPolicyPpi->GpioBase = GPIO_BASE_ADDRESS;
  527. PchPlatformPolicyPpi->SataMode = SystemConfiguration->SataType;
  528. PchPlatformPolicyPpi->EnableRmh = SystemConfiguration->PchUsbRmh;
  529. PchPlatformPolicyPpi->EhciPllCfgEnable = SystemConfiguration->EhciPllCfgEnable;
  530. PchPlatformPolicyPpi->HpetConfig = HpetConfig;
  531. PchPlatformPolicyPpi->PcieConfig = PcieConfig;
  532. PchPlatformPolicyPpi->IoApicConfig = IoApicConfig;
  533. PchPlatformPolicyPpi->HpetConfig->Enable = SystemConfiguration->Hpet;
  534. PchPlatformPolicyPpi->HpetConfig->Base = HPET_BASE_ADDRESS;
  535. PchPlatformPolicyPpi->IoApicConfig->IoApicId = 0x01;
  536. //
  537. // Set LPSS configuration according to setup value.
  538. //
  539. PchPlatformPolicyPpi->LpssConfig->LpssPciModeEnabled = SystemConfiguration->LpssPciModeEnabled;
  540. PchPlatformPolicyPpi->LpssConfig->Dma1Enabled = SystemConfiguration->LpssDma1Enabled;
  541. PchPlatformPolicyPpi->LpssConfig->I2C0Enabled = SystemConfiguration->LpssI2C0Enabled;
  542. PchPlatformPolicyPpi->LpssConfig->I2C1Enabled = SystemConfiguration->LpssI2C1Enabled;
  543. PchPlatformPolicyPpi->LpssConfig->I2C2Enabled = SystemConfiguration->LpssI2C2Enabled;
  544. PchPlatformPolicyPpi->LpssConfig->I2C3Enabled = SystemConfiguration->LpssI2C3Enabled;
  545. PchPlatformPolicyPpi->LpssConfig->I2C4Enabled = SystemConfiguration->LpssI2C4Enabled;
  546. PchPlatformPolicyPpi->LpssConfig->I2C5Enabled = SystemConfiguration->LpssI2C5Enabled;
  547. PchPlatformPolicyPpi->LpssConfig->I2C6Enabled = SystemConfiguration->LpssI2C6Enabled;
  548. PchPlatformPolicyPpi->LpssConfig->Dma0Enabled = SystemConfiguration->LpssDma0Enabled;;
  549. PchPlatformPolicyPpi->LpssConfig->Pwm0Enabled = SystemConfiguration->LpssPwm0Enabled;
  550. PchPlatformPolicyPpi->LpssConfig->Pwm1Enabled = SystemConfiguration->LpssPwm1Enabled;
  551. PchPlatformPolicyPpi->LpssConfig->Hsuart0Enabled = SystemConfiguration->LpssHsuart0Enabled;
  552. PchPlatformPolicyPpi->LpssConfig->Hsuart1Enabled = SystemConfiguration->LpssHsuart1Enabled;
  553. PchPlatformPolicyPpi->LpssConfig->SpiEnabled = SystemConfiguration->LpssSpiEnabled;
  554. for (Index = 0; Index < PCH_PCIE_MAX_ROOT_PORTS; Index++) {
  555. PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index] = SystemConfiguration->PcieRootPortSpeed[Index];
  556. }
  557. SpiHsfsReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_HSFS);
  558. if ((SpiHsfsReg & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) {
  559. MmioWrite32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOC, V_PCH_SPI_FDOC_FDSS_FSDM);
  560. SpiFdodReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOD);
  561. if (SpiFdodReg == V_PCH_SPI_FDBAR_FLVALSIG) {
  562. }
  563. //
  564. // Disable codec ALC-262
  565. //
  566. if (SystemConfiguration->DisableCodec262 == 1) {
  567. IoBase = MmioRead32 (MmPciAddress (0,
  568. PchPlatformPolicyPpi->BusNumber,
  569. PCI_DEVICE_NUMBER_PCH_LPC,
  570. PCI_FUNCTION_NUMBER_PCH_LPC,
  571. 0
  572. ) + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR;
  573. MmioAnd32 ((UINTN) (IoBase + 0x270), (UINT32) (~0x07));
  574. }
  575. }
  576. PchPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
  577. PchPlatformPolicyPpiDesc->Guid = &gPchPlatformPolicyPpiGuid;
  578. PchPlatformPolicyPpiDesc->Ppi = PchPlatformPolicyPpi;
  579. //
  580. // Install PCH Platform Policy PPI
  581. //
  582. Status = (**PeiServices).InstallPpi (
  583. PeiServices,
  584. PchPlatformPolicyPpiDesc
  585. );
  586. ASSERT_EFI_ERROR (Status);
  587. DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - End\n"));
  588. }
  589. EFI_STATUS
  590. InstallPeiPchUsbPolicy (
  591. IN CONST EFI_PEI_SERVICES **PeiServices
  592. )
  593. {
  594. EFI_STATUS Status = EFI_SUCCESS;
  595. EFI_PEI_PPI_DESCRIPTOR *PeiPchUsbPolicyPpiDesc;
  596. PCH_USB_POLICY_PPI *PeiPchUsbPolicyPpi;
  597. PCH_USB_CONFIG *UsbConfig;
  598. DEBUG ((EFI_D_INFO, "InstallPeiPchUsbPolicy...\n"));
  599. //
  600. // Allocate descriptor and PPI structures. Since these are dynamically updated
  601. // we cannot do a global variable PPI.
  602. //
  603. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), (void **)&PeiPchUsbPolicyPpiDesc);
  604. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_POLICY_PPI), (void **)&PeiPchUsbPolicyPpi);
  605. Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_CONFIG), (void **)&UsbConfig);
  606. //
  607. // Initiate PCH USB policy.
  608. //
  609. PeiPchUsbPolicyPpi->Revision = PCH_USB_POLICY_PPI_REVISION_1;
  610. UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_ENABLE;
  611. UsbConfig->UsbPerPortCtl = PCH_DEVICE_DISABLE;
  612. UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE;
  613. UsbConfig->Usb20OverCurrentPins[0] = PchUsbOverCurrentPin0;
  614. UsbConfig->Usb20OverCurrentPins[1] = PchUsbOverCurrentPin0;
  615. UsbConfig->Usb20OverCurrentPins[2] = PchUsbOverCurrentPin1;
  616. UsbConfig->Usb20OverCurrentPins[3] = PchUsbOverCurrentPin1;
  617. //
  618. // Enable USB Topology control and program the topology setting for every USB port
  619. // See Platform Design Guide for description of topologies
  620. //
  621. //
  622. // Port 0: ~10.9", Port 1: ~10.1", Port 2: ~11.2", Port 3: ~11.5", Port 4: ~3.7", Port 5: ~2.7", Port 6: ~4.1"
  623. // Port 7: ~4.5", Port 8: ~10.7", Port 9: ~10.5", Port 10: ~4.2", Port 11: ~4.3", Port 12: ~3.1", Port 13: ~2.9"
  624. //
  625. //
  626. // Port 0: ~3.5", Port 1: ~4.1", Port 2: ~4.6", Port 3: ~4.6", Port 4: ~12.5", Port 5: ~12", Port 6: ~5.1"
  627. // Port 7: ~5.1", Port 8: ~4.1", Port 9: ~4.1", Port 10: ~14.5", Port 11: ~12.8", Port 12: ~12.9", Port 13: ~14.6"
  628. //
  629. UsbConfig->Usb20PortLength[0] = 0x53;
  630. UsbConfig->Usb20PortLength[1] = 0x49;
  631. UsbConfig->Usb20PortLength[2] = 0x47;
  632. UsbConfig->Usb20PortLength[3] = 0x80;
  633. PeiPchUsbPolicyPpi->Mode = EHCI_MODE;
  634. PeiPchUsbPolicyPpi->EhciMemBaseAddr = PcdGet32(PcdPeiIchEhciControllerMemoryBaseAddress);
  635. PeiPchUsbPolicyPpi->EhciMemLength = (UINT32) 0x400 * PchEhciControllerMax;
  636. PeiPchUsbPolicyPpi->XhciMemBaseAddr = 0;
  637. PeiPchUsbPolicyPpi->UsbConfig = UsbConfig;
  638. PeiPchUsbPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
  639. PeiPchUsbPolicyPpiDesc->Guid = &gPchUsbPolicyPpiGuid;
  640. PeiPchUsbPolicyPpiDesc->Ppi = PeiPchUsbPolicyPpi;
  641. //
  642. // Install PCH USB Policy PPI
  643. //
  644. Status = (**PeiServices).InstallPpi (PeiServices, PeiPchUsbPolicyPpiDesc);
  645. return Status;
  646. }