summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/Proc/Mem/Ps
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/Proc/Mem/Ps')
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/C32/mprc32_3.c326
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/C32/mpuc32_3.c205
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpsda2.c161
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpsda3.c257
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpuda3.c210
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mprdr2.c166
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mprdr3.c205
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpsdr3.c192
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpudr2.c166
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpudr3.c161
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mprhy3.c325
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mpshy3.c221
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mpuhy3.c199
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/NI/mpsNi3.c257
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/NI/mpuNi3.c235
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/ON/mpson3.c181
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/ON/mpuon3.c182
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/PH/mpsph3.c257
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/PH/mpuph3.c211
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/RB/mpsRb3.c257
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/RB/mpuRb3.c211
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mp.c510
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mplribt.c190
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mplrnlr.c111
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mplrnpr.c111
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mpmaxfreq.c250
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mpmr0.c179
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mpodtpat.c189
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mprc10opspd.c163
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mprc2ibt.c210
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mprtt.c229
-rw-r--r--src/vendorcode/amd/agesa/Proc/Mem/Ps/mpsao.c200
32 files changed, 6927 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/C32/mprc32_3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/C32/mprc32_3.c
new file mode 100644
index 0000000000..9113812241
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/C32/mprc32_3.c
@@ -0,0 +1,326 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mprc32_3.c
+ *
+ * Platform specific settings for C32 DDR3 R-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_C32_MPRC32_3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define AMD_FAMILY_10_C32 AMD_FAMILY_10_HY
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsRC32_3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitRC32_3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*
+ * ODT Settings for 1 or 2 Dimms Per Channel
+ *
+ * Speeds Supported, # of Dimms, # of QRDimms, DramTerm, QR DramTerm, Dynamic DramTerm
+ */
+STATIC CONST DRAM_TERM_ENTRY C32RDdr3DramTerm2D[] = {
+ {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR667 + DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1},
+ {DDR667 + DDR800 + DDR1066 + DDR1333, ONE_DIMM, ONE_DIMM, 0, 1, 2},
+ {DDR1600, ONE_DIMM, ONE_DIMM, 0, 1, 1},
+ {DDR667 + DDR800, TWO_DIMM, ONE_DIMM, 5, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, ONE_DIMM, 5, 1, 1},
+ {DDR667 + DDR800, TWO_DIMM, TWO_DIMM, 0, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, TWO_DIMM, 0, 1, 1}
+};
+/*
+ * ODT Settings for 3 Dimms Per Channel
+ *
+ * Speeds Supported, # of Dimms, # of QRDimms, DramTerm, QR DramTerm, Dynamic DramTerm
+ */
+STATIC CONST DRAM_TERM_ENTRY C32RDdr3DramTerm3D[] = {
+ {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR667 + DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333 + DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600, THREE_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR667 + DDR800 + DDR1066 + DDR1333, ONE_DIMM, ONE_DIMM, 0, 1, 2},
+ {DDR667 + DDR800, TWO_DIMM, ONE_DIMM, 5, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, ONE_DIMM, 5, 1, 1},
+ {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600, THREE_DIMM, ONE_DIMM, 3, 1, 2}
+};
+/*
+ * POR Max Frequency supported for specific Dimm configurations for 1 Dimm Per Channel
+ *
+ * Dimm Config, # of Dimms, Max Freq @ 1.5V, Max Freq @ 1.35V, Max Freq @ 1.25
+ */
+STATIC CONST POR_SPEED_LIMIT C32RDdr3PSPorFreqLimit1D[] = {
+ {SR_DIMM0 + DR_DIMM0, 1, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {QR_DIMM0, 1, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0}
+};
+/*
+ * POR Max Frequency supported for specific Dimm configurations for 2 Dimms Per Channel
+ *
+ * Dimm Config, # of Dimms, Max Freq @ 1.5V, Max Freq @ 1.35V, Max Freq @ 1.25
+ */
+STATIC CONST POR_SPEED_LIMIT C32RDdr3PSPorFreqLimit2D[] = {
+ {SR_DIMM1 + DR_DIMM1, 1, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {QR_DIMM1, 1, DDR1333_FREQUENCY, DDR1066_FREQUENCY, 0},
+ {SR_DIMM0 + SR_DIMM1, 2, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, 2, DDR1066_FREQUENCY, DDR1066_FREQUENCY, 0},
+ {QR_DIMM0 + ANY_DIMM1, 2, DDR800_FREQUENCY, DDR667_FREQUENCY, 0},
+ {ANY_DIMM0 + QR_DIMM1, 2, DDR800_FREQUENCY, DDR667_FREQUENCY, 0}
+};
+/*
+ * POR Max Frequency supported for specific Dimm configurations for 3 Dimms Per Channel
+ *
+ * Dimm Config, # of Dimms, Max Freq @ 1.5V, Max Freq @ 1.35V, Max Freq @ 1.25
+ */
+STATIC CONST POR_SPEED_LIMIT C32RDdr3PSPorFreqLimit3D[] = {
+ {SR_DIMM2 + DR_DIMM2, 1, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {SR_DIMM0 + SR_DIMM2, 2, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM2 + DR_DIMM2, 2, DDR1066_FREQUENCY, DDR1066_FREQUENCY, 0},
+ {QR_DIMM1, 1, DDR800_FREQUENCY, DDR800_FREQUENCY, 0},
+ {QR_DIMM1 + SR_DIMM2 + DR_DIMM2, 2, DDR800_FREQUENCY, DDR667_FREQUENCY, 0},
+ {SR_DIMM0 + SR_DIMM1 + SR_DIMM2, 3, DDR1066_FREQUENCY, DDR800_FREQUENCY, 0},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, 3, DDR800_FREQUENCY, DDR800_FREQUENCY, 0},
+ {SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, 3, DDR667_FREQUENCY, DDR667_FREQUENCY, 0}
+
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor platform specific settings for R DIMM-DDR3 C32 DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsRC32_3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_C32) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->RegDimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsRC32_3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitRC32_3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for R-DDR3 C32 DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsRC32_3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if ((MaxDimmsPerChannel == 1) || (MaxDimmsPerChannel == 2)) {
+ DramTermSize = GET_SIZE_OF (C32RDdr3DramTerm2D);
+ DramTermPtr = C32RDdr3DramTerm2D;
+ } else if (MaxDimmsPerChannel == 3) {
+ DramTermSize = GET_SIZE_OF (C32RDdr3DramTerm3D);
+ DramTermPtr = C32RDdr3DramTerm3D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+ //
+ // Special Cases for certain configs not covered by the table
+ //
+ // SR-SR-SR 1.5v @1066 (Currently only 3DPCH config at 1066)
+ if ((MaxDimmsPerChannel == 3) && (NBPtr->ChannelPtr->Dimms == 3) &&
+ (NBPtr->DCTPtr->Timings.Speed == DDR1066_FREQUENCY)) {
+ NBPtr->PsPtr->DramTerm = 5; //30 Ohms
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for R-DDR3 C32 DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitRC32_3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 *DimmsPerChPtr;
+ UINT8 MaxDimmPerCH;
+ UINT8 FreqLimitSize;
+ UINT16 SpeedLimit;
+ CONST POR_SPEED_LIMIT *FreqLimitPtr;
+ DCT_STRUCT *DCTPtr;
+
+ DCTPtr = NBPtr->DCTPtr;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmPerCH = *DimmsPerChPtr;
+ } else {
+ MaxDimmPerCH = 2;
+ }
+
+ if (MaxDimmPerCH == 4) {
+ DCTPtr->Timings.DimmExclude |= DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_CRITICAL, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_CRITICAL, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ return;
+ } else if (MaxDimmPerCH == 3) {
+ FreqLimitPtr = C32RDdr3PSPorFreqLimit3D;
+ FreqLimitSize = GET_SIZE_OF (C32RDdr3PSPorFreqLimit3D);
+ } else if (MaxDimmPerCH == 2) {
+ FreqLimitPtr = C32RDdr3PSPorFreqLimit2D;
+ FreqLimitSize = GET_SIZE_OF (C32RDdr3PSPorFreqLimit2D);
+ } else {
+ FreqLimitPtr = C32RDdr3PSPorFreqLimit1D;
+ FreqLimitSize = GET_SIZE_OF (C32RDdr3PSPorFreqLimit1D);
+ }
+
+ SpeedLimit = MemPGetPorFreqLimit (NBPtr, FreqLimitSize, FreqLimitPtr);
+
+ if (SpeedLimit != 0) {
+ if (DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ }
+ } else {
+ DCTPtr->Timings.DimmExclude |= DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_CRITICAL, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_CRITICAL, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/C32/mpuc32_3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/C32/mpuc32_3.c
new file mode 100644
index 0000000000..7866eed5f8
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/C32/mpuc32_3.c
@@ -0,0 +1,205 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpuc32_3.c
+ *
+ * Platform specific settings for C32 DDR3 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_C32_MPUC32_3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define AMD_FAMILY_10_C32 AMD_FAMILY_10_HY
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsUC32_3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitUC32_3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY C32UDdr3DramTerm[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor for the platform specific settings for U-DDR3 C32 DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUC32_3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_C32) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsUC32_3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitUC32_3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR3 C32 DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsUC32_3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (C32UDdr3DramTerm), C32UDdr3DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for SO-DDR3 C32
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitUC32_3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT16 MaxSpeed;
+ //
+ // For 2/2 or 2/3 DPCH where one is a DR, Max Speed is 1066
+ //
+ if ( (NBPtr->ChannelPtr->Dimms >= 2) && ((NBPtr->ChannelPtr->DimmDrPresent & 0x07) != 0) ) {
+ MaxSpeed = DDR1066_FREQUENCY;
+ } else {
+ //
+ // Highest POR supported speed for Unbuffered dimm is 1333
+ //
+ MaxSpeed = DDR1333_FREQUENCY;
+ }
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > MaxSpeed) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = MaxSpeed;
+ } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) {
+ // Unbuffered DDR3 at 333MHz is not supported
+ NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_ERROR, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpsda2.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpsda2.c
new file mode 100644
index 0000000000..c69a526084
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpsda2.c
@@ -0,0 +1,161 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpsda2.c
+ *
+ * Platform specific settings for DA DDR2 SO-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support S1g3 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "PlatformMemoryConfiguration.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_DA_MPSDA2_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsSDA2 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DaSDdr2DramTerm[] = {
+ {DDR533 + DDR667 + DDR800, ONE_DIMM, ANY_NUM, 2, 0, 0},
+ {DDR533 + DDR667, TWO_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR800, TWO_DIMM, ANY_NUM, 3, 0, 0}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor the platform specific settings for SO-DIMM DA DDR2
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsSDA2 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & (AMD_FAMILY_10_DA | AMD_FAMILY_10_BL)) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR2_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->SODimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsSDA2;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitDef;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for SO-DIMM DA DDR2
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsSDA2 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (DaSDdr2DramTerm), DaSDdr2DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpsda3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpsda3.c
new file mode 100644
index 0000000000..981b8cd92d
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpsda3.c
@@ -0,0 +1,257 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpsda3.c
+ *
+ * Platform specific settings for DA DDR3 SO-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_DA_MPSDA3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsSDA3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitSDA3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DaSDdr3DramTerm1D[] = {
+ {DDR800, ONE_DIMM, NO_DIMM, 2, 0, 0},
+ {DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0}
+};
+
+STATIC CONST DRAM_TERM_ENTRY DaSDdr3DramTerm2D[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1066 + DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor the platform specific settings for SO-DIMM DA DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsSDA3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & (AMD_FAMILY_10_DA | AMD_FAMILY_10_BL)) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->SODimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsSDA3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitSDA3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for SO-DIMM DA DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsSDA3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if (MaxDimmsPerChannel == 1) {
+ DramTermSize = GET_SIZE_OF (DaSDdr3DramTerm1D);
+ DramTermPtr = DaSDdr3DramTerm1D;
+ } else if (MaxDimmsPerChannel == 2) {
+ DramTermSize = GET_SIZE_OF (DaSDdr3DramTerm2D);
+ DramTermPtr = DaSDdr3DramTerm2D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for SO-DDR3 DA
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitSDA3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 *DimmsPerChPtr;
+ UINT8 MaxDimmPerCH;
+ UINT16 SpeedLimit;
+
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmPerCH = *DimmsPerChPtr;
+ } else {
+ MaxDimmPerCH = 2;
+ }
+
+ if (MaxDimmPerCH == 1) {
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ //
+ // Highest POR supported speed for SODimm is 1333
+ //
+ SpeedLimit = DDR1333_FREQUENCY;
+ } else {
+ //
+ // Max LV DDR3 Speed is 1066 for this silicon
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ }
+ } else {
+ //
+ // Highest supported speed in 2DPC configuration is 1066
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ //
+ // VOLT1_35 won't be supported while two DIMMs are populated in a channel
+ //
+ if ((NBPtr->RefPtr->DDR3Voltage == VOLT1_35) &&
+ (NBPtr->ChannelPtr->Dimms == 2)) {
+ NBPtr->RefPtr->DDR3Voltage = VOLT1_5;
+ PutEventLog (AGESA_WARNING, MEM_WARNING_VOLTAGE_1_35_NOT_SUPPORTED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_WARNING, NBPtr->MCTPtr);
+ }
+ }
+
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpuda3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpuda3.c
new file mode 100644
index 0000000000..aad019ab79
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DA/mpuda3.c
@@ -0,0 +1,210 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpuda3.c
+ *
+ * Platform specific settings for DA DDR3 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_DA_MPUDA3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsUDA3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitUDA3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrUDdr3DramTerm[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor for the platform specific settings for U-DDR3 DA DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUDA3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & (AMD_FAMILY_10_DA | AMD_FAMILY_10_BL)) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsUDA3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitUDA3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR3 DA DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsUDA3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (DrUDdr3DramTerm), DrUDdr3DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for U-DDR3 DA
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitUDA3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT16 SpeedLimit;
+
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ //
+ // Highest POR supported speed for Unbuffered dimm is 1333
+ //
+ SpeedLimit = DDR1333_FREQUENCY;
+ } else {
+ //
+ // Max LV DDR3 Speed is 1066 for this silicon
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ }
+
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) {
+ // Unbuffered DDR3 at 333MHz is not supported
+ NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_ERROR, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mprdr2.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mprdr2.c
new file mode 100644
index 0000000000..2b59c8b9ba
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mprdr2.c
@@ -0,0 +1,166 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mprdr2.c
+ *
+ * Platform specific settings for DR DDR2 R-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "PlatformMemoryConfiguration.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_DR_MPRDR2_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsRDr2 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrUDdr2DramTerm[] = {
+ {DDR400 + DDR533 + DDR667, ONE_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR400 + DDR533, TWO_DIMM + THREE_DIMM + FOUR_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR667, TWO_DIMM + THREE_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR667, FOUR_DIMM, ANY_NUM, 3, 0, 0},
+ {DDR800, ONE_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR800, TWO_DIMM + THREE_DIMM + FOUR_DIMM, ANY_NUM, 3, 0, 0},
+ {DDR1066, ONE_DIMM, ANY_NUM, 1, 0, 0}
+};
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor platform specific settings for R DIMM-DDR2 DR DDR2
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsRDr2 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR2_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->RegDimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsRDr2;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitDef;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for R-DDR2 DR DDR2
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsRDr2 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (DrUDdr2DramTerm), DrUDdr2DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mprdr3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mprdr3.c
new file mode 100644
index 0000000000..f26f0c8beb
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mprdr3.c
@@ -0,0 +1,205 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mprdr3.c
+ *
+ * Platform specific settings for DR DDR3 R-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_DR_MPRDR3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsRDr3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrRDdr3DramTerm2D[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1},
+ {DDR800 + DDR1066 + DDR1333, ONE_DIMM, ONE_DIMM, 0, 1, 2},
+ {DDR1600, ONE_DIMM, ONE_DIMM, 0, 1, 1},
+ {DDR800, TWO_DIMM, ONE_DIMM, 5, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, ONE_DIMM, 5, 1, 1},
+ {DDR800, TWO_DIMM, TWO_DIMM, 0, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, TWO_DIMM, 0, 1, 1}
+};
+
+STATIC CONST DRAM_TERM_ENTRY DrRDdr3DramTerm3D[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333 + DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, THREE_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR800 + DDR1066 + DDR1333, ONE_DIMM, ONE_DIMM, 0, 1, 2},
+ {DDR800, TWO_DIMM, ONE_DIMM, 5, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, ONE_DIMM, 5, 1, 1},
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, THREE_DIMM, ONE_DIMM, 3, 1, 2}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor platform specific settings for R DIMM-DDR3 DR DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsRDr3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->RegDimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsRDr3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitDef;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for R-DDR3 DR DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsRDr3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if (MaxDimmsPerChannel == 2) {
+ DramTermSize = GET_SIZE_OF (DrRDdr3DramTerm2D);
+ DramTermPtr = DrRDdr3DramTerm2D;
+ } else if (MaxDimmsPerChannel == 3) {
+ DramTermSize = GET_SIZE_OF (DrRDdr3DramTerm3D);
+ DramTermPtr = DrRDdr3DramTerm3D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpsdr3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpsdr3.c
new file mode 100644
index 0000000000..6de04d9cfd
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpsdr3.c
@@ -0,0 +1,192 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpsdr3.c
+ *
+ * Platform specific settings for DR DDR3 SO-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_DR_MPSDR3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsSDr3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrSDdr3DramTerm1D[] = {
+ {DDR800, ONE_DIMM, NO_DIMM, 2, 0, 0},
+ {DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0}
+};
+
+STATIC CONST DRAM_TERM_ENTRY DrSDdr3DramTerm2D[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1066 + DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor the platform specific settings for SO SIMM-DDR3 DR DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsSDr3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->SODimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsSDr3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitDef;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for S-DDR3 DR DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsSDr3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if (MaxDimmsPerChannel == 1) {
+ DramTermSize = GET_SIZE_OF (DrSDdr3DramTerm1D);
+ DramTermPtr = DrSDdr3DramTerm1D;
+ } else if (MaxDimmsPerChannel == 2) {
+ DramTermSize = GET_SIZE_OF (DrSDdr3DramTerm2D);
+ DramTermPtr = DrSDdr3DramTerm2D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpudr2.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpudr2.c
new file mode 100644
index 0000000000..66fe7d187c
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpudr2.c
@@ -0,0 +1,166 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpudr2.c
+ *
+ * Platform specific settings for DR DDR2 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "PlatformMemoryConfiguration.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_DR_MPUDR2_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsUDr2 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrUDdr2DramTerm[] = {
+ {DDR400 + DDR533 + DDR667, ONE_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR400 + DDR533, TWO_DIMM + THREE_DIMM + FOUR_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR667, TWO_DIMM + THREE_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR667, FOUR_DIMM, ANY_NUM, 3, 0, 0},
+ {DDR800, ONE_DIMM, ANY_NUM, 1, 0, 0},
+ {DDR800, TWO_DIMM + THREE_DIMM + FOUR_DIMM, ANY_NUM, 3, 0, 0},
+ {DDR1066, ONE_DIMM, ANY_NUM, 1, 0, 0}
+};
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor platform specific settings for U DIMM-DDR2 DR DDR2
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUDr2 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR2_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsUDr2;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitDef;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR2 DR DDR2
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsUDr2 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (DrUDdr2DramTerm), DrUDdr2DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpudr3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpudr3.c
new file mode 100644
index 0000000000..1d3acbbb42
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/DR/mpudr3.c
@@ -0,0 +1,161 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpudr3.c
+ *
+ * Platform specific settings for DR DDR3 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "PlatformMemoryConfiguration.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_DR_MPUDR3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsUDr3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrUDdr3DramTerm[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor for the platform specific settings for U-DDR3 DR DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUDr3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsUDr3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitDef;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR3 DR DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsUDr3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (DrUDdr3DramTerm), DrUDdr3DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mprhy3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mprhy3.c
new file mode 100644
index 0000000000..7e4764ced9
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mprhy3.c
@@ -0,0 +1,325 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mprhy3.c
+ *
+ * Platform specific settings for HY DDR3 R-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "GeneralServices.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_HY_MPRHY3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsRHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitRHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*
+ * ODT Settings for 1 Dimm or 2 Dimms Per Channel
+ *
+ * Speeds Supported, # of Dimms, # of QRDimms, DramTerm, QR DramTerm, Dynamic DramTerm
+ */
+STATIC CONST DRAM_TERM_ENTRY HyRDdr3DramTerm2D[] = {
+ {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR667 + DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1},
+ {DDR667 + DDR800 + DDR1066 + DDR1333, ONE_DIMM, ONE_DIMM, 0, 1, 2},
+ {DDR1600, ONE_DIMM, ONE_DIMM, 0, 1, 1},
+ {DDR667 + DDR800, TWO_DIMM, ONE_DIMM, 5, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, ONE_DIMM, 5, 1, 1},
+ {DDR667 + DDR800, TWO_DIMM, TWO_DIMM, 0, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, TWO_DIMM, 0, 1, 1}
+};
+/*
+ * ODT Settings for 3 Dimms Per Channel
+ *
+ * Speeds Supported, # of Dimms, # of QRDimms, DramTerm, QR DramTerm, Dynamic DramTerm
+ */
+STATIC CONST DRAM_TERM_ENTRY HyRDdr3DramTerm3D[] = {
+ {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR667 + DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333 + DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600, THREE_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR667 + DDR800 + DDR1066 + DDR1333, ONE_DIMM, ONE_DIMM, 0, 1, 2},
+ {DDR667 + DDR800, TWO_DIMM, ONE_DIMM, 5, 1, 2},
+ {DDR1066 + DDR1333 + DDR1600, TWO_DIMM, ONE_DIMM, 5, 1, 1},
+ {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600, THREE_DIMM, ONE_DIMM, 3, 1, 2}
+};
+/*
+ * POR Max Frequency supported for specific Dimm configurations for 1 Dimm Per Channel
+ *
+ * Dimm Config, # of Dimms, Max Freq @ 1.5V, Max Freq @ 1.35V, Max Freq @ 1.25
+ */
+STATIC CONST POR_SPEED_LIMIT HyRDdr3PSPorFreqLimit1D[] = {
+ {SR_DIMM0 + DR_DIMM0, 1, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {QR_DIMM0, 1, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0}
+};
+/*
+ * POR Max Frequency supported for specific Dimm configurations for 2 Dimms Per Channel
+ *
+ * Dimm Config, # of Dimms, Max Freq @ 1.5V, Max Freq @ 1.35V, Max Freq @ 1.25
+ */
+STATIC CONST POR_SPEED_LIMIT HyRDdr3PSPorFreqLimit2D[] = {
+ {SR_DIMM1 + DR_DIMM1, 1, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {QR_DIMM1, 1, DDR1333_FREQUENCY, DDR1066_FREQUENCY, 0},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, 2, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {QR_DIMM0 + ANY_DIMM1, 2, DDR1066_FREQUENCY, DDR800_FREQUENCY, 0},
+ {ANY_DIMM0 + QR_DIMM1, 2, DDR1066_FREQUENCY, DDR800_FREQUENCY, 0}
+};
+/*
+ * POR Max Frequency supported for specific Dimm configurations for 3 Dimms Per Channel
+ *
+ * Dimm Config, # of Dimms, Max Freq @ 1.5V, Max Freq @ 1.35V, Max Freq @ 1.25
+ */
+STATIC CONST POR_SPEED_LIMIT HyRDdr3PSPorFreqLimit3D[] = {
+ {SR_DIMM2 + DR_DIMM2, 1, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM2 + DR_DIMM2, 2, DDR1333_FREQUENCY, DDR1333_FREQUENCY, 0},
+ {QR_DIMM1, 1, DDR1066_FREQUENCY, DDR1066_FREQUENCY, 0},
+ {QR_DIMM1 + SR_DIMM2 + DR_DIMM2, 2, DDR800_FREQUENCY, DDR800_FREQUENCY, 0},
+ {SR_DIMM0 + SR_DIMM1 + SR_DIMM2, 3, DDR1066_FREQUENCY, DDR1066_FREQUENCY, 0},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, 3, DDR1066_FREQUENCY, DDR800_FREQUENCY, 0},
+ {SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, 3, DDR800_FREQUENCY, DDR667_FREQUENCY, 0}
+};
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor platform specific settings for R DIMM-DDR3 HY DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsRHy3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_HY) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->RegDimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsRHy3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitRHy3;
+
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for R-DDR3 HY DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsRHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if ((MaxDimmsPerChannel == 1) || (MaxDimmsPerChannel == 2)) {
+ DramTermSize = GET_SIZE_OF (HyRDdr3DramTerm2D);
+ DramTermPtr = HyRDdr3DramTerm2D;
+ } else if (MaxDimmsPerChannel == 3) {
+ DramTermSize = GET_SIZE_OF (HyRDdr3DramTerm3D);
+ DramTermPtr = HyRDdr3DramTerm3D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+ //
+ // Special Cases for certain configs not covered by the table
+ //
+ // 3DPCH Fully populated.
+ if ((MaxDimmsPerChannel == 3) && (NBPtr->ChannelPtr->Dimms == 3)) {
+ NBPtr->PsPtr->DramTerm = 5; //30 Ohms
+ NBPtr->PsPtr->QR_DramTerm = 1; // 60 Ohms
+ }
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for R-DDR3 HY
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitRHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 *DimmsPerChPtr;
+ UINT8 MaxDimmPerCH;
+ UINT8 FreqLimitSize;
+ UINT16 SpeedLimit;
+ CONST POR_SPEED_LIMIT *FreqLimitPtr;
+ DCT_STRUCT *DCTPtr;
+
+ DCTPtr = NBPtr->DCTPtr;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmPerCH = *DimmsPerChPtr;
+ } else {
+ MaxDimmPerCH = 2;
+ }
+
+ if (MaxDimmPerCH == 4) {
+ DCTPtr->Timings.DimmExclude |= DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_CRITICAL, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_CRITICAL, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ return;
+ } else if (MaxDimmPerCH == 3) {
+ FreqLimitPtr = HyRDdr3PSPorFreqLimit3D;
+ FreqLimitSize = GET_SIZE_OF (HyRDdr3PSPorFreqLimit3D);
+ } else if (MaxDimmPerCH == 2) {
+ FreqLimitPtr = HyRDdr3PSPorFreqLimit2D;
+ FreqLimitSize = GET_SIZE_OF (HyRDdr3PSPorFreqLimit2D);
+ } else {
+ FreqLimitPtr = HyRDdr3PSPorFreqLimit1D;
+ FreqLimitSize = GET_SIZE_OF (HyRDdr3PSPorFreqLimit1D);
+ }
+
+ SpeedLimit = MemPGetPorFreqLimit (NBPtr, FreqLimitSize, FreqLimitPtr);
+
+ if (SpeedLimit != 0) {
+ if (DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ }
+ } else {
+ DCTPtr->Timings.DimmExclude |= DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_CRITICAL, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_CRITICAL, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mpshy3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mpshy3.c
new file mode 100644
index 0000000000..2943777363
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mpshy3.c
@@ -0,0 +1,221 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpshy3.c
+ *
+ * Platform specific settings for HY DDR3 SO-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_HY_MPSHY3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsSHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitSHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY HySDdr3DramTerm1D[] = {
+ {DDR800, ONE_DIMM, NO_DIMM, 2, 0, 0},
+ {DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0}
+};
+
+STATIC CONST DRAM_TERM_ENTRY HySDdr3DramTerm2D[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1066 + DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor the platform specific settings for SO SIMM-DDR3 HY DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsSHy3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_HY) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->SODimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsSHy3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitSHy3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for S-DDR3 HY DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsSHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if (MaxDimmsPerChannel == 1) {
+ DramTermSize = GET_SIZE_OF (HySDdr3DramTerm1D);
+ DramTermPtr = HySDdr3DramTerm1D;
+ } else if (MaxDimmsPerChannel == 2) {
+ DramTermSize = GET_SIZE_OF (HySDdr3DramTerm2D);
+ DramTermPtr = HySDdr3DramTerm2D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for SO-DDR3 HY
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitSHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT16 MaxSpeed;
+ //
+ // Highest POR supported speed for SODimm is 1333
+ //
+ MaxSpeed = DDR1333_FREQUENCY;
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > MaxSpeed) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = MaxSpeed;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mpuhy3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mpuhy3.c
new file mode 100644
index 0000000000..344b04b83a
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/HY/mpuhy3.c
@@ -0,0 +1,199 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpuhy3.c
+ *
+ * Platform specific settings for HY DDR3 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_HY_MPUHY3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsUhy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitUHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY HyUDdr3DramTerm[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor for the platform specific settings for U-DDR3 HY DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUHy3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_HY) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsUhy3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitUHy3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR3 HY DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsUhy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (HyUDdr3DramTerm), HyUDdr3DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for U-DDR3 HY
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitUHy3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT16 MaxSpeed;
+ //
+ // Highest POR supported speed for Unbuffered dimm is 1333
+ //
+ MaxSpeed = DDR1333_FREQUENCY;
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > MaxSpeed) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = MaxSpeed;
+ } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) {
+ // Unbuffered DDR3 at 333MHz is not supported
+ NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_ERROR, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/NI/mpsNi3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/NI/mpsNi3.c
new file mode 100644
index 0000000000..c6a8e2384c
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/NI/mpsNi3.c
@@ -0,0 +1,257 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpsNi3.c
+ *
+ * Platform specific settings for Ni DDR3 SO-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_NI_MPSNI3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsSNi3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitSNi3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY NiSDdr3DramTerm1D[] = {
+ {DDR800, ONE_DIMM, NO_DIMM, 2, 0, 0},
+ {DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0}
+};
+
+STATIC CONST DRAM_TERM_ENTRY NiSDdr3DramTerm2D[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1066 + DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor the platform specific settings for SO-DIMM Ni DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsSNi3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & (AMD_FAMILY_10_DA | AMD_FAMILY_10_BL)) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->SODimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsSNi3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitSNi3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for SO-DIMM Ni DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsSNi3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if (MaxDimmsPerChannel == 1) {
+ DramTermSize = GET_SIZE_OF (NiSDdr3DramTerm1D);
+ DramTermPtr = NiSDdr3DramTerm1D;
+ } else if (MaxDimmsPerChannel == 2) {
+ DramTermSize = GET_SIZE_OF (NiSDdr3DramTerm2D);
+ DramTermPtr = NiSDdr3DramTerm2D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for SO-DDR3 Ni
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitSNi3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 *DimmsPerChPtr;
+ UINT8 MaxDimmPerCH;
+ UINT16 SpeedLimit;
+
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmPerCH = *DimmsPerChPtr;
+ } else {
+ MaxDimmPerCH = 2;
+ }
+
+ if (MaxDimmPerCH == 1) {
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ //
+ // Highest POR supported speed for SODimm is 1333
+ //
+ SpeedLimit = DDR1333_FREQUENCY;
+ } else {
+ //
+ // Max LV DDR3 Speed is 1066 for this silicon
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ }
+ } else {
+ //
+ // Highest supported speed in 2DPC configuration is 1066
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ //
+ // VOLT1_35 won't be supported while two DIMMs are populated in a channel
+ //
+ if ((NBPtr->RefPtr->DDR3Voltage == VOLT1_35) &&
+ (NBPtr->ChannelPtr->Dimms == 2)) {
+ NBPtr->RefPtr->DDR3Voltage = VOLT1_5;
+ PutEventLog (AGESA_WARNING, MEM_WARNING_VOLTAGE_1_35_NOT_SUPPORTED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_WARNING, NBPtr->MCTPtr);
+ }
+ }
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/NI/mpuNi3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/NI/mpuNi3.c
new file mode 100644
index 0000000000..c922816d7e
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/NI/mpuNi3.c
@@ -0,0 +1,235 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpuNi3.c
+ *
+ * Platform specific settings for Ni DDR3 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_NI_MPUNI3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsUNi3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitUNi3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrUDdr3DramTerm[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor for the platform specific settings for U-DDR3 Ni DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUNi3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & (AMD_FAMILY_10_DA | AMD_FAMILY_10_BL)) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsUNi3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitUNi3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR3 Ni DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsUNi3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (DrUDdr3DramTerm), DrUDdr3DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for U-DDR3 Ni
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitUNi3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 *DimmsPerChPtr;
+ UINT8 MaxDimmPerCH;
+ UINT16 SpeedLimit;
+
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmPerCH = *DimmsPerChPtr;
+ } else {
+ MaxDimmPerCH = 2;
+ }
+
+ if (MaxDimmPerCH == 1) {
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ //
+ // Highest POR supported speed for Unbuffered dimm is 1333
+ //
+ SpeedLimit = DDR1333_FREQUENCY;
+ } else {
+ //
+ // Max LV DDR3 Speed is 1066 for this silicon
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ }
+ } else {
+ //
+ // Highest supported speed in 2DPC configuration is 1066
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ //
+ // VOLT1_35 won't be supported while two DIMMs are populated in a channel
+ //
+ if ((NBPtr->RefPtr->DDR3Voltage == VOLT1_35) &&
+ (NBPtr->ChannelPtr->Dimms == 2)) {
+ NBPtr->RefPtr->DDR3Voltage = VOLT1_5;
+ PutEventLog (AGESA_WARNING, MEM_WARNING_VOLTAGE_1_35_NOT_SUPPORTED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_WARNING, NBPtr->MCTPtr);
+ }
+ }
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) {
+ // Unbuffered DDR3 at 333MHz is not supported
+ NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_ERROR, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/ON/mpson3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/ON/mpson3.c
new file mode 100644
index 0000000000..4aa2969d83
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/ON/mpson3.c
@@ -0,0 +1,181 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpson3.c
+ *
+ * Platform specific settings for ON DDR3 SO-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps/ON)
+ * @e \$Revision: 38634 $ @e \$Date: 2010-09-27 21:39:01 +0800 (Mon, 27 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Filecode.h"
+#define FILECODE PROC_MEM_PS_ON_MPSON3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY OnSoDdr3DramTerm[] = {
+ {DDR800 + DDR1066, ONE_DIMM, NO_DIMM, 2, 0, 0},
+ {DDR1333, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1066 + DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2}
+};
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsSON3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitSON3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor the platform specific settings for SO SIMM-DDR3 ON DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsSON3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_14_ON) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->SODimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsSON3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitSON3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for S-DDR3 ON DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsSON3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (OnSoDdr3DramTerm), OnSoDdr3DramTerm)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for Sodimm DDR3 of ON
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+
+VOID
+STATIC
+MemPGetPORFreqLimitSON3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if ((NBPtr->DCTPtr->Timings.TargetSpeed == DDR1333_FREQUENCY) && (MemNGetBitFieldNb (NBPtr, BFFixedErrataSkipPorFreqCap) == 0)) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = DDR1066_FREQUENCY;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/ON/mpuon3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/ON/mpuon3.c
new file mode 100644
index 0000000000..6e62cc0f08
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/ON/mpuon3.c
@@ -0,0 +1,182 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpuon3.c
+ *
+ * Platform specific settings for ON DDR3 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps/ON)
+ * @e \$Revision: 38634 $ @e \$Date: 2010-09-27 21:39:01 +0800 (Mon, 27 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+
+#include "AGESA.h"
+#include "Ids.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "PlatformMemoryConfiguration.h"
+#include "ma.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "Filecode.h"
+#define FILECODE PROC_MEM_PS_ON_MPUON3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsUON3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitUON3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+STATIC CONST DRAM_TERM_ENTRY OnUDdr3DramTerm[] = {
+ {DDR800 + DDR1066, ONE_DIMM, NO_DIMM, 2, 0, 0},
+ {DDR1333, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2}
+};
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor for the platform specific settings for U-DDR3 ON DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUON3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_14_ON) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+ PsPtr->MemPDoPs = MemPDoPsUON3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitUON3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR3 ON DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsUON3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (OnUDdr3DramTerm), OnUDdr3DramTerm)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for U-DDR3 of ON
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+
+VOID
+STATIC
+MemPGetPORFreqLimitUON3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if ((NBPtr->DCTPtr->Timings.TargetSpeed == DDR1333_FREQUENCY) && (MemNGetBitFieldNb (NBPtr, BFFixedErrataSkipPorFreqCap) == 0)) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = DDR1066_FREQUENCY;
+ }
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/PH/mpsph3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/PH/mpsph3.c
new file mode 100644
index 0000000000..755abf54e4
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/PH/mpsph3.c
@@ -0,0 +1,257 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpsPh3.c
+ *
+ * Platform specific settings for Ph DDR3 SO-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_PH_MPSPH3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsSPh3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitSPh3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY PhSDdr3DramTerm1D[] = {
+ {DDR800, ONE_DIMM, NO_DIMM, 2, 0, 0},
+ {DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0}
+};
+
+STATIC CONST DRAM_TERM_ENTRY PhSDdr3DramTerm2D[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1066 + DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor the platform specific settings for SO-DIMM Ph DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsSPh3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_PH) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->SODimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsSPh3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitSPh3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for SO-DIMM Ph DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsSPh3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if (MaxDimmsPerChannel == 1) {
+ DramTermSize = GET_SIZE_OF (PhSDdr3DramTerm1D);
+ DramTermPtr = PhSDdr3DramTerm1D;
+ } else if (MaxDimmsPerChannel == 2) {
+ DramTermSize = GET_SIZE_OF (PhSDdr3DramTerm2D);
+ DramTermPtr = PhSDdr3DramTerm2D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for SO-DDR3 Ph
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitSPh3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 *DimmsPerChPtr;
+ UINT8 MaxDimmPerCH;
+ UINT16 SpeedLimit;
+
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmPerCH = *DimmsPerChPtr;
+ } else {
+ MaxDimmPerCH = 2;
+ }
+
+ if (MaxDimmPerCH == 1) {
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ //
+ // Highest POR supported speed for SODimm is 1333
+ //
+ SpeedLimit = DDR1333_FREQUENCY;
+ } else {
+ //
+ // Max LV DDR3 Speed is 1066 for this silicon
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ }
+ } else {
+ //
+ // Highest supported speed in 2DPC configuration is 1066
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ //
+ // VOLT1_35 won't be supported while two DIMMs are populated in a channel
+ //
+ if ((NBPtr->RefPtr->DDR3Voltage == VOLT1_35) &&
+ (NBPtr->ChannelPtr->Dimms == 2)) {
+ NBPtr->RefPtr->DDR3Voltage = VOLT1_5;
+ PutEventLog (AGESA_WARNING, MEM_WARNING_VOLTAGE_1_35_NOT_SUPPORTED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_WARNING, NBPtr->MCTPtr);
+ }
+ }
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/PH/mpuph3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/PH/mpuph3.c
new file mode 100644
index 0000000000..bcbff946a6
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/PH/mpuph3.c
@@ -0,0 +1,211 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpuPh3.c
+ *
+ * Platform specific settings for Ph DDR3 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_PH_MPUPH3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsUPh3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitUPh3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrUDdr3DramTerm[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor for the platform specific settings for U-DDR3 Ph DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUPh3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_PH) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsUPh3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitUPh3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR3 Ph DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsUPh3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (DrUDdr3DramTerm), DrUDdr3DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for U-DDR3 Ph
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitUPh3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT16 SpeedLimit;
+
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ //
+ // Highest POR supported speed for Unbuffered dimm is 1333
+ //
+ SpeedLimit = DDR1333_FREQUENCY;
+ } else {
+ //
+ // Max LV DDR3 Speed is 1066 for this silicon
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ }
+
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) {
+ // Unbuffered DDR3 at 333MHz is not supported
+ NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_ERROR, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/RB/mpsRb3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/RB/mpsRb3.c
new file mode 100644
index 0000000000..2e1ffdcb83
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/RB/mpsRb3.c
@@ -0,0 +1,257 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpsRb3.c
+ *
+ * Platform specific settings for RB DDR3 SO-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_RB_MPSRB3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsSRb3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitSRb3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY RbSDdr3DramTerm1D[] = {
+ {DDR800, ONE_DIMM, NO_DIMM, 2, 0, 0},
+ {DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0}
+};
+
+STATIC CONST DRAM_TERM_ENTRY RbSDdr3DramTerm2D[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1066 + DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor the platform specific settings for SO-DIMM RB DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsSRb3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->SODimmPresent != ChannelPtr->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsSRb3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitSRb3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for SO-DIMM RB DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsSRb3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ CONST DRAM_TERM_ENTRY *DramTermPtr;
+ UINT8 MaxDimmsPerChannel;
+ UINT8 *DimmsPerChPtr;
+ UINT8 DramTermSize;
+
+ DramTermSize = 0;
+ DramTermPtr = NULL;
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmsPerChannel = *DimmsPerChPtr;
+ } else {
+ MaxDimmsPerChannel = 2;
+ }
+
+ if (MaxDimmsPerChannel == 1) {
+ DramTermSize = GET_SIZE_OF (RbSDdr3DramTerm1D);
+ DramTermPtr = RbSDdr3DramTerm1D;
+ } else if (MaxDimmsPerChannel == 2) {
+ DramTermSize = GET_SIZE_OF (RbSDdr3DramTerm2D);
+ DramTermPtr = RbSDdr3DramTerm2D;
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (!MemPGetDramTerm (NBPtr, DramTermSize, DramTermPtr)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for SO-DDR3 RB
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitSRb3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 *DimmsPerChPtr;
+ UINT8 MaxDimmPerCH;
+ UINT16 SpeedLimit;
+
+ DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmPerCH = *DimmsPerChPtr;
+ } else {
+ MaxDimmPerCH = 2;
+ }
+
+ if (MaxDimmPerCH == 1) {
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ //
+ // Highest POR supported speed for SODimm is 1333
+ //
+ SpeedLimit = DDR1333_FREQUENCY;
+ } else {
+ //
+ // Max LV DDR3 Speed is 1066 for this silicon
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ }
+ } else {
+ //
+ // Highest supported speed in 2DPC configuration is 1066
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ //
+ // VOLT1_35 won't be supported while two DIMMs are populated in a channel
+ //
+ if ((NBPtr->RefPtr->DDR3Voltage == VOLT1_35) &&
+ (NBPtr->ChannelPtr->Dimms == 2)) {
+ NBPtr->RefPtr->DDR3Voltage = VOLT1_5;
+ PutEventLog (AGESA_WARNING, MEM_WARNING_VOLTAGE_1_35_NOT_SUPPORTED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_WARNING, NBPtr->MCTPtr);
+ }
+ }
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/RB/mpuRb3.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/RB/mpuRb3.c
new file mode 100644
index 0000000000..ebe4f2518d
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/RB/mpuRb3.c
@@ -0,0 +1,211 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpuRb3.c
+ *
+ * Platform specific settings for RB DDR3 U-DIMM system
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/* This file contains routine that add platform specific support L1 */
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "mport.h"
+#include "ma.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mp.h"
+#include "mu.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_RB_MPURB3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPDoPsURb3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemPGetPORFreqLimitURb3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+STATIC CONST DRAM_TERM_ENTRY DrUDdr3DramTerm[] = {
+ {DDR800 + DDR1066 + DDR1333 + DDR1600, ONE_DIMM, NO_DIMM, 1, 0, 0},
+ {DDR800 + DDR1066, TWO_DIMM, NO_DIMM, 3, 0, 2},
+ {DDR1333, TWO_DIMM, NO_DIMM, 5, 0, 2},
+ {DDR1600, TWO_DIMM, NO_DIMM, 5, 0, 1}
+};
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the constructor for the platform specific settings for U-DDR3 RB DDR3
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in,out] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in,out] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_SUCCESS
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsURb3 (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ ASSERT (MemPtr != 0);
+ ASSERT (ChannelPtr != 0);
+
+ if ((ChannelPtr->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (ChannelPtr->TechType != DDR3_TECHNOLOGY) {
+ return AGESA_UNSUPPORTED;
+ }
+ if ((ChannelPtr->RegDimmPresent != 0) || (ChannelPtr->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ PsPtr->MemPDoPs = MemPDoPsURb3;
+ PsPtr->MemPGetPORFreqLimit = MemPGetPORFreqLimitURb3;
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for U-DDR3 RB DDR3
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ * @return TRUE - Find settings for corresponding platform and dimm population.
+ * @return FALSE - Fail to find settings for corresponding platform and dimm population.
+ *
+ */
+
+BOOLEAN
+STATIC
+MemPDoPsURb3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ if (!MemPGetDramTerm (NBPtr, GET_SIZE_OF (DrUDdr3DramTerm), DrUDdr3DramTerm)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function gets the POR speed limit for U-DDR3 RB
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ *
+ */
+VOID
+STATIC
+MemPGetPORFreqLimitURb3 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT16 SpeedLimit;
+
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ //
+ // Highest POR supported speed for Unbuffered dimm is 1333
+ //
+ SpeedLimit = DDR1333_FREQUENCY;
+ } else {
+ //
+ // Max LV DDR3 Speed is 1066 for this silicon
+ //
+ SpeedLimit = DDR1066_FREQUENCY;
+ }
+
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit;
+ } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) {
+ // Unbuffered DDR3 at 333MHz is not supported
+ NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid;
+ PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_ERROR, NBPtr->MCTPtr);
+ // Change target speed to highest value so it won't affect other channels when leveling frequency across the node.
+ NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mp.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mp.c
new file mode 100644
index 0000000000..6e4e77a723
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mp.c
@@ -0,0 +1,510 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mp.c
+ *
+ * Common platform specific configuration.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_MP_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+STATIC
+MemPPSCGen (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+extern MEM_PSC_FLOW_BLOCK* memPlatSpecFlowArray[];
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is the default return function of the Platform Specific block. The function always
+ * returns AGESA_UNSUPPORTED
+ *
+ * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE
+ * @param[in] *ChannelPtr Pointer to CH_DEF_STRUCT
+ * @param[in] *PsPtr Pointer to MEM_PS_BLOCK
+ *
+ * @return AGESA_UNSUPPORTED AGESA status indicating that default is unsupported
+ *
+ */
+
+AGESA_STATUS
+MemPConstructPsUDef (
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN OUT CH_DEF_STRUCT *ChannelPtr,
+ IN OUT MEM_PS_BLOCK *PsPtr
+ )
+{
+ return AGESA_UNSUPPORTED;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function will set the DramTerm and DramTermDyn in the structure of a channel.
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ * @param[in] ArraySize Size of the array of DramTerm
+ * @param[in] *DramTermPtr Address the array of DramTerm
+ *
+ * @return TRUE - Find DramTerm and DramTermDyn for corresponding platform and dimm population.
+ * @return FALSE - Fail to find DramTerm and DramTermDyn for corresponding platform and dimm population.
+ *
+ */
+BOOLEAN
+MemPGetDramTerm (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 ArraySize,
+ IN CONST DRAM_TERM_ENTRY *DramTermPtr
+ )
+{
+ UINT8 Dimms;
+ UINT8 QR_Dimms;
+ UINT8 i;
+ Dimms = NBPtr->ChannelPtr->Dimms;
+ QR_Dimms = 0;
+ for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i ++) {
+ if (((NBPtr->ChannelPtr->DimmQrPresent & (UINT16) (1 << i)) != 0) && (i < 2)) {
+ QR_Dimms ++;
+ }
+ }
+
+ for (i = 0; i < ArraySize; i ++) {
+ if ((DramTermPtr[i].Speed & ((UINT32) 1 << (NBPtr->DCTPtr->Timings.Speed / 66))) != 0) {
+ if ((((UINT8) (1 << (Dimms - 1)) & DramTermPtr[i].Dimms) != 0) || (DramTermPtr[i].Dimms == ANY_NUM)) {
+ if (((QR_Dimms == 0) && (DramTermPtr[i].QR_Dimms == NO_DIMM)) ||
+ ((QR_Dimms > 0) && (((UINT8) (1 << (QR_Dimms - 1)) & DramTermPtr[i].QR_Dimms) != 0)) ||
+ (DramTermPtr[i].QR_Dimms == ANY_NUM)) {
+ NBPtr->PsPtr->DramTerm = DramTermPtr[i].DramTerm;
+ NBPtr->PsPtr->QR_DramTerm = DramTermPtr[i].QR_DramTerm;
+ NBPtr->PsPtr->DynamicDramTerm = DramTermPtr[i].DynamicDramTerm;
+ break;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets the highest POR supported speed.
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ * @param[in] FreqLimitSize Size of the array of Frequency Limit
+ * @param[in] *FreqLimitPtr Address the array of Frequency Limit
+ *
+ * @return UINT8 - frequency limit
+ *
+ */
+UINT16
+MemPGetPorFreqLimit (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 FreqLimitSize,
+ IN CONST POR_SPEED_LIMIT *FreqLimitPtr
+ )
+{
+ UINT8 i;
+ UINT8 j;
+ UINT8 DimmTpMatch;
+ UINT16 SpeedLimit;
+ UINT16 DIMMRankType;
+ UINT16 _DIMMRankType;
+
+ SpeedLimit = 0;
+ DIMMRankType = MemAGetPsRankType (NBPtr->ChannelPtr);
+ for (i = 0; i < FreqLimitSize; i++, FreqLimitPtr++) {
+ if (NBPtr->ChannelPtr->Dimms != FreqLimitPtr->Dimms) {
+ continue;
+ }
+ DimmTpMatch = 0;
+ _DIMMRankType = DIMMRankType & FreqLimitPtr->DIMMRankType;
+ for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j ++) {
+ if ((_DIMMRankType & (UINT16) 0x0F << (j << 2)) != 0) {
+ DimmTpMatch++;
+ }
+ }
+ if (DimmTpMatch == FreqLimitPtr->Dimms) {
+ if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) {
+ SpeedLimit = FreqLimitPtr->SpeedLimit_1_5V;
+ break;
+ } else if (NBPtr->RefPtr->DDR3Voltage == VOLT1_25) {
+ SpeedLimit = FreqLimitPtr->SpeedLimit_1_25V;
+ break;
+ } else {
+ SpeedLimit = FreqLimitPtr->SpeedLimit_1_35V;
+ break;
+ }
+ }
+ }
+
+ return SpeedLimit;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the default function for getting POR speed limit. When a
+ * package does not need to cap the speed, it should use this function to initialize
+ * the corresponding function pointer.
+ *
+ * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK
+ *
+ */
+VOID
+MemPGetPORFreqLimitDef (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets platform specific configuration such as Max Freq., Slow Mode, Dram Term,
+ * and so on.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return TRUE - Successfully execute platform specific configuration flow.
+ * @return FALSE - Fail to execute platform specific configuration flow.
+ *
+ */
+BOOLEAN
+MemPPSCFlow (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 i;
+
+ i = 0;
+ while (memPlatSpecFlowArray[i] != NULL) {
+ if ((memPlatSpecFlowArray[i])->DramTerm (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memPlatSpecFlowArray[i])->ODTPattern (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memPlatSpecFlowArray[i])->SAO (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memPlatSpecFlowArray[i])->MR0WrCL (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memPlatSpecFlowArray[i])->RC2IBT (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memPlatSpecFlowArray[i])->RC10OpSpeed (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memPlatSpecFlowArray[i])->LRIBT (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memPlatSpecFlowArray[i])->LRNPR (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memPlatSpecFlowArray[i])->LRNLR (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ if (MemPPSCGen (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+ return FALSE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function constructs the rank type map of Dimm0, Dimm1, Dimm2. Also it counts the number
+ * of dimm in the table.
+ *
+ * @param[in] Dimm0 Rank type of Dimm0
+ * @param[in] Dimm1 Rank type of Dimm1
+ * @param[in] Dimm2 Rank type of Dimm2
+ * @param[in, out] *RankTypeInTable Pointer to RankTypeInTable variable
+ *
+ *
+ */
+VOID
+MemPConstructRankTypeMap (
+ IN UINT16 Dimm0,
+ IN UINT16 Dimm1,
+ IN UINT16 Dimm2,
+ IN OUT UINT16 *RankTypeInTable
+ )
+{
+ UINT8 i;
+ UINT16 RT;
+ UINT8 BitShift;
+
+ *RankTypeInTable = 0;
+ RT = 0;
+ BitShift = 0;
+
+ for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) {
+ switch (i) {
+ case 0:
+ RT = (Dimm0 == 0) ? NP : Dimm0;
+ BitShift = 0;
+ break;
+ case 1:
+ RT = (Dimm1 == 0) ? NP : Dimm1;
+ BitShift = 4;
+ break;
+ case 2:
+ RT = (Dimm2 == 0) ? NP : Dimm2;
+ BitShift = 8;
+ break;
+ default:
+ // dimm3 is not used, fills nibble3 with "NP"
+ RT = NP;
+ BitShift = 12;
+ }
+ *RankTypeInTable |= RT << BitShift;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ * MemPIsIdSupported
+ * This function matches the CPU_LOGICAL_ID and PackageType with certain criteria to
+ * determine if it is supported by this NB type.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] LogicalId - CPU_LOGICAL_ID
+ * @param[in] PackageType - Package Type
+ *
+ * @return TRUE - NB type is matched !
+ * @return FALSE - NB type is not matched !
+ *
+ */
+BOOLEAN
+MemPIsIdSupported (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID LogicalId,
+ IN UINT8 PackageType
+ )
+{
+ CPUID_DATA CpuId;
+ UINT8 PkgType;
+
+ LibAmdCpuidRead (AMD_CPUID_FMF, &CpuId, &(NBPtr->MemPtr->StdHeader));
+ PkgType = (UINT8) (CpuId.EBX_Reg >> 28) & 0xF; // bit 31:28
+
+ if (((NBPtr->MCTPtr->LogicalCpuid.Family & LogicalId.Family) != 0)
+ && ((NBPtr->MCTPtr->LogicalCpuid.Revision & LogicalId.Revision) != 0)) {
+ if ((PackageType == PT_DONT_CARE) || (PackageType == PkgType)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function returns the rank type map of a channel.
+ *
+ * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT
+ *
+ * @return UINT16 - The map of rank type.
+ *
+ */
+UINT16
+MemPGetPsRankType (
+ IN CH_DEF_STRUCT *CurrentChannel
+ )
+{
+ UINT8 i;
+ UINT16 DIMMRankType;
+
+ DIMMRankType = 0;
+ for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) {
+ if ((CurrentChannel->DimmQrPresent & (UINT8) 1 << i) != 0) {
+ if (i < 2) {
+ DIMMRankType |= (UINT16) 8 << (i << 2);
+ }
+ } else if ((CurrentChannel->DimmDrPresent & (UINT8) 1 << i) != 0) {
+ DIMMRankType |= (UINT16) 4 << (i << 2);
+ } else if ((CurrentChannel->DimmSRPresent & (UINT8) 1 << i) != 0) {
+ DIMMRankType |= (UINT16) 2 << (i << 2);
+ } else {
+ DIMMRankType |= (UINT16) 1 << (i << 2);
+ }
+ }
+
+ //@todo construct DIMMRankType for LRDIMM
+
+ return DIMMRankType;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function performs the action for the rest of platform specific configuration such as
+ * tri-state stuff
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - No error occurred.
+ * @return FALSE - Error occurred.
+ *
+ */
+BOOLEAN
+STATIC
+MemPPSCGen (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ PSCFG_TYPE PSCType;
+ DIMM_TYPE DimmType;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+
+ PackageType = 0;
+ LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
+ MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
+ NOD = (UINT8) 1 << (MaxDimmPerCh - 1);
+
+ if (CurrentChannel->RegDimmPresent != 0) {
+ DimmType = RDIMM_TYPE;
+ } else if (CurrentChannel->SODimmPresent != 0) {
+ DimmType = SODIMM_TYPE;
+ //@todo LRDIMM
+ //} else if (CurrentChannel->LrDimmPresent) {
+ // DimmType = LRDIMM_TYPE;
+ } else {
+ DimmType = UDIMM_TYPE;
+ }
+
+ for (PSCType = PSCFG_GEN_START + 1; PSCType < PSCFG_GEN_END; PSCType++) {
+ i = 0;
+ while (EntryOfTables->TblEntryOfGen[i] != NULL) {
+ if ((EntryOfTables->TblEntryOfGen[i])->Header.PSCType == PSCType) {
+ if (((EntryOfTables->TblEntryOfGen[i])->Header.DimmType & DimmType) != 0) {
+ if (((EntryOfTables->TblEntryOfGen[i])->Header.NumOfDimm & NOD) != 0) {
+ //
+ // Determine if this is the expected NB Type
+ //
+ LogicalCpuid = (EntryOfTables->TblEntryOfGen[i])->Header.LogicalCpuid;
+ PackageType = (EntryOfTables->TblEntryOfGen[i])->Header.PackageType;
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ break;
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ // Check whether no table entry is found.
+ if (EntryOfTables->TblEntryOfGen[i] == NULL) {
+ return FALSE;
+ }
+
+ // Perform the action for specific PSCType.
+ if (PSCType == PSCFG_CLKDIS) {
+ CurrentChannel->MemClkDisMap = (UINT8 *) (EntryOfTables->TblEntryOfGen[i])->TBLPtr;
+ } else if (PSCType == PSCFG_CKETRI) {
+ CurrentChannel->CKETriMap = (UINT8 *) (EntryOfTables->TblEntryOfGen[i])->TBLPtr;
+ } else if (PSCType == PSCFG_ODTTRI) {
+ CurrentChannel->ODTTriMap = (UINT8 *) (EntryOfTables->TblEntryOfGen[i])->TBLPtr;
+ } else if (PSCType == PSCFG_CSTRI) {
+ CurrentChannel->ChipSelTriMap = (UINT8 *) (EntryOfTables->TblEntryOfGen[i])->TBLPtr;
+ }
+ }
+
+ CurrentChannel->DctEccDqsLike = 0x0403;
+ CurrentChannel->DctEccDqsScale = 0x70;
+
+ return TRUE;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplribt.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplribt.c
new file mode 100644
index 0000000000..c86ba86814
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplribt.c
@@ -0,0 +1,190 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mplribt.c
+ *
+ * A sub-engine which extracts F0RC8, F1RC0, F1RC1 and F1RC2 value for LRDIMM configuration.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 37655 $ @e \$Date: 2010-09-09 11:15:05 +0800 (Thu, 09 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_MPLRIBT_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts LRDIMM F0RC8, F1RC0, F1RC1 and F1RC2 value from a input
+ * table and stores extracted value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Succeed in extracting the table value
+ * @return FALSE - Fail to extract the table value
+ *
+ */
+BOOLEAN
+MemPGetLRIBT (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 TableSize;
+ UINT32 CurDDRrate;
+ UINT8 DDR3Voltage;
+ UINT16 RankTypeOfPopulatedDimm;
+ UINT16 RankTypeInTable;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ PSCFG_L_IBT_ENTRY *TblPtr;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+
+ //@todo LRDIMM
+ //if (CurrentChannel->LrDimmPresent == 0) {
+ // return TRUE;
+ //}
+
+ TblPtr = NULL;
+ TableSize = 0;
+ PackageType = 0;
+ LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
+ MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
+ NOD = (UINT8) 1 << (MaxDimmPerCh - 1);
+
+ i = 0;
+ // Obtain table pointer, table size, Logical Cpuid and PSC type according to NB type and package type.
+ while (EntryOfTables->TblEntryOfLRIBT[i] != NULL) {
+ if (((EntryOfTables->TblEntryOfLRIBT[i])->Header.NumOfDimm & NOD) != 0) {
+ LogicalCpuid = (EntryOfTables->TblEntryOfLRIBT[i])->Header.LogicalCpuid;
+ PackageType = (EntryOfTables->TblEntryOfLRIBT[i])->Header.PackageType;
+ //
+ // Determine if this is the expected NB Type
+ //
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ TblPtr = (PSCFG_L_IBT_ENTRY *) ((EntryOfTables->TblEntryOfLRIBT[i])->TBLPtr);
+ TableSize = (EntryOfTables->TblEntryOfLRIBT[i])->TableSize;
+ break;
+ }
+ }
+ i++;
+ }
+
+ // Check whether no table entry is found.
+ if (EntryOfTables->TblEntryOfLRIBT[i] == NULL) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo LRDIMM IBT table\n");
+ return FALSE;
+ }
+
+ CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66));
+ DDR3Voltage = (UINT8) (1 << (NBPtr->RefPtr->DDR3Voltage));
+ RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel);
+
+ for (i = 0; i < TableSize; i++) {
+ MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if (TblPtr->DimmPerCh == MaxDimmPerCh) {
+ if ((TblPtr->DDRrate & CurDDRrate) != 0) {
+ if ((TblPtr->VDDIO & DDR3Voltage) != 0) {
+ if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) {
+ NBPtr->PsPtr->F0RC8 = (UINT8) TblPtr->F0RC8;
+ NBPtr->PsPtr->F1RC0 = (UINT8) TblPtr->F1RC0;
+ NBPtr->PsPtr->F1RC1 = (UINT8) TblPtr->F1RC1;
+ NBPtr->PsPtr->F1RC2 = (UINT8) TblPtr->F1RC2;
+ break;
+ }
+ }
+ }
+ }
+ TblPtr++;
+ }
+ if (i == TableSize) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo LRDIMM IBT entries\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplrnlr.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplrnlr.c
new file mode 100644
index 0000000000..b2a12b9d2d
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplrnlr.c
@@ -0,0 +1,111 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mplrnlr.c
+ *
+ * A sub-engine which extracts F0RC13[NumLogicalRanks] value for LRDIMM configuration.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_MPLRNLR_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts LRDIMM F0RC13[NumLogicalRanks] value from a input
+ * table and stores extracted value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Succeed in extracting the table value
+ * @return FALSE - Fail to extract the table value
+ *
+ */
+BOOLEAN
+MemPGetLRNLR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ return TRUE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplrnpr.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplrnpr.c
new file mode 100644
index 0000000000..3bea942e79
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mplrnpr.c
@@ -0,0 +1,111 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mplrnpr.c
+ *
+ * A sub-engine which extracts F0RC13[NumPhysicalRanks] value for LRDIMM configuration.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_MPLRNPR_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts LRDIMM F0RC13[NumPhysicalRanks] value from a input
+ * table and stores extracted value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Succeed in extracting the table value
+ * @return FALSE - Fail to extract the table value
+ *
+ */
+BOOLEAN
+MemPGetLRNPR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ return TRUE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpmaxfreq.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpmaxfreq.c
new file mode 100644
index 0000000000..3351364282
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpmaxfreq.c
@@ -0,0 +1,250 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpmaxfreq.c
+ *
+ * A sub-engine which extracts max. frequency limit value.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 37655 $ @e \$Date: 2010-09-09 11:15:05 +0800 (Thu, 09 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_MPMAXFREQ_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+typedef struct {
+ UINT16 DimmPerCh:3;
+ UINT16 Dimms:3;
+ UINT16 SR:3;
+ UINT16 DR:3;
+ UINT16 QR:4;
+} CDNMaxFreq;
+
+typedef struct {
+ UINT16 DimmPerCh:3;
+ UINT16 Dimms:3;
+ UINT16 LR:10;
+} CDNLMaxFreq;
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts the value of max frequency supported from a input table and
+ * compares it with DCTPtr->Timings.TargetSpeed
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Succeed in extracting the table value
+ * @return FALSE - Fail to extract the table value
+ *
+ */
+BOOLEAN
+MemPGetMaxFreqSupported (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 TableSize;
+ PSCFG_TYPE Type;
+ UINT16 CDN;
+ UINT16 MaxFreqSupported;
+ UINT16 *SpeedArray;
+ DIMM_VOLTAGE DDR3Voltage;
+ DIMM_VOLTAGE CurrentVoltage;
+ DIMM_VOLTAGE VoltageHighestFreq;
+ DIMM_TYPE DimmType;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ PSCFG_MAXFREQ_ENTRY *TblPtr;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+
+ Type = PSCFG_MAXFREQ;
+ TblPtr = NULL;
+ TableSize = 0;
+ PackageType = 0;
+ LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
+
+ MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
+ NOD = (UINT8) 1 << (MaxDimmPerCh - 1);
+
+ if (CurrentChannel->RegDimmPresent != 0) {
+ DimmType = RDIMM_TYPE;
+ } else if (CurrentChannel->SODimmPresent != 0) {
+ DimmType = SODIMM_TYPE;
+ //@todo LRDIMM
+ //} else if (CurrentChannel->LrDimmPresent) {
+ // DimmType = LRDIMM_TYPE;
+ } else {
+ DimmType = UDIMM_TYPE;
+ }
+
+ i = 0;
+ // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type.
+ while (EntryOfTables->TblEntryOfMaxFreq[i] != NULL) {
+ if (((EntryOfTables->TblEntryOfMaxFreq[i])->Header.DimmType & DimmType) != 0) {
+ if (((EntryOfTables->TblEntryOfMaxFreq[i])->Header.NumOfDimm & NOD) != 0) {
+ //
+ // Determine if this is the expected NB Type
+ //
+ LogicalCpuid = (EntryOfTables->TblEntryOfMaxFreq[i])->Header.LogicalCpuid;
+ PackageType = (EntryOfTables->TblEntryOfMaxFreq[i])->Header.PackageType;
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ TblPtr = (PSCFG_MAXFREQ_ENTRY *) ((EntryOfTables->TblEntryOfMaxFreq[i])->TBLPtr);
+ TableSize = (EntryOfTables->TblEntryOfMaxFreq[i])->TableSize;
+ Type = (EntryOfTables->TblEntryOfMaxFreq[i])->Header.PSCType;
+ break;
+ }
+ }
+ }
+ i++;
+ }
+
+ // Check whether no table entry is found.
+ if (EntryOfTables->TblEntryOfMaxFreq[i] == NULL) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo MaxFreq table\n");
+ return FALSE;
+ }
+
+ MaxFreqSupported = DDR1866_FREQUENCY;
+ CDN = 0;
+ DDR3Voltage = NBPtr->RefPtr->DDR3Voltage;
+ VoltageHighestFreq = DDR3Voltage;
+
+ // Construct the condition value
+ ((CDNMaxFreq *)&CDN)->DimmPerCh = MaxDimmPerCh;
+ ((CDNMaxFreq *)&CDN)->Dimms = CurrentChannel->Dimms;
+ if (Type == PSCFG_MAXFREQ) {
+ for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) {
+ if ((CurrentChannel->DimmSRPresent & (UINT8) (1 << i)) != 0) {
+ ((CDNMaxFreq *)&CDN)->SR += 1;
+ }
+ if ((CurrentChannel->DimmDrPresent & (UINT16) (1 << i)) != 0) {
+ ((CDNMaxFreq *)&CDN)->DR += 1;
+ }
+ if ((CurrentChannel->DimmQrPresent & (UINT16) (1 << i)) != 0) {
+ ((CDNMaxFreq *)&CDN)->QR += 1;
+ }
+ }
+ } else {
+ ((CDNLMaxFreq *)&CDN)->LR = CurrentChannel->Dimms;
+ }
+
+ for (i = 0; i < TableSize; i++) {
+ if (CDN == ((Type == PSCFG_MAXFREQ) ? TblPtr->MAXFREQ_ENTRY.CDN :
+ ((PSCFG_LR_MAXFREQ_ENTRY *)TblPtr)->LR_MAXFREQ_ENTRY.CDN)) {
+ if (Type == PSCFG_MAXFREQ) {
+ SpeedArray = TblPtr->MAXFREQ_ENTRY.Speed;
+ } else {
+ SpeedArray = ((PSCFG_LR_MAXFREQ_ENTRY *)TblPtr)->LR_MAXFREQ_ENTRY.Speed;
+ }
+ if (NBPtr->SharedPtr->VoltageMap != VDDIO_DETERMINED) {
+ for (CurrentVoltage = VOLT1_5; CurrentVoltage <= VOLT1_25; CurrentVoltage ++) {
+ if (NBPtr->SharedPtr->VoltageMap & (1 << CurrentVoltage)) {
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedArray[CurrentVoltage]) {
+ MaxFreqSupported = SpeedArray[CurrentVoltage];
+ } else {
+ MaxFreqSupported = NBPtr->DCTPtr->Timings.TargetSpeed;
+ }
+ if (NBPtr->MaxFreqVDDIO[CurrentVoltage] > MaxFreqSupported) {
+ NBPtr->MaxFreqVDDIO[CurrentVoltage] = MaxFreqSupported;
+ }
+ } else {
+ NBPtr->MaxFreqVDDIO[CurrentVoltage] = 0;
+ }
+ }
+ }
+ MaxFreqSupported = SpeedArray[DDR3Voltage];
+ break;
+ }
+ TblPtr++;
+ }
+
+ if (NBPtr->DCTPtr->Timings.TargetSpeed > MaxFreqSupported) {
+ NBPtr->DCTPtr->Timings.TargetSpeed = MaxFreqSupported;
+ }
+ return TRUE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpmr0.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpmr0.c
new file mode 100644
index 0000000000..5819a58f22
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpmr0.c
@@ -0,0 +1,179 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpmr0.c
+ *
+ * A sub-engine which extracts MR0[WR] and MR0[CL] value.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 37655 $ @e \$Date: 2010-09-09 11:15:05 +0800 (Thu, 09 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_MPMR0_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts MR0[WR] or MR0[CL] value from a input table and store the
+ * value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Succeed in extracting the table value
+ * @return FALSE - Fail to extract the table value
+ *
+ */
+BOOLEAN
+MemPGetMR0WrCL (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+
+ UINT8 i;
+ UINT8 j;
+ UINT8 p;
+ UINT32 Value32;
+ UINT8 TableSize;
+ PSCFG_TYPE Type;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ PSCFG_MR0CL_ENTRY *TblPtr;
+ PSC_TBL_ENTRY **ptr;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+ TblPtr = NULL;
+ TableSize = 0;
+
+ // Extract MR0[WR] value, then MR0[CL] value
+ for (i = 0; i < 2; i++) {
+ if (i == 0) {
+ ptr = EntryOfTables->TblEntryOfMR0WR;
+ Type = PSCFG_MR0WR;
+ } else {
+ ptr = EntryOfTables->TblEntryOfMR0CL;
+ Type = PSCFG_MR0CL;
+ }
+
+ p = 0;
+ // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type.
+ while (ptr[p] != NULL) {
+ //
+ // Determine if this is the expected NB Type
+ //
+ LogicalCpuid = (ptr[p])->Header.LogicalCpuid;
+ PackageType = (ptr[p])->Header.PackageType;
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ TblPtr = (PSCFG_MR0CL_ENTRY *) ((ptr[p])->TBLPtr);
+ TableSize = (ptr[p])->TableSize;
+ break;
+ }
+ p++;
+ }
+
+ // Check whether no table entry is found.
+ if (ptr[p] == NULL) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo MR0 table\n");
+ return FALSE;
+ }
+
+ Value32 = (Type == PSCFG_MR0WR) ? NBPtr->GetBitField (NBPtr, BFTwrDDR3) : NBPtr->GetBitField (NBPtr, BFTcl);
+ for (j = 0; j < TableSize; j++, TblPtr++) {
+ if (Value32 == (UINT32) TblPtr->Timing) {
+ if (Type == PSCFG_MR0WR) {
+ NBPtr->PsPtr->MR0WR = (UINT8) TblPtr->Value;
+ break;
+ } else {
+ NBPtr->PsPtr->MR0CL31 = (UINT8) TblPtr->Value;
+ NBPtr->PsPtr->MR0CL0 = (UINT8) TblPtr->Value1;
+ break;
+ }
+ }
+ }
+ if (j == TableSize) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo MR0 entries\n");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpodtpat.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpodtpat.c
new file mode 100644
index 0000000000..c3c41b64cd
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpodtpat.c
@@ -0,0 +1,189 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpodtpat.c
+ *
+ * A sub-engine which extracts ODT pattern value.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 37655 $ @e \$Date: 2010-09-09 11:15:05 +0800 (Thu, 09 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_MPODTPAT_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts ODT Pattern value from a input table and stores extracted
+ * value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Table values can be extracted per dimm population and ranks type.
+ * @return FALSE - Table values cannot be extracted per dimm population and ranks type.
+ *
+ */
+BOOLEAN
+MemPGetODTPattern (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT16 RankTypeInTable;
+ UINT16 RankTypeOfPopulatedDimm;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 TableSize;
+ DIMM_TYPE DimmType;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ PSCFG_3D_ODTPAT_ENTRY *TblPtr;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+
+ TblPtr = NULL;
+ TableSize = 0;
+ PackageType = 0;
+ LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
+ MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
+ NOD = (UINT8) 1 << (MaxDimmPerCh - 1);
+
+ if (CurrentChannel->RegDimmPresent != 0) {
+ DimmType = RDIMM_TYPE;
+ } else if (CurrentChannel->SODimmPresent != 0) {
+ DimmType = SODIMM_TYPE;
+ //@todo LRDIMM
+ //} else if (CurrentChannel->LrDimmPresent) {
+ // DimmType = LRDIMM_TYPE;
+ } else {
+ DimmType = UDIMM_TYPE;
+ }
+
+ i = 0;
+ // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type.
+ while (EntryOfTables->TblEntryOfODTPattern[i] != NULL) {
+ if (((EntryOfTables->TblEntryOfODTPattern[i])->Header.DimmType & DimmType) != 0) {
+ if (((EntryOfTables->TblEntryOfODTPattern[i])->Header.NumOfDimm & NOD) != 0) {
+ //
+ // Determine if this is the expected NB Type
+ //
+ LogicalCpuid = (EntryOfTables->TblEntryOfODTPattern[i])->Header.LogicalCpuid;
+ PackageType = (EntryOfTables->TblEntryOfODTPattern[i])->Header.PackageType;
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ TblPtr = (PSCFG_3D_ODTPAT_ENTRY *) ((EntryOfTables->TblEntryOfODTPattern[i])->TBLPtr);
+ TableSize = (EntryOfTables->TblEntryOfODTPattern[i])->TableSize;
+ break;
+ }
+ }
+ }
+ i++;
+ }
+
+ // Check whether no table entry is found.
+ if (EntryOfTables->TblEntryOfODTPattern[i] == NULL) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo ODT table\n");
+ return FALSE;
+ }
+
+ RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel); //@todo - LRDIMM ?
+
+ for (i = 0; i < TableSize; i++) {
+ MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) {
+ CurrentChannel->PhyRODTCSHigh = TblPtr->RdODTCSHigh;
+ CurrentChannel->PhyRODTCSLow = TblPtr->RdODTCSLow;
+ CurrentChannel->PhyWODTCSHigh = TblPtr->WrODTCSHigh;
+ CurrentChannel->PhyWODTCSLow = TblPtr->WrODTCSLow;
+
+ //WL ODT
+ NBPtr->FamilySpecificHook[ExtractWLODT] (NBPtr, NBPtr);
+
+ return TRUE;
+ }
+ TblPtr++;
+ }
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo ODT entries\n");
+ return FALSE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprc10opspd.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprc10opspd.c
new file mode 100644
index 0000000000..0c3ed5d615
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprc10opspd.c
@@ -0,0 +1,163 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mprc10opspd.c
+ *
+ * A sub-engine which extracts RC10 operating speed value for RDIMM configuration.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 37655 $ @e \$Date: 2010-09-09 11:15:05 +0800 (Thu, 09 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_MPRC10OPSPD_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts RC10 operating speed value from a input table and stores extracted
+ * value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Succeed in extracting the table value
+ * @return FALSE - Fail to extract the table value
+ *
+ */
+BOOLEAN
+MemPGetRC10OpSpd (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 TableSize;
+ UINT32 CurDDRrate;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ PSCFG_OPSPD_ENTRY *TblPtr;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+
+ if (CurrentChannel->RegDimmPresent == 0) {
+ return TRUE;
+ }
+
+ TblPtr = NULL;
+ TableSize = 0;
+ PackageType = 0;
+ LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
+
+ i = 0;
+ // Obtain table pointer, table size, Logical Cpuid and PSC type according to NB type and package type.
+ while (EntryOfTables->TblEntryOfRC10OpSpeed[i] != NULL) {
+ LogicalCpuid = (EntryOfTables->TblEntryOfRC10OpSpeed[i])->Header.LogicalCpuid;
+ PackageType = (EntryOfTables->TblEntryOfRC10OpSpeed[i])->Header.PackageType;
+ //
+ // Determine if this is the expected NB Type
+ //
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ TblPtr = (PSCFG_OPSPD_ENTRY *) ((EntryOfTables->TblEntryOfRC10OpSpeed[i])->TBLPtr);
+ TableSize = (EntryOfTables->TblEntryOfRC10OpSpeed[i])->TableSize;
+ break;
+ }
+ i++;
+ }
+
+ // Check whether no table entry is found.
+ if (EntryOfTables->TblEntryOfRC10OpSpeed[i] == NULL) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo RC10 Op Speed table\n");
+ return FALSE;
+ }
+
+ CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66));
+
+ for (i = 0; i < TableSize; i++) {
+ if ((TblPtr->DDRrate & CurDDRrate) != 0) {
+ NBPtr->PsPtr->RC10OpSpd = TblPtr->OPSPD;
+ return TRUE;
+ }
+ TblPtr++;
+ }
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo RC10 Op Speed entries\n");
+ return FALSE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprc2ibt.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprc2ibt.c
new file mode 100644
index 0000000000..a1a0c8128b
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprc2ibt.c
@@ -0,0 +1,210 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mprc2ibt.c
+ *
+ * A sub-engine which extracts RC2[IBT] value for RDIMM configuration.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 37655 $ @e \$Date: 2010-09-09 11:15:05 +0800 (Thu, 09 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_MEM_PS_MPRC2IBT_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts RC2[IBT] value from a input table and stores extracted
+ * value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Table values can be extracted for all present dimms/ranks
+ * @return FALSE - Table values cannot be extracted for all present dimms/ranks
+ *
+ */
+BOOLEAN
+MemPGetRC2IBT (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 DimmIndex;
+ UINT8 TableSize;
+ UINT32 CurDDRrate;
+ UINT8 DDR3Voltage;
+ UINT16 RankTypeOfPopulatedDimm;
+ UINT16 RankTypeInTable;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ UINT8 TgtDimmType;
+ UINT8 NumOfReg;
+ PSCFG_MR2IBT_ENTRY *TblPtr;
+ PSCFG_MR2IBT_ENTRY *OrgTblPtr;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+
+ if (CurrentChannel->RegDimmPresent == 0) {
+ return TRUE;
+ }
+
+ TblPtr = NULL;
+ TableSize = 0;
+ PackageType = 0;
+ LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
+ MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
+ NOD = (UINT8) 1 << (MaxDimmPerCh - 1);
+
+ i = 0;
+ // Obtain table pointer, table size, Logical Cpuid and PSC type according to NB type and package type.
+ while (EntryOfTables->TblEntryOfRC2IBT[i] != NULL) {
+ if (((EntryOfTables->TblEntryOfRC2IBT[i])->Header.NumOfDimm & NOD) != 0) {
+ LogicalCpuid = (EntryOfTables->TblEntryOfRC2IBT[i])->Header.LogicalCpuid;
+ PackageType = (EntryOfTables->TblEntryOfRC2IBT[i])->Header.PackageType;
+ //
+ // Determine if this is the expected NB Type
+ //
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ TblPtr = (PSCFG_MR2IBT_ENTRY *) ((EntryOfTables->TblEntryOfRC2IBT[i])->TBLPtr);
+ TableSize = (EntryOfTables->TblEntryOfRC2IBT[i])->TableSize;
+ break;
+ }
+ }
+ i++;
+ }
+
+ // Check whether no table entry is found.
+ if (EntryOfTables->TblEntryOfRC2IBT[i] == NULL) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo RC2 IBT table\n");
+ return FALSE;
+ }
+
+ CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66));
+ DDR3Voltage = (UINT8) (1 << (NBPtr->RefPtr->DDR3Voltage));
+ RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel);
+
+ OrgTblPtr = TblPtr;
+ for (DimmIndex = 0; DimmIndex < MAX_DIMMS_PER_CHANNEL; DimmIndex++) {
+ TblPtr = OrgTblPtr;
+ NumOfReg = NBPtr->PsPtr->NumOfReg[DimmIndex];
+ if ((CurrentChannel->ChDimmValid& (UINT8) (1 << DimmIndex)) != 0) {
+ if ((CurrentChannel->DimmQrPresent & (UINT8) (1 << DimmIndex)) != 0) {
+ TgtDimmType = DIMM_QR;
+ } else if ((CurrentChannel->DimmDrPresent & (UINT8) (1 << DimmIndex)) != 0) {
+ TgtDimmType = DIMM_DR;
+ } else {
+ TgtDimmType = DIMM_SR;
+ }
+
+ for (i = 0; i < TableSize; i++) {
+ MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if (TblPtr->DimmPerCh == MaxDimmPerCh) {
+ if ((TblPtr->DDRrate & CurDDRrate) != 0) {
+ if ((TblPtr->VDDIO & DDR3Voltage) != 0) {
+ if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) {
+ if ((TblPtr->Dimm & TgtDimmType) != 0) {
+ // If TblPtr->NumOfReg == 0x0F, that means the condition will be TRUE regardless of NumRegisters in DIMM
+ if ((TblPtr->NumOfReg == 0xF) || (TblPtr->NumOfReg == NumOfReg)) {
+ CurrentChannel->CtrlWrd02[DimmIndex] = (UINT8) ((TblPtr->IBT & 0x1) << 2);
+ CurrentChannel->CtrlWrd08[DimmIndex] = (UINT8) ((TblPtr->IBT & 0xE) >> 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ TblPtr++;
+ }
+ if (i == TableSize) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo RC2 IBT entries\n");
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprtt.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprtt.c
new file mode 100644
index 0000000000..5c635ad911
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mprtt.c
@@ -0,0 +1,229 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mprtt.c
+ *
+ * A sub-engine which extracts RttNom and RttWr (Dram Term and Dynamic Dram Term) value.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 37655 $ @e \$Date: 2010-09-09 11:15:05 +0800 (Thu, 09 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_MPRTT_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define _DONT_CARE 0xFF
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts RttNom and RttWr value from a input table and stores extracted
+ * value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Table values can be extracted for all present dimms/ranks
+ * @return FALSE - Table values cannot be extracted for all present dimms/ranks
+ *
+ */
+BOOLEAN
+MemPGetRttNomWr (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 TableSize;
+ UINT32 CurDDRrate;
+ UINT8 DDR3Voltage;
+ UINT16 RankTypeOfPopulatedDimm;
+ UINT16 RankTypeInTable;
+ DIMM_TYPE DimmType;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ UINT8 TgtDimmType;
+ UINT8 TgtRank;
+ UINT8 Chipsel;
+ PSCFG_RTT_ENTRY *TblPtr;
+ PSCFG_RTT_ENTRY *OrgTblPtr;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+
+ TblPtr = NULL;
+ TableSize = 0;
+ PackageType = 0;
+ LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
+ MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
+ NOD = (UINT8) 1 << (MaxDimmPerCh - 1);
+
+ if (CurrentChannel->RegDimmPresent != 0) {
+ DimmType = RDIMM_TYPE;
+ } else if (CurrentChannel->SODimmPresent != 0) {
+ DimmType = SODIMM_TYPE;
+ //@todo LRDIMM
+ //} else if (CurrentChannel->LrDimmPresent) {
+ // DimmType = LRDIMM_TYPE;
+ } else {
+ DimmType = UDIMM_TYPE;
+ }
+
+ i = 0;
+ // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type.
+ while (EntryOfTables->TblEntryOfDramTerm[i] != NULL) {
+ if (((EntryOfTables->TblEntryOfDramTerm[i])->Header.DimmType & DimmType) != 0) {
+ if (((EntryOfTables->TblEntryOfDramTerm[i])->Header.NumOfDimm & NOD) != 0) {
+ //
+ // Determine if this is the expected NB Type
+ //
+ LogicalCpuid = (EntryOfTables->TblEntryOfDramTerm[i])->Header.LogicalCpuid;
+ PackageType = (EntryOfTables->TblEntryOfDramTerm[i])->Header.PackageType;
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ TblPtr = (PSCFG_RTT_ENTRY *) ((EntryOfTables->TblEntryOfDramTerm[i])->TBLPtr);
+ TableSize = (EntryOfTables->TblEntryOfDramTerm[i])->TableSize;
+ break;
+ }
+ }
+ }
+ i++;
+ }
+
+ // Check whether no table entry is found.
+ if (EntryOfTables->TblEntryOfDramTerm[i] == NULL) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo RTT table\n");
+ return FALSE;
+ }
+
+ CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66));
+ DDR3Voltage = (UINT8) (1 << (NBPtr->RefPtr->DDR3Voltage));
+ RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel); //@todo - LRDIMM ?
+
+ OrgTblPtr = TblPtr;
+ for (Chipsel = 0; Chipsel < MAX_CS_PER_CHANNEL; Chipsel++) {
+ TblPtr = OrgTblPtr;
+ if ((NBPtr->DCTPtr->Timings.CsEnabled & (UINT16) (1 << Chipsel)) != 0) {
+ if ((CurrentChannel->DimmQrPresent & (UINT8) (1 << (Chipsel >> 1))) != 0) {
+ TgtDimmType = DIMM_QR;
+ TgtRank = (UINT8) ((Chipsel < 4) ? 1 << (Chipsel & 1) : 4 << (Chipsel & 1));
+ } else if ((CurrentChannel->DimmDrPresent & (UINT8) (1 << (Chipsel >> 1))) != 0) {
+ TgtDimmType = DIMM_DR;
+ TgtRank = (UINT8) 1 << (Chipsel & 1);
+ } else {
+ TgtDimmType = DIMM_SR;
+ TgtRank = (UINT8) 1 << (Chipsel & 1);
+ }
+
+ if (DimmType == LRDIMM_TYPE) {
+ TgtDimmType = _DONT_CARE;
+ TgtRank = _DONT_CARE;
+ }
+
+ for (i = 0; i < TableSize; i++) {
+ MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if (TblPtr->DimmPerCh == MaxDimmPerCh) {
+ if ((TblPtr->DDRrate & CurDDRrate) != 0) {
+ if ((TblPtr->VDDIO & DDR3Voltage) != 0) {
+ if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) {
+ if (((TblPtr->Dimm & TgtDimmType) != 0) || (TgtDimmType == _DONT_CARE)) {
+ if (((TblPtr->Rank & TgtRank) != 0) || (TgtRank == _DONT_CARE)) {
+ NBPtr->PsPtr->RttNom[Chipsel] = (UINT8) TblPtr->RttNom;
+ NBPtr->PsPtr->RttWr[Chipsel] = (UINT8) TblPtr->RttWr;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ TblPtr++;
+ }
+ if ((i == TableSize) && (NBPtr->SharedPtr->VoltageMap == VDDIO_DETERMINED)) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo Rtt entries\n");
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpsao.c b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpsao.c
new file mode 100644
index 0000000000..b0b2cc9b2f
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Mem/Ps/mpsao.c
@@ -0,0 +1,200 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mpsao.c
+ *
+ * A sub-engine which extracts Slow access mode, Address timing and Output driver compensation value.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Ps)
+ * @e \$Revision: 37655 $ @e \$Date: 2010-09-09 11:15:05 +0800 (Thu, 09 Sep 2010) $
+ *
+ **/
+/*
+ *****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***************************************************************************
+ *
+ */
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "AdvancedApi.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "mu.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_MEM_PS_MPSAO_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * A sub-function which extracts Slow mode, Address timing and Output driver compensation value
+ * from a input table and store those value to a specific address.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
+ *
+ * @return TRUE - Table values can be extracted per dimm population and ranks type.
+ * @return FALSE - Table values cannot be extracted per dimm population and ranks type.
+ *
+ */
+BOOLEAN
+MemPGetSAO (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 TableSize;
+ UINT32 CurDDRrate;
+ UINT8 DDR3Voltage;
+ UINT16 RankTypeOfPopulatedDimm;
+ UINT16 RankTypeInTable;
+ DIMM_TYPE DimmType;
+ CPU_LOGICAL_ID LogicalCpuid;
+ UINT8 PackageType;
+ PSCFG_SAO_ENTRY *TblPtr;
+ CH_DEF_STRUCT *CurrentChannel;
+
+ CurrentChannel = NBPtr->ChannelPtr;
+
+ TblPtr = NULL;
+ TableSize = 0;
+ PackageType = 0;
+ LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
+ MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
+ NOD = (UINT8) 1 << (MaxDimmPerCh - 1);
+
+ if (CurrentChannel->RegDimmPresent != 0) {
+ DimmType = RDIMM_TYPE;
+ } else if (CurrentChannel->SODimmPresent != 0) {
+ DimmType = SODIMM_TYPE;
+ //@todo LRDIMM
+ //} else if (CurrentChannel->LrDimmPresent) {
+ // DimmType = LRDIMM_TYPE;
+ } else {
+ DimmType = UDIMM_TYPE;
+ }
+
+ i = 0;
+ // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type.
+ while (EntryOfTables->TblEntryOfSAO[i] != NULL) {
+ if (((EntryOfTables->TblEntryOfSAO[i])->Header.DimmType & DimmType) != 0) {
+ if (((EntryOfTables->TblEntryOfSAO[i])->Header.NumOfDimm & NOD) != 0) {
+ //
+ // Determine if this is the expected NB Type
+ //
+ LogicalCpuid = (EntryOfTables->TblEntryOfSAO[i])->Header.LogicalCpuid;
+ PackageType = (EntryOfTables->TblEntryOfSAO[i])->Header.PackageType;
+ if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
+ TblPtr = (PSCFG_SAO_ENTRY *) ((EntryOfTables->TblEntryOfSAO[i])->TBLPtr);
+ TableSize = (EntryOfTables->TblEntryOfSAO[i])->TableSize;
+ break;
+ }
+ }
+ }
+ i++;
+ }
+
+ // Check whether no table entry is found.
+ if (EntryOfTables->TblEntryOfSAO[i] == NULL) {
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo SlowMode table\n");
+ return FALSE;
+ }
+
+ CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66));
+ DDR3Voltage = (UINT8) (1 << (NBPtr->RefPtr->DDR3Voltage));
+ RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel); //@todo - LRDIMM ?
+
+ for (i = 0; i < TableSize; i++) {
+ MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if (TblPtr->DimmPerCh == MaxDimmPerCh) {
+ if ((TblPtr->DDRrate & CurDDRrate) != 0) {
+ if ((TblPtr->VDDIO & DDR3Voltage) != 0) {
+ if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) {
+ CurrentChannel->DctAddrTmg = TblPtr->AddTmgCtl;
+ CurrentChannel->DctOdcCtl = TblPtr->ODC;
+ CurrentChannel->SlowMode = (TblPtr->SlowMode == 1) ? TRUE : FALSE;
+ return TRUE;
+ }
+ }
+ }
+ }
+ TblPtr++;
+ }
+ IDS_HDT_CONSOLE (MEM_FLOW, "\nNo SlowMode entries\n");
+ if (NBPtr->SharedPtr->VoltageMap != VDDIO_DETERMINED) {
+ return TRUE;
+ }
+
+ return FALSE;
+} \ No newline at end of file