Home | History | Annotate | Download | only in PlatformInitPei
      1 /** @file
      2 
      3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      9   The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     13 
     15   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     19 
     21 
     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
     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   )
     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 /**
     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
    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
    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).
    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 ,
    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);
    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)
    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 
    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 (
    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