summaryrefslogtreecommitdiff
path: root/BraswellPlatformPkg/PlatformInitPei
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-06-02 10:35:14 +0800
committerHao Wu <hao.a.wu@intel.com>2016-06-07 09:56:43 +0800
commit2c398e099c2729243fc0436c626258e94081ea7f (patch)
tree9c1301ce539e46da61cfae4a367ce8067c1343bd /BraswellPlatformPkg/PlatformInitPei
parent6467b2bbcd4ed6a1632e00fbd57657f1e83bb459 (diff)
downloadedk2-platforms-2c398e099c2729243fc0436c626258e94081ea7f.tar.xz
BraswellPlatformPkg: Add PlatformInitPei module.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'BraswellPlatformPkg/PlatformInitPei')
-rw-r--r--BraswellPlatformPkg/PlatformInitPei/MemoryCallback.c298
-rw-r--r--BraswellPlatformPkg/PlatformInitPei/MemoryPeim.c110
-rw-r--r--BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.c207
-rw-r--r--BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.h335
-rw-r--r--BraswellPlatformPkg/PlatformInitPei/PlatformEarlyInit.inf97
-rw-r--r--BraswellPlatformPkg/PlatformInitPei/PlatformPchInitPeim.c563
6 files changed, 1610 insertions, 0 deletions
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.<BR>
+
+ 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.<BR>
+
+ 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.<BR>
+
+ 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 <Library/BiosIdLib.h>
+#include <CpuRegs.h>
+#include <CpuPpmLib.h>
+
+#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.<BR>
+
+ 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 <FrameworkPei.h>
+#include "PlatformBaseAddresses.h"
+#include "PchAccess.h"
+#include "ChvAccess.h"
+#include "CpuRegs.h"
+#include "Platform.h"
+#include "CpuRegs.h"
+#include <Ppi/Stall.h>
+#include <Guid/PlatformInfo.h>
+#include <Library/GpioLib.h>
+#include <Guid/SetupVariable.h>
+#include <Ppi/AtaController.h>
+#include <Ppi/FindFv.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/Capsule.h>
+#include <Library/DebugLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PeiServicesLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Guid/FirmwareFileSystem.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/Cache.h>
+#include <Library/PchPlatformLib.h>
+#include <Ppi/SmbusPolicy.h>
+#include <Ppi/Reset.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/ChvPlatformPolicyPpi.h>
+#include <Guid/GlobalVariable.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/DeviceRecoveryModulePei.h>
+#include <Guid/Capsule.h>
+#include <Guid/RecoveryDevice.h>
+#include <Ppi/MasterBootMode.h>
+#include <Library/I2CLib.h>
+#include <Library/TimerLib.h>
+
+#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.<BR>
+#
+# 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.<BR>
+
+ 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 <Ppi/PchPlatformPolicy.h>
+#include "PchRegs.h"
+#include "Ppi/PchInit.h"
+#include <Library/PcdLib.h>
+
+
+#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;
+}