summaryrefslogtreecommitdiff
path: root/Platform/BroxtonPlatformPkg/Common/PlatformSettings
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-23 14:31:30 +0800
committerGuo Mang <mang.guo@intel.com>2017-05-09 13:03:03 +0800
commit46e638b002b713e7bdc0d0087bd3d9336ee2ccc1 (patch)
tree55942376af0babec47cd6a97f0e4093dde757fd6 /Platform/BroxtonPlatformPkg/Common/PlatformSettings
parentd37b484fa6be720884745b56a24bc2b14c51f47b (diff)
downloadedk2-platforms-46e638b002b713e7bdc0d0087bd3d9336ee2ccc1.tar.xz
BroxtonPlatformPkg: Add PlatformPostMemPei
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Platform/BroxtonPlatformPkg/Common/PlatformSettings')
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/BootMode.c450
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryCallback.h25
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryPeim.c180
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PeiSaPolicyUpdate.h29
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.c981
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.h283
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformPostMemPei.inf130
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformScInitPeim.c322
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PowerFailureHandle.c126
9 files changed, 2526 insertions, 0 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/BootMode.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/BootMode.c
new file mode 100644
index 0000000000..c113097e55
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/BootMode.c
@@ -0,0 +1,450 @@
+/** @file
+ EFI PEIM to provide the platform support functionality.
+
+ Copyright (c) 1999 - 2016, 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 "PlatformInit.h"
+
+#define NORMALMODE 0
+#define RECOVERYMODE 1
+#define SAFEMODE 2
+#define MANUFACTURINGMODE 3
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiBootInRecoveryModePpiGuid,
+ NULL
+};
+
+
+/**
+ Return the setting of the Bios configuration jumper
+
+ @retval NORMALMODE jumper in normal mode
+
+**/
+UINTN
+GetConfigJumper (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+ return NORMALMODE;
+}
+
+
+BOOLEAN
+CheckIfRecoveryMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+ if (GetConfigJumper (PeiServices, PlatformInfoHob) == RECOVERYMODE) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOLEAN
+CheckIfSafeMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+ if (GetConfigJumper (PeiServices, PlatformInfoHob) == SAFEMODE) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOLEAN
+CheckIfManufacturingMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
+ UINT32 Attributes;
+ UINTN DataSize;
+ CHAR16 VarName[] = MFGMODE_VARIABLE_NAME;
+ UINT8 MfgMode;
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **) &Variable
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Check if SW MMJ mode
+ //
+ Attributes = (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+ DataSize = sizeof (MFG_MODE_VAR);
+
+ Status = Variable->GetVariable (
+ Variable,
+ VarName,
+ &gMfgModeVariableGuid,
+ &Attributes,
+ &DataSize,
+ &MfgMode
+ );
+
+ if (!(EFI_ERROR (Status))) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/**
+ Parse the status registers for figuring out the wake-up event and save it into
+ an GUID HOB which will be referenced later. However, modification is required
+ to meet the chipset register definition and the practical hardware design. Thus,
+ this is just an example.
+
+ @param[in] PeiServices Pointer to the PEI Service Table.
+
+ @retval EFI_SUCCESS Always return Success.
+
+**/
+EFI_STATUS
+EFIAPI
+GetWakeupEventAndSaveToHob (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINT16 AcpiBaseAddr;
+ UINT16 Pm1Sts;
+ UINTN Gpe0Sts;
+ UINTN WakeEventData;
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Read the ACPI registers
+ //
+ Pm1Sts = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_STS);
+ Gpe0Sts = IoRead32 (AcpiBaseAddr + R_ACPI_GPE0a_STS);
+
+ //
+ // Figure out the wake-up event
+ //
+ if ((Pm1Sts & B_ACPI_PM1_STS_PWRBTN) != 0) {
+ WakeEventData = SMBIOS_WAKEUP_TYPE_POWER_SWITCH;
+ } else if (((Pm1Sts & B_ACPI_PM1_STS_WAK) != 0)) {
+ WakeEventData = SMBIOS_WAKEUP_TYPE_PCI_PME;
+ } else if (Gpe0Sts != 0) {
+ WakeEventData = SMBIOS_WAKEUP_TYPE_OTHERS;
+ } else {
+ WakeEventData = SMBIOS_WAKEUP_TYPE_UNKNOWN;
+ }
+
+ DEBUG ((EFI_D_INFO, "ACPI Wake Status Register: %04x\n", Pm1Sts));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+UpdateBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ UINT16 SleepType;
+ CHAR16 *strBootMode;
+ PEI_CAPSULE_PPI *Capsule;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ UINTN VariableSize;
+
+ DEBUG ((EFI_D_INFO, "PEIM UpdateBootMode Enter: \n"));
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ ASSERT_EFI_ERROR (Status);
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ DEBUG ((EFI_D_INFO, "PEIM UpdateBootMode Enter: Set Recovery Mode \n"));
+ return Status;
+ }
+ DEBUG ((EFI_D_INFO, "GetWakeupEventAndSaveToHob \n"));
+ GetWakeupEventAndSaveToHob (PeiServices);
+
+ //
+ // Let's assume things are OK if not told otherwise
+ //
+ BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ &SystemConfiguration
+ );
+ if (!EFI_ERROR (Status)) {
+ if (SystemConfiguration.FastBoot == 1) {
+ BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
+ }
+ }
+
+ //
+ // Check if we need to boot in forced recovery mode
+ //
+ if (CheckIfRecoveryMode (PeiServices, PlatformInfoHob)) {
+ DEBUG ((EFI_D_ERROR, "Set Boot mode in recovery mode \n"));
+ BootMode = BOOT_IN_RECOVERY_MODE;
+ }
+
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiListRecoveryBootMode);
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {
+ switch (SleepType) {
+ case V_ACPI_PM1_CNT_S3:
+ BootMode = BOOT_ON_S3_RESUME;
+ //
+ // Determine if we're in capsule update mode
+ //
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gPeiCapsulePpiGuid,
+ 0,
+ NULL,
+ (VOID **) &Capsule
+ );
+
+ if (Status == EFI_SUCCESS) {
+ if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES **) PeiServices) == EFI_SUCCESS) {
+ BootMode = BOOT_ON_FLASH_UPDATE;
+ }
+ }
+ break;
+
+ case V_ACPI_PM1_CNT_S4:
+ BootMode = BOOT_ON_S4_RESUME;
+ break;
+
+ case V_ACPI_PM1_CNT_S5:
+ BootMode = BOOT_ON_S5_RESUME;
+ break;
+ } // switch (SleepType)
+ }
+ // Check for Safe Mode
+ }
+
+ switch (BootMode) {
+ case BOOT_WITH_FULL_CONFIGURATION:
+ strBootMode = L"BOOT_WITH_FULL_CONFIGURATION";
+ break;
+
+ case BOOT_WITH_MINIMAL_CONFIGURATION:
+ strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";
+ break;
+
+ case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+ strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
+ break;
+
+ case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+ strBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
+ break;
+
+ case BOOT_WITH_DEFAULT_SETTINGS:
+ strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";
+ break;
+
+ case BOOT_ON_S4_RESUME:
+ strBootMode = L"BOOT_ON_S4_RESUME";
+ break;
+
+ case BOOT_ON_S5_RESUME:
+ strBootMode = L"BOOT_ON_S5_RESUME";
+ break;
+
+ case BOOT_ON_S2_RESUME:
+ strBootMode = L"BOOT_ON_S2_RESUME";
+ break;
+
+ case BOOT_ON_S3_RESUME:
+ strBootMode = L"BOOT_ON_S3_RESUME";
+ break;
+
+ case BOOT_ON_FLASH_UPDATE:
+ strBootMode = L"BOOT_ON_FLASH_UPDATE";
+ break;
+
+ case BOOT_IN_RECOVERY_MODE:
+ strBootMode = L"BOOT_IN_RECOVERY_MODE";
+ break;
+
+ default:
+ strBootMode = L"Unknown boot mode";
+ } // switch (BootMode)
+
+ DEBUG ((EFI_D_INFO, "Setting BootMode to %s\n", strBootMode));
+ Status = (*PeiServices)->SetBootMode (PeiServices, BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ Get sleep type after wakeup.
+
+ @param[in] PeiServices Pointer to the PEI Service Table.
+ @param[out] SleepType Sleep type to be returned.
+
+ @retval TRUE A wake event occured without power failure.
+ @retval FALSE Power failure occured or not a wakeup.
+
+**/
+BOOLEAN
+GetSleepTypeAfterWakeup (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT UINT16 *SleepType
+ )
+{
+ UINT16 Pm1Sts;
+ UINT16 Pm1Cnt;
+ UINTN GenPmCon1;
+ UINT16 AcpiBaseAddr;
+
+ //
+ // When the SUS_PWR_FLR bit is set, it indicates the SUS well power is lost.
+ // This bit is in the SUS Well and defaults to 1'b1 based on RSMRST# assertion (not cleared by any type of reset).
+ // System BIOS should follow cold boot path if SUS_PWR_FLR (PBASE + 0x20[14]),
+ // GEN_RST_STS (PBASE + 0x20[9]) or PWRBTNOR_STS (ABASE + 0x00[11]) is set to 1'b1
+ // regardless of the value in the SLP_TYP (ABASE + 0x04[12:10]) field.
+ //
+ GenPmCon1 = MmioRead32 (PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1);
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Read the ACPI registers
+ //
+ Pm1Sts = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_STS);
+ Pm1Cnt = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_CNT);
+
+ DEBUG ((EFI_D_INFO, "ACPI Pm1Cnt Register: %04x\n", Pm1Cnt));
+ DEBUG ((EFI_D_INFO, "ACPI Pm1Sts Register: %04x\n", Pm1Sts));
+ DEBUG ((EFI_D_INFO, "PMC GenPmCon1 Register: %08x\n", GenPmCon1));
+
+ if (GenPmCon1 != 0xFFFF) {
+ if ((GenPmCon1 & (B_PMC_GEN_PMCON_COLD_BOOT_STS | B_PMC_GEN_PMCON_WARM_RST_STS)) ||\
+ (Pm1Sts & B_ACPI_PM1_STS_PRBTNOR) || \
+ (((Pm1Sts & B_ACPI_PM1_STS_WAK) == 0) && ((Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP) == V_ACPI_PM1_CNT_S3))) {
+ //
+ // If power failure indicator, then don't attempt s3 resume.
+ // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has
+ // lost already. This is to make sure no one will use PM1_CNT to check for S3 after
+ // power failure.
+ //
+ if ((Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP) == V_ACPI_PM1_CNT_S3) {
+ Pm1Cnt = ((Pm1Cnt & ~B_ACPI_PM1_CNT_SLP_TYP) | V_ACPI_PM1_CNT_S5);
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, Pm1Cnt);
+ }
+ //
+ // Clear Wake Status (WAK_STS)
+ //
+ IoWrite16 ((AcpiBaseAddr + R_ACPI_PM1_STS), B_ACPI_PM1_STS_WAK);
+ }
+ }
+
+ //
+ // Get sleep type if a wake event occurred and there is no power failure
+ //
+ if ((Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP) == V_ACPI_PM1_CNT_S3) {
+ *SleepType = Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP;
+ return TRUE;
+ } else if ((Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP) == V_ACPI_PM1_CNT_S4) {
+ *SleepType = Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+VOID
+SetPlatformBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+ EFI_PLATFORM_SETUP_ID PlatformSetupId;
+
+ ZeroMem (&PlatformSetupId, sizeof (EFI_PLATFORM_SETUP_ID));
+
+ CopyMem (&PlatformSetupId.SetupGuid, &gEfiNormalSetupGuid, sizeof (EFI_GUID));
+
+ if (CheckIfRecoveryMode (PeiServices, PlatformInfoHob)) {
+ //
+ // Recovery mode
+ //
+ CopyMem (&PlatformSetupId.SetupName, SAFE_SETUP_NAME, StrSize (SAFE_SETUP_NAME));
+ PlatformSetupId.PlatformBootMode = PLATFORM_RECOVERY_MODE;
+ } else if (CheckIfSafeMode (PeiServices, PlatformInfoHob)) {
+ //
+ // Safe mode also called config mode or maintenace mode.
+ //
+ CopyMem (&PlatformSetupId.SetupName, SAFE_SETUP_NAME, StrSize (SAFE_SETUP_NAME));
+ PlatformSetupId.PlatformBootMode = PLATFORM_SAFE_MODE;
+
+ } else if (0) {
+ //
+ // Manufacturing mode
+ //
+ CopyMem (&PlatformSetupId.SetupName, MANUFACTURE_SETUP_NAME, StrSize (MANUFACTURE_SETUP_NAME));
+ PlatformSetupId.PlatformBootMode = PLATFORM_MANUFACTURING_MODE;
+
+ } else {
+ //
+ // Default to normal mode.
+ //
+ CopyMem (&PlatformSetupId.SetupName, &NORMAL_SETUP_NAME, StrSize (NORMAL_SETUP_NAME));
+ PlatformSetupId.PlatformBootMode = PLATFORM_NORMAL_MODE;
+ }
+
+ BuildGuidDataHob (
+ &gEfiPlatformBootModeGuid,
+ &PlatformSetupId,
+ sizeof (EFI_PLATFORM_SETUP_ID)
+ );
+
+ return;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryCallback.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryCallback.h
new file mode 100644
index 0000000000..49dd74ab33
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryCallback.h
@@ -0,0 +1,25 @@
+/** @file
+ Common header file shared by all source files.
+ This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+ Copyright (c) 2010 - 2016, 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 __MEMORY_CALLBACK_H__
+#define __MEMORY_CALLBACK_H__
+
+//
+//Function Prototypes and Defines only - please do not add #includes here
+//
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryPeim.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryPeim.c
new file mode 100644
index 0000000000..4566ebc2c7
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryPeim.c
@@ -0,0 +1,180 @@
+/** @file
+ This file implements the Platform Memory Range PPI.
+
+ Copyright (c) 1999 - 2016, 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 "PlatformInit.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[] = {
+#if (ENBDT_PF_ENABLE == 1)
+ { EfiACPIReclaimMemory, 0x40 }, // 0x40 pages = 256k for ASL
+ { EfiACPIMemoryNVS, 0x60 }, // 0x100 pages = 1 MB for S3, SMM, HII, etc
+ { EfiReservedMemoryType, 0x1A80 }, // 48k for BIOS Reserved
+ { EfiRuntimeServicesCode, 0xF0 },
+ { EfiRuntimeServicesData, 0x240 },
+ { EfiMaxMemoryType, 0 }
+#else
+ { EfiACPIReclaimMemory, 0x30 }, // 0x40 pages = 256k for ASL
+ { EfiACPIMemoryNVS, 0x60 }, // 0x100 pages = 1 MB for S3, SMM, HII, etc
+ { EfiReservedMemoryType, 0x10 }, // 48k for BIOS Reserved
+ { EfiMemoryMappedIO, 0 },
+ { EfiMemoryMappedIOPortSpace, 0 },
+ { EfiPalCode, 0 },
+ { EfiRuntimeServicesCode, 0x50 },
+ { EfiRuntimeServicesData, 0x13B },
+ { EfiLoaderCode, 0x100 },
+ { EfiLoaderData, 0x100 },
+ { EfiBootServicesCode, 0x800 },
+ { EfiBootServicesData, 0x2500},
+ { EfiConventionalMemory, 0 },
+ { EfiUnusableMemory, 0 },
+ { EfiMaxMemoryType, 0 }
+#endif
+};
+
+STATIC
+EFI_STATUS
+GetMemorySize (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT UINT64 *LowMemoryLength,
+ OUT UINT64 *HighMemoryLength
+ );
+
+STATIC
+EFI_STATUS
+GetMemorySize (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT UINT64 *LowMemoryLength,
+ OUT UINT64 *HighMemoryLength
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+
+ *HighMemoryLength = 0;
+ *LowMemoryLength = 0x100000;
+ //
+ // Get the HOB list for processing
+ //
+ Status = (*PeiServices)->GetHobList (PeiServices, (VOID **) &Hob.Raw);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Collect memory ranges
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ //
+ // Need memory above 1MB to be collected here
+ //
+ if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
+ Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) {
+ *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+ } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) {
+ *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Publish Memory Type Information.
+
+ @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,
+ (VOID **) &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_INFO, "Build Hob from variable \n"));
+ BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, MemoryData, DataSize);
+ }
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PeiSaPolicyUpdate.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PeiSaPolicyUpdate.h
new file mode 100644
index 0000000000..d9f5be520f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PeiSaPolicyUpdate.h
@@ -0,0 +1,29 @@
+/** @file
+ Copyright (c) 2013 - 2016, 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 _PEI_SA_POLICY_UPDATE_H_
+#define _PEI_SA_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <Guid/SetupVariable.h>
+#include <SaAccess.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/SaPolicy.h>
+#include <Library/PeiServicesLib.h>
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.c
new file mode 100644
index 0000000000..84ff11700c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.c
@@ -0,0 +1,981 @@
+/** @file
+ Do platform specific PEI stage initializations.
+
+ Copyright (c) 2012 - 2016, 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 "PlatformInit.h"
+#include <Library/SteppingLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/PttPTPInstanceGuid.h>
+#include <Ppi/Smbus2.h>
+#include <Library/PcdLib.h>
+#include <Private/Library/CpuS3Lib.h>
+#include <Library/HeciMsgLib.h>
+#include <Ppi/SecUma.h>
+
+#ifdef __GNUC__
+ #pragma GCC push_options
+ #pragma GCC optimize ("O0")
+#else
+ #pragma optimize ("", off)
+#endif
+
+EFI_STATUS
+CpuS3SmmAccessNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+static EFI_PEI_RESET_PPI mResetPpi = { IchReset };
+
+static EFI_PEI_PPI_DESCRIPTOR mBoardPostMemInitStartPpi[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gBoardPostMemInitStartGuid,
+ NULL
+ }
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ //
+ // This PPI is hard coded to be installed as SPI boot (vs. eMMC boot)
+ // to trigger GetFvNotifyCallback()
+ //
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gCseSpiSelectPpiGuid,
+ NULL
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiTpmDeviceSelectedGuid,
+ NULL
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiResetPpiGuid,
+ &mResetPpi
+ }
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ &gPeiSmmAccessPpiGuid,
+ CpuS3SmmAccessNotifyCallback
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ EndOfPeiPpiNotifyCallback
+ }
+};
+
+EFI_STATUS
+TpmPolicyInit (
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+#if FTPM_SUPPORT
+ EFI_STATUS Status;
+ UINTN Size;
+ BOOLEAN IsPttEnabled = TRUE;
+ MBP_ME_FW_CAPS Mbp_Me_Fw_Caps = { 0 };
+
+ DEBUG ((EFI_D_ERROR, "TpmPolicyInit entry.\n"));
+
+ //
+ // Get ME FW Capability from MBP table to determine PTT State
+ //
+ Status = HeciGetMeFwCapability (&Mbp_Me_Fw_Caps);
+ if (!EFI_ERROR (Status)) {
+ IsPttEnabled = (BOOLEAN) Mbp_Me_Fw_Caps.CurrentFeatures.Fields.PTT;
+ }
+
+ if ((IsPttEnabled) && (SystemConfiguration->TPM == TPM_PTT)) {
+ if (SystemConfiguration->PttSuppressCommandSend == 1) {
+ PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceNoneGuid);
+ DEBUG ((DEBUG_ERROR, "BIOS will send no further commands to PTT.\n"));
+ } else {
+ //
+ // Set PcdTpmInstanceGuid to PTT
+ //
+ Size = sizeof (gTpmDeviceInstanceTpm20PttPtpGuid);
+ PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gTpmDeviceInstanceTpm20PttPtpGuid);
+ DEBUG ((DEBUG_INFO, "Set PcdTpmInstanceGuid to PTT.\n"));
+ }
+ } else if (SystemConfiguration->TPM == TPM_DTPM_1_2) {
+ //
+ // Set PcdTpmInstanceGuid to dTPM 1.2
+ //
+ Size = sizeof (gEfiTpmDeviceInstanceTpm12Guid);
+ PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceTpm12Guid);
+ DEBUG ((DEBUG_INFO, "Set PcdTpmInstanceGuid to dTPM 1.2.\n"));
+ } else if (SystemConfiguration->TPM == TPM_DTPM_2_0) {
+ //
+ // Set PcdTpmInstanceGuid to dTPM 2.0
+ //
+ Size = sizeof (gEfiTpmDeviceInstanceTpm20DtpmGuid);
+ PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceTpm20DtpmGuid);
+ DEBUG ((DEBUG_INFO, "Set PcdTpmInstanceGuid to dTPM 2.0.\n"));
+ } else {
+ //
+ // Set PcdTpmInstanceGuid to NONE
+ //
+ Size = sizeof (gEfiTpmDeviceInstanceNoneGuid);
+ PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceNoneGuid);
+ DEBUG ((DEBUG_INFO, "Set PcdTpmInstanceGuid to NONE.\n"));
+ }
+#endif
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function will power off the system at once.
+
+**/
+VOID
+PowerOffNow (
+ VOID
+ )
+{
+ UINT16 AcpiBaseAddr;
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+ DEBUG ((DEBUG_INFO, " PowerOffNow: AcpiBaseAddr = 0x%x\n",AcpiBaseAddr));
+
+ //
+ // Set PM Register and Put system to S5
+ //
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5);
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5 + B_ACPI_PM1_CNT_SLP_EN);
+}
+
+
+/**
+ This function gets system config.
+
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param[in] SystemConfiguration The pointer to get System Setup
+
+
+ @retval EFI_SUCCESS The system configuration is obtained
+ @retval Other values The system configuration cannot be obtained
+
+**/
+EFI_STATUS
+GetSystemConfig (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ UINTN VariableSize;
+
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ SystemConfiguration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PWM_Fan_Start (
+ VOID
+ )
+{
+ PWMCTRL PwmCtl = {0};
+ UINT32 TimeOut = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ //
+ // Program GPIO_37 to enable FAN device
+ //
+ GpioPadWrite(N_GPIO_37,0x400);
+
+ //
+ // Set PWM Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_PMC_PWM, PCI_FUNCTION_NUMBER_PMC_PWM, R_LPSS_IO_BAR),
+ PWM_TEMP_MEM_BASE_ADDRESS
+ );
+
+ //
+ // Enable PWM Memory decode
+ //
+ MmioWrite16 (
+ MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_PMC_PWM, PCI_FUNCTION_NUMBER_PMC_PWM, R_LPSS_IO_STSCMD),
+ B_LPSS_IO_STSCMD_BME| B_LPSS_IO_STSCMD_MSE
+ );
+
+ MmioWrite32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00, PwmCtl.Raw);
+
+ //
+ // Initial Enable or First Activation for PWM
+ // 1. Program the Base Unit and On Time Divisor values.
+ // 2. Set the Software Update Bit.
+ // 3. Enable the PWM Output by setting PWM Enable.
+ // 4. Repeat the above steps for the next PWM Module.
+ //
+ PwmCtl.BITS.Pwm_Base_Unit = 0x15;
+ PwmCtl.BITS.Pwm_On_Time_Divisor = 0x80;
+ MmioWrite32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00, PwmCtl.Raw);
+
+ PwmCtl.Raw = MmioRead32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00);
+ PwmCtl.BITS.Pwm_Sw_Update = 1;
+ MmioWrite32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00, PwmCtl.Raw);
+
+ PwmCtl.Raw = MmioRead32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00);
+ while (((PwmCtl.Raw & BIT30) == BIT30) && (TimeOut < PWM_TIMEOUT_MAX)) {
+ MicroSecondDelay (1);
+ PwmCtl.Raw = MmioRead32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00);
+ TimeOut ++;
+ }
+
+ PwmCtl.Raw = MmioRead32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00);
+ PwmCtl.BITS.Pwm_Enable = 1;
+ MmioWrite32 (PWM_TEMP_MEM_BASE_ADDRESS+0x0C00, PwmCtl.Raw);
+
+ if (TimeOut > PWM_TIMEOUT_MAX) {
+ Status = EFI_TIMEOUT;
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+BXTPolicyInit (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+ EFI_STATUS Status;
+ SI_SA_POLICY_PPI *SiSaPolicyPpi;
+ SA_MISC_CONFIG *MiscConfig = NULL;
+ GRAPHICS_CONFIG *GtConfig = NULL;
+ IPU_CONFIG *IpuPolicy = NULL;
+#if (ENBDT_PF_ENABLE == 1)
+ HYBRID_GRAPHICS_CONFIG *HgConfig = NULL;
+#endif
+ VOID* Buffer;
+ UINT32 Size;
+ EFI_GUID PeiLogoGuid = { 0x7BB28B99, 0x61BB, 0x11D5, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D };
+ EFI_GUID TianmaVbtGuid = { 0xE08CA6D5, 0x8D02, 0x43ae, 0xAB, 0xB1, 0x95, 0x2C, 0xC7, 0x87, 0xC9, 0x33 };
+ VBT_INFO VbtInfo;
+ EFI_BOOT_MODE BootMode;
+
+ DEBUG ((DEBUG_INFO, " BXTPolicyInit: SystemAgent PEI Platform Policy Initialization begin \n"));
+
+ Status = CreateConfigBlocks (&SiSaPolicyPpi);
+ DEBUG ((DEBUG_INFO, "SiSaPolicyPpi->TableHeader.NumberOfBlocks = 0x%x\n ", SiSaPolicyPpi->TableHeader.NumberOfBlocks ));
+ ASSERT_EFI_ERROR (Status);
+
+
+ Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gSaMiscConfigGuid , (VOID *) &MiscConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gGraphicsConfigGuid, (VOID *) &GtConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gIpuConfigGuid, (VOID *) &IpuPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+#if (ENBDT_PF_ENABLE == 1)
+ Status = GetConfigBlock((VOID *) SiSaPolicyPpi, &gHybridGraphicsConfigGuid, (VOID *) &HgConfig);
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get the Platform Configuration from SetupData
+ //
+ GtConfig->GttMmAdr = GTTMM_BASE_ADDRESS;
+ GtConfig->GmAdr = GMADR_BASE_ADDRESS;
+ GtConfig->PeiGraphicsPeimInit = SystemConfiguration->PeiGraphicsPeimInit;
+ GtConfig->PmSupport = SystemConfiguration->PmSupport;
+ GtConfig->EnableRenderStandby = SystemConfiguration->EnableRenderStandby;
+ GtConfig->CdClock = SystemConfiguration->CdClock;
+ GtConfig->PavpEnable = SystemConfiguration->PavpEnable;
+
+ GtConfig->ForceWake = 0;
+ GtConfig->PavpLock = 1;
+ GtConfig->GraphicsFreqModify = 0;
+ GtConfig->GraphicsFreqReq = 0;
+ GtConfig->GraphicsVideoFreq = 0;
+ GtConfig->PmLock = 1;
+ GtConfig->DopClockGating = 1;
+ GtConfig->UnsolicitedAttackOverride = 0;
+ GtConfig->WOPCMSupport = 1;
+ GtConfig->WOPCMSize = 0;
+ GtConfig->PowerGating = 0;
+ GtConfig->UnitLevelClockGating = 1;
+
+ MiscConfig->FastBoot = 1;
+ MiscConfig->DynSR = 1;
+ IpuPolicy->SaIpuEnable = SystemConfiguration->IpuEn;
+ IpuPolicy->IpuAcpiMode = SystemConfiguration->IpuAcpiMode;
+ IpuPolicy->IpuMmAdr = IPUMM_BASE_ADDRESS;
+
+#if (ENBDT_PF_ENABLE == 1)
+ //
+ // In Hybrid Gfx mode PCIe needs to be always enabled
+ // and IGFX must be set as Primary Display.
+ //
+ if (SystemConfiguration->PrimaryVideoAdaptor == 4) {
+ HgConfig->HgEnabled = 1;
+ HgConfig->HgSubSystemId = 0x2112;
+ } else {
+ HgConfig->HgEnabled = 0;
+ HgConfig->HgSubSystemId = 0x2212;
+ }
+
+ HgConfig->HgDelayAfterPwrEn = SystemConfiguration->DelayAfterPwrEn;
+ HgConfig->HgDelayAfterHoldReset = SystemConfiguration->DelayAfterHoldReset;
+ //
+ // Configure below based on the OEM platfrom design
+ // Hybrid Graphics Enabled - 0= Disabled, 1=Enabled
+ //
+ if (HgConfig->HgEnabled == 1) {
+ //
+ // dGPU HLD RST GPIO assigned
+ //
+ HgConfig->HgDgpuHoldRst.CommunityOffset = (((UINT32) GPIO_MMIO_OFFSET_W) << 16);
+ HgConfig->HgDgpuHoldRst.PinOffset = 0x05B0;
+ HgConfig->HgDgpuHoldRst.Active = 0;
+ //
+ // dGPU PWR Enable GPIO assigned
+ //
+ HgConfig->HgDgpuPwrEnable.CommunityOffset = (((UINT32) GPIO_MMIO_OFFSET_N) << 16);
+ HgConfig->HgDgpuPwrEnable.PinOffset = 0x0598;
+ HgConfig->HgDgpuPwrEnable.Active = 1;
+
+ HgConfig->RootPortDev = PCI_DEVICE_NUMBER_SC_PCIE_DEVICE_2;
+ HgConfig->RootPortFun = PCI_FUNCTION_NUMBER_PCIE_ROOT_PORT_3;
+
+ DEBUG ((DEBUG_INFO, "HG::Hybrid Graphics Policy updated\n"));
+ }
+#endif
+ }
+
+ Status = (*PeiServices)->GetBootMode ((CONST EFI_PEI_SERVICES **) PeiServices, &BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ PeiGetSectionFromFv (PeiLogoGuid, &Buffer, &Size);
+ if (Buffer == NULL) {
+ DEBUG (( DEBUG_ERROR, "Could not locate PeiLogo"));
+ }
+ GtConfig->LogoPtr = Buffer;
+ GtConfig->LogoSize = Size;
+ DEBUG ((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n", Buffer));
+ DEBUG ((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n", Size));
+ DEBUG ((DEBUG_INFO, "SystemConfiguration->PanelSel = 0x%x\n", SystemConfiguration->PanelSel));
+
+ //
+ // May need a different VBT depending on PanelSel
+ //
+ PeiGetSectionFromFv (TianmaVbtGuid, &Buffer, &Size);
+
+ if (Buffer == NULL) {
+ DEBUG (( DEBUG_ERROR, "Could not locate VBT"));
+ }
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ GtConfig->GraphicsConfigPtr = NULL;
+ } else {
+ GtConfig->GraphicsConfigPtr = Buffer;
+ }
+
+ //
+ // Build the VBT data into HOB for DXE GOP
+ //
+ VbtInfo.VbtAddress = (EFI_PHYSICAL_ADDRESS) Buffer;
+ VbtInfo.VbtSize = Size;
+ DEBUG ((DEBUG_INFO, "VbtInfo VbtAddress is 0x%x\n", Buffer));
+ DEBUG ((DEBUG_INFO, "VbtInfo VbtSize is 0x%x\n", Size));
+
+ BuildGuidDataHob (
+ &gVbtInfoGuid,
+ &VbtInfo,
+ sizeof (VbtInfo)
+ );
+
+ //
+ // Install SiSaPolicyPpi.
+ // While installed, RC assumes the Policy is ready and finalized. So please
+ // update and override any setting before calling this function.
+ //
+ Status = SiSaInstallPolicyPpi (SiSaPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, " SystemAgent PEI Platform Policy Initialization Done \n"));
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Platform Init PEI module entry point
+
+ @param[in] FileHandle Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformInitEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;
+ EFI_PEI_HOB_POINTERS Hob;
+ BOARD_POST_MEM_INIT_FUNC BoardPostMemInitFunc;
+
+ DEBUG ((EFI_D_INFO, "PlatformInit EntryPoint\n"));
+ //
+ // Trigger board post mem init
+ //
+ Status = PeiServicesInstallPpi (mBoardPostMemInitStartPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set the some PCI and chipset range as UC
+ // And align to 1M at leaset
+ //
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (Hob.Raw != NULL);
+ PlatformInfo = GET_GUID_HOB_DATA (Hob.Raw);
+
+ if (PlatformInfo->SsidSvid != 0) {
+ PlatformInfo->SsidSvid = 0;
+ }
+
+
+ //
+ // Initialize GFX VT-d Base Address
+ //
+ if (BxtStepping () <= BxtA1) {
+ PcdSet32S (PcdVtdGfxBaseAddress, 0xFF000000);
+ }
+
+ PWM_Fan_Start ();
+
+ //
+ // Initialize PlatformInfo HOB
+ //
+ BoardPostMemInitFunc = (BOARD_POST_MEM_INIT_FUNC) (UINTN) PcdGet64 (PcdBoardPostMemInitFunc);
+ if (BoardPostMemInitFunc != NULL) {
+ BoardPostMemInitFunc (PeiServices, PlatformInfo);
+ }
+ // MultiPlatformInfoInit(PeiServices, PlatformInfo);
+
+ //
+ // Set the new boot mode
+ //
+ Status = UpdateBootMode (PeiServices, PlatformInfo);
+ ASSERT_EFI_ERROR (Status);
+
+ SetPlatformBootMode (PeiServices, PlatformInfo);
+
+ GetSystemConfig (PeiServices, &SystemConfiguration);
+
+ //
+ //Update the PlatformInfo Hob according to setup
+ //
+ PlatformInfo->OsSelection = 3;
+
+ //
+ // Initialize all PEI Policy
+ //
+ PeiPolicyInit (PeiServices, &SystemConfiguration);
+
+ //
+ // Do basic SC init
+ //
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_CAR_SB_INIT));
+ Status = PlatformScInit (&SystemConfiguration, PeiServices, PlatformInfo->PlatformType);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize BxtPolicy PPI
+ //
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_CAR_NB_INIT));
+ Status = BXTPolicyInit (PeiServices, &SystemConfiguration);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize TPM Policy before Initializing Platform PPIs - Tcg2Pei load depends on gEfiTpmDeviceSelectedGuid which will be installed as a part of Platform PPIs
+ //
+ Status = TpmPolicyInit (&SystemConfiguration);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize platform PPIs
+ //
+ Status = PeiServicesInstallPpi (&mPpiList[0]);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set LVDS_BKLT_CTRL to 50%.
+ //
+ MmPci8 (0, 0, 2, 0, 0xF4) = 128;
+
+ //
+ // Initialize platform PPIs
+ //
+ Status = PeiServicesNotifyPpi (&mNotifyList[0]);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Maybe move to MemoryCallBack.c (which would be called between PreMemPlatInit and PlatInit)
+ //
+ PlatformInitFinalConfig (PeiServices);
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+CpuOnlyReset (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+
+#ifdef __GNUC__
+ __asm__
+ (
+ "xorl %ecx, %ecx\n"
+ "1:hlt; hlt; hlt\n"
+ "jmp 1b\n"
+ );
+#else
+ _asm {
+ xor ecx, ecx
+ HltLoop:
+ hlt
+ hlt
+ hlt
+ loop HltLoop
+ }
+#endif
+
+ //
+ // If we get here we need to mark it as a failure.
+ //
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+ IN CONST EFI_GUID NameGuid,
+ OUT VOID **Address,
+ OUT UINT32 *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
+ EFI_FV_FILE_INFO FvFileInfo;
+ PEI_CORE_INSTANCE *PrivateData;
+ UINTN CurrentFv;
+ PEI_CORE_FV_HANDLE *CoreFvHandle;
+ EFI_PEI_FILE_HANDLE VbtFileHandle;
+ EFI_GUID *VbtGuid;
+ EFI_COMMON_SECTION_HEADER *Section;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer ();
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ Status = PeiServicesLocatePpi (
+ &gEfiFirmwareFileSystem2Guid,
+ 0,
+ NULL,
+ (VOID **) &FvPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ CurrentFv = PrivateData->CurrentPeimFvCount;
+ CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
+
+ Status = FvPpi->FindFileByName (FvPpi, &NameGuid, &CoreFvHandle->FvHandle, &VbtFileHandle);
+ if (!EFI_ERROR (Status) && VbtFileHandle != NULL) {
+
+ DEBUG ((DEBUG_INFO, "Find SectionByType \n"));
+
+ Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, VbtFileHandle, (VOID **) &VbtGuid);
+ if (!EFI_ERROR (Status)) {
+
+ DEBUG ((DEBUG_INFO, "GetFileInfo \n"));
+
+ Status = FvPpi->GetFileInfo (FvPpi, VbtFileHandle, &FvFileInfo);
+ Section = (EFI_COMMON_SECTION_HEADER *)FvFileInfo.Buffer;
+
+ if (IS_SECTION2 (Section)) {
+ ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
+ *Size = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
+ *Address = ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+ } else {
+ *Size = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
+ *Address = ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+CpuS3SmmAccessNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ //
+ // Restore Cpu settings only during S3 resume
+ //
+ S3InitializeCpu (PeiServices);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Install Firmware Volume Hob's once there is main memory
+
+ @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 EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;
+ EFI_PEI_HOB_POINTERS Hob;
+
+ DEBUG ((EFI_D_INFO, "Platform Init End of PEI signal\n"));
+
+ //
+ // Set the some PCI and chipset range as UC
+ // And align to 1M at leaset
+ //
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (Hob.Raw != NULL);
+ PlatformInfo = GET_GUID_HOB_DATA (Hob.Raw);
+
+
+ DEBUG ((EFI_D_INFO, "Memory TOLM: %X\n", PlatformInfo->MemData.MemTolm));
+ DEBUG ((EFI_D_INFO, "PCIE OSBASE: %lX\n", PlatformInfo->PciData.PciExpressBase));
+ DEBUG (
+ (EFI_D_INFO,
+ "PCIE BASE: %lX Size : %X\n",
+ PlatformInfo->PciData.PciExpressBase,
+ PlatformInfo->PciData.PciExpressSize)
+ );
+ DEBUG (
+ (EFI_D_INFO,
+ "PCI32 BASE: %X Limit: %X\n",
+ PlatformInfo->PciData.PciResourceMem32Base,
+ PlatformInfo->PciData.PciResourceMem32Limit)
+ );
+ DEBUG (
+ (EFI_D_INFO,
+ "PCI64 BASE: %lX Limit: %lX\n",
+ PlatformInfo->PciData.PciResourceMem64Base,
+ PlatformInfo->PciData.PciResourceMem64Limit)
+ );
+ DEBUG ((EFI_D_INFO, "UC START: %lX End : %lX\n", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ 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
+PlatformInitFinalConfig (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ EFI_CPUID_REGISTER FeatureInfo;
+ UINT8 CpuAddressWidth;
+ UINT16 Pm1Cnt;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;
+ UINT16 AcpiBaseAddr;
+
+ //
+ // Get Platform Info HOB
+ //
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (Hob.Raw != NULL);
+ PlatformInfo = GET_GUID_HOB_DATA (Hob.Raw);
+
+ Status = (*PeiServices)->GetBootMode ((CONST EFI_PEI_SERVICES **) PeiServices, &BootMode);
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Check if user wants to turn off in PEI phase
+ //
+ if ((BootMode != BOOT_ON_S3_RESUME) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
+ CheckPowerOffNow ();
+ } else {
+ Pm1Cnt = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_CNT);
+ Pm1Cnt &= ~B_ACPI_PM1_CNT_SLP_TYP;
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, Pm1Cnt);
+ }
+
+ //
+ // Pulish memory tyoe info
+ //
+ PublishMemoryTypeInfo ();
+
+ //
+ // Work done if on a S3 resume
+ //
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Add HOP entries for reserved MMIO ranges so that DXE will know about them.
+ // Note: this really only need to be done for addresses that are outside the upper 16MB.
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ PMC_BASE_ADDRESS,
+ 0x1000
+ );
+ DEBUG ((EFI_D_INFO, "PmcBase : 0x%x\n", PMC_BASE_ADDRESS));
+
+ //
+ // Spi BAR needs to be set to SPI_BASE_ADDRESS before it can be read..
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ SPI_BASE_ADDRESS,
+ 0x1000
+ );
+ DEBUG ((EFI_D_INFO, "SpiBase : 0x%x\n", SPI_BASE_ADDRESS));
+
+ //
+ // Local APIC
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ LOCAL_APIC_BASE_ADDRESS,
+ 0x1000
+ );
+ DEBUG ((EFI_D_INFO, "LOCAL_APIC_BASE_ADDRESS : 0x%x\n", LOCAL_APIC_BASE_ADDRESS));
+
+ //
+ // IO APIC
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ IO_APIC_BASE_ADDRESS,
+ 0x1000
+ );
+ DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS : 0x%x\n", IO_APIC_BASE_ADDRESS));
+
+ //
+ // Adding the PCIE Express area to the memory table as type 2 memory.
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ PlatformInfo->PciData.PciExpressBase,
+ PlatformInfo->PciData.PciExpressSize
+ );
+ DEBUG ((EFI_D_INFO, "PciExpressBase : 0x%x\n", PlatformInfo->PciData.PciExpressBase));
+
+ //
+ // Adding the Flashpart to the memory table as type 2 memory.
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_FIRMWARE_DEVICE,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ PcdGet32(PcdFlashBaseAddress),
+ PcdGet32(PcdFlashSize)
+ );
+ DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", PcdGet32(PcdFlashBaseAddress)));
+
+ //
+ // P2SB (BXT) 16MB
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ PcdGet32(PcdP2SBBaseAddress),
+ 0x1000000
+ );
+
+ //
+ // PMC IPC (BXT) 8KB and 4KB
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ PcdGet32(PcdPmcIpc1BaseAddress0),
+ 0x2000
+ );
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ PcdGet32(PcdPmcIpc1BaseAddress1),
+ 0x1000
+ );
+
+ //
+ // PMC SSRAM (BXT) 8KB and 4KB
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ PcdGet32(PcdPmcSsramBaseAddress0),
+ 0x2000
+ );
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ PcdGet32(PcdPmcSsramBaseAddress1),
+ 0x1000
+ );
+
+ //
+ // 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);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+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;
+}
+
+#ifdef __GNUC__
+#pragma GCC pop_options
+#else
+#pragma optimize ("", on)
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.h
new file mode 100644
index 0000000000..09813e904f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.h
@@ -0,0 +1,283 @@
+/** @file
+ Platform Early Stage header file.
+
+ Copyright (c) 1999 - 2016, 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_INIT_H_
+#define _EFI_PLATFORM_INIT_H_
+
+#define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+
+#include <CpuRegs.h>
+#include <CpuType.h>
+#include <FrameworkPei.h>
+#include <PeiSaPolicyUpdate.h>
+#include <Core/Pei/PeiMain.h>
+
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+
+#include <Guid/Capsule.h>
+#include <Guid/EfiVpdData.h>
+#include <Guid/FirmwareFileSystem.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/PlatformInfo.h>
+
+#include <Guid/RecoveryDevice.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/PlatformCpuInfo.h>
+
+#include <Ppi/AtaController.h>
+#include <Ppi/BlockIo.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Ppi/Capsule.h>
+#include <Ppi/DeviceRecoveryModule.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/Reset.h>
+#include <Ppi/SaPolicy.h>
+#include <Ppi/Smbus.h>
+#include <Ppi/Stall.h>
+#include <Ppi/CpuPolicy.h>
+#include <Ppi/FirmwareVolume.h>
+#include <Ppi/BoardInitSignalling.h>
+#include <Library/PeiPolicyInitLib.h>
+#include <Library/PeiCpuPolicyUpdateLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/SideBandLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/GpioLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PmicLib.h>
+
+#include "CMOSMap.h"
+#include "Platform.h"
+#include <PlatformBaseAddresses.h>
+#include <PlatformBootMode.h>
+#include <SaAccess.h>
+#include <ScAccess.h>
+#include <SetupMode.h>
+#include <CpuAccess.h>
+
+#define SMC_LAN_ON 0x46
+#define SMC_LAN_OFF 0x47
+#define SMC_DEEP_S3_STS 0xB2
+
+//
+// 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
+
+//
+// Define for Vibra
+//
+#define PWM_DUTY_CYCLE 0x55 // zero duty cycle is 0x32/0xff
+#define PWM_BASE_UNIT 0x3 // DRV2603 work on 10k-250k while PWM base is 19.2M, 0x3/0xFF*19.2MHz ~ 200KHz
+#define PWM_TIMEOUT_MAX 100
+#define PWM_DELAY 1000000
+
+extern EFI_GUID gVbtInfoGuid;
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS VbtAddress;
+ UINT32 VbtSize;
+} VBT_INFO;
+
+#pragma pack(push, 1)
+typedef union {
+ UINT32 Raw;
+ struct {
+ UINT32 Pwm_On_Time_Divisor :8; ///< [7:0]
+ UINT32 Pwm_Base_Unit :16; ///< [23:8]
+ UINT32 Pwm_Rsvd :6; ///< [29:24]
+ UINT32 Pwm_Sw_Update :1; ///< [30]
+ UINT32 Pwm_Enable :1; ///< [31]
+ } BITS; // Bits
+} PWMCTRL;
+#pragma pack(pop)
+
+//
+// Function Prototypes
+//
+EFI_STATUS
+PlatformScInit (
+ IN SYSTEM_CONFIGURATION *SystemConfiguration,
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 PlatformType
+ );
+
+EFI_STATUS
+EFIAPI
+IchReset (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+BOOLEAN
+GetSleepTypeAfterWakeup (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT UINT16 *SleepType
+ );
+
+EFI_STATUS
+EndOfPeiPpiNotifyCallback (
+ IN 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
+SetPlatformBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ );
+
+EFI_STATUS
+EFIAPI
+CpuOnlyReset (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+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
+ );
+
+EFI_STATUS
+InitializePlatform (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PLATFORM_INFO_HOB *PlatformInfoHob,
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ );
+
+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
+EFIAPI
+PublishMemoryTypeInfo (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+ IN CONST EFI_GUID NameGuid,
+ OUT VOID **Address,
+ OUT UINT32 *Size
+ );
+
+EFI_STATUS
+EFIAPI
+ConfigClockTrunk (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+EFI_STATUS
+EFIAPI
+PlatformInitFinalConfig (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+EFI_STATUS
+ValidateFvHeader (
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
+ );
+
+EFI_STATUS
+UpdateBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ );
+
+UINT8
+ConfigurePlatformPmic (
+ VOID
+ );
+
+VOID
+ScUsb2PhyOverride (
+ VOID
+ );
+#endif // _EFI_PLATFORM_INIT_H_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformPostMemPei.inf b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformPostMemPei.inf
new file mode 100644
index 0000000000..cd8b617017
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformPostMemPei.inf
@@ -0,0 +1,130 @@
+## @file
+# Component description file for PlatformInit module.
+#
+# Copyright (c) 1999 - 2016, 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 = PlatformInit
+ FILE_GUID = 0A5EA2E1-BE0B-44a0-A775-F429C9A018A0
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformInitEntryPoint
+
+[Sources]
+ BootMode.c
+ PlatformScInitPeim.c
+ MemoryPeim.c
+ PlatformInit.c
+ PlatformInit.h
+ PowerFailureHandle.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ HobLib
+ IoLib
+ PcdLib
+ ReportStatusCodeLib
+ PciExpressLib
+ PeiScPolicyLib
+ SteppingLib
+ SideBandLib
+ ConfigBlockLib
+ PeiSaPolicyLib
+ PeiPolicyUpdateLib
+ PeiPolicyInitLib
+ CpuPolicyLib
+ TimerLib
+ ScPlatformLib
+ CpuS3Lib
+ SeCUmaLib
+
+[Ppis]
+ gEfiPeiStallPpiGuid
+ gEfiPeiMemoryDiscoveredPpiGuid
+ gEfiPeiReadOnlyVariable2PpiGuid
+ gEfiPeiResetPpiGuid
+ gEfiEndOfPeiSignalPpiGuid
+ gPeiCapsulePpiGuid
+ gEfiPeiBootInRecoveryModePpiGuid
+ gEfiPeiRecoveryModulePpiGuid
+ gEfiPeiDeviceRecoveryModulePpiGuid
+ gPeiCachePpiGuid
+ gEfiPeiMasterBootModePpiGuid
+ gEfiPeiSmbusPpiGuid
+ gEfiPeiSmbus2PpiGuid
+ gScPolicyPpiGuid
+ gEfiPeiVirtualBlockIoPpiGuid
+ gSiSaPolicyPpiGuid
+ gDramPolicyPpiGuid
+ gBiosGuardConfigGuid
+ gCpuConfigGuid
+ gCpuOverclockingConfigGuid
+ gPowerMgmtConfigGuid
+ gSiPolicyPpiGuid
+
+[Guids]
+ gEfiSetupVariableGuid
+ gEfiPlatformInfoGuid
+ gEfiPlatformBootModeGuid
+ gEfiPlatformCpuInfoGuid
+ gEfiGlobalVariableGuid
+ gRecoveryOnFatFloppyDiskGuid
+ gRecoveryOnFatUsbDiskGuid
+ gRecoveryOnFatIdeDiskGuid
+ gRecoveryOnDataCdGuid
+ gMfgModeVariableGuid
+ gEfiNormalSetupGuid
+ gEfiMemoryTypeInformationGuid
+ gVbtInfoGuid
+ gPcieRpConfigGuid
+ gSataConfigGuid
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdFlashBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBXBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBXSize
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiIchTokenSpaceGuid.PcdPeiIchEhciControllerMemoryBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdScsiChunk
+ gPlatformModuleTokenSpaceGuid.PcdUfsInitStall
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdP2SBBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdPmcIpc1BaseAddress0
+ gEfiBxtTokenSpaceGuid.PcdPmcIpc1BaseAddress1
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdPmcSsramBaseAddress0
+ gEfiBxtTokenSpaceGuid.PcdPmcSsramBaseAddress1
+ gEfiBxtTokenSpaceGuid.PcdVtdGfxBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdTcoBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdVibratorFeature
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES
+ gPlatformModuleTokenSpaceGuid.PcdBoardPostMemInitFunc
+
+[Depex]
+ gDramPolicyPpiGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformScInitPeim.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformScInitPeim.c
new file mode 100644
index 0000000000..554096db57
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformScInitPeim.c
@@ -0,0 +1,322 @@
+/** @file
+ Early SC platform initialization.
+
+ Copyright (c) 2012 - 2016, 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 <Library/PcdLib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PeiScPolicyLib.h>
+#include <Library/SideBandLib.h>
+#include <Library/PeiScPolicyUpdateLib.h>
+#include <Library/SteppingLib.h>
+#include <Library/ScPlatformLib.h>
+#include "PlatformInit.h"
+#include <Ppi/ScPolicy.h>
+#include <ScAccess.h>
+#include <PlatformBaseAddresses.h>
+#include <Ppi/ScPcieDeviceTable.h>
+#include <Ppi/SiPolicyPpi.h>
+#include <Library/MmPciLib.h>
+
+
+VOID
+ScPolicySetupInit (
+ 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_RTC_EXT_INDEX, Address);
+ Data = IoRead8 (R_RTC_EXT_TARGET);
+
+ return Data;
+}
+
+
+VOID
+WriteCmosBank1Byte (
+ IN UINT8 Address,
+ IN UINT8 Data
+ )
+{
+ IoWrite8 (R_RTC_EXT_INDEX, Address);
+ IoWrite8 (R_RTC_EXT_TARGET, Data);
+}
+
+
+EFI_STATUS
+InstallPeiScUsbPolicy (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+
+VOID
+CheckPowerOffNow (
+ VOID
+ )
+{
+ UINT16 Pm1Sts;
+ UINT16 AcpiBaseAddr;
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Read and check the ACPI registers
+ //
+ Pm1Sts = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_STS);
+ if ((Pm1Sts & B_ACPI_PM1_STS_PWRBTN) == B_ACPI_PM1_STS_PWRBTN) {
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_STS, B_ACPI_PM1_STS_PWRBTN);
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5);
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5 + B_ACPI_PM1_CNT_SLP_EN);
+ }
+}
+
+
+VOID
+ClearPowerState (
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+ UINT16 Data16;
+ UINT32 Data32;
+ UINT16 AcpiBaseAddr;
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Clear the GPE and PM enable
+ //
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_EN, (UINT16) 0x00);
+ IoWrite32 (AcpiBaseAddr + R_ACPI_GPE0a_EN, (UINT32) 0x00);
+
+ //
+ // Halt the TCO timer
+ //
+ Data16 = IoRead16 (AcpiBaseAddr + R_TCO_CNT);
+ Data16 |= B_TCO_CNT_TMR_HLT;
+ IoWrite16 (AcpiBaseAddr + R_TCO_CNT, Data16);
+
+ //
+ // NMI NOW bit is "Write '1' to clear"
+ //
+
+ //
+ // Before we clear the TO status bit here we need to save the results in a CMOS bit for later use.
+ //
+ Data32 = IoRead16 (AcpiBaseAddr + R_TCO_STS);
+ if ((Data32 & B_TCO_STS_SECOND_TO) == B_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;
+ UINT16 AcpiBaseAddr;
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Read the ACPI registers
+ //
+ Pm1Sts = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_STS);
+ Gpe0Sts = IoRead32 (AcpiBaseAddr + R_ACPI_GPE0a_STS);
+ SmiSts = IoRead32 (AcpiBaseAddr + R_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 (EFI_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_ACPI_PM1_STS_PWRBTN) || (Gpe0Sts & (B_ACPI_GPE0a_STS_CORE_GPIO | B_ACPI_GPE0a_STS_SUS_GPIO))) {
+ WriteCmosBank1Byte (EFI_CMOS_S4_WAKEUP_FLAG_ADDRESS, 1);
+ }
+
+ //
+ // Clear any SMI or wake state from the boot
+ //
+ Pm1Sts = (B_ACPI_PM1_STS_PRBTNOR | B_ACPI_PM1_STS_PWRBTN);
+
+ Gpe0Sts |=
+ (
+ B_ACPI_GPE0a_STS_CORE_GPIO |
+ B_ACPI_GPE0a_STS_SUS_GPIO |
+ B_ACPI_GPE0a_STS_PME_B0 |
+ B_ACPI_GPE0a_STS_BATLOW |
+ B_ACPI_GPE0a_STS_PCI_EXP |
+ B_ACPI_GPE0a_STS_GUNIT_SCI |
+ B_ACPI_GPE0a_STS_PUNIT_SCI |
+ B_ACPI_GPE0a_STS_SWGPE |
+ B_ACPI_GPE0a_STS_HOT_PLUG
+ );
+
+ SmiSts |=
+ (
+ B_SMI_STS_PERIODIC |
+ B_SMI_STS_TCO |
+ B_SMI_STS_SWSMI_TMR |
+ B_SMI_STS_APM |
+ B_SMI_STS_ON_SLP_EN |
+ B_SMI_STS_BIOS
+ );
+
+ //
+ // Write them back
+ //
+ IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_STS, Pm1Sts);
+ IoWrite32 (AcpiBaseAddr + R_ACPI_GPE0a_STS, Gpe0Sts);
+ IoWrite32 (AcpiBaseAddr + R_SMI_STS, SmiSts);
+}
+
+
+/**
+ 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 occurred.
+ @retval EFI_DEVICE_ERROR Device error, could not reset the system.
+
+**/
+EFI_STATUS
+EFIAPI
+IchReset (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ IoWrite8 (
+ R_RST_CNT,
+ V_RST_CNT_HARDSTARTSTATE
+ );
+
+ IoWrite8 (
+ R_RST_CNT,
+ V_RST_CNT_HARDRESET
+ );
+
+ //
+ // System reset occurred, should never reach at this line.
+ //
+ ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+EFI_STATUS
+PlatformScInit (
+ IN SYSTEM_CONFIGURATION *SystemConfiguration,
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 PlatformType
+ )
+{
+ BXT_SERIES BxtSeries;
+ //
+ // SC Policy Initialization based on Setup variable.
+ //
+ ScPolicySetupInit (PeiServices);
+
+ //
+ // Install PCIe device override table
+ //
+ BxtSeries = GetBxtSeries ();
+ if (BxtSeries == BxtP) {
+ //
+ // Set TCO Base Address
+ //
+ SetTcoBase (PcdGet16 (PcdTcoBaseAddress));
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+ScPolicySetupInit (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ SC_POLICY_PPI *ScPolicyPpi;
+
+ //
+ // Install SC Policy PPI. As we depend on SC Init PPI so we are executed after
+ // ScInit PEIM. Thus we can insure SC Initialization is performed when we install the SC Policy PPI,
+ // as ScInit PEIM registered a notification function on our policy PPI.
+ //
+ // For better code structure / modularity, we should use a notification function on SC Init PPI to perform
+ // actions that depend on ScInit PEIM's initialization.
+ //
+ DEBUG ((EFI_D_INFO, "ScPolicySetupInit() - Start\n"));
+ ScCreateConfigBlocks (&ScPolicyPpi);
+
+ UpdatePeiScPolicy (ScPolicyPpi);
+
+ //
+ // Install SC Policy PPI
+ //
+ Status = ScInstallPolicyPpi (ScPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "ScPolicySetupInit() - End\n"));
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PowerFailureHandle.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PowerFailureHandle.c
new file mode 100644
index 0000000000..e1cb27cbe7
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PowerFailureHandle.c
@@ -0,0 +1,126 @@
+/** @file
+ RTC Power failure handler.
+
+ Copyright (c) 1999 - 2016, 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 "PlatformInit.h"
+
+
+BOOLEAN
+IsRtcUipAlwaysSet (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_PEI_STALL_PPI *StallPpi;
+ UINTN Count;
+
+ (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (VOID **) &StallPpi);
+
+ for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
+ IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERA);
+ if ((IoRead8 (R_RTC_TARGET2) & B_RTC_REGISTERA_UIP) == 0) {
+ return FALSE;
+ }
+
+ StallPpi->Stall (PeiServices, StallPpi, 3000);
+ }
+
+ return TRUE;
+}
+
+
+EFI_STATUS
+RtcPowerFailureHandler (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINT16 DataUint16;
+ UINT8 DataUint8;
+ BOOLEAN RtcUipIsAlwaysSet;
+
+ //
+ // When the RTC_PWR_STS bit is set, it indicates that the RTCRST# signal went low.
+ // Software should clear this bit. Changing the RTC battery sets this bit.
+ // System BIOS should reset CMOS to default values if the RTC_PWR_STS bit is set.
+ //
+ // The System BIOS should execute the sequence below if the RTC_PWR_STS bit is set before memory initialization.
+ // 1. If the RTC_PWR_STS bit is set which indicates a new coin-cell battery insertion or a battery failure,
+ // steps 2 through 5 should be executed.
+ // 2. Set RTC Register 0x0A[6:4] to '110' or '111'.
+ // 3. Set RTC Register 0x0B[7].
+ // 4. Set RTC Register 0x0A[6:4] to '010'.
+ // 5. Clear RTC Register 0x0B[7].
+ //
+ DataUint16 = MmioRead16 (PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1);
+ RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices);
+ if ((DataUint16 & B_PMC_GEN_PMCON_RTC_PWR_STS) || (RtcUipIsAlwaysSet)) {
+ //
+ // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
+ //
+ // Step 1.
+ // BIOS clears this bit by writing a '0' to it.
+ //
+ if (DataUint16 & B_PMC_GEN_PMCON_RTC_PWR_STS) {
+ DataUint16 &= ~B_PMC_GEN_PMCON_RTC_PWR_STS;
+ MmioWrite16 ((PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1), DataUint16);
+
+ //
+ // Set to invalid date to be set later to a valid time
+ //
+ IoWrite8 (R_RTC_INDEX2, R_RTC_YEAR);
+ IoWrite8 (R_RTC_TARGET2, 0x0FF);
+ IoWrite8 (R_RTC_INDEX2, R_RTC_MONTH);
+ IoWrite8 (R_RTC_TARGET2, 0x0FF);
+ IoWrite8 (R_RTC_INDEX2, R_RTC_DAYOFMONTH);
+ IoWrite8 (R_RTC_TARGET2, 0x0FF);
+ IoWrite8 (R_RTC_INDEX2, R_RTC_DAYOFWEEK);
+ IoWrite8 (R_RTC_TARGET2, 0x0FF);
+ }
+
+ //
+ // Step 2.
+ // Set RTC Register 0Ah[6:4] to '110' or '111'.
+ //
+ IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERA);
+ IoWrite8 (R_RTC_TARGET2, (V_RTC_REGISTERA_DV_DIV_RST1 | V_RTC_REGISTERA_RS_976P5US));
+
+ //
+ // Step 3.
+ // Set RTC Register 0Bh[7].
+ //
+ IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERB);
+ DataUint8 = (IoRead8 (R_RTC_TARGET2) | B_RTC_REGISTERB_SET);
+ IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERB);
+ IoWrite8 (R_RTC_TARGET2, DataUint8);
+
+ //
+ // Step 4.
+ // Set RTC Register 0Ah[6:4] to '010'.
+ //
+ IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERA);
+ IoWrite8 (R_RTC_TARGET2, (V_RTC_REGISTERA_DV_NORM_OP | V_RTC_REGISTERA_RS_976P5US));
+
+ //
+ // Step 5.
+ // Clear RTC Register 0Bh[7].
+ //
+ IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERB);
+ DataUint8 = (IoRead8 (R_RTC_TARGET2) & (UINT8)~B_RTC_REGISTERB_SET);
+ IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERB);
+ IoWrite8 (R_RTC_TARGET2, DataUint8);
+ }
+
+ return EFI_SUCCESS;
+}
+
+