summaryrefslogtreecommitdiff
path: root/Vlv2TbltDevicePkg/PlatformPei
diff options
context:
space:
mode:
authorDavid Wei <david.wei@intel.com>2015-01-12 09:37:20 +0000
committerzwei4 <zwei4@Edk2>2015-01-12 09:37:20 +0000
commit3cbfba02fef9dae07a041fdbf2e89611d72d6f90 (patch)
tree0b3bf0783124d38a191e09736492c0141aa36c15 /Vlv2TbltDevicePkg/PlatformPei
parent6f785cfcc304c48ec04e542ee429df95e7b51bc5 (diff)
downloadedk2-platforms-3cbfba02fef9dae07a041fdbf2e89611d72d6f90.tar.xz
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
https://svn.code.sf.net/p/edk2/code/trunk/edk2/, which are for MinnowBoard MAX open source project. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: David Wei <david.wei@intel.com> Reviewed-by: Mike Wu <mike.wu@intel.com> Reviewed-by: Hot Tian <hot.tian@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16599 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'Vlv2TbltDevicePkg/PlatformPei')
-rw-r--r--Vlv2TbltDevicePkg/PlatformPei/BootMode.c403
-rw-r--r--Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h65
-rw-r--r--Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c160
-rw-r--r--Vlv2TbltDevicePkg/PlatformPei/Platform.c1063
-rw-r--r--Vlv2TbltDevicePkg/PlatformPei/Platform.h216
-rw-r--r--Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf136
-rw-r--r--Vlv2TbltDevicePkg/PlatformPei/Stall.c95
7 files changed, 2138 insertions, 0 deletions
diff --git a/Vlv2TbltDevicePkg/PlatformPei/BootMode.c b/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
new file mode 100644
index 0000000000..4d933a09db
--- /dev/null
+++ b/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
@@ -0,0 +1,403 @@
+/** @file
+
+ Copyright (c) 2004 - 2014, 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 that 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.
+
+
+Module Name:
+
+
+ BootMode.c
+
+Abstract:
+
+ EFI PEIM to provide the platform support functionality on the Thurley.
+
+
+--*/
+#include "CommonHeader.h"
+#include "Platform.h"
+#include "PlatformBaseAddresses.h"
+#include "PchAccess.h"
+#include "PlatformBootMode.h"
+#include <Guid/SetupVariable.h>
+
+#include <Guid/BootState.h>
+
+//
+// Priority of our boot modes, highest priority first
+//
+EFI_BOOT_MODE mBootModePriority[] = {
+ BOOT_IN_RECOVERY_MODE,
+ BOOT_WITH_DEFAULT_SETTINGS,
+ BOOT_ON_FLASH_UPDATE,
+ BOOT_ON_S2_RESUME,
+ BOOT_ON_S3_RESUME,
+ BOOT_ON_S4_RESUME,
+ BOOT_WITH_MINIMAL_CONFIGURATION,
+ BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
+ BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
+ BOOT_WITH_FULL_CONFIGURATION,
+ BOOT_ON_S5_RESUME
+};
+
+EFI_PEI_NOTIFY_DESCRIPTOR mCapsuleNotifyList[1] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiCapsulePpiGuid,
+ CapsulePpiNotifyCallback
+ }
+};
+
+BOOLEAN
+GetSleepTypeAfterWakeup (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT UINT16 *SleepType
+ );
+
+EFI_STATUS
+EFIAPI
+CapsulePpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ PEI_CAPSULE_PPI *Capsule;
+
+ Status = (*PeiServices)->GetBootMode((const EFI_PEI_SERVICES **)PeiServices, &BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ //
+ // Determine if we're in capsule update mode
+ //
+ Status = (*PeiServices)->LocatePpi ((const EFI_PEI_SERVICES **)PeiServices,
+ &gPeiCapsulePpiGuid,
+ 0,
+ NULL,
+ (VOID **)&Capsule
+ );
+
+ if (Status == EFI_SUCCESS) {
+ if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES**)PeiServices) == EFI_SUCCESS) {
+ BootMode = BOOT_ON_FLASH_UPDATE;
+ Status = (*PeiServices)->SetBootMode((const EFI_PEI_SERVICES **)PeiServices, BootMode);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Check CMOS register bit to determine if previous boot was successful
+
+ @param PeiServices pointer to the PEI Service Table
+
+ @retval TRUE - Previous Boot was success
+ @retval FALSE - Previous Boot wasn't success
+
+**/
+BOOLEAN
+IsPreviousBootSuccessful(
+ IN CONST EFI_PEI_SERVICES **PeiServices
+
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN BootState;
+ UINTN DataSize;
+ CHAR16 VarName[] = BOOT_STATE_VARIABLE_NAME;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar;
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (void **)&PeiVar
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get last Boot State Variable to confirm that it is not a first boot .
+ //
+
+ DataSize = sizeof (BOOLEAN);
+ Status = PeiVar->GetVariable (
+ PeiVar,
+ VarName,
+ &gEfiBootStateGuid,
+ NULL,
+ &DataSize,
+ &BootState
+ );
+ if (EFI_ERROR (Status) || (BootState == TRUE)) {
+ return FALSE;
+ }
+
+ DEBUG ((EFI_D_INFO, "Previous boot cycle successfully completed handover to OS\n"));
+ return TRUE;
+}
+#ifdef NOCS_S3_SUPPORT
+EFI_STATUS
+UpdateBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ UINT16 SleepType;
+ CHAR16 *strBootMode;
+
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ ASSERT_EFI_ERROR (Status);
+ if (BootMode == BOOT_IN_RECOVERY_MODE){
+ return Status;
+ }
+
+ //
+ // Let's assume things are OK if not told otherwise
+ //
+ BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+ if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {
+ switch (SleepType) {
+ case V_PCH_ACPI_PM1_CNT_S3:
+ BootMode = BOOT_ON_S3_RESUME;
+ Status = (*PeiServices)->NotifyPpi (PeiServices, &mCapsuleNotifyList[0]);
+ ASSERT_EFI_ERROR (Status);
+ break;
+
+ case V_PCH_ACPI_PM1_CNT_S4:
+ BootMode = BOOT_ON_S4_RESUME;
+ break;
+
+ case V_PCH_ACPI_PM1_CNT_S5:
+ BootMode = BOOT_ON_S5_RESUME;
+ break;
+ } // switch (SleepType)
+ }
+
+ if (IsFastBootEnabled (PeiServices) && IsPreviousBootSuccessful (PeiServices)) {
+ DEBUG ((EFI_D_INFO, "Prioritizing Boot mode to BOOT_WITH_MINIMAL_CONFIGURATION\n"));
+ PrioritizeBootMode (&BootMode, BOOT_WITH_MINIMAL_CONFIGURATION);
+ }
+
+ 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_ERROR, "Setting BootMode to %s\n", strBootMode));
+ Status = (*PeiServices)->SetBootMode(PeiServices, BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+#endif
+
+/**
+ Get sleep type after wakeup
+
+ @param PeiServices Pointer to the PEI Service Table.
+ @param 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;
+ UINT16 GenPmCon1;
+ //
+ // VLV BIOS Specification 0.6.2 - Section 18.4, "Power Failure Consideration"
+ //
+ // 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 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
+
+ //
+ // Read the ACPI registers
+ //
+ Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
+ Pm1Cnt = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
+
+ if ((GenPmCon1 & (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR | B_PCH_PMC_GEN_PMCON_GEN_RST_STS)) ||
+ (Pm1Sts & B_PCH_ACPI_PM1_STS_PRBTNOR)) {
+ //
+ // 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_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {
+ Pm1Cnt = ((Pm1Cnt & ~B_PCH_ACPI_PM1_CNT_SLP_TYP) | V_PCH_ACPI_PM1_CNT_S5);
+ IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+ }
+ //
+ // Clear Wake Status (WAK_STS)
+ //
+ }
+ //
+ // Get sleep type if a wake event occurred and there is no power failure
+ //
+ if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {
+ *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
+ return TRUE;
+ } else if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S4) {
+ *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOLEAN
+EFIAPI
+IsFastBootEnabled (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
+ UINTN VarSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ BOOLEAN FastBootEnabledStatus;
+
+ FastBootEnabledStatus = FALSE;
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (void **)&PeiReadOnlyVarPpi
+ );
+ if (Status == EFI_SUCCESS) {
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = PeiReadOnlyVarPpi->GetVariable (
+ PeiReadOnlyVarPpi,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+ if (Status == EFI_SUCCESS) {
+ if (SystemConfiguration.FastBoot != 0) {
+ FastBootEnabledStatus = TRUE;
+ }
+ }
+ }
+
+ return FastBootEnabledStatus;
+}
+
+/**
+ Given the current boot mode, and a proposed new boot mode, determine
+ which has priority. If the new boot mode has higher priority, then
+ make it the current boot mode.
+
+ @param CurrentBootMode pointer to current planned boot mode
+ @param NewBootMode proposed boot mode
+
+ @retval EFI_NOT_FOUND if either boot mode is not recognized
+ @retval EFI_SUCCESS if both boot mode values were recognized and
+ were processed.
+**/
+EFI_STATUS
+PrioritizeBootMode (
+ IN OUT EFI_BOOT_MODE *CurrentBootMode,
+ IN EFI_BOOT_MODE NewBootMode
+ )
+{
+ UINT32 CurrentIndex;
+ UINT32 NewIndex;
+
+ //
+ // Find the position of the current boot mode in our priority array
+ //
+ for ( CurrentIndex = 0;
+ CurrentIndex < sizeof (mBootModePriority) / sizeof (mBootModePriority[0]);
+ CurrentIndex++) {
+ if (mBootModePriority[CurrentIndex] == *CurrentBootMode) {
+ break;
+ }
+ }
+ if (CurrentIndex >= sizeof (mBootModePriority) / sizeof (mBootModePriority[0])) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Find the position of the new boot mode in our priority array
+ //
+ for ( NewIndex = 0;
+ NewIndex < sizeof (mBootModePriority) / sizeof (mBootModePriority[0]);
+ NewIndex++) {
+ if (mBootModePriority[NewIndex] == NewBootMode) {
+ //
+ // If this new boot mode occurs before the current boot mode in the
+ // priority array, then take it.
+ //
+ if (NewIndex < CurrentIndex) {
+ *CurrentBootMode = NewBootMode;
+ }
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
diff --git a/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h b/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
new file mode 100644
index 0000000000..19e26acdcf
--- /dev/null
+++ b/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
@@ -0,0 +1,65 @@
+/*++
+
+ Copyright (c) 2004 - 2014, 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 that 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 __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <FrameworkPei.h>
+
+#include <IndustryStandard/SmBus.h>
+#include <IndustryStandard/Pci22.h>
+#include <Ppi/AtaController.h>
+#include <Guid/Capsule.h>
+#include <Ppi/Cache.h>
+#include <Ppi/MasterBootMode.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/RecoveryDevice.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/FvLoadFile.h>
+#include <Ppi/DeviceRecoveryModule.h>
+#include <Ppi/Capsule.h>
+#include <Ppi/Reset.h>
+#include <Ppi/Stall.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/Smbus2.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/MtrrLib.h>
+
+
+#endif
diff --git a/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c b/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
new file mode 100644
index 0000000000..82954d3a50
--- /dev/null
+++ b/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
@@ -0,0 +1,160 @@
+/** @file
+
+ Copyright (c) 2004 - 2014, 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 that 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.
+
+
+
+ This file includes a memory call back function notified when MRC is done,
+ following action is performed in this file,
+ 1. ICH initialization after MRC.
+ 2. SIO initialization.
+ 3. Install ResetSystem and FinvFv PPI.
+ 4. Set MTRR for PEI
+ 5. Create FV HOB and Flash HOB
+
+
+**/
+
+
+#include "CommonHeader.h"
+#include "Platform.h"
+#include <Ppi/Cache.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/PciLib.h>
+#include "VlvAccess.h"
+
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode[] = {
+{ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiBootInRecoveryModePpiGuid,
+ NULL
+}
+};
+
+#if 0
+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;
+}
+
+#endif
+/**
+ This function will be called when MRC is done.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param NotifyDescriptor Information about the notify event..
+ @param Ppi The notify context.
+
+ @retval EFI_SUCCESS If the function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ UINT32 Pages;
+ VOID* Memory;
+ UINTN Size;
+
+ //
+ // Allocate LM memory and configure PDM if enabled by user.
+ // ConfigureLM(PeiServices);
+ //
+ Status = (*PeiServices)->GetBootMode (
+ (const EFI_PEI_SERVICES **)PeiServices,
+ &BootMode
+ );
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ Size = (PcdGet32 (PcdFlashFvRecovery2Base) - PcdGet32 (PcdFlashFvMainBase)) + FixedPcdGet32(PcdFlashFvRecovery2Size);
+ Pages= Size/0x1000;
+
+ Memory = AllocatePages ( Pages );
+ CopyMem(Memory , (VOID *) FixedPcdGet32(PcdFlashFvMainBase) , Size);
+
+ //
+ // We don't verify just load
+ //
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ (VOID *) ((UINTN) Memory + (PcdGet32 (PcdFlashFvRecovery2Base) - PcdGet32 (PcdFlashFvMainBase))),
+ PcdGet32 (PcdFlashFvRecovery2Size),
+ NULL,
+ NULL
+ );
+
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ (VOID *) Memory,
+ PcdGet32 (PcdFlashFvMainSize),
+ NULL,
+ NULL
+ );
+
+ }
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ (VOID *) (UINTN) (PcdGet32 (PcdFlashFvRecovery2Base)),
+ PcdGet32 (PcdFlashFvRecovery2Size),
+ NULL,
+ NULL
+ );
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Vlv2TbltDevicePkg/PlatformPei/Platform.c b/Vlv2TbltDevicePkg/PlatformPei/Platform.c
new file mode 100644
index 0000000000..1dab9ca851
--- /dev/null
+++ b/Vlv2TbltDevicePkg/PlatformPei/Platform.c
@@ -0,0 +1,1063 @@
+/** @file
+
+ Copyright (c) 2004 - 2014, 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 that 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.
+
+
+
+Module Name:
+
+**/
+
+#include "CommonHeader.h"
+
+#include "Platform.h"
+#include <Library/PciCf8Lib.h>
+#include "PlatformBaseAddresses.h"
+#include "PchAccess.h"
+#include <Guid/PlatformInfo.h>
+#include "Platform.h"
+#include "PchCommonDefinitions.h"
+#include <Ppi/MfgMemoryTest.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/Vlv2Variable.h>
+
+//
+// Start::Alpine Valley platform
+//
+enum {
+ SMBUS_READ_BYTE,
+ SMBUS_WRITE_BYTE,
+ SMBUS_READ_BLOCK,
+ SMBUS_WRITE_BLOCK
+};
+
+#define EC_BASE 0xE0000000
+
+//
+// DEVICE 0 (Memroy Controller Hub)
+//
+#define MC_BUS 0x00
+#define MC_DEV 0x00
+#define MC_FUN 0x00
+#define MC_DEV_FUN (MC_DEV << 3)
+#define MC_BUS_DEV_FUN ((MC_BUS << 8) + MC_DEV_FUN)
+
+//
+// SysCtl SMBus address and block size
+//
+#define AV_SC_SMBUS_ADDRESS 0x60
+#define AV_SC_BYTE_LEN 1
+#define AV_SC_BLOCK_LEN 4
+#define AV_SC_SMBUS_WRCMD 1
+#define AV_SC_SMBUS_RDCMD 0
+
+//
+// SysCtl registers offset
+//
+#define AV_SC_REG_PLATFORM_ID 24 // 0x18
+#define AV_SC_REG_BOARD_ID 28 // 0x1C
+#define AV_SC_REG_FAB_ID 32 // 0x20
+#define AV_SC_REG_ECO_ID 68 // 0x44
+#define AV_SC_REG_DDR_DAUGHTER_CARD_ID 144 // 0x90
+#define AV_SC_REG_SODIMM_CONFIG 36
+
+//
+// ID values
+//
+#define AV_SC_PLATFORM_ID_TABLET 0
+#define AV_SC_PLATFORM_ID_NETBOOK 2
+#define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD
+#define AV_SC_BOARD_ID_AV_SVP 1492
+
+#define BUS_TRIES 3 // How many times to retry on Bus Errors
+
+#define GTT_SIZE_1MB 1
+#define GTT_SIZE_2MB 2
+
+#define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \
+ MmioRead16(PciExpressBase + \
+ (UINTN)(Bus << 20) + \
+ (UINTN)(Device << 15) + \
+ (UINTN)(Function << 12) + \
+ (UINTN)(Register))
+#define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register, Data ) \
+ MmioWrite16(PciExpressBase + \
+ (UINTN)(Bus << 20) + \
+ (UINTN)(Device << 15) + \
+ (UINTN)(Function << 12) + \
+ (UINTN)(Register), \
+ (UINT16)Data)
+
+
+//
+//Memory Test Manufacturing mode
+//
+UINT32 DataPatternForMemoryTest[] = {
+ 0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF,
+ 0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55,
+ 0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555,
+ 0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555
+};
+#define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32))
+
+//
+//Memory Test Manufacturing mode
+//
+//
+// The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
+//
+BOOLEAN ImageInMemory = FALSE;
+
+EFI_STATUS
+EFIAPI
+Stall (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_STALL_PPI *This,
+ IN UINTN Microseconds
+ );
+
+EFI_STATUS
+EFIAPI
+MfgMemoryTest (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_MFG_MEMORY_TEST_PPI *This,
+ IN UINT32 BeginAddress,
+ IN UINT32 MemoryLength
+ );
+
+static EFI_PEI_STALL_PPI mStallPpi = {
+ PEI_STALL_RESOLUTION,
+ Stall
+};
+
+static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi = {
+ MfgMemoryTest
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiPeiStallPpiGuid,
+ &mStallPpi
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiMfgMemoryTestPpiGuid,
+ &mPeiMfgMemoryTestPpi
+ }
+ };
+
+EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMemoryDiscoveredPpiGuid,
+ MemoryDiscoveredPpiNotifyCallback
+ }
+};
+
+EFI_STATUS
+EFIAPI
+InstallMonoStatusCode (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+
+EFI_STATUS
+ReadPlatformIds (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ );
+
+//
+// Start::Alpine Valley platform
+//
+EFI_STATUS
+PeiSmbusExec (
+ UINT16 SmbusBase,
+ UINT8 SlvAddr,
+ UINT8 Operation,
+ UINT8 Offset,
+ UINT8 *Length,
+ UINT8 *Buffer
+ );
+
+/**
+ This routine attempts to acquire the SMBus
+
+ @retval FAILURE as failed
+ @retval SUCCESS as passed
+
+**/
+EFI_STATUS
+AcquireBus (
+ UINT16 SmbusBase
+ )
+{
+ UINT8 StsReg;
+
+ StsReg = 0;
+ StsReg = (UINT8)IoRead8(SmbusBase + R_PCH_SMBUS_HSTS);
+ if (StsReg & B_PCH_SMBUS_IUS) {
+ return EFI_DEVICE_ERROR;
+ } else if (StsReg & B_PCH_SMBUS_HBSY) {
+ //
+ // Clear Status Register and exit
+ //
+ // Wait for HSTS.HBSY to be clear
+ //
+ do { StsReg = (UINT8) IoRead8(SmbusBase+R_PCH_SMBUS_HSTS); } while ((StsReg & B_PCH_SMBUS_HBSY) != 0);
+
+ //
+ // Clear all status bits
+ //
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, 0xFE);
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Clear out any odd status information (Will Not Clear In Use)
+ //
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, StsReg);
+ return EFI_SUCCESS;
+ }
+}
+//
+// End::Alpine Valley platform
+//
+
+/**
+ This function checks the memory range in PEI.
+
+ @param PeiServices Pointer to PEI Services.
+ @param This Pei memory test PPI pointer.
+ @param BeginAddress Beginning of the memory address to be checked.
+ @param MemoryLength Bytes of memory range to be checked.
+ @param Operation Type of memory check operation to be performed.
+ @param ErrorAddress Return the address of the error memory address.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory.
+
+**/
+EFI_STATUS
+EFIAPI
+MfgMemoryTest (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_MFG_MEMORY_TEST_PPI *This,
+ IN UINT32 BeginAddress,
+ IN UINT32 MemoryLength
+ )
+{
+ UINT32 i;
+ UINT32 memAddr;
+ UINT32 readData;
+ UINT32 xorData;
+ UINT32 TestFlag = 0;
+ memAddr = BeginAddress;
+
+ //
+ //Output Message for MFG
+ //
+ DEBUG ((EFI_D_ERROR, "MFGMODE SET\n"));
+
+ //
+ //Writting the pattern in defined location.
+ //
+ while (memAddr < (BeginAddress+MemoryLength)) {
+ for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
+ if (memAddr > (BeginAddress+MemoryLength -4)) {
+ memAddr = memAddr + 4;
+ break;
+ }
+ *((volatile UINT32*) memAddr) = DataPatternForMemoryTest[i];
+ memAddr = memAddr + 4;
+ }
+ }
+
+ //
+ //Verify the pattern.
+ //
+ memAddr = BeginAddress;
+ while (memAddr < (BeginAddress+MemoryLength)) {
+ for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
+ if (memAddr > (BeginAddress+MemoryLength -4)) {
+ memAddr = memAddr + 4;
+ break;
+ }
+ readData = *((volatile UINT32*) memAddr);
+ xorData = readData ^ DataPatternForMemoryTest[i];
+
+ //
+ // If xorData is nonzero, this particular memAddr has a failure.
+ //
+ if (xorData != 0x00000000) {
+ DEBUG ((EFI_D_ERROR, "Expected value....: %x\n", DataPatternForMemoryTest[i]));
+ DEBUG ((EFI_D_ERROR, "ReadData value....: %x\n", readData));
+ DEBUG ((EFI_D_ERROR, "Pattern failure at....: %x\n", memAddr));
+ TestFlag = 1;
+ }
+ memAddr = memAddr + 4;
+ }
+ }
+ if (TestFlag) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Output Message for MFG
+ //
+ DEBUG ((EFI_D_ERROR, "MFGMODE MEMORY TEST PASSED\n"));
+ return EFI_SUCCESS;
+}
+
+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_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
+ if ((IoRead8 (R_PCH_RTC_TARGET2) & B_PCH_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;
+ DataUint16 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
+ RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices);
+ if ((DataUint16 & B_PCH_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_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
+ //
+ // Set to invalid date in order to reset the time to
+ // BIOS build time later in the boot (SBRUN.c file).
+ //
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_YEAR);
+ IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MONTH);
+ IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFMONTH);
+ IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFWEEK);
+ IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
+
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_SECONDSALARM);
+ IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MINUTESALARM);
+ IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_HOURSALARM);
+ IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
+ }
+
+ //
+ // Step 2.
+ // Set RTC Register 0Ah[6:4] to '110' or '111'.
+ //
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
+ IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_DIV_RST1 | V_PCH_RTC_REGISTERA_RS_976P5US));
+
+ //
+ // Step 3.
+ // Set RTC Register 0Bh[7].
+ //
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
+ DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) | B_PCH_RTC_REGISTERB_SET);
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
+ IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
+
+ //
+ // Step 4.
+ // Set RTC Register 0Ah[6:4] to '010'.
+ //
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
+ IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_NORM_OP | V_PCH_RTC_REGISTERA_RS_976P5US));
+
+ //
+ // Step 5.
+ // Clear RTC Register 0Bh[7].
+ //
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
+ DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) & (UINT8)~B_PCH_RTC_REGISTERB_SET);
+ IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
+ IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+PchBaseInit (
+ VOID
+ )
+{
+ //
+ // Program ACPI Power Management I/O Space Base Address
+ //
+ MmioWrite16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE
+ ),
+ (UINT16)((ACPI_BASE_ADDRESS & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)
+ );
+
+ //
+ // Program GPIO Base Address
+ //
+ MmioWrite16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_BASE
+ ),
+ (UINT16)((GPIO_BASE_ADDRESS & B_PCH_LPC_GPIO_BASE_BAR) | B_PCH_LPC_GPIO_BASE_EN)
+ );
+
+ //
+ // Set PMC Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_PMC_BASE
+ ),
+ (UINT32)((PMC_BASE_ADDRESS & B_PCH_LPC_PMC_BASE_BAR) | B_PCH_LPC_PMC_BASE_EN)
+ );
+
+ //
+ // Set IO Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_IO_BASE
+ ),
+ (UINT32)((IO_BASE_ADDRESS & B_PCH_LPC_IO_BASE_BAR) | B_PCH_LPC_IO_BASE_EN)
+ );
+
+ //
+ // Set ILB Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ILB_BASE
+ ),
+ (UINT32)((ILB_BASE_ADDRESS & B_PCH_LPC_ILB_BASE_BAR) | B_PCH_LPC_ILB_BASE_EN)
+ );
+
+ //
+ // Set PUnit Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_PUNIT_BASE
+ ),
+ (UINT32)((PUNIT_BASE_ADDRESS & B_PCH_LPC_PUNIT_BASE_BAR) | B_PCH_LPC_PUNIT_BASE_EN)
+ );
+
+ //
+ // Set SPI Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_SPI_BASE
+ ),
+ (UINT32)((SPI_BASE_ADDRESS & B_PCH_LPC_SPI_BASE_BAR) | B_PCH_LPC_SPI_BASE_EN)
+ );
+
+ //
+ // Set Root Complex Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_RCBA
+ ),
+ (UINT32)((RCBA_BASE_ADDRESS & B_PCH_LPC_RCBA_BAR) | B_PCH_LPC_RCBA_EN)
+ );
+
+ //
+ // Set MPHY Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_MPHY_BASE
+ ),
+ (UINT32)((MPHY_BASE_ADDRESS & B_PCH_LPC_MPHY_BASE_BAR) | B_PCH_LPC_MPHY_BASE_EN)
+ );
+ MmioWrite16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ R_PCH_SMBUS_BASE
+ ),
+ (UINT16)(SMBUS_BASE_ADDRESS & B_PCH_SMBUS_BASE_BAR)
+ );
+
+ MmioOr8 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ R_PCH_SMBUS_PCICMD
+ ),
+ B_PCH_SMBUS_PCICMD_IOSE
+ );
+
+}
+
+/**
+ This is the entrypoint of PEIM
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+PeiInitPlatform (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINTN SmbusRegBase;
+ EFI_PLATFORM_INFO_HOB PlatformInfo;
+ EFI_STATUS Status= EFI_SUCCESS;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable = NULL;
+ UINTN VariableSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINT32 GGC = 0;
+
+ EFI_PEI_PPI_DESCRIPTOR *mVlvMmioPolicyPpiDesc;
+ VLV_MMIO_POLICY_PPI *mVlvMmioPolicyPpi;
+
+ ZeroMem (&PlatformInfo, sizeof(PlatformInfo));
+
+ Status = InstallMonoStatusCode(FileHandle, PeiServices);
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Initialize Stall PPIs
+ //
+ Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = (*PeiServices)->NotifyPpi (PeiServices, &mMemoryDiscoveredNotifyList[0]);
+ ASSERT_EFI_ERROR (Status);
+ SmbusRegBase = PchPciDeviceMmBase (
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS
+ );
+ //
+ // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
+ //
+ MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS);
+
+ MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);
+
+ PchBaseInit();
+
+ //
+ //Todo: confirm if we need program 8254
+ //
+ // Setting 8254
+ // Program timer 1 as refresh timer
+ //
+ IoWrite8 (0x43, 0x54);
+ IoWrite8 (0x41, 0x12);
+
+ //
+ // RTC power failure handling
+ //
+ RtcPowerFailureHandler (PeiServices);
+
+
+ PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ ZeroMem (&SystemConfiguration, VariableSize);
+
+ //
+ // Obtain variable services
+ //
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (void **)&Variable
+ );
+ ASSERT_EFI_ERROR(Status);
+ Status = Variable->GetVariable (
+ Variable,
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ &SystemConfiguration
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR (Status)) {
+ GGC = ((2 << 3) | 0x200);
+ PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
+ GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
+ DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
+ } else {
+ if (SystemConfiguration.Igd == 1 && SystemConfiguration.PrimaryVideoAdaptor != 2) {
+ GGC = (SystemConfiguration.IgdDvmt50PreAlloc << 3) |
+ (SystemConfiguration.GTTSize == GTT_SIZE_1MB ? 0x100: 0x200);
+ PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
+ GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
+ DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
+ }
+ }
+
+ //
+ // Initialize PlatformInfo HOB
+ //
+ Status = ReadPlatformIds(PeiServices, &PlatformInfo);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // 0 -> Disable , 1 -> Enable
+ //
+ if(SystemConfiguration.CfioPnpSettings == 1) {
+ DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));
+ PlatformInfo.CfioEnabled = 1;
+ } else {
+ DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));
+ PlatformInfo.CfioEnabled = 0;
+ }
+
+ //
+ // Build HOB for PlatformInfo
+ //
+ BuildGuidDataHob (
+ &gEfiPlatformInfoGuid,
+ &PlatformInfo,
+ sizeof (EFI_PLATFORM_INFO_HOB)
+ );
+
+
+ //
+ // Set the new boot mode for MRC
+ //
+#ifdef NOCS_S3_SUPPORT
+ Status = UpdateBootMode (PeiServices);
+ ASSERT_EFI_ERROR (Status);
+#endif
+
+ DEBUG((EFI_D_INFO, "Setup MMIO size ... \n\n"));
+
+ //
+ // Setup MMIO size
+ //
+ Status = (*PeiServices)->AllocatePool(
+ PeiServices,
+ sizeof (EFI_PEI_PPI_DESCRIPTOR),
+ (void **)&mVlvMmioPolicyPpiDesc
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = (*PeiServices)->AllocatePool(
+ PeiServices,
+ sizeof (VLV_MMIO_POLICY_PPI),
+ (void **)&mVlvMmioPolicyPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+ (*PeiServices)->SetMem (
+ (VOID *)mVlvMmioPolicyPpi,
+ sizeof (VLV_MMIO_POLICY_PPI),
+ 0
+ );
+ mVlvMmioPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ mVlvMmioPolicyPpiDesc->Guid = &gVlvMmioPolicyPpiGuid;
+ mVlvMmioPolicyPpiDesc->Ppi = mVlvMmioPolicyPpi;
+ switch (SystemConfiguration.MmioSize) {
+ case 0: // 768MB
+ mVlvMmioPolicyPpi->MmioSize = 0x300;
+ break;
+ case 1: // 1GB
+ mVlvMmioPolicyPpi->MmioSize = 0x400;
+ break;
+ case 2: // 1.25GB
+ mVlvMmioPolicyPpi->MmioSize = 0x500;
+ break;
+ case 3: // 1.5GB
+ mVlvMmioPolicyPpi->MmioSize = 0x600;
+ break;
+ case 4: // 2GB
+ mVlvMmioPolicyPpi->MmioSize = 0x800;
+ break;
+ default:
+ mVlvMmioPolicyPpi->MmioSize = 0x800;
+ break;
+ }
+ Status = (*PeiServices)->InstallPpi(
+ PeiServices,
+ mVlvMmioPolicyPpiDesc
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+EFI_STATUS
+ReadPlatformIds (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+ {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 FabId = 0;
+ UINTN DataSize;
+ EFI_PLATFORM_INFO_HOB TmpHob;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar;
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (void **)&PeiVar
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DataSize = sizeof (EFI_PLATFORM_INFO_HOB);
+ Status = PeiVar->GetVariable (
+ PeiVar,
+ L"PlatformInfo",
+ &gEfiVlv2VariableGuid,
+ NULL,
+ &DataSize,
+ &TmpHob
+ );
+
+ if (Status == EFI_SUCCESS) {
+ PlatformInfoHob->BoardId = TmpHob.BoardId;
+ PlatformInfoHob->MemCfgID = TmpHob.MemCfgID;
+ PlatformInfoHob->BoardRev = TmpHob.BoardRev;
+ PlatformInfoHob->PlatformFlavor = TmpHob.PlatformFlavor;
+ return Status;
+ }
+
+
+ PlatformInfoHob->BoardId = BOARD_ID_MINNOW2;
+ DEBUG ((EFI_D_INFO, "I'm Minnow2!\n"));
+
+ PlatformInfoHob->MemCfgID = 0;
+ PlatformInfoHob->BoardRev = FabId + 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
+ PlatformInfoHob->PlatformFlavor = FlavorMobile;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//
+// Start::Alpine Valley platform
+//
+/**
+ This routine reads SysCtl registers
+
+ @param SmbusBase SMBUS Base Address
+ @param SlvAddr Targeted Smbus Slave device address
+ @param Operation Which SMBus protocol will be used
+ @param Offset Offset of the register
+ @param Length Number of bytes
+ @param Buffer Buffer contains values read from registers
+
+ @retval SUCCESS as passed
+ @retval Others as failed
+
+**/
+EFI_STATUS
+PeiSmbusExec (
+ UINT16 SmbusBase,
+ UINT8 SlvAddr,
+ UINT8 Operation,
+ UINT8 Offset,
+ UINT8 *Length,
+ UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINT8 AuxcReg;
+ UINT8 SmbusOperation = 0;
+ UINT8 StsReg;
+ UINT8 SlvAddrReg;
+ UINT8 HostCmdReg;
+ UINT8 BlockCount = 0;
+ BOOLEAN BufferTooSmall;
+ UINT8 Index;
+ UINT8 *CallBuffer;
+ UINT8 RetryCount = BUS_TRIES;
+
+ //
+ // MrcSmbusExec supports byte and block read.
+ // Only allow Byte or block access
+ //
+ if (!((*Length == AV_SC_BYTE_LEN) || (*Length == AV_SC_BLOCK_LEN))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // See if its ok to use the bus based upon INUSE_STS bit.
+ //
+ Status = AcquireBus (SmbusBase);
+ ASSERT_EFI_ERROR(Status);
+
+ CallBuffer = Buffer;
+
+ //
+ //SmbStatus Bits of interest
+ //[6] = IUS (In Use Status)
+ //[4] = FAIL
+ //[3] = BERR (Bus Error = transaction collision)
+ //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)
+ //[1] = INTR (Successful completion of last command)
+ //[0] = HOST BUSY
+ //
+ //
+ // This is the main operation loop. If the operation results in a Smbus
+ // collision with another master on the bus, it attempts the requested
+ // transaction again at least BUS_TRIES attempts.
+ //
+ while (RetryCount--) {
+ //
+ // Operation Specifics (pre-execution)
+ //
+ Status = EFI_SUCCESS;
+ SlvAddrReg = SlvAddr;
+ HostCmdReg = Offset;
+ AuxcReg = 0;
+
+ switch (Operation) {
+
+ case SMBUS_WRITE_BYTE:
+ IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, CallBuffer[0]);
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
+ break;
+
+ case SMBUS_READ_BYTE:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
+ SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
+ if (*Length < 1) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ *Length = 1;
+ break;
+
+ case SMBUS_WRITE_BLOCK:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
+ IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, *(UINT8 *) Length);
+ BlockCount = (UINT8) (*Length);
+ if ((*Length < 1) || (*Length > 32)) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ AuxcReg |= B_PCH_SMBUS_E32B;
+ break;
+
+ case SMBUS_READ_BLOCK:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
+ SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
+ if ((*Length < 1) || (*Length > 32)) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ AuxcReg |= B_PCH_SMBUS_E32B;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Set Auxiliary Control register
+ //
+ IoWrite8 (SmbusBase+R_PCH_SMBUS_AUXC, AuxcReg);
+
+ //
+ // Reset the pointer of the internal buffer
+ //
+ IoRead8 (SmbusBase+R_PCH_SMBUS_HCTL);
+
+ //
+ // Now that the 32 byte buffer is turned on, we can write th block data
+ // into it
+ //
+ if (Operation == SMBUS_WRITE_BLOCK) {
+ for (Index = 0; Index < BlockCount; Index++) {
+ //
+ // Write next byte
+ //
+ IoWrite8 (SmbusBase+R_PCH_SMBUS_HBD, CallBuffer[Index]);
+ }
+ }
+
+ //
+ // Set SMBus slave address for the device to read
+ //
+ IoWrite8(SmbusBase+R_PCH_SMBUS_TSA, SlvAddrReg);
+
+ //
+ //
+ // Set Command register for the offset to read
+ //
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HCMD, HostCmdReg );
+
+ //
+ // Set Control Register to Set "operation command" protocol and start bit
+ //
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START));
+
+ //
+ // Wait for IO to complete
+ //
+ do { StsReg = (UINT8) IoRead8(SmbusBase+0); } while ((StsReg & (BIT4|BIT3|BIT2|BIT1)) == 0);
+
+ if (StsReg & B_PCH_SMBUS_DERR) {
+ Status = EFI_DEVICE_ERROR;
+ break;
+ } else if (StsReg & B_PCH_SMBUS_BERR) {
+ //
+ // Clear the Bus Error for another try
+ //
+ Status = EFI_DEVICE_ERROR;
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
+
+ //
+ // Clear Status Registers
+ //
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+ IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+
+ continue;
+ }
+
+ //
+ // successfull completion
+ // Operation Specifics (post-execution)
+ //
+ switch (Operation) {
+
+ case SMBUS_READ_BYTE:
+ CallBuffer[0] = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
+ break;
+
+ case SMBUS_WRITE_BLOCK:
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);
+ break;
+
+ case SMBUS_READ_BLOCK:
+ BufferTooSmall = FALSE;
+
+ //
+ // Find out how many bytes will be in the block
+ //
+ BlockCount = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
+ if (*Length < BlockCount) {
+ BufferTooSmall = TRUE;
+ } else {
+ for (Index = 0; Index < BlockCount; Index++) {
+ //
+ // Read the byte
+ //
+ CallBuffer[Index] = (UINT8)IoRead8 (SmbusBase+R_PCH_SMBUS_HBD);
+ }
+ }
+
+ *Length = BlockCount;
+ if (BufferTooSmall) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ break;
+
+ default:
+ break;
+ };
+
+ if ((StsReg & B_PCH_SMBUS_BERR) && (Status == EFI_SUCCESS)) {
+ //
+ // Clear the Bus Error for another try
+ //
+ Status = EFI_DEVICE_ERROR;
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
+
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ //
+ // Clear Status Registers and exit
+ //
+ IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+ IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+ IoWrite8(SmbusBase+R_PCH_SMBUS_AUXC, 0);
+ return Status;
+}
+//
+// End::Alpine Valley platform
+//
+
diff --git a/Vlv2TbltDevicePkg/PlatformPei/Platform.h b/Vlv2TbltDevicePkg/PlatformPei/Platform.h
new file mode 100644
index 0000000000..12e4b658d0
--- /dev/null
+++ b/Vlv2TbltDevicePkg/PlatformPei/Platform.h
@@ -0,0 +1,216 @@
+/*++
+
+ Copyright (c) 2004 - 2014, 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 that 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_PLATFORM_H__
+#define __PEI_PLATFORM_H__
+
+#define PEI_STALL_RESOLUTION 1
+#define STALL_PEIM_SIGNATURE SIGNATURE_32('p','p','u','s')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ EFI_PEI_NOTIFY_DESCRIPTOR StallNotify;
+} STALL_CALLBACK_STATE_INFORMATION;
+
+#define STALL_PEIM_FROM_THIS(a) CR (a, STALL_CALLBACK_STATE_INFORMATION, StallNotify, STALL_PEIM_SIGNATURE)
+
+#ifdef NOCS_S3_SUPPORT
+
+/**
+ Peform the boot mode determination logic
+ If the box is closed, then
+ 1. If it's first time to boot, it's boot with full config .
+ 2. If the ChassisIntrution is selected, force to be a boot with full config
+ 3. Otherwise it's boot with no change.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param BootMode The detected boot mode.
+
+ @retval EFI_SUCCESS if the boot mode could be set
+**/
+EFI_STATUS
+UpdateBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+#endif
+
+/**
+ This function reset the entire platform, including all processor and devices, and
+ reboots the system.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+ResetSystem (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ This function will be called when MRC is done.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param NotifyDescriptor Information about the notify event..
+ @param Ppi The notify context.
+
+ @retval EFI_SUCCESS If the function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ This is the callback function notified by FvFileLoader PPI, it depends on FvFileLoader PPI to load
+ the PEIM into memory.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param NotifyDescriptor The context of notification.
+ @param Ppi The notify PPI.
+
+ @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+FvFileLoaderPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ This function provides a blocking stall for reset at least the given number of microseconds
+ stipulated in the final argument.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param this Pointer to the local data for the interface.
+ @param Microseconds number of microseconds for which to stall.
+
+ @retval EFI_SUCCESS the function provided at least the required stall.
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_STALL_PPI *This,
+ IN UINTN Microseconds
+ );
+
+/**
+ This function initialize recovery functionality by installing the recovery PPI.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS If the interface could be successfully installed.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRecovery (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ This function
+ 1. Calling MRC to initialize memory.
+ 2. Install EFI Memory.
+ 3. Capsule coalesce if capsule boot mode.
+ 4. Create HOB of system memory.
+
+ @param PeiServices Pointer to the PEI Service Table
+
+ @retval EFI_SUCCESS If it completes successfully.
+
+**/
+EFI_STATUS
+MemoryInit (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ This function provides the implementation of AtaController PPI Enable Channel function.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param this Pointer to the local data for the interface.
+ @param ChannelMask This parameter is used to specify primary or slavery IDE channel.
+
+ @retval EFI_SUCCESS Procedure returned successfully.
+**/
+EFI_STATUS
+EnableAtaChannel (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_ATA_CONTROLLER_PPI *This,
+ IN UINT8 ChannelMask
+ );
+
+/**
+ This function provides the implementation of AtaController PPI Get IDE channel Register Base Address
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param this Pointer to the local data for the interface.
+ @param IdeRegsBaseAddr Pointer to IDE_REGS_BASE_ADDR struct, which is used to record
+ IDE Command and Control regeisters Base Address.
+
+ @retval EFI_SUCCESS Procedure returned successfully.
+**/
+EFI_STATUS
+GetIdeRegsBaseAddr (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_ATA_CONTROLLER_PPI *This,
+ IN IDE_REGS_BASE_ADDR *IdeRegsBaseAddr
+ );
+
+/**
+ This function provides the implementation to properly setup both LM & PDM functionality.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS Procedure returned successfully.
+
+**/
+EFI_STATUS
+ConfigureLM(
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+#include <Ppi/VlvMmioPolicy.h>
+
+BOOLEAN
+EFIAPI
+IsFastBootEnabled (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+EFI_STATUS
+PrioritizeBootMode (
+ IN OUT EFI_BOOT_MODE *CurrentBootMode,
+ IN EFI_BOOT_MODE NewBootMode
+ );
+
+EFI_STATUS
+EFIAPI
+CapsulePpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+#endif
diff --git a/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf b/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
new file mode 100644
index 0000000000..af8bb19083
--- /dev/null
+++ b/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
@@ -0,0 +1,136 @@
+#
+#
+# Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License that 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.
+#
+#
+# This PEIM includes 3 parts, pre memory initialization, MRC
+# wrapper and post memory initialization.
+# On pre memory, following action is performed,
+# 1. Initizluize GMCH.
+# 2. Detect boot mode.
+# 3. Detect video adapter to determine whether we need pre allocated
+# memory.
+#
+# After that MRC wrapper calls MRC to initialize memory and install a PPI
+# notify to do post memory
+# initialization. MRC wrapper performance following actions,
+# 1. Install EFI Memory.
+# 2. Capsule coalesce if capsule boot mode.
+# 3. Create HOB of system memory.
+# Note: MRC supports 3 kinds of chipsets including Lakeport, Glenwood and Mukilteo,
+# so please don't define MACRO MUKILTEO_SUPPORT on Lakeport here.
+#
+# On post memory, following action is performed,
+# 1. TC initialization after MRC.
+# 2. SIO initialization.
+# 3. Install ResetSystem and FinvFv PPI, relocate Stall to memory on
+# recovery boot mode.
+# 4. Set MTRR for PEI
+# 5. Create FV HOB and Flash HOB
+# 6. Install RecoveryModule and AtaController PPI if on recovery boot mode.
+#
+# This PEIM does not have any register access directly, it depends on
+# IntelTCLib, TCAccess libraries to access Chipset
+# registers.
+#
+# Platform.c - Provide main flow and entrypoint of PEIM.
+# MemoryCallback.c - Includes a memory call back function notified when
+# MRC is done.
+#
+#
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformPeim
+ FILE_GUID = 9618C0DC-50A4-496c-994F-7241F282ED01
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PeiInitPlatform
+ PI_SPECIFICATION_VERSION = 0x0001000A
+
+[sources.common]
+ Platform.c
+ Platform.h
+ MemoryCallback.c
+ CommonHeader.h
+ Stall.c
+ BootMode.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ Vlv2TbltDevicePkg/PlatformPkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+ IA32FamilyCpuPkg/IA32FamilyCpuPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ CryptoPkg/CryptoPkg.dec
+ EdkCompatibilityPkg/EdkCompatibilityPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ HobLib
+ IoLib
+ MultiPlatformLib
+ MtrrLib
+ PerformanceLib
+ MonoStatusCodeLib
+ BaseCryptLib
+ PciLib
+
+[Ppis]
+ gEfiPeiStallPpiGuid
+ gPeiSpeakerInterfacePpiGuid
+ gEfiPeiMemoryDiscoveredPpiGuid
+ gVlvPolicyPpiGuid
+ gEfiPeiReadOnlyVariable2PpiGuid
+ gEfiPeiResetPpiGuid
+ gEfiEndOfPeiSignalPpiGuid
+ gEfiFindFvPpiGuid
+ gPeiCapsulePpiGuid
+ gEfiPeiBootInRecoveryModePpiGuid
+ gEfiPeiRecoveryModulePpiGuid
+ gEfiPeiDeviceRecoveryModulePpiGuid
+ gPeiCachePpiGuid
+ gEfiPeiMasterBootModePpiGuid
+ gEfiPeiSmbusPpiGuid
+ gPeiMfgMemoryTestPpiGuid
+ gPeiSha256HashPpiGuid
+ gVlvMmioPolicyPpiGuid
+
+[Guids]
+ gEfiSetupVariableGuid
+ gEfiPlatformInfoGuid
+ gEfiPlatformBootModeGuid
+ gEfiPlatformCpuInfoGuid
+ gEfiGlobalVariableGuid
+ gRecoveryOnFatFloppyDiskGuid
+ gRecoveryOnFatUsbDiskGuid
+ gRecoveryOnFatIdeDiskGuid
+ gRecoveryOnDataCdGuid
+ gMfgModeVariableGuid
+ gEfiNormalSetupGuid
+ gEfiBootStateGuid
+ gEfiVlv2VariableGuid
+
+[Pcd.common]
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
+[Depex]
+ TRUE
+
diff --git a/Vlv2TbltDevicePkg/PlatformPei/Stall.c b/Vlv2TbltDevicePkg/PlatformPei/Stall.c
new file mode 100644
index 0000000000..8c2ab99f1c
--- /dev/null
+++ b/Vlv2TbltDevicePkg/PlatformPei/Stall.c
@@ -0,0 +1,95 @@
+/** @file
+
+ Copyright (c) 2004 - 2014, 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 that 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.
+
+
+
+Module Name:
+
+ Stall.c
+
+Abstract:
+
+ Produce Stall Ppi.
+
+--*/
+
+
+#include "CommonHeader.h"
+#include "PlatformBaseAddresses.h"
+#include "PchRegs.h"
+
+/**
+ Waits for at least the given number of microseconds.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param This PPI instance structure.
+ @param Microseconds Desired length of time to wait.
+
+ @retval EFI_SUCCESS If the desired amount of time was passed.
+
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_STALL_PPI *This,
+ IN UINTN Microseconds
+ )
+{
+ UINTN Ticks;
+ UINTN Counts;
+ UINT32 CurrentTick;
+ UINT32 OriginalTick;
+ UINT32 RemainingTick;
+
+ if (Microseconds == 0) {
+ return EFI_SUCCESS;
+ }
+
+ OriginalTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR);
+ OriginalTick &= (V_PCH_ACPI_PM1_TMR_MAX_VAL - 1);
+ CurrentTick = OriginalTick;
+
+ //
+ // The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks
+ //
+ Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+ //
+ // The loops needed for timer overflow
+ //
+ Counts = (UINTN)RShiftU64((UINT64)Ticks, 24);
+
+ //
+ // Remaining clocks within one loop
+ //
+ RemainingTick = Ticks & 0xFFFFFF;
+
+ //
+ // Do not intend to use TMROF_STS bit of register PM1_STS, because this add extra
+ // one I/O operation, and may generate SMI
+ //
+ while (Counts != 0) {
+ CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
+ if (CurrentTick <= OriginalTick) {
+ Counts--;
+ }
+ OriginalTick = CurrentTick;
+ }
+
+ while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
+ OriginalTick = CurrentTick;
+ CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
+ }
+
+ return EFI_SUCCESS;
+}