From 2c398e099c2729243fc0436c626258e94081ea7f Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 2 Jun 2016 10:35:14 +0800 Subject: BraswellPlatformPkg: Add PlatformInitPei module. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../PlatformInitPei/MemoryCallback.c | 298 +++++++++++ BraswellPlatformPkg/PlatformInitPei/MemoryPeim.c | 110 ++++ .../PlatformInitPei/PlatformEarlyInit.c | 207 ++++++++ .../PlatformInitPei/PlatformEarlyInit.h | 335 ++++++++++++ .../PlatformInitPei/PlatformEarlyInit.inf | 97 ++++ .../PlatformInitPei/PlatformPchInitPeim.c | 563 +++++++++++++++++++++ 6 files changed, 1610 insertions(+) create mode 100644 BraswellPlatformPkg/PlatformInitPei/MemoryCallback.c create mode 100644 BraswellPlatformPkg/PlatformInitPei/MemoryPeim.c create mode 100644 BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.c create mode 100644 BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.h create mode 100644 BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.inf create mode 100644 BraswellPlatformPkg/PlatformInitPei/PlatformPchInitPeim.c (limited to 'BraswellPlatformPkg/PlatformInitPei') diff --git a/BraswellPlatformPkg/PlatformInitPei/MemoryCallback.c b/BraswellPlatformPkg/PlatformInitPei/MemoryCallback.c new file mode 100644 index 0000000000..0740d3dd17 --- /dev/null +++ b/BraswellPlatformPkg/PlatformInitPei/MemoryCallback.c @@ -0,0 +1,298 @@ +/** @file + EFI 2.0 PEIM termination callback to provide the platform. + + Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformEarlyInit.h" + +VOID +UpdateDefaultSetupValue ( + IN EFI_PLATFORM_INFO_HOB *PlatformInfo + ) +{ +return; +} + +/** + PEI termination callback. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor Not uesed. + @param[in] Ppi Not uesed. + + @retval EFI_SUCCESS If the interface could be successfully + installed. + +**/ +EFI_STATUS +EndOfPeiPpiNotifyCallback ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + UINT64 MemoryTop; + UINT64 LowUncableBase; + EFI_PLATFORM_INFO_HOB *PlatformInfo; + UINT32 HecBaseHigh; + EFI_BOOT_MODE BootMode; + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + ASSERT_EFI_ERROR (Status); + + // + // Set the some PCI and chipset range as UC + // And align to 1M at leaset + // + PlatformInfo = PcdGetPtr (PcdPlatformInfo); + + UpdateDefaultSetupValue (PlatformInfo); + + DEBUG ((EFI_D_ERROR, "Memory TOLM: %X\n", PlatformInfo->MemData.MemTolm)); + DEBUG ((EFI_D_ERROR, "PCIE OSBASE: %lX\n", PlatformInfo->PciData.PciExpressBase)); + DEBUG ( + (EFI_D_ERROR, + "PCIE BASE: %lX Size : %X\n", + PlatformInfo->PciData.PciExpressBase, + PlatformInfo->PciData.PciExpressSize) + ); + DEBUG ( + (EFI_D_ERROR, + "PCI32 BASE: %X Limit: %X\n", + PlatformInfo->PciData.PciResourceMem32Base, + PlatformInfo->PciData.PciResourceMem32Limit) + ); + DEBUG ( + (EFI_D_ERROR, + "PCI64 BASE: %lX Limit: %lX\n", + PlatformInfo->PciData.PciResourceMem64Base, + PlatformInfo->PciData.PciResourceMem64Limit) + ); + DEBUG ((EFI_D_ERROR, "UC START: %lX End : %lX\n", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1)); + + LowUncableBase = PlatformInfo->MemData.MemMaxTolm; + LowUncableBase &= (0x0FFF00000); + MemoryTop = (0x100000000); + + if (BootMode != BOOT_ON_S3_RESUME) { + // + // In BIOS, HECBASE will be always below 4GB + // + HecBaseHigh = (UINT32) RShiftU64 (PlatformInfo->PciData.PciExpressBase, 28); + ASSERT (HecBaseHigh < 16); + + // + // Programe HECBASE for DXE phase + // + } + + return Status; +} + +/** + Install Firmware Volume Hob's once there is main memory + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor Notify that this module published. + @param[in] Ppi PPI that was installed. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +EFIAPI +MemoryDiscoveredPpiNotifyCallback ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_CPUID_REGISTER FeatureInfo; + UINT8 CpuAddressWidth; + UINT32 RootComplexBar; + UINT32 PmcBase; + UINT32 IoBase; + UINT32 IlbBase; + UINT32 SpiBase; + UINT32 MphyBase; + UINT32 PunitBase; + + // + // Pulish memory type info + // + PublishMemoryTypeInfo (); + + RootComplexBar = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_RCBA) & B_PCH_LPC_RCBA_BAR; + DEBUG ((EFI_D_INFO, "RootComplexBar : 0x%x\n", RootComplexBar)); + ASSERT (RootComplexBar != 0 && RootComplexBar != B_PCH_LPC_RCBA_BAR); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + RootComplexBar, + 0x1000 + ); + + PmcBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR; + DEBUG ((EFI_D_INFO, "PmcBase : 0x%x\n", PmcBase)); + ASSERT (PmcBase != 0 && PmcBase != B_PCH_LPC_PMC_BASE_BAR); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PmcBase, + 0x1000 + ); + + IoBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR; + DEBUG ((EFI_D_INFO, "IoBase : 0x%x\n", IoBase)); + ASSERT (IoBase != 0 && IoBase != B_PCH_LPC_IO_BASE_BAR); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + IoBase, + 0x40000 + ); + + IlbBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ILB_BASE) & B_PCH_LPC_ILB_BASE_BAR; + DEBUG ((EFI_D_INFO, "IlbBase : 0x%x\n", IlbBase)); + ASSERT (IlbBase != 0 && IlbBase != B_PCH_LPC_ILB_BASE_BAR); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + IlbBase, + 0x2000 + ); + + SpiBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_SPI_BASE) & B_PCH_LPC_SPI_BASE_BAR; + DEBUG ((EFI_D_INFO, "SpiBase : 0x%x\n", SpiBase)); + ASSERT (SpiBase != 0 && SpiBase != B_PCH_LPC_SPI_BASE_BAR); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + SpiBase, + 0x1000 + ); + + MphyBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_MPHY_BASE) & B_PCH_LPC_MPHY_BASE_BAR; + DEBUG ((EFI_D_INFO, "MphyBase : 0x%x\n", MphyBase)); + ASSERT (MphyBase != 0 && MphyBase != B_PCH_LPC_MPHY_BASE_BAR); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + MphyBase, + 0x100000 + ); + + PunitBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PUNIT_BASE) & B_PCH_LPC_PUNIT_BASE_BAR; + DEBUG ((EFI_D_INFO, "PunitBase : 0x%x\n", PunitBase)); + ASSERT (PunitBase != 0 && PunitBase != B_PCH_LPC_PUNIT_BASE_BAR); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PunitBase, + 0x1000 + ); + // + // Local APIC + // + DEBUG ((EFI_D_INFO, "LOCAL_APIC_ADDRESS : 0x%x\n", LOCAL_APIC_ADDRESS)); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + LOCAL_APIC_ADDRESS, + 0x1000 + ); + // + // IO APIC + // + DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS : 0x%x\n", IO_APIC_ADDRESS)); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + IO_APIC_ADDRESS, + 0x1000 + ); + // + // Adding the PCIE Express area to the E820 memory table as type 2 memory. + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + ((UINTN)PcdGet64(PcdPciExpressBaseAddress)), //PlatformInfo->PciData.PciExpressBase, + 0x10000000 //PlatformInfo->PciData.PciExpressSize + ); + // + // Adding the Flashpart to the E820 memory table as type 2 memory. + // + DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", PcdGet32(PcdFlashAreaBaseAddress))); + BuildResourceDescriptorHob ( + EFI_RESOURCE_FIRMWARE_DEVICE, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PcdGet32(PcdFlashAreaBaseAddress), + PcdGet32(PcdFlashAreaSize) + ); + + // + // Create a CPU hand-off information + // + CpuAddressWidth = 32; + AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx); + if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) { + AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx); + CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF); + } + + BuildCpuHob(CpuAddressWidth, 16); + + return EFI_SUCCESS; +} + +EFI_STATUS +ValidateFvHeader ( + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader + ) +{ + UINT16 *Ptr; + UINT16 HeaderLength; + UINT16 Checksum; + + // + // Verify the header revision, header signature, length + // Length of FvBlock cannot be 2**64-1 + // HeaderLength cannot be an odd number + // + if ((FwVolHeader->Revision != EFI_FVH_REVISION) || + (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || + (FwVolHeader->FvLength == ((UINT64) -1)) || + ((FwVolHeader->HeaderLength & 0x01) != 0) + ) { + return EFI_NOT_FOUND; + } + // + // Verify the header checksum + // + HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2); + Ptr = (UINT16 *) FwVolHeader; + Checksum = 0; + while (HeaderLength > 0) { + Checksum = *Ptr++; + HeaderLength--; + } + + if (Checksum != 0) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} diff --git a/BraswellPlatformPkg/PlatformInitPei/MemoryPeim.c b/BraswellPlatformPkg/PlatformInitPei/MemoryPeim.c new file mode 100644 index 0000000000..58445cd717 --- /dev/null +++ b/BraswellPlatformPkg/PlatformInitPei/MemoryPeim.c @@ -0,0 +1,110 @@ +/** @file + Tiano PEIM to provide the platform support functionality. + This file implements the Platform Memory Range PPI. + + Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformEarlyInit.h" + +// +// Need min. of 48MB PEI phase +// +#define PEI_MIN_MEMORY_SIZE (6 * 0x800000) +#define PEI_RECOVERY_MIN_MEMORY_SIZE (6 * 0x800000) + +// +// This is the memory needed for PEI to start up DXE. +// +// Over-estimating this size will lead to higher fragmentation +// of main memory. Under-estimation of this will cause catastrophic +// failure of PEI to load DXE. Generally, the failure may only be +// realized during capsule updates. +// +#define PRERESERVED_PEI_MEMORY ( \ + EFI_SIZE_TO_PAGES (3 * 0x800000) /* PEI Core memory based stack */ \ + ) + +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { + { EfiACPIReclaimMemory, 0x2B }, // ASL + { EfiACPIMemoryNVS, 0xCF }, // ACPI NVS + { EfiReservedMemoryType, 0xC8 }, // BIOS Reserved + { EfiRuntimeServicesCode, 0x100 }, + { EfiRuntimeServicesData, 0x200 }, + { EfiMaxMemoryType, 0 } +}; + +/** + Publish Memory Type Information. + + @param None + + @retval EFI_SUCCESS Success. + @retval Others Errors have occurred. +**/ +EFI_STATUS +EFIAPI +PublishMemoryTypeInfo ( + void + ) +{ + EFI_STATUS Status; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; + UINTN DataSize; + EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; + + Status = PeiServicesLocatePpi ( + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + &Variable + ); + if (EFI_ERROR (Status)) { + DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status)); + DEBUG((EFI_D_ERROR, "Build Hob from default\n")); + // + // Build the default GUID'd HOB for DXE + // + BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) ); + + return Status; + } + + DataSize = sizeof (MemoryData); + // + // This variable is saved in BDS stage. Now read it back + // + Status = Variable->GetVariable ( + Variable, + EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, + &gEfiMemoryTypeInformationGuid, + NULL, + &DataSize, + &MemoryData + ); + if (EFI_ERROR (Status)) { + // + // build default + // + DEBUG((EFI_D_ERROR, "Build Hob from default\n")); + BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) ); + } else { + // + // Build the GUID'd HOB for DXE from variable + // + DEBUG((EFI_D_ERROR, "Build Hob from variable \n")); + BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, MemoryData, DataSize); + } + + return Status; +} + diff --git a/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.c b/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.c new file mode 100644 index 0000000000..5c2381cb4c --- /dev/null +++ b/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.c @@ -0,0 +1,207 @@ +/** @file + Do platform specific PEI stage initializations. + + Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformEarlyInit.h" +#include +#include +#include + +#pragma optimize ("", off) + +static EFI_PEI_FIND_FV_PPI mEfiFindFvPpi = { + FindFv +}; + +static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiFindFvPpiGuid, + &mEfiFindFvPpi + } +}; + +static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = { + { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, + &gEfiEndOfPeiSignalPpiGuid, + EndOfPeiPpiNotifyCallback + }, + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMemoryDiscoveredPpiGuid, + MemoryDiscoveredPpiNotifyCallback + } +}; + + +/** + Bugbug: temp workaround - Initialize performance to HFM. + + @param[in] None + +**/ +VOID +ProcessorsPerfPowerInit ( + ) +{ + EFI_CPUID_REGISTER Cpuid = { 0, 0, 0, 0 }; + UINT16 MaxBusRatio; + UINT16 MaxVid; + MSR_REGISTER Ia32MiscEnable; + MSR_REGISTER TempMsr; + MSR_REGISTER IaCoreRatios; + MSR_REGISTER IaCoreVids; + + + // + // Get Maximum Non-Turbo bus ratio (HFM) from IACORE_RATIOS MSR Bits[23:16] + // + IaCoreRatios.Qword = AsmReadMsr64 (MSR_IACORE_RATIOS); + MaxBusRatio = IaCoreRatios.Bytes.ThirdByte; + + // + // Get Maximum Non-Turbo Vid (HFM) from IACORE_VIDS MSR Bits[23:16] + // + IaCoreVids.Qword = AsmReadMsr64 (MSR_IACORE_VIDS); + MaxVid = IaCoreVids.Bytes.ThirdByte; + + AsmCpuid (EFI_CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx); + + // + // This function will be executed when EIST is enabled and EIST is capable + // So processor can be switched to HFM + // + if ((Cpuid.RegEcx & B_EFI_CPUID_VERSION_INFO_ECX_EIST) == B_EFI_CPUID_VERSION_INFO_ECX_EIST) { + + // + // Enable EIST + // + Ia32MiscEnable.Qword = AsmReadMsr64 (EFI_MSR_IA32_MISC_ENABLE); + Ia32MiscEnable.Qword |= B_EFI_MSR_IA32_MISC_ENABLE_EIST; + AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, Ia32MiscEnable.Qword); + + TempMsr.Qword = AsmReadMsr64 (EFI_MSR_IA32_PERF_CTRL); + TempMsr.Qword &= (~(UINT64)P_STATE_TARGET_MASK); + + TempMsr.Qword |= LShiftU64 (MaxBusRatio, P_STATE_TARGET_OFFSET); + TempMsr.Qword |= (UINT64)MaxVid; + + AsmWriteMsr64 (EFI_MSR_IA32_PERF_CTRL, TempMsr.Qword); + } + + return; +} + +/** + Platform specific initializations in stage1. + + @param[in] FileHandle Pointer to the PEIM FFS file header. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS Operation completed successfully. + @retval Otherwise Platform initialization failed. + +**/ +EFI_STATUS +EFIAPI +PlatformEarlyInitEntry ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + SYSTEM_CONFIGURATION SystemConfiguration; + EFI_PLATFORM_INFO_HOB *PlatformInfo; + + // + // Set the some PCI and chipset range as UC + // And align to 1M at least + // + PlatformInfo = PcdGetPtr (PcdPlatformInfo); + + // + // Initialize PlatformInfo HOB + // + MultiPlatformInfoInit (PeiServices, PlatformInfo); + + // + // Get setup variable. This can only be done after BootMode is updated + // + CopyMem (&SystemConfiguration, PcdGetPtr (PcdSystemConfiguration), sizeof(SYSTEM_CONFIGURATION)); + + // + // Do basic PCH init + // + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_CAR_SB_INIT)); + Status = PlatformPchInit (&SystemConfiguration, PeiServices, PlatformInfo->PlatformType); + ASSERT_EFI_ERROR (Status); + + // + // Initialize platform PPIs + // + Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]); + ASSERT_EFI_ERROR (Status); + + // + // Bugbug: temp workaround to increase performance. + // + ProcessorsPerfPowerInit(); + + return Status; +} + +/** + Return the mainblockcompact Fv. + + @param[in] This EFI PEI FIND FV PPI instance + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FvNumber enumeration of the firmware volumes we care about. + @param[in] FvAddress Base Address of the memory containing the firmware volume + + @retval EFI_SUCCESS + @retval EFI_NOT_FOUND + +**/ +EFI_STATUS +EFIAPI +FindFv ( + IN EFI_PEI_FIND_FV_PPI *This, + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT8 *FvNumber, + OUT EFI_FIRMWARE_VOLUME_HEADER **FVAddress + ) +{ + // + // At present, we only have one Fv to search + // + if (*FvNumber == 0) { + *FvNumber = 1; + *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) MAINBLOCK_BASE_ADDR; + return EFI_SUCCESS; + } else if (*FvNumber == 1) { + *FvNumber = 2; + if (IsA16Inverted ()) { + *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BOOTBLOCK2_BACKUP_BASE_ADDR; + } else { + *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BOOTBLOCK2_BASE_ADDR; + } + return EFI_SUCCESS; + } else { // Not the one Fv we care about + return EFI_NOT_FOUND; + } +} + +#pragma optimize ("", on) + diff --git a/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.h b/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.h new file mode 100644 index 0000000000..5d189b2390 --- /dev/null +++ b/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.h @@ -0,0 +1,335 @@ +/** @file + Platform Early Stage header file + + Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _EFI_PLATFORM_EARLY_INIT_H_ +#define _EFI_PLATFORM_EARLY_INIT_H_ + +#define EFI_FORWARD_DECLARATION(x) typedef struct _##x x + +#include +#include "PlatformBaseAddresses.h" +#include "PchAccess.h" +#include "ChvAccess.h" +#include "CpuRegs.h" +#include "Platform.h" +#include "CpuRegs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SMC_LAN_ON 0x46 +#define SMC_LAN_OFF 0x47 +#define SMC_DEEP_S3_STS 0xB2 +#define EXT_MODEL_ID_VLV2 0x3 + +typedef struct { + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; +} EFI_CPUID_REGISTER; + +// +// Wake Event Types +// +#define SMBIOS_WAKEUP_TYPE_RESERVED 0x00 +#define SMBIOS_WAKEUP_TYPE_OTHERS 0x01 +#define SMBIOS_WAKEUP_TYPE_UNKNOWN 0x02 +#define SMBIOS_WAKEUP_TYPE_APM_TIMER 0x03 +#define SMBIOS_WAKEUP_TYPE_MODEM_RING 0x04 +#define SMBIOS_WAKEUP_TYPE_LAN_REMOTE 0x05 +#define SMBIOS_WAKEUP_TYPE_POWER_SWITCH 0x06 +#define SMBIOS_WAKEUP_TYPE_PCI_PME 0x07 +#define SMBIOS_WAKEUP_TYPE_AC_POWER_RESTORED 0x08 + +// +// Defines for stall ppi +// +#define PEI_STALL_RESOLUTION 1 + +// +// Used in PEI memory test routines +// +#define MEMORY_TEST_COVER_SPAN 0x40000 +#define MEMORY_TEST_PATTERN 0x5A5A5A5A + +#define EFI_LOW_BEEP_FREQUENCY 0x31B +#define EFI_HIGH_BEEP_FREQUENCY 0x254 + +// +// General Purpose Constants +// +#define ICH_ACPI_TIMER_MAX_VALUE 0x1000000 //The timer is 24 bit overflow + +// +// Function Prototypes +// +EFI_STATUS +PlatformPchInit ( + IN SYSTEM_CONFIGURATION *SystemConfiguration, + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT16 PlatformType + ); + +EFI_STATUS +PeimInitializeFlashMap ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +PeimInstallFlashMapPpi ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +IchReset ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +BOOLEAN +GetSleepTypeAfterWakeup ( + IN CONST EFI_PEI_SERVICES **PeiServices, + OUT UINT16 *SleepType + ); + +EFI_STATUS +EFIAPI +GetWakeupEventAndSaveToHob ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +MemoryDiscoveredPpiNotifyCallback ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +EFI_STATUS +EFIAPI +PeiGetVariable ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CHAR16 *VariableName, + IN EFI_GUID * VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + +EFI_STATUS +EFIAPI +PeiGetNextVariableName ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + +EFI_STATUS +UpdateBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ); + +EFI_STATUS +EndOfPeiPpiNotifyCallback ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +EFI_STATUS +EFIAPI +PeimInitializeRecovery ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +VOID +CheckPowerOffNow ( + VOID + ); + +VOID +IchGpioInit ( + IN UINT16 PlatformType, + IN SYSTEM_CONFIGURATION *SystemConfiguration + ); + +EFI_STATUS +PcieSecondaryBusReset ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Fun + ); + +VOID +SetPlatformBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ); + +BOOLEAN +CheckIfJumperSetForRecovery ( + VOID + ); + +EFI_STATUS +FindFv ( + IN EFI_PEI_FIND_FV_PPI *This, + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT8 *FvNumber, + OUT EFI_FIRMWARE_VOLUME_HEADER **FVAddress + ); + +BOOLEAN +IsA16Inverted ( + ); + +EFI_STATUS +EFIAPI +CpuOnlyReset ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +InitLan ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN SYSTEM_CONFIGURATION *Buffer + ); + +EFI_STATUS +EFIAPI +Stall ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_STALL_PPI *This, + IN UINTN Microseconds + ); + +EFI_STATUS +MultiPlatformInfoInit ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ); + +BOOLEAN +IsRecoveryJumper ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ); + +EFI_STATUS +PlatformInfoUpdate ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob, + IN SYSTEM_CONFIGURATION *SystemConfiguration + ); + +VOID +PlatformSaInit ( +IN SYSTEM_CONFIGURATION *SystemConfiguration, +IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +InitializePlatform ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PLATFORM_INFO_HOB *PlatformInfoHob, + IN SYSTEM_CONFIGURATION *SystemConfiguration + ); + +EFI_STATUS +EFIAPI +SetPeiCacheMode ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +SetDxeCacheMode ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +GPIO_initialization ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *SmbusPpi + ); + +EFI_STATUS +GeneralPowerFailureHandler ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +BOOLEAN +IsRtcUipAlwaysSet ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +RtcPowerFailureHandler ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +InitPchUsb ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +PublishMemoryTypeInfo ( + void + ); + +#endif diff --git a/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.inf b/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.inf new file mode 100644 index 0000000000..08a41e685e --- /dev/null +++ b/BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.inf @@ -0,0 +1,97 @@ +## @file +# Component description file for PlatformEarlyInit module +# +# This module will do early platform initialization during pei stage. +# +# Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformEarlyInit + FILE_GUID = E039B4AC-DAB5-44FC-AA40-86079CE4C263 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = PlatformEarlyInitEntry + +[Sources.common] + PlatformPchInitPeim.c + MemoryCallback.c + MemoryPeim.c + PlatformEarlyInit.c + PlatformEarlyInit.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + ChvRefCodePkg/ChvRefCodePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + PeimEntryPoint + DebugLib + HobLib + IoLib + MultiPlatformLib + PcdLib + ReportStatusCodeLib + PchPlatformLib + TimerLib + +# +# [Hob] +# RESOURCE_DESCRIPTOR ## PRODUCES +# + +[Ppis] + ## CONSUMES + gEfiPeiStallPpiGuid + + ## NOTIFY + gEfiPeiMemoryDiscoveredPpiGuid + + ## CONSUMES + gEfiPeiReadOnlyVariable2PpiGuid + + ## NOTIFY + gEfiEndOfPeiSignalPpiGuid + + ## PRODUCES + gEfiFindFvPpiGuid + +[Guids] + + ## PRODUCES ## HOB + gEfiMemoryTypeInformationGuid + +[Pcd] + ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + + ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress + + ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize + + ## CONSUMES + gEfiEdkIIPlatformTokenSpaceGuid.PcdPlatformInfo + gEfiEdkIIPlatformTokenSpaceGuid.PcdSystemConfiguration + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + +[Depex] + gEfiPeiReadOnlyVariable2PpiGuid AND gEfiPeiStallPpiGuid + diff --git a/BraswellPlatformPkg/PlatformInitPei/PlatformPchInitPeim.c b/BraswellPlatformPkg/PlatformInitPei/PlatformPchInitPeim.c new file mode 100644 index 0000000000..4c548468c2 --- /dev/null +++ b/BraswellPlatformPkg/PlatformInitPei/PlatformPchInitPeim.c @@ -0,0 +1,563 @@ +/** @file + Do Early PCH platform initialization. + + Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformEarlyInit.h" +#include +#include "PchRegs.h" +#include "Ppi/PchInit.h" +#include + + +#define MC_PMSTS_OFFSET 0xC + +#define DEFAULT_BUS_INFO 0x2020 + +VOID +PchInitInterrupt ( + IN SYSTEM_CONFIGURATION *SystemConfiguration + ); + +#pragma warning (push) +#pragma warning (disable : 4245) +#pragma warning (pop) + +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. + + @param[in] + + @retval + +**/ +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); + } +} + +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 + // Write '1' to Invert NMI_NOW & NMI_NOW_STS + // + 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 + } + // + // Now clear the TO status bit (Write '1' to clear) + // + IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS, (UINT32) (Data32 | B_PCH_TCO_STS_SECOND_TO)); +} + +/** + Clear any SMI status or wake status left over from boot. + + @param[in] + + @retval + +**/ +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); + + // + // 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_TCO | + 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 | + B_PCH_ACPI_GPE0a_STS_PMU_WAKEB + ); + + 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[in] PeiServices General-purpose services that are available to every PEIM. + @param[in] Bus Bus number of the bridge + @param[in] Dev Devices number of the bridge + @param[in] 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, + &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[in] 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); + + 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); + + // + // 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) + ); +} + +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); + + if ((BootMode == BOOT_ON_S3_RESUME)) { + // + // We are resuming from S3 + // Program HPET based on Setup + // + if (SystemConfiguration->Hpet == 1) { + MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN); + } else { + MmioAnd8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, (UINT8) ~(B_PCH_PCH_HPET_GCFG_EN)); + } + } +} + +VOID +PchInitInterrupt ( + IN SYSTEM_CONFIGURATION *SystemConfiguration + ) +{ + DEBUG ((EFI_D_ERROR, "PchInitInterrupt () - Start\n")); + + // + // Configure LPSS Interrupts (Done by FSP) + // + + // + // Program Interrupt routing registers + // + // + // Device 31 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D31IR), + V_PCH_ILB_DXXIR_IBR_PIRQC // For SMBUS + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D31IR); // Read Posted Writes Register + + // + // Device 30 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D30IR), + V_PCH_ILB_DXXIR_IAR_PIRQD + // For LPSS1 + V_PCH_ILB_DXXIR_IBR_PIRQB + + V_PCH_ILB_DXXIR_ICR_PIRQC + + V_PCH_ILB_DXXIR_IDR_PIRQA + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D30IR); // Read Posted Writes Register + + // + // Device 28 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D28IR), + V_PCH_ILB_DXXIR_IAR_PIRQA + // For PCIe #1 + V_PCH_ILB_DXXIR_IBR_PIRQB + // For PCIe #2 + V_PCH_ILB_DXXIR_ICR_PIRQC + // For PCIe #3 + V_PCH_ILB_DXXIR_IDR_PIRQD // For PCIe #4 + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D28IR); // Read Posted Writes Register + // + // Device 27 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D27IR), + V_PCH_ILB_DXXIR_IAR_PIRQG // For Azalia + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D27IR); // Read Posted Writes Register + + // + // Device 26 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D26IR), + V_PCH_ILB_DXXIR_IAR_PIRQF // For SEC + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D26IR); // Read Posted Writes Register + + // + // Device 24 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D24IR), + V_PCH_ILB_DXXIR_IAR_PIRQB | // For LPSS2 + V_PCH_ILB_DXXIR_IBR_PIRQA | + V_PCH_ILB_DXXIR_ICR_PIRQD | + V_PCH_ILB_DXXIR_IDR_PIRQC + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D24IR); // Read Posted Writes Register + + // + // Device 22 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D22IR), + V_PCH_ILB_DXXIR_IAR_PIRQH // For OTG + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D22IR); // Read Posted Writes Register + + // + // Device 21 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D21IR), + V_PCH_ILB_DXXIR_IAR_PIRQF // For LPE + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D21IR); // Read Posted Writes Register + + // + // Device 20 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D20IR), + V_PCH_ILB_DXXIR_IAR_PIRQE // For xHCI + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D20IR); // Read Posted Writes Register + // + // Device 19 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D19IR), + V_PCH_ILB_DXXIR_IAR_PIRQD // For SATA + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D19IR); // Read Posted Writes Register + + // + // Device 18 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D18IR), + V_PCH_ILB_DXXIR_IAR_PIRQC // For SDIO #2 + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D18IR); // Read Posted Writes Register + + // + // Device 17 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D17IR), + V_PCH_ILB_DXXIR_IAR_PIRQB // For SDIO #1 + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D17IR); // Read Posted Writes Register + + // + // Device 16 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D16IR), + V_PCH_ILB_DXXIR_IAR_PIRQA // For SDIO #0 + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D16IR); // Read Posted Writes Register + + // + // Device 10 Interrupt Route + // + MmioWrite16 ( + (ILB_BASE_ADDRESS + R_PCH_ILB_D10IR), + V_PCH_ILB_DXXIR_IAR_PIRQE // For ISH + ); + MmioRead16 (ILB_BASE_ADDRESS + R_PCH_ILB_D10IR); // Read Posted Writes Register + + DEBUG ((EFI_D_ERROR, "PchInitInterrupt () - End\n")); +} + +EFI_STATUS +PlatformPchInit ( + IN SYSTEM_CONFIGURATION *SystemConfiguration, + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT16 PlatformType + ) +{ + // + // Setup Interrupt Routing + // + PchInitInterrupt (SystemConfiguration); + + PchPlatformLpcInit (PeiServices, SystemConfiguration); + + return EFI_SUCCESS; +} + +/** + Returns the state of A16 inversion + + @param + + @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; +} -- cgit v1.2.3