aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/Proc/Mem/Ps
diff options
context:
space:
mode:
authorFrank Vibrans <frank.vibrans@amd.com>2011-02-14 18:30:54 +0000
committerMarc Jones <marc.jones@amd.com>2011-02-14 18:30:54 +0000
commit2b4c831b4d16b55a7abdea20bce82cccd168232c (patch)
tree95a35c737d16119f1dfa9c1c9d7700710d8a04f7 /src/vendorcode/amd/agesa/Proc/Mem/Ps
parent74ad66cdc143e04f976ba21e538e02b20362d7e6 (diff)
Add AMD Agesa and AMD CIMx SB800 code. Patch 1 of 8.
This code currently generates many warnings that are functionally benign. These are being addressed, but the wheels of bureaucracy turn slowly. This drop supports AMD cpu families 10h and 14h. Only Family 14h is used as an example in this set of patches. Other cpu families are supported by the infrastructure, but their specific support is not included herein. This patch is functionally independent of the other patches in this set. Signed-off-by: Frank Vibrans <frank.vibrans@amd.com> Acked-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Acked-by: Marc Jones <marcj303@gmail.com> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6344 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
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