/** @file Source code file for Platform Init Pre-Memory PEI module Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** Early Silicon initialization **/ VOID EarlySiliconInit ( VOID ) { UINT16 Data16; UINT8 Data8; UINTN LpcBaseAddress; UINTN P2sbBase; LpcBaseAddress = MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC ); /// /// Program bar /// P2sbBase = MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB ); MmioWrite32 (P2sbBase + R_PCH_P2SB_SBREG_BAR, PCH_PCR_BASE_ADDRESS); MmioOr8 (P2sbBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE); /// /// Program ACPI BASE /// PchAcpiBaseSet (PcdGet16 (PcdAcpiBaseAddress)); /// /// Program PWRM BASE /// PchPwrmBaseSet (PCH_PWRM_BASE_ADDRESS); /// /// Program TCO BASE if it is present and not locked /// if (PchIsTcoBaseSetValid ()) { PchTcoBaseSet (PcdGet16 (PcdTcoBaseAddress)); } /// /// LPC I/O Configuration /// PchLpcIoDecodeRangesSet ( (V_PCH_LPC_IOD_LPT_378 << N_PCH_LPC_IOD_LPT) | (V_PCH_LPC_IOD_COMB_3E8 << N_PCH_LPC_IOD_COMB) | (V_PCH_LPC_IOD_COMA_3F8 << N_PCH_LPC_IOD_COMA) ); PchLpcIoEnableDecodingSet ( B_PCH_LPC_IOE_ME2 | B_PCH_LPC_IOE_SE | B_PCH_LPC_IOE_ME1 | B_PCH_LPC_IOE_KE | B_PCH_LPC_IOE_HGE | B_PCH_LPC_IOE_LGE | B_PCH_LPC_IOE_FDE | B_PCH_LPC_IOE_PPE | B_PCH_LPC_IOE_CBE | B_PCH_LPC_IOE_CAE ); /// /// Enable the upper 128-byte bank of RTC RAM /// PchPcrAndThenOr32 (PID_RTC, R_PCH_PCR_RTC_CONF, (UINT32)~0, B_PCH_PCR_RTC_CONF_UCMOS_EN); /// /// Disable the Watchdog timer expiration from causing a system reset /// PchPcrAndThenOr32 (PID_ITSS, R_PCH_PCR_ITSS_GIC, (UINT32)~0, B_PCH_PCR_ITSS_GIC_AME); /// /// Halt the TCO timer /// Data16 = IoRead16 (PcdGet16 (PcdTcoBaseAddress) + R_PCH_TCO1_CNT); Data16 |= B_PCH_TCO_CNT_TMR_HLT; IoWrite16 (PcdGet16 (PcdTcoBaseAddress) + R_PCH_TCO1_CNT, Data16); /// /// Clear the Second TO status bit /// IoWrite8 (PcdGet16 (PcdTcoBaseAddress) + R_PCH_TCO2_STS, B_PCH_TCO2_STS_SECOND_TO); /// /// Disable SERR NMI and IOCHK# NMI in port 61 /// Data8 = IoRead8 (R_PCH_NMI_SC); Data8 |= (B_PCH_NMI_SC_PCI_SERR_EN | B_PCH_NMI_SC_IOCHK_NMI_EN); IoWrite8 (R_PCH_NMI_SC, Data8); PchPcrAndThenOr32 (PID_ITSS, R_PCH_PCR_ITSS_GIC, (UINT32)~B_PCH_PCR_ITSS_GIC_AME, 0); // // Program timer 1 as refresh timer // IoWrite8 (0x43, 0x54); IoWrite8 (0x41, 0x12); } // @todo: It should be moved Policy Init. /** Initialize the GPIO IO selection, GPIO USE selection, and GPIO signal inversion registers **/ VOID SiliconInit ( VOID ) { UINT16 Data16; UINT8 Data8; UINTN LpcBaseAddress; UINT16 ABase; UINT16 Pm1Sts; UINT32 Pm1Cnt; LpcBaseAddress = MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC ); /// /// LPC I/O Configuration /// PchLpcIoDecodeRangesSet ( (V_PCH_LPC_IOD_LPT_378 << N_PCH_LPC_IOD_LPT) | (V_PCH_LPC_IOD_COMB_3E8 << N_PCH_LPC_IOD_COMB) | (V_PCH_LPC_IOD_COMA_3F8 << N_PCH_LPC_IOD_COMA) ); PchLpcIoEnableDecodingSet ( B_PCH_LPC_IOE_ME2 | B_PCH_LPC_IOE_SE | B_PCH_LPC_IOE_ME1 | B_PCH_LPC_IOE_KE | B_PCH_LPC_IOE_HGE | B_PCH_LPC_IOE_LGE | B_PCH_LPC_IOE_FDE | B_PCH_LPC_IOE_PPE | B_PCH_LPC_IOE_CBE | B_PCH_LPC_IOE_CAE ); /// /// Enable the upper 128-byte bank of RTC RAM /// PchPcrAndThenOr32 (PID_RTC, R_PCH_PCR_RTC_CONF, (UINT32)~0, B_PCH_PCR_RTC_CONF_UCMOS_EN); /// /// Disable the Watchdog timer expiration from causing a system reset /// PchPcrAndThenOr32 (PID_SMB, R_PCH_PCR_SMBUS_GC, (UINT32)~0, B_PCH_PCR_SMBUS_GC_NR); /// /// Halt the TCO timer /// Data16 = IoRead16 (PcdGet16 (PcdTcoBaseAddress) + R_PCH_TCO1_CNT); Data16 |= B_PCH_TCO_CNT_TMR_HLT; IoWrite16 (PcdGet16 (PcdTcoBaseAddress) + R_PCH_TCO1_CNT, Data16); /// /// Clear the Second TO status bit /// IoWrite8 (PcdGet16 (PcdTcoBaseAddress) + R_PCH_TCO2_STS, B_PCH_TCO2_STS_SECOND_TO); /// /// Disable SERR NMI and IOCHK# NMI in port 61 /// Data8 = IoRead8 (R_PCH_NMI_SC); Data8 |= (B_PCH_NMI_SC_PCI_SERR_EN | B_PCH_NMI_SC_IOCHK_NMI_EN); IoWrite8 (R_PCH_NMI_SC, Data8); /// /// Clear all pending SMI. On S3 clear power button enable so it will not generate an SMI. /// IoWrite16 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_EN, 0); IoWrite32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_GPE0_EN_127_96, 0); ///---------------------------------------------------------------------------------- /// /// BIOS should check the WAK_STS bit in PM1_STS[15] (PCH register ABASE+00h) before memory /// initialization to determine if ME has reset the system while the host was in a sleep state. /// If WAK_STS is not set, BIOS should ensure a non-sleep exit path is taken by overwriting /// PM1_CNT[12:10] (PCH register ABASE+04h) to 111b to force an s5 exit. /// PchAcpiBaseGet (&ABase); Pm1Sts = IoRead16 (ABase + R_PCH_ACPI_PM1_STS); if ((Pm1Sts & B_PCH_ACPI_PM1_STS_WAK) == 0) { Pm1Cnt = IoRead32 (ABase + R_PCH_ACPI_PM1_CNT); Pm1Cnt |= V_PCH_ACPI_PM1_CNT_S5; IoWrite32 (ABase + R_PCH_ACPI_PM1_CNT, Pm1Cnt); } }