summaryrefslogtreecommitdiff
path: root/Platform/BroxtonPlatformPkg/Common/PlatformSettings
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-23 14:31:51 +0800
committerGuo Mang <mang.guo@intel.com>2017-05-09 13:03:04 +0800
commitb83cfc49fc9b723c739242bc0518c01ea5a4eccd (patch)
treed786d287c333ea68591f29ae897faee7ed5a873c /Platform/BroxtonPlatformPkg/Common/PlatformSettings
parent46e638b002b713e7bdc0d0087bd3d9336ee2ccc1 (diff)
downloadedk2-platforms-b83cfc49fc9b723c739242bc0518c01ea5a4eccd.tar.xz
BroxtonPlatformPkg: Add PlatformPreMemPei
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/PlatformPreMemPei/BoardGpiosPreMem.c299
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BoardGpiosPreMem.h33
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BootMode.c450
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/FvCallback.c425
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/FvCallback.h38
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/MemoryCallback.h25
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PeiSaPolicyUpdate.h29
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInit.h283
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.c1519
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h149
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformPreMemPei.inf185
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Smip.c296
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Smip.h26
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Stall.c101
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Stall.h42
15 files changed, 3900 insertions, 0 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BoardGpiosPreMem.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BoardGpiosPreMem.c
new file mode 100644
index 0000000000..73b9afc4b0
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BoardGpiosPreMem.c
@@ -0,0 +1,299 @@
+/** @file
+ Gpio setting for multiplatform before Memory init.
+
+ Copyright (c) 2015 - 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 "BoardGpiosPreMem.h"
+
+#include <Guid/SetupVariable.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/GpioLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SteppingLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <ScRegs/RegsGpio.h>
+
+//
+// BXT PreMemory GPIO CONFIGURATION
+//
+
+//
+// BXT GPIO Settings
+//
+/**
+GPIO input pin interrupt type configuration:
+Interrupt type GPI Route Host SW Enable/Status Comment
+ GPI None GPIO Driver Mode GPI Interrupt Status\Enable GPIO driver to handle it
+ Direct IRQ GPIROUTIOXAPIC ACPI Mode IRQ number is fixed to each GPIO pin in N and NW communities
+ SCI/GPE GPIROUTSCI ACPI Mode GPI General Purpose Events Status\Enable SCI is not supported in BXT A0. The reason is because the PMC lacks the ACPI registers and status tunneling. This will be fixed in derivatives.
+ SMI GPIROUTSMI ACPI Mode SMI Status\Enable Don't enable SMI for BXT0. It is currently unsupported by the PMC.
+ NMI GPIROUTNMI ACPI Mode Not support on BXT
+
+Interrupt trigger type Configuration Comment
+ rising edge Edge+No_invert
+ falling edge Edge+Invert
+ both edge BothEdge+Invert
+ level high Level+No_invert Direct IRQ pin mostly use this config.Wake pin MUST use it.
+ level low Level+Invert
+
+HostSw:
+* All GPIO pins which are 'M0' PMode, have to set HostSw to GPIO_D, indicating GPIO driver owns it.
+* Others, such as Native function(M1,M2,M3..) and SCI/SMI/NMI/Direct IRQ, need to set it to ACPI_D or NA.
+
+**/
+
+//
+// For Apl board
+//
+BXT_GPIO_PAD_INIT IshI2cGpio[] =
+{
+ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger, Wake_Enabled, Term_H_L,Inverted, GPI_ROUT, IOSstae, IOSTerm, MMIO_Offset, Community
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_134 LPSS_I2C5_SDA", M2 , NA , NA , NA , NA , Wake_Disabled, P_1K_H, NA , NA, IOS_Masked, EnPu, GPIO_PADBAR+0x0050, WEST),
+ BXT_GPIO_PAD_CONF(L"GPIO_135 LPSS_I2C5_SCL", M2 , NA , NA , NA , NA , Wake_Disabled, P_1K_H, NA , NA, IOS_Masked, EnPu, GPIO_PADBAR+0x0058, WEST),
+ BXT_GPIO_PAD_CONF(L"GPIO_136 LPSS_I2C6_SDA", M2 , NA , NA , NA , NA , Wake_Disabled, P_1K_H, NA , NA, IOS_Masked, EnPu, GPIO_PADBAR+0x0060, WEST),
+ BXT_GPIO_PAD_CONF(L"GPIO_137 LPSS_I2C6_SCL", M2 , NA , NA , NA , NA , Wake_Disabled, P_1K_H, NA , NA, IOS_Masked, EnPu, GPIO_PADBAR+0x0068, WEST),
+};
+
+//
+// North Peak GPIO settings before memory initialization, as it needs to be enabled before memory init
+//
+BXT_GPIO_PAD_INIT NorthPeakGpio[] =
+{
+ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger, Wake_Enabled ,Term_H_L,Inverted, GPI_ROUT, IOSstae, IOSTerm, MMIO_Offset, Community
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_0", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0000, NORTH),
+ BXT_GPIO_PAD_CONF(L"GPIO_1", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0008, NORTH),
+ BXT_GPIO_PAD_CONF(L"GPIO_2", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0010, NORTH),
+ BXT_GPIO_PAD_CONF(L"GPIO_3", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0018, NORTH),
+ BXT_GPIO_PAD_CONF(L"GPIO_4", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0020, NORTH),
+ BXT_GPIO_PAD_CONF(L"GPIO_5", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0028, NORTH),//Mux with CSE_PG based on the SW3 switch
+ BXT_GPIO_PAD_CONF(L"GPIO_6", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0030, NORTH),//Mux with DISP1_RST_N based on the SW3 switch
+ BXT_GPIO_PAD_CONF(L"GPIO_7", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0038, NORTH),//Mux with DISP1_TOUCH_INT_N based on the SW3 switch
+ BXT_GPIO_PAD_CONF(L"GPIO_8", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I, SAME, GPIO_PADBAR+0x0040, NORTH),//Mux with DISP1_TOUCH_RST_N based on the SW3 switch
+};
+
+
+BXT_GPIO_PAD_INIT LpssSpi1Gpio [] =
+{
+ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger, Wake_Enabled, Term_H_L,Inverted,GPI_ROUT,IOSstae, IOSTerm, MMIO_Offset, Community
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_111 GP_SSP_1_CLK", M1 , HI_Z , NA , NA , NA , Wake_Disabled, P_20K_H, NA , NA,Last_Value, SAME, GPIO_PADBAR+0x0210, NORTHWEST),//SSP_5_CLK_R
+ BXT_GPIO_PAD_CONF(L"GPIO_112 GP_SSP_1_FS0", M1 , HI_Z , NA , NA , NA , Wake_Disabled, P_20K_H, NA , NA,Last_Value, SAME, GPIO_PADBAR+0x0218, NORTHWEST),//GP_SSP_1_FS0_R post
+ BXT_GPIO_PAD_CONF(L"GPIO_113 GP_SSP_1_FS1", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_H, NA , NA,Last_Value, SAME, GPIO_PADBAR+0x0220, NORTHWEST),//GP_SSP_1_FS1_R UART
+ BXT_GPIO_PAD_CONF(L"GPIO_116 GP_SSP_1_RXD", M1 , HI_Z , NA , NA , NA , Wake_Disabled, P_20K_H, NA , NA,Last_Value, SAME, GPIO_PADBAR+0x0228, NORTHWEST),//SSP_5_RXD_R
+ BXT_GPIO_PAD_CONF(L"GPIO_117 GP_SSP_1_TXD", M1 , HI_Z , NA , NA , NA , Wake_Disabled, P_20K_H, NA , NA,Last_Value, SAME, GPIO_PADBAR+0x0230, NORTHWEST),//SSP_5_TXD_R
+};
+
+
+//
+// Need to make sure ISH I2C GPIOs are configured before ISH starts running. [HSD 1205461649]
+// ApolloLake
+//
+BXT_GPIO_PAD_INIT IshI2cGpio2[] =
+{
+ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger, Wake_Enabled ,Term_H_L,Inverted, GPI_ROUT, IOSstae, IOSTerm,MMIO_Offset,Community
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_134 ISH_I2C0_SDA", M2 , NA , NA , NA , NA , Wake_Disabled, P_NONE, NA , NA, D0RxDRx0I, EnPu, GPIO_PADBAR+0x0050, WEST),
+ BXT_GPIO_PAD_CONF(L"GPIO_135 ISH_I2C0_SCL", M2 , NA , NA , NA , NA , Wake_Disabled, P_NONE, NA , NA, D0RxDRx0I, EnPu, GPIO_PADBAR+0x0058, WEST)
+};
+
+
+//
+// Need to make sure ISH I2C GPIOs are configured before ISH starts running. [HSD 1205461649]
+// ApolloLake
+//
+BXT_GPIO_PAD_INIT IshI2cGpio3[] =
+{
+ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger, Wake_Enabled ,Term_H_L,Inverted, GPI_ROUT, IOSstae, IOSTerm,MMIO_Offset,Community
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_136 ISH_I2C1_SDA", M2 , NA , NA , NA , NA , Wake_Disabled, P_NONE, NA , NA, D0RxDRx0I, EnPu, GPIO_PADBAR+0x0060, WEST),
+ BXT_GPIO_PAD_CONF(L"GPIO_137 ISH_I2C1_SCL", M2 , NA , NA , NA , NA , Wake_Disabled, P_NONE, NA , NA, D0RxDRx0I, EnPu, GPIO_PADBAR+0x0068, WEST)
+};
+
+
+BXT_GPIO_PAD_INIT LpcGpio [] =
+{
+ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger, Wake_Enabled, Term_H_L,Inverted,GPI_ROUT, IOSstae, IOSTerm, MMIO_Offset, Community
+ //
+ BXT_GPIO_PAD_CONF(L"LPC_ILB_SERIRQ", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,IOS_Masked, SAME ,GPIO_PADBAR+0x0110 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"LPC_CLKOUT0", M1, NA , NA , NA , NA ,Wake_Disabled, P_NONE , NA , NA ,HizRx1I , DisPuPd,GPIO_PADBAR+0x0118 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"LPC_CLKOUT1", M1, NA , NA , NA , NA ,Wake_Disabled, P_NONE , NA , NA ,HizRx1I , DisPuPd,GPIO_PADBAR+0x0120 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"LPC_AD0", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,HizRx1I , DisPuPd,GPIO_PADBAR+0x0128 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"LPC_AD1", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,HizRx1I , DisPuPd,GPIO_PADBAR+0x0130 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"LPC_AD2", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,HizRx1I , DisPuPd,GPIO_PADBAR+0x0138 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"LPC_AD3", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,HizRx1I , DisPuPd,GPIO_PADBAR+0x0140 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"LPC_CLKRUNB", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,HizRx1I , DisPuPd,GPIO_PADBAR+0x0148 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"LPC_FRAMEB", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,HizRx1I , DisPuPd,GPIO_PADBAR+0x0150 , SOUTHWEST),
+};
+
+
+BXT_GPIO_PAD_INIT SmbusGpio [] =
+{ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger,Wake_Enabled, Term_H_L, Inverted,GPI_ROUT,IOSstae, IOSTerm, MMIO_Offset, Community
+ //
+ BXT_GPIO_PAD_CONF(L"SMB_CLK", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,IOS_Masked, SAME ,GPIO_PADBAR+0x0100 , SOUTHWEST),
+ BXT_GPIO_PAD_CONF(L"SMB_DATA", M1, NA , NA , NA , NA ,Wake_Disabled, P_20K_H , NA , NA ,IOS_Masked, SAME ,GPIO_PADBAR+0x0108 , SOUTHWEST),
+};
+
+
+BXT_GPIO_PAD_INIT UartGpio [] =
+{
+ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger,Wake_Enabled, Term_H_L, Inverted,GPI_ROUT,IOSstae, IOSTerm, MMIO_Offset, Community
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_46 LPSS_UART2_RXD", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_H, NA , NA, NA , NA, GPIO_PADBAR+0x0170, NORTH),
+ BXT_GPIO_PAD_CONF(L"GPIO_47 LPSS_UART2_TXD", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_H, NA , NA, NA , NA, GPIO_PADBAR+0x0178, NORTH),
+};
+
+
+BXT_GPIO_PAD_INIT SataGpio [] =
+{
+ BXT_GPIO_PAD_CONF(L"GPIO_22", M0 , GPO , GPIO_D, HI , NA , Wake_Disabled, P_20K_L, NA , NA, HizRx0I , SAME, GPIO_PADBAR+0x00B0, NORTH),//Feature:Power Enable for SATA DIRECT CONNECTOR
+};
+
+
+BXT_GPIO_PAD_INIT PcieGpio [] =
+{
+ //
+ // Group Pin#: pad_name, PMode,GPIO_Config,HostSw,GPO_STATE,INT_Trigger,Wake_Enabled, Term_H_L, Inverted,GPI_ROUT,IOSstae, IOSTerm, MMIO_Offset, Community
+ //
+ // slot 1
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_152 ISH_GPIO_6", M0 , GPO , GPIO_D, LO , NA , Wake_Disabled, P_20K_L, NA , NA, NA , NA, GPIO_PADBAR+0x00B0, WEST), // PERST#
+ BXT_GPIO_PAD_CONF(L"GPIO_19", M0 , GPO , GPIO_D, HI , NA , Wake_Disabled, P_20K_H, NA , NA, NA , NA, GPIO_PADBAR+0x0098, NORTH), // PFET
+
+ //
+ // Slot 2
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_13", M0 , GPO , GPIO_D, LO , NA , Wake_Disabled, P_20K_L, NA , NA, NA , NA, GPIO_PADBAR+0x0068, NORTH), // PERST#
+ BXT_GPIO_PAD_CONF(L"GPIO_17", M0 , GPO , GPIO_D, HI , NA , Wake_Disabled, P_20K_H, NA , NA, NA , NA, GPIO_PADBAR+0x0088, NORTH), // PFET
+
+ //
+ // NGFF
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_15", M0 , GPO , GPIO_D, LO , NA , Wake_Disabled, P_20K_L, NA , NA, NA , NA, GPIO_PADBAR+0x0078, NORTH), // PERST#
+
+ //
+ // LAN
+ //
+ BXT_GPIO_PAD_CONF(L"GPIO_210 PCIE_CLKREQ1_B", M1 , NA , NA , NA , NA , Wake_Disabled, P_20K_L, NA , NA, NA , NA, GPIO_PADBAR+0x00D8, WEST), // CLKREQ#
+ BXT_GPIO_PAD_CONF(L"GPIO_37 PWM3", M0 , GPO , GPIO_D, LO , NA , Wake_Disabled, P_20K_L, NA , NA, NA , NA, GPIO_PADBAR+0x0128, NORTH), // PERST#
+};
+
+
+/**
+ Set GPIO pins before MRC init per board design.
+
+ @retval EFI_SUCCESS The function completed successfully.
+
+**/
+EFI_STATUS
+MultiPlatformGpioProgramPreMem (
+ IN OUT UINT64 *StartTimerTick
+ )
+{
+ // PAD programming
+ GpioPadConfigTable (sizeof (IshI2cGpio) / sizeof (IshI2cGpio[0]), IshI2cGpio);
+ GpioPadConfigTable (sizeof (NorthPeakGpio) / sizeof (NorthPeakGpio[0]), NorthPeakGpio);
+ GpioPadConfigTable (sizeof (LpssSpi1Gpio) / sizeof (LpssSpi1Gpio[0]), LpssSpi1Gpio);
+
+ GpioPadConfigTable (sizeof (PcieGpio) / sizeof (PcieGpio[0]), PcieGpio);
+ *StartTimerTick = GetPerformanceCounter ();
+ GpioPadConfigTable (sizeof (SataGpio) / sizeof (SataGpio[0]), SataGpio);
+ GpioPadConfigTable (sizeof (LpcGpio) / sizeof (LpcGpio[0]), LpcGpio);
+ GpioPadConfigTable (sizeof (SmbusGpio) / sizeof (SmbusGpio[0]), SmbusGpio);
+ GpioPadConfigTable (sizeof (UartGpio) / sizeof (UartGpio[0]), UartGpio);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Set GPIO pins before MRC init per board design.
+ Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
+
+ @retval EFI_SUCCESS The function completed successfully.
+
+**/
+EFI_STATUS
+MultiPlatformGpioUpdatePreMem (
+ VOID
+ )
+{
+ UINTN VariableSize;
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINT8 LpcGpioSize;
+ UINT8 Index;
+ UINT32 PadCfgDw1Offset;
+ UINT32 Data32;
+
+ ZeroMem (&SystemConfiguration, sizeof (SYSTEM_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.IshI2c0PullUp == 0) {
+ GpioPadConfigTable (sizeof (IshI2cGpio2) / sizeof (IshI2cGpio2[0]), IshI2cGpio2);
+ }
+
+ if (SystemConfiguration.IshI2c1PullUp == 0) {
+ GpioPadConfigTable (sizeof (IshI2cGpio3) / sizeof (IshI2cGpio3[0]), IshI2cGpio3);
+ }
+
+ if (SystemConfiguration.LowPowerS0Idle == TRUE) {
+ LpcGpioSize = sizeof (LpcGpio) / sizeof (LpcGpio[0]);
+ //
+ // Set Indxe = 1 becasue the first element of LpcGpio[] has already set to IOS_Masked.
+ //
+ for (Index = 1; Index < LpcGpioSize; Index++) {
+
+ PadCfgDw1Offset = ((LpcGpio[Index].Community << 16) + LpcGpio[Index].MMIO_ADDRESS + BXT_GPIO_PAD_CONF1_OFFSET);
+ Data32 = GpioPadRead (PadCfgDw1Offset);
+ Data32 &= ~(B_GPIO_IOSSTATE | B_GPIO_IOSTERM);
+ Data32 |= ((IOS_Masked << N_GPIO_IOSSTATE) | (SAME << N_GPIO_IOSTERM));
+ GpioPadWrite (PadCfgDw1Offset, Data32);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BoardGpiosPreMem.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BoardGpiosPreMem.h
new file mode 100644
index 0000000000..bbc25678a1
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BoardGpiosPreMem.h
@@ -0,0 +1,33 @@
+/** @file
+ Header file for Gpio setting for multiplatform before Memory init.
+
+ 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 _BOARDGPIOS_PREMEM_H_
+#define _BOARDGPIOS_PREMEM_H_
+
+//
+// Function Prototypes Only - Do not add #includes here
+//
+EFI_STATUS
+MultiPlatformGpioProgramPreMem (
+ IN OUT UINT64 *StartTimerTick
+ );
+
+EFI_STATUS
+MultiPlatformGpioUpdatePreMem (
+ VOID
+ );
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BootMode.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/BootMode.c
new file mode 100644
index 0000000000..c113097e55
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/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/PlatformPreMemPei/FvCallback.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/FvCallback.c
new file mode 100644
index 0000000000..6dcdc75dfc
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/FvCallback.c
@@ -0,0 +1,425 @@
+/** @file
+ Locate and install Firmware Volume Hob's Once there is main memory.
+
+ Copyright (c) 2015 - 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 <Uefi.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SystemNvDataGuid.h>
+#include <Guid/VariableFormat.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiPlatformConfigUpdateLib.h>
+#include <Library/PeiVariableCacheLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Guid/FspHeaderFile.h>
+#include <Library/FspWrapperApiLib.h>
+#include "FvCallback.h"
+
+#define MAX_DIGEST_SIZE 64
+#define TEMP_TOLUD 0x80000000
+
+extern EFI_GUID gObbyFirmwareFileSystemFvGuid;
+extern EFI_GUID gFspSFirmwareFileSystemFvGuid;
+extern EFI_GUID gIbbrFirmwareFileSystemFvGuid;
+
+
+VOID
+PrintSetupVariableData (
+ IN UINT8 *Data8,
+ IN UINTN DataSize
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < DataSize; Index++) {
+ if (Index % 0x10 == 0) {
+ DEBUG ((EFI_D_INFO, "\n%08X:", Index));
+ }
+ DEBUG ((EFI_D_INFO, " %02X", *Data8++));
+ }
+ DEBUG ((EFI_D_INFO, "\n"));
+}
+
+
+/**
+ Produces the default variable HOB to be consumed by the variable driver.
+
+ @param[in] VariableStoreHeader Pointer to the NV Storage firmware volume header.
+ @param[in] DefaultVariableDataSize The DataSize of variable.
+
+ @retval EFI_SUCCESS If the function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateDefaultVariableHob (
+ IN CONST VARIABLE_STORE_HEADER *VariableStoreHeader,
+ IN UINT32 DefaultVariableDataSize
+ )
+{
+ UINT32 VariableDataOffset = 0;
+ UINT32 VariableHobDataOffset = 0;
+
+ UINT8 *VariablePtr = NULL;
+ UINT8 *VariableHobPtr = NULL;
+ VARIABLE_STORE_HEADER *VariableStoreHeaderHob = NULL;
+
+ if (VariableStoreHeader == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((EFI_D_INFO, "Total size requested for HOB = %d.\n", (sizeof (VARIABLE_STORE_HEADER) + DefaultVariableDataSize + HEADER_ALIGNMENT - 1)));
+
+ VariableStoreHeaderHob = (VARIABLE_STORE_HEADER *) BuildGuidHob (&VariableStoreHeader->Signature,
+ sizeof (VARIABLE_STORE_HEADER) + DefaultVariableDataSize + HEADER_ALIGNMENT - 1);
+
+ if (VariableStoreHeaderHob == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DEBUG ((EFI_D_INFO, "Default HOB allocated at 0x%x\n", VariableStoreHeaderHob));
+
+ //
+ // Copy the variable store header to the beginning of the HOB
+ //
+ CopyMem (VariableStoreHeaderHob, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));
+
+ VariablePtr = (UINT8 *) HEADER_ALIGN ((UINTN) (VariableStoreHeader + 1));
+ VariableDataOffset = (UINT32) ((UINTN) VariablePtr - (UINTN) VariableStoreHeader);
+ VariableHobPtr = (UINT8 *) HEADER_ALIGN ((UINTN) (VariableStoreHeaderHob + 1));
+ VariableHobDataOffset = (UINT32) ((UINTN) VariableHobPtr - (UINTN) VariableStoreHeaderHob);
+
+ //
+ // Copy the Setup default variable
+ //
+ CopyMem (VariableHobPtr, VariablePtr, DefaultVariableDataSize);
+
+ //
+ // Update the variable store size in the HOB
+ //
+ VariableStoreHeaderHob->Size = sizeof (VARIABLE_STORE_HEADER) + DefaultVariableDataSize;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Caches the Setup defaults so Setup data is returned more quickly.
+
+ @param[in] NvStorageFvHeader Pointer to the NV Storage firmware volume header.
+
+ @retval EFI_SUCCESS If the function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateVariableHobs (
+ IN CONST EFI_FIRMWARE_VOLUME_HEADER *NvStorageFvHeader
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS VariableStoreBase;
+ EFI_GUID VariableGuid;
+ UINT8 VariableState;
+ BOOLEAN AuthenticatedVariableStore = FALSE;
+ BOOLEAN FoundVariableDefaults = FALSE;
+ UINT32 VariableHeaderSize = 0;
+ UINT32 VariableNameSize = 0;
+ UINT32 VariableDataSize = 0;
+ UINT32 SetupVariableSize = 0;
+ CHAR16 *VariableName = NULL;
+ UINT8 *VariableSearchCandidateDataPtr = NULL;
+ VARIABLE_STORE_HEADER *VariableStoreHeader = NULL;
+ VARIABLE_HEADER *StartVariableStoreVariableHeader = NULL;
+ VARIABLE_HEADER *VariableSearchHeader = NULL;
+ VARIABLE_HEADER *LastVariableStoreVariableHeader = NULL;
+ SYSTEM_CONFIGURATION *SystemConfiguration = NULL;
+
+ DEBUG ((EFI_D_INFO, "Loading variable defaults from NvStorage...\n"));
+ DEBUG ((EFI_D_INFO, " NvStorageHeader at 0x%x\n", NvStorageFvHeader));
+
+ if (NvStorageFvHeader == NULL \
+ || NvStorageFvHeader->Signature != EFI_FVH_SIGNATURE \
+ || !CompareGuid (&gEfiSystemNvDataFvGuid, &NvStorageFvHeader->FileSystemGuid)) {
+ DEBUG ((EFI_D_ERROR, " NvStorage FV passed to gather setup defaults is invalid!\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ VariableStoreBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) NvStorageFvHeader + NvStorageFvHeader->HeaderLength);
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) VariableStoreBase;
+
+ DEBUG ((EFI_D_INFO, " VariableStoreHeader at 0x%x. VariableStoreSize = %d\n", VariableStoreHeader, (UINTN) VariableStoreHeader->Size));
+
+ AuthenticatedVariableStore = (BOOLEAN) CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid);
+
+ StartVariableStoreVariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN (VariableStoreHeader + 1);
+ LastVariableStoreVariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN ((CHAR8 *) VariableStoreHeader + VariableStoreHeader->Size);
+
+ DEBUG ((EFI_D_INFO, " StartVariableStoreVariableHeader at 0x%x. LastVariableSearchHeader at 0x%x\n", StartVariableStoreVariableHeader, LastVariableStoreVariableHeader));
+
+ ASSERT (StartVariableStoreVariableHeader < LastVariableStoreVariableHeader);
+
+ VariableHeaderSize = (AuthenticatedVariableStore) ? sizeof (AUTHENTICATED_VARIABLE_HEADER) : sizeof (VARIABLE_HEADER);
+
+ //
+ // Attempt to find the SetupDefault variable
+ //
+ VariableSearchHeader = StartVariableStoreVariableHeader;
+
+ while ((VariableSearchHeader != NULL)
+ && (VariableSearchHeader <= LastVariableStoreVariableHeader)
+ && (VariableSearchHeader->StartId == VARIABLE_DATA)) {
+ VariableName = (CHAR16 *) ((CHAR8 *) ((CHAR8 *) VariableSearchHeader + VariableHeaderSize));
+
+ if (!AuthenticatedVariableStore) {
+ VariableNameSize = VariableSearchHeader->NameSize;
+ VariableDataSize = VariableSearchHeader->DataSize;
+ VariableGuid = VariableSearchHeader->VendorGuid;
+ VariableState = VariableSearchHeader->State;
+ } else {
+ VariableNameSize = ((AUTHENTICATED_VARIABLE_HEADER *) VariableSearchHeader)->NameSize;
+ VariableDataSize = ((AUTHENTICATED_VARIABLE_HEADER *) VariableSearchHeader)->DataSize;
+ VariableGuid = ((AUTHENTICATED_VARIABLE_HEADER *) VariableSearchHeader)->VendorGuid;
+ VariableState = ((AUTHENTICATED_VARIABLE_HEADER *) VariableSearchHeader)->State;
+ }
+
+ DEBUG ((EFI_D_INFO, " VariableName at 0x%x.\n", VariableName));
+
+ VariableSearchCandidateDataPtr = (UINT8 *) (((CHAR8 *) VariableSearchHeader + VariableHeaderSize) \
+ + VariableNameSize \
+ + GET_PAD_SIZE (VariableNameSize));
+
+ DEBUG ((EFI_D_INFO, " VariableSearchCandidatePtr at 0x%x.\n", (UINTN) VariableSearchCandidateDataPtr));
+ DEBUG ((EFI_D_INFO, " Variable name is %s.\n", VariableName));
+ DEBUG ((EFI_D_INFO, " Variable data size is %d bytes.\n", VariableDataSize));
+
+ if (CompareGuid (&VariableGuid, &gEfiSetupVariableGuid) \
+ && !StrCmp (L"Setup", VariableName) \
+ && (VariableState == VAR_ADDED)) {
+ DEBUG ((EFI_D_INFO, " Found the Setup defaults via BPDT to cache.\n"));
+
+ SystemConfiguration = (SYSTEM_CONFIGURATION *) VariableSearchCandidateDataPtr;
+ SetupVariableSize = VariableDataSize;
+ FoundVariableDefaults = TRUE;
+ }
+
+ //
+ // Get next variable header
+ //
+ VariableSearchHeader = (VARIABLE_HEADER *) HEADER_ALIGN ((CHAR8 *) VariableSearchCandidateDataPtr \
+ + VariableDataSize \
+ + GET_PAD_SIZE (VariableDataSize));
+ }
+
+ if (!FoundVariableDefaults) {
+ DEBUG ((EFI_D_ERROR, "Could not find the setup defaults in the NvStorage FV!\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((EFI_D_INFO, " Setup data before update at address 0x%x\n", SystemConfiguration));
+ DEBUG ((EFI_D_INFO, " Size of data in Setup header = %d bytes. Size of SYSTEM_CONFIGURATION = %d bytes.\n", SetupVariableSize, sizeof (SYSTEM_CONFIGURATION)));
+ DEBUG ((EFI_D_INFO, " Printing system configuration variable data read from the FV:\n"));
+ PrintSetupVariableData ((UINT8 *) SystemConfiguration, VariableDataSize);
+
+ //
+ // Update values in Setup before it is written to the default HOB
+ //
+ Status = UpdateSetupDataValues (SystemConfiguration);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, " Couldn't override memory and platform information system configuration values.\n"));
+ }
+
+ DEBUG ((EFI_D_INFO, " Total size of data to copy for default HOB = %d bytes.\n", (UINT32) ((VariableSearchCandidateDataPtr + VariableDataSize) - (UINTN) StartVariableStoreVariableHeader)));
+
+ Status = CreateDefaultVariableHob (VariableStoreHeader, (UINT32) ((VariableSearchCandidateDataPtr + VariableDataSize) - (UINTN) StartVariableStoreVariableHeader));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, " Error occurred creating the default variable HOB. Variable data is invalid.\n"));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "Successfully read Setup defaults.\n"));
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+ParseObbPayload (
+ IN UINT8 *PayloadPtr,
+ IN UINTN PayloadSize,
+ IN EFI_BOOT_MODE BootMode
+ )
+{
+ UINT32 PayloadTail;
+ UINTN VariableSize;
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeaderS3;
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ EFI_HOB_GUID_TYPE *GuidHobPtr;
+ EFI_HOB_GUID_TYPE *FdoEnabledGuidHob = NULL;
+ EFI_GUID *FvName;
+ FSP_INFO_HEADER *FspHeader;
+ UINT32 FspSImageBase;
+
+ DEBUG ((EFI_D_INFO, "Parsing and checking OBB Payload\n"));
+
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) PayloadPtr;
+ PayloadTail = (UINTN) PayloadPtr + PayloadSize;
+ DEBUG ((EFI_D_INFO, "FvHeader = 0x%x; PayloadTail = 0x%x\n", (UINT32) FvHeader, PayloadTail));
+
+ FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader ((UINT32) FvHeader);
+ if (FspHeader == NULL) {
+ DEBUG ((EFI_D_INFO, "Cannot find FSP-S header!\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ FspSImageBase = FspHeader->ImageBase;
+ DEBUG ((EFI_D_INFO, "FSP-S FV Base = 0x%X\n", (UINT32) FvHeader));
+ DEBUG ((EFI_D_INFO, "FSP-S FV Length = 0x%X\n", (UINT32) FvHeader->FvLength));
+ DEBUG ((EFI_D_INFO, "FSP-S Fsp Base = 0x%X\n", (UINT32) FspSImageBase));
+ DEBUG ((EFI_D_INFO, "FSP-S Fsp Size = 0x%X\n", FspHeader->ImageSize));
+
+ //
+ // Copy to FSP-S to preferred base
+ //
+ CopyMemSse4 ((VOID*) FspSImageBase, FvHeader, (UINT32) FvHeader->FvLength);
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ PcdSet32S (PcdFspsBaseAddress, (UINT32) FspSImageBase);
+ }
+
+ while ((UINT32) FvHeader < PayloadTail) {
+ if (FvHeader->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "Found Fv with invalid signature -- Stop parsing OBB.\n"));
+ break;
+ }
+
+ if (FvHeader->ExtHeaderOffset == 0) {
+ FvName = (EFI_GUID *) ((UINTN) FvHeader + 0x48); // 0x48 == FvHeader->BlockMap
+ } else {
+ FvName = (EFI_GUID *) ((UINTN) FvHeader + FvHeader->ExtHeaderOffset);
+ }
+ DEBUG ((EFI_D_INFO, "Found Fv with GUID: %g\n", FvName));
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ //
+ // FspW requires both IBBR and FSP-S on S3 resume
+ // but only copy FSP-S, do not install it.
+ //
+ DEBUG ((DEBUG_INFO, "S3 Resume: Only looking for IBBR and FSP-S.\n"));
+ if (CompareGuid (FvName, &gFspSFirmwareFileSystemFvGuid) || CompareGuid (FvName, &gIbbrFirmwareFileSystemFvGuid)) {
+ FvHeaderS3 = FvHeader;
+ if (CompareGuid (FvName, &gIbbrFirmwareFileSystemFvGuid)) {
+ PeiServicesInstallFvInfoPpi (NULL, FvHeaderS3, (UINT32) FvHeaderS3->FvLength, NULL, NULL);
+ } else {
+ PcdSet32S (PcdFspsBaseAddress, (UINT32) FvHeaderS3);
+ }
+ }
+ } else if (CompareGuid (&FvHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid)) {
+ DEBUG ((EFI_D_INFO, "NVStorage FV at 0x%x.\n", (UINT32) FvHeader));
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Could not locate EFI_PEI_READ_ONLY_VARIABLE2_PPI.\n"));
+ ASSERT_EFI_ERROR (Status);
+ return EFI_NOT_FOUND;
+ }
+ FdoEnabledGuidHob = GetFirstGuidHob (&gFdoModeEnabledHobGuid);
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ &SystemConfiguration
+ );
+
+ if (Status == EFI_NOT_FOUND || FdoEnabledGuidHob != NULL) {
+ DEBUG ((EFI_D_INFO, "Initializing variable defaults from BPDT...\n"));
+
+ //
+ // Create the variable default HOB
+ //
+ Status = CreateVariableHobs (FvHeader);
+ } else if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to read Setup variable to determine if defauls should be loaded.\n"));
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else if (CompareGuid (FvName, &gObbyFirmwareFileSystemFvGuid)) {
+ DEBUG ((EFI_D_INFO, "Found OBBY: Saving info and skipping Install FV.\n"));
+ GuidHobPtr = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (GuidHobPtr != NULL);
+ PlatformInfo = GET_GUID_HOB_DATA (GuidHobPtr);
+ PlatformInfo->FvMain3Base = (UINTN) FvHeader;
+ PlatformInfo->FvMain3Length = (UINT32) (FvHeader->FvLength);
+ } else if (!CompareGuid(FvName, &gFspSFirmwareFileSystemFvGuid)) {
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ FvHeader,
+ (UINT32) (FvHeader->FvLength),
+ NULL,
+ NULL
+ );
+ }//if/else S3
+
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvHeader + (UINTN) FvHeader->FvLength);
+ } //while (< PayloadTail)
+
+ DEBUG ((DEBUG_INFO, "PcdFspsBaseAddress: 0x%x\n", PcdGet32 (PcdFspsBaseAddress) ));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Locate and 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
+GetFvNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_BOOT_MODE BootMode;
+
+ PeiServicesGetBootMode (&BootMode);
+ DEBUG ((EFI_D_INFO, "GetFvNotifyCallback: Processing OBB Payload.\n"));
+
+ ParseObbPayload ((UINT8*) PcdGet32 (PcdFlashObbPayloadMappedBase), PcdGet32 (PcdFlashObbPayloadSize), BootMode);
+
+ //
+ // Set Zephr ID
+ //
+ PcdSet32S (PcdIfwiZid, 0);
+ DEBUG ((DEBUG_INFO, "ZID value = 0x%X\n", PcdGet32 (PcdIfwiZid)));
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/FvCallback.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/FvCallback.h
new file mode 100644
index 0000000000..a81bedf79e
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/FvCallback.h
@@ -0,0 +1,38 @@
+/** @file
+ Header file for locate and install Firmware Volume Hob's Once there is main memory..
+
+ Copyright (c) 2015 - 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 __FV_CALLBACK_H__
+#define __FV_CALLBACK_H__
+
+//
+// Please do not put #includes here, they should be with the implementation code
+//
+EFI_STATUS
+EFIAPI
+GetFvNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+VOID
+CopyMemSse4 (
+ IN VOID* Dst,
+ IN VOID* Src,
+ IN UINTN SizeInBytes
+ );
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/MemoryCallback.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/MemoryCallback.h
new file mode 100644
index 0000000000..49dd74ab33
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/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/PlatformPreMemPei/PeiSaPolicyUpdate.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PeiSaPolicyUpdate.h
new file mode 100644
index 0000000000..d9f5be520f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/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/PlatformPreMemPei/PlatformInit.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInit.h
new file mode 100644
index 0000000000..09813e904f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/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/PlatformPreMemPei/PlatformInitPreMem.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.c
new file mode 100644
index 0000000000..8348bf7233
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.c
@@ -0,0 +1,1519 @@
+/** @file
+ Source code file for Platform Init Pre-Memory PEI module.
+
+ Copyright (c) 2015 - 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 <Base.h>
+#include <ScAccess.h>
+#include <SaAccess.h>
+#include <SeCAccess.h>
+#include <PlatformBaseAddresses.h>
+#include <FrameworkPei.h>
+#include <Guid/VariableFormat.h>
+#include <Ppi/MfgMemoryTest.h>
+#include <Ppi/TemporaryRamSupport.h>
+#include <Ppi/BlockIo.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/SecUma.h>
+#include <Ppi/FvLoadFile.h>
+#include <Ppi/Stall.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Ppi/SiPolicyPpi.h>
+#include <Ppi/BiosReservedMemory.h>
+#include <Ppi/DramPolicyPpi.h>
+#include <Ppi/SaPolicy.h>
+#include <Ppi/ScPolicyPreMem.h>
+#include <Ppi/BoardInitSignalling.h>
+#include <Guid/Capsule.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Guid/SystemNvDataGuid.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/AcpiVariableCompatibility.h>
+#include <Guid/FirmwarePerformance.h>
+#include <Guid/VariableFormat.h>
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiVariableCacheLib.h>
+#include <Library/PeiPlatformConfigUpdateLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/I2cLib.h>
+#include <Library/PmicLib.h>
+#include <Library/PeiVariableCacheLib.h>
+#include <Library/PeiSiPolicyLib.h>
+#include <Library/PeiPlatformConfigUpdateLib.h>
+#include <Library/CpuPolicyLib.h>
+#include <Library/ScPlatformLib.h>
+#include <Library/PeiPolicyInitLib.h>
+#include <Library/PeiScPolicyLib.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include "Smip.h"
+#include "Stall.h"
+#include "FvCallback.h"
+#include "MemoryCallback.h"
+#include "BoardGpiosPreMem.h"
+#include "PlatformInitPreMem.h"
+#include <Library/SteppingLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Ppi/SecPlatformInformation.h>
+#include <Library/PlatformSecLib.h>
+#include <Library/TimerLib.h>
+
+#if (ENBDT_PF_ENABLE == 1)
+//
+//SSC
+//
+ #include <Library/PmcIpcLib.h>
+ #include <SscRegs.h>
+ #include <Library/SideBandLib.h>
+#endif
+
+extern EFI_GUID gEfiBootMediaHobGuid;
+
+//
+// The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
+//
+BOOLEAN ImageInMemory = FALSE;
+CHAR8 mGdtTable[0x40];
+
+//
+//Memory Test Manufacturing mode
+//
+#define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32))
+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
+};
+
+extern EFI_PEI_PPI_DESCRIPTOR mCseUfsSelectPpiList[];
+extern EFI_PEI_PPI_DESCRIPTOR mCseEmmcSelectPpiList[];
+extern EFI_PEI_PPI_DESCRIPTOR mCseSpiSelectPpiList[];
+
+#define PEI_STALL_RESOLUTION 1
+static EFI_PEI_STALL_PPI mStallPpi = {
+ PEI_STALL_RESOLUTION,
+ Stall
+};
+
+
+#if defined(PRAM_SUPPORT)
+static PEI_BIOS_RESERVED_MEMORY_POLICY_PPI mPeiBiosReservedMemoryPolicyPpi = {
+ GetBiosReservedMemoryPolicy
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mBiosReservedMemoryPolicyPpi =
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gBiosReservedMemoryPolicyPpiGuid,
+ &mPeiBiosReservedMemoryPolicyPpi
+ };
+#endif
+
+
+static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi =
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiStallPpiGuid,
+ &mStallPpi
+ };
+
+
+static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi = {
+ MfgMemoryTest
+};
+
+
+static EFI_PEI_PPI_DESCRIPTOR mMfgMemTestPpi =
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiMfgMemoryTestPpiGuid,
+ &mPeiMfgMemoryTestPpi
+ };
+
+static EFI_PEI_PPI_DESCRIPTOR mPeiTemporaryRamSupportPpiPpi[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamSupportPpiGuid,
+ NULL
+ }
+};
+
+
+//
+// Notify Callbacks for SPI and non-SPI boot devices.
+// These are installed by MemoryDiscovered Callback, since they require main memory.
+//
+EFI_PEI_NOTIFY_DESCRIPTOR mFvNotifyList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ &gEfiPeiVirtualBlockIoPpiGuid, //non-SPI boot - installed after MemInit
+ GetFvNotifyCallback
+ },
+
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gCseSpiSelectPpiGuid, //SPI boot - installed by PeiSecUma
+ GetFvNotifyCallback
+ }
+};
+
+
+EFI_STATUS
+EFIAPI
+FspTempRamExitCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ DEBUG ((DEBUG_INFO, "FspTempRamExitCallback\n"));
+ Status = PeiServicesNotifyPpi (&mFvNotifyList[0]);
+ return Status;
+}
+
+
+EFI_PEI_NOTIFY_DESCRIPTOR mFspTempRamExitList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gFspTempRamExitGuid,
+ FspTempRamExitCallback
+ }
+};
+
+
+EFI_STATUS
+EFIAPI
+GetBiosReservedMemoryPolicy (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BIOS_RESERVED_MEMORY_POLICY_PPI *This,
+ IN OUT BIOS_RESERVED_MEMORY_CONFIG *BiosReservedMemoryPolicy
+ );
+
+
+VOID
+CopyMemSse4 (
+ IN VOID* Dst,
+ IN VOID* Src,
+ IN UINTN SizeInBytes
+ )
+{
+ _asm {
+ //
+ // Initialize pointers to start of the USWC memory
+ //
+ mov esi, Src
+ mov edx, Src
+
+ //
+ // Initialize pointer to end of the USWC memory
+ //
+ add edx, SizeInBytes
+
+ //
+ // Initialize pointer to start of the cacheable WB buffer
+ //
+ mov edi, Dst
+
+ //
+ // save xmm0 ~ xmm3 to stack
+ //
+ sub esp, 040h
+ movdqu [esp], xmm0
+ movdqu [esp + 16], xmm1
+ movdqu [esp + 32], xmm2
+ movdqu [esp + 48], xmm3
+
+ //
+ // Start of Bulk Load loop
+ //
+ inner_start:
+ //
+ // Load data from USWC Memory using Streaming Load
+ //
+ MOVNTDQA xmm0, xmmword ptr [esi]
+ MOVNTDQA xmm1, xmmword ptr [esi + 16]
+ MOVNTDQA xmm2, xmmword ptr [esi + 32]
+ MOVNTDQA xmm3, xmmword ptr [esi + 48]
+
+ //
+ // Copy data to buffer
+ //
+ MOVDQA xmmword ptr [edi], xmm0
+ MOVDQA xmmword ptr [edi + 16], xmm1
+ MOVDQA xmmword ptr [edi + 32], xmm2
+ MOVDQA xmmword ptr [edi + 48], xmm3
+
+ //
+ // Increment pointers by cache line size and test for end of loop
+ //
+ add esi, 040h
+ add edi, 040h
+ cmp esi, edx
+ jne inner_start
+
+ //
+ // restore xmm0 ~ xmm3
+ //
+ mfence
+ movdqu xmm0, [esp]
+ movdqu xmm1, [esp + 16]
+ movdqu xmm2, [esp + 32]
+ movdqu xmm3, [esp + 48]
+ add esp, 040h // stack cleanup
+ }
+ // End of Bulk Load loop
+}
+
+
+/**
+ This function get SA setup config in PEI.
+
+ @param[in, out] SaPreMemConfig Pointer to SA Pre Mem Config Block
+
+ @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
+UpdateSaPreMemPolicy (
+ IN OUT SA_PRE_MEM_CONFIG *SaPreMemConfig
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableSize = 0;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+
+ 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 (Status == EFI_SUCCESS) {
+ SaPreMemConfig->IgdDvmt50PreAlloc = SystemConfiguration.IgdDvmt50PreAlloc;
+ SaPreMemConfig->ApertureSize = SystemConfiguration.IgdApertureSize;
+ SaPreMemConfig->GttSize = SystemConfiguration.GTTSize;
+ SaPreMemConfig->InternalGraphics = SystemConfiguration.Igd;
+ SaPreMemConfig->PrimaryDisplay = SystemConfiguration.PrimaryVideoAdaptor;
+ if (SystemConfiguration.PrimaryVideoAdaptor == 4) {
+ //
+ // When Primary Display is selected as HG, Display is driven on-board and PrimaryDisplay should be set as 0. (IGD)
+ //
+ SaPreMemConfig->PrimaryDisplay = 0;
+ }
+ }
+
+ return Status;
+}
+
+
+#if defined(PRAM_SUPPORT)
+
+/**
+ This function is to get Bios Reserved Memory in PEI.
+
+ @param[in] PeiServices Pointer to PEI Services.
+ @param[in] This Pei memory test PPI pointer.
+ @param[in, out] BiosReservedMemoryPolicy Pointer to BiosReservedMemorypolicy.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+GetBiosReservedMemoryPolicy (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BIOS_RESERVED_MEMORY_POLICY_PPI *This,
+ IN OUT BIOS_RESERVED_MEMORY_CONFIG *BiosReservedMemoryPolicy
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableSize;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+
+ 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 (Status == EFI_SUCCESS) {
+#ifdef PRAM_SUPPORT
+ BiosReservedMemoryPolicy->Pram = SystemConfiguration.Pram;
+#endif
+ } else {
+#ifdef PRAM_SUPPORT
+ BiosReservedMemoryPolicy->Pram = 0x30;
+#endif
+
+ }
+ Status = EFI_SUCCESS;
+
+#ifdef PRAM_SUPPORT
+ DEBUG ((DEBUG_INFO, "SystemConfiguration.Pram = %x \n", SystemConfiguration.Pram));
+#endif
+ return Status;
+}
+
+#endif
+
+
+/**
+ This function checks the memory range in PEI.
+
+ @param[in] PeiServices Pointer to PEI Services.
+ @param[in] This Pei memory test PPI pointer.
+ @param[in] BeginAddress Beginning of the memory address to be checked.
+ @param[in] MemoryLength Bytes of memory range to be checked.
+
+ @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 ((DEBUG_INFO, "MFGMODE SET\n"));
+
+ //
+ // Writing 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 non-zero, this particular memAddr has a failure.
+ //
+ if (xorData != 0x00000000) {
+ DEBUG ((DEBUG_ERROR, "Expected value....: %x\n", DataPatternForMemoryTest[i]));
+ DEBUG ((DEBUG_ERROR, "ReadData value....: %x\n", readData));
+ DEBUG ((DEBUG_ERROR, "Pattern failure at....: %x\n", memAddr));
+ TestFlag = 1;
+ }
+
+ memAddr = memAddr + 4;
+ }
+ }
+
+ if (TestFlag) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Output Message for MFG
+ //
+ DEBUG ((DEBUG_INFO, "MFGMODE MEMORY TEST PASSED\n"));
+
+ return EFI_SUCCESS;
+}
+
+
+BOOLEAN
+IsRtcUipAlwaysSet (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_PEI_STALL_PPI *StallPpi;
+ UINTN Count;
+
+ PeiServicesLocatePpi (&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;
+}
+
+
+VOID
+RtcPowerFailureHandler (
+ VOID
+ )
+{
+ UINT16 Data16;
+ UINT8 Data8;
+
+ // When the RTC_PWR_STS bit is set, it indicates that the RTCRST# signal went low.
+ // Software should clear this bit. For example, 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. This will ensure that the RTC state machine has been
+ // initialized.
+ // 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 110b or 111b.
+ // 3. Set RTC Register 0x0B[7].
+ // 4. Set RTC Register 0x0A[6:4] to 010b.
+ // 5. Clear RTC Register 0x0B[7].
+ //
+
+ Data16 = MmioRead16 (PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1);
+
+ if ((Data16 & B_PMC_GEN_PMCON_RTC_PWR_STS) != 0) {
+ //
+ // 2. Set RTC Register 0Ah[6:4] to 110b or 111b
+ //
+ IoWrite8 (R_RTC_INDEX2, (UINT8) R_RTC_REGISTERA);
+ Data8 = IoRead8 (R_RTC_TARGET2) & (UINT8) ~(B_RTC_REGISTERA_DV);
+ Data8 |= (UINT8) (V_RTC_REGISTERA_DV_DIV_RST1);
+ IoWrite8 (R_RTC_TARGET2, Data8);
+
+ //
+ // 3. Set RTC Register 0Bh[7].
+ //
+ IoWrite8 (R_RTC_INDEX2, (UINT8) R_RTC_REGISTERB);
+ IoOr8 (R_RTC_TARGET2, (UINT8) B_RTC_REGISTERB_SET);
+
+ //
+ // 4. Set RTC Register 0Ah[6:4] to 010b
+ //
+ IoWrite8 (R_RTC_INDEX2, (UINT8) R_RTC_REGISTERA);
+ Data8 = IoRead8 (R_RTC_TARGET2) & (UINT8) ~(B_RTC_REGISTERA_DV);
+ Data8 |= (UINT8) (V_RTC_REGISTERA_DV_NORM_OP);
+ IoWrite8 (R_RTC_TARGET2, Data8);
+
+ //
+ // 5. Clear RTC Register 0Bh[7].
+ //
+ IoWrite8 (R_RTC_INDEX2, (UINT8) R_RTC_REGISTERB);
+ IoAnd8 (R_RTC_TARGET2, (UINT8) ~B_RTC_REGISTERB_SET);
+ }
+
+ return;
+}
+
+
+VOID
+ScBaseInit (
+ VOID
+ )
+{
+ //
+ // Set BARs for PMC SSRAM (0/13/3)
+ // Allocation for these regions is done in PlatformInitFinalConfig() via call to BuildResourceDescriptorHob()
+ //
+ MmioWrite32 (
+ MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PMC, PCI_FUNCTION_NUMBER_PMC_SSRAM, 0x10), //Write BAR0-lower
+ PcdGet32 (PcdPmcSsramBaseAddress0)
+ );
+ MmioWrite32 (
+ MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PMC, PCI_FUNCTION_NUMBER_PMC_SSRAM, 0x18), //Write BAR1-lower
+ PcdGet32 (PcdPmcSsramBaseAddress1)
+ );
+ MmioWrite16 (
+ MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PMC, PCI_FUNCTION_NUMBER_PMC_SSRAM, 0x4), //Set BME and MSE
+ 0x6
+ );
+
+ //
+ // Set SPI Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0,DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_SPI, PCI_FUNCTION_NUMBER_SPI, R_SPI_BASE),
+ (UINT32) ((SPI_BASE_ADDRESS & B_SPI_BASE_BAR))
+ );
+
+ //
+ // Enable SPI Memory decode
+ //
+ MmioWrite16 (
+ MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_SPI, PCI_FUNCTION_NUMBER_SPI, R_SPI_COMMAND),
+ EFI_PCI_COMMAND_MEMORY_SPACE
+ );
+
+ //
+ // Set P2SB Base Address
+ //
+ MmioWrite32 (
+ MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_P2SB, PCI_FUNCTION_NUMBER_P2SB, R_P2SB_BASE),
+ (UINT32) ((PcdGet32 (PcdP2SBBaseAddress)))
+ );
+
+ //
+ // Enable P2SB Memory decode
+ //
+ MmioWrite16 (
+ MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_P2SB, PCI_FUNCTION_NUMBER_P2SB, R_P2SB_STSCMD),
+ B_P2SB_STSCMD_BME | B_P2SB_STSCMD_MSE
+ );
+
+ PchLpcIoDecodeRangesSet (
+ (V_PCH_LPC_IOD_LPT_378 << N_PCH_LPC_IOD_LPT) |
+ (V_PCH_LPC_IOD_COMB_3E8 << N_PCH_LPC_IOD_COMB) |
+ (V_PCH_LPC_IOD_COMA_3F8 << N_PCH_LPC_IOD_COMA)
+ );
+
+ PchLpcIoEnableDecodingSet (
+ B_PCH_LPC_IOE_ME2 |
+ B_PCH_LPC_IOE_SE |
+ B_PCH_LPC_IOE_ME1 |
+ B_PCH_LPC_IOE_KE |
+ B_PCH_LPC_IOE_HGE |
+ B_PCH_LPC_IOE_LGE |
+ B_PCH_LPC_IOE_FDE |
+ B_PCH_LPC_IOE_PPE |
+ B_PCH_LPC_IOE_CBE |
+ B_PCH_LPC_IOE_CAE
+ );
+
+}
+
+
+/**
+ This function performs Silicon Policy initialization.
+
+ @param[in] FirmwareConfiguration It uses to skip specific policy init that depends
+ on the 'FirmwareConfiguration' variable.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+
+**/
+EFI_STATUS
+EFIAPI
+PeiSiPolicyInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ SI_POLICY_PPI *SiPolicyPpi;
+
+ //
+ // Call SiCreatePolicyDefaults to initialize Silicon Policy structure
+ // and get all Intel default policy settings.
+ //
+ Status = SiCreatePolicyDefaults (&SiPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update and override all platform related and customized settings below.
+ //
+ UpdatePeiSiPolicy (SiPolicyPpi);
+
+ //
+ // Install SiPolicyPpi.
+ // While installed, RC assumes the Policy is ready and finalized. So please
+ // update and override any setting before calling this function.
+ //
+ Status = SiInstallPolicyPpi (SiPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ This function performs SC PreMem Policy initialization.
+
+ @param[in] StartTimerTicker The Start Timer Ticker for PFET# enabled
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+
+**/
+EFI_STATUS
+EFIAPI
+PeiScPreMemPolicyInit (
+ IN UINT64 *StartTimerTicker
+ )
+{
+ EFI_STATUS Status;
+ SC_PREMEM_POLICY_PPI *ScPreMemPolicy;
+ SC_PCIE_PREMEM_CONFIG *PciePreMemConfig;
+
+ //
+ // Call ScCreatePreMemConfigBlocks to initialize SC Policy structure
+ // and get all Intel default policy settings.
+ //
+ Status = ScCreatePreMemConfigBlocks (&ScPreMemPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update and override all platform related and customized settings below.
+ //
+ Status = GetConfigBlock ((VOID *) ScPreMemPolicy, &gPcieRpPreMemConfigGuid, (VOID *) &PciePreMemConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update PCIe PERST# and CLK# policies
+ //
+ PciePreMemConfig->StartTimerTickerOfPfetAssert = (UINTN) *StartTimerTicker;
+ PciePreMemConfig->RootPort[0].Perst = N_GPIO_13; // Slot2
+ PciePreMemConfig->RootPort[1].Perst = N_GPIO_15; // NGFF
+ PciePreMemConfig->RootPort[2].Perst = W_GPIO_152; // Slot1
+ PciePreMemConfig->RootPort[3].Perst = 0;
+ PciePreMemConfig->RootPort[4].Perst = N_GPIO_37; // LOM
+ PciePreMemConfig->RootPort[5].Perst = 0;
+ PciePreMemConfig->RootPort[0].Clock = W_GPIO_211; // Slot2
+ PciePreMemConfig->RootPort[1].Clock = W_GPIO_212; // NGFF
+ PciePreMemConfig->RootPort[2].Clock = W_GPIO_209; // Slot1
+ PciePreMemConfig->RootPort[3].Clock = 0;
+ PciePreMemConfig->RootPort[4].Clock = 0;
+ PciePreMemConfig->RootPort[5].Clock = 0;
+
+ //
+ // Install ScPreMemPolicyPpi.
+ // While installed, RC assumes the Policy is ready and finalized. So please
+ // update and override any setting before calling this function.
+ //
+ Status = ScInstallPreMemPolicyPpi (ScPreMemPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ This function performs SA PreMem Policy initialization.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+
+**/
+EFI_STATUS
+EFIAPI
+PeiSaPreMemPolicyInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ SI_SA_POLICY_PPI *SaPolicyPpi;
+ SA_PRE_MEM_CONFIG *SaPreMemConfig = NULL;
+
+ //
+ // Call SaCreatePreMemConfigBlocks to initialize SA Policy structure
+ // and get all Intel default policy settings.
+ //
+ Status = SaCreatePreMemConfigBlocks (&SaPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update and override all platform related and customized settings below.
+ //
+ Status = GetConfigBlock ((VOID *) SaPolicyPpi, &gSaPreMemConfigGuid, (VOID *) &SaPreMemConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update SA Pre-mem policies with setup values
+ //
+ UpdateSaPreMemPolicy (SaPreMemConfig);
+
+ //
+ // Install SaPreMemPolicyPpi.
+ // While installed, RC assumes the Policy is ready and finalized. So please
+ // update and override any setting before calling this function.
+ //
+ Status = SaInstallPreMemPolicyPpi (SaPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+#if (ENBDT_PF_ENABLE == 1)
+//
+// DDR SSC
+//
+EFI_STATUS
+EFIAPI
+PeiDDRSSCInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SSC_IPC_BUFFER WBuf;
+ UINT32 BufferSize = 0;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINTN VariableSize;
+
+ //
+ // static table for the SSC settings (corresponding with the SSC settings 0~-0.5%, 0.1% stepping)
+ // Modulation Freq = 32KHz
+ //
+ SSC_SETTING SSC_Select_Table[] = {{No_SSC, 0x12B, 0},
+ {M01_SSC, 0x12B, 0x1062},
+ {M02_SSC, 0x12B, 0x2BB0},
+ {M03_SSC, 0x12B, 0x46FF},
+ {M04_SSC, 0x12B, 0x624D},
+ {M05_SSC, 0x12B, 0x7D9C}};
+
+ //
+ //static table for the clock bending settings (corresponding with the clock bending settings 1.3%, 0.6%, 0, -0.9%)
+ //
+ CLOCK_BENDING_SETTING CLK_Bending_Table[] = {{Clk_Bending_13, 0xA00000, 0x7E},
+ {Clk_Bending_06, 0xC00000, 0x7D},
+ {No_Clk_Bending, 0x0, 0x7D},
+ {Clk_Bending_M09, 0xDB6C20, 0x7B}};
+
+ //
+ // default value of the 4 SSC setting registers
+ //
+ WBuf.LJ1PLL_CTRL_1.Data = 0x00;
+ WBuf.LJ1PLL_CTRL_2.Data = 0x0888812B;
+ WBuf.LJ1PLL_CTRL_3 = 0x7D000000;
+ WBuf.LJ1PLL_CTRL_5.Data = 0x7D000000;
+ BufferSize = sizeof (UINT32) * 4;
+
+ 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)) {
+ DEBUG ((DEBUG_ERROR, "Setup Variable is not ready for SSC setting! Used default value!!\n\r"));
+ //
+ // Set default value of SSC
+ //
+ WBuf.LJ1PLL_CTRL_2.Fields.ssc_cyc_to_peak_m1 = SSC_Select_Table[SSC_DEFAULT_SETTING].Ssc_Cyc_To_Peak;
+ WBuf.LJ1PLL_CTRL_2.Fields.ssc_frac_step = SSC_Select_Table[SSC_DEFAULT_SETTING].Ffs_Frac_Step;
+ //
+ // Set default value of Clock bending
+ //
+ WBuf.LJ1PLL_CTRL_5.Fields.pll_ratio_frac = CLK_Bending_Table[CLK_BENDING_DEFAULT_SETTING].Pll_Ratio_Frac;
+ WBuf.LJ1PLL_CTRL_5.Fields.pll_ratio_int = CLK_Bending_Table[CLK_BENDING_DEFAULT_SETTING].Pll_Ratio_Int;
+
+ //
+ // send the IPC command for SSC
+ //
+ Status = IpcSendCommandEx (IPC_CMD_ID_EMI_RFI_SUPPORT, IPC_SUBCMD_ID_SSC_APPLY_NOW, &WBuf, BufferSize);
+
+ //
+ // Delay for 1ms to avoid the SSC doesn't set correctly sometimes
+ //
+ MicroSecondDelay (1000);
+
+ //
+ // set the ssc_en to Disable!
+ //
+ WBuf.LJ1PLL_CTRL_1.Fields.ssc_en = SSC_DISABLE;
+ WBuf.LJ1PLL_CTRL_1.Fields.ssc_en_ovr = SSC_DISABLE;
+ Status = IpcSendCommandEx (IPC_CMD_ID_EMI_RFI_SUPPORT, IPC_SUBCMD_ID_SSC_APPLY_NOW, &WBuf, BufferSize);
+ return Status;
+ }
+
+ if (SystemConfiguration.DDRSSCEnable) {
+ //
+ // get the correct register values of the SSC setting
+ //
+ WBuf.LJ1PLL_CTRL_2.Fields.ssc_cyc_to_peak_m1 = SSC_Select_Table[SystemConfiguration.DDRSSCSelection].Ssc_Cyc_To_Peak;
+ WBuf.LJ1PLL_CTRL_2.Fields.ssc_frac_step = SSC_Select_Table[SystemConfiguration.DDRSSCSelection].Ffs_Frac_Step;
+ //
+ // get the correct register values of the clock bending setting
+
+ WBuf.LJ1PLL_CTRL_5.Fields.pll_ratio_frac = CLK_Bending_Table[SystemConfiguration.DDRCLKBending].Pll_Ratio_Frac;
+ WBuf.LJ1PLL_CTRL_5.Fields.pll_ratio_int = CLK_Bending_Table[SystemConfiguration.DDRCLKBending].Pll_Ratio_Int;
+
+ //
+ // send the IPC command for SSC settings
+ //
+ Status = IpcSendCommandEx (IPC_CMD_ID_EMI_RFI_SUPPORT, IPC_SUBCMD_ID_SSC_APPLY_NOW, &WBuf, BufferSize);
+
+ //
+ // Delay for 1ms to avoid the SSC doesn't set correctly sometimes
+ //
+ MicroSecondDelay (1000);
+
+ //
+ // set the ssc_en and ssc_en_ovr to Enable!
+ //
+ WBuf.LJ1PLL_CTRL_1.Fields.ssc_en = SSC_ENABLE;
+ WBuf.LJ1PLL_CTRL_1.Fields.ssc_en_ovr = SSC_ENABLE;
+
+ //
+ // send the IPC command for SSC EN
+ //
+ Status = IpcSendCommandEx (IPC_CMD_ID_EMI_RFI_SUPPORT, IPC_SUBCMD_ID_SSC_APPLY_NOW, &WBuf, BufferSize);
+ } else {
+ // get the correct register values of the clock bending setting
+ WBuf.LJ1PLL_CTRL_5.Fields.pll_ratio_frac = CLK_Bending_Table[SystemConfiguration.DDRCLKBending].Pll_Ratio_Frac;
+ WBuf.LJ1PLL_CTRL_5.Fields.pll_ratio_int = CLK_Bending_Table[SystemConfiguration.DDRCLKBending].Pll_Ratio_Int;
+
+ Status = IpcSendCommandEx (IPC_CMD_ID_EMI_RFI_SUPPORT, IPC_SUBCMD_ID_SSC_APPLY_NOW, &WBuf, BufferSize);
+ return Status;
+ }
+
+ return Status;
+}
+
+//
+// USB3, PCie, SATA, eDP, DP, eMMC, SD and SDIO SSC
+//
+EFI_STATUS
+EFIAPI
+PeiHighSpeedSerialInterfaceSSCInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ LCPLL_CR_RW_CONTROL_1 LCPLL_CTRL_1;
+ LCPLL_CR_RW_CONTROL_2 LCPLL_CTRL_2;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINTN VariableSize;
+
+ //
+ // static table for the SSC settings (corresponding with the SSC settings 0~-0.5%, 0.1% stepping)
+ // Modulation Freq = 32KHz
+ //
+ SSC_SETTING HSSIO_SSC_Select_Table[] = {{ No_SSC, 0x12B, 0 },
+ { M01_SSC, 0x12B, 0x1062 },
+ { M02_SSC, 0x12B, 0x2BB0 },
+ { M03_SSC, 0x12B, 0x46FF },
+ { M04_SSC, 0x12B, 0x624D },
+ { M05_SSC, 0x12B, 0x7D9C }};
+
+ LCPLL_CTRL_1.Data = SideBandRead32 (0x99, 0x9910);
+ LCPLL_CTRL_2.Data = SideBandRead32 (0x99, 0x9914);
+
+ VariableSize = sizeof (SYSTEM_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)) {
+ DEBUG ((DEBUG_ERROR, "\nSetup Variable is not ready for SSC setting! Leave the default system HSSIO SSC settings!!\n\r"));
+ return EFI_SUCCESS;
+ }
+
+ if (SystemConfiguration.HSSIOSSCEnable) {
+ LCPLL_CTRL_2.Fields.ssc_cyc_to_peak_m1 = HSSIO_SSC_Select_Table[SystemConfiguration.HSSIOSSCSelection].Ssc_Cyc_To_Peak;
+ LCPLL_CTRL_2.Fields.ssc_frac_step = HSSIO_SSC_Select_Table[SystemConfiguration.HSSIOSSCSelection].Ffs_Frac_Step;
+ SideBandWrite32 (0x99, 0x9914, LCPLL_CTRL_2.Data);
+ SideBandWrite32 (0x99, 0x9910, 0);
+ } else {
+ LCPLL_CTRL_1.Fields.ssc_en = SSC_DISABLE;
+ LCPLL_CTRL_1.Fields.ssc_en_ovr = SSC_ENABLE;
+ SideBandWrite32 (0x99, 0x9910, LCPLL_CTRL_1.Data);
+ }
+ return EFI_SUCCESS;
+}
+#endif
+
+
+/**
+ This is the entry point of PEIM
+
+ @param[in] FileHandle Handle of the file being invoked.
+ @param[in] PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS if it completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformInitPreMemEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_PLATFORM_INFO_HOB PlatformInfo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
+ FIRMWARE_SEC_PERFORMANCE Performance;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ VOID *Memory;
+ IA32_DESCRIPTOR GdtDscriptor;
+ UINT32 Temp32;
+ UINT32 IfwiVerAddr;
+ DRAM_POLICY_PPI *DramPolicy;
+ EFI_PEI_PPI_DESCRIPTOR *NewPeiPpiDescriptor;
+ EFI_BOOT_MODE BootMode;
+ CarMapStruc *CarMap;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINTN VariableSize;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PLATFORM_INFO_HOB *PlatformInfoPtr;
+ EFI_HOB_GUID_TYPE *FdoEnabledGuidHob = NULL;
+ UINT64 StartTimerTicker = 0;
+ UINT64 Tick;
+ UINTN AcpiVarHobSize;
+ #if (ENBDT_PF_ENABLE == 1)
+ MBP_CURRENT_BOOT_MEDIA BootMediaData;
+ #endif
+ PEI_BOARD_PRE_MEM_INIT_PPI *BoardPreMemInitPpi;
+ UINTN Instance;
+
+ Status = (*PeiServices)->RegisterForShadow (FileHandle);
+
+ if (Status == EFI_ALREADY_STARTED) {
+ ImageInMemory = TRUE;
+ } else if (Status == EFI_NOT_FOUND) {
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (!ImageInMemory) {
+
+ //
+ // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
+ //
+ ScBaseInit ();
+ MultiPlatformGpioProgramPreMem (&StartTimerTicker);
+ }
+
+ Status = InstallMonoStatusCode (FileHandle, PeiServices);
+
+ if (!ImageInMemory) {
+ //
+ // Locate all Board Pre Mem Init PPI instances and call them one by one
+ //
+ Instance = 0;
+ do {
+ Status = PeiServicesLocatePpi (
+ &gBoardPreMemInitPpiGuid,
+ Instance,
+ &PeiPpiDescriptor,
+ &BoardPreMemInitPpi
+ );
+
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((EFI_D_INFO, "Call Board Pre Mem Init PPI\n"));
+ Status = BoardPreMemInitPpi->PreMemInit (PeiServices, BoardPreMemInitPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Instance ++;
+ } while (TRUE);
+ }
+
+ AsmReadGdtr (&GdtDscriptor);
+ DEBUG ((DEBUG_INFO, "GdtDscriptor Base Address:0x%X\n", (UINT32) GdtDscriptor.Base));
+
+ PERF_START_EX (NULL, NULL, NULL, 0, 0x9100);
+ SeCUmaEntry (FileHandle, PeiServices);
+ PERF_END_EX (NULL, NULL, NULL, 0, 0x9101);
+
+ Status = PeiScPreMemPolicyInit (&StartTimerTicker);
+ ASSERT_EFI_ERROR (Status);
+ Status = PeiSiPolicyInit ();
+ ASSERT_EFI_ERROR (Status);
+
+ if (!ImageInMemory) {
+ if (GdtDscriptor.Base >= 0xFE000000) {
+ IfwiVerAddr = GdtDscriptor.Base;
+ IfwiVerAddr &= 0xfffff000; // 4K alignment to get IBBL base address.
+ IfwiVerAddr +=0x1000; // the address of IBBL end
+ for (Temp32 = 0; Temp32 < 0x8000; Temp32 += 0x10) {
+ CarMap = (CarMapStruc *) (IfwiVerAddr-Temp32);
+ if (CarMap->Sign == SIGNATURE_32 ('$','S','I','G')) {
+ DEBUG ((DEBUG_INFO, "CarMap Address:0x%X\n", (UINT32) CarMap));
+ break;
+ }
+ }
+ }
+
+ //
+ // Set PcdIafwPlatformInfo = Real_Silicon + Max_RevId
+ //
+ PcdSet32S (PcdIafwPlatformInfo, 0x0000FF00);
+
+ //
+ // Initialize PlatformInfo HOB
+ //
+ ZeroMem (&PlatformInfo, sizeof (PlatformInfo));
+
+ PlatformInfo.SsidSvid = (UINT32) CarMap;
+
+ Status = ReadBxtIPlatformIds (PeiServices, &PlatformInfo);
+
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Build HOB for PlatformInfo
+ //
+ BuildGuidDataHob (
+ &gEfiPlatformInfoGuid,
+ &PlatformInfo,
+ sizeof (EFI_PLATFORM_INFO_HOB)
+ );
+ //
+ // Attempt to locate SMIP and publish its data to PPI's and PCDs.
+ // Currently no reason to check Status, but could add in future.
+ //
+ // This currently installs gDramPolicyPpiGuid, but may move in future
+ //
+ Status = SmipInit ((VOID *)CarMap->FITBase, PlatformInfo.BoardId);
+
+ MultiPlatformGpioUpdatePreMem ();
+
+ //
+ //Print out Patch version string (BXT)
+ //
+ AsmWriteMsr64 (0x8B, 0);
+ AsmCpuid (0x1, NULL, NULL, NULL, NULL);
+ Temp32 = (UINT32) (AsmReadMsr64 (0x8B) >> 32);
+ DEBUG ((DEBUG_INFO, "PatchInfo: 0x%08x ", Temp32 ));
+ DEBUG ((DEBUG_INFO, "%08x \n", (UINT32) (AsmReadMsr64 (0x8B))));
+
+ //
+ // Set the new boot mode for MRC
+ //
+ Status = UpdateBootMode (PeiServices, &PlatformInfo);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize MfgMemoryTest PPIs
+ //
+ Status = PeiServicesInstallPpi (&mMfgMemTestPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Setting 8254
+ // Program timer 1 as refresh timer
+ //
+ IoWrite8 (0x43, 0x54);
+ IoWrite8 (0x41, 0x12);
+
+ //
+ // RTC power failure handling
+ //
+ RtcPowerFailureHandler ();
+
+ Status = PeiSaPreMemPolicyInit();
+ ASSERT_EFI_ERROR (Status);
+
+ #if (ENBDT_PF_ENABLE == 1)
+ if (GetBxtSeries() == BxtP) {
+ //
+ // DDR SSC
+ //
+ PeiDDRSSCInit ();
+
+ //
+ // USB3, PCie, SATA, eDP, DP, eMMC, SD and SDIO SSC
+ //
+ PeiHighSpeedSerialInterfaceSSCInit ();
+ }
+ #endif
+
+ #if defined(PRAM_SUPPORT)
+ //
+ // Install Ppi for BIOS reserved memory
+ //
+ Status = PeiServicesInstallPpi (&mBiosReservedMemoryPolicyPpi);
+ #endif
+
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ VariableSize = sizeof (SystemConfiguration);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ &SystemConfiguration
+ );
+
+ AcpiVarHobSize = sizeof (UINT64);
+ BuildGuidDataHob (
+ &gEfiAcpiVariableCompatiblityGuid,
+ &SystemConfiguration.AcpiVariableSetCompatibility,
+ sizeof (AcpiVarHobSize)
+ );
+
+ DEBUG ((DEBUG_INFO, "AcpiVariableAddr : 0x%08x\n", SystemConfiguration.AcpiVariableSetCompatibility));
+
+ PERF_START_EX (NULL, "RstVctr", "IBBL", 1, 0x1000);
+ Tick = CarMap->IbblPerfRecord0;
+ PERF_END_EX (NULL, "RstVctr", "IBBL", Tick, 0x1001);
+
+ PERF_START_EX (NULL, "InitNEM", "IBBL", Tick, 0x1010);
+ Tick = CarMap->IbblPerfRecord1;
+ PERF_END_EX (NULL, "InitNEM", "IBBL", Tick, 0x1011);
+
+ PERF_START_EX (NULL, "IBBLSdw", "IBBL", Tick, 0x1020);
+ Tick = CarMap->IbblPerfRecord2;
+ PERF_END_EX (NULL, "IBBLSdw", "IBBL", Tick, 0x1021);
+
+ PERF_START_EX (NULL, "IBBMLod", "IBBL", Tick, 0x1030);
+ Tick = CarMap->IbblPerfRecord3;
+ PERF_END_EX (NULL, "IBBMLod", "IBBL", Tick, 0x1031);
+
+ PERF_START_EX (NULL, "IBBMVer", "IBBL", Tick, 0x1040);
+ Tick = CarMap->IbblPerfRecord4;
+ PERF_END_EX (NULL, "IBBMVer", "IBBL", Tick, 0x1041);
+
+ //
+ // Normal boot - build Hob for SEC performance data.
+ //
+ Performance.ResetEnd = GetTimeInNanoSecond (CarMap->IbblPerfRecord0);
+ if (!EFI_ERROR (Status)) {
+ BuildGuidDataHob (
+ &gEfiFirmwarePerformanceGuid,
+ &Performance,
+ sizeof (FIRMWARE_SEC_PERFORMANCE)
+ );
+ DEBUG ((EFI_D_INFO, "FPDT: SEC Performance Hob ResetEnd = %ld\n", Performance.ResetEnd));
+ }
+
+ } else { //PostMem
+
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (Hob.Raw != NULL);
+ PlatformInfoPtr = GET_GUID_HOB_DATA (Hob.Raw);
+ CarMap = (CarMapStruc *) (UINT32) PlatformInfoPtr->SsidSvid;
+ //
+ // Locate and Reinstall necessary PPI's before MemoryCallback is run
+ //
+ Status = PeiServicesLocatePpi (
+ &gDramPolicyPpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ NULL // PPI
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Couldn't locate DRAM Policy PPI, LocatePpi returned %r.\n", Status));
+ } else {
+ DramPolicy = (DRAM_POLICY_PPI *) AllocateZeroPool (sizeof (DRAM_POLICY_PPI));
+ NewPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ if ((DramPolicy == NULL) || (NewPeiPpiDescriptor == NULL)) {
+ DEBUG ((DEBUG_ERROR, "Couldn't allocate memory for DRAM Policy PPI.\n"));
+ } else {
+ (*PeiServices)->CopyMem (
+ (VOID *) DramPolicy,
+ (VOID *) PeiPpiDescriptor->Ppi,
+ sizeof (DRAM_POLICY_PPI)
+ );
+
+ NewPeiPpiDescriptor->Ppi = DramPolicy;
+ NewPeiPpiDescriptor->Guid = &gDramPolicyPpiGuid;
+ NewPeiPpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ Status = (**PeiServices).ReInstallPpi (
+ PeiServices,
+ PeiPpiDescriptor,
+ NewPeiPpiDescriptor
+ );
+ }
+ }
+
+ if (GdtDscriptor.Base >= 0xFE000000) {
+ (*PeiServices)->CopyMem (
+ (VOID *) mGdtTable,
+ (VOID *) GdtDscriptor.Base,
+ GdtDscriptor.Limit + 1
+ );
+ GdtDscriptor.Base = (UINT32) mGdtTable;
+ AsmWriteGdtr (&GdtDscriptor);
+ }
+
+ //
+ // Set "Force Volatile Mode" in the variable driver
+ // If Firmware Descriptor Override (FDO) boot is enabled
+ //
+ FdoEnabledGuidHob = GetFirstGuidHob (&gFdoModeEnabledHobGuid);
+ if (FdoEnabledGuidHob != NULL) {
+ PcdSetBoolS (PcdForceVolatileVariable, TRUE);
+ }
+
+ //
+ // locate the MfgMemoryTest PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gPeiMfgMemoryTestPpiGuid, // GUID
+ 0, // INSTANCE
+ &PeiPpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
+ NULL // PPI
+ );
+ if (Status == EFI_SUCCESS) {
+ //
+ // Reinstall the MfgMemoryTest PPI
+ //
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mMfgMemTestPpi
+ );
+ }
+
+ //
+ // locate the TemporaryRamSupport PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiTemporaryRamSupportPpiGuid, // GUID
+ 0, // INSTANCE
+ &PeiPpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
+ NULL // PPI
+ );
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Reinstall the Variable PPI
+ //
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ mPeiTemporaryRamSupportPpiPpi
+ );
+ }
+
+#if defined(PRAM_SUPPORT)
+ //
+ // locate the BiosReservedMemory PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gBiosReservedMemoryPolicyPpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ NULL // PPI
+ );
+
+ if (Status == EFI_SUCCESS) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mBiosReservedMemoryPolicyPpi
+ );
+ }
+#endif
+
+ //
+ // Initialize Stall PPIs
+ //
+ Status = PeiServicesInstallPpi (&mInstallStallPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesGetBootMode (&BootMode);
+#if (ENBDT_PF_ENABLE == 1)
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ 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)) {
+ SetMem (&BootMediaData, sizeof (MBP_CURRENT_BOOT_MEDIA), 0x0);
+ switch (SystemConfiguration.CseBootDevice) {
+ case 0:
+ DEBUG ((DEBUG_INFO, "CSE Boot Device is EMMC.\n"));
+ Status = (*PeiServices)->InstallPpi (PeiServices, mCseEmmcSelectPpiList);
+ break;
+ case 1:
+ DEBUG ((DEBUG_INFO, "CSE Boot Device is UFS.\n"));
+ Status = (*PeiServices)->InstallPpi (PeiServices, mCseUfsSelectPpiList);
+ break;
+ case 2:
+ DEBUG ((DEBUG_INFO, "CSE Boot Device is SPI.\n"));
+ Status = (*PeiServices)->InstallPpi (PeiServices, mCseSpiSelectPpiList);
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "\nCSE Boot device is unknown. Cannot continue!\n"));
+ CpuDeadLoop();
+ break;
+
+ }
+ BootMediaData.PhysicalData = SystemConfiguration.CseBootDevice;
+ //
+ // Build HOB for BootMediaData
+ //
+ BuildGuidDataHob (
+ &gEfiBootMediaHobGuid,
+ &BootMediaData,
+ sizeof (MBP_CURRENT_BOOT_MEDIA)
+ );
+ }
+ }
+#endif
+
+ //
+ // copy IBBM from Cache to DRAM. the hardcoded address need to be changed
+ // to use the parameter in IBBL.
+ //
+ Memory = AllocatePages (EFI_SIZE_TO_PAGES (PcdGet32 (PcdFlashFvIBBMSize)));
+ if (Memory != NULL) {
+ CopyMem (Memory , (VOID *) CarMap->IBBBase, PcdGet32 (PcdFlashFvIBBMSize));
+ DEBUG ((DEBUG_INFO, "IBBM address: %x\n", Memory));
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ (VOID *) Memory,
+ PcdGet32 (PcdFlashFvIBBMSize),
+ NULL,
+ NULL
+ );
+ } else {
+ ASSERT (FALSE);
+ }
+
+ DEBUG ((DEBUG_INFO, "PreMem Policy Init - Start\n"));
+ //
+ // Initialize Pre-Mem PEI Platform Policy
+ //
+ Status = PeiPolicyInitPreMem ();
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "PreMem Policy Init - End\n\n"));
+
+ //
+ // Register Notify Callback to process OBB loading.
+ // In FSP+Wrapper, the MTRRs are set after TempRamExit, not gEfiPeiMemoryDiscoveredPpiGuid.
+ //
+ Status = PeiServicesNotifyPpi (&mFspTempRamExitList[0]);
+ ASSERT_EFI_ERROR (Status);
+ } //end PostMem
+
+ DEBUG ((DEBUG_INFO, "PeiInitPlatform end\n"));
+
+ return Status;
+}
+
+//
+// Read Platform ID for IOTG Platforms
+//
+EFI_STATUS
+ReadBxtIPlatformIds (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+ UINT8 BoardId = 0;
+ UINT8 FabId = 0;
+
+ DEBUG ((DEBUG_INFO, "Port(0x62) = %02X\n", IoRead8 (0x62)));
+
+ PlatformInfoHob->ECPresent = 0;
+ BoardId = (UINT8) PcdGet8 (PcdBoardId);
+ FabId = (UINT8) PcdGet8 (PcdFabId);
+
+ PlatformInfoHob->BoardId = BoardId;
+ PlatformInfoHob->BoardRev = FabId;
+
+ DEBUG ((DEBUG_INFO, "BoardId: [0x%08x]\n", PlatformInfoHob->BoardId));
+ DEBUG ((DEBUG_INFO, "FabId: [0x%08x]\n", PlatformInfoHob->BoardRev));
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h
new file mode 100644
index 0000000000..ca571ec8ed
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h
@@ -0,0 +1,149 @@
+/** @file
+ The header file of Platform PEIM.
+
+ 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 __PLATFORM_INIT_PREMEM_H__
+#define __PLATFORM_INIT_PREMEM_H__
+
+typedef struct {
+ UINT32 Sign ; ///< Signiture#
+ UINT32 CarBase ; ///< Cache As Ram Base Address
+ UINT32 CarSize ; ///< Cache As Ram Size
+ UINT32 IBBSource ; ///< IBB Address in SRAM
+ UINT32 IBBBase ; ///< IBB Base in CAR.
+ UINT32 IBBSize ; ///< IBB Size
+ UINT32 IBBLSource ; ///< IBBL Address in SRAM
+ UINT32 IBBLBase ; ///< IBBL Base in CAR.
+ UINT32 IBBLSize ; ///< IBBL Size
+ UINT32 FITBase ; ///< FIT Base Address
+ UINT32 StackHeapBase ; ///< STACK&HEAP Base.
+ UINT32 StackHeapSize ; ///< STACK&HEAP Size
+ UINT32 HostToCse ;
+ UINT32 CseToHost ;
+ UINT32 ChunkIndex ;
+ UINT32 NumberOfChunks ;
+ UINT32 IbbSizeLeft ;
+ UINT32 Chunksize ;
+ UINT64 IbblPerfRecord0; ///< The QWORD Performance record0 of IBBL
+ UINT64 IbblPerfRecord1; ///< The QWORD Performance record1 of IBBL
+ UINT64 IbblPerfRecord2; ///< The QWORD Performance record2 of IBBL
+ UINT64 IbblPerfRecord3; ///< The QWORD Performance record3 of IBBL
+ UINT64 IbblPerfRecord4; ///< The QWORD Performance record4 of IBBL
+ UINT64 IbblPerfRecord5; ///< The QWORD Performance record5 of IBBL
+} CarMapStruc;
+
+//
+//Function Prototypes Only - please do not add #includes here
+//
+/**
+ This is the callback function notified by FvFileLoader PPI, it depends on FvFileLoader PPI to load
+ the PEIM into memory.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The context of notification.
+ @param[in] 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
+ );
+
+EFI_STATUS
+EFIAPI
+SeCUmaEntry (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+EFI_STATUS
+EFIAPI
+UpdateSaPreMemPolicy (
+ IN OUT SA_PRE_MEM_CONFIG *SaPreMemConfig
+ );
+
+EFI_STATUS
+EFIAPI
+GetBiosReservedMemoryPolicy (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BIOS_RESERVED_MEMORY_POLICY_PPI *This,
+ IN OUT BIOS_RESERVED_MEMORY_CONFIG *BiosReservedMemoryPolicy
+ );
+
+EFI_STATUS
+EFIAPI
+MfgMemoryTest (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_MFG_MEMORY_TEST_PPI *This,
+ IN UINT32 BeginAddress,
+ IN UINT32 MemoryLength
+ );
+
+BOOLEAN
+IsRtcUipAlwaysSet (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+VOID
+RtcPowerFailureHandler (
+ VOID
+ );
+
+VOID
+ScBaseInit (
+ VOID
+ );
+
+EFI_STATUS
+UpdateBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ );
+
+/**
+ This function performs Silicon Policy initialization.
+
+ @param[in] FirmwareConfiguration It uses to skip specific policy init that depends
+ on the 'FirmwareConfiguration' variable.
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+
+**/
+EFI_STATUS
+EFIAPI
+PeiSiPolicyInit (
+ VOID
+ );
+
+EFI_STATUS
+ReadBxtIPlatformIds (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ );
+
+EFI_STATUS
+EFIAPI
+InstallMonoStatusCode (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformPreMemPei.inf b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformPreMemPei.inf
new file mode 100644
index 0000000000..dd8d073dbb
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformPreMemPei.inf
@@ -0,0 +1,185 @@
+## @file
+# This is the Platform PEIM to initialize whole platform on PEI phase.
+#
+# This PEIM includes 3 parts, pre-memory initialization, MRC
+# wrapper and post memory initialization.
+#
+# On pre-memory, the following actions are performed:
+# 1. Initialize System Agent.
+# 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, the following actions are 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.
+#
+# 1. Platform.c - Provide main flow and entry point of PEIM.
+# 2. MemoryCallback.c - Includes a memory call back function notified when
+# MRC is done.
+#
+# 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformInitPreMem
+ FILE_GUID = 9618C0DC-50A4-496c-994F-7241F282ED01
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformInitPreMemEntryPoint
+
+[Sources]
+ PlatformInitPreMem.c
+ PlatformInitPreMem.h
+ Stall.c
+ Smip.c
+ BootMode.c
+ BoardGpiosPreMem.c
+ FvCallback.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ SecurityPkg/SecurityPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+ BroxtonFspPkg/BroxtonFspPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ PeiServicesLib
+ DebugLib
+ HobLib
+ IoLib
+ PcdLib
+ MtrrLib
+ PerformanceLib
+ MonoStatusCodeLib
+ SeCUmaLib
+ BaseIpcLib
+ PeiSiPolicyInit
+ PeiPlatformConfigUpdateLib
+ GpioLib
+ CpuPolicyLib
+ HeciMsgLib
+ ScPlatformLib
+ SteppingLib
+ TimerLib
+ PeiPolicyInitLib
+ PeiVariableCacheLib
+ FspWrapperApiLib
+
+[Guids]
+ gEfiSetupVariableGuid
+ gEfiPlatformInfoGuid
+ gEfiPlatformBootModeGuid
+ gEfiPlatformCpuInfoGuid
+ gEfiGlobalVariableGuid
+ gMfgModeVariableGuid
+ gEfiNormalSetupGuid
+ gEfiSystemNvDataFvGuid
+ gIFWIVersionHobGuid
+ gEfiBootMediaHobGuid
+ gUfsBootLunIdHobGuid
+ gMicroCodepointerGuid
+ gUfsPhyOverrideHobGuid
+ gEfiAcpiVariableCompatiblityGuid
+ gObbyFirmwareFileSystemFvGuid
+ gFspSFirmwareFileSystemFvGuid
+ gIbbrFirmwareFileSystemFvGuid
+ gEfiFirmwarePerformanceGuid
+ gEfiAuthenticatedVariableGuid
+ gFspTempRamExitGuid
+
+[Ppis]
+ gEfiPeiStallPpiGuid
+ gEfiPeiMemoryDiscoveredPpiGuid
+ gEfiPeiReadOnlyVariable2PpiGuid
+ gPeiCapsulePpiGuid
+ gEfiPeiBootInRecoveryModePpiGuid
+ gPeiCachePpiGuid
+ gPeiMfgMemoryTestPpiGuid
+ gEfiPeiVirtualBlockIoPpiGuid
+ gEfiTemporaryRamSupportPpiGuid
+ gDramPolicyPpiGuid
+ gCpuConfigGuid
+ gBiosReservedMemoryPolicyPpiGuid
+ gPowerMgmtConfigGuid
+ gSiSaPreMemPolicyPpiGuid
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdFlashBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBXBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBXSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBRBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBRSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBMBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBMSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBLBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBLSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBYBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBYSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashObbPayloadMappedBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashObbPayloadSize
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdIafwPlatformInfo ## PRODUCES
+ gEfiBxtTokenSpaceGuid.PcdPmcSsramBaseAddress0 ## CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdPmcSsramBaseAddress1 ## CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdPlatformIdRegisterOffset ## CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdP2SBBaseAddress ## CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdIfwiZid
+ gSiPkgTokenSpaceGuid.PcdForceVolatileVariable ## PRODUCES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdBoardId
+ gPlatformModuleTokenSpaceGuid.PcdFabId
+ gPlatformModuleTokenSpaceGuid.PcdDramCreatePolicyDefaultsFunc
+
+[FeaturePcd]
+ gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam
+
+[Depex]
+ TRUE
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Smip.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Smip.c
new file mode 100644
index 0000000000..74ed5643aa
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Smip.c
@@ -0,0 +1,296 @@
+/** @file
+ Copyright (c) 2015 - 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 <Uefi.h>
+#include <SmipGenerated.h>
+#include <Ppi/DramPolicyPpi.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiVariableCacheLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/PreMemoryVariableLocationHobGuid.h>
+#include <Library/SteppingLib.h>
+#include <BoardFunctionsPei.h>
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+#define DEBUG(x)
+
+#define COUNT_LIMIT 0x13 // reasonable limit for smipblock loop
+#define GPT_MARKER 0x54504724
+
+#define NO_MRC_TRG_DATA_MSG "__NO_MRC_TRNG_DATA_AVAILABLE__"
+
+#pragma pack(push, 1)
+typedef struct {
+ UINT64 Address;
+ UINT32 Size:24;
+ UINT32 Rsvd:8;
+ UINT16 Version;
+ UINT8 Type:7;
+ UINT8 C_V:1;
+ UINT8 Checksum;
+} FitEntry;
+
+typedef struct {
+ UINT16 BlockCount;
+ UINT16 TotalSize;
+} SmipHeader;
+
+typedef struct {
+ UINT16 BlockType; // 0=CSE, 1=PMC, 2=IAFW
+ UINT16 BlockOffset;
+ UINT16 BlockLength;
+ UINT16 Reserved;
+} SmipBlockHeader;
+#pragma pack(pop)
+
+
+/**
+ DramInstallPolicyPpi installs Dram Policy Ppi.
+
+ @param[in] DramPolicyPpi The pointer to Dram Policy PPI instance
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+DramInstallPolicyPpi (
+ IN DRAM_POLICY_PPI *DramPolicyPpi
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *DramPolicyPpiDesc;
+
+ DramPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ if (DramPolicyPpiDesc == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DramPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ DramPolicyPpiDesc->Guid = &gDramPolicyPpiGuid;
+ DramPolicyPpiDesc->Ppi = DramPolicyPpi;
+
+ //
+ // Install Silicon Policy PPI
+ //
+ Status = PeiServicesInstallPpi (DramPolicyPpiDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+VOID
+PrintVariableData (
+ IN UINT8 *Data8,
+ IN UINTN DataSize
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < DataSize; Index++) {
+ if (Index % 0x10 == 0) {
+ DEBUG ((EFI_D_INFO, "\n%08X:", Index));
+ }
+ DEBUG ((EFI_D_INFO, " %02X", *Data8++));
+ }
+ DEBUG ((EFI_D_INFO, "\n"));
+}
+
+
+/**
+ Smip Init Function.
+
+ @retval EFI_SUCCESS Smip init successfully.
+ @retval EFI_NOT_FOUND Smip init fail.
+
+**/
+EFI_STATUS
+SmipInit (
+ IN VOID *FitHeaderPtr,
+ IN UINT8 BoardId
+ )
+{
+ UINT16 Index;
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN MrcTrainingDataSize = 0;
+ UINTN MrcBootDataSize = 0;
+ UINTN SetupDataSize = 0;
+ UINTN MrcTrainingDataAddr = 0;
+ UINTN MrcBootDataAddr = 0;
+ PRE_MEMORY_VARIABLE_LOCATION_HOB PreMemoryVariableLocation;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
+ SmipHeader *SmipHeadPointer = NULL;
+ SmipBlockHeader *SmipBlockPtr = NULL;
+ IafwSmipLayout *SmipIafwPointer = NULL;
+ FitEntry *FitHeader = NULL;
+ FitEntry *FitEntries = NULL;
+ DRAM_POLICY_PPI *DramPolicyPpi = NULL;
+ CHAR8 *NoMrcTrainingDataString = NO_MRC_TRG_DATA_MSG;
+ EFI_PLATFORM_INFO_HOB *PlatformInfoHob = NULL;
+ DRAM_CREATE_POLICY_DEFAULTS_FUNC DramCreatePolicyDefaultsFunc;
+
+ ZeroMem (&Hob, sizeof (Hob));
+ FitHeader = (FitEntry *) FitHeaderPtr;
+ FitEntries = FitHeader;
+
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "Checking FitHeader at 0x%08x\n", FitHeader ));
+
+ if (FitHeader->Address != SIGNATURE_64 ('_', 'F', 'I', 'T', '_', ' ', ' ', ' ')) {
+ DEBUG ((EFI_D_ERROR, "FitHeader signature was invalid.\n"));
+ return EFI_NOT_FOUND;
+ }
+ DEBUG ((EFI_D_INFO, "FitHeader signature verified.\n"));
+
+ //
+ // Get Platform Info HOB
+ //
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (Hob.Raw != NULL);
+ PlatformInfoHob = GET_GUID_HOB_DATA(Hob.Raw);
+
+ //
+ // Loop through FIT Entries until we find SMIP (start at 1 to skip header)
+ //
+ DEBUG ((EFI_D_INFO, "Searching for SMIP Entry in FIT...\n" ));
+ for (Index = 1; Index < FitHeader->Size; Index++) {
+ if (FitEntries[Index].Type == 0x10 && FitEntries[Index].Rsvd == 0x5) {
+ DEBUG ((EFI_D_INFO, "Found SMIP Entry in FIT.\n" ));
+
+ SmipHeadPointer = (SmipHeader *) (UINTN) (FitEntries[Index].Address);
+ SmipBlockPtr = (SmipBlockHeader *) ((UINT8 *) SmipHeadPointer + sizeof (SmipHeadPointer));
+
+ DEBUG ((EFI_D_INFO, "SMIP table located at: 0x%08x\n", SmipHeadPointer));
+ DEBUG ((EFI_D_INFO, "SMIP table size = 0x%08x bytes\n", SmipHeadPointer->TotalSize));
+ } else if (FitEntries[Index].Type == 0x10 && FitEntries[Index].Rsvd == 0x6) {
+ DEBUG ((EFI_D_INFO, "Found the entry for MRC Training Data in FIT. Checking if data is present...\n" ));
+ PreMemoryVariableLocation.VariableDataPtr = (VOID *) (UINTN) (FitEntries[Index].Address);
+ PreMemoryVariableLocation.VariableDataSize = FitEntries[Index].Size;
+
+ //
+ // Check if Setup data is available in the MRC training data file
+ //
+ if (AsciiStrnCmp ((CHAR8 *) PreMemoryVariableLocation.VariableDataPtr, NoMrcTrainingDataString, AsciiStrSize (NoMrcTrainingDataString)) != 0) {
+ DEBUG ((EFI_D_INFO, "MRC training data is present in FIT. Data will be loaded from the file...\n"));
+ DEBUG ((EFI_D_INFO, "Training data file contents at 0x%08x. Content data size = %d bytes.\n", PreMemoryVariableLocation.VariableDataPtr, PreMemoryVariableLocation.VariableDataSize));
+
+ //
+ // Store the temporary location of the training data variable store
+ //
+ BuildGuidDataHob (&gPreMemoryVariableLocationHobGuid, (VOID *) &PreMemoryVariableLocation, sizeof (PRE_MEMORY_VARIABLE_LOCATION_HOB));
+
+ //
+ // Create the variable cache HOB
+ // - It is populated with the pre-memory NVM file contents and consumed by the variable PEIM
+ // on variable read requests.
+ // - The address to the training data is stored in the MemoryConfig variable.
+ //
+ Status = CreateVariableCacheHob ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "The PEI variable data cache was not established but training data is available.\n"));
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ SetupDataSize = sizeof (SETUP_DATA);
+ Status = VariablePpi->GetVariable (VariablePpi, L"Setup", &gEfiSetupVariableGuid, NULL, &SetupDataSize, &SystemConfiguration);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_WARN, "Could not read the Setup variable after establishing the cache.\n"));
+ }
+
+ MrcTrainingDataSize = sizeof (EFI_PHYSICAL_ADDRESS);
+ Status = VariablePpi->GetVariable (VariablePpi, L"MemoryConfig", &gEfiMemoryConfigVariableGuid, NULL, &MrcTrainingDataSize, &MrcTrainingDataAddr);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_WARN, "Could not read the variable to find the MemoryConfig data address.\n"));
+ }
+
+ MrcBootDataSize = sizeof (EFI_PHYSICAL_ADDRESS);
+ Status = VariablePpi->GetVariable (VariablePpi, L"MemoryBootData", &gEfiMemoryConfigVariableGuid, NULL, &MrcBootDataSize, &MrcBootDataAddr);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_WARN, "Could not read the variable to find the MemoryBootData address.\n"));
+ }
+
+ //
+ // Print Setup variable data
+ //
+ DEBUG_CODE_BEGIN ();
+
+ //
+ // Print default Setup variable.
+ //
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "\nDumping Setup data:"));
+ PrintVariableData ((UINT8 *) &SystemConfiguration, SetupDataSize);
+ }
+ DEBUG_CODE_END ();
+ } else {
+ DEBUG ((EFI_D_INFO, "Training data not found. This is considered a first boot.\n\n"));
+ }
+ }
+ }
+ if (SmipHeadPointer == NULL) {
+ DEBUG ((EFI_D_ERROR, "No SMIP Entry found in FIT\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Loop through SMIP Header and look for IAFW SMIP entry
+ //
+ DEBUG ((EFI_D_INFO, "Searching SMIP Header for IAFW entry...\n" ));
+ for (Index = 1; Index <= SmipHeadPointer->BlockCount && Index < COUNT_LIMIT; Index++, SmipBlockPtr++) {
+ if ( SmipBlockPtr->BlockType == 0x2) {
+ DEBUG ((EFI_D_INFO, "Found IAFW SMIP Block at 0x%08x\n", SmipBlockPtr->BlockOffset ));
+ SmipIafwPointer = (IafwSmipLayout*) ((UINT8*) SmipHeadPointer + SmipBlockPtr->BlockOffset);
+ break;
+ }
+ }
+
+ if (SmipIafwPointer == NULL) {
+ DEBUG ((EFI_D_ERROR, "No IAFW SMIP Block found\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Parse SMIP and publish data to PPI's and PCD's -- STILL UNDER DEVELOPMENT...
+ //
+ DEBUG ((EFI_D_INFO, "IafwSmipLayout->IafwSmipSignature = 0x%08x\n", SmipIafwPointer->IafwSmipSignature ));
+ DEBUG ((DEBUG_INFO, "***** Calling DramCreatePolicyDefaults ***** \n"));
+ DramCreatePolicyDefaultsFunc = (DRAM_CREATE_POLICY_DEFAULTS_FUNC) (UINTN) PcdGet64 (PcdDramCreatePolicyDefaultsFunc);
+
+ Status = DramCreatePolicyDefaultsFunc (VariablePpi, &DramPolicyPpi, &(SmipIafwPointer->DramConfig), &MrcTrainingDataAddr, &MrcBootDataAddr, BoardId);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = DramInstallPolicyPpi (DramPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Smip.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Smip.h
new file mode 100644
index 0000000000..bd4b30d528
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Smip.h
@@ -0,0 +1,26 @@
+/** @file
+ Header file for the SMIP parser code.
+
+ Copyright (c) 2015 - 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 __SMIP_HEADER_H__
+#define __SMIP_HEADER_H__
+
+EFI_STATUS
+SmipInit (
+ IN VOID* FitHeaderPtr,
+ IN UINT8 BoardId
+ );
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Stall.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Stall.c
new file mode 100644
index 0000000000..7630325299
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Stall.c
@@ -0,0 +1,101 @@
+/** @file
+ Produce Stall 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 <ScAccess.h>
+#include <PlatformBaseAddresses.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/Stall.h>
+#include "Stall.h" //Function Prototypes
+
+
+/**
+ Waits for at least the given number of microseconds.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This PPI instance structure.
+ @param[in] 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
+ )
+{
+ //
+ // !! This should be re-written to use TimerLib !!
+ //
+ UINTN Ticks;
+ UINTN Counts;
+ UINT16 AcpiBaseAddr;
+ UINT32 CurrentTick;
+ UINT32 OriginalTick;
+ UINT32 RemainingTick;
+
+ if (Microseconds == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ OriginalTick = IoRead32 (AcpiBaseAddr + R_ACPI_PM1_TMR);
+ OriginalTick &= (V_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 (AcpiBaseAddr + R_ACPI_PM1_TMR) & B_ACPI_PM1_TMR_VAL;
+ if (CurrentTick <= OriginalTick) {
+ Counts--;
+ }
+ OriginalTick = CurrentTick;
+ }
+
+ while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
+ OriginalTick = CurrentTick;
+ CurrentTick = IoRead32 (AcpiBaseAddr + R_ACPI_PM1_TMR) & B_ACPI_PM1_TMR_VAL;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Stall.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Stall.h
new file mode 100644
index 0000000000..7508341ea6
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/Stall.h
@@ -0,0 +1,42 @@
+/** @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 __STALL_HEADER_H__
+#define __STALL_HEADER_H__
+
+//
+//Function Prototypes only - please do not add #includes here
+//
+/**
+ This function provides a blocking stall for reset at least the given number of microseconds
+ stipulated in the final argument.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This Pointer to the local data for the interface.
+ @param[in] 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
+ );
+#endif
+