summaryrefslogtreecommitdiff
path: root/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib
diff options
context:
space:
mode:
authorJiewen Yao <jiewen.yao@intel.com>2017-06-19 10:55:06 +0800
committerJiewen Yao <jiewen.yao@intel.com>2017-06-20 15:12:29 +0800
commit646b243c0e3ef49b98071ca2c3fec15299b4d72f (patch)
tree00d62812fcedd3d1bf49692b863bb48a826f3ab0 /Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib
parentf98787b719524d7ba9f2cefac0e8c8b8698cb02c (diff)
downloadedk2-platforms-646b243c0e3ef49b98071ca2c3fec15299b4d72f.tar.xz
Add KabylakeSiliconPkg
reviewed-by: Jiewen Yao <jiewen.yao@intel.com> reviewed-by: Michael A Kubacki <michael.a.kubacki@intel.com> reviewed-by: Amy Chan <amy.chan@intel.com> reviewed-by: Rangasai V Chaganty <rangasai.v.chaganty@intel.com> reviewed-by: Chasel Chiu <chasel.chiu@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
Diffstat (limited to 'Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib')
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S58
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm85
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm79
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c747
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h313
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c365
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf72
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c281
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h44
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c326
10 files changed, 2370 insertions, 0 deletions
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S
new file mode 100644
index 0000000000..d8fe66154a
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S
@@ -0,0 +1,58 @@
+## @file
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License that accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+ASM_GLOBAL ASM_PFX(SaMmioRead64)
+ASM_PFX(SaMmioRead64):
+ subl $16, %esp
+ movq %mm0, (%esp) #Save mm0 on stack
+ movl 20(%esp), %edx #edx = Address
+ movq (%edx), %mm0 #mm0 = [Address]
+ movq %mm0, 8(%esp) #Store mm0 on Stack
+ movq (%esp), %mm0 #Restore mm0
+ emms
+ movl 8(%esp), %eax #eax = [Address][31:0]
+ movl 12(%esp), %edx #edx = [Address][64:32]
+ addl $16, %esp
+ ret
+
+#-----------------------------------------------------------------------------
+#
+# Section: SaMmioWrite64
+#
+# Description: Write 64 bits to the Memory Mapped I/O space.
+# Use MMX instruction for atomic access, because some MC registers have side effect.
+#
+# @param[in] Address - Memory mapped I/O address.
+# @param[in] Value - The value to write.
+#
+#-----------------------------------------------------------------------------
+
+#UINT64
+#SaMmioWrite64 (
+# IN UINTN Address,
+# IN UINT64 Value
+# )
+
+ASM_GLOBAL ASM_PFX(SaMmioWrite64)
+ASM_PFX(SaMmioWrite64):
+ subl $8, %esp
+ movq %mm0, (%esp) #Save mm0 on Stack
+ movl 12(%esp), %edx #edx = Address
+ movq 16(%esp), %mm0 #mm0 = Value
+ movq %mm0, (%edx) #[Address] = Value
+ movq (%esp), %mm0 #Restore mm0
+ emms
+ movl 16(%esp), %eax #eax = Value[31:0]
+ movl 20(%esp), %edx #edx = Value[64:32]
+ addl $8, %esp
+ ret
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm
new file mode 100644
index 0000000000..bef8aafe1a
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm
@@ -0,0 +1,85 @@
+;; @file
+; This file provides assembly 64-bit atomic reads/writes required for memory initialization.
+;
+; Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials are licensed and made available under
+; the terms and conditions of the BSD License that accompanies this distribution.
+; The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;;
+
+.686p
+.xmm
+.model small, c
+
+.CODE
+
+;-----------------------------------------------------------------------------
+;
+; Section: SaMmioRead64
+;
+; Description: Read 64 bits from the Memory Mapped I/O space.
+; Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+; @param[in] Address - Memory mapped I/O address.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioRead64 (
+; IN UINTN Address
+; )
+
+SaMmioRead64 PROC NEAR PUBLIC
+ sub esp, 16
+ movq [esp], mm0 ;Save mm0 on stack
+ mov edx, [esp + 20] ;edx = Address
+ movq mm0, [edx] ;mm0 = [Address]
+ movq [esp + 8], mm0 ;Store mm0 on Stack
+ movq mm0, [esp] ;Restore mm0
+ emms
+ mov eax, [esp + 8] ;eax = [Address][31:0]
+ mov edx, [esp + 12] ;edx = [Address][64:32]
+ add esp, 16
+ ret
+SaMmioRead64 ENDP
+
+;-----------------------------------------------------------------------------
+;
+; Section: SaMmioWrite64
+;
+; Description: Write 64 bits to the Memory Mapped I/O space.
+; Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+; @param[in] Address - Memory mapped I/O address.
+; @param[in] Value - The value to write.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioWrite64 (
+; IN UINTN Address,
+; IN UINT64 Value
+; )
+
+SaMmioWrite64 PROC NEAR PUBLIC
+ sub esp, 8
+ movq [esp], mm0 ;Save mm0 on Stack
+ mov edx, [esp + 12] ;edx = Address
+ movq mm0, [esp + 16] ;mm0 = Value
+ movq [edx], mm0 ;[Address] = Value
+ movq mm0, [esp] ;Restore mm0
+ emms
+ mov eax, [esp + 16] ;eax = Value[31:0]
+ mov edx, [esp + 20] ;edx = Value[64:32]
+ add esp, 8
+ ret
+SaMmioWrite64 ENDP
+
+end
+
+
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm
new file mode 100644
index 0000000000..5bc17065bd
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm
@@ -0,0 +1,79 @@
+;; @file
+; This file provides assembly 64-bit atomic reads/writes required for memory initialization.
+;
+; Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials are licensed and made available under
+; the terms and conditions of the BSD License that accompanies this distribution.
+; The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;;
+
+
+SECTION .TEXT
+
+;-----------------------------------------------------------------------------
+;
+; Section: SaMmioRead64
+;
+; Description: Read 64 bits from the Memory Mapped I/O space.
+; Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+; @param[in] Address - Memory mapped I/O address.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioRead64 (
+; IN UINTN Address
+; )
+
+global ASM_PFX(SaMmioRead64)
+ASM_PFX(SaMmioRead64):
+ sub esp, 16
+ movq [esp], mm0 ;Save mm0 on stack
+ mov edx, [esp + 20] ;edx = Address
+ movq mm0, [edx] ;mm0 = [Address]
+ movq [esp + 8], mm0 ;Store mm0 on Stack
+ movq mm0, [esp] ;Restore mm0
+ emms
+ mov eax, [esp + 8] ;eax = [Address][31:0]
+ mov edx, [esp + 12] ;edx = [Address][64:32]
+ add esp, 16
+ ret
+
+;-----------------------------------------------------------------------------
+;
+; Section: SaMmioWrite64
+;
+; Description: Write 64 bits to the Memory Mapped I/O space.
+; Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+; @param[in] Address - Memory mapped I/O address.
+; @param[in] Value - The value to write.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioWrite64 (
+; IN UINTN Address,
+; IN UINT64 Value
+; )
+
+global ASM_PFX(SaMmioWrite64)
+ASM_PFX(SaMmioWrite64):
+ sub esp, 8
+ movq [esp], mm0 ;Save mm0 on Stack
+ mov edx, [esp + 12] ;edx = Address
+ movq mm0, [esp + 16] ;mm0 = Value
+ movq [edx], mm0 ;[Address] = Value
+ movq mm0, [esp] ;Restore mm0
+ emms
+ mov eax, [esp + 16] ;eax = Value[31:0]
+ mov edx, [esp + 20] ;edx = Value[64:32]
+ add esp, 8
+ ret
+
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c
new file mode 100644
index 0000000000..e4d6f1b35c
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c
@@ -0,0 +1,747 @@
+/** @file
+ This file is SampleCode for Intel SA PEI Policy initialization.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "MrcOemPlatform.h"
+#include <Library/CpuPlatformLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmbusLib.h>
+#include <PchAccess.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/PchCycleDecodingLib.h>
+
+#pragma pack (push, 1)
+typedef union {
+ struct {
+ UINT32 : 8;
+ UINT32 MAX_NON_TURBO_LIM_RATIO : 8;
+ UINT32 : 16;
+ UINT32 : 32;
+ } Bits;
+ UINT64 Data;
+ UINT32 Data32[2];
+ UINT16 Data16[4];
+ UINT8 Data8[8];
+} PCU_CR_PLATFORM_INFO_STRUCT;
+
+#pragma pack (pop)
+
+#define SA_SYSTEM_BCLK (100)
+#define PCU_CR_PLATFORM_INFO (0xCE)
+#define MRC_POST_CODE_LOW_BYTE_ADDR (0x48)
+#define MRC_POST_CODE_HIGH_BYTE_ADDR (0x49)
+#define MAX_SPD_PAGE_COUNT (2)
+#define MAX_SPD_PAGE_SIZE (256)
+#define MAX_SPD_DDR3_SIZE (MAX_SPD_PAGE_SIZE * 1)
+#define MAX_SPD_DDR4_SIZE (MAX_SPD_PAGE_SIZE * 2)
+#define MAX_SPD_SIZE (MAX_SPD_PAGE_SIZE * MAX_SPD_PAGE_COUNT)
+#define SPD_PAGE_ADDRESS_0 (0x6C)
+#define SPD_PAGE_ADDRESS_1 (0x6E)
+#define SPD_DDR3_XMP_OFFSET (176)
+#define SPD_DDR4_XMP_OFFSET (384)
+#define SPD_DDR3_SDRAM_TYPE_OFFSET (0x02)
+#define SPD_DDR3_SDRAM_TYPE_NUMBER (0x0B)
+#define SPD_DDR4_SDRAM_TYPE_NUMBER (0x0C)
+#define SPD_LPDDR3_SDRAM_TYPE_NUMBER (0xF1)
+#define SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER (0x0F)
+
+/**
+ Read the SPD data over the SMBus, at the specified SPD address, starting at
+ the specified starting offset and read the given amount of data.
+
+ @param[in] SpdAddress - SPD SMBUS address
+ @param[in, out] Buffer - Buffer to store the data.
+ @param[in] Start - Starting SPD offset
+ @param[in] Size - The number of bytes of data to read and also the size of the buffer.
+ @param[in, out] Page - The final page that is being pointed to.
+
+ @retval RETURN_SUCCESS if the read is successful, otherwise error status.
+**/
+static
+RETURN_STATUS
+DoSpdRead (
+ IN const UINT8 SpdAddress,
+ IN OUT UINT8 *const Buffer,
+ IN const UINT16 Start,
+ IN UINT16 Size,
+ IN OUT UINT8 *const Page
+ )
+{
+ RETURN_STATUS EfiStatus;
+ BOOLEAN PageUpdate;
+ UINT16 Count;
+ UINT16 Index;
+
+ EfiStatus = RETURN_DEVICE_ERROR;
+ if ((Buffer != NULL) && (Start < MAX_SPD_SIZE) && ((Start + Size) < MAX_SPD_SIZE)) {
+ Count = 0;
+ PageUpdate = FALSE;
+ while (Size--) {
+ Index = Start + Count;
+ if ((Index / MAX_SPD_PAGE_SIZE) != *Page) {
+ *Page = (UINT8) (Index / MAX_SPD_PAGE_SIZE);
+ PageUpdate = TRUE;
+ }
+ Index %= MAX_SPD_PAGE_SIZE;
+ if (PageUpdate == TRUE) {
+ PageUpdate = FALSE;
+ SmBusWriteDataByte ((*Page == 0) ? SPD_PAGE_ADDRESS_0 : SPD_PAGE_ADDRESS_1, 0, &EfiStatus);
+ }
+ Buffer[Count] = SmBusReadDataByte (SpdAddress | ((UINT32) Index << 8), &EfiStatus);
+ if (RETURN_SUCCESS != EfiStatus) {
+ Buffer[Count] = 0;
+ break;
+ }
+ Count++;
+ }
+ EfiStatus = RETURN_SUCCESS;
+ }
+ return (EfiStatus);
+}
+
+/**
+ See if there is valid XMP SPD data.
+
+ @param[in] Debug - Mrc debug structure.
+ @param[in, out] Spd - Mrc SPD structure.
+ @param[in] XmpStart - The current offset in the SPD.
+
+ @retval TRUE if valid, FALSE in not.
+**/
+static
+BOOLEAN
+VerifyXmp (
+ IN OUT MrcSpd *const Spd,
+ IN const UINT16 XmpStart
+ )
+{
+ SPD_EXTREME_MEMORY_PROFILE_HEADER *Header1;
+ SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0 *Header2;
+ BOOLEAN Xmp;
+
+ Xmp = FALSE;
+
+ switch (((UINT8 *) Spd) [2]) {
+ case SPD_DDR3_SDRAM_TYPE_NUMBER:
+ Header1 = &Spd->Ddr3.Xmp.Header;
+ if (XmpStart == ((UINT32) (Header1) - (UINT32) Spd)) {
+ Xmp = TRUE;
+ if ((Header1->XmpRevision.Data & 0xFE) == 0x12) {
+ return (TRUE);
+ } else {
+ Header1->XmpId = 0;
+ Header1->XmpOrgConf.Data = 0;
+ Header1->XmpRevision.Data = 0;
+ }
+ }
+ break;
+ case SPD_DDR4_SDRAM_TYPE_NUMBER:
+ Header2 = &Spd->Ddr4.EndUser.Xmp.Header;
+ if (XmpStart == ((UINT32) (Header2) - (UINT32) Spd)) {
+ Xmp = TRUE;
+ if ((Header2->XmpRevision.Data) == 0x20) {
+ return (TRUE);
+ } else {
+ Header2->XmpId = 0;
+ Header2->XmpOrgConf.Data = 0;
+ Header2->XmpRevision.Data = 0;
+ }
+ }
+ break;
+ case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
+ case SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER:
+ return (TRUE);
+ default:
+ return (FALSE);
+ }
+ if (!Xmp) {
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/**
+ Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
+ The SPD data locations read is controlled by the current boot mode.
+
+ @param[in] BootMode - The current MRC boot mode.
+ @param[in] Address - SPD SmBus address offset.
+ @param[in] Buffer - Buffer that contains the data read from the SPD.
+ @param[in] SpdDdr3Table - Indicates which SPD bytes to read.
+ @param[in] SpdDdr3TableSize - Size of SpdDdr3Table in bytes.
+ @param[in] SpdDdr4Table - Indicates which SPD bytes to read.
+ @param[in] SpdDdr4TableSize - Size of SpdDdr4Table in bytes.
+ @param[in] SpdLpddrTable - Indicates which SPD bytes to read.
+ @param[in] SpdLpddrTableSize - Size of SpdLpddrTable in bytes.
+
+ @retval TRUE if the read is successful, otherwise FALSE on error.
+**/
+BOOLEAN
+GetSpdData (
+ IN SPD_BOOT_MODE BootMode,
+ IN UINT8 Address,
+ IN OUT UINT8 *Buffer,
+ IN UINT8 *SpdDdr3Table,
+ IN UINT32 SpdDdr3TableSize,
+ IN UINT8 *SpdDdr4Table,
+ IN UINT32 SpdDdr4TableSize,
+ IN UINT8 *SpdLpddrTable,
+ IN UINT32 SpdLpddrTableSize
+ )
+{
+ const SPD_OFFSET_TABLE *Tbl;
+ const SPD_OFFSET_TABLE *TableSelect;
+ RETURN_STATUS Status;
+ UINT32 Byte;
+ UINT32 Stop;
+ UINT8 Page;
+
+ Page = (UINT8) (~0);
+ Status = DoSpdRead (Address, &Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET], 2, 1, &Page);
+ if (RETURN_SUCCESS == Status) {
+ switch (Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET]) {
+ case SPD_DDR3_SDRAM_TYPE_NUMBER:
+ case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
+ default:
+ TableSelect = (SPD_OFFSET_TABLE *) SpdDdr3Table;
+ Stop = (SpdDdr3TableSize / sizeof (SPD_OFFSET_TABLE));
+ break;
+ case SPD_DDR4_SDRAM_TYPE_NUMBER:
+ TableSelect = (SPD_OFFSET_TABLE *) SpdDdr4Table;
+ Stop = (SpdDdr4TableSize / sizeof (SPD_OFFSET_TABLE));
+ break;
+ case SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER:
+ TableSelect = (SPD_OFFSET_TABLE *) SpdLpddrTable;
+ Stop = (SpdLpddrTableSize / sizeof (SPD_OFFSET_TABLE));
+ break;
+ }
+ for (Byte = 0; (RETURN_SUCCESS == Status) && (Byte < Stop); Byte++) {
+ Tbl = &TableSelect[Byte];
+ if ((1 << BootMode) & Tbl->BootMode) {
+ Status = DoSpdRead (Address, &Buffer[Tbl->Start], Tbl->Start, Tbl->End - Tbl->Start + 1, &Page);
+ if (Status == RETURN_SUCCESS) {
+ if (SpdCold == BootMode) {
+ if (FALSE == VerifyXmp ((MrcSpd *) Buffer, Tbl->Start)) {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ return ((RETURN_SUCCESS == Status) ? TRUE : FALSE);
+}
+
+//
+// This is from MdeModulePkg\Include\Guid\StatusCodeDataTypeDebug.h
+// Might need to be adjusted for a particular BIOS core
+//
+#ifndef EFI_STATUS_CODE_DATA_MAX_SIZE
+#define EFI_STATUS_CODE_DATA_MAX_SIZE 200
+#endif
+
+/**
+ Output a string to the debug stream/device.
+ If there is a '%' sign in the string, convert it to '%%', so that DEBUG() macro will print it properly.
+
+ @param[in] String - The string to output.
+
+ @retval Nothing.
+**/
+VOID
+SaDebugPrint (
+ VOID *String
+ )
+{
+ CHAR8 Str[EFI_STATUS_CODE_DATA_MAX_SIZE];
+ CHAR8 *InputStr;
+ CHAR8 *OutputStr;
+ UINT32 i;
+
+ InputStr = (CHAR8 *) String;
+ OutputStr = Str;
+ i = 0;
+ while (*InputStr != 0) {
+ if (i < (EFI_STATUS_CODE_DATA_MAX_SIZE - 2)) {
+ *OutputStr++ = *InputStr;
+ i++;
+ if (*InputStr++ == '%') {
+ *OutputStr++ = '%';
+ i++;
+ }
+ }
+ }
+ *OutputStr = 0; // Terminating NULL
+ DEBUG ((DEBUG_ERROR, Str));
+ return;
+}
+
+/**
+ Calculate the PCI device address for the given Bus/Device/Function/Offset.
+
+ @param[in] Bus - PCI bus
+ @param[in] Device - PCI device
+ @param[in] Function - PCI function
+ @param[in] Offset - Offset
+
+ @retval The PCI device address.
+**/
+UINT32
+GetPciDeviceAddress (
+ IN const UINT8 Bus,
+ IN const UINT8 Device,
+ IN const UINT8 Function,
+ IN const UINT8 Offset
+ )
+{
+ return (
+ ((UINT32) ((Bus) & 0xFF) << 16) |
+ ((UINT32) ((Device) & 0x1F) << 11) |
+ ((UINT32) ((Function) & 0x07) << 8) |
+ ((UINT32) ((Offset) & 0xFF) << 0) |
+ (1UL << 31));
+}
+
+/**
+ Calculate the PCIE device address for the given Bus/Device/Function/Offset.
+
+ @param[in] Bus - PCI bus
+ @param[in] Device - PCI device
+ @param[in] Function - PCI function
+ @param[in] Offset - Offset
+
+ The PCIE device address.
+
+ @retval The PCIe device address
+**/
+UINT32
+GetPcieDeviceAddress (
+ IN const UINT8 Bus,
+ IN const UINT8 Device,
+ IN const UINT8 Function,
+ IN const UINT8 Offset
+ )
+{
+ return (
+ ((UINT32) Bus << 20) +
+ ((UINT32) Device << 15) +
+ ((UINT32) Function << 12) +
+ ((UINT32) Offset << 0));
+}
+
+/**
+ Read specific RTC/CMOS RAM
+
+ @param[in] Location Point to RTC/CMOS RAM offset for read
+
+ @retval The data of specific location in RTC/CMOS RAM.
+**/
+UINT8
+PeiRtcRead (
+ IN const UINT8 Location
+ )
+{
+ UINT8 RtcIndexPort;
+ UINT8 RtcDataPort;
+
+ //
+ // CMOS access registers (using alternative access not to handle NMI bit)
+ //
+ if (Location < RTC_BANK_SIZE) {
+ //
+ // First bank
+ //
+ RtcIndexPort = R_PCH_RTC_INDEX_ALT;
+ RtcDataPort = R_PCH_RTC_TARGET_ALT;
+ } else {
+ //
+ // Second bank
+ //
+ RtcIndexPort = R_PCH_RTC_EXT_INDEX_ALT;
+ RtcDataPort = R_PCH_RTC_EXT_TARGET_ALT;
+ }
+
+ IoWrite8 (RtcIndexPort, Location & RTC_INDEX_MASK);
+ return IoRead8 (RtcDataPort);
+}
+
+/**
+ Returns the current time, as determined by reading the Real Time Clock (RTC) on the platform.
+ Since RTC time is stored in BCD, convert each value to binary.
+
+ @param[out] Seconds - The current second (0-59).
+ @param[out] Minutes - The current minute (0-59).
+ @param[out] Hours - The current hour (0-23).
+ @param[out] DayOfMonth - The current day of the month (1-31).
+ @param[out] Month - The current month (1-12).
+ @param[out] Year - The current year (2000-2099).
+
+ @retval Nothing.
+**/
+VOID
+GetRtcTime (
+ OUT UINT8 *const Seconds,
+ OUT UINT8 *const Minutes,
+ OUT UINT8 *const Hours,
+ OUT UINT8 *const DayOfMonth,
+ OUT UINT8 *const Month,
+ OUT UINT16 *const Year
+ )
+{
+ UINT32 Timeout;
+
+ //
+ // Wait until RTC "update in progress" bit goes low.
+ //
+ Timeout = 0x0FFFFF;
+ do {
+ IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGA);
+ if ((IoRead8 (RTC_TARGET_REGISTER) & RTC_UPDATE_IN_PROGRESS) != RTC_UPDATE_IN_PROGRESS) {
+ break;
+ }
+ } while (--Timeout > 0);
+
+ if (0 == Timeout) {
+ IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGB);
+ IoWrite8 (RTC_TARGET_REGISTER, RTC_HOLD | RTC_MODE_24HOUR);
+
+ IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGA);
+ IoWrite8 (RTC_TARGET_REGISTER, RTC_CLOCK_DIVIDER | RTC_RATE_SELECT);
+
+ IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGC);
+ IoRead8 (RTC_TARGET_REGISTER);
+
+ IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGD);
+ IoRead8 (RTC_TARGET_REGISTER);
+
+ IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGB);
+ IoWrite8 (RTC_TARGET_REGISTER, RTC_MODE_24HOUR);
+ }
+ //
+ // Read seconds
+ //
+ IoWrite8 (RTC_INDEX_REGISTER, RTC_SECONDS);
+ *Seconds = IoRead8 (RTC_TARGET_REGISTER);
+
+ //
+ // Read minutes
+ //
+ IoWrite8 (RTC_INDEX_REGISTER, RTC_MINUTES);
+ *Minutes = IoRead8 (RTC_TARGET_REGISTER);
+
+ //
+ // Read hours
+ //
+ IoWrite8 (RTC_INDEX_REGISTER, RTC_HOURS);
+ *Hours = IoRead8 (RTC_TARGET_REGISTER);
+
+ //
+ // Read day of month
+ //
+ IoWrite8 (RTC_INDEX_REGISTER, RTC_DAY_OF_MONTH);
+ *DayOfMonth = IoRead8 (RTC_TARGET_REGISTER);
+
+ //
+ // Read month
+ //
+ IoWrite8 (RTC_INDEX_REGISTER, RTC_MONTH);
+ *Month = IoRead8 (RTC_TARGET_REGISTER);
+
+ //
+ // Read year and add current century.
+ //
+ IoWrite8 (RTC_INDEX_REGISTER, RTC_YEAR);
+ *Year = IoRead8 (RTC_TARGET_REGISTER);
+
+ *Seconds = BCD2BINARY (*Seconds);
+ *Minutes = BCD2BINARY (*Minutes);
+ *Hours = BCD2BINARY (*Hours);
+ *DayOfMonth = BCD2BINARY (*DayOfMonth);
+ *Month = BCD2BINARY (*Month);
+ *Year = BCD2BINARY (*Year) + CENTURY_OFFSET;
+}
+
+/**
+ Gets CPU current time.
+
+ @param[in] GlobalData - Pointer to global MRC data struct.
+
+ @retval The current CPU time in milliseconds.
+**/
+UINT64
+GetCpuTime (
+ IN VOID *GlobalData
+ )
+{
+ MrcParameters *MrcData;
+ MrcInput *Inputs;
+ PCU_CR_PLATFORM_INFO_STRUCT Msr;
+ UINT32 TimeBase;
+
+ MrcData = (MrcParameters *) GlobalData;
+ Inputs = &MrcData->Inputs;
+
+ Msr.Data = AsmReadMsr64 (PCU_CR_PLATFORM_INFO);
+ TimeBase = (Inputs->BClkFrequency / 1000) * Msr.Bits.MAX_NON_TURBO_LIM_RATIO; //In Millisec
+ return ((TimeBase == 0) ? 0 : DivU64x32 (AsmReadTsc (), TimeBase));
+}
+
+/**
+ Sets the specified number of memory words, a word at a time, at the
+ specified destination.
+
+ @param[in, out] Dest - Destination pointer.
+ @param[in] NumWords - The number of dwords to set.
+ @param[in] Value - The value to set.
+
+ @retval Pointer to the buffer.
+**/
+VOID *
+SetMemWord (
+ IN OUT VOID *Dest,
+ IN UINTN NumWords,
+ IN const UINT16 Value
+ )
+{
+ UINT16 *Buffer;
+
+ Buffer = (UINT16 *) Dest;
+ while (0 != NumWords--) {
+ *Buffer++ = Value;
+ }
+
+ return (Dest);
+}
+
+/**
+ Sets the specified number of memory dwords, a dword at a time, at the
+ specified destination.
+
+ @param[in, out] Dest - Destination pointer.
+ @param[in] NumDwords - The number of dwords to set.
+ @param[in] Value - The value to set.
+
+ @retval Pointer to the buffer.
+**/
+VOID *
+SetMemDword (
+ IN OUT VOID *Dest,
+ IN UINT32 NumDwords,
+ IN const UINT32 Value
+ )
+{
+ UINT32 *Buffer;
+
+ Buffer = (UINT32 *) Dest;
+ while (0 != NumDwords--) {
+ *Buffer++ = Value;
+ }
+
+ return (Dest);
+}
+
+
+/**
+ Gets the current memory voltage (VDD).
+
+ @param[in] GlobalData - Pointer to global MRC data struct.
+ @param[in] DefaultVdd - Default Vdd for the given platform.
+
+ @retval The current memory voltage (VDD), in millivolts. 0 means platform default.
+**/
+UINT32
+GetMemoryVdd (
+ IN VOID *GlobalData,
+ IN UINT32 DefaultVdd
+ )
+{
+ MrcParameters *MrcData;
+ UINT32 CurrentVoltage;
+
+ MrcData = (MrcParameters *) GlobalData;
+ CurrentVoltage = DefaultVdd;
+
+ return CurrentVoltage;
+}
+
+/**
+ Sets the memory voltage (VDD) to the specified value.
+
+ @param[in] GlobalData - Pointer to global MRC data struct.
+ @param[in] DefaultVdd - Default Vdd for the given platform.
+ @param[in] Voltage - The new memory voltage to set.
+
+ @retval The actual memory voltage (VDD), in millivolts, that is closest to what the caller passed in.
+**/
+UINT32
+SetMemoryVdd (
+ IN VOID *GlobalData,
+ IN UINT32 DefaultVdd,
+ IN UINT32 Voltage
+ )
+{
+ MrcParameters *MrcData;
+
+ MrcData = (MrcParameters *) GlobalData;
+
+ return Voltage;
+}
+
+/**
+ This function is used by the OEM to do a dedicated task during the MRC.
+
+ @param[in] GlobalData - include all the MRC data
+ @param[in] OemStatusCommand - A command that indicates the task to perform.
+ @param[in] Pointer - general ptr for general use.
+
+ @retval The status of the task.
+**/
+MrcStatus
+CheckPoint (
+ IN VOID *GlobalData,
+ IN MrcOemStatusCommand OemStatusCommand,
+ IN VOID *Pointer
+ )
+{
+ const SA_MEMORY_FUNCTIONS *SaCall;
+ MrcParameters *MrcData;
+ MrcInput *Inputs;
+ MrcStatus Status;
+ SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi;
+ MEMORY_CONFIG_NO_CRC *MemConfigNoCrc;
+ EFI_STATUS Status1;
+
+ //
+ // Locate SiPreMemPolicyPpi to do a GetConfigBlock() to access platform data
+ //
+ Status1 = PeiServicesLocatePpi (
+ &gSiPreMemPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &SiPreMemPolicyPpi
+ );
+ ASSERT_EFI_ERROR (Status1);
+
+ Status1 = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+ ASSERT_EFI_ERROR (Status1);
+ MrcData = (MrcParameters *) GlobalData;
+ Inputs = &MrcData->Inputs;
+ SiPreMemPolicyPpi = (SI_PREMEM_POLICY_PPI *) Inputs->SiPreMemPolicyPpi;
+ SaCall = &MemConfigNoCrc->MrcCall;
+ Status = mrcSuccess;
+
+ switch (OemStatusCommand) {
+ case OemAfterNormalMode:
+ SaCall->MrcThermalOverrides (MrcData);
+ break;
+
+ default:
+ break;
+ }
+
+ return (mrcSuccess);
+}
+
+/**
+ Typically used to display to the I/O port 80h.
+
+ @param[in] GlobalData - Mrc Global Data
+ @param[in] DisplayDebugNumber - the number to display on port 80.
+
+ @retval Nothing.
+**/
+VOID
+DebugHook (
+ IN VOID *GlobalData,
+ UINT16 DisplayDebugNumber
+ )
+{
+ MrcParameters *MrcData;
+ MrcOutput *Outputs;
+ MrcDebug *Debug;
+ EFI_STATUS Status;
+ SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi;
+ SA_MISC_PEI_PREMEM_CONFIG *MiscPeiPreMemConfig;
+
+ MrcData = (MrcParameters *) GlobalData;
+ Outputs = &MrcData->Outputs;
+ Debug = &Outputs->Debug;
+
+ Debug->PostCode[MRC_POST_CODE] = DisplayDebugNumber;
+ IoWrite16 (0x80, DisplayDebugNumber);
+ DEBUG ((DEBUG_INFO, "Post Code: %04Xh\n", DisplayDebugNumber));
+
+ //
+ // Locate SiPreMemPolicyPpi to do a GetConfigBlock() to access platform data
+ //
+ Status = PeiServicesLocatePpi (&gSiPreMemPolicyPpiGuid, 0, NULL, (VOID **) &SiPreMemPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+ if (Status == EFI_SUCCESS) {
+ Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+ }
+ return;
+}
+
+/**
+ Hook to take any action after returning from MrcStartMemoryConfiguration()
+ and prior to taking any action regarding MrcStatus. Pre-populated with issuing
+ Intel Silicon View Technology (ISVT) checkpoint 0x10.
+
+ @param[in] GlobalData - Mrc Global Data
+ @param[in] MrcStatus - Mrc status variable
+**/
+void
+ReturnFromSmc (
+ IN VOID *GlobalData,
+ IN UINT32 MrcStatus
+ )
+{
+ return;
+}
+
+/**
+ Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
+
+ @param[in] PciEBaseAddress - PCI express base address.
+ @param[in] ResetValue - desired value of DRAM_RESET#. 1 - reset deasserted, 0 - reset asserted.
+**/
+VOID
+SaDramReset (
+ IN UINT32 PciEBaseAddress,
+ IN UINT32 ResetValue
+ )
+{
+ UINT32 MmioBase;
+ UINT32 PmCfg2;
+
+ //
+ // Get the PCH PWRM Base
+ //
+ PchPwrmBaseGet (&MmioBase);
+
+ //
+ // Set DRAM RESET# value via PCH register (both SKL PCH-H and SKL PCH-LP)
+ //
+ PmCfg2 = MmioRead32 (MmioBase + R_PCH_PWRM_CFG2);
+ PmCfg2 &= ~(B_PCH_PWRM_CFG2_DRAM_RESET_CTL);
+ PmCfg2 |= (ResetValue << 26);
+ MmioWrite32 (MmioBase + R_PCH_PWRM_CFG2, PmCfg2);
+
+ return;
+}
+
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h
new file mode 100644
index 0000000000..f561138b04
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h
@@ -0,0 +1,313 @@
+/** @file
+ This file contains functions that read the SPD data for each DIMM slot over
+ the SMBus interface.
+ This file is SampleCode for Intel SA PEI Policy initialization.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "PeiSaPolicyLibrary.h"
+#include "MrcInterface.h"
+#include <SaRegs.h>
+
+#define RTC_INDEX_REGISTER (0x70)
+#define RTC_TARGET_REGISTER (0x71)
+
+#define RTC_INDEX_MASK (0x7F)
+#define RTC_BANK_SIZE (0x80)
+
+#define RTC_SECONDS (0x00)
+#define RTC_MINUTES (0x02)
+#define RTC_HOURS (0x04)
+#define RTC_DAY_OF_MONTH (0x07)
+#define RTC_MONTH (0x08)
+#define RTC_YEAR (0x09)
+#define CMOS_REGA (0x0A)
+#define CMOS_REGB (0x0B)
+#define CMOS_REGC (0x0C)
+#define CMOS_REGD (0x0D)
+
+#define RTC_UPDATE_IN_PROGRESS (0x80)
+#define RTC_HOLD (0x80)
+#define RTC_MODE_24HOUR (0x02)
+#define RTC_CLOCK_DIVIDER (0x20)
+#define RTC_RATE_SELECT (0x06)
+
+#define BCD2BINARY(A) (((((A) >> 4) & 0xF) * 10) + ((A) & 0xF))
+#define CENTURY_OFFSET (2000)
+
+/**
+ Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
+ The SPD data locations read is controlled by the current boot mode.
+
+ @param[in] BootMode - The current MRC boot mode.
+ @param[in] Address - SPD SmBus address offset.
+ @param[in] Buffer - Buffer that contains the data read from the SPD.
+ @param[in] SpdDdr3Table - Indicates which SPD bytes to read.
+ @param[in] SpdDdr3TableSize - Size of SpdDdr3Table in bytes.
+ @param[in] SpdDdr4Table - Indicates which SPD bytes to read.
+ @param[in] SpdDdr4TableSize - Size of SpdDdr4Table in bytes.
+ @param[in] SpdLpddrTable - Indicates which SPD bytes to read.
+ @param[in] SpdLpddrTableSize - Size of SpdLpddrTable in bytes.
+
+ @retval TRUE if the read is successful, otherwise FALSE on error.
+**/
+BOOLEAN
+GetSpdData (
+ IN SPD_BOOT_MODE BootMode,
+ IN UINT8 Address,
+ IN OUT UINT8 *Buffer,
+ IN UINT8 *SpdDdr3Table,
+ IN UINT32 SpdDdr3TableSize,
+ IN UINT8 *SpdDdr4Table,
+ IN UINT32 SpdDdr4TableSize,
+ IN UINT8 *SpdLpddrTable,
+ IN UINT32 SpdLpddrTableSize
+ );
+
+/**
+ Output a string to the debug stream/device.
+
+ @param[in] String - The string to output.
+**/
+VOID
+SaDebugPrint (
+ VOID *String
+ );
+
+/**
+ Calculate the PCI device address for the given Bus/Device/Function/Offset.
+
+ @param[in] Bus - PCI bus
+ @param[in] Device - PCI device
+ @param[in] Function - PCI function
+ @param[in] Offset - Offset
+
+ @retval The PCI device address.
+**/
+UINT32
+GetPciDeviceAddress (
+ IN const UINT8 Bus,
+ IN const UINT8 Device,
+ IN const UINT8 Function,
+ IN const UINT8 Offset
+ );
+
+/**
+ Calculate the PCIE device address for the given Bus/Device/Function/Offset.
+
+ @param[in] Bus - PCI bus
+ @param[in] Device - PCI device
+ @param[in] Function - PCI function
+ @param[in] Offset - Offset
+
+ The PCIE device address.
+
+ @retval The PCIe device address
+**/
+UINT32
+GetPcieDeviceAddress (
+ IN const UINT8 Bus,
+ IN const UINT8 Device,
+ IN const UINT8 Function,
+ IN const UINT8 Offset
+ );
+
+/**
+ Read specific RTC/CMOS RAM
+
+ @param[in] Location Point to RTC/CMOS RAM offset for read
+
+ @retval The data of specific location in RTC/CMOS RAM.
+**/
+UINT8
+PeiRtcRead (
+ IN const UINT8 Location
+ );
+
+/**
+ Returns the current time, as determined by reading the Real Time Clock (RTC) on the platform.
+ Since RTC time is stored in BCD, convert each value to binary.
+
+ @param[out] Seconds - The current second (0-59).
+ @param[out] Minutes - The current minute (0-59).
+ @param[out] Hours - The current hour (0-23).
+ @param[out] DayOfMonth - The current day of the month (1-31).
+ @param[out] Month - The current month (1-12).
+ @param[out] Year - The current year (2000-2099).
+**/
+VOID
+GetRtcTime (
+ OUT UINT8 *const Seconds,
+ OUT UINT8 *const Minutes,
+ OUT UINT8 *const Hours,
+ OUT UINT8 *const DayOfMonth,
+ OUT UINT8 *const Month,
+ OUT UINT16 *const Year
+ );
+
+/**
+ Gets CPU current time.
+
+ @param[in] GlobalData - Pointer to global MRC data struct.
+
+ @retval The current CPU time in milliseconds.
+**/
+UINT64
+GetCpuTime (
+ IN VOID *GlobalData
+ );
+
+/**
+ Sets the specified number of memory words, a word at a time, at the
+ specified destination.
+
+ @param[in, out] Dest - Destination pointer.
+ @param[in] NumWords - The number of dwords to set.
+ @param[in] Value - The value to set.
+
+ @retval Pointer to the buffer.
+**/
+VOID *
+SetMemWord (
+ IN OUT VOID *Dest,
+ IN UINTN NumWords,
+ IN const UINT16 Value
+ );
+
+/**
+ Sets the specified number of memory dwords, a dword at a time, at the
+ specified destination.
+
+ @param[in, out] Dest - Destination pointer.
+ @param[in] NumDwords - The number of dwords to set.
+ @param[in] Value - The value to set.
+
+ @retval Pointer to the buffer.
+**/
+VOID *
+SetMemDword (
+ IN OUT VOID *Dest,
+ IN UINT32 NumDwords,
+ IN const UINT32 Value
+ );
+
+/**
+ Read 64 bits from the Memory Mapped I/O space.
+ Use MMX instruction for atomic access, because some MC registers have side effect.
+
+ @param[in] Address - Memory mapped I/O address.
+**/
+UINT64
+SaMmioRead64 (
+ IN UINTN Address
+ );
+
+/**
+ Write 64 bits to the Memory Mapped I/O space.
+ Use MMX instruction for atomic access, because some MC registers have side effect.
+
+ @param[in] Address - Memory mapped I/O address.
+ @param[in] Value - The value to write.
+**/
+UINT64
+SaMmioWrite64 (
+ IN UINTN Address,
+ IN UINT64 Value
+ );
+
+/**
+ Gets the current memory voltage (VDD).
+
+ @param[in] GlobalData - Pointer to global MRC data struct.
+ @param[in] DefaultVdd - Default Vdd for the given platform.
+
+ @retval The current memory voltage (VDD), in millivolts. 0 means platform default.
+**/
+UINT32
+GetMemoryVdd (
+ IN VOID *GlobalData,
+ IN UINT32 DefaultVdd
+ );
+
+/**
+ Sets the memory voltage (VDD) to the specified value.
+
+ @param[in] GlobalData - Pointer to global MRC data struct.
+ @param[in] DefaultVdd - Default Vdd for the given platform.
+ @param[in] Voltage - The new memory voltage to set.
+
+ @retval The actual memory voltage (VDD), in millivolts, that is closest to what the caller passed in.
+**/
+UINT32
+SetMemoryVdd (
+ IN VOID *GlobalData,
+ IN UINT32 DefaultVdd,
+ IN UINT32 Voltage
+ );
+
+/**
+ Check point that is called at various points in the MRC.
+
+ @param[in] GlobalData - MRC global data.
+ @param[in] Command - OEM command.
+ @param[in] Pointer - Command specific data.
+
+ @retval MrcStatus value.
+**/
+UINT32
+CheckPoint (
+ VOID *GlobalData,
+ UINT32 Command,
+ VOID *Pointer
+ );
+
+/**
+ Typically used to display to the I/O port 80h.
+
+ @param[in] GlobalData - Mrc Global Data
+ @param[in] DisplayDebugNumber - the number to display on port 80.
+
+ @retval Nothing.
+**/
+VOID
+DebugHook (
+ VOID *GlobalData,
+ UINT16 DisplayDebugNumber
+ );
+
+/**
+ Hook to take any action after returning from MrcStartMemoryConfiguration()
+ and prior to taking any action regarding MrcStatus. Pre-populated with issuing
+ Intel Silicon View Technology (ISVT) checkpoint 0x01.
+
+ @param[in] GlobalData - Mrc Global Data
+ @param[in] MrcStatus - Mrc status variable
+**/
+VOID
+ReturnFromSmc (
+ VOID *GlobalData,
+ UINT32 MrcStatus
+ );
+
+/**
+ Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
+
+ @param[in] PciEBaseAddress - PCI express base address.
+ @param[in] ResetValue - desired value of DRAM_RESET#. 1 - reset deasserted, 0 - reset asserted.
+**/
+VOID
+SaDramReset (
+ IN UINT32 PciEBaseAddress,
+ IN UINT32 ResetValue
+ );
+
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c
new file mode 100644
index 0000000000..ddc83ba4b2
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c
@@ -0,0 +1,365 @@
+/** @file
+ This file provides services for PEI policy default initialization
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include "PeiSaPolicyLibrary.h"
+#include <Library/GpioLib.h>
+#include <GpioPinsSklH.h>
+#include <Library/CpuPlatformLib.h>
+#include <MrcTypes.h>
+#include "MrcInterface.h"
+
+
+extern EFI_GUID gSaMiscPeiPreMemConfigGuid;
+extern EFI_GUID gMemoryConfigGuid;
+extern EFI_GUID gMemoryConfigNoCrcGuid;
+extern EFI_GUID gGraphicsPeiConfigGuid;
+extern EFI_GUID gVtdConfigGuid;
+
+//
+// Function call to Load defaults for Individial IP Blocks
+//
+VOID
+LoadSaMiscPeiPreMemDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ SA_MISC_PEI_PREMEM_CONFIG *MiscPeiPreMemConfig;
+
+ MiscPeiPreMemConfig = ConfigBlockPointer;
+
+ DEBUG ((DEBUG_INFO, "MiscPeiPreMemConfig->Header.GuidHob.Name = %g\n", &MiscPeiPreMemConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "MiscPeiPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MiscPeiPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+VOID
+LoadVtdDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ VTD_CONFIG *Vtd;
+
+ Vtd = ConfigBlockPointer;
+ DEBUG ((DEBUG_INFO, "Vtd->Header.GuidHob.Name = %g\n", &Vtd->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "Vtd->Header.GuidHob.Header.HobLength = 0x%x\n", Vtd->Header.GuidHob.Header.HobLength));
+
+ //
+ // Initialize the Vtd Configuration
+ //
+ Vtd->BaseAddress[0] = 0xFED90000;
+ Vtd->BaseAddress[1] = 0xFED91000;
+}
+
+VOID
+LoadGraphichsPeiDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ GRAPHICS_PEI_CONFIG *GtConfig;
+
+ GtConfig = ConfigBlockPointer;
+ DEBUG ((DEBUG_INFO, "GtConfig->Header.GuidHob.Name = %g\n", &GtConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "GtConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GtConfig->Header.GuidHob.Header.HobLength));
+}
+
+VOID
+LoadMemConfigNoCrcDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+
+ MEMORY_CONFIG_NO_CRC *MemConfigNoCrc;
+
+ MemConfigNoCrc = ConfigBlockPointer;
+ DEBUG ((DEBUG_INFO, "MemConfigNoCrc->Header.GuidHob.Name = %g\n", &MemConfigNoCrc->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "MemConfigNoCrc->Header.GuidHob.Header.HobLength = 0x%x\n", MemConfigNoCrc->Header.GuidHob.Header.HobLength));
+ //
+ // Allocating memory space for pointer structures inside MemConfigNoCrc
+ //
+ MemConfigNoCrc->SpdData = (SPD_DATA_BUFFER *) AllocateZeroPool (sizeof (SPD_DATA_BUFFER));
+ ASSERT (MemConfigNoCrc->SpdData != NULL);
+ if (MemConfigNoCrc->SpdData == NULL) {
+ return;
+ }
+
+ MemConfigNoCrc->DqByteMap = (SA_MEMORY_DQ_MAPPING *) AllocateZeroPool (sizeof (SA_MEMORY_DQ_MAPPING));
+ ASSERT (MemConfigNoCrc->DqByteMap != NULL);
+ if (MemConfigNoCrc->DqByteMap == NULL) {
+ return;
+ }
+
+ MemConfigNoCrc->DqsMap = (SA_MEMORY_DQS_MAPPING *) AllocateZeroPool (sizeof (SA_MEMORY_DQS_MAPPING));
+ ASSERT (MemConfigNoCrc->DqsMap != NULL);
+ if (MemConfigNoCrc->DqsMap == NULL) {
+ return;
+ }
+
+ MemConfigNoCrc->RcompData = (SA_MEMORY_RCOMP *) AllocateZeroPool (sizeof (SA_MEMORY_RCOMP));
+ ASSERT (MemConfigNoCrc->RcompData != NULL);
+ if (MemConfigNoCrc->RcompData == NULL) {
+ return;
+ }
+
+ //
+ // Set PlatformMemory Size
+ //
+ MemConfigNoCrc->PlatformMemorySize = PcdGet32 (PcdPeiMinMemorySize);
+
+ MemConfigNoCrc->SerialDebugLevel = 3; //< Enable MRC debug message
+
+}
+
+
+VOID
+LoadMemConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ MEMORY_CONFIGURATION *MemConfig;
+ CPU_SKU CpuSku;
+ UINT16 DeviceId;
+ BOOLEAN HasEdram;
+
+ CpuSku = GetCpuSku ();
+ DeviceId = MmioRead16 (MmPciBase (SA_MC_BUS, 0, 0) + R_SA_MC_DEVICE_ID);
+ HasEdram = ((AsmReadMsr64 (MSR_PLATFORM_INFO) & B_PLATFORM_INFO_EDRAM_EN) != 0);
+
+
+ MemConfig = ConfigBlockPointer;
+ DEBUG ((DEBUG_INFO, "MemConfig->Header.GuidHob.Name = %g\n", &MemConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "MemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MemConfig->Header.GuidHob.Header.HobLength));
+ //
+ // Initialize the Memory Configuration
+ //
+ MemConfig->EccSupport = 1;
+ MemConfig->ScramblerSupport = 1;
+ MemConfig->PowerDownMode = 0xFF;
+ MemConfig->RankInterleave = TRUE;
+ MemConfig->EnhancedInterleave = TRUE;
+ MemConfig->CmdTriStateDis = 0;
+ MemConfig->EnCmdRate = 3;
+ MemConfig->AutoSelfRefreshSupport = TRUE;
+ MemConfig->ExtTemperatureSupport = TRUE;
+
+ //
+ // Thermal Management Configuration
+ //
+ MemConfig->ThermalManagement = 1;
+ //
+ // Channel Hash Configuration
+ //
+ MemConfig->ChHashEnable = TRUE;
+ MemConfig->ChHashMask = ((CpuSku == EnumCpuUlt) && (HasEdram)) ? 0x30D0 : 0x30C8;
+ MemConfig->ChHashInterleaveBit = 2;
+ //
+ // Options for Thermal settings
+ //
+ MemConfig->EnablePwrDn = 1;
+ MemConfig->EnablePwrDnLpddr = 1;
+ MemConfig->DdrThermalSensor = 1;
+
+ MemConfig->EnergyScaleFact = 3;
+ MemConfig->WarmThresholdCh0Dimm0 = 0xFF;
+ MemConfig->WarmThresholdCh0Dimm1 = 0xFF;
+ MemConfig->WarmThresholdCh1Dimm0 = 0xFF;
+ MemConfig->WarmThresholdCh1Dimm1 = 0xFF;
+ MemConfig->HotThresholdCh0Dimm0 = 0xFF;
+ MemConfig->HotThresholdCh0Dimm1 = 0xFF;
+ MemConfig->HotThresholdCh1Dimm0 = 0xFF;
+ MemConfig->HotThresholdCh1Dimm1 = 0xFF;
+ MemConfig->WarmBudgetCh0Dimm0 = 0xFF;
+ MemConfig->WarmBudgetCh0Dimm1 = 0xFF;
+ MemConfig->WarmBudgetCh1Dimm0 = 0xFF;
+ MemConfig->WarmBudgetCh1Dimm1 = 0xFF;
+ MemConfig->HotBudgetCh0Dimm0 = 0xFF;
+ MemConfig->HotBudgetCh0Dimm1 = 0xFF;
+ MemConfig->HotBudgetCh1Dimm0 = 0xFF;
+ MemConfig->HotBudgetCh1Dimm1 = 0xFF;
+
+ MemConfig->SrefCfgEna = 1;
+ MemConfig->SrefCfgIdleTmr = 0x200;
+ MemConfig->ThrtCkeMinTmr = 0x30;
+ MemConfig->ThrtCkeMinDefeatLpddr = 1;
+ MemConfig->ThrtCkeMinTmrLpddr = 0x40;
+
+ //
+ // CA Vref routing: board-dependent
+ // 0 - VREF_CA goes to both CH_A and CH_B (LPDDR3/DDR3L)
+ // 1 - VREF_CA to CH_A, VREF_DQ_A to CH_B (should not be used)
+ // 2 - VREF_CA to CH_A, VREF_DQ_B to CH_B (DDR4)
+ //
+ //MemConfig->CaVrefConfig = 0;
+
+ MemConfig->VttTermination = ((CpuSku == EnumCpuUlx) || (CpuSku == EnumCpuUlt));
+ MemConfig->VttCompForVsshi = 1;
+
+ MemConfig->McLock = TRUE;
+
+ MemConfig->GdxcIotSize = 4;
+ MemConfig->GdxcMotSize = 12;
+
+ //
+ // MRC training steps
+ //
+ MemConfig->ERDMPRTC2D = 1;
+ MemConfig->SOT = 1;
+ MemConfig->RDMPRT = 1;
+ MemConfig->RCVET = 1;
+ MemConfig->JWRL = 1;
+ MemConfig->EWRTC2D = 1;
+ MemConfig->ERDTC2D = 1;
+ MemConfig->WRTC1D = 1;
+ MemConfig->WRVC1D = 1;
+ MemConfig->RDTC1D = 1;
+ MemConfig->DIMMODTT = 1;
+ MemConfig->DIMMRONT = 1;
+ MemConfig->WRSRT = 1;
+ MemConfig->RDODTT = 1;
+ MemConfig->RDEQT = 1;
+ MemConfig->RDAPT = 1;
+ MemConfig->WRTC2D = 1;
+ MemConfig->RDTC2D = 1;
+ MemConfig->CMDVC = 1;
+ MemConfig->WRVC2D = 1;
+ MemConfig->RDVC2D = 1;
+ MemConfig->LCT = 1;
+ MemConfig->RTL = 1;
+ MemConfig->TAT = 1;
+ MemConfig->ALIASCHK = 1;
+ MemConfig->RCVENC1D = 1;
+ MemConfig->RMC = 1;
+ MemConfig->CMDSR = 1;
+ MemConfig->CMDDSEQ = 1;
+ MemConfig->CMDNORM = 1;
+ MemConfig->EWRDSEQ = 1;
+
+ // MrcFastBoot enabled by default
+ MemConfig->MrcFastBoot = TRUE;
+ MemConfig->RemapEnable = TRUE;
+ MemConfig->BClkFrequency = 100 * 1000 * 1000;
+
+ MemConfig->Vc1ReadMeter = TRUE;
+ MemConfig->Vc1ReadMeterTimeWindow = 0x320;
+ MemConfig->Vc1ReadMeterThreshold = 0x118;
+ MemConfig->StrongWkLeaker = 7;
+
+ MemConfig->MobilePlatform = (IS_SA_DEVICE_ID_MOBILE (DeviceId)) ? TRUE : FALSE;
+ MemConfig->PciIndex = 0xCF8;
+ MemConfig->PciData = 0xCFC;
+ MemConfig->CkeRankMapping = 0xAA;
+ //
+ // SA GV: 0 - Disabled, 1 - FixedLow, 2 - FixedHigh, 3 - Enabled
+ //
+ //
+ // Current Simics will fail in MRC training when SAGV enabled so need to by default disable SAGV.
+ //
+ MemConfig->SaGv = 3; // This only affects ULX/ULT and CPU steppings C0/J0 and above; otherwise SA GV is disabled.
+
+ MemConfig->Idd3n = 26;
+ MemConfig->Idd3p = 11;
+
+ MemConfig->RhPrevention = TRUE; // Row Hammer prevention.
+ MemConfig->RhSolution = HardwareRhp; // Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+ MemConfig->RhActProbability = OneIn2To11; // Activation probability for Hardware RHP
+
+ MemConfig->LpddrMemWriteLatencySet = 1; // Enable LPDDR3 WL Set B if supported by DRAM
+ MemConfig->EvLoaderDelay = 1;
+
+ MemConfig->DllBwEn1 = 1;
+ MemConfig->DllBwEn2 = 2;
+ MemConfig->DllBwEn3 = 2;
+
+ MemConfig->RetrainOnFastFail = 1; // Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, 1 = Enabled
+}
+
+
+static COMPONENT_BLOCK_ENTRY mSaIpBlocksPreMem[] = {
+ { &gSaMiscPeiPreMemConfigGuid, sizeof(SA_MISC_PEI_PREMEM_CONFIG), SA_MISC_PEI_PREMEM_CONFIG_REVISION, LoadSaMiscPeiPreMemDefault },
+ { &gMemoryConfigGuid, sizeof(MEMORY_CONFIGURATION), MEMORY_CONFIG_REVISION, LoadMemConfigDefault },
+ { &gMemoryConfigNoCrcGuid, sizeof(MEMORY_CONFIG_NO_CRC), MEMORY_CONFIG_REVISION, LoadMemConfigNoCrcDefault }
+};
+
+static COMPONENT_BLOCK_ENTRY mSaIpBlocks [] = {
+ {&gGraphicsPeiConfigGuid, sizeof (GRAPHICS_PEI_CONFIG), GRAPHICS_PEI_CONFIG_REVISION, LoadGraphichsPeiDefault},
+ {&gVtdConfigGuid, sizeof (VTD_CONFIG), VTD_CONFIG_REVISION, LoadVtdDefault}
+};
+
+/**
+ Get SA config block table total size.
+
+ @retval Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSize (
+ VOID
+ )
+{
+ return GetComponentConfigBlockTotalSize (&mSaIpBlocks[0], sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+ Get SA config block table total size.
+
+ @retval Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSizePreMem (
+ VOID
+ )
+{
+ return GetComponentConfigBlockTotalSize (&mSaIpBlocksPreMem[0], sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+ SaAddConfigBlocksPreMem add all SA config blocks.
+
+ @param[in] ConfigBlockTableAddress The pointer to add SA config blocks
+
+ @retval EFI_SUCCESS The policy default is initialized.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SaAddConfigBlocksPreMem (
+ IN VOID *ConfigBlockTableAddress
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "SA AddConfigBlocks. TotalBlockCount = 0x%x\n", sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY)));
+ Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mSaIpBlocksPreMem[0], sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+ if (Status == EFI_SUCCESS) {
+ SaLoadSamplePolicyPreMem (ConfigBlockTableAddress);
+ }
+ return Status;
+}
+
+/**
+ SaAddConfigBlocks add all SA config blocks.
+
+ @param[in] ConfigBlockTableAddress The pointer to add SA config blocks
+
+ @retval EFI_SUCCESS The policy default is initialized.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SaAddConfigBlocks (
+ IN VOID *ConfigBlockTableAddress
+ )
+{
+ DEBUG ((DEBUG_INFO, "SA AddConfigBlocks. TotalBlockCount = 0x%x\n", sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)));
+
+ return AddComponentConfigBlocks (ConfigBlockTableAddress, &mSaIpBlocks[0], sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
new file mode 100644
index 0000000000..0afd31b584
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
@@ -0,0 +1,72 @@
+## @file
+# Component description file for the PeiSaPolicy library.
+#
+# Copyright (c) 2017, 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 = 0x00010017
+BASE_NAME = PeiSaPolicyLib
+FILE_GUID = d7022865-ef1b-449d-8c3f-ac36488c408b
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiSaPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+ConfigBlockLib
+CpuMailboxLib
+SiConfigBlockLib
+RngLib
+SmbusLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+KabylakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdTsegSize
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress
+gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress
+gSiPkgTokenSpaceGuid.PcdPeiMinMemorySize
+
+[Sources]
+PeiSaPolicyLib.c
+PeiSaPolicyLibrary.h
+MrcOemPlatform.c
+MrcOemPlatform.h
+SaPrintPolicy.c
+PeiSaPolicyLibSample.c
+
+[Sources.IA32]
+Ia32/MrcOemPlatform.asm | MSFT
+Ia32/MrcOemPlatform.S | GCC
+# Ia32/MrcOemPlatform.nasm | GCC # To support Nasm
+
+[Ppis]
+gSiPreMemPolicyPpiGuid ## CONSUMES
+gSiPolicyPpiGuid ## CONSUMES
+
+[Guids]
+gSaMiscPeiPreMemConfigGuid ## PRODUCES
+gMemoryConfigGuid ## PRODUCES
+gMemoryConfigNoCrcGuid ## PRODUCES
+gGraphicsPeiConfigGuid ## CONSUMES
+gVtdConfigGuid ## PRODUCES
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c
new file mode 100644
index 0000000000..a65349b29c
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c
@@ -0,0 +1,281 @@
+/** @file
+ This file provides services for Sample PEI policy default initialization.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <SaPolicyCommon.h>
+#include "PeiSaPolicyLibrary.h"
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MmPciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include "MrcOemPlatform.h"
+#include <Library/GpioLib.h>
+#include <GpioPinsSklH.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/RngLib.h>
+#include <Library/CpuMailboxLib.h>
+
+//
+// DQ byte mapping to CMD/CTL/CLK, from the CPU side - for SKL RVP, SKL SDS.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqByteMapSkl[2][6][2] = {
+ // Channel 0:
+ {
+ { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+ { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+ { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+ { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+ { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+ { 0xFF, 0x00 } // CA Vref is one for all bytes
+ },
+ // Channel 1:
+ {
+ { 0x33, 0xCC }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+ { 0x00, 0xCC }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+ { 0x33, 0xCC }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+ { 0x33, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+ { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+ { 0xFF, 0x00 } // CA Vref is one for all bytes
+ }
+};
+
+//
+// DQS byte swizzling between CPU and DRAM - for SKL RVP1, RVP3, RVP13
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqsMapCpu2DramSklRvp[2][8] = {
+ { 0, 1, 3, 2, 4, 5, 6, 7 }, // Channel 0
+ { 1, 0, 4, 5, 2, 3, 6, 7 } // Channel 1
+};
+
+//
+// Reference RCOMP resistors on motherboard - for SKL RVP1/RVP3
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 mRcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk - for SKL RVP1/RVP3
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 mRcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 };
+
+/**
+ Hynix H9CCNNN8JTMLAR-NTM_178b_DDP LPDDR3, 4Gb die (128Mx32), x32
+ or Elpida EDF8132A1MC-GD-F
+ or Samsung K4E8E304EB-EGCE
+ 1600, 12-15-15-34
+ 2 rank per channel, 2 SDRAMs per rank, 4x4Gb = 2GB total per channel
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mSkylakeRvp3Spd[] = {
+ 0x24, ///< 0 Number of Serial PD Bytes Written / SPD Device Size
+ 0x20, ///< 1 SPD Revision
+ 0x0F, ///< 2 DRAM Device Type
+ 0x0E, ///< 3 Module Type
+ 0x14, ///< 4 SDRAM Density and Banks: 8 Banks, 4 Gb SDRAM density
+ 0x11, ///< 5 SDRAM Addressing: 14 Rows, 10 Columns
+ 0x95, ///< 6 SDRAM Package Type: DDP, 1 Channel per die, Signal Loading Matrix 1
+ 0x00, ///< 7 SDRAM Optional Features
+ 0x00, ///< 8 SDRAM Thermal and Refresh Options
+ 0x00, ///< 9 Other SDRAM Optional Features
+ 0x00, ///< 10 Reserved - must be coded as 0x00
+ 0x03, ///< 11 Module Nominal Voltage, VDD
+ 0x0B, ///< 12 Module Organization, SDRAM width: 32 bits, 2 Ranks
+ 0x23, ///< 13 Module Memory Bus Width: 2 channels, 64 bit channel bus width
+ 0x00, ///< 14 Module Thermal Sensor
+ 0x00, ///< 15 Extended Module Type
+ 0x00, ///< 16 Reserved - must be coded as 0x00
+ 0x00, ///< 17 Timebases
+ 0x0A, ///< 18 SDRAM Minimum Cycle Time (tCKmin)
+ 0xFF, ///< 19 SDRAM Minimum Cycle Time (tCKmax)
+ 0x54, ///< 20 CAS Latencies Supported, First Byte (tCk): 12 10 8
+ 0x00, ///< 21 CAS Latencies Supported, Second Byte
+ 0x00, ///< 22 CAS Latencies Supported, Third Byte
+ 0x00, ///< 23 CAS Latencies Supported, Fourth Byte
+ 0x78, ///< 24 Minimum CAS Latency Time (tAAmin)
+ 0x00, ///< 25 Read and Write Latency Set Options
+ 0x90, ///< 26 Minimum RAS# to CAS# Delay Time (tRCDmin)
+ 0xA8, ///< 27 Minimum Row Precharge Delay Time for all banks (tRPab)
+ 0x90, ///< 28 Minimum Row Precharge Delay Time per bank (tRPpb)
+ 0x10, ///< 29 Minimum Refresh Recovery Delay Time for all banks (tRFCab), Least Significant Byte
+ 0x04, ///< 30 Minimum Refresh Recovery Delay Time for all banks (tRFCab), Most Significant Byte
+ 0xE0, ///< 31 Minimum Refresh Recovery Delay Time for per bank (tRFCpb), Least Significant Byte
+ 0x01, ///< 32 Minimum Refresh Recovery Delay Time for per bank (tRFCpb), Most Significant Byte
+ 0, 0, 0, 0, 0, 0, 0, ///< 33 - 39
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 40 - 49
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 50 - 59
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 60 - 69 Connector to SDRAM Bit Mapping
+ 0, 0, 0, 0, 0, 0, 0, 0, ///< 70 - 77 Connector to SDRAM Bit Mapping
+ 0, 0, ///< 78 - 79
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 80 - 89
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 90 - 99
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 100 - 109
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 110 - 119
+ 0x00, ///< 120 Fine Offset for Minimum Row Precharge Delay Time per bank (tRPpb)
+ 0x00, ///< 121 Fine Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
+ 0x00, ///< 122 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+ 0x00, ///< 123 Fine Offset for Minimum CAS Latency Time (tAAmin)
+ 0x7F, ///< 124 Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
+ 0x00, ///< 125 Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+ 0x00, ///< 126 CRC A
+ 0x00, ///< 127 CRC B
+ 0, 0, ///< 128 - 129
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 130 - 139
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 140 - 149
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 150 - 159
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 160 - 169
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 170 - 179
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 180 - 189
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 190 - 199
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 200 - 209
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 210 - 219
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 220 - 229
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 230 - 239
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 240 - 249
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 250 - 259
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 260 - 269
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 270 - 279
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 280 - 289
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 290 - 299
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 300 - 309
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 310 - 319
+ 0x00, ///< 320 Module Manufacturer ID Code, Least Significant Byte
+ 0x00, ///< 321 Module Manufacturer ID Code, Most Significant Byte
+ 0x00, ///< 322 Module Manufacturing Location
+ 0x00, ///< 323 Module Manufacturing Date Year
+ 0x00, ///< 324 Module Manufacturing Date Week
+ 0x55, ///< 325 Module Serial Number A
+ 0x00, ///< 326 Module Serial Number B
+ 0x00, ///< 327 Module Serial Number C
+ 0x00, ///< 328 Module Serial Number D
+ 0x20, 0x20, 0x20, 0x20, 0x20, ///< 329 - 333 Module Part Number: Unused bytes coded as ASCII Blanks (0x20)
+ 0x20, 0x20, 0x20, 0x20, 0x20, ///< 334 - 338 Module Part Number
+ 0x20, 0x20, 0x20, 0x20, 0x20, ///< 339 - 343 Module Part Number
+ 0x20, 0x20, 0x20, 0x20, 0x20, ///< 344 - 348 Module Part Number
+ 0x00, ///< 349 Module Revision Code
+ 0x00, ///< 350 DRAM Manufacturer ID Code, Least Significant Byte
+ 0x00, ///< 351 DRAM Manufacturer ID Code, Most Significant Byte
+ 0x00, ///< 352 DRAM Stepping
+ 0, 0, 0, 0, 0, 0, 0, ///< 353 - 359
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 360 - 369
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 370 - 379
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 380 - 389
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 390 - 399
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 400 - 409
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 410 - 419
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 420 - 429
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 430 - 439
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 440 - 449
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 450 - 459
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 460 - 469
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 470 - 479
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 480 - 489
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 490 - 499
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 500 - 509
+ 0, 0 ///< 510 - 511
+};
+
+#define SaIoRead8 IoRead8
+#define SaIoRead16 IoRead16
+#define SaIoRead32 IoRead32
+#define SaIoWrite8 IoWrite8
+#define SaIoWrite16 IoWrite16
+#define SaIoWrite32 IoWrite32
+#define SaCopyMem CopyMem
+#define SaSetMem SetMem
+#define SaLShiftU64 LShiftU64
+#define SaRShiftU64 RShiftU64
+#define SaMultU64x32 MultU64x32
+
+/**
+ SaLoadSamplePolicyPreMem - Load some policy default for reference board.
+
+ @param[in] ConfigBlockTableAddress The pointer for SA config blocks
+
+**/
+VOID
+SaLoadSamplePolicyPreMem (
+ IN VOID *ConfigBlockTableAddress
+ )
+{
+ SA_FUNCTION_CALLS *MemCall;
+ EFI_STATUS Status;
+ MEMORY_CONFIG_NO_CRC *MemConfigNoCrc;
+
+ MemConfigNoCrc = NULL;
+ Status = GetConfigBlock (ConfigBlockTableAddress, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+ ASSERT_EFI_ERROR (Status);
+
+ if (MemConfigNoCrc == NULL) {
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO, "Applying Sample policy defaults for RVP3\n"));
+ MemCall = &MemConfigNoCrc->SaCall;
+ MemCall->IoRead8 = &SaIoRead8;
+ MemCall->IoRead16 = &SaIoRead16;
+ MemCall->IoRead32 = &SaIoRead32;
+ MemCall->IoWrite8 = &SaIoWrite8;
+ MemCall->IoWrite16 = &SaIoWrite16;
+ MemCall->IoWrite32 = &SaIoWrite32;
+ MemCall->MmioRead8 = &MmioRead8;
+ MemCall->MmioRead16 = &MmioRead16;
+ MemCall->MmioRead32 = &MmioRead32;
+ MemCall->MmioRead64 = &SaMmioRead64;
+ MemCall->MmioWrite8 = &MmioWrite8;
+ MemCall->MmioWrite16 = &MmioWrite16;
+ MemCall->MmioWrite32 = &MmioWrite32;
+ MemCall->MmioWrite64 = &SaMmioWrite64;
+ MemCall->SmbusRead8 = &SmBusReadDataByte;
+ MemCall->SmbusRead16 = &SmBusReadDataWord;
+ MemCall->SmbusWrite8 = &SmBusWriteDataByte;
+ MemCall->SmbusWrite16 = &SmBusWriteDataWord;
+ MemCall->GetPciDeviceAddress = &GetPciDeviceAddress;
+ MemCall->GetPcieDeviceAddress = &GetPcieDeviceAddress;
+ MemCall->GetRtcTime = &GetRtcTime;
+ MemCall->GetCpuTime = &GetCpuTime;
+ MemCall->CopyMem = &SaCopyMem;
+ MemCall->SetMem = &SaSetMem;
+ MemCall->SetMemWord = &SetMemWord;
+ MemCall->SetMemDword = &SetMemDword;
+ MemCall->LeftShift64 = &SaLShiftU64;
+ MemCall->RightShift64 = &SaRShiftU64;
+ MemCall->MultU64x32 = &SaMultU64x32;
+ MemCall->DivU64x64 = &DivU64x64Remainder;
+ MemCall->GetSpdData = &GetSpdData;
+ MemCall->GetRandomNumber = &GetRandomNumber32;
+ MemCall->CpuMailboxRead = &MailboxRead;
+ MemCall->CpuMailboxWrite = &MailboxWrite;
+ MemCall->GetMemoryVdd = &GetMemoryVdd;
+ MemCall->SetMemoryVdd = &SetMemoryVdd;
+ MemCall->CheckPoint = &CheckPoint;
+ MemCall->DebugHook = &DebugHook;
+ MemCall->DebugPrint = &SaDebugPrint;
+ MemCall->GetRtcCmos = &PeiRtcRead;
+ MemCall->ReadMsr64 = &AsmReadMsr64;
+ MemCall->WriteMsr64 = &AsmWriteMsr64;
+ MemCall->MrcReturnFromSmc = &ReturnFromSmc;
+ MemCall->MrcDramReset = &SaDramReset;
+
+ //
+ // RCOMP resistors and target values: board-dependent
+ //
+ CopyMem ((VOID *) MemConfigNoCrc->RcompData->RcompResistor, mRcompResistorSklRvp1, sizeof (mRcompResistorSklRvp1));
+ CopyMem ((VOID *) MemConfigNoCrc->RcompData->RcompTarget, mRcompTargetSklRvp1, sizeof (mRcompTargetSklRvp1));
+
+ CopyMem ((VOID *) MemConfigNoCrc->SpdData->SpdData[0][0], mSkylakeRvp3Spd, sizeof (mSkylakeRvp3Spd));
+ CopyMem ((VOID *) MemConfigNoCrc->SpdData->SpdData[1][0], mSkylakeRvp3Spd, sizeof (mSkylakeRvp3Spd));
+ CopyMem ((VOID *) MemConfigNoCrc->DqByteMap, mDqByteMapSkl, sizeof (UINT8) * SA_MC_MAX_CHANNELS * SA_MRC_ITERATION_MAX *2);
+ CopyMem ((VOID *) MemConfigNoCrc->DqsMap, mDqsMapCpu2DramSklRvp, sizeof (UINT8) * SA_MC_MAX_CHANNELS * SA_MC_MAX_BYTES_NO_ECC);
+}
+
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h
new file mode 100644
index 0000000000..e7fe3d2fcf
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h
@@ -0,0 +1,44 @@
+/** @file
+ Header file for the PeiSaPolicy library.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _PEI_SA_POLICY_LIBRARY_H_
+#define _PEI_SA_POLICY_LIBRARY_H_
+
+#include <CpuRegs.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MmPciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/SiConfigBlockLib.h>
+
+/**
+ SaLoadSamplePolicyPreMem - Load some policy default for reference board.
+
+ @param[in] ConfigBlockTableAddress The pointer for SA config blocks
+
+**/
+VOID
+SaLoadSamplePolicyPreMem (
+ IN VOID *ConfigBlockTableAddress
+ );
+#endif // _PEI_SA_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c
new file mode 100644
index 0000000000..0a6ddb8a8f
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c
@@ -0,0 +1,326 @@
+/** @file
+ This file provides service for PEI phase policy printing
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include "PeiSaPolicyLibrary.h"
+#include <Library/GpioNativeLib.h>
+
+/**
+ This function prints the PEI phase PreMem policy.
+
+ @param[in] SiPolicyPreMemPpi - Instance of SI_PREMEM_POLICY_PPI
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpiPreMem (
+ IN SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ INTN Index;
+ INTN Index2;
+ EFI_STATUS Status;
+ SA_MISC_PEI_PREMEM_CONFIG *MiscPeiPreMemConfig;
+ MEMORY_CONFIGURATION *MemConfig;
+ MEMORY_CONFIG_NO_CRC *MemConfigNoCrc;
+
+ //
+ // Get requisite IP Config Blocks which needs to be used here
+ //
+ Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gMemoryConfigGuid, (VOID *) &MemConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+ ASSERT_EFI_ERROR (Status);
+
+
+ DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI PreMem) Print BEGIN -----------------\n"));
+ DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", SiPolicyPreMemPpi->TableHeader.Header.Revision));
+ ASSERT (SiPolicyPreMemPpi->TableHeader.Header.Revision == SI_PREMEM_POLICY_REVISION);
+
+ DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_PEI_PREMEM_CONFIG -----------------\n"));
+ DEBUG ((DEBUG_INFO, " Revision : %d\n", MiscPeiPreMemConfig->Header.Revision));
+ ASSERT (MiscPeiPreMemConfig->Header.Revision == SA_MISC_PEI_PREMEM_CONFIG_REVISION);
+ DEBUG ((DEBUG_INFO, " SpdAddressTable[%d] :", SA_MC_MAX_SOCKETS));
+ for (Index = 0; Index < SA_MC_MAX_SOCKETS; Index++) {
+ DEBUG ((DEBUG_INFO, " 0x%x", MiscPeiPreMemConfig->SpdAddressTable[Index]));
+ }
+ DEBUG ((DEBUG_INFO, "\n"));
+
+ DEBUG ((DEBUG_INFO, " MchBar : 0x%x\n", MiscPeiPreMemConfig->MchBar));
+ DEBUG ((DEBUG_INFO, "------------------------ MEMORY_CONFIG ------------------------------\n"));
+ DEBUG ((DEBUG_INFO, " Guid : %g\n", &MemConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, " Revision : %d\n", MemConfig->Header.Revision));
+ ASSERT (MemConfig->Header.Revision == MEMORY_CONFIG_REVISION);
+ DEBUG ((DEBUG_INFO, " Size : 0x%x\n", MemConfig->Header.GuidHob.Header.HobLength));
+ DEBUG ((DEBUG_INFO, " HobBufferSize : 0x%x\n", MemConfig->HobBufferSize));
+ DEBUG ((DEBUG_INFO, " EccSupport : 0x%x\n", MemConfig->EccSupport));
+ DEBUG ((DEBUG_INFO, " DdrFreqLimit: %d\n", MemConfig->DdrFreqLimit));
+ DEBUG ((DEBUG_INFO, " SpdProfileSelected : 0x%x\n", MemConfig->SpdProfileSelected));
+ DEBUG ((DEBUG_INFO, " tCL : 0x%x\n", MemConfig->tCL));
+ DEBUG ((DEBUG_INFO, " tRCDtRP : 0x%x\n", MemConfig->tRCDtRP));
+ DEBUG ((DEBUG_INFO, " tRAS : 0x%x\n", MemConfig->tRAS));
+ DEBUG ((DEBUG_INFO, " tWR : 0x%x\n", MemConfig->tWR));
+ DEBUG ((DEBUG_INFO, " tRFC : 0x%x\n", MemConfig->tRFC));
+ DEBUG ((DEBUG_INFO, " tRRD : 0x%x\n", MemConfig->tRRD));
+ DEBUG ((DEBUG_INFO, " tWTR : 0x%x\n", MemConfig->tWTR));
+ DEBUG ((DEBUG_INFO, " tRTP : 0x%x\n", MemConfig->tRTP));
+ DEBUG ((DEBUG_INFO, " tFAW : 0x%x\n", MemConfig->tFAW));
+ DEBUG ((DEBUG_INFO, " tCWL : 0x%x\n", MemConfig->tCWL));
+ DEBUG ((DEBUG_INFO, " tREFI : 0x%x\n", MemConfig->tREFI));
+ DEBUG ((DEBUG_INFO, " NModeSupport : 0x%x\n", MemConfig->NModeSupport));
+ DEBUG ((DEBUG_INFO, " VddVoltage : %d\n", MemConfig->VddVoltage));
+ DEBUG ((DEBUG_INFO, " ThermalManagement : 0x%x\n", MemConfig->ThermalManagement));
+ DEBUG ((DEBUG_INFO, " PeciInjectedTemp : 0x%x\n", MemConfig->PeciInjectedTemp));
+ DEBUG ((DEBUG_INFO, " ExttsViaTsOnBoard : 0x%x\n", MemConfig->ExttsViaTsOnBoard));
+ DEBUG ((DEBUG_INFO, " ExttsViaTsOnDimm : 0x%x\n", MemConfig->ExttsViaTsOnDimm));
+ DEBUG ((DEBUG_INFO, " VirtualTempSensor : 0x%x\n", MemConfig->VirtualTempSensor));
+
+ DEBUG ((DEBUG_INFO, " DisableDimmChannel[%d] :", SA_MC_MAX_CHANNELS));
+ for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+ DEBUG ((DEBUG_INFO, " 0x%x", MemConfig->DisableDimmChannel[Index]));
+ }
+ DEBUG ((DEBUG_INFO, "\n"));
+ DEBUG ((DEBUG_INFO, " RemapEnable : 0x%x\n", MemConfig->RemapEnable));
+ DEBUG ((DEBUG_INFO, " ScramblerSupport : 0x%x\n", MemConfig->ScramblerSupport));
+ DEBUG ((DEBUG_INFO, " SerialDebug : 0x%x\n", MemConfigNoCrc->SerialDebugLevel));
+ DEBUG ((DEBUG_INFO, " McLock : 0x%x\n", MemConfig->McLock));
+ DEBUG ((DEBUG_INFO, " ProbelessTrace : 0x%x\n", MemConfig->ProbelessTrace));
+ DEBUG ((DEBUG_INFO, " GdxcIotSize : 0x%x\n", MemConfig->GdxcIotSize));
+ DEBUG ((DEBUG_INFO, " GdxcMotSize : 0x%x\n", MemConfig->GdxcMotSize));
+
+ DEBUG ((DEBUG_INFO, " ECT : 0x%x\n", MemConfig->ECT));
+ DEBUG ((DEBUG_INFO, " SOT : 0x%x\n", MemConfig->SOT));
+ DEBUG ((DEBUG_INFO, " ERDMPRTC2D : 0x%x\n", MemConfig->ERDMPRTC2D));
+ DEBUG ((DEBUG_INFO, " RDMPRT : 0x%x\n", MemConfig->RDMPRT));
+ DEBUG ((DEBUG_INFO, " RCVET : 0x%x\n", MemConfig->RCVET));
+ DEBUG ((DEBUG_INFO, " JWRL : 0x%x\n", MemConfig->JWRL));
+ DEBUG ((DEBUG_INFO, " EWRDSEQ : 0x%x\n", MemConfig->EWRDSEQ));
+ DEBUG ((DEBUG_INFO, " EWRTC2D : 0x%x\n", MemConfig->EWRTC2D));
+ DEBUG ((DEBUG_INFO, " ERDTC2D : 0x%x\n", MemConfig->ERDTC2D));
+ DEBUG ((DEBUG_INFO, " WRTC1D : 0x%x\n", MemConfig->WRTC1D));
+ DEBUG ((DEBUG_INFO, " WRVC1D : 0x%x\n", MemConfig->WRVC1D));
+ DEBUG ((DEBUG_INFO, " RDTC1D : 0x%x\n", MemConfig->RDTC1D));
+ DEBUG ((DEBUG_INFO, " DIMMODTT : 0x%x\n", MemConfig->DIMMODTT));
+ DEBUG ((DEBUG_INFO, " DIMMRONT : 0x%x\n", MemConfig->DIMMRONT));
+ DEBUG ((DEBUG_INFO, " WRDSEQT : 0x%x\n", MemConfig->WRDSEQT));
+ DEBUG ((DEBUG_INFO, " WRSRT : 0x%x\n", MemConfig->WRSRT));
+ DEBUG ((DEBUG_INFO, " RDODTT : 0x%x\n", MemConfig->RDODTT));
+ DEBUG ((DEBUG_INFO, " RDEQT : 0x%x\n", MemConfig->RDEQT));
+ DEBUG ((DEBUG_INFO, " RDAPT : 0x%x\n", MemConfig->RDAPT));
+ DEBUG ((DEBUG_INFO, " WRTC2D : 0x%x\n", MemConfig->WRTC2D));
+ DEBUG ((DEBUG_INFO, " RDTC2D : 0x%x\n", MemConfig->RDTC2D));
+ DEBUG ((DEBUG_INFO, " WRVC2D : 0x%x\n", MemConfig->WRVC2D));
+ DEBUG ((DEBUG_INFO, " RDVC2D : 0x%x\n", MemConfig->RDVC2D));
+ DEBUG ((DEBUG_INFO, " CMDVC : 0x%x\n", MemConfig->CMDVC));
+ DEBUG ((DEBUG_INFO, " LCT : 0x%x\n", MemConfig->LCT));
+ DEBUG ((DEBUG_INFO, " RTL : 0x%x\n", MemConfig->RTL));
+ DEBUG ((DEBUG_INFO, " TAT : 0x%x\n", MemConfig->TAT));
+ DEBUG ((DEBUG_INFO, " RMT : 0x%x\n", MemConfig->RMT));
+ DEBUG ((DEBUG_INFO, " MEMTST : 0x%x\n", MemConfig->MEMTST));
+ DEBUG ((DEBUG_INFO, " ALIASCHK : 0x%x\n", MemConfig->ALIASCHK));
+ DEBUG ((DEBUG_INFO, " RCVENC1D : 0x%x\n", MemConfig->RCVENC1D));
+ DEBUG ((DEBUG_INFO, " RMC : 0x%x\n", MemConfig->RMC));
+ DEBUG ((DEBUG_INFO, " WRDSUDT : 0x%x\n", MemConfig->WRDSUDT));
+ DEBUG ((DEBUG_INFO, " CMDSR: %d\n CMDDSEQ: %d\n CMDNORM: %d\n",
+ MemConfig->CMDSR, MemConfig->CMDDSEQ, MemConfig->CMDNORM));
+
+ DEBUG ((DEBUG_INFO, " VddSettleWaitTime : 0x%x\n", MemConfig->VddSettleWaitTime));
+ DEBUG ((DEBUG_INFO, " RefClk : 0x%x\n", MemConfig->RefClk));
+ DEBUG ((DEBUG_INFO, " Ratio : 0x%x\n", MemConfig->Ratio));
+ DEBUG ((DEBUG_INFO, " OddRatioMode : 0x%x\n", MemConfig->OddRatioMode));
+ DEBUG ((DEBUG_INFO, " MrcTimeMeasure : 0x%x\n", MemConfig->MrcTimeMeasure));
+ DEBUG ((DEBUG_INFO, " MrcFastBoot : 0x%x\n", MemConfig->MrcFastBoot));
+ DEBUG ((DEBUG_INFO, " DqPinsInterleaved : 0x%x\n", MemConfig->DqPinsInterleaved));
+ DEBUG ((DEBUG_INFO, " MrcSafeConfig : 0x%x\n", MemConfig->MrcSafeConfig));
+
+ DEBUG ((DEBUG_INFO, " PowerDownMode : 0x%x\n", MemConfig->PowerDownMode));
+ DEBUG ((DEBUG_INFO, " PwdwnIdleCounter : 0x%x\n", MemConfig->PwdwnIdleCounter));
+ DEBUG ((DEBUG_INFO, " RankInterleave : 0x%x\n", MemConfig->RankInterleave));
+ DEBUG ((DEBUG_INFO, " EnhancedInterleave : 0x%x\n", MemConfig->EnhancedInterleave));
+ DEBUG ((DEBUG_INFO, " WeaklockEn : 0x%x\n", MemConfig->WeaklockEn));
+ DEBUG ((DEBUG_INFO, " EnCmdRate : 0x%x\n", MemConfig->EnCmdRate));
+ DEBUG ((DEBUG_INFO, " CmdTriStateDis : 0x%x\n", MemConfig->CmdTriStateDis));
+ DEBUG ((DEBUG_INFO, " BClkFrequency: %d Hz\n", MemConfig->BClkFrequency));
+ DEBUG ((DEBUG_INFO, " MemoryTrace : 0x%x\n", MemConfig->MemoryTrace));
+ DEBUG ((DEBUG_INFO, " ChHashEnable : 0x%x\n", MemConfig->ChHashEnable));
+ DEBUG ((DEBUG_INFO, " ChHashMask : 0x%x\n", MemConfig->ChHashMask));
+ DEBUG ((DEBUG_INFO, " ChHashInterleaveBit : 0x%x\n", MemConfig->ChHashInterleaveBit));
+ DEBUG ((DEBUG_INFO, " EnableExtts : 0x%x\n", MemConfig->EnableExtts));
+ DEBUG ((DEBUG_INFO, " EnableCltm : 0x%x\n", MemConfig->EnableCltm));
+ DEBUG ((DEBUG_INFO, " EnableOltm : 0x%x\n", MemConfig->EnableOltm));
+ DEBUG ((DEBUG_INFO, " EnablePwrDn : 0x%x\n", MemConfig->EnablePwrDn));
+ DEBUG ((DEBUG_INFO, " EnablePwrDnLpddr : 0x%x\n", MemConfig->EnablePwrDnLpddr));
+ DEBUG ((DEBUG_INFO, " Refresh2X : 0x%x\n", MemConfig->Refresh2X));
+ DEBUG ((DEBUG_INFO, " DdrThermalSensor : 0x%x\n", MemConfig->DdrThermalSensor));
+ DEBUG ((DEBUG_INFO, " LockPTMregs : 0x%x\n", MemConfig->LockPTMregs));
+ DEBUG ((DEBUG_INFO, " UserPowerWeightsEn : 0x%x\n", MemConfig->UserPowerWeightsEn));
+ DEBUG ((DEBUG_INFO, " EnergyScaleFact : 0x%x\n", MemConfig->EnergyScaleFact));
+ DEBUG ((DEBUG_INFO, " RaplPwrFlCh1 : 0x%x\n", MemConfig->RaplPwrFlCh1));
+ DEBUG ((DEBUG_INFO, " RaplPwrFlCh0 : 0x%x\n", MemConfig->RaplPwrFlCh0));
+ DEBUG ((DEBUG_INFO, " RaplLim2Lock : 0x%x\n", MemConfig->RaplLim2Lock));
+ DEBUG ((DEBUG_INFO, " RaplLim2WindX : 0x%x\n", MemConfig->RaplLim2WindX));
+ DEBUG ((DEBUG_INFO, " RaplLim2WindY : 0x%x\n", MemConfig->RaplLim2WindY));
+ DEBUG ((DEBUG_INFO, " RaplLim2Ena : 0x%x\n", MemConfig->RaplLim2Ena));
+ DEBUG ((DEBUG_INFO, " RaplLim2Pwr : 0x%x\n", MemConfig->RaplLim2Pwr));
+ DEBUG ((DEBUG_INFO, " RaplLim1WindX : 0x%x\n", MemConfig->RaplLim1WindX));
+ DEBUG ((DEBUG_INFO, " RaplLim1WindY : 0x%x\n", MemConfig->RaplLim1WindY));
+ DEBUG ((DEBUG_INFO, " RaplLim1Ena : 0x%x\n", MemConfig->RaplLim1Ena));
+ DEBUG ((DEBUG_INFO, " RaplLim1Pwr : 0x%x\n", MemConfig->RaplLim1Pwr));
+ DEBUG ((DEBUG_INFO, " WarmThresholdCh0Dimm0 : 0x%x\n", MemConfig->WarmThresholdCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " WarmThresholdCh0Dimm1 : 0x%x\n", MemConfig->WarmThresholdCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " WarmThresholdCh1Dimm0 : 0x%x\n", MemConfig->WarmThresholdCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " WarmThresholdCh1Dimm1 : 0x%x\n", MemConfig->WarmThresholdCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " HotThresholdCh0Dimm0 : 0x%x\n", MemConfig->HotThresholdCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " HotThresholdCh0Dimm1 : 0x%x\n", MemConfig->HotThresholdCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " HotThresholdCh1Dimm0 : 0x%x\n", MemConfig->HotThresholdCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " HotThresholdCh1Dimm1 : 0x%x\n", MemConfig->HotThresholdCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " WarmBudgetCh0Dimm0 : 0x%x\n", MemConfig->WarmBudgetCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " WarmBudgetCh0Dimm1 : 0x%x\n", MemConfig->WarmBudgetCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " WarmBudgetCh1Dimm0 : 0x%x\n", MemConfig->WarmBudgetCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " WarmBudgetCh1Dimm1 : 0x%x\n", MemConfig->WarmBudgetCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " HotBudgetCh0Dimm0 : 0x%x\n", MemConfig->HotBudgetCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " HotBudgetCh0Dimm1 : 0x%x\n", MemConfig->HotBudgetCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " HotBudgetCh1Dimm0 : 0x%x\n", MemConfig->HotBudgetCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " HotBudgetCh1Dimm1 : 0x%x\n", MemConfig->HotBudgetCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " IdleEnergyCh0Dimm0 : 0x%x\n", MemConfig->IdleEnergyCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " IdleEnergyCh0Dimm1 : 0x%x\n", MemConfig->IdleEnergyCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " IdleEnergyCh1Dimm0 : 0x%x\n", MemConfig->IdleEnergyCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " IdleEnergyCh1Dimm1 : 0x%x\n", MemConfig->IdleEnergyCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " PdEnergyCh0Dimm0 : 0x%x\n", MemConfig->PdEnergyCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " PdEnergyCh0Dimm1 : 0x%x\n", MemConfig->PdEnergyCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " PdEnergyCh1Dimm0 : 0x%x\n", MemConfig->PdEnergyCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " PdEnergyCh1Dimm1 : 0x%x\n", MemConfig->PdEnergyCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " ActEnergyCh0Dimm0 : 0x%x\n", MemConfig->ActEnergyCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " ActEnergyCh0Dimm1 : 0x%x\n", MemConfig->ActEnergyCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " ActEnergyCh1Dimm0 : 0x%x\n", MemConfig->ActEnergyCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " ActEnergyCh1Dimm1 : 0x%x\n", MemConfig->ActEnergyCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " RdEnergyCh0Dimm0 : 0x%x\n", MemConfig->RdEnergyCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " RdEnergyCh0Dimm1 : 0x%x\n", MemConfig->RdEnergyCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " RdEnergyCh1Dimm0 : 0x%x\n", MemConfig->RdEnergyCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " RdEnergyCh1Dimm1 : 0x%x\n", MemConfig->RdEnergyCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " WrEnergyCh0Dimm0 : 0x%x\n", MemConfig->WrEnergyCh0Dimm0));
+ DEBUG ((DEBUG_INFO, " WrEnergyCh0Dimm1 : 0x%x\n", MemConfig->WrEnergyCh0Dimm1));
+ DEBUG ((DEBUG_INFO, " WrEnergyCh1Dimm0 : 0x%x\n", MemConfig->WrEnergyCh1Dimm0));
+ DEBUG ((DEBUG_INFO, " WrEnergyCh1Dimm1 : 0x%x\n", MemConfig->WrEnergyCh1Dimm1));
+ DEBUG ((DEBUG_INFO, " SrefCfgEna : 0x%x\n", MemConfig->SrefCfgEna));
+ DEBUG ((DEBUG_INFO, " SrefCfgIdleTmr : 0x%x\n", MemConfig->SrefCfgIdleTmr));
+ DEBUG ((DEBUG_INFO, " ThrtCkeMinDefeat : 0x%x\n", MemConfig->ThrtCkeMinDefeat));
+ DEBUG ((DEBUG_INFO, " ThrtCkeMinTmr : 0x%x\n", MemConfig->ThrtCkeMinTmr));
+ DEBUG ((DEBUG_INFO, " ThrtCkeMinDefeatLpddr : 0x%x\n", MemConfig->ThrtCkeMinDefeatLpddr));
+ DEBUG ((DEBUG_INFO, " ThrtCkeMinTmrLpddr : 0x%x\n", MemConfig->ThrtCkeMinTmrLpddr));
+ DEBUG ((DEBUG_INFO, " AutoSelfRefreshSupport : 0x%x\n", MemConfig->AutoSelfRefreshSupport));
+ DEBUG ((DEBUG_INFO, " ExtTemperatureSupport : 0x%x\n", MemConfig->ExtTemperatureSupport));
+ DEBUG ((DEBUG_INFO, " MaxRttWr : 0x%x\n", MemConfig->MaxRttWr));
+ DEBUG ((DEBUG_INFO, " MobilePlatform : 0x%x\n", MemConfig->MobilePlatform));
+ DEBUG ((DEBUG_INFO, " Force1Dpc : 0x%x\n", MemConfig->Force1Dpc));
+
+
+ DEBUG ((DEBUG_INFO, " ForceSingleRank : 0x%x\n", MemConfig->ForceSingleRank));
+ DEBUG ((DEBUG_INFO, " PciIndex : 0x%x\n", MemConfig->PciIndex));
+ DEBUG ((DEBUG_INFO, " PciData : 0x%x\n", MemConfig->PciData));
+ DEBUG ((DEBUG_INFO, " CkeRankMapping : 0x%x\n", MemConfig->CkeRankMapping));
+ DEBUG ((DEBUG_INFO, " RhPrevention : 0x%x\n", MemConfig->RhPrevention));
+ DEBUG ((DEBUG_INFO, " RhSolution : 0x%x\n", MemConfig->RhSolution));
+ DEBUG ((DEBUG_INFO, " RhActProbability : 0x%x\n", MemConfig->RhActProbability));
+ DEBUG ((DEBUG_INFO, " VttTermination : 0x%x\n", MemConfig->VttTermination));
+ DEBUG ((DEBUG_INFO, " VttCompForVsshi : 0x%x\n", MemConfig->VttCompForVsshi));
+ DEBUG ((DEBUG_INFO, " BerEnable : 0x%x\n", MemConfig->BerEnable));
+ for (Index = 0; Index < 4; Index++) {
+ DEBUG ((DEBUG_INFO, " BerAddress[%d] : 0x%x\n",Index , MemConfig->BerAddress[Index]));
+ }
+ DEBUG ((DEBUG_INFO, " CleanMemory : 0x%x\n", MemConfigNoCrc->CleanMemory));
+ DEBUG ((DEBUG_INFO, " ExitOnFailure : 0x%x\n", MemConfig->ExitOnFailure));
+ DEBUG ((DEBUG_INFO, " Vc1ReadMeter : 0x%x\n", MemConfig->Vc1ReadMeter));
+ DEBUG ((DEBUG_INFO, " Vc1ReadMeterTimeWindow : 0x%x\n", MemConfig->Vc1ReadMeterTimeWindow));
+ DEBUG ((DEBUG_INFO, " Vc1ReadMeterThreshold : 0x%x\n", MemConfig->Vc1ReadMeterThreshold));
+ DEBUG ((DEBUG_INFO, " SaGv : 0x%x\n", MemConfig->SaGv));
+ DEBUG ((DEBUG_INFO, " FreqSaGvLow : 0x%x\n", MemConfig->FreqSaGvLow));
+ DEBUG ((DEBUG_INFO, " StrongWkLeaker : 0x%x\n", MemConfig->StrongWkLeaker));
+ DEBUG ((DEBUG_INFO, " CaVrefConfig : 0x%x\n", MemConfig->CaVrefConfig));
+ DEBUG ((DEBUG_INFO, " EvLoader : 0x%x\n", MemConfig->EvLoader));
+ DEBUG ((DEBUG_INFO, " EvLoaderDelay : 0x%x\n", MemConfig->EvLoaderDelay));
+ DEBUG ((DEBUG_INFO, " PlatformMemorySize : 0x%x\n", MemConfigNoCrc->PlatformMemorySize));
+ DEBUG ((DEBUG_INFO, " SmramMask : 0x%x\n", MemConfig->SmramMask));
+ DEBUG ((DEBUG_INFO, " DllBwEn0: %d\n DllBwEn1: %d\n DllBwEn2: %d\n DllBwEn3: %d\n",
+ MemConfig->DllBwEn0, MemConfig->DllBwEn1, MemConfig->DllBwEn2, MemConfig->DllBwEn3));
+ DEBUG ((DEBUG_INFO, " RetrainOnFastFail: %d\n ForceOltmOrRefresh2x: %d\n",
+ MemConfig->RetrainOnFastFail, MemConfig->ForceOltmOrRefresh2x));
+ for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+ DEBUG ((DEBUG_INFO, " DqByteMapCh%d : ", Index));
+ for (Index2 = 0; Index2 < SA_MRC_ITERATION_MAX; Index2++) {
+ DEBUG ((DEBUG_INFO, "0x%02x ", MemConfigNoCrc->DqByteMap->DqByteMap[Index][Index2][0]));
+ DEBUG ((DEBUG_INFO, "0x%02x ", MemConfigNoCrc->DqByteMap->DqByteMap[Index][Index2][1]));
+ }
+ DEBUG ((DEBUG_INFO, "\n"));
+ }
+ for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+ DEBUG ((DEBUG_INFO, " DqsMapCpu2DramCh%d : ", Index));
+ for (Index2 = 0; Index2 < SA_MC_MAX_BYTES_NO_ECC; Index2++) {
+ DEBUG ((DEBUG_INFO, "%d ", MemConfigNoCrc->DqsMap->DqsMapCpu2Dram[Index][Index2]));
+ }
+ DEBUG ((DEBUG_INFO, "\n"));
+ }
+ DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI PreMem) Print END -----------------\n"));
+ DEBUG_CODE_END ();
+ return;
+}
+
+/**
+ This function prints the PEI phase policy.
+
+ @param[in] SiPolicyPpi - Instance of SI_POLICY_PPI
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpi (
+ IN SI_POLICY_PPI *SiPolicyPpi
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ EFI_STATUS Status;
+ GRAPHICS_PEI_CONFIG *GtConfig;
+ INTN Index;
+ VTD_CONFIG *Vtd;
+
+ Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gVtdConfigGuid, (VOID *) &Vtd);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *) &GtConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI) Print BEGIN -----------------\n"));
+ DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", SiPolicyPpi->TableHeader.Header.Revision));
+ ASSERT (SiPolicyPpi->TableHeader.Header.Revision == SI_POLICY_REVISION);
+ DEBUG ((DEBUG_INFO, "------------------------ GRAPHICS_PEI_CONFIG -----------------\n"));
+ DEBUG ((DEBUG_INFO, " Revision : %d\n", GtConfig->Header.Revision));
+ ASSERT (GtConfig->Header.Revision == GRAPHICS_PEI_CONFIG_REVISION);
+ DEBUG ((DEBUG_INFO, " PeiGraphicsPeimInit : 0x%x\n", GtConfig->PeiGraphicsPeimInit));
+ DEBUG ((DEBUG_INFO, " LogoPtr : 0x%x\n", GtConfig->LogoPtr));
+ DEBUG ((DEBUG_INFO, " LogoSize : 0x%x\n", GtConfig->LogoSize));
+ DEBUG ((DEBUG_INFO, " GraphicsConfigPtr : 0x%x\n", GtConfig->GraphicsConfigPtr));
+ DEBUG ((DEBUG_INFO, "------------------------ VTD_CONFIG -----------------\n"));
+ DEBUG ((DEBUG_INFO, " Revision : %d\n", Vtd->Header.Revision));
+ ASSERT (Vtd->Header.Revision == VTD_CONFIG_REVISION);
+ DEBUG ((DEBUG_INFO, " VtdDisable : 0x%x\n", Vtd->VtdDisable));
+ DEBUG ((DEBUG_INFO, " X2ApicOptOut : 0x%x\n", Vtd->X2ApicOptOut));
+ DEBUG ((DEBUG_INFO, " VtdBaseAddress[%d] :", SA_VTD_ENGINE_NUMBER));
+ for (Index = 0; Index < SA_VTD_ENGINE_NUMBER; Index++) {
+ DEBUG ((DEBUG_INFO, " 0x%x", Vtd->BaseAddress[Index]));
+ }
+ DEBUG ((DEBUG_INFO, "\n"));
+ DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI) Print END -----------------\n"));
+ DEBUG_CODE_END ();
+ return;
+} \ No newline at end of file