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