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