/** @file Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent Module Name: PchInitPeim.c Abstract: Do Early PCH platform initialization. --*/ #include "PlatformEarlyInit.h" #include "Ppi/PchPlatformPolicy.h" #include "PchRegs.h" #include #include "Ppi/PchInit.h" #include EFI_GUID gPchPlatformPolicyPpiGuid = PCH_PLATFORM_POLICY_PPI_GUID; #define MC_PMSTS_OFFSET 0xC #define DEFAULT_BUS_INFO 0x2020 #define PCI_LPC_BASE (0x8000F800) #define PCI_LPC_REG(x) (PCI_LPC_BASE + (x)) #define PCIEX_BASE_ADDRESS 0xE0000000 #define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15) VOID PchPolicySetupInit ( IN CONST EFI_PEI_SERVICES **PeiServices, IN SYSTEM_CONFIGURATION *SystemConfiguration ); VOID PchInitInterrupt ( IN SYSTEM_CONFIGURATION *SystemConfiguration ); EFI_STATUS InstallPeiPchUsbPolicy ( IN CONST EFI_PEI_SERVICES **PeiServices ); #ifndef __GNUC__ #pragma warning (push) #pragma warning (disable : 4245) #pragma warning (pop) #endif UINT8 ReadCmosBank1Byte ( IN UINT8 Address ) { UINT8 Data; IoWrite8(R_PCH_RTC_EXT_INDEX, Address); Data = IoRead8 (R_PCH_RTC_EXT_TARGET); return Data; } VOID WriteCmosBank1Byte ( IN UINT8 Address, IN UINT8 Data ) { IoWrite8(R_PCH_RTC_EXT_INDEX, Address); IoWrite8(R_PCH_RTC_EXT_TARGET, Data); } /** Turn off system if needed. @retval None. **/ VOID CheckPowerOffNow ( VOID ) { UINT16 Pm1Sts; // // Read and check the ACPI registers // Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS); if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) == B_PCH_ACPI_PM1_STS_PWRBTN) { IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN); IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5); IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5 + B_PCH_ACPI_PM1_CNT_SLP_EN); // // Should not return // CpuDeadLoop(); } } VOID ClearPowerState ( IN SYSTEM_CONFIGURATION *SystemConfiguration ) { UINT8 Data8; UINT16 Data16; UINT32 Data32; // // Check for PowerState option for AC power loss and program the chipset // // // Clear PWROK (Set to Clear) // MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_PWROK_FLR); // // Clear Power Failure Bit (Set to Clear) // // TODO: Check if it is OK to clear here // MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR); // // Clear the GPE and PM enable // IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_EN, (UINT16) 0x00); IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_EN, (UINT32) 0x00); // // Halt the TCO timer // Data16 = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT); Data16 |= B_PCH_TCO_CNT_TMR_HLT; IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT, Data16); // // if NMI_NOW_STS is set // NMI NOW bit is "Write '1' to clear" // Data8 = MmioRead8(ILB_BASE_ADDRESS + R_PCH_ILB_GNMI); if ((Data8 & B_PCH_ILB_GNMI_NMINS) == B_PCH_ILB_GNMI_NMINS) { MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_GNMI, B_PCH_ILB_GNMI_NMIN); } // // Before we clear the TO status bit here we need to save the results in a CMOS bit for later use. // Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS); if ((Data32 & B_PCH_TCO_STS_SECOND_TO) == B_PCH_TCO_STS_SECOND_TO) { #if (defined(HW_WATCHDOG_TIMER_SUPPORT) && (HW_WATCHDOG_TIMER_SUPPORT != 0)) WriteCmosBank1Byte ( EFI_CMOS_PERFORMANCE_FLAGS, ReadCmosBank1Byte (EFI_CMOS_PERFORMANCE_FLAGS) | B_CMOS_TCO_WDT_RESET ); #endif } } /*++ Clear any SMI status or wake status left over from boot. **/ VOID ClearSmiAndWake ( VOID ) { UINT16 Pm1Sts; UINT32 Gpe0Sts; UINT32 SmiSts; // // Read the ACPI registers // Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS); Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS); SmiSts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS); // // Register Wake up reason for S4. This information is used to notify // WinXp of wake up reason because S4 wake up path doesn't keep SCI. // This is important for Viiv(Quick resume) platform. // // // First Clear CMOS S4 Wake up flag. // WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 0); // // Check wake up reason and set CMOS accordingly. Currently checks // Power button, USB, PS/2. // Note : PS/2 wake up is using GPI13 (IO_PME). This must be changed depending // on board design. // if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) || (Gpe0Sts & (B_PCH_ACPI_GPE0a_STS_CORE_GPIO | B_PCH_ACPI_GPE0a_STS_SUS_GPIO))) { WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 1); } // // Clear any SMI or wake state from the boot // Pm1Sts = (B_PCH_ACPI_PM1_STS_PRBTNOR | B_PCH_ACPI_PM1_STS_PWRBTN); Gpe0Sts |= ( B_PCH_ACPI_GPE0a_STS_CORE_GPIO | B_PCH_ACPI_GPE0a_STS_SUS_GPIO | B_PCH_ACPI_GPE0a_STS_PME_B0 | B_PCH_ACPI_GPE0a_STS_BATLOW | B_PCH_ACPI_GPE0a_STS_PCI_EXP | B_PCH_ACPI_GPE0a_STS_GUNIT_SCI | B_PCH_ACPI_GPE0a_STS_PUNIT_SCI | B_PCH_ACPI_GPE0a_STS_SWGPE | B_PCH_ACPI_GPE0a_STS_HOT_PLUG ); SmiSts |= ( B_PCH_SMI_STS_SMBUS | B_PCH_SMI_STS_PERIODIC | B_PCH_SMI_STS_TCO | B_PCH_SMI_STS_SWSMI_TMR | B_PCH_SMI_STS_APM | B_PCH_SMI_STS_ON_SLP_EN | B_PCH_SMI_STS_BIOS ); // // Write them back // IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, Pm1Sts); IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS, Gpe0Sts); IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS, SmiSts); } /** Issue PCI-E Secondary Bus Reset @param Bus Bus number of the bridge @param Dev Devices number of the bridge @param Fun Function number of the bridge @retval EFI_SUCCESS **/ EFI_STATUS PcieSecondaryBusReset ( IN CONST EFI_PEI_SERVICES **PeiServices, IN UINT8 Bus, IN UINT8 Dev, IN UINT8 Fun ) { EFI_PEI_STALL_PPI *PeiStall; EFI_STATUS Status; Status = (**PeiServices).LocatePpi ( PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (void **)&PeiStall ); ASSERT_EFI_ERROR (Status); // // Issue secondary bus reset // MmPci16Or(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS); // // Wait 1ms // PeiStall->Stall (PeiServices, PeiStall, 1000); // // Clear the reset bit // Note: The PCIe spec suggests 100ms delay between clearing this bit and accessing // the device's config space. Since we will not access the config space until we enter DXE // we don't put delay expressly here. // MmPci16And(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, ~(EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS)); return EFI_SUCCESS; } /** Provide hard reset PPI service. To generate full hard reset, write 0x0E to ICH RESET_GENERATOR_PORT (0xCF9). @param PeiServices General purpose services available to every PEIM. @retval Not return System reset occured. @retval EFI_DEVICE_ERROR Device error, could not reset the system. **/ EFI_STATUS EFIAPI IchReset ( IN CONST EFI_PEI_SERVICES **PeiServices ) { IoWrite8 ( R_PCH_RST_CNT, V_PCH_RST_CNT_HARDSTARTSTATE ); IoWrite8 ( R_PCH_RST_CNT, V_PCH_RST_CNT_HARDRESET ); // // System reset occured, should never reach at this line. // ASSERT_EFI_ERROR (EFI_DEVICE_ERROR); CpuDeadLoop(); return EFI_DEVICE_ERROR; } VOID PchPlatformLpcInit ( IN CONST EFI_PEI_SERVICES **PeiServices, IN SYSTEM_CONFIGURATION *SystemConfiguration ) { EFI_BOOT_MODE BootMode; UINT8 Data8; UINT16 Data16; (*PeiServices)->GetBootMode(PeiServices, &BootMode); if ((BootMode != BOOT_ON_S3_RESUME)) { // // Clear all pending SMI. On S3 clear power button enable so it wll not generate an SMI // ClearSmiAndWake (); } ClearPowerState (SystemConfiguration); // // Need to set and clear SET bit (RTC_REGB Bit 7) as requested by the ICH EDS // early in POST after each power up directly after coin-cell battery insertion. // This is to avoid the UIP bit (RTC_REGA Bit 7) from stuck at "1". // The UIP bit status may be polled by software (i.e ME FW) during POST. // if (MmioRead8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1) & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) { // // Set and clear SET bit in RTC_REGB // IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB); Data8 = IoRead8(R_PCH_RTC_TARGET); Data8 |= B_PCH_RTC_REGISTERB_SET; IoWrite8(R_PCH_RTC_TARGET, Data8); IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB); Data8 &= (~B_PCH_RTC_REGISTERB_SET); IoWrite8(R_PCH_RTC_TARGET, Data8); // // Clear the UIP bit in RTC_REGA // IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERA); IoWrite8(R_PCH_RTC_TARGET, 0x00); } // // Disable SERR NMI and IOCHK# NMI in port 61 // Data8 = IoRead8 (R_PCH_NMI_SC); IoWrite8(R_PCH_NMI_SC, (UINT8) (Data8 | B_PCH_NMI_SC_PCI_SERR_EN | B_PCH_NMI_SC_IOCHK_NMI_EN)); // // Enable Bus Master, I/O, Mem, and SERR on LPC bridge // Data16 = PchLpcPciCfg16 (R_PCH_LPC_COMMAND); MmioWrite16 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_COMMAND ), (Data16 | B_PCH_LPC_COMMAND_IOSE | B_PCH_LPC_COMMAND_MSE | B_PCH_LPC_COMMAND_BME | B_PCH_LPC_COMMAND_SERR_EN) ); // // Set Stretch S4 to 1-2s per marketing request. // Note: This register is powered by RTC well. // MmioAndThenOr8 ( PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 , (UINT8) (~B_PCH_PMC_GEN_PMCON_SLP_S4_MAW), (UINT8) (B_PCH_PMC_GEN_PMCON_SLP_S4_ASE | V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_4S) ); } #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable VOID UARTInit ( IN SYSTEM_CONFIGURATION *SystemConfiguration ) { if (0) { // for fix cr4 issue // // Program and enable PMC Base. // IoWrite32 (0xCF8, PCI_LPC_REG(R_PCH_LPC_PMC_BASE)); IoWrite32 (0xCFC, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN)); if( (SystemConfiguration->PcuUart1 == 1) && (SystemConfiguration->LpssHsuart0Enabled == 0)){ // // Enable COM1 for debug message output. // MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, BIT24); // //Enable internal UART3 port(COM1) // MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3); MmioOr32 (IO_BASE_ADDRESS + 0x0520, 0x01); // UART3_RXD-L MmioOr32 (IO_BASE_ADDRESS + 0x0530, 0x01); // UART3_TXD-0 MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN); } else { // //Disable UART3(COM1) // MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3); MmioAnd32 (IO_BASE_ADDRESS + 0x0520, ~(UINT32)0x07); MmioAnd32 (IO_BASE_ADDRESS + 0x0530, ~(UINT32)0x07); MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN); if (SystemConfiguration->LpssHsuart0Enabled == 1){ // //Valleyview BIOS Specification Vol2,17.2 //LPSS_UART1 C set each pad PAD_CONF0.Func_Pin_Mux to function 1: // MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07); MmioOr8 (IO_BASE_ADDRESS + 0x0090, 0x01); MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07); MmioOr8 (IO_BASE_ADDRESS + 0x00D0, 0x01); } } DEBUG ((EFI_D_ERROR, "EnableInternalUart\n")); } else { // // If SIO UART interface selected //Disable internal UART port(COM1) // if (0) {; // For fix CR4 issue MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3); MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07); MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07); MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN); } } } VOID IchRcrbInit ( IN CONST EFI_PEI_SERVICES **PeiServices, IN SYSTEM_CONFIGURATION *SystemConfiguration ) { EFI_BOOT_MODE BootMode; (*PeiServices)->GetBootMode(PeiServices, &BootMode); // // If not recovery or flash update boot path. set the BIOS interface lock down bit. // It locks the top swap bit and BIOS boot strap bits from being changed. // if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode != BOOT_ON_FLASH_UPDATE)) { MmioOr8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS, B_PCH_RCRB_GCS_BILD); } // // Disable the Watchdog timer expiration from causing a system reset // MmioOr8 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG, B_PCH_PMC_PM_CFG_NO_REBOOT); // // Initial RCBA according to the PeiRCBA table // if (BootMode == BOOT_ON_S3_RESUME) { // // We are resuming from S3 // Enable HPET if enabled in Setup // ICH Config register Offset 0x3404 bit 7 (Enable) = 1, // Bit 1:0 (Mem I/O address) = 0 (0xFED00000) // MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN); } } EFI_STATUS PlatformPchInit ( IN SYSTEM_CONFIGURATION *SystemConfiguration, IN CONST EFI_PEI_SERVICES **PeiServices, IN UINT16 PlatformType ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); IchRcrbInit (PeiServices, SystemConfiguration); if (BootMode == BOOT_IN_RECOVERY_MODE) { InstallPeiPchUsbPolicy(PeiServices); } // // PCH Policy Initialization based on Setup variable. // PchPolicySetupInit (PeiServices, SystemConfiguration); UARTInit(SystemConfiguration); PchPlatformLpcInit (PeiServices, SystemConfiguration); return EFI_SUCCESS; } /** Returns the state of A16 inversion @retval TRUE A16 is inverted @retval FALSE A16 is not inverted **/ BOOLEAN IsA16Inverted ( ) { UINT8 Data; Data = MmioRead8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS); return (Data & B_PCH_RCRB_GCS_TS) ? TRUE : FALSE; } VOID PchPolicySetupInit ( IN CONST EFI_PEI_SERVICES **PeiServices, IN SYSTEM_CONFIGURATION *SystemConfiguration ) { EFI_STATUS Status; EFI_PEI_PPI_DESCRIPTOR *PchPlatformPolicyPpiDesc; PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi; PCH_HPET_CONFIG *HpetConfig; PCH_PCIE_CONFIG *PcieConfig; UINT8 Index; PCH_IOAPIC_CONFIG *IoApicConfig; PCH_LPSS_CONFIG *LpssConfig; UINT32 SpiHsfsReg; UINT32 SpiFdodReg; // // Disable codec ALC-262 // UINT32 IoBase; // // Install Pch Platform Policy PPI. As we depend on Pch Init PPI so we are executed after // PchInit PEIM. Thus we can insure PCH Initialization is performed when we install the Pch Platform Policy PPI, // as PchInit PEIM registered a notification function on our policy PPI. // // --cr-- For better code structure / modularity, we should use a notification function on Pch Init PPI to perform // actions that depend on PchInit PEIM's initialization. // //Todo: confirm if we need update to PCH_PLATFORM_POLICY_PPI_REVISION_5 // DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - Start\n")); Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), (void **)&PchPlatformPolicyPpiDesc); ASSERT_EFI_ERROR (Status); Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PLATFORM_POLICY_PPI), (void **)&PchPlatformPolicyPpi); ASSERT_EFI_ERROR (Status); Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_HPET_CONFIG), (void **)&HpetConfig); ASSERT_EFI_ERROR (Status); Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PCIE_CONFIG), (void **)&PcieConfig); ASSERT_EFI_ERROR (Status); Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_IOAPIC_CONFIG), (void **)&IoApicConfig); ASSERT_EFI_ERROR (Status); Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_LPSS_CONFIG), (void **)&LpssConfig); ASSERT_EFI_ERROR (Status); PchPlatformPolicyPpi->Revision = PCH_PLATFORM_POLICY_PPI_REVISION_1; PchPlatformPolicyPpi->BusNumber = DEFAULT_PCI_BUS_NUMBER_PCH; PchPlatformPolicyPpi->SpiBase = SPI_BASE_ADDRESS; PchPlatformPolicyPpi->PmcBase = PMC_BASE_ADDRESS; PchPlatformPolicyPpi->IoBase = IO_BASE_ADDRESS; PchPlatformPolicyPpi->IlbBase = ILB_BASE_ADDRESS; PchPlatformPolicyPpi->PUnitBase = PUNIT_BASE_ADDRESS; PchPlatformPolicyPpi->MphyBase = MPHY_BASE_ADDRESS; PchPlatformPolicyPpi->Rcba = RCBA_BASE_ADDRESS; PchPlatformPolicyPpi->AcpiBase = ACPI_BASE_ADDRESS; PchPlatformPolicyPpi->GpioBase = GPIO_BASE_ADDRESS; PchPlatformPolicyPpi->SataMode = SystemConfiguration->SataType; PchPlatformPolicyPpi->EnableRmh = SystemConfiguration->PchUsbRmh; PchPlatformPolicyPpi->EhciPllCfgEnable = SystemConfiguration->EhciPllCfgEnable; PchPlatformPolicyPpi->HpetConfig = HpetConfig; PchPlatformPolicyPpi->PcieConfig = PcieConfig; PchPlatformPolicyPpi->IoApicConfig = IoApicConfig; PchPlatformPolicyPpi->HpetConfig->Enable = SystemConfiguration->Hpet; PchPlatformPolicyPpi->HpetConfig->Base = HPET_BASE_ADDRESS; PchPlatformPolicyPpi->IoApicConfig->IoApicId = 0x01; // // Set LPSS configuration according to setup value. // PchPlatformPolicyPpi->LpssConfig->LpssPciModeEnabled = SystemConfiguration->LpssPciModeEnabled; PchPlatformPolicyPpi->LpssConfig->Dma1Enabled = SystemConfiguration->LpssDma1Enabled; PchPlatformPolicyPpi->LpssConfig->I2C0Enabled = SystemConfiguration->LpssI2C0Enabled; PchPlatformPolicyPpi->LpssConfig->I2C1Enabled = SystemConfiguration->LpssI2C1Enabled; PchPlatformPolicyPpi->LpssConfig->I2C2Enabled = SystemConfiguration->LpssI2C2Enabled; PchPlatformPolicyPpi->LpssConfig->I2C3Enabled = SystemConfiguration->LpssI2C3Enabled; PchPlatformPolicyPpi->LpssConfig->I2C4Enabled = SystemConfiguration->LpssI2C4Enabled; PchPlatformPolicyPpi->LpssConfig->I2C5Enabled = SystemConfiguration->LpssI2C5Enabled; PchPlatformPolicyPpi->LpssConfig->I2C6Enabled = SystemConfiguration->LpssI2C6Enabled; PchPlatformPolicyPpi->LpssConfig->Dma0Enabled = SystemConfiguration->LpssDma0Enabled;; PchPlatformPolicyPpi->LpssConfig->Pwm0Enabled = SystemConfiguration->LpssPwm0Enabled; PchPlatformPolicyPpi->LpssConfig->Pwm1Enabled = SystemConfiguration->LpssPwm1Enabled; PchPlatformPolicyPpi->LpssConfig->Hsuart0Enabled = SystemConfiguration->LpssHsuart0Enabled; PchPlatformPolicyPpi->LpssConfig->Hsuart1Enabled = SystemConfiguration->LpssHsuart1Enabled; PchPlatformPolicyPpi->LpssConfig->SpiEnabled = SystemConfiguration->LpssSpiEnabled; for (Index = 0; Index < PCH_PCIE_MAX_ROOT_PORTS; Index++) { PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index] = SystemConfiguration->PcieRootPortSpeed[Index]; } SpiHsfsReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_HSFS); if ((SpiHsfsReg & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) { MmioWrite32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOC, V_PCH_SPI_FDOC_FDSS_FSDM); SpiFdodReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOD); if (SpiFdodReg == V_PCH_SPI_FDBAR_FLVALSIG) { } // // Disable codec ALC-262 // if (SystemConfiguration->DisableCodec262 == 1) { IoBase = MmioRead32 (MmPciAddress (0, PchPlatformPolicyPpi->BusNumber, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0 ) + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR; MmioAnd32 ((UINTN) (IoBase + 0x270), (UINT32) (~0x07)); } } PchPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; PchPlatformPolicyPpiDesc->Guid = &gPchPlatformPolicyPpiGuid; PchPlatformPolicyPpiDesc->Ppi = PchPlatformPolicyPpi; // // Install PCH Platform Policy PPI // Status = (**PeiServices).InstallPpi ( PeiServices, PchPlatformPolicyPpiDesc ); ASSERT_EFI_ERROR (Status); DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - End\n")); } EFI_STATUS InstallPeiPchUsbPolicy ( IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status = EFI_SUCCESS; EFI_PEI_PPI_DESCRIPTOR *PeiPchUsbPolicyPpiDesc; PCH_USB_POLICY_PPI *PeiPchUsbPolicyPpi; PCH_USB_CONFIG *UsbConfig; DEBUG ((EFI_D_INFO, "InstallPeiPchUsbPolicy...\n")); // // Allocate descriptor and PPI structures. Since these are dynamically updated // we cannot do a global variable PPI. // Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), (void **)&PeiPchUsbPolicyPpiDesc); Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_POLICY_PPI), (void **)&PeiPchUsbPolicyPpi); Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_CONFIG), (void **)&UsbConfig); // // Initiate PCH USB policy. // PeiPchUsbPolicyPpi->Revision = PCH_USB_POLICY_PPI_REVISION_1; UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_ENABLE; UsbConfig->UsbPerPortCtl = PCH_DEVICE_DISABLE; UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE; UsbConfig->Usb20OverCurrentPins[0] = PchUsbOverCurrentPin0; UsbConfig->Usb20OverCurrentPins[1] = PchUsbOverCurrentPin0; UsbConfig->Usb20OverCurrentPins[2] = PchUsbOverCurrentPin1; UsbConfig->Usb20OverCurrentPins[3] = PchUsbOverCurrentPin1; // // Enable USB Topology control and program the topology setting for every USB port // See Platform Design Guide for description of topologies // // // 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" // 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" // // // 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" // 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" // UsbConfig->Usb20PortLength[0] = 0x53; UsbConfig->Usb20PortLength[1] = 0x49; UsbConfig->Usb20PortLength[2] = 0x47; UsbConfig->Usb20PortLength[3] = 0x80; PeiPchUsbPolicyPpi->Mode = EHCI_MODE; PeiPchUsbPolicyPpi->EhciMemBaseAddr = PcdGet32(PcdPeiIchEhciControllerMemoryBaseAddress); PeiPchUsbPolicyPpi->EhciMemLength = (UINT32) 0x400 * PchEhciControllerMax; PeiPchUsbPolicyPpi->XhciMemBaseAddr = 0; PeiPchUsbPolicyPpi->UsbConfig = UsbConfig; PeiPchUsbPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; PeiPchUsbPolicyPpiDesc->Guid = &gPchUsbPolicyPpiGuid; PeiPchUsbPolicyPpiDesc->Ppi = PeiPchUsbPolicyPpi; // // Install PCH USB Policy PPI // Status = (**PeiServices).InstallPpi (PeiServices, PeiPchUsbPolicyPpiDesc); return Status; }