summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/Proc/Recovery
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/Recovery
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/Recovery')
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/CPU/cpuRecovery.c104
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/CPU/cpuRecovery.h77
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/GNB/GfxRecovery.c112
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/GNB/GfxRecovery.h77
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/GNB/GnbRecovery.c103
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/GNB/NbInitRecovery.c138
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/GNB/NbInitRecovery.h57
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/HT/htInitRecovery.c163
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/HT/htInitReset.c332
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnc32.c711
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnc32.h110
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnmctc32.c162
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnprotoc32.c62
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnda.c651
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnda.h110
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnmctda.c165
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrndr.c655
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrndr.h110
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrnmctdr.c167
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrndcthy.c76
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnhy.c710
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnhy.h110
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnmcthy.c162
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnprotohy.c62
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/NI/mrnNi.c651
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/NI/mrnNi.h97
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrndcton.c363
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnmcton.c191
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnon.c653
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnon.h125
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/PH/mrnPh.c652
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/PH/mrnPh.h97
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/RB/mrnRb.c651
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/RB/mrnRb.h97
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrn.c190
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrndct.c1502
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrnmct.c298
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrntrain3.c127
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrp.c261
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplribt.c183
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplrnlr.c111
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplrnpr.c111
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpmr0.c178
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpodtpat.c183
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprc10opspd.c93
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprc2ibt.c199
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprtt.c218
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpsao.c188
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrt3.c189
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtrci3.c244
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtsdi3.c360
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c326
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.h132
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrttwl3.c347
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrtthrc.c287
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrttpos.c115
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrttsrc.c437
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrdef.c129
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrinit.c126
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrm.c288
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrport.h82
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrt3.h121
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/mru.asm187
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/mru.h140
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/Mem/mruc.c267
-rw-r--r--src/vendorcode/amd/agesa/Proc/Recovery/recoveryPage.h59
66 files changed, 16441 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/CPU/cpuRecovery.c b/src/vendorcode/amd/agesa/Proc/Recovery/CPU/cpuRecovery.c
new file mode 100644
index 0000000000..67140cd103
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/CPU/cpuRecovery.c
@@ -0,0 +1,104 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD CPU Recovery API, and related functions.
+ *
+ * Contains code that implements the CPU Recovery functionality
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Recovery/CPU
+ * @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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "AGESA.h"
+#include "cpuRecovery.h"
+#include "cpuRegisters.h"
+#include "cpuEarlyInit.h"
+#include "Table.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_CPU_CPURECOVERY_FILECODE
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Performs CPU related initialization at the recovery entry point
+ *
+ * This function processes the MSR and PCI register tables.
+ *
+ * @param[in] CpuRecoveryParams Required input parameters for recovery CPU
+ * initialization.
+ *
+ * @retval AGESA_SUCCESS Always succeeds.
+ *
+ */
+AGESA_STATUS
+AmdCpuRecovery (
+ IN AMD_CPU_RECOVERY_PARAMS *CpuRecoveryParams
+ )
+{
+ SetRegistersFromTables (&CpuRecoveryParams->PlatformConfig, &CpuRecoveryParams->StdHeader);
+ LoadMicrocodePatch (&CpuRecoveryParams->StdHeader);
+ return (AGESA_SUCCESS);
+}
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/CPU/cpuRecovery.h b/src/vendorcode/amd/agesa/Proc/Recovery/CPU/cpuRecovery.h
new file mode 100644
index 0000000000..5f2d3b5cf3
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/CPU/cpuRecovery.h
@@ -0,0 +1,77 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD CPU Recovery API, and related function prototypes.
+ *
+ * Contains code that implements the CPU Recovery functionality
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Recovery/CPU
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _CPU_RECOVERY_H_
+#define _CPU_RECOVERY_H_
+
+/*----------------------------------------------------------------------------------------
+ * M I X E D (Definitions And Macros / Typedefs, Structures, Enums)
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S, S T R U C T U R E S, E N U M S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * F U N C T I O N P R O T O T Y P E
+ *----------------------------------------------------------------------------------------
+ */
+
+// These are P U B L I C functions
+AGESA_STATUS
+AmdCpuRecovery (
+ IN AMD_CPU_RECOVERY_PARAMS *CpuRecoveryParams
+ );
+
+#endif // _CPU_RECOVERY_H_
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GfxRecovery.c b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GfxRecovery.c
new file mode 100644
index 0000000000..80249932f0
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GfxRecovery.c
@@ -0,0 +1,112 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD GFX Recovery API, and related functions.
+ *
+ * Contains code that implements the GFX Recovery functionality
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Recovery/GNB
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "AGESA.h"
+#include "GfxRecovery.h"
+#include "OptionGfxRecovery.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_GNB_GFXRECOVERY_FILECODE
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+extern OPTION_GFX_RECOVERY_CONFIGURATION OptionGfxRecoveryConfiguration; // global user config record
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Performs Gfx related initialization at the recovery entry point
+ *
+ * This function processes the MSR and PCI register tables.
+ *
+ * @param[in] StdHeader global state, input data
+ *
+ * @retval AGESA_SUCCESS Always succeeds.
+ *
+ */
+AGESA_STATUS
+AmdGfxRecovery (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ return ((*(OptionGfxRecoveryConfiguration.GfxRecoveryFeature)) (StdHeader));
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ * This function will called if OPTION_GfxRecovery is true
+ *
+ * @param[in, out] StdHeader Standard Head Pointer
+ *
+ * @retval AGESA_STATUS
+ */
+AGESA_STATUS
+GetGfxRecoveryMain (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ //to be done
+ return AGESA_SUCCESS;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GfxRecovery.h b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GfxRecovery.h
new file mode 100644
index 0000000000..70c977807c
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GfxRecovery.h
@@ -0,0 +1,77 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD GFX Recovery API, and related function prototypes.
+ *
+ * Contains code that implements the Gfx Recovery functionality
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Recovery/GNB
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _GFX_RECOVERY_H_
+#define _GFX_RECOVERY_H_
+
+/*----------------------------------------------------------------------------------------
+ * M I X E D (Definitions And Macros / Typedefs, Structures, Enums)
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S, S T R U C T U R E S, E N U M S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * F U N C T I O N P R O T O T Y P E
+ *----------------------------------------------------------------------------------------
+ */
+
+// These are P U B L I C functions
+AGESA_STATUS
+AmdGfxRecovery (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+#endif // _GNB_RECOVERY_H_
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GnbRecovery.c b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GnbRecovery.c
new file mode 100644
index 0000000000..0c787d92d2
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/GnbRecovery.c
@@ -0,0 +1,103 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD GNB Recovery API, and related functions.
+ *
+ * Contains code that implements the GNB Recovery functionality
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Recovery/GNB
+ * @e \$Revision: 39275 $ @e \$Date: 2010-10-09 08:22:05 +0800 (Sat, 09 Oct 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "AGESA.h"
+#include "Gnb.h"
+#include GNB_MODULE_DEFINITIONS (GnbCommonLib)
+#include GNB_MODULE_DEFINITIONS (GnbNbInitLibV1)
+#include "NbInitRecovery.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_GNB_GNBRECOVERY_FILECODE
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Performs Gnb Recovery related initialization at the recovery entry point
+ *
+ * This function processes the MSR and PCI register tables.
+ *
+ *
+ * @param[in] StdHeader global state, input data
+ *
+ * @retval AGESA_SUCCESS Always succeeds.
+ *
+ */
+AGESA_STATUS
+AmdGnbRecovery (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ PCI_ADDR NbPciAddress;
+ NbPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0);
+ NbInitOnPowerOnRecovery (NbPciAddress, StdHeader);
+ GnbSetTom (NbPciAddress, StdHeader);
+ return AGESA_SUCCESS;
+}
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/GNB/NbInitRecovery.c b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/NbInitRecovery.c
new file mode 100644
index 0000000000..d4b831d05a
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/NbInitRecovery.c
@@ -0,0 +1,138 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Various NB Recovery initialization services
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: GNB
+ * @e \$Revision: 39275 $ @e \$Date: 2010-10-09 08:22:05 +0800 (Sat, 09 Oct 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdlib.h"
+#include "Gnb.h"
+#include GNB_MODULE_DEFINITIONS (GnbCommonLib)
+#include "GnbRegistersON.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_GNB_NBINITRECOVERY_FILECODE
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+typedef struct {
+ UINT8 Reg;
+ UINT32 Mask;
+ UINT32 Data;
+} NB_REGISTER_RECOVERY_ENTRY;
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+
+CONST NB_REGISTER_RECOVERY_ENTRY NbPciInitRecoveryTable [] = {
+ {
+ D0F0x04_ADDRESS,
+ 0xffffffff,
+ 0x1 << D0F0x04_MemAccessEn_WIDTH
+ }
+};
+
+CONST NB_REGISTER_RECOVERY_ENTRY NbMiscInitRecoveryTable [] = {
+ {
+ D0F0x64_x51_ADDRESS,
+ 0xffffffff,
+ 1 << D0F0x64_x51_SetPowEn_OFFSET
+ }
+};
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init NB at Power On
+ *
+ *
+ * @param[in] NbPciAddress Gnb PCI address
+ * @param[in] StdHeader Standard Configuration Header
+ */
+
+
+VOID
+NbInitOnPowerOnRecovery (
+ IN PCI_ADDR NbPciAddress,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINTN Index;
+ // Init NBCONFIG
+ for (Index = 0; Index < (sizeof (NbPciInitRecoveryTable) / sizeof (NB_REGISTER_RECOVERY_ENTRY)); Index++) {
+ GnbLibPciRMW (
+ NbPciAddress.AddressValue | NbPciInitRecoveryTable[Index].Reg,
+ AccessWidth32,
+ NbPciInitRecoveryTable[Index].Mask,
+ NbPciInitRecoveryTable[Index].Data,
+ StdHeader
+ );
+ }
+
+ // Init MISCIND
+ for (Index = 0; Index < (sizeof (NbMiscInitRecoveryTable) / sizeof (NB_REGISTER_RECOVERY_ENTRY)); Index++) {
+ GnbLibPciIndirectRMW (
+ NbPciAddress.AddressValue | D0F0x60_ADDRESS,
+ NbMiscInitRecoveryTable[Index].Reg | IOC_WRITE_ENABLE,
+ AccessWidth32,
+ NbMiscInitRecoveryTable[Index].Mask,
+ NbMiscInitRecoveryTable[Index].Data,
+ StdHeader
+ );
+ }
+ return;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/GNB/NbInitRecovery.h b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/NbInitRecovery.h
new file mode 100644
index 0000000000..651aed68b5
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/GNB/NbInitRecovery.h
@@ -0,0 +1,57 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Various NB Recovery initialization services
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: GNB
+ * @e \$Revision: 39275 $ @e \$Date: 2010-10-09 08:22:05 +0800 (Sat, 09 Oct 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _NBINITRECOVERY_H_
+#define _NBINITRECOVERY_H_
+
+
+VOID
+NbInitOnPowerOnRecovery (
+ IN PCI_ADDR NbPciAddress,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+#endif
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/HT/htInitRecovery.c b/src/vendorcode/amd/agesa/Proc/Recovery/HT/htInitRecovery.c
new file mode 100644
index 0000000000..f034b1aa57
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/HT/htInitRecovery.c
@@ -0,0 +1,163 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Init the Socket and Node maps for Recovery mode.
+ *
+ * Create the Socket and Node maps just like normal boot,
+ * except that they only indicate the BSC is present.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: HyperTransport
+ * @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 "Ids.h"
+#include "Topology.h"
+#include "heapManager.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_HT_HTINITRECOVERY_FILECODE
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get new Socket and Node Maps.
+ *
+ * Put the Socket Die Table and the Node Table in heap with known handles.
+ *
+ * @param[out] SocketDieToNodeMap The Socket, Module to Node info map
+ * @param[out] NodeToSocketDieMap The Node to Socket, Module map.
+ * @param[in] StdHeader Header for library and services.
+ */
+VOID
+STATIC
+NewNodeAndSocketTablesRecovery (
+ OUT SOCKET_DIE_TO_NODE_MAP *SocketDieToNodeMap,
+ OUT NODE_TO_SOCKET_DIE_MAP *NodeToSocketDieMap,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 i;
+ UINT8 j;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ // Allocate heap for the table
+ AllocHeapParams.RequestedBufferSize = (((MAX_SOCKETS) * (MAX_DIES)) * sizeof (SOCKET_DIE_TO_NODE_ITEM));
+ AllocHeapParams.BufferHandle = SOCKET_DIE_MAP_HANDLE;
+ AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
+ if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
+ // HeapAllocateBuffer must set BufferPtr to valid or NULL.
+ *SocketDieToNodeMap = (SOCKET_DIE_TO_NODE_MAP)AllocHeapParams.BufferPtr;
+ ASSERT (SocketDieToNodeMap != NULL);
+ // Initialize shared data structures
+ for (i = 0; i < MAX_SOCKETS; i++) {
+ for (j = 0; j < MAX_DIES; j++) {
+ (**SocketDieToNodeMap)[i][j].Node = HT_LIST_TERMINAL;
+ (**SocketDieToNodeMap)[i][j].LowCore = HT_LIST_TERMINAL;
+ (**SocketDieToNodeMap)[i][j].HighCore = HT_LIST_TERMINAL;
+ }
+ }
+ }
+ // Allocate heap for the table
+ AllocHeapParams.RequestedBufferSize = (MAX_NODES * sizeof (NODE_TO_SOCKET_DIE_ITEM));
+ AllocHeapParams.BufferHandle = NODE_ID_MAP_HANDLE;
+ AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
+ if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
+ // HeapAllocateBuffer must set BufferPtr to valid or NULL.
+ *NodeToSocketDieMap = (NODE_TO_SOCKET_DIE_MAP)AllocHeapParams.BufferPtr;
+ ASSERT (NodeToSocketDieMap != NULL);
+ // Initialize shared data structures
+ for (i = 0; i < MAX_NODES; i++) {
+ (**NodeToSocketDieMap)[i].Socket = HT_LIST_TERMINAL;
+ (**NodeToSocketDieMap)[i].Die = HT_LIST_TERMINAL;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Initialize the Node and Socket maps for an AP Core.
+ *
+ * In each core's local heap, create a Node to Socket map and a Socket/Module to Node map.
+ * The mapping is filled in by reading the AP Mailboxes from PCI config on each node.
+ *
+ * @param[in] StdHeader global state, input data
+ *
+ * @retval AGESA_SUCCESS Always succeeds.
+ */
+AGESA_STATUS
+AmdHtInitRecovery (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ AP_MAILBOXES NodeApMailBox;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+ SOCKET_DIE_TO_NODE_MAP SocketDieToNodeMap;
+ NODE_TO_SOCKET_DIE_MAP NodeToSocketDieMap;
+
+ NodeApMailBox.ApMailInfo.Info = 0;
+ NodeApMailBox.ApMailExtInfo.Info = 0;
+
+ // Allocate heap for caching the mailboxes
+ AllocHeapParams.RequestedBufferSize = sizeof (AP_MAILBOXES);
+ AllocHeapParams.BufferHandle = LOCAL_AP_MAIL_BOX_CACHE_HANDLE;
+ AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
+ if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
+ *(AP_MAILBOXES *)AllocHeapParams.BufferPtr = NodeApMailBox;
+ }
+
+ NewNodeAndSocketTablesRecovery (&SocketDieToNodeMap, &NodeToSocketDieMap, StdHeader);
+ // HeapAllocateBuffer must set BufferPtr to valid or NULL, so the checks below are ok.
+
+ // There is no option to not have socket - node maps, if they aren't allocated that is a fatal bug.
+ ASSERT (SocketDieToNodeMap != NULL);
+ ASSERT (NodeToSocketDieMap != NULL);
+
+ (*SocketDieToNodeMap)[0][0].Node = 0;
+ (*SocketDieToNodeMap)[0][0].LowCore = 0;
+ (*SocketDieToNodeMap)[0][0].HighCore = 0;
+
+ // We lie about being Socket 0 and Module 0 always, it isn't necessarily true.
+ (*NodeToSocketDieMap)[0].Socket = (UINT8)0;
+ (*NodeToSocketDieMap)[0].Die = (UINT8)0;
+
+ return AGESA_SUCCESS;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/HT/htInitReset.c b/src/vendorcode/amd/agesa/Proc/Recovery/HT/htInitReset.c
new file mode 100644
index 0000000000..9d58026823
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/HT/htInitReset.c
@@ -0,0 +1,332 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Recovery HT, a Hypertransport init for Boot Blocks. For normal
+ * boots, run Recovery HT first in boot block, then run full HT init
+ * in the system BIOS. Recovery HT moves the devices on the chain with
+ * the southbridge to their assigned device IDS, so that all their PCI
+ * Config space is accessible.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Recovery HyperTransport
+ * @e \$Revision: 35740 $ @e \$Date: 2010-07-30 00:04:17 +0800 (Fri, 30 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 "amdlib.h"
+#include "Ids.h"
+#include "AdvancedApi.h"
+#include "GeneralServices.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_HT_HTINITRESET_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_NODES 1
+#define MAX_LINKS 8
+
+extern CONST AMD_HT_RESET_INTERFACE HtOptionResetDefaults;
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/**
+ * Our global state data structure.
+ *
+ * Keep track of inputs and outputs, and keep any working state.
+ */
+typedef struct {
+ AMD_HT_RESET_INTERFACE *HtBlock; ///< The interface
+ AGESA_STATUS Status; ///< Remember the highest severity status event
+ VOID *ConfigHandle; ///< Config Pointer, opaque handle for passing to lib
+} HTR_STATE_DATA;
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/***************************************************************************
+ *** FAMILY/NORTHBRIDGE SPECIFIC FUNCTIONS ***
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable Routing Tables.
+ *
+ * Turns routing tables on for a node zero.
+ *
+ * @param[in] State Our State
+ */
+
+VOID
+STATIC
+HtrEnableRoutingTables (
+ IN HTR_STATE_DATA *State
+ )
+{
+ PCI_ADDR Reg;
+ UINT32 Temp;
+ Temp = 0;
+ Reg.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0x6C);
+ LibAmdPciWriteBits (Reg, 0, 0, &Temp, State->ConfigHandle);
+}
+
+/***************************************************************************
+ *** Non-coherent init code ***
+ *** Algorithms ***
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Process the SouthBridge Link.
+ *
+ * Process a non-coherent link, and setting the device ID for all devices found.
+ *
+ * @param[in] State Our State, Inputs
+ */
+VOID
+STATIC
+HtrProcessLink (
+ IN HTR_STATE_DATA *State
+ )
+{
+ UINT32 CurrentBUID;
+ UINT32 Temp;
+ UINT32 UnitIDcnt;
+ PCI_ADDR CurrentPtr;
+ UINT8 Depth;
+ BUID_SWAP_LIST *SwapPtr;
+ PCI_ADDR Link1ControlRegister;
+ BOOLEAN IsCaveDevice;
+
+ // No PCI init to run, everything has to be on Bus zero. This makes fewer
+ // northbridge dependencies.
+ //
+ // Assign BUIDs so that config space for all devices is visible.
+ //
+ if (State->HtBlock->ManualBuidSwapList != NULL) {
+ // Manual non-coherent BUID assignment
+ // Assign BUID's per manual override
+ //
+ SwapPtr = &(State->HtBlock->ManualBuidSwapList->SwapList);
+ Depth = 0;
+ while (SwapPtr->Swaps[Depth].FromId != 0xFF) {
+ CurrentPtr.AddressValue = MAKE_SBDFO (0, 0, SwapPtr->Swaps[Depth].FromId, 0, 0);
+
+ do {
+ LibAmdPciFindNextCap (&CurrentPtr, State->ConfigHandle);
+ ASSERT (CurrentPtr.AddressValue != ILLEGAL_SBDFO);
+ LibAmdPciRead (AccessWidth32, CurrentPtr, &Temp, State->ConfigHandle);
+ } while ((Temp & (UINT32)0xE00000FF) != (UINT32)0x00000008); // HyperTransport Slave Capability
+
+ CurrentBUID = SwapPtr->Swaps[Depth].ToId;
+ // Set the device's BUID
+ LibAmdPciWriteBits (CurrentPtr, 20, 16, &CurrentBUID, State->ConfigHandle);
+ Depth++;
+ }
+ } else {
+ // Automatic non-coherent device detection
+ Depth = 0;
+ CurrentBUID = 1;
+ for (;;) {
+ CurrentPtr.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0);
+
+ LibAmdPciRead (AccessWidth32, CurrentPtr, &Temp, State->ConfigHandle);
+ if (Temp == (UINT32)0xFFFFFFFF) {
+ // No device found at currentPtr
+ break;
+ }
+
+ // HyperTransport Slave Capability
+ do {
+ LibAmdPciFindNextCap (&CurrentPtr, State->ConfigHandle);
+ if (CurrentPtr.AddressValue == ILLEGAL_SBDFO) {
+ // There is a device at currentPtr, but it isn't an HT device.
+ return;
+ }
+ LibAmdPciRead (AccessWidth32, CurrentPtr, &Temp, State->ConfigHandle);
+ } while ((Temp & (UINT32)0xE00000FF) != (UINT32)0x00000008); // HyperTransport Slave Capability
+
+ // Get the device's Unit ID Count.
+ LibAmdPciReadBits (CurrentPtr, 25, 21, &UnitIDcnt, State->ConfigHandle);
+ if ((UnitIDcnt + CurrentBUID) > 24) {
+ // An error handler for the case where we run out of BUID's on a chain
+ State->Status = AGESA_ERROR;
+ ASSERT (FALSE);
+ return;
+ }
+ // While we are still certain we are accessing this device, remember if it is a cave device.
+ // This is found by reading EOC from the Link 1 Control Register.
+ Link1ControlRegister = CurrentPtr;
+ Link1ControlRegister.Address.Register += 8;
+ LibAmdPciReadBits (Link1ControlRegister, 6, 6, &Temp, State->ConfigHandle);
+ IsCaveDevice = ((Temp == 0) ? FALSE : TRUE);
+
+ // Set the device's BUID
+ IDS_HDT_CONSOLE (HT_TRACE, "Device found at depth=%d.\n", Depth);
+ LibAmdPciWriteBits (CurrentPtr, 20, 16, &CurrentBUID, State->ConfigHandle);
+
+ CurrentPtr.Address.Device = CurrentBUID;
+ // Get the device's BUID
+ LibAmdPciReadBits (CurrentPtr, 20, 16, &Temp, State->ConfigHandle);
+ if (Temp != CurrentBUID) {
+ if ((Depth == 0) && IsCaveDevice) {
+ // If the chain only consists of a single cave device, that device may have retained zero
+ // for it's BUID.
+ CurrentPtr.Address.Device = 0;
+ LibAmdPciReadBits (CurrentPtr, 20, 16, &Temp, State->ConfigHandle);
+ if (Temp == 0) {
+ // Per HyperTransport specification, devices not accepting BUID reassignment hardwire BUID to zero.
+ Depth++;
+ // Success!
+ IDS_HDT_CONSOLE (HT_TRACE, "Compliant Cave at BUID=0.\n");
+ break;
+ } else if (Temp == CurrentBUID) {
+ // and then, there are the other kind of devices ....
+ // Restore the writable BUID field (which contains the value we just wrote) to zero.
+ Temp = 0;
+ LibAmdPciWriteBits (CurrentPtr, 20, 16, &Temp, State->ConfigHandle);
+ Depth++;
+ // Success!
+ IDS_HDT_CONSOLE (HT_TRACE, "Cave left at BUID=0.\n");
+ break;
+ }
+ }
+ // An error handler for this critical error
+ State->Status = AGESA_ERROR;
+ ASSERT (FALSE);
+ return;
+ }
+
+ IDS_HDT_CONSOLE (HT_TRACE, "Compliant Device assigned at BUID=%d.\n", CurrentBUID);
+ Depth++;
+ CurrentBUID += UnitIDcnt;
+ }
+ // Provide information on automatic device results
+ State->HtBlock->Depth = Depth;
+ }
+}
+
+/***************************************************************************
+ *** HT Reset Initialize ***
+ ***************************************************************************/
+
+/**
+ * A constructor for the HyperTransport input structure.
+ *
+ * Sets inputs to valid, basic level, defaults.
+ *
+ * @param[in] StdHeader Config handle
+ * @param[in,out] AmdHtResetInterface HT Interface structure to initialize.
+ *
+ * @retval AGESA_SUCCESS Constructors are not allowed to fail
+*/
+AGESA_STATUS
+AmdHtResetConstructor (
+ IN AMD_CONFIG_PARAMS *StdHeader,
+ IN AMD_HT_RESET_INTERFACE *AmdHtResetInterface
+ )
+{
+ AmdHtResetInterface->ManualBuidSwapList = HtOptionResetDefaults.ManualBuidSwapList;
+ return AGESA_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Initialize HT for Reset, Boot Blocks.
+ *
+ * This is the top level external interface for Hypertransport Reset Initialization.
+ * Create our initial internal state and initialize the non-coherent chain to the
+ * southbridge. This interface must be executed by both normal and recovery boot paths.
+ *
+ * @param[in] StdHeader Interface structure
+ * @param[in] AmdHtResetInterface our interface and inputs
+ *
+ * @retval AGESA_SUCCESS Successful init
+ * @retval AGESA_ERROR Device Error, BUID max exceed error.
+ *
+ */
+AGESA_STATUS
+AmdHtInitReset (
+ IN AMD_CONFIG_PARAMS *StdHeader,
+ IN AMD_HT_RESET_INTERFACE *AmdHtResetInterface
+ )
+{
+ HTR_STATE_DATA State;
+ AGESA_STATUS IgnoredStatus;
+
+ State.Status = AGESA_SUCCESS;
+ if (IsBsp (StdHeader, &IgnoredStatus)) {
+ State.ConfigHandle = (AMD_CONFIG_PARAMS *)StdHeader;
+ State.HtBlock = AmdHtResetInterface;
+ HtrEnableRoutingTables (&State);
+
+ HtrProcessLink (&State);
+ }
+ return State.Status;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnc32.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnc32.c
new file mode 100644
index 0000000000..7176417c80
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnc32.c
@@ -0,0 +1,711 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnc32.c
+ *
+ * Common Northbridge functions for C32 Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnc32.h"
+#include "heapManager.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_C32_MRNC32_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_DIES_PER_SOCKET 2
+#define MAX_DCTS_PER_DIE 2
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableC32 (
+ IN OUT TSEFO *NBRegTable
+ );
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ );
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ );
+
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ );
+
+VOID
+STATIC
+MemRecNSwitchNodeC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 NodeID
+ );
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the northbridge block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ * @param[in] NodeID - Node ID for this NB block
+ *
+ * @return TRUE - This node is a C32 and this NB block has been initialized
+ * @return FALSE - This node is not a C32
+ */
+
+BOOLEAN
+MemRecConstructNBBlockC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ )
+{
+ UINT8 i;
+ UINT8 Dct;
+ UINT8 Channel;
+ DIE_STRUCT *MCTPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ //
+ // Determine if this is the expected NB Type
+ //
+ GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+ if (!MemRecNIsIdSupportedC32 (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ //
+ MCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_C32 * (
+ sizeof (DCT_STRUCT) + (
+ MAX_CHANNELS_PER_DCT_C32 * (
+ sizeof (CH_DEF_STRUCT) + (
+ MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
+ )
+ )
+ )
+ );
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ return FALSE;
+ }
+
+ MemPtr->DieCount = MAX_DIES_PER_SOCKET;
+ MCTPtr->DctCount = MAX_DCTS_PER_NODE_C32;
+ MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ MemPtr->DiesPerSystem[NodeID + 1].DctCount = MAX_DCTS_PER_NODE_C32;
+ MemPtr->DiesPerSystem[NodeID + 1].DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_C32 * sizeof (DCT_STRUCT);
+ for (Dct = 0; Dct < MAX_DCTS_PER_NODE_C32; Dct++) {
+ MCTPtr->DctData[Dct].Dct = Dct;
+ MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_C32;
+ MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[0].ChannelID = (MCTPtr->DieId * 2) + Dct;
+ AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_C32 * sizeof (CH_DEF_STRUCT);
+ for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_C32; Channel++) {
+ MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
+ MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
+ }
+ }
+
+ //
+ // Initialize NB block's variables
+ //
+ NBPtr->MemPtr = MemPtr;
+ NBPtr->RefPtr = MemPtr->ParameterListPtr;
+ NBPtr->MCTPtr = MCTPtr;
+ NBPtr->AllNodeMCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+ NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+
+ MemRecNInitNBRegTableC32 (NBPtr->NBRegTable);
+ NBPtr->Dct = 0;
+ NBPtr->Channel = 0;
+ NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+
+ LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
+ LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
+ for (i = 0; i < NumberOfHooks; i++) {
+ NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
+ }
+
+ NBPtr->InitRecovery = MemRecNMemInitNb;
+
+ NBPtr->SwitchNodeRec = MemRecNSwitchNodeC32;
+ NBPtr->SwitchDCT = MemRecNSwitchDctC32;
+ NBPtr->SwitchChannel = MemRecNSwitchChannelC32;
+ NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
+ NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
+ NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
+ NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
+ NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
+
+ NBPtr->GetBitField = MemRecNGetBitFieldNb;
+ NBPtr->SetBitField = MemRecNSetBitFieldNb;
+ NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
+ NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
+
+ NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldC32;
+ NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyC32;
+ NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctC32;
+ NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
+ NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctC32;
+ NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctC32;
+ NBPtr->IsSupported[DramModeAfterDimmPres] = TRUE;
+ MemRecNSwitchDctC32 (NBPtr, 0);
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function sets the current die to work on.
+ * Should be called before accessing a certain die
+ * All data structures will be updated to point to the current node
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] NodeID - ID of the target die
+ *
+ */
+
+VOID
+STATIC
+MemRecNSwitchNodeC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 NodeID
+ )
+{
+ NBPtr->MCTPtr = &(NBPtr->AllNodeMCTPtr[NodeID]);
+ NBPtr->Node = NodeID;
+ NBPtr->MCTPtr->NodeId = NodeID;
+ MemRecNSwitchDctC32 (NBPtr, NBPtr->Dct);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current DCT to work on.
+ * Should be called before accessing a certain DCT
+ * All data structures will be updated to point to the current DCT
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Dct - ID of the target DCT
+ *
+ */
+
+VOID
+MemRecNSwitchDctC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ )
+{
+ NBPtr->Dct = Dct & 1;
+ NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[(NBPtr->MCTPtr->NodeId * MAX_DCTS_PER_DIE + Dct) * MAX_DIMMS_PER_CHANNEL]);
+ NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
+
+ MemRecNSwitchChannelC32 (NBPtr, 0);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current channel to work on.
+ * Should be called before accessing a certain channel
+ * All data structures will be updated to point to the current channel
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Channel - ID of the target channel
+ *
+ */
+
+VOID
+MemRecNSwitchChannelC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ )
+{
+ NBPtr->Channel = 0;
+ NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[0]);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or set DQS timing during training.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ UINT16 index;
+ UINT16 offset;
+ UINT32 value;
+ UINT32 address;
+ UINT8 DIMM;
+ UINT8 Rank;
+ UINT8 Byte;
+ UINT8 Nibble;
+
+ DIMM = DRBN_DIMM (DrbnVar);
+ Rank = DRBN_RANK (DrbnVar);
+ Byte = DRBN_BYTE (DrbnVar);
+ Nibble = DRBN_NBBL (DrbnVar);
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ index = 0x10;
+ break;
+ case AccessWrDqsDly:
+ index = 0x30;
+ break;
+ case AccessWrDatDly:
+ index = 0x01;
+ break;
+ case AccessRdDqsDly:
+ index = 0x05;
+ break;
+ case AccessPhRecDly:
+ index = 0x50;
+ break;
+ default:
+ index = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ case AccessWrDqsDly:
+ index += (DIMM * 3);
+ if ((Byte & 0x04) != 0) {
+ // if byte 4,5,6,7
+ index += 0x10;
+ }
+ if ((Byte & 0x02) != 0) {
+ // if byte 2,3,6,7
+ index++;
+ }
+ if (Byte > 7) {
+ index += 2;
+ }
+ offset = 16 * (Byte % 2);
+ index |= (Rank << 8);
+ index |= (Nibble << 9);
+ break;
+
+ case AccessRdDqsDly:
+ Field &= ~ 0x0001;
+ case AccessWrDatDly:
+ index += (DIMM * 0x100);
+ if (Nibble != 0) {
+ if (Rank != 0) {
+ index += 0xA0;
+ } else {
+ index += 0x70;
+ }
+ } else if (Rank != 0) {
+ index += 0x60;
+ }
+ // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
+ // to run AccessPhRecDly sequence.
+ case AccessPhRecDly:
+ index += (Byte / 4);
+ offset = 8 * (Byte % 4);
+ break;
+ default:
+ offset = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ address = index;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+
+ if (IsSet != 0) {
+ if (TrnDly == AccessPhRecDly) {
+ value = NBPtr->DctCachePtr->PhRecReg[index & 0x03];
+ }
+
+ value = ((UINT32)Field << offset) | (value & (~((UINT32)0xFF << offset)));
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, value);
+ address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ if (TrnDly == AccessPhRecDly) {
+ NBPtr->DctCachePtr->PhRecReg[index & 0x03] = value;
+ }
+ } else {
+ value = (value >> offset) & 0xFF;
+ }
+
+ return value;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or sets a value to a bit field in a PCI register.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] FieldName - Name of Field to be set
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ SBDFO Address;
+ PCI_ADDR PciAddr;
+ UINT8 Type;
+ UINT32 Value;
+ UINT32 Highbit;
+ UINT32 Lowbit;
+ UINT32 Mask;
+
+ Value = 0;
+ if (FieldName < BFEndOfList) {
+ Address = NBPtr->NBRegTable[FieldName];
+ if (Address != 0) {
+ Lowbit = TSEFO_END (Address);
+ Highbit = TSEFO_START (Address);
+ Type = TSEFO_TYPE (Address);
+
+ // If Fn2 and DCT1 selected, set Address to be 1xx
+ if (((Address & 0xF000) == 0x2000) && (NBPtr->Dct != 0)) {
+ Address |= 0x0100;
+ }
+ if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
+ // Special DCT Phy access
+ Address &= 0x0FFFFFFF;
+ Lowbit = 0;
+ Highbit = 16;
+ } else {
+ // Normal DCT Phy access
+ Address = TSEFO_OFFSET (Address);
+ }
+
+
+ if (Type == NB_ACCESS) {
+ // Address |= (((UINT32) (24 + 0)) << 15);
+ PciAddr.AddressValue = Address;
+ // Fix for MCM
+ PciAddr.Address.Device = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Device;
+ PciAddr.Address.Bus = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Bus;
+ PciAddr.Address.Segment = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Segment;
+ Address = PciAddr.AddressValue;
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (IsSet != 0) {
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32)0xFFFFFFFF;
+ }
+ Value &= ~(Mask << Lowbit);
+ Value |= (Field & Mask) << Lowbit;
+
+ if (Type == NB_ACCESS) {
+ PciAddr.AddressValue = Address;
+ LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ } else {
+ IDS_ERROR_TRAP;
+ }
+ } else {
+ Value = Value >> Lowbit; // Shift
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ }
+ }
+ }
+ } else {
+ IDS_ERROR_TRAP; // Invalid bit field index
+ }
+ return Value;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes bit field translation table
+ *
+* @param[in,out] *NBRegTable - Pointer to the NB Table *
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableC32 (
+ IN OUT TSEFO *NBRegTable
+ )
+{
+ UINT16 i;
+ for (i = 0; i <= BFEndOfList; i++) {
+ NBRegTable[i] = 0;
+ }
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 5, 5, BFSubMemclkRegDly);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 31, 0, BFMctCfgHiReg);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
+
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ * MemRecNIsIdSupportedC32
+ * This function matches the CPU_LOGICAL_ID with certain criteria to
+ * determine if it is supported by this NBBlock.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ *
+ * @return TRUE - This node is a C32.
+ * @return FALSE - This node is not a C32.
+ *
+ */
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ )
+{
+ if ((LogicalIdPtr->Revision & AMD_F10_C32_ALL) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnc32.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnc32.h
new file mode 100644
index 0000000000..2d851ce1b7
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnc32.h
@@ -0,0 +1,110 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mnc32.h
+ *
+ * Northbridge C32 Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRNC32_H_
+#define _MRNC32_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_DCTS_PER_NODE_C32 2
+#define MAX_CHANNELS_PER_DCT_C32 1
+
+#define _4GB_RJ8 ((UINT32)4 << (30 - 8))
+#define MTRR_VALID 11
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BOOLEAN
+MemRecConstructNBBlockC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ );
+
+VOID
+MemRecNSwitchDctC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ );
+
+VOID
+MemRecNSwitchChannelC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ );
+
+VOID
+MemRecNFinalizeMctC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+MemRecNInitializeMctC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+#endif /* _MRNC32_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnmctc32.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnmctc32.c
new file mode 100644
index 0000000000..bc22a8c254
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnmctc32.c
@@ -0,0 +1,162 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnmctc32.c
+ *
+ * Northbridge C32 MCT supporting functions Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnc32.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_C32_MRNMCTC32_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets final values in BUCFG and BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNFinalizeMctC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MEM_DATA_STRUCT *MemPtr;
+ S_UINT64 SMsr;
+
+ MemPtr = NBPtr->MemPtr;
+
+ // Recommended settings for F2x11C
+ MemRecNSetBitFieldNb (NBPtr, BFMctCfgHiReg, 0x2CE00F60);
+
+ LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ if (!NBPtr->ClToNbFlag) {
+ SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis
+ }
+ LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis
+ LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets initial values in BUCFG and BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNInitializeMctC32 (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MEM_DATA_STRUCT *MemPtr;
+ S_UINT64 SMsr;
+
+ MemPtr = NBPtr->MemPtr;
+
+ LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ if (SMsr.lo & ((UINT32) 1 << 15)) {
+ NBPtr->ClToNbFlag = TRUE;
+ }
+ SMsr.lo |= (UINT32) 1 << 15; // ClLinesToNbDis
+ LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.hi |= (UINT32) 1 << (48 - 32); // WbEnhWsbDis
+ LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnprotoc32.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnprotoc32.c
new file mode 100644
index 0000000000..8259742f88
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/C32/mrnprotoc32.c
@@ -0,0 +1,62 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnprotoc32.c
+ *
+ * Northbridge support functions for Errata and early samples Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_C32_MRNPROTOC32_FILECODE
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnda.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnda.c
new file mode 100644
index 0000000000..8281f61ea9
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnda.c
@@ -0,0 +1,651 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnda.c
+ *
+ * Common Northbridge functions for Ridgeback Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnda.h"
+#include "heapManager.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_DA_MRNDA_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableDA (
+ IN OUT TSEFO *NBRegTable
+ );
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ );
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ );
+
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the northbridge block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ * @param[in] NodeID - Node ID for this NB block
+ *
+ * @return TRUE - This node is a RB and this NB block has been initialized
+ * @return FALSE - This node is not a RB
+ */
+
+BOOLEAN
+MemRecConstructNBBlockDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ )
+{
+ UINT8 i;
+ UINT8 Dct;
+ UINT8 Channel;
+ DIE_STRUCT *MCTPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ //
+ // Determine if this is the expected NB Type
+ //
+ GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+ if (!MemRecNIsIdSupportedDA (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ //
+ MCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DA * (
+ sizeof (DCT_STRUCT) + (
+ MAX_CHANNELS_PER_DCT_DA * (
+ sizeof (CH_DEF_STRUCT) + (
+ MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
+ )
+ )
+ )
+ );
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ return FALSE;
+ }
+
+ MemPtr->DieCount = 1;
+ MCTPtr->DctCount = MAX_DCTS_PER_NODE_DA;
+ MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT);
+ for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) {
+ MCTPtr->DctData[Dct].Dct = Dct;
+ MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA;
+ MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct;
+ AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DA * sizeof (CH_DEF_STRUCT);
+ for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; Channel++) {
+ MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
+ MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
+ }
+ }
+
+ //
+ // Initialize NB block's variables
+ //
+ NBPtr->MemPtr = MemPtr;
+ NBPtr->RefPtr = MemPtr->ParameterListPtr;
+ NBPtr->MCTPtr = MCTPtr;
+ NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+ NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+
+ MemRecNInitNBRegTableDA (NBPtr->NBRegTable);
+ NBPtr->Dct = 0;
+ NBPtr->Channel = 0;
+ NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+
+ LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
+ LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
+ for (i = 0; i < NumberOfHooks; i++) {
+ NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
+ }
+
+ NBPtr->InitRecovery = MemRecNMemInitNb;
+
+ NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->SwitchDCT = MemRecNSwitchDctDA;
+ NBPtr->SwitchChannel = MemRecNSwitchChannelDA;
+ NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
+ NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
+ NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
+ NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
+ NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
+
+ NBPtr->GetBitField = MemRecNGetBitFieldNb;
+ NBPtr->SetBitField = MemRecNSetBitFieldNb;
+ NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
+ NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
+ NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldDA;
+ NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyDA;
+ NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctDA;
+ NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
+ NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctDA;
+ NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDA;
+ NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE;
+ NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE;
+ MemRecNSwitchDctDA (NBPtr, 0);
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current DCT to work on.
+ * Should be called before accessing a certain DCT
+ * All data structures will be updated to point to the current DCT
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Dct - ID of the target DCT
+ *
+ */
+
+VOID
+MemRecNSwitchDctDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ )
+{
+ NBPtr->Dct = Dct & 1;
+ NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]);
+ NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
+
+ MemRecNSwitchChannelDA (NBPtr, NBPtr->Channel);
+}
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current channel to work on.
+ * Should be called before accessing a certain channel
+ * All data structures will be updated to point to the current channel
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Channel - ID of the target channel
+ *
+ */
+
+VOID
+MemRecNSwitchChannelDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ )
+{
+ NBPtr->Channel = Channel & 1;
+ NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]);
+}
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or set DQS timing during training.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ UINT16 Index;
+ UINT16 Offset;
+ UINT32 Value;
+ UINT32 Address;
+ UINT8 Dimm;
+ UINT8 Byte;
+
+ Dimm = DRBN_DIMM (DrbnVar);
+ Byte = DRBN_BYTE (DrbnVar);
+
+ ASSERT (Dimm < 4);
+ ASSERT (Byte <= 8);
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ Index = 0x10;
+ break;
+ case AccessWrDqsDly:
+ Index = 0x30;
+ break;
+ case AccessWrDatDly:
+ Index = 0x01;
+ break;
+ case AccessRdDqsDly:
+ Index = 0x05;
+ break;
+ case AccessPhRecDly:
+ Index = 0x50;
+ break;
+ default:
+ Index = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ case AccessWrDqsDly:
+ Index += (Dimm * 3);
+ if (Byte & 0x04) {
+ // if byte 4,5,6,7
+ Index += 0x10;
+ }
+ if (Byte & 0x02) {
+ // if byte 2,3,6,7
+ Index++;
+ }
+ Offset = 16 * (Byte % 2);
+ break;
+
+ case AccessRdDqsDly:
+ Field &= ~ 0x0001;
+ case AccessWrDatDly:
+ Index += (Dimm * 0x100);
+ // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
+ // to run AccessPhRecDly sequence.
+ case AccessPhRecDly:
+ Index += (Byte / 4);
+ Offset = 8 * (Byte % 4);
+ break;
+ default:
+ Offset = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ Address = Index;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+
+ if (IsSet) {
+ if (TrnDly == AccessPhRecDly) {
+ Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
+ }
+
+ Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset)));
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ if (TrnDly == AccessPhRecDly) {
+ NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
+ }
+ } else {
+ Value = (Value >> Offset) & 0xFF;
+ }
+
+ return Value;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or sets a value to a bit field in a PCI register.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] IsSet - Indicates if the function will set or get
+ * @param[in] FieldName - Name of field to be set
+ * @param[in] Field - Value to be programmed
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ SBDFO Address;
+ PCI_ADDR PciAddr;
+ UINT8 Type;
+ UINT32 Value;
+ UINT32 Highbit;
+ UINT32 Lowbit;
+ UINT32 Mask;
+
+ Value = 0;
+ if (FieldName < BFEndOfList) {
+ Address = NBPtr->NBRegTable[FieldName];
+ if (Address) {
+ Lowbit = TSEFO_END (Address);
+ Highbit = TSEFO_START (Address);
+ Type = TSEFO_TYPE (Address);
+
+ // If Fn2 and DCT1 selected, set Address to be 1xx
+ if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) {
+ Address |= 0x0100;
+ }
+ if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
+ // Special DCT Phy access
+ Address &= 0x0FFFFFFF;
+ Lowbit = 0;
+ Highbit = 16;
+ } else {
+ // Normal DCT Phy access
+ Address = TSEFO_OFFSET (Address);
+ }
+
+
+ if (Type == NB_ACCESS) {
+ Address |= (((UINT32) (24 + 0)) << 15);
+ PciAddr.AddressValue = Address;
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (IsSet) {
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32)0xFFFFFFFF;
+ }
+ Value &= ~(Mask << Lowbit);
+ Value |= (Field & Mask) << Lowbit;
+
+ if (Type == NB_ACCESS) {
+ PciAddr.AddressValue = Address;
+ LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ } else {
+ IDS_ERROR_TRAP;
+ }
+ } else {
+ Value = Value >> Lowbit; // Shift
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ }
+ }
+ }
+ } else {
+ IDS_ERROR_TRAP; // Invalid bit field index
+ }
+ return Value;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes bit field translation table
+ *
+ * @param[in,out] *NBRegTable - Pointer to the NB Table *
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableDA (
+ IN OUT TSEFO *NBRegTable
+ )
+{
+ UINT16 i;
+ for (i = 0; i <= BFEndOfList; i++) {
+ NBRegTable[i] = 0;
+ }
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFMctWrLimit);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
+
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ * MemRecNIsIdSupportedDA
+ * This function matches the CPU_LOGICAL_ID with certain criteria to
+ * determine if it is supported by this NBBlock.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ *
+ */
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ )
+{
+
+ if ((LogicalIdPtr->Revision & (AMD_F10_BL_ALL | AMD_F10_DA_ALL)) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnda.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnda.h
new file mode 100644
index 0000000000..5652cec879
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnda.h
@@ -0,0 +1,110 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mnda.h
+ *
+ * Northbridge Ridgeback Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRNDA_H_
+#define _MRNDA_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_DCTS_PER_NODE_DA 2
+#define MAX_CHANNELS_PER_DCT_DA 1
+
+#define _4GB_RJ8 ((UINT32)4 << (30 - 8))
+#define MTRR_VALID 11
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BOOLEAN
+MemRecConstructNBBlockDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ );
+
+VOID
+MemRecNSwitchDctDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ );
+
+VOID
+MemRecNSwitchChannelDA (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ );
+
+VOID
+MemRecNFinalizeMctDA (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+MemRecNInitializeMctDA (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+#endif /* _MRNDA_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnmctda.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnmctda.c
new file mode 100644
index 0000000000..3cb2cfd31b
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DA/mrnmctda.c
@@ -0,0 +1,165 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnmctda.c
+ *
+ * Northbridge DA MCT supporting functions Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnda.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_DA_MRNMCTDA_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets final values in BUCFG and BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNFinalizeMctDA (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MEM_DATA_STRUCT *MemPtr;
+ S_UINT64 SMsr;
+
+ MemPtr = NBPtr->MemPtr;
+
+
+ // Recommended settings for F2x11C
+ MemRecNSetBitFieldNb (NBPtr, BFMctWrLimit, 16);
+ MemRecNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0);
+ MemRecNSetBitFieldNb (NBPtr, BFPrefIoDis, 0);
+ MemRecNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1);
+
+ LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ if (!NBPtr->ClToNbFlag) {
+ SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis
+ }
+ LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis
+ LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets initial values in BUCFG and BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNInitializeMctDA (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MEM_DATA_STRUCT *MemPtr;
+ S_UINT64 SMsr;
+
+ MemPtr = NBPtr->MemPtr;
+
+ LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ if (SMsr.lo & ((UINT32) 1 << 15)) {
+ NBPtr->ClToNbFlag = TRUE;
+ }
+ SMsr.lo |= (UINT32) 1 << 15; // ClLinesToNbDis
+ LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.hi |= (UINT32) 1 << (48 - 32); // WbEnhWsbDis
+ LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrndr.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrndr.c
new file mode 100644
index 0000000000..e30f2b7837
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrndr.c
@@ -0,0 +1,655 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrndr.c
+ *
+ * Common Northbridge functions for Ridgeback Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrndr.h"
+#include "heapManager.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_DR_MRNDR_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableDR (
+ IN OUT TSEFO *NBRegTable
+ );
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ );
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ );
+
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedDr (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the northbridge block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ * @param[in] NodeID - Node ID for this NB block
+ *
+ * @return TRUE - This node is a RB and this NB block has been initialized
+ * @return FALSE - This node is not a RB
+ */
+
+BOOLEAN
+MemRecConstructNBBlockDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ )
+{
+ UINT8 i;
+ UINT8 Dct;
+ UINT8 Channel;
+ DIE_STRUCT *MCTPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ //
+ // Determine if this is the expected NB Type
+ //
+ GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+ if (!MemRecNIsIdSupportedDr (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ //
+ MCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DR * (
+ sizeof (DCT_STRUCT) + (
+ MAX_CHANNELS_PER_DCT_DR * (
+ sizeof (CH_DEF_STRUCT) + (
+ MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
+ )
+ )
+ )
+ );
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ return FALSE;
+ }
+
+ MemPtr->DieCount = 1;
+ MCTPtr->DctCount = MAX_DCTS_PER_NODE_DR;
+ MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DR * sizeof (DCT_STRUCT);
+ for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DR; Dct++) {
+ MCTPtr->DctData[Dct].Dct = Dct;
+ MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DR;
+ MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct;
+ AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DR * sizeof (CH_DEF_STRUCT);
+ for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DR; Channel++) {
+ MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
+ MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
+ }
+ }
+
+ //
+ // Initialize NB block's variables
+ //
+ NBPtr->MemPtr = MemPtr;
+ NBPtr->RefPtr = MemPtr->ParameterListPtr;
+ NBPtr->MCTPtr = MCTPtr;
+ NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+ NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+
+ MemRecNInitNBRegTableDR (NBPtr->NBRegTable);
+ NBPtr->Dct = 0;
+ NBPtr->Channel = 0;
+ NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+
+ LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
+ LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
+ for (i = 0; i < NumberOfHooks; i++) {
+ NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
+ }
+
+ NBPtr->InitRecovery = MemRecNMemInitNb;
+
+ NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->SwitchDCT = MemRecNSwitchDctDR;
+ NBPtr->SwitchChannel = MemRecNSwitchChannelDR;
+ NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
+ NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
+ NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
+ NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
+ NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
+
+ NBPtr->GetBitField = MemRecNGetBitFieldNb;
+ NBPtr->SetBitField = MemRecNSetBitFieldNb;
+ NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
+ NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
+ NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldDR;
+ NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyDR;
+ NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctDR;
+ NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
+ NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctDR;
+ NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDR;
+ NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE;
+ NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE;
+ MemRecNSwitchDctDR (NBPtr, 0);
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current DCT to work on.
+ * Should be called before accessing a certain DCT
+ * All data structures will be updated to point to the current DCT
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Dct - ID of the target DCT
+ *
+ */
+
+VOID
+MemRecNSwitchDctDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ )
+{
+ NBPtr->Dct = Dct & 1;
+ NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]);
+ NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
+
+ MemRecNSwitchChannelDR (NBPtr, NBPtr->Channel);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current channel to work on.
+ * Should be called before accessing a certain channel
+ * All data structures will be updated to point to the current channel
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Channel - ID of the target channel
+ *
+ */
+
+VOID
+MemRecNSwitchChannelDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ )
+{
+ NBPtr->Channel = Channel & 1;
+ NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]);
+}
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or set DQS timing during training.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ UINT16 Index;
+ UINT16 Offset;
+ UINT32 Value;
+ UINT32 Address;
+ UINT8 Dimm;
+ UINT8 Byte;
+
+ Dimm = DRBN_DIMM (DrbnVar);
+ Byte = DRBN_BYTE (DrbnVar);
+
+ ASSERT (Dimm < 4);
+ ASSERT (Byte <= 8);
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ Index = 0x10;
+ break;
+ case AccessWrDqsDly:
+ Index = 0x30;
+ break;
+ case AccessWrDatDly:
+ Index = 0x01;
+ break;
+ case AccessRdDqsDly:
+ Index = 0x05;
+ break;
+ case AccessPhRecDly:
+ Index = 0x50;
+ break;
+ default:
+ Index = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ case AccessWrDqsDly:
+ Index += (Dimm * 3);
+ if (Byte & 0x04) {
+ // if byte 4,5,6,7
+ Index += 0x10;
+ }
+ if (Byte & 0x02) {
+ // if byte 2,3,6,7
+ Index++;
+ }
+ Offset = 16 * (Byte % 2);
+ break;
+
+ case AccessRdDqsDly:
+ Field &= ~ 0x0001;
+ case AccessWrDatDly:
+ Index += (Dimm * 0x100);
+ // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
+ // to run AccessPhRecDly sequence.
+ case AccessPhRecDly:
+ Index += (Byte / 4);
+ Offset = 8 * (Byte % 4);
+ break;
+ default:
+ Offset = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ Address = Index;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+
+ if (IsSet) {
+ if (TrnDly == AccessPhRecDly) {
+ Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
+ }
+
+ Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset)));
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ if (TrnDly == AccessPhRecDly) {
+ NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
+ }
+ } else {
+ Value = (Value >> Offset) & 0xFF;
+ }
+
+ return Value;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or sets a value to a bit field in a PCI register.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] IsSet - Indicates if the function will set or get
+ * @param[in] FieldName - Name of field to be set
+ * @param[in] Field - Value to be programmed
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ SBDFO Address;
+ PCI_ADDR PciAddr;
+ UINT8 Type;
+ UINT32 Value;
+ UINT32 Highbit;
+ UINT32 Lowbit;
+ UINT32 Mask;
+
+ Value = 0;
+ if (FieldName < BFEndOfList) {
+ Address = NBPtr->NBRegTable[FieldName];
+ if (Address) {
+ Lowbit = TSEFO_END (Address);
+ Highbit = TSEFO_START (Address);
+ Type = TSEFO_TYPE (Address);
+
+ // If Fn2 and DCT1 selected, set Address to be 1xx
+ if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) {
+ Address |= 0x0100;
+ }
+ if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
+ // Special DCT Phy access
+ Address &= 0x0FFFFFFF;
+ Lowbit = 0;
+ Highbit = 16;
+ } else {
+ // Normal DCT Phy access
+ Address = TSEFO_OFFSET (Address);
+ }
+
+
+ if (Type == NB_ACCESS) {
+ Address |= (((UINT32) (24 + 0)) << 15);
+ PciAddr.AddressValue = Address;
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (IsSet) {
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32)0xFFFFFFFF;
+ }
+ Value &= ~(Mask << Lowbit);
+ Value |= (Field & Mask) << Lowbit;
+
+ if (Type == NB_ACCESS) {
+ PciAddr.AddressValue = Address;
+ LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ } else {
+ IDS_ERROR_TRAP;
+ }
+ } else {
+ Value = Value >> Lowbit; // Shift
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ }
+ }
+ }
+ } else {
+ IDS_ERROR_TRAP; // Invalid bit field index
+ }
+ return Value;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes bit field translation table
+ *
+ * @param[in,out] *NBRegTable - Pointer to the NB Table *
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableDR (
+ IN OUT TSEFO *NBRegTable
+ )
+{
+ UINT16 i;
+ for (i = 0; i <= BFEndOfList; i++) {
+ NBRegTable[i] = 0;
+ }
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 5, 5, BFSubMemclkRegDly);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFMctWrLimit);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
+
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ * MemRecNIsIdSupportedDr
+ * This function matches the CPU_LOGICAL_ID with certain criteria to
+ * determine if it is supported by this NBBlock.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ *
+ */
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedDr (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ )
+{
+
+ if ((LogicalIdPtr->Revision & (AMD_F10_RB_ALL
+ | AMD_F10_BL_ALL
+ | AMD_F10_DA_ALL )) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrndr.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrndr.h
new file mode 100644
index 0000000000..2181ae5786
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrndr.h
@@ -0,0 +1,110 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mndr.h
+ *
+ * Northbridge Ridgeback Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRNDR_H_
+#define _MRNDR_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_DCTS_PER_NODE_DR 2
+#define MAX_CHANNELS_PER_DCT_DR 1
+
+#define _4GB_RJ8 ((UINT32)4 << (30 - 8))
+#define MTRR_VALID 11
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BOOLEAN
+MemRecConstructNBBlockDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ );
+
+VOID
+MemRecNSwitchDctDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ );
+
+VOID
+MemRecNSwitchChannelDR (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ );
+
+VOID
+MemRecNFinalizeMctDR (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+MemRecNInitializeMctDR (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+#endif /* _MRNDR_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrnmctdr.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrnmctdr.c
new file mode 100644
index 0000000000..8ca2fae008
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/DR/mrnmctdr.c
@@ -0,0 +1,167 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnmctdr.c
+ *
+ * Northbridge DR MCT supporting functions Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mrndr.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_DR_MRNMCTDR_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets final values in BUCFG and BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNFinalizeMctDR (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MEM_DATA_STRUCT *MemPtr;
+ S_UINT64 SMsr;
+
+ MemPtr = NBPtr->MemPtr;
+
+
+ // Recommended settings for F2x11C
+ MemRecNSetBitFieldNb (NBPtr, BFMctWrLimit, 16);
+ MemRecNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0);
+ MemRecNSetBitFieldNb (NBPtr, BFPrefIoDis, 0);
+ MemRecNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1);
+
+ LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ if (!NBPtr->ClToNbFlag) {
+ SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis
+ }
+ LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis
+ LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets initial values in BUCFG and BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNInitializeMctDR (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MEM_DATA_STRUCT *MemPtr;
+ S_UINT64 SMsr;
+
+ MemPtr = NBPtr->MemPtr;
+
+ LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ if (SMsr.lo & ((UINT32) 1 << 15)) {
+ NBPtr->ClToNbFlag = TRUE;
+ }
+ SMsr.lo |= (UINT32) 1 << 15; // ClLinesToNbDis
+ LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.hi |= (UINT32) 1 << (48 - 32); // WbEnhWsbDis
+ LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrndcthy.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrndcthy.c
new file mode 100644
index 0000000000..c908382bd6
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrndcthy.c
@@ -0,0 +1,76 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrndctHy.c
+ *
+ * Northbridge DCT support for Hydra Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Ids.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mru.h"
+#include "mrnhy.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_HY_MRNDCTHY_FILECODE
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnhy.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnhy.c
new file mode 100644
index 0000000000..453308ade8
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnhy.c
@@ -0,0 +1,710 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnhy.c
+ *
+ * Common Northbridge functions for Hydra Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnhy.h"
+#include "heapManager.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_RECOVERY_MEM_NB_HY_MRNHY_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_DIES_PER_SOCKET 2
+#define MAX_DCTS_PER_DIE 2
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableHy (
+ IN OUT TSEFO *NBRegTable
+ );
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ );
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ );
+
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ );
+
+VOID
+STATIC
+MemRecNSwitchNodeHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 NodeID
+ );
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the northbridge block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ * @param[in] NodeID - Node ID for this NB block
+ *
+ * @return TRUE - This node is a Hydra and this NB block has been initialized
+ * @return FALSE - This node is not a Hydra
+ */
+
+BOOLEAN
+MemRecConstructNBBlockHY (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ )
+{
+ UINT8 i;
+ UINT8 Dct;
+ UINT8 Channel;
+ DIE_STRUCT *MCTPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ //
+ // Determine if this is the expected NB Type
+ //
+ GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+ if (!MemRecNIsIdSupportedHy (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ //
+ MCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_HY * (
+ sizeof (DCT_STRUCT) + (
+ MAX_CHANNELS_PER_DCT_HY * (
+ sizeof (CH_DEF_STRUCT) + (
+ MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
+ )
+ )
+ )
+ );
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ return FALSE;
+ }
+
+ MemPtr->DieCount = MAX_DIES_PER_SOCKET;
+ MCTPtr->DctCount = MAX_DCTS_PER_NODE_HY;
+ MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ MemPtr->DiesPerSystem[NodeID + 1].DctCount = MAX_DCTS_PER_NODE_HY;
+ MemPtr->DiesPerSystem[NodeID + 1].DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_HY * sizeof (DCT_STRUCT);
+ for (Dct = 0; Dct < MAX_DCTS_PER_NODE_HY; Dct++) {
+ MCTPtr->DctData[Dct].Dct = Dct;
+ MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_HY;
+ MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[0].ChannelID = (MCTPtr->DieId * 2) + Dct;
+ AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_HY * sizeof (CH_DEF_STRUCT);
+ for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_HY; Channel++) {
+ MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
+ MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
+ }
+ }
+
+ //
+ // Initialize NB block's variables
+ //
+ NBPtr->MemPtr = MemPtr;
+ NBPtr->RefPtr = MemPtr->ParameterListPtr;
+ NBPtr->MCTPtr = MCTPtr;
+ NBPtr->AllNodeMCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+ NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+
+ MemRecNInitNBRegTableHy (NBPtr->NBRegTable);
+ NBPtr->Dct = 0;
+ NBPtr->Channel = 0;
+ NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+
+ LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
+ LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
+ for (i = 0; i < NumberOfHooks; i++) {
+ NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
+ }
+
+ NBPtr->InitRecovery = MemRecNMemInitNb;
+
+ NBPtr->SwitchNodeRec = MemRecNSwitchNodeHy;
+ NBPtr->SwitchDCT = MemRecNSwitchDctHy;
+ NBPtr->SwitchChannel = MemRecNSwitchChannelHy;
+ NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
+ NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
+ NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
+ NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
+ NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
+
+ NBPtr->GetBitField = MemRecNGetBitFieldNb;
+ NBPtr->SetBitField = MemRecNSetBitFieldNb;
+ NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
+ NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
+
+ NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldHy;
+ NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyHy;
+ NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctHy;
+ NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
+ NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctHy;
+ NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctHy;
+ NBPtr->IsSupported[DramModeAfterDimmPres] = TRUE;
+ MemRecNSwitchDctHy (NBPtr, 0);
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function sets the current die to work on.
+ * Should be called before accessing a certain die
+ * All data structures will be updated to point to the current node
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] NodeID - ID of the target die
+ *
+ */
+
+VOID
+STATIC
+MemRecNSwitchNodeHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 NodeID
+ )
+{
+ NBPtr->MCTPtr = &(NBPtr->AllNodeMCTPtr[NodeID]);
+ NBPtr->Node = NodeID;
+ NBPtr->MCTPtr->NodeId = NodeID;
+ MemRecNSwitchDctHy (NBPtr, NBPtr->Dct);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current DCT to work on.
+ * Should be called before accessing a certain DCT
+ * All data structures will be updated to point to the current DCT
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Dct - ID of the target DCT
+ *
+ */
+
+VOID
+MemRecNSwitchDctHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ )
+{
+ NBPtr->Dct = Dct & 1;
+ NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[(NBPtr->MCTPtr->NodeId * MAX_DCTS_PER_DIE + Dct) * MAX_DIMMS_PER_CHANNEL]);
+ NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
+
+ MemRecNSwitchChannelHy (NBPtr, 0);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current channel to work on.
+ * Should be called before accessing a certain channel
+ * All data structures will be updated to point to the current channel
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Channel - ID of the target channel
+ *
+ */
+
+VOID
+MemRecNSwitchChannelHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ )
+{
+ NBPtr->Channel = 0;
+ NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[0]);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or set DQS timing during training.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ UINT16 index;
+ UINT16 offset;
+ UINT32 value;
+ UINT32 address;
+ UINT8 DIMM;
+ UINT8 Rank;
+ UINT8 Byte;
+ UINT8 Nibble;
+
+ DIMM = DRBN_DIMM (DrbnVar);
+ Rank = DRBN_RANK (DrbnVar);
+ Byte = DRBN_BYTE (DrbnVar);
+ Nibble = DRBN_NBBL (DrbnVar);
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ index = 0x10;
+ break;
+ case AccessWrDqsDly:
+ index = 0x30;
+ break;
+ case AccessWrDatDly:
+ index = 0x01;
+ break;
+ case AccessRdDqsDly:
+ index = 0x05;
+ break;
+ case AccessPhRecDly:
+ index = 0x50;
+ break;
+ default:
+ index = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ case AccessWrDqsDly:
+ index += (DIMM * 3);
+ if ((Byte & 0x04) != 0) {
+ // if byte 4,5,6,7
+ index += 0x10;
+ }
+ if ((Byte & 0x02) != 0) {
+ // if byte 2,3,6,7
+ index++;
+ }
+ if (Byte > 7) {
+ index += 2;
+ }
+ offset = 16 * (Byte % 2);
+ index |= (Rank << 8);
+ index |= (Nibble << 9);
+ break;
+
+ case AccessRdDqsDly:
+ Field &= ~ 0x0001;
+ case AccessWrDatDly:
+ index += (DIMM * 0x100);
+ if (Nibble != 0) {
+ if (Rank != 0) {
+ index += 0xA0;
+ } else {
+ index += 0x70;
+ }
+ } else if (Rank != 0) {
+ index += 0x60;
+ }
+ // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
+ // to run AccessPhRecDly sequence.
+ case AccessPhRecDly:
+ index += (Byte / 4);
+ offset = 8 * (Byte % 4);
+ break;
+ default:
+ offset = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ address = index;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+
+ if (IsSet != 0) {
+ if (TrnDly == AccessPhRecDly) {
+ value = NBPtr->DctCachePtr->PhRecReg[index & 0x03];
+ }
+
+ value = ((UINT32)Field << offset) | (value & (~((UINT32)0xFF << offset)));
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, value);
+ address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ if (TrnDly == AccessPhRecDly) {
+ NBPtr->DctCachePtr->PhRecReg[index & 0x03] = value;
+ }
+ } else {
+ value = (value >> offset) & 0xFF;
+ }
+
+ return value;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or sets a value to a bit field in a PCI register.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] FieldName - Name of Field to be set
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ SBDFO Address;
+ PCI_ADDR PciAddr;
+ UINT8 Type;
+ UINT32 Value;
+ UINT32 Highbit;
+ UINT32 Lowbit;
+ UINT32 Mask;
+
+ Value = 0;
+ if (FieldName < BFEndOfList) {
+ Address = NBPtr->NBRegTable[FieldName];
+ if (Address != 0) {
+ Lowbit = TSEFO_END (Address);
+ Highbit = TSEFO_START (Address);
+ Type = TSEFO_TYPE (Address);
+
+ // If Fn2 and DCT1 selected, set Address to be 1xx
+ if (((Address & 0xF000) == 0x2000) && (NBPtr->Dct != 0)) {
+ Address |= 0x0100;
+ }
+ if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
+ // Special DCT Phy access
+ Address &= 0x0FFFFFFF;
+ Lowbit = 0;
+ Highbit = 16;
+ } else {
+ // Normal DCT Phy access
+ Address = TSEFO_OFFSET (Address);
+ }
+
+
+ if (Type == NB_ACCESS) {
+ // Address |= (((UINT32) (24 + 0)) << 15);
+ PciAddr.AddressValue = Address;
+ // Fix for MCM
+ PciAddr.Address.Device = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Device;
+ PciAddr.Address.Bus = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Bus;
+ PciAddr.Address.Segment = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Segment;
+ Address = PciAddr.AddressValue;
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (IsSet != 0) {
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32)0xFFFFFFFF;
+ }
+ Value &= ~(Mask << Lowbit);
+ Value |= (Field & Mask) << Lowbit;
+
+ if (Type == NB_ACCESS) {
+ PciAddr.AddressValue = Address;
+ LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ } else {
+ IDS_ERROR_TRAP;
+ }
+ } else {
+ Value = Value >> Lowbit; // Shift
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ }
+ }
+ }
+ } else {
+ IDS_ERROR_TRAP; // Invalid bit field index
+ }
+ return Value;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes bit field translation table
+ *
+* @param[in,out] *NBRegTable - Pointer to the NB Table *
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableHy (
+ IN OUT TSEFO *NBRegTable
+ )
+{
+ UINT16 i;
+ for (i = 0; i <= BFEndOfList; i++) {
+ NBRegTable[i] = 0;
+ }
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 5, 5, BFSubMemclkRegDly);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 31, 0, BFMctCfgHiReg);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
+
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ * MemRecNIsIdSupportedHy
+ * This function matches the CPU_LOGICAL_ID with certain criteria to
+ * determine if it is supported by this NBBlock.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ *
+ * @return TRUE - This node is a Hydra.
+ * @return FALSE - This node is not a Hydra.
+ *
+ */
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ )
+{
+ if ((LogicalIdPtr->Revision & AMD_F10_HY_ALL) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnhy.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnhy.h
new file mode 100644
index 0000000000..93c3d01911
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnhy.h
@@ -0,0 +1,110 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mnhy.h
+ *
+ * Northbridge Hydra Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRNHY_H_
+#define _MRNHY_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_DCTS_PER_NODE_HY 2
+#define MAX_CHANNELS_PER_DCT_HY 1
+
+#define _4GB_RJ8 ((UINT32)4 << (30 - 8))
+#define MTRR_VALID 11
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BOOLEAN
+MemRecConstructNBBlockHY (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ );
+
+VOID
+MemRecNSwitchDctHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ );
+
+VOID
+MemRecNSwitchChannelHy (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ );
+
+VOID
+MemRecNFinalizeMctHy (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+MemRecNInitializeMctHy (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+#endif /* _MRNHY_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnmcthy.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnmcthy.c
new file mode 100644
index 0000000000..60fbc9a73e
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnmcthy.c
@@ -0,0 +1,162 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnmctdr.c
+ *
+ * Northbridge DR MCT supporting functions Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnhy.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_HY_MRNMCTHY_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets final values in BUCFG and BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNFinalizeMctHy (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MEM_DATA_STRUCT *MemPtr;
+ S_UINT64 SMsr;
+
+ MemPtr = NBPtr->MemPtr;
+
+ // Recommended settings for F2x11C
+ MemRecNSetBitFieldNb (NBPtr, BFMctCfgHiReg, 0x2CE00F60);
+
+ LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ if (!NBPtr->ClToNbFlag) {
+ SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis
+ }
+ LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis
+ LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets initial values in BUCFG and BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNInitializeMctHy (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MEM_DATA_STRUCT *MemPtr;
+ S_UINT64 SMsr;
+
+ MemPtr = NBPtr->MemPtr;
+
+ LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ if (SMsr.lo & ((UINT32) 1 << 15)) {
+ NBPtr->ClToNbFlag = TRUE;
+ }
+ SMsr.lo |= (UINT32) 1 << 15; // ClLinesToNbDis
+ LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.hi |= (UINT32) 1 << (48 - 32); // WbEnhWsbDis
+ LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnprotohy.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnprotohy.c
new file mode 100644
index 0000000000..316b25d717
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/HY/mrnprotohy.c
@@ -0,0 +1,62 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnproto.c
+ *
+ * Northbridge support functions for Errata and early samples Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_HY_MRNPROTOHY_FILECODE
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/NI/mrnNi.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/NI/mrnNi.c
new file mode 100644
index 0000000000..1ed06f4772
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/NI/mrnNi.c
@@ -0,0 +1,651 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnNi.c
+ *
+ * Common Northbridge functions for Nile Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnda.h"
+#include "mrnNi.h"
+#include "heapManager.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_NI_MRNNI_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableNi (
+ IN OUT TSEFO *NBRegTable
+ );
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ );
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ );
+
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the northbridge block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ * @param[in] NodeID - Node ID for this NB block
+ *
+ * @return TRUE - This node is a RB and this NB block has been initialized
+ * @return FALSE - This node is not a RB
+ */
+
+BOOLEAN
+MemRecConstructNBBlockNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ )
+{
+ UINT8 i;
+ UINT8 Dct;
+ UINT8 Channel;
+ DIE_STRUCT *MCTPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ //
+ // Determine if this is the expected NB Type
+ //
+ GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+ if (!MemRecNIsIdSupportedNi (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ //
+ MCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DA * (
+ sizeof (DCT_STRUCT) + (
+ MAX_CHANNELS_PER_DCT_DA * (
+ sizeof (CH_DEF_STRUCT) + (
+ MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
+ )
+ )
+ )
+ );
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ return FALSE;
+ }
+
+ MCTPtr->DctCount = MAX_DCTS_PER_NODE_DA;
+ MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT);
+ for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) {
+ MCTPtr->DctData[Dct].Dct = Dct;
+ MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA;
+ MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct;
+ AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DA * sizeof (CH_DEF_STRUCT);
+ for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; Channel++) {
+ MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
+ MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
+ }
+ }
+
+ //
+ // Initialize NB block's variables
+ //
+ NBPtr->MemPtr = MemPtr;
+ NBPtr->RefPtr = MemPtr->ParameterListPtr;
+ NBPtr->MCTPtr = MCTPtr;
+ NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+ NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+
+ MemRecNInitNBRegTableNi (NBPtr->NBRegTable);
+ NBPtr->Dct = 0;
+ NBPtr->Channel = 0;
+ NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+
+ LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
+ LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
+ for (i = 0; i < NumberOfHooks; i++) {
+ NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
+ }
+
+ NBPtr->InitRecovery = MemRecNMemInitNb;
+
+ NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->SwitchDCT = MemRecNSwitchDctNi;
+ NBPtr->SwitchChannel = MemRecNSwitchChannelNi;
+ NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
+ NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
+ NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
+ NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
+ NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
+
+ NBPtr->GetBitField = MemRecNGetBitFieldNb;
+ NBPtr->SetBitField = MemRecNSetBitFieldNb;
+ NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
+ NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
+ NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldNi;
+ NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyNi;
+ NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctNi;
+ NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
+ NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctDA;
+ NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDA;
+ NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE;
+ NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE;
+ MemRecNSwitchDctNi (NBPtr, 0);
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current DCT to work on.
+ * Should be called before accessing a certain DCT
+ * All data structures will be updated to point to the current DCT
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Dct - ID of the target DCT
+ *
+ */
+
+VOID
+MemRecNSwitchDctNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ )
+{
+ NBPtr->Dct = Dct & 1;
+ NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]);
+ NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
+
+ MemRecNSwitchChannelNi (NBPtr, NBPtr->Channel);
+}
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current channel to work on.
+ * Should be called before accessing a certain channel
+ * All data structures will be updated to point to the current channel
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Channel - ID of the target channel
+ *
+ */
+
+VOID
+MemRecNSwitchChannelNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ )
+{
+ NBPtr->Channel = Channel & 1;
+ NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]);
+}
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or set DQS timing during training.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ UINT16 Index;
+ UINT16 Offset;
+ UINT32 Value;
+ UINT32 Address;
+ UINT8 Dimm;
+ UINT8 Byte;
+
+ Dimm = DRBN_DIMM (DrbnVar);
+ Byte = DRBN_BYTE (DrbnVar);
+
+ ASSERT (Dimm < 4);
+ ASSERT (Byte <= 8);
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ Index = 0x10;
+ break;
+ case AccessWrDqsDly:
+ Index = 0x30;
+ break;
+ case AccessWrDatDly:
+ Index = 0x01;
+ break;
+ case AccessRdDqsDly:
+ Index = 0x05;
+ break;
+ case AccessPhRecDly:
+ Index = 0x50;
+ break;
+ default:
+ Index = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ case AccessWrDqsDly:
+ Index += (Dimm * 3);
+ if (Byte & 0x04) {
+ // if byte 4,5,6,7
+ Index += 0x10;
+ }
+ if (Byte & 0x02) {
+ // if byte 2,3,6,7
+ Index++;
+ }
+ Offset = 16 * (Byte % 2);
+ break;
+
+ case AccessRdDqsDly:
+ Field &= ~ 0x0001;
+ case AccessWrDatDly:
+ Index += (Dimm * 0x100);
+ // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
+ // to run AccessPhRecDly sequence.
+ case AccessPhRecDly:
+ Index += (Byte / 4);
+ Offset = 8 * (Byte % 4);
+ break;
+ default:
+ Offset = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ Address = Index;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+
+ if (IsSet) {
+ if (TrnDly == AccessPhRecDly) {
+ Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
+ }
+
+ Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset)));
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ if (TrnDly == AccessPhRecDly) {
+ NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
+ }
+ } else {
+ Value = (Value >> Offset) & 0xFF;
+ }
+
+ return Value;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or sets a value to a bit field in a PCI register.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] IsSet - Indicates if the function will set or get
+ * @param[in] FieldName - Name of field to be set
+ * @param[in] Field - Value to be programmed
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ SBDFO Address;
+ PCI_ADDR PciAddr;
+ UINT8 Type;
+ UINT32 Value;
+ UINT32 Highbit;
+ UINT32 Lowbit;
+ UINT32 Mask;
+
+ Value = 0;
+ if (FieldName < BFEndOfList) {
+ Address = NBPtr->NBRegTable[FieldName];
+ if (Address) {
+ Lowbit = TSEFO_END (Address);
+ Highbit = TSEFO_START (Address);
+ Type = TSEFO_TYPE (Address);
+
+ // If Fn2 and DCT1 selected, set Address to be 1xx
+ if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) {
+ Address |= 0x0100;
+ }
+ if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
+ // Special DCT Phy access
+ Address &= 0x0FFFFFFF;
+ Lowbit = 0;
+ Highbit = 16;
+ } else {
+ // Normal DCT Phy access
+ Address = TSEFO_OFFSET (Address);
+ }
+
+
+ if (Type == NB_ACCESS) {
+ Address |= (((UINT32) (24 + 0)) << 15);
+ PciAddr.AddressValue = Address;
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (IsSet) {
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32)0xFFFFFFFF;
+ }
+ Value &= ~(Mask << Lowbit);
+ Value |= (Field & Mask) << Lowbit;
+
+ if (Type == NB_ACCESS) {
+ PciAddr.AddressValue = Address;
+ LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ } else {
+ IDS_ERROR_TRAP;
+ }
+ } else {
+ Value = Value >> Lowbit; // Shift
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ }
+ }
+ }
+ } else {
+ IDS_ERROR_TRAP; // Invalid bit field index
+ }
+ return Value;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes bit field translation table
+ *
+ * @param[in,out] *NBRegTable - Pointer to the NB Table *
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableNi (
+ IN OUT TSEFO *NBRegTable
+ )
+{
+ UINT16 i;
+ for (i = 0; i <= BFEndOfList; i++) {
+ NBRegTable[i] = 0;
+ }
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFMctWrLimit);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
+
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ * MemRecNIsIdSupportedNi
+ * This function matches the CPU_LOGICAL_ID with certain criteria to
+ * determine if it is supported by this NBBlock.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ *
+ */
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ )
+{
+
+ if ((LogicalIdPtr->Revision & (AMD_F10_BL_ALL | AMD_F10_DA_ALL)) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/NI/mrnNi.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/NI/mrnNi.h
new file mode 100644
index 0000000000..ddfde8993d
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/NI/mrnNi.h
@@ -0,0 +1,97 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnNi.h
+ *
+ * Northbridge Ni Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRNNI_H_
+#define _MRNNI_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+#define _4GB_RJ8 ((UINT32)4 << (30 - 8))
+#define MTRR_VALID 11
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BOOLEAN
+MemRecConstructNBBlockNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ );
+
+VOID
+MemRecNSwitchDctNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ );
+
+VOID
+MemRecNSwitchChannelNi (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ );
+
+#endif /* _MRNNI_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrndcton.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrndcton.c
new file mode 100644
index 0000000000..e90de93b84
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrndcton.c
@@ -0,0 +1,363 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrndcton.c
+ *
+ * Northbridge DCT support for Ontario Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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 "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Ids.h"
+#include "amdlib.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mru.h"
+#include "mrnon.h"
+#include "cpuFamilyTranslation.h"
+#include "cpuCommonF14Utilities.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_MEM_NB_ON_MRNDCTON_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define RECDEF_DRAM_CONTROL_REG 0x14042A03
+#define RECDEF_DRAM_MRSREG 0x000400A5
+#define RECDEF_DRAM_TIMING_LO 0x000A0092
+#define RECDEF_DRAM_TIMING_HI 0x001218FF
+#define RECDEF_CSMASK_REG 0x00003FE0
+#define RECDEF_DRAM_CONFIG_LO_REG 0x30000000
+#define RECDEF_DRAM_CONFIG_HI_REG 0x1E000000
+#define RECDEF_DRAM_BASE_REG 0x00000003
+#define RECDEF_DRAM_TIMING_0 0x0A000101
+#define RECDEF_DRAM_TIMING_1 0
+
+#define MAX_RD_DQS_DLY 0x1F
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets platform specific config/timing values from the interface layer and
+ * programs them into DCT.
+ *
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return TRUE - An Error value lower than AGESA_ERROR may have occurred
+ * @return FALSE - An Error value greater than or equal to AGESA_ERROR may have occurred
+ */
+
+BOOLEAN
+MemRecNPlatformSpecON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT32 AddrTmgValue;
+ UINT32 DrvStrValue;
+ CH_DEF_STRUCT *ChannelPtr;
+
+ ChannelPtr = NBPtr->ChannelPtr;
+ if (ChannelPtr->SODimmPresent != 0) {
+ // SODIMM
+ if (ChannelPtr->Dimms == 2) {
+ AddrTmgValue = 0x00000039;
+ DrvStrValue = 0x30222323;
+ } else {
+ AddrTmgValue = 0;
+ DrvStrValue = 0x00002222;
+ }
+ } else {
+ // UDIMM
+ if (ChannelPtr->Dimms == 2) {
+ AddrTmgValue = 0x00390039;
+ DrvStrValue = 0x30222322;
+ } else {
+ AddrTmgValue = 0;
+ DrvStrValue = 0x00112222;
+ if (ChannelPtr->DimmDrPresent != 0) {
+ AddrTmgValue = 0x003B0000;
+ }
+ }
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFODCControl, DrvStrValue);
+ MemRecNSetBitFieldNb (NBPtr, BFAddrTmgControl, AddrTmgValue);
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the maximum round-trip latency in the system from the processor to the DRAM
+ * devices and back.
+
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] MaxRcvEnDly - Maximum receiver enable delay value
+ *
+ */
+
+VOID
+MemRecNSetMaxLatencyON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT16 MaxRcvEnDly
+ )
+{
+ UINT32 N;
+ UINT32 T;
+ UINT32 P;
+ UINT32 Px2;
+ UINT32 MemClkPeriod;
+
+ T = MemRecNTotalSyncComponentsClientNb (NBPtr);
+
+ // P = P + CEIL(MAX (total delay in DqsRcvEn + RdDqsTime))
+ P = (MaxRcvEnDly + MAX_RD_DQS_DLY + 31) / 32;
+
+ MemClkPeriod = 1000000 / DDR800_FREQUENCY;
+
+ // P = P + 6.5
+ // T = T + 2586 ps
+ Px2 = (P * 2) + 13;
+ T += 2586;
+
+ // N = (P/(MemClkFreq * 2) + T) * NclkFreq
+ N = ((((Px2 * MemClkPeriod + 3) / 4) + T) * NBPtr->NBClkFreq + 999999) / 1000000;
+
+ MemRecNSetBitFieldNb (NBPtr, BFMaxLatency, N);
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * Set Dram ODT for mission mode and write leveling mode.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] OdtMode - Mission mode or write leveling mode
+ * @param[in] ChipSelect - Chip select number
+ * @param[in] TargetCS - Chip select number that is being trained
+ *
+ */
+
+VOID
+MemRecNSetDramOdtON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN ODT_MODE OdtMode,
+ IN UINT8 ChipSelect,
+ IN UINT8 TargetCS
+ )
+{
+ UINT8 Dimms;
+ UINT8 DramTerm;
+ UINT8 DramTermDyn;
+ UINT8 WrLvOdt;
+ UINT8 MaxDimmsPerChannel;
+
+ Dimms = NBPtr->ChannelPtr->Dimms;
+
+ // Dram nominal termination
+ if (Dimms == 1) {
+ DramTerm = 2; // 120 Ohms
+ DramTermDyn = 0; // Disabled
+ } else {
+ DramTerm = 3; // 40 Ohms
+ DramTermDyn = 2; // 120 Ohms
+ }
+
+ if (OdtMode == WRITE_LEVELING_MODE) {
+ if (ChipSelect == TargetCS) {
+ DramTerm = DramTermDyn;
+
+ MaxDimmsPerChannel = RecGetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, 0, NBPtr->ChannelPtr->ChannelID);
+
+ if (MaxDimmsPerChannel == 2) {
+ if (Dimms == 2) {
+ WrLvOdt = 5;
+ } else {
+ // Dimms = 1
+ if (TargetCS == 0) {
+ WrLvOdt = 0xF;
+ } else {
+ // TargetCS = 2
+ WrLvOdt = 4;
+ }
+ }
+ } else {
+ WrLvOdt = 1;
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFWrLvOdt, WrLvOdt);
+ }
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFDramTerm, DramTerm);
+ MemRecNSetBitFieldNb (NBPtr, BFDramTermDyn, DramTermDyn);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function programs the memory controller with configuration parameters
+ *
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return TRUE - An Error value lower than AGESA_ERROR may have occurred
+ * @return FALSE - An Error value greater than or equal to AGESA_ERROR may have occurred
+ */
+
+BOOLEAN
+MemRecNAutoConfigON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 Dimm;
+ UINT8 ChipSel;
+ UINT32 CSBase;
+ UINT32 NBClkFreq;
+ DCT_STRUCT *DCTPtr;
+ CH_DEF_STRUCT *ChannelPtr;
+
+ DCTPtr = NBPtr->DCTPtr;
+ ChannelPtr = NBPtr->ChannelPtr;
+
+ // Force NB P-state to NBP0
+ F14NbPstateInit (DDR800_FREQUENCY,
+ 6,
+ 0,
+ &NBClkFreq,
+ &(NBPtr->MemPtr->StdHeader));
+ NBPtr->NBClkFreq = NBClkFreq;
+ MemRecNSetBitFieldNb (NBPtr, BFNbPsCtrlDis, 1);
+
+ //Prepare variables for future usage.
+ for (Dimm = 0; Dimm < 2; Dimm++) {
+ if ((ChannelPtr->ChDimmValid & (UINT8) 1 << Dimm) != 0) {
+ DCTPtr->Timings.CsPresent |= (UINT16) 1 << (Dimm * 2);
+ if (((ChannelPtr->DimmDrPresent & (UINT8) 1 << Dimm) == 0) && ((ChannelPtr->DimmQrPresent & (UINT8) 1 << Dimm) == 0)) {
+ continue;
+ } else {
+ DCTPtr->Timings.CsPresent |= (UINT16) 1 << (Dimm * 2 + 1);
+ }
+ }
+ }
+
+ //Temporarily set all CS Base/Limit registers (corresponding to Dimms exist on a channel) with 256MB size for WL training.
+ CSBase = 0;
+ for (ChipSel = 0; ChipSel < 4; ChipSel++) {
+ if (DCTPtr->Timings.CsPresent & (UINT8) 1 << ChipSel) {
+
+ CSBase &= (UINT32) ~0x08; //Clear OnDimmMirror bit.
+ if (((ChipSel & 1) != 0) && ((ChannelPtr->DimmMirrorPresent & (UINT8) 1 << (ChipSel >> 1)) != 0)) {
+ CSBase |= (UINT32) 0x08; //Set OnDimmMirror bit.
+ }
+ MemRecNSetBitFieldNb (NBPtr, (BFCSBaseAddr0Reg + ChipSel), (CSBase | 0x01));
+ CSBase += 0x100000;
+ if ((ChipSel & 1) == 0) {
+ MemRecNSetBitFieldNb (NBPtr, (BFCSMask0Reg + (ChipSel >> 1)), RECDEF_CSMASK_REG);
+ }
+ }
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFDramBaseReg0, RECDEF_DRAM_BASE_REG);
+ MemRecNSetBitFieldNb (NBPtr, BFDramLimitReg0, 0x70000);
+ MemRecNSetBitFieldNb (NBPtr, BFDramBankAddrReg, 0x00000011);
+
+ // Set timing registers
+ MemRecNSetBitFieldNb (NBPtr, BFDramTiming0, RECDEF_DRAM_TIMING_0);
+ MemRecNSetBitFieldNb (NBPtr, BFDramTiming1, RECDEF_DRAM_TIMING_1);
+ MemRecNSetBitFieldNb (NBPtr, BFDramTimingLoReg, RECDEF_DRAM_TIMING_LO);
+ MemRecNSetBitFieldNb (NBPtr, BFDramTimingHiReg, RECDEF_DRAM_TIMING_HI);
+ MemRecNSetBitFieldNb (NBPtr, BFDramMRSReg, RECDEF_DRAM_MRSREG);
+ MemRecNSetBitFieldNb (NBPtr, BFDramControlReg, RECDEF_DRAM_CONTROL_REG);
+ // Set DRAM Config Low Register
+ MemRecNSetBitFieldNb (NBPtr, BFDramConfigLoReg, RECDEF_DRAM_CONFIG_LO_REG);
+
+ // Set DRAM Config High Register
+ MemRecNSetBitFieldNb (NBPtr, BFDramConfigHiReg, RECDEF_DRAM_CONFIG_HI_REG);
+
+ // DctWrLimit = 0x1F
+ MemRecNSetBitFieldNb (NBPtr, BFDctWrLimit, 0x1F);
+ // EnCpuSerRdBehindNpIoWr = 1
+ MemRecNSetBitFieldNb (NBPtr, BFEnCpuSerRdBehindNpIoWr, 1);
+
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnmcton.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnmcton.c
new file mode 100644
index 0000000000..df1d5d8e40
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnmcton.c
@@ -0,0 +1,191 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnmcton.c
+ *
+ * Northbridge ON MCT supporting functions Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mrnon.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_MEM_NB_ON_MRNMCTON_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the Recovery memory configuration function for ON DDR3
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return AGESA_STATUS
+ * - AGESA_ALERT
+ * - AGESA_FATAL
+ * - AGESA_SUCCESS
+ * - AGESA_WARNING
+ */
+
+AGESA_STATUS
+MemRecNMemInitON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ AGESA_STATUS Status;
+ MEM_TECH_BLOCK *TechPtr;
+
+ TechPtr = NBPtr->TechPtr;
+
+ Status = AGESA_FATAL;
+ if (TechPtr->DimmPresence (TechPtr)) {
+
+ if (MemRecNAutoConfigON (NBPtr)) {
+
+ AGESA_TESTPOINT (TpProcMemPlatformSpecificConfig, &(NBPtr->MemPtr->StdHeader));
+ if (MemRecNPlatformSpecON (NBPtr)) {
+ AgesaHookBeforeDramInitRecovery (0, NBPtr->MemPtr);
+ AGESA_TESTPOINT (TpProcMemStartDcts, &(NBPtr->MemPtr->StdHeader));
+ MemRecNStartupDCTClientNb (NBPtr);
+
+ AGESA_TESTPOINT (TpProcMemMtrrConfiguration, &(NBPtr->MemPtr->StdHeader));
+ MemRecNCPUMemRecTypingNb (NBPtr);
+
+ AGESA_TESTPOINT (TpProcMemDramTraining, &(NBPtr->MemPtr->StdHeader));
+ NBPtr->TrainingFlow (NBPtr);
+
+ Status = AGESA_SUCCESS;
+ }
+ }
+ }
+
+ return Status;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the final values for specific registers
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNFinalizeMctON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ //
+ // Recommended registers setting after DRAM device initialization and training
+ //
+ // PrefCpuDis = 0
+ MemRecNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0);
+ // DctWrLimit = 0x1C
+ MemRecNSetBitFieldNb (NBPtr, BFDctWrLimit, 0x1C);
+ // DramTrainPdbDis = 1
+ MemRecNSetBitFieldNb (NBPtr, BFDramTrainPdbDis, 1);
+ // EnCpuSerRdBehindNpIoWr = 0
+ MemRecNSetBitFieldNb (NBPtr, BFEnCpuSerRdBehindNpIoWr, 0);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets initial values in BUCFG2
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNInitializeMctON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnon.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnon.c
new file mode 100644
index 0000000000..e8a28ed2e9
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnon.c
@@ -0,0 +1,653 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnon.c
+ *
+ * Common Northbridge functions for Ontario Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 38303 $ @e \$Date: 2010-09-22 00:22:47 +0800 (Wed, 22 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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnon.h"
+#include "heapManager.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_MEM_NB_ON_MRNON_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+CONST MEM_FREQ_CHANGE_PARAM RecFreqChangeParamON = {0x1838, NULL, 3, 10, 2};
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableON (
+ IN OUT TSEFO *NBRegTable
+ );
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ );
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ );
+
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the northbridge block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ * @param[in] NodeID - Node ID for this NB block
+ *
+ * @return TRUE - This node is a Llano and this NB block has been initialized
+ * @return FALSE - This node is not a Llano
+ */
+
+BOOLEAN
+MemRecConstructNBBlockON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ )
+{
+ UINT8 i;
+ DIE_STRUCT *MCTPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ //
+ // Determine if this is the expected NB Type
+ //
+ GetLogicalIdOfSocket (MemPtr->DiesPerSystem->SocketId, &(MemPtr->DiesPerSystem->LogicalCpuid), &(MemPtr->StdHeader));
+ if (!MemRecNIsIdSupportedON (NBPtr, &(MemPtr->DiesPerSystem->LogicalCpuid))) {
+ return FALSE;
+ }
+
+ NBPtr->MemPtr = MemPtr;
+ NBPtr->RefPtr = MemPtr->ParameterListPtr;
+
+ MCTPtr = MemPtr->DiesPerSystem;
+ NBPtr->MCTPtr = MCTPtr;
+ NBPtr->MCTPtr->NodeId = 0;
+ NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue;
+
+ //
+ // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ //
+ AllocHeapParams.RequestedBufferSize = (sizeof (DCT_STRUCT) + sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK));
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ ASSERT(FALSE); // Could not allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ return FALSE;
+ }
+
+ MemPtr->DieCount = 1;
+ MCTPtr->Dct = 0;
+ MCTPtr->DctCount = 1;
+ MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += sizeof (DCT_STRUCT);
+ MCTPtr->DctData->ChannelCount = 1;
+ MCTPtr->DctData->ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += sizeof (CH_DEF_STRUCT);
+ NBPtr->PSBlock = (MEM_PS_BLOCK *) AllocHeapParams.BufferPtr;
+
+ //
+ // Initialize NB block's variables
+ //
+ NBPtr->DCTPtr = NBPtr->MCTPtr->DctData;
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+ NBPtr->PsPtr = NBPtr->PSBlock;
+ NBPtr->ChannelPtr = NBPtr->DCTPtr->ChData;
+
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+
+ MemRecNInitNBRegTableON (NBPtr->NBRegTable);
+ NBPtr->Dct = 0;
+ NBPtr->Channel = 0;
+ NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+ NBPtr->FreqChangeParam = (MEM_FREQ_CHANGE_PARAM *) &RecFreqChangeParamON;
+ LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
+ LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
+ for (i = 0; i < NumberOfHooks; i++) {
+ NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
+ }
+
+ NBPtr->InitRecovery = MemRecNMemInitON;
+
+ NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->SwitchDCT = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->SwitchChannel = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->SetMaxLatency = MemRecNSetMaxLatencyON;
+ NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
+ NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
+ NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
+ NBPtr->SetDramOdtRec = MemRecNSetDramOdtON;
+
+ NBPtr->GetBitField = MemRecNGetBitFieldNb;
+ NBPtr->SetBitField = MemRecNSetBitFieldNb;
+ NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
+ NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
+
+ NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldON;
+ NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyON;
+ NBPtr->MemRecNSwitchDctNb = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctON;
+ NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctON;
+ NBPtr->IsSupported[DramModeAfterDimmPres] = TRUE;
+ NBPtr->TrainingFlow = MemNRecTrainingFlowClientNb;
+ NBPtr->ReadPattern = MemRecNContReadPatternClientNb;
+
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or set DQS timing during training.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ UINT16 Index;
+ UINT16 Offset;
+ UINT32 Value;
+ UINT32 Address;
+ UINT8 Dimm;
+ UINT8 Byte;
+
+ Dimm = DRBN_DIMM (DrbnVar);
+ Byte = DRBN_BYTE (DrbnVar);
+
+ ASSERT (Dimm < 1);
+ ASSERT (Byte <= 8);
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ Index = 0x10;
+ break;
+ case AccessWrDqsDly:
+ Index = 0x30;
+ break;
+ case AccessWrDatDly:
+ Index = 0x01;
+ break;
+ case AccessRdDqsDly:
+ Index = 0x05;
+ break;
+ case AccessPhRecDly:
+ Index = 0x50;
+ break;
+ default:
+ Index = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ case AccessWrDqsDly:
+ if ((Byte & 0x04) != 0) {
+ // if byte 4,5,6,7
+ Index += 0x10;
+ }
+ if ((Byte & 0x02) != 0) {
+ // if byte 2,3,6,7
+ Index++;
+ }
+ Offset = 16 * (Byte % 2);
+ break;
+
+ case AccessRdDqsDly:
+ Field &= ~ 0x0001;
+ case AccessWrDatDly:
+ Index += (Dimm * 0x100);
+ // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
+ // to run AccessPhRecDly sequence.
+ case AccessPhRecDly:
+ Index += (Byte / 4);
+ Offset = 8 * (Byte % 4);
+ break;
+ default:
+ Offset = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ Address = Index;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+
+ if (IsSet != 0) {
+ if (TrnDly == AccessPhRecDly) {
+ Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
+ }
+
+ Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset)));
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+
+ if (TrnDly == AccessPhRecDly) {
+ NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
+ }
+ } else {
+ Value = (Value >> Offset) & 0xFF;
+ }
+
+ return Value;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or sets a value to a bit field in a PCI register.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] FieldName - Name of Field to be set * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ SBDFO Address;
+ PCI_ADDR PciAddr;
+ UINT8 Type;
+ UINT32 Value;
+ UINT32 Highbit;
+ UINT32 Lowbit;
+ UINT32 Mask;
+
+ Value = 0;
+ if ((FieldName == BFDctAccessDone) || (FieldName == BFDctExtraAccessDone)) {
+ Value = 1;
+ } else if ((FieldName < BFEndOfList) && (FieldName >= 0)) {
+ Address = NBPtr->NBRegTable[FieldName];
+ if (Address != 0) {
+ Lowbit = TSEFO_END (Address);
+ Highbit = TSEFO_START (Address);
+ Type = TSEFO_TYPE (Address);
+
+ if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
+ // Special DCT Phy access
+ Address &= 0x0FFFFFFF;
+ Lowbit = 0;
+ Highbit = 16;
+ } else {
+ // Normal DCT Phy access
+ Address = TSEFO_OFFSET (Address);
+ }
+
+
+ if (Type == NB_ACCESS) {
+ Address |= (((UINT32) (24 + 0)) << 15);
+ PciAddr.AddressValue = Address;
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+ } else if (Type == DCT_EXTRA) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctExtraOffsetReg, Address);
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctExtraDataReg);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (IsSet != 0) {
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32)0xFFFFFFFF;
+ }
+ Value &= ~(Mask << Lowbit);
+ Value |= (Field & Mask) << Lowbit;
+
+ if (Type == NB_ACCESS) {
+ PciAddr.AddressValue = Address;
+ LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ } else if (Type == DCT_EXTRA) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctExtraDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctExtraOffsetReg, Address);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+ } else {
+ Value = Value >> Lowbit; // Shift
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ }
+ }
+ }
+ } else {
+ IDS_ERROR_TRAP; // Invalid bit field index
+ }
+ return Value;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes bit field translation table
+ *
+ * @param[in,out] *NBRegTable - Pointer to the NB Table
+ *
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableON (
+ IN OUT TSEFO *NBRegTable
+ )
+{
+ UINT16 i;
+ for (i = 0; i <= BFEndOfList; i++) {
+ NBRegTable[i] = 0;
+ }
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 1, 1, BFExitSelfRef);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 17, 17, BFEnterSelfRef);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 27, 27, BFDisDllShutdownSR);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 4, 0, BFMemClkFreq);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 7, 7, BFMemClkFreqVal);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 22, 21, BFDbeGskMemClkAlignMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xF0), 31, 0, BFDctExtraOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xF4), 31, 0, BFDctExtraDataReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFDctWrLimit);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1C0), 17, 2, BFTrainLength);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1C0), 20, 20, BFDramTrainPdbDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1C0), 22, 22, BFRdDramTrainMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1C0), 23, 23, BFRdTrainGo);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1C8), 31, 0, BFWrTrainAdrPtrLo);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1D0), 9, 0, BFWrTrainBufAddr);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 5, 0, BFMainPllOpFreqId);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xDC), 26, 20, BFNbPs0NclkDiv);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x188), 22, 22, BFEnCpuSerRdBehindNpIoWr);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (6, 0x90), 30, 30, BFNbPsCtrlDis);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 2, 0, BFCkeDrvStren);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 6, 4, BFCsOdtDrvStren);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 10, 8, BFAddrCmdDrvStren);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 14, 12, BFClkDrvStren);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 18, 16, BFDataDrvStren);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 22, 20, BFDqsDrvStren);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 3, 3, BFPhyFenceTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 4, 4, BFTrDimmSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 7, 6, BFFenceTrSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 13, 13, BFDqsRcvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 21, 15, BFPllMult);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 27, 24, BFPllDiv);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0B, 31, 0, BFDramPhyStatusReg);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0C, 20, 16, BFPhyFence);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FE006, 15, 0, BFPllLockTime);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FE013, 15, 0, BFPllRegWaitTime);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F1F, 4, 3, BFDataRxVioLvl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2F1F, 4, 3, BFClkRxVioLvl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F4009, 15, 14, BFCmpVioLvl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8F1F, 4, 3, BFCmdRxVioLvl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC01F, 4, 3, BFAddrRxVioLvl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F31, 14, 0, BFDataFence2);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2F31, 4, 0, BFClkFence2);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8F31, 4, 0, BFCmdFence2);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC031, 4, 0, BFAddrFence2);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F0F, 14, 12, BFAlwaysEnDllClks);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FE003, 14, 13, BFDisablePredriverCal);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F02, 15, 0, BFDataByteTxPreDriverCal);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F06, 15, 0, BFDataByteTxPreDriverCal2Pad1);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F0A, 15, 0, BFDataByteTxPreDriverCal2Pad2);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8006, 15, 0, BFCmdAddr0TxPreDriverCal2Pad1);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F800A, 15, 0, BFCmdAddr0TxPreDriverCal2Pad2);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8106, 15, 0, BFCmdAddr1TxPreDriverCal2Pad1);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F810A, 15, 0, BFCmdAddr1TxPreDriverCal2Pad2);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC006, 15, 0, BFAddrTxPreDriverCal2Pad1);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC00A, 15, 0, BFAddrTxPreDriverCal2Pad2);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC00E, 15, 0, BFAddrTxPreDriverCal2Pad3);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC012, 15, 0, BFAddrTxPreDriverCal2Pad4);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8002, 15, 0, BFCmdAddr0TxPreDriverCalPad0);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8102, 15, 0, BFCmdAddr1TxPreDriverCalPad0);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC002, 15, 0, BFAddrTxPreDriverCalPad0);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2002, 15, 0, BFClock0TxPreDriverCalPad0);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2102, 15, 0, BFClock1TxPreDriverCalPad0);
+
+ MAKE_TSEFO (NBRegTable, DCT_EXTRA, 0x30, 12, 0, BFDbeGskFifoNumerator);
+ MAKE_TSEFO (NBRegTable, DCT_EXTRA, 0x31, 12, 0, BFDbeGskFifoDenominator);
+
+ MAKE_TSEFO (NBRegTable, DCT_EXTRA, 0x32, 4, 0, BFDataTxFifoSchedDlySlot0);
+ MAKE_TSEFO (NBRegTable, DCT_EXTRA, 0x32, 7, 7, BFDataTxFifoSchedDlyNegSlot0);
+ MAKE_TSEFO (NBRegTable, DCT_EXTRA, 0x32, 12, 8, BFDataTxFifoSchedDlySlot1);
+ MAKE_TSEFO (NBRegTable, DCT_EXTRA, 0x32, 15, 15, BFDataTxFifoSchedDlyNegSlot1);
+
+ MAKE_TSEFO (NBRegTable, DCT_EXTRA, 0x40, 31, 0, BFDramTiming0);
+ MAKE_TSEFO (NBRegTable, DCT_EXTRA, 0x41, 31, 0, BFDramTiming1);
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ *
+ * This function matches the CPU_LOGICAL_ID with certain criteria to
+ * determine if it is supported by this NBBlock.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ *
+ * @return TRUE - This node is a Llano.
+ * @return FALSE - This node is not a Llano.
+ */
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ )
+{
+ if ((LogicalIdPtr->Family & (AMD_FAMILY_14_ON)) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnon.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnon.h
new file mode 100644
index 0000000000..aa5614813c
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/ON/mrnon.h
@@ -0,0 +1,125 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mnon.h
+ *
+ * Northbridge Ontario Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRNON_H_
+#define _MRNON_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+
+#define _4GB_RJ8 ((UINT32)4 << (30 - 8))
+#define MTRR_VALID 11
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BOOLEAN
+MemRecConstructNBBlockON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ );
+
+AGESA_STATUS
+MemRecNMemInitON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+MemRecNFinalizeMctON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+MemRecNInitializeMctON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+MemRecNSetMaxLatencyON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT16 MaxRcvEnDly
+ );
+
+BOOLEAN
+MemRecNPlatformSpecON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+MemRecNSetDramOdtON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN ODT_MODE OdtMode,
+ IN UINT8 ChipSelect,
+ IN UINT8 TargetCS
+ );
+
+BOOLEAN
+MemRecNAutoConfigON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+#endif /* _MRNON_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/PH/mrnPh.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/PH/mrnPh.c
new file mode 100644
index 0000000000..0552cd596a
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/PH/mrnPh.c
@@ -0,0 +1,652 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnPh.c
+ *
+ * Common Northbridge functions for Pharaoh Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnda.h"
+#include "mrnPh.h"
+#include "heapManager.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_PH_MRNPH_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTablePh (
+ IN OUT TSEFO *NBRegTable
+ );
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ );
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ );
+
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the northbridge block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ * @param[in] NodeID - Node ID for this NB block
+ *
+ * @return TRUE - This node is a RB and this NB block has been initialized
+ * @return FALSE - This node is not a RB
+ */
+
+BOOLEAN
+MemRecConstructNBBlockPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ )
+{
+ UINT8 i;
+ UINT8 Dct;
+ UINT8 Channel;
+ DIE_STRUCT *MCTPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ //
+ // Determine if this is the expected NB Type
+ //
+ GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+ if (!MemRecNIsIdSupportedPh (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ //
+ MCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DA * (
+ sizeof (DCT_STRUCT) + (
+ MAX_CHANNELS_PER_DCT_DA * (
+ sizeof (CH_DEF_STRUCT) + (
+ MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
+ )
+ )
+ )
+ );
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ return FALSE;
+ }
+
+ MemPtr->DieCount = 1;
+ MCTPtr->DctCount = MAX_DCTS_PER_NODE_DA;
+ MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT);
+ for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) {
+ MCTPtr->DctData[Dct].Dct = Dct;
+ MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA;
+ MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct;
+ AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DA * sizeof (CH_DEF_STRUCT);
+ for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; Channel++) {
+ MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
+ MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
+ }
+ }
+
+ //
+ // Initialize NB block's variables
+ //
+ NBPtr->MemPtr = MemPtr;
+ NBPtr->RefPtr = MemPtr->ParameterListPtr;
+ NBPtr->MCTPtr = MCTPtr;
+ NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+ NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+
+ MemRecNInitNBRegTablePh (NBPtr->NBRegTable);
+ NBPtr->Dct = 0;
+ NBPtr->Channel = 0;
+ NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+
+ LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
+ LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
+ for (i = 0; i < NumberOfHooks; i++) {
+ NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
+ }
+
+ NBPtr->InitRecovery = MemRecNMemInitNb;
+
+ NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->SwitchDCT = MemRecNSwitchDctPh;
+ NBPtr->SwitchChannel = MemRecNSwitchChannelPh;
+ NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
+ NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
+ NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
+ NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
+ NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
+
+ NBPtr->GetBitField = MemRecNGetBitFieldNb;
+ NBPtr->SetBitField = MemRecNSetBitFieldNb;
+ NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
+ NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
+ NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldPh;
+ NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyPh;
+ NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctPh;
+ NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
+ NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctDA;
+ NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDA;
+ NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE;
+ NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE;
+ MemRecNSwitchDctPh (NBPtr, 0);
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current DCT to work on.
+ * Should be called before accessing a certain DCT
+ * All data structures will be updated to point to the current DCT
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Dct - ID of the target DCT
+ *
+ */
+
+VOID
+MemRecNSwitchDctPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ )
+{
+ NBPtr->Dct = Dct & 1;
+ NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]);
+ NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
+
+ MemRecNSwitchChannelPh (NBPtr, NBPtr->Channel);
+}
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current channel to work on.
+ * Should be called before accessing a certain channel
+ * All data structures will be updated to point to the current channel
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Channel - ID of the target channel
+ *
+ */
+
+VOID
+MemRecNSwitchChannelPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ )
+{
+ NBPtr->Channel = Channel & 1;
+ NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]);
+}
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or set DQS timing during training.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ UINT16 Index;
+ UINT16 Offset;
+ UINT32 Value;
+ UINT32 Address;
+ UINT8 Dimm;
+ UINT8 Byte;
+
+ Dimm = DRBN_DIMM (DrbnVar);
+ Byte = DRBN_BYTE (DrbnVar);
+
+ ASSERT (Dimm < 4);
+ ASSERT (Byte <= 8);
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ Index = 0x10;
+ break;
+ case AccessWrDqsDly:
+ Index = 0x30;
+ break;
+ case AccessWrDatDly:
+ Index = 0x01;
+ break;
+ case AccessRdDqsDly:
+ Index = 0x05;
+ break;
+ case AccessPhRecDly:
+ Index = 0x50;
+ break;
+ default:
+ Index = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ case AccessWrDqsDly:
+ Index += (Dimm * 3);
+ if (Byte & 0x04) {
+ // if byte 4,5,6,7
+ Index += 0x10;
+ }
+ if (Byte & 0x02) {
+ // if byte 2,3,6,7
+ Index++;
+ }
+ Offset = 16 * (Byte % 2);
+ break;
+
+ case AccessRdDqsDly:
+ Field &= ~ 0x0001;
+ case AccessWrDatDly:
+ Index += (Dimm * 0x100);
+ // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
+ // to run AccessPhRecDly sequence.
+ case AccessPhRecDly:
+ Index += (Byte / 4);
+ Offset = 8 * (Byte % 4);
+ break;
+ default:
+ Offset = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ Address = Index;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+
+ if (IsSet) {
+ if (TrnDly == AccessPhRecDly) {
+ Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
+ }
+
+ Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset)));
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ if (TrnDly == AccessPhRecDly) {
+ NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
+ }
+ } else {
+ Value = (Value >> Offset) & 0xFF;
+ }
+
+ return Value;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or sets a value to a bit field in a PCI register.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] IsSet - Indicates if the function will set or get
+ * @param[in] FieldName - Name of field to be set
+ * @param[in] Field - Value to be programmed
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ SBDFO Address;
+ PCI_ADDR PciAddr;
+ UINT8 Type;
+ UINT32 Value;
+ UINT32 Highbit;
+ UINT32 Lowbit;
+ UINT32 Mask;
+
+ Value = 0;
+ if (FieldName < BFEndOfList) {
+ Address = NBPtr->NBRegTable[FieldName];
+ if (Address) {
+ Lowbit = TSEFO_END (Address);
+ Highbit = TSEFO_START (Address);
+ Type = TSEFO_TYPE (Address);
+
+ // If Fn2 and DCT1 selected, set Address to be 1xx
+ if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) {
+ Address |= 0x0100;
+ }
+ if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
+ // Special DCT Phy access
+ Address &= 0x0FFFFFFF;
+ Lowbit = 0;
+ Highbit = 16;
+ } else {
+ // Normal DCT Phy access
+ Address = TSEFO_OFFSET (Address);
+ }
+
+
+ if (Type == NB_ACCESS) {
+ Address |= (((UINT32) (24 + 0)) << 15);
+ PciAddr.AddressValue = Address;
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (IsSet) {
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32)0xFFFFFFFF;
+ }
+ Value &= ~(Mask << Lowbit);
+ Value |= (Field & Mask) << Lowbit;
+
+ if (Type == NB_ACCESS) {
+ PciAddr.AddressValue = Address;
+ LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ } else {
+ IDS_ERROR_TRAP;
+ }
+ } else {
+ Value = Value >> Lowbit; // Shift
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ }
+ }
+ }
+ } else {
+ IDS_ERROR_TRAP; // Invalid bit field index
+ }
+ return Value;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes bit field translation table
+ *
+ * @param[in,out] *NBRegTable - Pointer to the NB Table *
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTablePh (
+ IN OUT TSEFO *NBRegTable
+ )
+{
+ UINT16 i;
+ for (i = 0; i <= BFEndOfList; i++) {
+ NBRegTable[i] = 0;
+ }
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFMctWrLimit);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
+
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ * MemRecNIsIdSupportedPh
+ * This function matches the CPU_LOGICAL_ID with certain criteria to
+ * determine if it is supported by this NBBlock.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ *
+ */
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ )
+{
+
+ if ((LogicalIdPtr->Revision & AMD_F10_PH_ALL) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/PH/mrnPh.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/PH/mrnPh.h
new file mode 100644
index 0000000000..341b433001
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/PH/mrnPh.h
@@ -0,0 +1,97 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnPh.h
+ *
+ * Northbridge PH Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRNPH_H_
+#define _MRNPH_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+#define _4GB_RJ8 ((UINT32)4 << (30 - 8))
+#define MTRR_VALID 11
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BOOLEAN
+MemRecConstructNBBlockPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ );
+
+VOID
+MemRecNSwitchDctPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ );
+
+VOID
+MemRecNSwitchChannelPh (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ );
+
+#endif /* _MRNPH_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/RB/mrnRb.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/RB/mrnRb.c
new file mode 100644
index 0000000000..627e5f7508
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/RB/mrnRb.c
@@ -0,0 +1,651 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnRb.c
+ *
+ * Common Northbridge functions for RidgeBack Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mrnda.h"
+#include "mrnRb.h"
+#include "heapManager.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_NB_RB_MRNRB_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableRb (
+ IN OUT TSEFO *NBRegTable
+ );
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ );
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ );
+
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the northbridge block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ * @param[in] NodeID - Node ID for this NB block
+ *
+ * @return TRUE - This node is a RB and this NB block has been initialized
+ * @return FALSE - This node is not a RB
+ */
+
+BOOLEAN
+MemRecConstructNBBlockRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ )
+{
+ UINT8 i;
+ UINT8 Dct;
+ UINT8 Channel;
+ DIE_STRUCT *MCTPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ //
+ // Determine if this is the expected NB Type
+ //
+ GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+ if (!MemRecNIsIdSupportedRb (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
+ //
+ MCTPtr = &MemPtr->DiesPerSystem[NodeID];
+ AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DA * (
+ sizeof (DCT_STRUCT) + (
+ MAX_CHANNELS_PER_DCT_DA * (
+ sizeof (CH_DEF_STRUCT) + (
+ MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
+ )
+ )
+ )
+ );
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ return FALSE;
+ }
+
+ MCTPtr->DctCount = MAX_DCTS_PER_NODE_DA;
+ MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT);
+ for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) {
+ MCTPtr->DctData[Dct].Dct = Dct;
+ MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA;
+ MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct;
+ AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DA * sizeof (CH_DEF_STRUCT);
+ for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; Channel++) {
+ MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
+ MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
+ MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
+ AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
+ }
+ }
+
+ //
+ // Initialize NB block's variables
+ //
+ NBPtr->MemPtr = MemPtr;
+ NBPtr->RefPtr = MemPtr->ParameterListPtr;
+ NBPtr->MCTPtr = MCTPtr;
+ NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+ NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
+
+ NBPtr->DctCachePtr = NBPtr->DctCache;
+
+ MemRecNInitNBRegTableRb (NBPtr->NBRegTable);
+ NBPtr->Dct = 0;
+ NBPtr->Channel = 0;
+ NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
+
+ LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
+ LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
+ for (i = 0; i < NumberOfHooks; i++) {
+ NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
+ }
+
+ NBPtr->InitRecovery = MemRecNMemInitNb;
+
+ NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
+ NBPtr->SwitchDCT = MemRecNSwitchDctRb;
+ NBPtr->SwitchChannel = MemRecNSwitchChannelRb;
+ NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
+ NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
+ NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
+ NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
+ NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
+
+ NBPtr->GetBitField = MemRecNGetBitFieldNb;
+ NBPtr->SetBitField = MemRecNSetBitFieldNb;
+ NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
+ NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
+ NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldRb;
+ NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyRb;
+ NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctRb;
+ NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
+ NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctDA;
+ NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDA;
+ NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE;
+ NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE;
+ MemRecNSwitchDctRb (NBPtr, 0);
+
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current DCT to work on.
+ * Should be called before accessing a certain DCT
+ * All data structures will be updated to point to the current DCT
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Dct - ID of the target DCT
+ *
+ */
+
+VOID
+MemRecNSwitchDctRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ )
+{
+ NBPtr->Dct = Dct & 1;
+ NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]);
+ NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
+
+ MemRecNSwitchChannelRb (NBPtr, NBPtr->Channel);
+}
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the current channel to work on.
+ * Should be called before accessing a certain channel
+ * All data structures will be updated to point to the current channel
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] Channel - ID of the target channel
+ *
+ */
+
+VOID
+MemRecNSwitchChannelRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ )
+{
+ NBPtr->Channel = Channel & 1;
+ NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]);
+}
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or set DQS timing during training.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ * @param[in] IsSet - Indicates if the function will set or get
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNcmnGetSetTrainDlyRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ UINT16 Index;
+ UINT16 Offset;
+ UINT32 Value;
+ UINT32 Address;
+ UINT8 Dimm;
+ UINT8 Byte;
+
+ Dimm = DRBN_DIMM (DrbnVar);
+ Byte = DRBN_BYTE (DrbnVar);
+
+ ASSERT (Dimm < 4);
+ ASSERT (Byte <= 8);
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ Index = 0x10;
+ break;
+ case AccessWrDqsDly:
+ Index = 0x30;
+ break;
+ case AccessWrDatDly:
+ Index = 0x01;
+ break;
+ case AccessRdDqsDly:
+ Index = 0x05;
+ break;
+ case AccessPhRecDly:
+ Index = 0x50;
+ break;
+ default:
+ Index = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ switch (TrnDly) {
+ case AccessRcvEnDly:
+ case AccessWrDqsDly:
+ Index += (Dimm * 3);
+ if (Byte & 0x04) {
+ // if byte 4,5,6,7
+ Index += 0x10;
+ }
+ if (Byte & 0x02) {
+ // if byte 2,3,6,7
+ Index++;
+ }
+ Offset = 16 * (Byte % 2);
+ break;
+
+ case AccessRdDqsDly:
+ Field &= ~ 0x0001;
+ case AccessWrDatDly:
+ Index += (Dimm * 0x100);
+ // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
+ // to run AccessPhRecDly sequence.
+ case AccessPhRecDly:
+ Index += (Byte / 4);
+ Offset = 8 * (Byte % 4);
+ break;
+ default:
+ Offset = 0;
+ IDS_ERROR_TRAP;
+ }
+
+ Address = Index;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+
+ if (IsSet) {
+ if (TrnDly == AccessPhRecDly) {
+ Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
+ }
+
+ Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset)));
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ if (TrnDly == AccessPhRecDly) {
+ NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
+ }
+ } else {
+ Value = (Value >> Offset) & 0xFF;
+ }
+
+ return Value;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets or sets a value to a bit field in a PCI register.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] IsSet - Indicates if the function will set or get
+ * @param[in] FieldName - Name of field to be set
+ * @param[in] Field - Value to be programmed
+ *
+ * @return value read, if the function is used as a "get"
+ */
+
+UINT32
+STATIC
+MemRecNCmnGetSetFieldRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 IsSet,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ SBDFO Address;
+ PCI_ADDR PciAddr;
+ UINT8 Type;
+ UINT32 Value;
+ UINT32 Highbit;
+ UINT32 Lowbit;
+ UINT32 Mask;
+
+ Value = 0;
+ if (FieldName < BFEndOfList) {
+ Address = NBPtr->NBRegTable[FieldName];
+ if (Address) {
+ Lowbit = TSEFO_END (Address);
+ Highbit = TSEFO_START (Address);
+ Type = TSEFO_TYPE (Address);
+
+ // If Fn2 and DCT1 selected, set Address to be 1xx
+ if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) {
+ Address |= 0x0100;
+ }
+ if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
+ // Special DCT Phy access
+ Address &= 0x0FFFFFFF;
+ Lowbit = 0;
+ Highbit = 16;
+ } else {
+ // Normal DCT Phy access
+ Address = TSEFO_OFFSET (Address);
+ }
+
+
+ if (Type == NB_ACCESS) {
+ Address |= (((UINT32) (24 + 0)) << 15);
+ PciAddr.AddressValue = Address;
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+
+ Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
+ } else {
+ IDS_ERROR_TRAP;
+ }
+
+ if (IsSet) {
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32)0xFFFFFFFF;
+ }
+ Value &= ~(Mask << Lowbit);
+ Value |= (Field & Mask) << Lowbit;
+
+ if (Type == NB_ACCESS) {
+ PciAddr.AddressValue = Address;
+ LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
+ } else if (Type == DCT_PHY_ACCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
+ Address |= DCT_ACCESS_WRITE;
+
+ MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
+ while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
+ } else {
+ IDS_ERROR_TRAP;
+ }
+ } else {
+ Value = Value >> Lowbit; // Shift
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+ if ((Highbit - Lowbit) != 31) {
+ Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
+ }
+ }
+ }
+ } else {
+ IDS_ERROR_TRAP; // Invalid bit field index
+ }
+ return Value;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes bit field translation table
+ *
+ * @param[in,out] *NBRegTable - Pointer to the NB Table *
+ */
+
+VOID
+STATIC
+MemRecNInitNBRegTableRb (
+ IN OUT TSEFO *NBRegTable
+ )
+{
+ UINT16 i;
+ for (i = 0; i <= BFEndOfList; i++) {
+ NBRegTable[i] = 0;
+ }
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
+
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFMctWrLimit);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis);
+ MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl);
+
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
+ MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
+
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ * MemRecNIsIdSupportedRb
+ * This function matches the CPU_LOGICAL_ID with certain criteria to
+ * determine if it is supported by this NBBlock.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ *
+ */
+BOOLEAN
+STATIC
+MemRecNIsIdSupportedRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN CPU_LOGICAL_ID *LogicalIdPtr
+ )
+{
+
+ if ((LogicalIdPtr->Revision & AMD_F10_RB_ALL) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/RB/mrnRb.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/RB/mrnRb.h
new file mode 100644
index 0000000000..32641d3818
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/RB/mrnRb.h
@@ -0,0 +1,97 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnRb.h
+ *
+ * Northbridge RB Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRNRB_H_
+#define _MRNRB_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+#define _4GB_RJ8 ((UINT32)4 << (30 - 8))
+#define MTRR_VALID 11
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BOOLEAN
+MemRecConstructNBBlockRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT MEM_DATA_STRUCT *MemPtr,
+ IN UINT8 NodeID
+ );
+
+VOID
+MemRecNSwitchDctRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Dct
+ );
+
+VOID
+MemRecNSwitchChannelRb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Channel
+ );
+
+#endif /* _MRNRB_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrn.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrn.c
new file mode 100644
index 0000000000..c4baec0851
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrn.c
@@ -0,0 +1,190 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrn.c
+ *
+ * Common Northbridge functions for Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem/NB)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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 "amdlib.h"
+#include "Ids.h"
+#include "cpuFamRegisters.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "mm.h"
+#include "mn.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_MEM_NB_MRN_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+#define MAX_DCTS_PER_DIE 2
+#define SPLIT_CHANNEL 0x20000000
+#define CHANNEL_SELECT 0x10000000
+#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */
+#define MAX_DIMMS 4 /* 4 DIMMs per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets a bit field from PCI register
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] FieldName - Field name
+ *
+ * @return Bit field value
+ */
+
+UINT32
+MemRecNGetBitFieldNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN BIT_FIELD_NAME FieldName
+ )
+{
+ return NBPtr->MemRecNCmnGetSetFieldNb (NBPtr, 0, FieldName, 0);
+}
+
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets a bit field from PCI register
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] FieldName - Field name
+ * @param[in] Field - Value to be stored in PCT register
+ *
+ */
+
+VOID
+MemRecNSetBitFieldNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN BIT_FIELD_NAME FieldName,
+ IN UINT32 Field
+ )
+{
+ NBPtr->MemRecNCmnGetSetFieldNb (NBPtr, 1, FieldName, Field);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets a delay value a PCI register during training
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ *
+ * @return Value read
+ */
+
+UINT32
+MemRecNGetTrainDlyNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar
+ )
+{
+ return NBPtr->MemRecNcmnGetSetTrainDlyNb (NBPtr, 0, TrnDly, DrbnVar, 0);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets a delay value a PCI register during training
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] TrnDly - type of delay to be set
+ * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
+ * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
+ * @param[in] Field - Value to be programmed
+ *
+ */
+
+VOID
+MemRecNSetTrainDlyNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN TRN_DLY_TYPE TrnDly,
+ IN DRBN DrbnVar,
+ IN UINT16 Field
+ )
+{
+ NBPtr->MemRecNcmnGetSetTrainDlyNb (NBPtr, 1, TrnDly, DrbnVar, Field);
+}
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrndct.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrndct.c
new file mode 100644
index 0000000000..15ccaf3e8a
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrndct.c
@@ -0,0 +1,1502 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrndct.c
+ *
+ * Northbridge common DCT support for Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem/NB)
+ * @e \$Revision: 38303 $ @e \$Date: 2010-09-22 00:22:47 +0800 (Wed, 22 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 "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "cpuFamRegisters.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mru.h"
+#include "ma.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_MEM_NB_MRNDCT_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define RECDEF_DRAM_CONTROL_REG 0x320C2A06
+#define RECDEF_DRAM_MRSREG 0x000400A4
+#define RECDEF_DRAM_TIMING_LO 0x000A0092
+#define RECDEF_DRAM_TIMING_HI 0xB6D218FF
+#define RECDEF_CSMASK_REG 0x00083FE0
+#define RECDEF_DRAM_CONFIG_LO_REG 0x00000000
+#define RECDEF_DRAM_CONFIG_HI_REG 0x1F48010B
+#define RECDEF_DRAM_BASE_REG 0x00000003
+
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/// Type of an entry for processing phy init compensation for client NB
+typedef struct {
+ BIT_FIELD_NAME IndexBitField; ///< Bit field on which the value is decided
+ BIT_FIELD_NAME StartTargetBitField; ///< First bit field to be modified
+ BIT_FIELD_NAME EndTargetBitField; ///< Last bit field to be modified
+ UINT16 ExtraValue; ///< Extra value needed to be written to bit field
+ CONST UINT16 (*TxPrePN)[4]; ///< Pointer to slew rate table
+} REC_PHY_COMP_INIT_CLIENTNB;
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+VOID
+STATIC
+MemRecTCtlOnDimmMirrorNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN BOOLEAN SetFlag
+ );
+
+VOID
+STATIC
+MemRecNSwapBitsNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemRecNProgNbPstateDependentRegClientNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemRecNTrainPhyFenceNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+VOID
+STATIC
+MemRecNInitPhyCompClientNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function programs the memory controller with configuration parameters
+ *
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return TRUE - An Error value lower than AGESA_ERROR may have occurred
+ * @return FALSE - An Error value greater than or equal to AGESA_ERROR may have occurred
+ */
+
+BOOLEAN
+MemRecNAutoConfigNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 Dimm;
+ UINT8 Dct;
+ UINT32 RegValue;
+ UINT8 ChipSel;
+ UINT32 CSBase;
+ DCT_STRUCT *DCTPtr;
+ CH_DEF_STRUCT *ChannelPtr;
+
+ Dct = NBPtr->Dct;
+ DCTPtr = NBPtr->DCTPtr;
+ ChannelPtr = NBPtr->ChannelPtr;
+
+ //Prepare variables for future usage.
+ for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) {
+ if ((ChannelPtr->ChDimmValid & (UINT8) 1 << Dimm) != 0) {
+ DCTPtr->Timings.CsPresent |= (UINT16) 1 << (Dimm * 2);
+ if (((ChannelPtr->DimmDrPresent & (UINT8) 1 << Dimm) == 0) && ((ChannelPtr->DimmQrPresent & (UINT8) 1 << Dimm) == 0)) {
+ continue;
+ } else {
+ DCTPtr->Timings.CsPresent |= (UINT16) 1 << (Dimm * 2 + 1);
+ }
+ }
+ }
+
+ Dimm = NBPtr->DimmToBeUsed;
+
+ //Temporarily set all CS Base/Limit registers (corresponding to Dimms exist on a channel) with 256MB size for WL training.
+ CSBase = 0;
+ for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) {
+ if (DCTPtr->Timings.CsPresent & (UINT8) 1 << ChipSel) {
+
+ CSBase &= (UINT32) ~0x08; //Clear OnDimmMirror bit.
+ if (((ChipSel & 1) != 0) && ((ChannelPtr->DimmMirrorPresent & (UINT8) 1 << (ChipSel >> 1)) != 0)) {
+ CSBase |= (UINT32) 0x08; //Set OnDimmMirror bit.
+ }
+ MemRecNSetBitFieldNb (NBPtr, (BFCSBaseAddr0Reg + ChipSel), (CSBase | 0x01));
+ CSBase += 0x100000;
+ if ((ChipSel & 1) == 0) {
+ MemRecNSetBitFieldNb (NBPtr, (BFCSMask0Reg + (ChipSel >> 1)), RECDEF_CSMASK_REG);
+ }
+ }
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFDramBaseReg0, RECDEF_DRAM_BASE_REG);
+ MemRecNSetBitFieldNb (NBPtr, BFDramLimitReg0, 0x70000);
+
+ // Disable the other DCT
+ NBPtr->MemRecNSwitchDctNb (NBPtr, Dct ^ 0x01);
+ MemRecNSetBitFieldNb (NBPtr, BFDisDramInterface, 1);
+ NBPtr->MemRecNSwitchDctNb (NBPtr, Dct);
+ if (Dct != 0) {
+ // If DCT 1, set DctSelBase registers
+ MemRecNSetBitFieldNb (NBPtr, BFDctSelBaseAddrReg, 0x00000003);
+ MemRecNSetBitFieldNb (NBPtr, BFDctSelBaseOffsetReg, 0x00000000);
+ }
+
+ MemRecNSetBitFieldNb (NBPtr, BFDramBankAddrReg, 0x00001111);
+
+ // Set timing registers
+ MemRecNSetBitFieldNb (NBPtr, BFDramTimingLoReg, RECDEF_DRAM_TIMING_LO);
+ MemRecNSetBitFieldNb (NBPtr, BFDramTimingHiReg, RECDEF_DRAM_TIMING_HI);
+ MemRecNSetBitFieldNb (NBPtr, BFDramMRSReg, RECDEF_DRAM_MRSREG);
+ MemRecNSetBitFieldNb (NBPtr, BFDramControlReg, RECDEF_DRAM_CONTROL_REG);
+
+ // Set DRAM Config Low Register
+ RegValue = RECDEF_DRAM_CONFIG_LO_REG;
+ // Set x4Dimm based on DIMM type
+ if ((NBPtr->ChannelPtr->Dimmx4Present & ((UINT8) 1 << Dimm)) != 0) {
+ RegValue |= ((UINT32) 1 << (Dimm + 12));
+ }
+ // If not registered, set unbuffered DIMM
+ if (!(NBPtr->ChannelPtr->RegDimmPresent & ((UINT8) 1 << Dimm))) {
+ RegValue |= ((UINT32) 1 << 16);
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFDramConfigLoReg, RegValue);
+
+ // Set DRAM Config High Register
+ RegValue = RECDEF_DRAM_CONFIG_HI_REG;
+ MemRecNSetBitFieldNb (NBPtr, BFDramConfigHiReg, RegValue);
+
+ //======================================================================
+ // Build Dram Config Misc Register Value
+ //======================================================================
+ //
+ if ((NBPtr->ChannelPtr->RegDimmPresent != 0) && (NBPtr->ChannelPtr->TechType == DDR3_TECHNOLOGY)) {
+ MemRecNSetBitFieldNb (NBPtr, BFSubMemclkRegDly, 1);
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFOdtSwizzle, 1);
+
+ return TRUE;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets platform specific config/timing values from the interface layer and
+ * programs them into DCT.
+ *
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return TRUE - An Error value lower than AGESA_ERROR may have occurred
+ * @return FALSE - An Error value greater than or equal to AGESA_ERROR may have occurred
+ */
+
+BOOLEAN
+MemRecNPlatformSpecNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 p;
+
+ p = 0;
+ for (p = 0; p < MAX_PLATFORM_TYPES; p++) {
+ if (NBPtr->MemPtr->GetPlatformCfg[p] (NBPtr->MemPtr, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr) == AGESA_SUCCESS) {
+ MemRecNSetBitFieldNb (NBPtr, BFODCControl, NBPtr->ChannelPtr->DctOdcCtl);
+ MemRecNSetBitFieldNb (NBPtr, BFAddrTmgControl, NBPtr->ChannelPtr->DctAddrTmg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function reads MemClkFreqVal bit to see if the DIMMs are present in this node.
+ * If the DIMMs are present then set the DRAM Enable bit for this node.
+ *
+ * Setting dram init starts up the DCT state machine, initializes the
+ * dram devices with MRS commands, and kicks off any
+ * HW memory clear process that the chip is capable of. The sooner
+ * that dram init is set for all nodes, the faster the memory system
+ * initialization can complete. Thus, the init loop is unrolled into
+ * two loops so as to start the processes for non BSP nodes sooner.
+ * This procedure will not wait for the process to finish. Synchronization is
+ * handled elsewhere.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNStartupDCTNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ // 1. Ensure F2x[1, 0]9C_x08[DisAutoComp] = 1.
+ // 2. BIOS waits 5 us for the disabling of the compensation engine to complete.
+ // ------- Done in InitPhyComp_Nb -------
+ //
+ MemRecNSetBitFieldNb (NBPtr, BFDisAutoComp, 1);
+ MemRecUWait10ns (500, NBPtr->MemPtr);
+
+ //MemRecNSetBitFieldNb (NBPtr, BFInitDram, 1); // HW Dram init
+ AGESA_TESTPOINT (TpProcMemDramInit, &(NBPtr->MemPtr->StdHeader));
+ NBPtr->TechPtr->DramInit (NBPtr->TechPtr);
+
+ // 7. Program F2x[1, 0]9C_x08[DisAutoComp] = 0.
+ // 8. BIOS must wait 750 us for the phy compensation engine
+ // to reinitialize.
+ //
+ MemRecNSetBitFieldNb (NBPtr, BFDisAutoComp, 0);
+ MemRecUWait10ns (75000, NBPtr->MemPtr);
+
+ while (MemRecNGetBitFieldNb (NBPtr, BFDramEnabled) == 0);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the DRAM devices on all DCTs at the same time
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNStartupDCTClientNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ // Program D18F2x[1,0]9C_x0000_000B = 80000000h. #109999.
+ MemRecNSetBitFieldNb (NBPtr, BFDramPhyStatusReg, 0x80000000);
+
+ // Program D18F2x[1,0]9C_x0D0F_E013[PllRegWaitTime] = 0118h. #193770.
+ MemRecNSetBitFieldNb (NBPtr, BFPllRegWaitTime, 0x118);
+
+ // Phy Voltage Level Programming
+ MemRecNPhyVoltageLevelNb (NBPtr);
+
+ // Run frequency change sequence
+ MemRecNSetBitFieldNb (NBPtr, BFPllLockTime, NBPtr->FreqChangeParam->PllLockTimeDefault);
+ MemRecNSetBitFieldNb (NBPtr, BFMemClkFreq, 6);
+ MemRecNProgNbPstateDependentRegClientNb (NBPtr);
+ MemRecNSetBitFieldNb (NBPtr, BFMemClkFreqVal, 1);
+ MemRecNSetBitFieldNb (NBPtr, BFPllLockTime, 0x000F);
+
+ MemRecNSetBitFieldNb (NBPtr, BFDbeGskMemClkAlignMode, 0);
+ MemRecNSetBitFieldNb (NBPtr, BFEnDramInit, 1);
+
+ // Phy fence programming
+ MemRecNPhyFenceTrainingNb (NBPtr);
+
+ // Phy Compensation Initialization
+ MemRecNInitPhyCompClientNb (NBPtr);
+
+ // Run DramInit sequence
+ AGESA_TESTPOINT (TpProcMemDramInit, &(NBPtr->MemPtr->StdHeader));
+ NBPtr->TechPtr->DramInit (NBPtr->TechPtr);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the maximum round-trip latency in the system from the processor to the DRAM
+ * devices and back.
+
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] MaxRcvEnDly - Maximum receiver enable delay value
+ *
+ */
+
+VOID
+MemRecNSetMaxLatencyNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT16 MaxRcvEnDly
+ )
+{
+ UINT16 SubTotal;
+
+ AGESA_TESTPOINT (TpProcMemRcvrCalcLatency, &(NBPtr->MemPtr->StdHeader));
+
+ // Multiply the CAS Latency by two to get a number of 1/2 MEMCLKs UINTs.
+ SubTotal = 6 * 2;
+
+ // If registered DIMMs are being used then add 1 MEMCLK to the sub-total.
+ if (MemRecNGetBitFieldNb (NBPtr, BFUnBuffDimm) == 0) {
+ SubTotal += 2;
+ }
+
+ // if (AddrCmdSetup || CsOdtSetup || CkeSetup) then K := K + 2;
+ SubTotal += 2;
+
+ // If the F2x[1, 0]78[RdPtrInit] field is 4, 5, 6 or 7 MEMCLKs,
+ // then add 4, 3, 2, or 1 MEMCLKs, respectively to the sub-total.
+ //
+ SubTotal += 8 - 5;
+
+ // Add the maximum (worst case) delay value of DqsRcvEnGrossDelay
+ // that exists across all DIMMs and byte lanes.
+ //
+ SubTotal += MaxRcvEnDly >> 5;
+
+ // Add 5.5 to the sub-total. 5.5 represents part of the processor
+ // specific constant delay value in the DRAM clock domain.
+ //
+ SubTotal += 5; // add 5.5 1/2MemClk
+
+ // Convert the sub-total (in 1/2 MEMCLKs) to northbridge clocks (NCLKs)
+ // as follows (assuming DDR400 and assuming that no P-state or link speed
+ // changes have occurred).
+ //
+ // Simplified formula:
+ // SubTotal *= (Fn2xD4[NBFid]+4)/4
+ //
+ SubTotal = SubTotal * ((UINT16) MemRecNGetBitFieldNb (NBPtr, BFNbFid) + 4);
+ SubTotal /= 4;
+
+ // Add 5 NCLKs to the sub-total. 5 represents part of the processor
+ // specific constant value in the northbridge clock domain.
+ //
+ SubTotal += 5;
+
+ // Program the F2x[1, 0]78[MaxRdLatency] register with the total delay value
+ MemRecNSetBitFieldNb (NBPtr, BFMaxLatency, SubTotal);
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * Set Dram ODT for mission mode and write leveling mode.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] OdtMode - Mission mode or write leveling mode
+ * @param[in] ChipSelect - Chip select number
+ * @param[in] TargetCS - Chip select number that is being trained
+ *
+ */
+
+VOID
+MemRecNSetDramOdtNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN ODT_MODE OdtMode,
+ IN UINT8 ChipSelect,
+ IN UINT8 TargetCS
+ )
+{
+ UINT8 DramTerm;
+ UINT8 DramTermDyn;
+
+ DramTerm = NBPtr->ChannelPtr->Reserved[0];
+ DramTermDyn = NBPtr->ChannelPtr->Reserved[1];
+
+ if (OdtMode == WRITE_LEVELING_MODE) {
+ if (ChipSelect == TargetCS) {
+ DramTerm = DramTermDyn;
+ MemRecNSetBitFieldNb (NBPtr, BFWrLvOdt, NBPtr->ChannelPtr->PhyWLODT[TargetCS >> 1]);
+ }
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFDramTerm, DramTerm);
+ MemRecNSetBitFieldNb (NBPtr, BFDramTermDyn, DramTermDyn);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sends an MRS command
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNSendMrsCmdNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ BOOLEAN ClearODM;
+ ClearODM = FALSE;
+ if (NBPtr->IsSupported[CheckClearOnDimmMirror]) {
+ ClearODM = FALSE;
+ if ((NBPtr->MCTPtr->LogicalCpuid.Revision & AMD_F10_C0) != 0) {
+ if (NBPtr->IsSupported[CheckClearOnDimmMirror]) {
+ if (MemRecNGetBitFieldNb (NBPtr, BFEnDramInit) == 0) {
+ // For C0, if EnDramInit bit is cleared, ODM needs to be cleared before sending MRS
+ MemRecTCtlOnDimmMirrorNb (NBPtr, FALSE);
+ ClearODM = TRUE;
+ }
+ }
+ }
+ }
+
+ MemRecNSwapBitsNb (NBPtr);
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS%d MR%d %04x\n",
+ (MemRecNGetBitFieldNb (NBPtr, BFDramInitRegReg) >> 20) & 0xF,
+ (MemRecNGetBitFieldNb (NBPtr, BFDramInitRegReg) >> 16) & 0xF,
+ (MemRecNGetBitFieldNb (NBPtr, BFDramInitRegReg) & 0xFFFF));
+
+ // 1.Set SendMrsCmd=1
+ MemRecNSetBitFieldNb (NBPtr, BFSendMrsCmd, 1);
+
+ // 2.Wait for SendMrsCmd=0
+ while (MemRecNGetBitFieldNb (NBPtr, BFSendMrsCmd)) {}
+
+ if (NBPtr->IsSupported[CheckClearOnDimmMirror]) {
+ if (ClearODM) {
+ // Restore ODM if necessary
+ MemRecTCtlOnDimmMirrorNb (NBPtr, TRUE);
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sends the ZQCL command
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNSendZQCmdNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ // 1.Program MrsAddress[10]=1
+ MemRecNSetBitFieldNb (NBPtr, BFMrsAddress, (UINT32) 1 << 10);
+
+ // 2.Set SendZQCmd=1
+ MemRecNSetBitFieldNb (NBPtr, BFSendZQCmd, 1);
+
+ // 3.Wait for SendZQCmd=0
+ while (MemRecNGetBitFieldNb (NBPtr, BFSendZQCmd)) {}
+
+ // 4.Wait 512 MEMCLKs
+ MemRecUWait10ns (128, NBPtr->MemPtr); // 512*2.5ns=1280, wait 1280ns
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function disables/enables F2x[1, 0][5C:40][OnDimmMirror]
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] SetFlag - Enable or disable flag - TRUE - Enable, FALSE - DISABLE
+ *
+ */
+
+VOID
+STATIC
+MemRecTCtlOnDimmMirrorNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN BOOLEAN SetFlag
+ )
+{
+ UINT8 Chipsel;
+ UINT32 CSBaseAddrReg;
+
+ for (Chipsel = 0; Chipsel < MAX_CS_PER_CHANNEL; Chipsel += 2) {
+ CSBaseAddrReg = MemRecNGetBitFieldNb (NBPtr, BFCSBaseAddr1Reg + Chipsel);
+ if ((CSBaseAddrReg & 1) == 1) {
+ if (SetFlag && ((NBPtr->ChannelPtr->DimmMirrorPresent & ((UINT8) 1 << (Chipsel >> 1))) != 0)) {
+ CSBaseAddrReg |= ((UINT32) 1 << BFOnDimmMirror);
+ } else {
+ CSBaseAddrReg &= ~((UINT32) 1 << BFOnDimmMirror);
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFCSBaseAddr1Reg + Chipsel, CSBaseAddrReg);
+ }
+ }
+}
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function swaps bits for OnDimmMirror support
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+STATIC
+MemRecNSwapBitsNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 ChipSel;
+ UINT32 MRSReg;
+
+ ChipSel = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFMrsChipSel);
+ if ((ChipSel & 1) != 0) {
+ MRSReg = MemRecNGetBitFieldNb (NBPtr, BFDramInitRegReg);
+ if ((NBPtr->ChannelPtr->DimmMirrorPresent & (UINT8) 1 << (ChipSel >> 1)) != 0) {
+ MRSReg = (MRSReg & 0xFFFCFE07) | ((MRSReg&0x100A8) << 1) | ((MRSReg&0x20150) >> 1);
+ MemRecNSetBitFieldNb (NBPtr, BFDramInitRegReg, MRSReg);
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function gets the total of sync components for Max Read Latency calculation
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return Total in 1/2 MEMCLKs
+ */
+
+UINT32
+MemRecNTotalSyncComponentsClientNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT32 T;
+ UINT32 P;
+ UINT32 AddrTmgCtl;
+ UINT32 MemClkPeriod;
+
+ AGESA_TESTPOINT (TpProcMemRcvrCalcLatency , &(NBPtr->MemPtr->StdHeader));
+
+ // Before calculating MaxRdLatecny, program a number of registers.
+ MemRecNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 1);
+ MemRecNSetBitFieldNb (NBPtr, BFEnterSelfRef, 1);
+ while (MemRecNGetBitFieldNb (NBPtr, BFEnterSelfRef) != 0) {}
+ MemRecNSetBitFieldNb (NBPtr, BFDbeGskMemClkAlignMode, 2);
+ MemRecNSetBitFieldNb (NBPtr, BFExitSelfRef, 1);
+ while (MemRecNGetBitFieldNb (NBPtr, BFExitSelfRef) != 0) {}
+ MemRecNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 0);
+
+ // P = P + ((16 + RdPtrInitMin - D18F2x[1,0]78[RdPtrInit]) MOD 16) where RdPtrInitMin = RdPtrInit
+ P = 0;
+
+ AddrTmgCtl = MemRecNGetBitFieldNb (NBPtr, BFAddrTmgControl);
+ if (((AddrTmgCtl >> 16) & 0x20) != (AddrTmgCtl & 0x20)) {
+ P += 1;
+ }
+
+ // IF (DbeGskMemClkAlignMode==01b || (DbeGskMemClkAlignMode==00b && !(AddrCmdSetup==CsOdtSetup==CkeSetup)))
+ // THEN P = P + 1
+
+ // IF (SlowAccessMode==1) THEN P = P + 2
+
+ // T = T + (0.5 * MemClkPeriod) - 786 ps
+ MemClkPeriod = 1000000 / DDR800_FREQUENCY;
+ T = MemClkPeriod / 2 - 768;
+
+ // If (AddrCmdSetup==0 && CsOdtSetup==0 && CkeSetup==0)
+ // then P = P + 1
+ // else P = P + 2
+ if ((AddrTmgCtl & 0x0202020) == 0) {
+ P += 1;
+ } else {
+ P += 2;
+ }
+
+ // P = P + (2 * (D18F2x[1,0]88[Tcl] clocks - 1))
+ P += 2 * 5; // Tcl = 6 clocks
+
+ // (DisCutThroughMode = 0), so P = P + 3
+ P += 3;
+
+ return ((P * MemClkPeriod + 1) / 2) + T;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function programs the phy registers according to the desired phy VDDIO voltage level
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNPhyVoltageLevelNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ BIT_FIELD_NAME BitField;
+ UINT16 Value;
+ UINT16 Mask;
+
+ Mask = 0xFFE7;
+ Value = (UINT16) NBPtr->RefPtr->DDR3Voltage << 3;
+
+ for (BitField = BFDataRxVioLvl; BitField <= BFCmpVioLvl; BitField++) {
+ if (BitField == BFCmpVioLvl) {
+ Mask = 0x3FFF;
+ Value <<= (14 - 3);
+ }
+ MemRecNSetBitFieldNb (NBPtr, BitField, ((MemRecNGetBitFieldNb (NBPtr, BitField) & Mask)) | Value);
+ }
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function executes prototypical Phy fence training function.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNPhyFenceTrainingNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 FenceThresholdTxDll;
+ UINT8 FenceThresholdRxDll;
+ UINT8 FenceThresholdTxPad;
+ UINT16 Fence2Data;
+
+ // 1. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=10b.
+ // 2. Perform phy fence training. See 2.10.3.2.3.1 [Phy Fence Training].
+ // 3. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdTxDll].
+ MemRecNSetBitFieldNb (NBPtr, BFFenceTrSel, 2);
+ MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 30, 26, BFPhyFence);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tFenceThresholdTxDll\n");
+ MemRecNTrainPhyFenceNb (NBPtr);
+ FenceThresholdTxDll = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFPhyFence);
+
+ // 4. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]0F[AlwaysEnDllClks]=001b.
+ MemRecNSetBitFieldNb (NBPtr, BFAlwaysEnDllClks, 0x1000);
+
+ // 5. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=01b.
+ // 6. Perform phy fence training. See 2.10.3.2.3.1 [Phy Fence Training].
+ // 7. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdRxDll].
+ MemRecNSetBitFieldNb (NBPtr, BFFenceTrSel, 1);
+ MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 25, 21, BFPhyFence);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFenceThresholdRxDll\n");
+ MemRecNTrainPhyFenceNb (NBPtr);
+ FenceThresholdRxDll = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFPhyFence);
+
+ // 8. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]0F[AlwaysEnDllClks]=000b.
+ MemRecNSetBitFieldNb (NBPtr, BFAlwaysEnDllClks, 0x0000);
+
+ // 9. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=11b.
+ // 10. Perform phy fence training. See 2.10.3.2.3.1 [Phy Fence Training].
+ // 11. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdTxPad].
+ MemRecNSetBitFieldNb (NBPtr, BFFenceTrSel, 3);
+ MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 20, 16, BFPhyFence);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFenceThresholdTxPad\n");
+ MemRecNTrainPhyFenceNb (NBPtr);
+ FenceThresholdTxPad = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFPhyFence);
+
+ // Program Fence2 threshold for Clk, Cmd, and Addr
+ if (FenceThresholdTxPad < 16) {
+ MemRecNSetBitFieldNb (NBPtr, BFClkFence2, FenceThresholdTxPad | 0x10);
+ MemRecNSetBitFieldNb (NBPtr, BFCmdFence2, FenceThresholdTxPad | 0x10);
+ MemRecNSetBitFieldNb (NBPtr, BFAddrFence2, FenceThresholdTxPad | 0x10);
+ } else {
+ MemRecNSetBitFieldNb (NBPtr, BFClkFence2, 0);
+ MemRecNSetBitFieldNb (NBPtr, BFCmdFence2, 0);
+ MemRecNSetBitFieldNb (NBPtr, BFAddrFence2, 0);
+ }
+
+ // Program Fence2 threshold for data
+ Fence2Data = 0;
+ if (FenceThresholdTxPad < 16) {
+ Fence2Data |= FenceThresholdTxPad | 0x10;
+ }
+ if (FenceThresholdRxDll < 16) {
+ Fence2Data |= (FenceThresholdRxDll | 0x10) << 10;
+ }
+ if (FenceThresholdTxDll < 16) {
+ Fence2Data |= (FenceThresholdTxDll | 0x10) << 5;
+ }
+ MemRecNSetBitFieldNb (NBPtr, BFDataFence2, Fence2Data);
+
+ // Reprogram F2x9C_04.
+ MemRecNSetBitFieldNb (NBPtr, BFAddrTmgControl, MemRecNGetBitFieldNb (NBPtr, BFAddrTmgControl));
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function executes Phy fence training
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+STATIC
+MemRecNTrainPhyFenceNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 Byte;
+ UINT16 Avg;
+ UINT8 PREvalue;
+
+ if (MemRecNGetBitFieldNb (NBPtr, BFDisDramInterface)) {
+ return;
+ }
+
+ // 1. BIOS first programs a seed value to the phase recovery
+ // engine registers.
+ //
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tSeeds: ");
+ for (Byte = 0; Byte < 9; Byte++) {
+ // This includes ECC as byte 8
+ MemRecNSetTrainDlyNb (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (0, Byte), 19);
+ IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", 19);
+ }
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tPhyFenceTrEn = 1");
+ // 2. Set F2x[1, 0]9C_x08[PhyFenceTrEn]=1.
+ MemRecNSetBitFieldNb (NBPtr, BFPhyFenceTrEn, 1);
+
+ MemRecUWait10ns (5000, NBPtr->MemPtr);
+
+ // 4. Clear F2x[1, 0]9C_x08[PhyFenceTrEn]=0.
+ MemRecNSetBitFieldNb (NBPtr, BFPhyFenceTrEn, 0);
+
+ // 5. BIOS reads the phase recovery engine registers
+ // F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52.
+ // 6. Calculate the average value of the fine delay and subtract 8.
+ //
+ Avg = 0;
+ for (Byte = 0; Byte < 9; Byte++) {
+ // This includes ECC as byte 8
+ PREvalue = (UINT8) (0x1F & MemRecNGetTrainDlyNb (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (0, Byte)));
+ Avg = Avg + ((UINT16) PREvalue);
+ }
+ Avg = ((Avg + 8) / 9); // round up
+ Avg -= 6;
+
+ // 7. Write the value to F2x[1, 0]9C_x0C[PhyFence].
+ MemRecNSetBitFieldNb (NBPtr, BFPhyFence, Avg);
+
+ // 8. BIOS rewrites F2x[1, 0]9C_x04, DRAM Address/Command Timing Control
+ // Register delays for both channels. This forces the phy to recompute
+ // the fence.
+ //
+ MemRecNSetBitFieldNb (NBPtr, BFAddrTmgControl, MemRecNGetBitFieldNb (NBPtr, BFAddrTmgControl));
+}
+
+/* -----------------------------------------------------------------------------*/
+CONST UINT16 RecPllDivTab[10] = {1, 2, 4, 8, 16, 128, 256, 1, 3, 6};
+
+/**
+ *
+ * This function calculates and programs NB P-state dependent registers
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+STATIC
+MemRecNProgNbPstateDependentRegClientNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 i;
+ UINT8 NclkFid;
+ UINT16 MemClkDid;
+ UINT8 PllMult;
+ UINT8 NclkDiv;
+ UINT32 NclkPeriod;
+ UINT32 MemClkPeriod;
+ INT32 PartialSum2x;
+ INT32 PartialSumSlotI2x;
+
+ NclkFid = (UINT8) (MemRecNGetBitFieldNb (NBPtr, BFMainPllOpFreqId) + 0x10);
+ MemClkDid = RecPllDivTab[MemRecNGetBitFieldNb (NBPtr, BFPllDiv)];
+ PllMult = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFPllMult);
+ NclkDiv = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFNbPs0NclkDiv);
+
+ NclkPeriod = (2500 * NclkDiv) / NclkFid;
+ MemClkPeriod = 1000000 / DDR800_FREQUENCY;
+
+ // Program D18F2x[1,0]F4_x30[DbeGskFifoNumerator] and D18F2x[1,0]F4_x31[DbeGskFifoDenominator].
+ MemRecNSetBitFieldNb (NBPtr, BFDbeGskFifoNumerator, NclkFid * MemClkDid * 16);
+ MemRecNSetBitFieldNb (NBPtr, BFDbeGskFifoDenominator, PllMult * NclkDiv);
+
+ // Program D18F2x[1,0]F4_x32[DataTxFifoSchedDlyNegSlot1, DataTxFifoSchedDlySlot1,
+ // DataTxFifoSchedDlyNegSlot0, DataTxFifoSchedDlySlot0].
+ // PartialSum = ((7 * NclkPeriod) + (1.5 * MemClkPeriod) + 520ps)*MemClkFrequency - tCWL -
+ // CmdSetup - PtrSeparation - 1. (Llano)
+ // PartialSum = ((5 * NclkPeriod) + MemClkPeriod) + 520ps)*MemClkFrequency - tCWL -
+ // CmdSetup - PtrSeparation - 1. (Ontario)
+ PartialSum2x = NBPtr->FreqChangeParam->NclkPeriodMul2x * NclkPeriod;
+ PartialSum2x += NBPtr->FreqChangeParam->MemClkPeriodMul2x * MemClkPeriod;
+ PartialSum2x += 520 * 2;
+ PartialSum2x = (PartialSum2x + MemClkPeriod - 1) / MemClkPeriod; // round-up here
+ PartialSum2x -= 2 * 5; //Tcwl + 5
+ if ((MemRecNGetBitFieldNb (NBPtr, BFAddrTmgControl) & 0x0202020) == 0) {
+ PartialSum2x -= 1;
+ } else {
+ PartialSum2x -= 2;
+ }
+ // ((16 + RdPtrInitMin - D18F2x78[RdPtrInit]) MOD 16)/2 where RdPtrInitMin = RdPtrInit
+ PartialSum2x -= 0;
+ PartialSum2x -= 2;
+
+ // If PartialSumSlotN is positive:
+ // DataTxFifoSchedDlySlotN=CEIL(PartialSumSlotN).
+ // DataTxFifoSchedDlyNegSlotN=0.
+ // Else if PartialSumSlotN is negative:
+ // DataTxFifoSchedDlySlotN=ABS(CEIL(PartialSumSlotN*MemClkPeriod/NclkPeriod)).
+ // DataTxFifoSchedDlyNegSlotN=1.
+ for (i = 0; i < 2; i++) {
+ PartialSumSlotI2x = PartialSum2x;
+ PartialSumSlotI2x += 2;
+ if (PartialSumSlotI2x > 0) {
+ MemRecNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlyNegSlot0 + i, 0);
+ MemRecNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlySlot0 + i, (PartialSumSlotI2x + 1) / 2);
+ } else {
+ MemRecNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlyNegSlot0 + i, 1);
+ PartialSumSlotI2x = ((-PartialSumSlotI2x) * MemClkPeriod) / (2 * NclkPeriod);
+ MemRecNSetBitFieldNb (NBPtr, BFDataTxFifoSchedDlySlot0 + i, PartialSumSlotI2x);
+ }
+ }
+ // Program ProcOdtAdv
+ MemRecNSetBitFieldNb (NBPtr, BFProcOdtAdv, 0);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function reads cache lines continuously using TCB CPG engine
+ *
+ * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] Buffer - Array of bytes to be filled with data read from DRAM
+ * @param[in] Address - System Address [47:16]
+ * @param[in] ClCount - Number of cache lines
+ *
+ */
+
+VOID
+MemRecNContReadPatternClientNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT8 Buffer[],
+ IN UINT32 Address,
+ IN UINT16 ClCount
+ )
+{
+ // 1. Program D18F2x1C0[RdDramTrainMode]=1.
+ MemRecNSetBitFieldNb (NBPtr, BFRdDramTrainMode, 1);
+
+ // 2. Program D18F2x1C0[TrainLength] to the appropriate number of cache lines.
+ MemRecNSetBitFieldNb (NBPtr, BFTrainLength, ClCount);
+
+ // 3. Program the DRAM training address as follows:
+ MemRecNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrLo, (Address >> 6));
+
+ // 4. Program D18F2x1D0[WrTrainBufAddr]=000h
+ MemRecNSetBitFieldNb (NBPtr, BFWrTrainBufAddr, 0);
+
+ // 5. Program D18F2x1C0[RdTrainGo]=1.
+ MemRecNSetBitFieldNb (NBPtr, BFRdTrainGo, 1);
+
+ // 6. Wait for D18F2x1C0[RdTrainGo]=0.
+ while (MemRecNGetBitFieldNb (NBPtr, BFRdTrainGo) != 0) {}
+
+ // 7. Read D18F2x1E8[TrainCmpSts] and D18F2x1E8[TrainCmpSts2].
+
+ // 8. Program D18F2x1C0[RdDramTrainMode]=0.
+ MemRecNSetBitFieldNb (NBPtr, BFRdDramTrainMode, 0);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for the systems with UDIMMs configuration
+ *
+ * @param[in,out] *MemData Pointer to MEM_DATA_STRUCTURE
+ * @param[in] SocketID Socket number
+ * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT
+ *
+ * @return AGESA_SUCCESS
+ * @return CurrentChannel->DctAddrTmg Address Command Timing Settings for specified channel
+ * @return CurrentChannel->DctOdcCtl Drive Strength settings for specified channel
+ * @return CurrentChannel->Reserved[0] Dram Term for specified channel
+ * @return CurrentChannel->Reserved[1] Dynamic Dram Term for specified channel
+ * @return CurrentChannel->PhyWLODT[0] WL ODT for DIMM0
+ * @return CurrentChannel->PhyWLODT[1] WL ODT for DIMM1
+ * @return CurrentChannel->PhyWLODT[2] WL ODT for DIMM2
+ * @return CurrentChannel->PhyWLODT[3] WL ODT for DIMM3
+ *
+ */
+AGESA_STATUS
+MemRecNGetPsCfgUDIMM3Nb (
+ IN OUT MEM_DATA_STRUCT *MemData,
+ IN UINT8 SocketID,
+ IN OUT CH_DEF_STRUCT *CurrentChannel
+ )
+{
+ UINT32 AddrTmgCTL;
+ UINT32 DctOdcCtl;
+ UINT8 Dimms;
+ UINT8 MaxDimmPerCH;
+ UINT8 DramTerm;
+ UINT8 DramTermDyn;
+
+ if ((CurrentChannel->RegDimmPresent != 0) || (CurrentChannel->SODimmPresent != 0)) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ Dimms = CurrentChannel->Dimms;
+ MaxDimmPerCH = RecGetMaxDimmsPerChannel (MemData->ParameterListPtr->PlatformMemoryConfiguration, 0, CurrentChannel->ChannelID);
+
+ if (MaxDimmPerCH == 1) {
+ return AGESA_UNSUPPORTED;
+ } else {
+ DctOdcCtl = 0x20223323;
+ AddrTmgCTL = 0x00390039;
+ if (Dimms == 1) {
+ DctOdcCtl = 0x20113222;
+ AddrTmgCTL = 0x00390039;
+ if (CurrentChannel->Loads == 16) {
+ AddrTmgCTL = 0x003B0000;
+ }
+ }
+ }
+ CurrentChannel->DctAddrTmg = AddrTmgCTL;
+ CurrentChannel->DctOdcCtl = DctOdcCtl;
+
+ // ODT
+ if (Dimms == 1) {
+ DramTerm = 1; // 60 ohms
+ DramTermDyn = 0; // Disable
+ if ((MaxDimmPerCH == 3) && (CurrentChannel->DimmDrPresent != 0)) {
+ DramTermDyn = 1; // 60 ohms
+ }
+ } else {
+ DramTerm = 3; // 40 ohms
+ DramTermDyn = 2; // 120 ohms
+ }
+ CurrentChannel->Reserved[0] = DramTerm;
+ CurrentChannel->Reserved[1] = DramTermDyn;
+
+ // WL ODT
+ if (Dimms == 1) {
+ CurrentChannel->PhyWLODT[0] = 0;
+ CurrentChannel->PhyWLODT[1] = (CurrentChannel->DimmDrPresent != 0) ? 8 : 2;
+ } else {
+ CurrentChannel->PhyWLODT[0] = 3;
+ CurrentChannel->PhyWLODT[1] = 3;
+ }
+ CurrentChannel->PhyWLODT[2] = 0;
+ CurrentChannel->PhyWLODT[3] = 0;
+
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for the systems with SODIMMs configuration
+ *
+ * @param[in,out] *MemData Pointer to MEM_DATA_STRUCTURE
+ * @param[in] SocketID Socket number
+ * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT
+ *
+ * @return AGESA_SUCCESS
+ * @return CurrentChannel->DctAddrTmg Address Command Timing Settings for specified channel
+ * @return CurrentChannel->DctOdcCtl Drive Strength settings for specified channel
+ * @return CurrentChannel->Reserved[0] Dram Term for specified channel
+ * @return CurrentChannel->Reserved[1] Dynamic Dram Term for specified channel
+ * @return CurrentChannel->PhyWLODT[0] WL ODT for DIMM0
+ * @return CurrentChannel->PhyWLODT[1] WL ODT for DIMM1
+ * @return CurrentChannel->PhyWLODT[2] WL ODT for DIMM2
+ * @return CurrentChannel->PhyWLODT[3] WL ODT for DIMM3
+ *
+ */
+AGESA_STATUS
+MemRecNGetPsCfgSODIMM3Nb (
+ IN OUT MEM_DATA_STRUCT *MemData,
+ IN UINT8 SocketID,
+ IN OUT CH_DEF_STRUCT *CurrentChannel
+ )
+{
+ UINT32 AddrTmgCTL;
+ UINT32 DctOdcCtl;
+ UINT8 MaxDimmPerCH;
+ UINT8 Dimms;
+ UINT8 DramTerm;
+ UINT8 DramTermDyn;
+
+ if (CurrentChannel->SODimmPresent != CurrentChannel->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ Dimms = CurrentChannel->Dimms;
+ MaxDimmPerCH = RecGetMaxDimmsPerChannel (MemData->ParameterListPtr->PlatformMemoryConfiguration, 0, CurrentChannel->ChannelID);
+
+ if (MaxDimmPerCH == 1) {
+ DctOdcCtl = 0x00113222;
+ AddrTmgCTL = 0;
+ } else {
+ DctOdcCtl = 0x00223323;
+ AddrTmgCTL = 0x00000039;
+ if (Dimms == 1) {
+ DctOdcCtl = 0x00113222;
+ AddrTmgCTL = 0;
+ }
+ }
+ CurrentChannel->DctAddrTmg = AddrTmgCTL;
+ CurrentChannel->DctOdcCtl = DctOdcCtl;
+
+ // ODT
+ if (Dimms == 1) {
+ DramTerm = 2; // 120 ohms
+ DramTermDyn = 0; // Disable
+ if (MaxDimmPerCH == 2) {
+ DramTerm = 1; // 60 ohms
+ }
+ } else {
+ DramTerm = 3; // 40 ohms
+ DramTermDyn = 2; // 120 ohms
+ }
+ CurrentChannel->Reserved[0] = DramTerm;
+ CurrentChannel->Reserved[1] = DramTermDyn;
+
+ // WL ODT
+ if (Dimms == 1) {
+ if (MaxDimmPerCH == 1) {
+ CurrentChannel->PhyWLODT[0] = (CurrentChannel->DimmDrPresent != 0) ? 4 : 1;
+ CurrentChannel->PhyWLODT[1] = 0;
+ } else {
+ CurrentChannel->PhyWLODT[0] = 0;
+ CurrentChannel->PhyWLODT[1] = (CurrentChannel->DimmDrPresent != 0) ? 8 : 2;
+ }
+ } else {
+ CurrentChannel->PhyWLODT[0] = 3;
+ CurrentChannel->PhyWLODT[1] = 3;
+ }
+ CurrentChannel->PhyWLODT[2] = 0;
+ CurrentChannel->PhyWLODT[3] = 0;
+
+ return AGESA_SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is function sets the platform specific settings for the systems with RDIMMs configuration
+ *
+ * @param[in,out] *MemData Pointer to MEM_DATA_STRUCTURE
+ * @param[in] SocketID Socket number
+ * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT
+ *
+ * @return AGESA_SUCCESS
+ * @return CurrentChannel->DctAddrTmg Address Command Timing Settings for specified channel
+ * @return CurrentChannel->DctOdcCtl Drive Strength settings for specified channel
+ * @return CurrentChannel->Reserved[0] Dram Term for specified channel
+ * @return CurrentChannel->Reserved[1] Dynamic Dram Term for specified channel
+ * @return CurrentChannel->PhyWLODT[0] WL ODT for DIMM0
+ * @return CurrentChannel->PhyWLODT[1] WL ODT for DIMM1
+ * @return CurrentChannel->PhyWLODT[2] WL ODT for DIMM2
+ * @return CurrentChannel->PhyWLODT[3] WL ODT for DIMM3
+ *
+ */
+
+AGESA_STATUS
+MemRecNGetPsCfgRDIMM3Nb (
+ IN OUT MEM_DATA_STRUCT *MemData,
+ IN UINT8 SocketID,
+ IN OUT CH_DEF_STRUCT *CurrentChannel
+ )
+{
+ STATIC CONST ADV_R_PSCFG_WL_ODT_ENTRY RecPSCfg2DIMMsWlODT[] = {
+ {SR_DIMM0, {0x01, 0x00, 0x00, 0x00}, 1},
+ {DR_DIMM0, {0x04, 0x00, 0x00, 0x00}, 1},
+ {QR_DIMM0, {0x05, 0x00, 0x00, 0x00}, 1},
+ {SR_DIMM1, {0x00, 0x02, 0x00, 0x00}, 1},
+ {DR_DIMM1, {0x00, 0x08, 0x00, 0x00}, 1},
+ {QR_DIMM1, {0x00, 0x0A, 0x00, 0x00}, 1},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, {0x03, 0x03, 0x00, 0x00}, 2},
+ {SR_DIMM0 + QR_DIMM1, {0x0B, 0x03, 0x00, 0x09}, 2},
+ {DR_DIMM0 + QR_DIMM1, {0x0B, 0x03, 0x00, 0x09}, 2},
+ {QR_DIMM0 + SR_DIMM1, {0x03, 0x07, 0x06, 0x00}, 2},
+ {QR_DIMM0 + DR_DIMM1, {0x03, 0x07, 0x06, 0x00}, 2},
+ {QR_DIMM0 + QR_DIMM1, {0x0B, 0x07, 0x0E, 0x0D}, 2}
+ };
+ STATIC CONST ADV_R_PSCFG_WL_ODT_ENTRY RecPSCfg3DIMMsWlODT[] = {
+ {SR_DIMM2 + DR_DIMM2, {0x00, 0x00, 0x04, 0x00}, 1},
+ {SR_DIMM0 + DR_DIMM0, {0x01, 0x02, 0x00, 0x00}, 1},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM2 + DR_DIMM2, {0x05, 0x00, 0x05, 0x00}, 2},
+ {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, {0x07, 0x07, 0x07, 0x00}, 3},
+ {QR_DIMM1, {0x00, 0x0A, 0x00, 0x0A}, 1},
+ {QR_DIMM1 + SR_DIMM2 + DR_DIMM2, {0x00, 0x06, 0x0E, 0x0C}, 2},
+ {SR_DIMM0 + DR_DIMM0 + QR_DIMM1, {0x0B, 0x03, 0x00, 0x09}, 2},
+ {SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, {0x0F, 0x07, 0x0F, 0x0D}, 3}
+ };
+ STATIC CONST ADV_R_PSCFG_WL_ODT_ENTRY RecPSCfg4DIMMsWlODT[] = {
+ {ANY_DIMM3, {0x00, 0x00, 0x00, 0x08}, 1},
+ {ANY_DIMM2 + ANY_DIMM3, {0x00, 0x00, 0x0C, 0x0C}, 2},
+ {ANY_DIMM1 + ANY_DIMM2 + ANY_DIMM3, {0x00, 0x0E, 0x0E, 0x0E}, 3},
+ {ANY_DIMM0 + ANY_DIMM1 + ANY_DIMM2 + ANY_DIMM3, {0x0F, 0x0F, 0x0F, 0x0F}, 4}
+ };
+
+ UINT8 i;
+ UINT8 j;
+ UINT8 Dimms;
+ UINT8 DimmQrPresent;
+ UINT32 AddrTmgCTL;
+ UINT32 DctOdcCtl;
+ UINT8 PhyWLODT[4];
+ UINT8 DramTerm;
+ UINT8 DramTermDyn;
+ UINT16 DIMMRankType;
+ UINT16 _DIMMRankType_;
+ UINT8 DimmTpMatch;
+ UINT8 MaxDimmPerCH;
+ UINT8 PSCfgWlODTSize;
+ CONST ADV_R_PSCFG_WL_ODT_ENTRY *PSCfgWlODTPtr;
+
+ if (CurrentChannel->RegDimmPresent != CurrentChannel->ChDimmValid) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ DIMMRankType = MemRecNGetPsRankType (CurrentChannel);
+ MaxDimmPerCH = RecGetMaxDimmsPerChannel (MemData->ParameterListPtr->PlatformMemoryConfiguration, 0, CurrentChannel->ChannelID);
+ Dimms = CurrentChannel->Dimms;
+ PSCfgWlODTPtr = RecPSCfg2DIMMsWlODT;
+ PSCfgWlODTSize = GET_SIZE_OF (RecPSCfg2DIMMsWlODT);
+ PhyWLODT[0] = PhyWLODT[1] = PhyWLODT[2] = PhyWLODT[3] = 0xFF;
+ DimmQrPresent = CurrentChannel->DimmQrPresent;
+
+ if (MaxDimmPerCH == 4) {
+ AddrTmgCTL = (Dimms > 2) ? 0x002F0000 : 0;
+ DctOdcCtl = (Dimms == 1) ? 0x20113222 : 0x20223222;
+ PSCfgWlODTPtr = RecPSCfg4DIMMsWlODT;
+ PSCfgWlODTSize = GET_SIZE_OF (RecPSCfg4DIMMsWlODT);
+ } else if (MaxDimmPerCH == 3) {
+ AddrTmgCTL = 0;
+ DctOdcCtl = 0x20223222;
+ if (Dimms == 3) {
+ AddrTmgCTL = 0x00380038;
+ DctOdcCtl = 0x20113222;
+ }
+ if (Dimms == 1) {
+ DctOdcCtl = 0x20113222;
+ }
+ PSCfgWlODTPtr = RecPSCfg3DIMMsWlODT;
+ PSCfgWlODTSize = GET_SIZE_OF (RecPSCfg3DIMMsWlODT);
+ } else if (MaxDimmPerCH == 2) {
+ AddrTmgCTL = 0;
+ DctOdcCtl = 0x20223222;
+ if ((Dimms == 1) && (DimmQrPresent == 0)) {
+ DctOdcCtl = 0x20113222;
+ }
+ } else {
+ AddrTmgCTL = 0;
+ DctOdcCtl = (DimmQrPresent == 0) ? 0x20113222 : 0x20223222;
+ }
+ CurrentChannel->DctAddrTmg = AddrTmgCTL;
+ CurrentChannel->DctOdcCtl = DctOdcCtl;
+
+ // ODT
+ if (Dimms == 1) {
+ DramTerm = 1; // 60 ohms
+ DramTermDyn = 0; // Disable
+ if (DimmQrPresent != 0) {
+ DramTermDyn = 2; // 120 ohms
+ }
+ } else {
+ DramTerm = 3; // 40 ohms
+ DramTermDyn = 2; // 120 ohms
+ if (DimmQrPresent != 0) {
+ DramTerm = 1; // 60 ohms
+ }
+ }
+ CurrentChannel->Reserved[0] = DramTerm;
+ CurrentChannel->Reserved[1] = DramTermDyn;
+
+ // WL ODT
+ for (i = 0; i < PSCfgWlODTSize; i++, PSCfgWlODTPtr++) {
+ if (Dimms != PSCfgWlODTPtr->Dimms) {
+ continue;
+ }
+ DimmTpMatch = 0;
+ _DIMMRankType_ = DIMMRankType & PSCfgWlODTPtr->DIMMRankType;
+ for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) {
+ if ((_DIMMRankType_ & (UINT16) 0x0F << (j << 2)) != 0) {
+ DimmTpMatch++;
+ }
+ }
+ if (DimmTpMatch == PSCfgWlODTPtr->Dimms) {
+ PhyWLODT[0] = PSCfgWlODTPtr->PhyWrLvOdt[0];
+ PhyWLODT[1] = PSCfgWlODTPtr->PhyWrLvOdt[1];
+ PhyWLODT[2] = PSCfgWlODTPtr->PhyWrLvOdt[2];
+ PhyWLODT[3] = PSCfgWlODTPtr->PhyWrLvOdt[3];
+ break;
+ }
+ }
+ CurrentChannel->PhyWLODT[0] = PhyWLODT[0];
+ CurrentChannel->PhyWLODT[1] = PhyWLODT[1];
+ CurrentChannel->PhyWLODT[2] = PhyWLODT[2];
+ CurrentChannel->PhyWLODT[3] = PhyWLODT[3];
+
+ return AGESA_SUCCESS;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function returns the max dimms for a given memory channel on a given
+ * processor. It first searches the platform override table for the max dimms
+ * value. If it is not provided, the AGESA default value is returned. The target
+ * socket must be a valid present socket.
+ *
+ * @param[in] PlatformMemoryConfiguration - Platform config table
+ * @param[in] SocketID - ID of the processor that owns the channel
+ * @param[in] ChannelID - Channel to get max dimms for
+ *
+ *
+ * @return UINT8 - Max Number of Dimms for that channel
+ */
+UINT8
+RecGetMaxDimmsPerChannel (
+ IN PSO_TABLE *PlatformMemoryConfiguration,
+ IN UINT8 SocketID,
+ IN UINT8 ChannelID
+ )
+{
+ UINT8 *DimmsPerChPtr;
+ UINT8 MaxDimmPerCH;
+
+ DimmsPerChPtr = MemRecFindPSOverrideEntry (PlatformMemoryConfiguration, PSO_MAX_DIMMS, SocketID, ChannelID);
+ if (DimmsPerChPtr != NULL) {
+ MaxDimmPerCH = *DimmsPerChPtr;
+ } else {
+ MaxDimmPerCH = 2;
+ }
+
+ return MaxDimmPerCH;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is the default return function of the ARDK block. The function always
+ * returns AGESA_UNSUPPORTED
+ *
+ * @param[in,out] *MemData Pointer to MEM_DATA_STRUCTURE
+ * @param[in] SocketID Socket number
+ * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT
+ *
+ * @return AGESA_UNSUPPORTED AGESA status indicating that default is unsupported
+ *
+ */
+
+AGESA_STATUS
+MemRecNGetPsCfgDef (
+ IN OUT MEM_DATA_STRUCT *MemData,
+ IN UINT8 SocketID,
+ IN OUT CH_DEF_STRUCT *CurrentChannel
+ )
+{
+ return AGESA_UNSUPPORTED;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * 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
+MemRecNGetPsRankType (
+ 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) 4 << (i << 2);
+ }
+ } else if ((CurrentChannel->DimmDrPresent & (UINT8) 1 << i) != 0) {
+ DIMMRankType |= (UINT16) 2 << (i << 2);
+ } else if ((CurrentChannel->DimmSRPresent & (UINT8) 1 << i) != 0) {
+ DIMMRankType |= (UINT16) 1 << (i << 2);
+ }
+ }
+ return DIMMRankType;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function initializes the DDR phy compensation logic
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+STATIC
+MemRecNInitPhyCompClientNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ // Slew rate table array [x]
+ // array[0]: slew rate for VDDIO 1.5V
+ // array[1]: slew rate for VDDIO 1.35V
+ CONST STATIC UINT16 RecTxPrePNDataDqs[2][4] = {
+ //{TxPreP, TxPreN}[VDDIO][Drive Strength]
+ {0x924, 0x924, 0x924, 0x924},
+ {0xFF6, 0xB6D, 0xB6D, 0x924}
+ };
+
+ CONST STATIC UINT16 RecTxPrePNCmdAddr[2][4] = {
+ //{TxPreP, TxPreN}[VDDIO][Drive Strength]
+ {0x492, 0x492, 0x492, 0x492},
+ {0x492, 0x492, 0x492, 0x492}
+ };
+ CONST STATIC UINT16 RecTxPrePNClock[2][4] = {
+ //{TxPreP, TxPreN}[VDDIO][Drive Strength]
+ {0x924, 0x924, 0x924, 0x924},
+ {0xDAD, 0xDAD, 0x924, 0x924}
+ };
+
+ //
+ // Tables to describe the relationship between drive strength bit fields, PreDriver Calibration bit fields and also
+ // the extra value that needs to be written to specific PreDriver bit fields
+ //
+ CONST REC_PHY_COMP_INIT_CLIENTNB RecPhyCompInitBitField[] = {
+ // 3. Program TxPreP/TxPreN for Data and DQS according toTable 14 if VDDIO is 1.5V or Table 15 if 1.35V.
+ // A. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]0[A,6]={0000b, TxPreP, TxPreN}.
+ // B. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]02={1000b, TxPreP, TxPreN}.
+ {BFDqsDrvStren, BFDataByteTxPreDriverCal2Pad1, BFDataByteTxPreDriverCal2Pad1, 0, RecTxPrePNDataDqs},
+ {BFDataDrvStren, BFDataByteTxPreDriverCal2Pad2, BFDataByteTxPreDriverCal2Pad2, 0, RecTxPrePNDataDqs},
+ {BFDataDrvStren, BFDataByteTxPreDriverCal, BFDataByteTxPreDriverCal, 8, RecTxPrePNDataDqs},
+ // 4. Program TxPreP/TxPreN for Cmd/Addr according toTable 16 if VDDIO is 1.5V or Table 17 if 1.35V.
+ // A. Program D18F2x[1,0]9C_x0D0F_[C,8][1:0][12,0E,0A,06]={0000b, TxPreP, TxPreN}.
+ // B. Program D18F2x[1,0]9C_x0D0F_[C,8][1:0]02={1000b, TxPreP, TxPreN}.
+ {BFCsOdtDrvStren, BFCmdAddr0TxPreDriverCal2Pad1, BFCmdAddr0TxPreDriverCal2Pad2, 0, RecTxPrePNCmdAddr},
+ {BFAddrCmdDrvStren, BFCmdAddr1TxPreDriverCal2Pad1, BFAddrTxPreDriverCal2Pad4, 0, RecTxPrePNCmdAddr},
+ {BFCsOdtDrvStren, BFCmdAddr0TxPreDriverCalPad0, BFCmdAddr0TxPreDriverCalPad0, 8, RecTxPrePNCmdAddr},
+ {BFCkeDrvStren, BFAddrTxPreDriverCalPad0, BFAddrTxPreDriverCalPad0, 8, RecTxPrePNCmdAddr},
+ {BFAddrCmdDrvStren, BFCmdAddr1TxPreDriverCalPad0, BFCmdAddr1TxPreDriverCalPad0, 8, RecTxPrePNCmdAddr},
+ // 5. Program TxPreP/TxPreN for Clock according toTable 18 if VDDIO is 1.5V or Table 19 if 1.35V.
+ // A. Program D18F2x[1,0]9C_x0D0F_2[1:0]02={1000b, TxPreP, TxPreN}.
+ {BFClkDrvStren, BFClock0TxPreDriverCalPad0, BFClock1TxPreDriverCalPad0, 8, RecTxPrePNClock}
+ };
+
+ BIT_FIELD_NAME CurrentBitField;
+ CONST UINT16 *TxPrePNArray;
+ UINT8 Voltage;
+ UINT8 CurDct;
+ UINT8 i;
+ UINT8 j;
+
+ CurDct = NBPtr->Dct;
+ NBPtr->SwitchDCT (NBPtr, 0);
+ // 1. Program D18F2x[1,0]9C_x0D0F_E003[DisAutoComp, DisalbePredriverCal]={1b, 1b}
+ MemRecNSetBitFieldNb (NBPtr, BFDisablePredriverCal, 0x6000);
+
+ NBPtr->SwitchDCT (NBPtr, CurDct);
+
+ Voltage = (UINT8) NBPtr->RefPtr->DDR3Voltage;
+
+ for (j = 0; j < GET_SIZE_OF (RecPhyCompInitBitField); j ++) {
+ i = (UINT8) MemRecNGetBitFieldNb (NBPtr, RecPhyCompInitBitField[j].IndexBitField);
+ TxPrePNArray = RecPhyCompInitBitField[j].TxPrePN[Voltage];
+ for (CurrentBitField = RecPhyCompInitBitField[j].StartTargetBitField; CurrentBitField <= RecPhyCompInitBitField[j].EndTargetBitField; CurrentBitField ++) {
+ MemRecNSetBitFieldNb (NBPtr, CurrentBitField, ((RecPhyCompInitBitField[j].ExtraValue << 12) | TxPrePNArray[i]));
+ }
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrnmct.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrnmct.c
new file mode 100644
index 0000000000..75156e7c0b
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrnmct.c
@@ -0,0 +1,298 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrnmct.c
+ *
+ * Northbridge Common MCT supporting functions Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem/NB)
+ * @e \$Revision: 38303 $ @e \$Date: 2010-09-22 00:22:47 +0800 (Wed, 22 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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "cpuFamilyTranslation.h"
+#include "cpuCacheInit.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_MEM_NB_MRNMCT_FILECODE
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the Recovery memory configuration function for Nb DDR3
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return AGESA_STATUS
+ * - AGESA_ALERT
+ * - AGESA_FATAL
+ * - AGESA_SUCCESS
+ * - AGESA_WARNING
+ */
+
+AGESA_STATUS
+MemRecNMemInitNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ AGESA_STATUS Status;
+ MEM_TECH_BLOCK *TechPtr;
+
+ TechPtr = NBPtr->TechPtr;
+
+ NBPtr->MemRecNInitializeMctNb (NBPtr);
+
+ if (NBPtr->IsSupported[DramModeBeforeDimmPres]) {
+ TechPtr->SetDramMode (TechPtr);
+ }
+
+ Status = AGESA_FATAL;
+ if (TechPtr->DimmPresence (TechPtr)) {
+
+ if (NBPtr->IsSupported[DramModeAfterDimmPres]) {
+ TechPtr->SetDramMode (TechPtr);
+ }
+
+ if (MemRecNAutoConfigNb (NBPtr)) {
+
+ AGESA_TESTPOINT (TpProcMemPlatformSpecificConfig, &(NBPtr->MemPtr->StdHeader));
+ if (MemRecNPlatformSpecNb (NBPtr)) {
+ AgesaHookBeforeDramInitRecovery (0, NBPtr->MemPtr);
+ AGESA_TESTPOINT (TpProcMemStartDcts, &(NBPtr->MemPtr->StdHeader));
+ MemRecNStartupDCTNb (NBPtr);
+
+ AGESA_TESTPOINT (TpProcMemMtrrConfiguration, &(NBPtr->MemPtr->StdHeader));
+ MemRecNCPUMemRecTypingNb (NBPtr);
+
+ AGESA_TESTPOINT (TpProcMemDramTraining, &(NBPtr->MemPtr->StdHeader));
+ NBPtr->TrainingFlow (NBPtr);
+
+ Status = AGESA_SUCCESS;
+ }
+ }
+ }
+
+ NBPtr->MemRecNFinalizeMctNb (NBPtr);
+
+ return Status;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function returns a physical address of a corresponding Chip select
+ *
+ * @return Addr - System Address
+ */
+
+UINT32
+MemRecNGetMCTSysAddrNb (
+ )
+{
+ UINT32 CSBase;
+
+ CSBase = (UINT32) 1 << 21; // 1MB offset to avoid compat area from the base address.
+ if ((CSBase >= (MCT_TRNG_KEEPOUT_START << 8)) && (CSBase <= (MCT_TRNG_KEEPOUT_END << 8))) {
+ CSBase += (((MCT_TRNG_KEEPOUT_END << 8) - CSBase) + 0x0FFFFF) & 0xFFF00000;
+ }
+
+ return CSBase;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function runs on the BSP only, it sets the fixed MTRRs for common legacy ranges.
+ * It sets TOP_MEM and TOM2 and some variable MTRRs with WB Uncacheable type.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemRecNCPUMemRecTypingNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ S_UINT64 SMsr;
+
+ MEM_DATA_STRUCT *MemPtr;
+ MemPtr = NBPtr->MemPtr;
+
+ //
+ //======================================================================
+ // Set default values for CPU registers
+ //======================================================================
+ //
+
+ LibAmdMsrRead (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.lo |= 0x1C0000; // turn on modification enable bit and
+ // mtrr enable bits
+ LibAmdMsrWrite (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ SMsr.lo = SMsr.hi = 0x1E1E1E1E;
+ LibAmdMsrWrite (0x250, (UINT64 *)&SMsr, &MemPtr->StdHeader); // 0 - 512K = WB Mem
+ LibAmdMsrWrite (0x258, (UINT64 *)&SMsr, &MemPtr->StdHeader); // 512K - 640K = WB Mem
+
+ LibAmdMsrRead (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.lo &= 0xFFF7FFFF; // turn off modification enable bit
+ LibAmdMsrWrite (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ //
+ //======================================================================
+ // Set TOP_MEM and TOM2 CPU registers
+ //======================================================================
+ //
+ SMsr.hi = 0;
+ SMsr.lo = 0x08000000;
+ LibAmdMsrWrite (TOP_MEM, (UINT64 *)&SMsr, &MemPtr->StdHeader); // TOP_MEM
+
+ // Set FS Base address for later memory accesses
+ SMsr.lo = 0;
+ LibAmdMsrWrite (FS_BASE, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+
+ //
+ //======================================================================
+ // Set variable MTRR values
+ //======================================================================
+ //
+ SMsr.lo = 0x00000006;
+ LibAmdMsrWrite (0x200, (UINT64 *)&SMsr, &MemPtr->StdHeader); // MTRRPhysBase0
+
+ SMsr.hi = NBPtr->VarMtrrHiMsk;
+ SMsr.lo = 0xF8000800;
+ LibAmdMsrWrite (0x201, (UINT64 *)&SMsr, &MemPtr->StdHeader); // MTRRPhysMask0
+
+}
+
+/*-----------------------------------------------------------------------------*/
+/**
+ *
+ * This function returns the upper 32 bits mask for variable MTRR based on
+ * the CPU_LOGICAL_ID.
+ * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
+ * @param[in] StdHeader - Header for library and services
+ *
+ * @return UINT32 - MTRR mask for upper 32 bits
+ *
+ */
+UINT32
+MemRecGetVarMtrrHiMsk (
+ IN CPU_LOGICAL_ID *LogicalIdPtr,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 TempNotCare;
+ CPU_SPECIFIC_SERVICES *FamilySpecificServices;
+ CACHE_INFO *CacheInfoPtr;
+
+ GetCpuServicesFromLogicalId (LogicalIdPtr, &FamilySpecificServices, StdHeader);
+ FamilySpecificServices->GetCacheInfo (FamilySpecificServices, &CacheInfoPtr, &TempNotCare, StdHeader);
+ return (UINT32) (CacheInfoPtr->VariableMtrrMask >> 32);
+}
+
+/*-----------------------------------------------------------------------------
+ *
+ *
+ * This function re-enable phy compensation.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] OptParam - Optional parameter
+ *
+ * @return TRUE
+ * ----------------------------------------------------------------------------
+ */
+BOOLEAN
+MemRecNReEnablePhyCompNb (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT VOID *OptParam
+ )
+{
+ UINT8 Dct;
+
+ Dct = NBPtr->Dct;
+
+ NBPtr->SwitchDCT (NBPtr, 0);
+ // Clear DisableCal and set DisablePredriverCal
+ MemRecNSetBitFieldNb (NBPtr, BFDisablePredriverCal, 0x2000);
+ NBPtr->SwitchDCT (NBPtr, Dct);
+
+ return TRUE;
+}
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrntrain3.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrntrain3.c
new file mode 100644
index 0000000000..7a35921643
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/NB/mrntrain3.c
@@ -0,0 +1,127 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrntrain3.c
+ *
+ * Common Recovery Northbridge function for training flow for DDR3
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/NB)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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 "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "OptionMemory.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mrt3.h"
+#include "Filecode.h"
+#define FILECODE PROC_RECOVERY_MEM_NB_MRNTRAIN3_FILECODE
+/* features */
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the training control flow
+ * The DDR3 mode bit must be set prior to calling this function
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ */
+VOID
+MemNRecTrainingFlowNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MemRecTTrainDQSWriteHw3 (NBPtr->TechPtr);
+
+ MemRecTTrainRcvrEnSw (NBPtr->TechPtr);
+
+ MemRecTTrainDQSPosSw (NBPtr->TechPtr);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the client training control flow
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ */
+VOID
+MemNRecTrainingFlowClientNb (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MemRecTTrainDQSWriteHw3 (NBPtr->TechPtr);
+
+ MemRecTTrainRcvrEnHw (NBPtr->TechPtr);
+
+ // Clear DisableCal and set DisablePredriverCal
+ NBPtr->FamilySpecificHook[ReEnablePhyComp] (NBPtr, NBPtr);
+
+ MemRecTTrainDQSPosSw (NBPtr->TechPtr);
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrp.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrp.c
new file mode 100644
index 0000000000..ab42a87eb8
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrp.c
@@ -0,0 +1,261 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrp.c
+ *
+ * Common platform specific configuration.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_PS_MRP_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+extern MEM_PSC_FLOW_BLOCK* memRecPlatSpecFlowArray[];
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function gets platform specific configuration such as Max Freq., Slow Mode, Dram Term,
+ * and so on.
+ *
+ * @param[in] *NBPtr Pointer to MEM_NB_BLOCK
+ * @return TRUE - Successfully execute platform specific configuration flow.
+ * @return FALSE - Fail to execute platform specific configuration flow.
+ *
+ */
+BOOLEAN
+MemPRecPSCFlow (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 i;
+
+ i = 0;
+ while (memRecPlatSpecFlowArray[i] != NULL) {
+ if ((memRecPlatSpecFlowArray[i])->DramTerm (NBPtr, (memRecPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memRecPlatSpecFlowArray[i])->ODTPattern (NBPtr, (memRecPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memRecPlatSpecFlowArray[i])->SAO (NBPtr, (memRecPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memRecPlatSpecFlowArray[i])->MR0WrCL (NBPtr, (memRecPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memRecPlatSpecFlowArray[i])->RC2IBT (NBPtr, (memRecPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memRecPlatSpecFlowArray[i])->RC10OpSpeed (NBPtr, (memRecPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memRecPlatSpecFlowArray[i])->LRIBT (NBPtr, (memRecPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memRecPlatSpecFlowArray[i])->LRNPR (NBPtr, (memRecPlatSpecFlowArray[i])->EntryOfTables)) {
+ if ((memRecPlatSpecFlowArray[i])->LRNLR (NBPtr, (memRecPlatSpecFlowArray[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
+MemPRecConstructRankTypeMap (
+ 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
+MemPRecIsIdSupported (
+ 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
+MemPRecGetPsRankType (
+ 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);
+ }
+ }
+ return DIMMRankType;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplribt.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplribt.c
new file mode 100644
index 0000000000..32a78c1b5f
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplribt.c
@@ -0,0 +1,183 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrplribt.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: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "cpuFamRegisters.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_RECOVERY_MEM_PS_MRPLRIBT_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
+MemPRecGetLRIBT (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 TableSize;
+ 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 = RecGetMaxDimmsPerChannel (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 (MemPRecIsIdSupported (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) {
+ return FALSE;
+ }
+
+ DDR3Voltage = (UINT8) (1 << (NBPtr->RefPtr->DDR3Voltage));
+ RankTypeOfPopulatedDimm = MemPRecGetPsRankType (CurrentChannel);
+
+ for (i = 0; i < TableSize; i++) {
+ MemPRecConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if (TblPtr->DimmPerCh == MaxDimmPerCh) {
+ 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) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplrnlr.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplrnlr.c
new file mode 100644
index 0000000000..3169e21fd1
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplrnlr.c
@@ -0,0 +1,111 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrplrnlr.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: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_RECOVERY_MEM_PS_MRPLRNLR_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
+MemPRecGetLRNLR (
+ 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/Recovery/Mem/Ps/mrplrnpr.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplrnpr.c
new file mode 100644
index 0000000000..ac934e5b20
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrplrnpr.c
@@ -0,0 +1,111 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrplrnpr.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: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_RECOVERY_MEM_PS_MRPLRNPR_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
+MemPRecGetLRNPR (
+ 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/Recovery/Mem/Ps/mrpmr0.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpmr0.c
new file mode 100644
index 0000000000..da78b20db2
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpmr0.c
@@ -0,0 +1,178 @@
+/* $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: (Proc/Recovery/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_RECOVERY_MEM_PS_MRPMR0_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
+MemPRecGetMR0WrCL (
+ 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 (MemPRecIsIdSupported (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) {
+ 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) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpodtpat.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpodtpat.c
new file mode 100644
index 0000000000..7b981d9ecc
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpodtpat.c
@@ -0,0 +1,183 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrpodtpat.c
+ *
+ * A sub-engine which extracts ODT pattern value.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_RECOVERY_MEM_PS_MRPODTPAT_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
+MemPRecGetODTPattern (
+ 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 = RecGetMaxDimmsPerChannel (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 (MemPRecIsIdSupported (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) {
+ return FALSE;
+ }
+
+ RankTypeOfPopulatedDimm = MemPRecGetPsRankType (CurrentChannel); //@todo - LRDIMM ?
+
+ for (i = 0; i < TableSize; i++) {
+ MemPRecConstructRankTypeMap ((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;
+ return TRUE;
+ }
+ TblPtr++;
+ }
+ return FALSE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprc10opspd.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprc10opspd.c
new file mode 100644
index 0000000000..5a2c1e0fda
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprc10opspd.c
@@ -0,0 +1,93 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrprc10opspd.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: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_PS_MRPRC10OPSPD_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprc2ibt.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprc2ibt.c
new file mode 100644
index 0000000000..99aa5c3430
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprc2ibt.c
@@ -0,0 +1,199 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrprc2ibt.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: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_RECOVERY_MEM_PS_MRPRC2IBT_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
+MemPRecGetRC2IBT (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 DimmIndex;
+ UINT8 TableSize;
+ 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;
+ MaxDimmPerCh = RecGetMaxDimmsPerChannel (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 (MemPRecIsIdSupported (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) {
+ return FALSE;
+ }
+
+ DDR3Voltage = (UINT8) (1 << (NBPtr->RefPtr->DDR3Voltage));
+ RankTypeOfPopulatedDimm = MemPRecGetPsRankType (CurrentChannel);
+
+ OrgTblPtr = TblPtr;
+ for (DimmIndex = 0; DimmIndex < MAX_DIMMS_PER_CHANNEL; DimmIndex++) {
+ TblPtr = OrgTblPtr;
+ if ((CurrentChannel->ChDimmValid& (UINT8) (1 << DimmIndex)) != 0) {
+ NumOfReg = CurrentChannel->CtrlWrd02[DimmIndex];
+ 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++) {
+ MemPRecConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if (TblPtr->DimmPerCh == MaxDimmPerCh) {
+ 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++;
+ }
+ }
+ }
+ return TRUE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprtt.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprtt.c
new file mode 100644
index 0000000000..523f729399
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrprtt.c
@@ -0,0 +1,218 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrprtt.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: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_PS_MRPRTT_FILECODE
+
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * 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
+MemPRecGetRttNomWr (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 TableSize;
+ 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 = RecGetMaxDimmsPerChannel (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 (MemPRecIsIdSupported (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) {
+ return FALSE;
+ }
+
+ DDR3Voltage = (UINT8) (1 << (NBPtr->RefPtr->DDR3Voltage));
+ RankTypeOfPopulatedDimm = MemPRecGetPsRankType (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);
+ }
+
+ for (i = 0; i < TableSize; i++) {
+ MemPRecConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if (TblPtr->DimmPerCh == MaxDimmPerCh) {
+ if ((TblPtr->VDDIO & DDR3Voltage) != 0) {
+ if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) {
+ if ((TblPtr->Dimm & TgtDimmType) != 0) {
+ if ((TblPtr->Rank & TgtRank) != 0) {
+ NBPtr->PsPtr->RttNom[Chipsel] = (UINT8) TblPtr->RttNom;
+ NBPtr->PsPtr->RttWr[Chipsel] = (UINT8) TblPtr->RttWr;
+ break;
+ }
+ }
+ }
+ }
+ }
+ TblPtr++;
+ }
+ if (i == TableSize) {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpsao.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpsao.c
new file mode 100644
index 0000000000..034217ba67
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Ps/mrpsao.c
@@ -0,0 +1,188 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrpsao.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: (Proc/Recovery/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 "mru.h"
+#include "ma.h"
+#include "mp.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+#define FILECODE PROC_RECOVERY_MEM_PS_MRPSAO_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
+MemPRecGetSAO (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN MEM_PSC_TABLE_BLOCK *EntryOfTables
+ )
+{
+ UINT8 i;
+ UINT8 MaxDimmPerCh;
+ UINT8 NOD;
+ UINT8 TableSize;
+ 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 = RecGetMaxDimmsPerChannel (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 (MemPRecIsIdSupported (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) {
+ return FALSE;
+ }
+
+ DDR3Voltage = (UINT8) (1 << (NBPtr->RefPtr->DDR3Voltage));
+ RankTypeOfPopulatedDimm = MemPRecGetPsRankType (CurrentChannel); //@todo - LRDIMM ?
+
+ for (i = 0; i < TableSize; i++) {
+ MemPRecConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
+ if (TblPtr->DimmPerCh == MaxDimmPerCh) {
+ 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++;
+ }
+ return FALSE;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrt3.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrt3.c
new file mode 100644
index 0000000000..4f59351115
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrt3.c
@@ -0,0 +1,189 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrt3.c
+ *
+ * Common Technology functions for DDR3 Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mrt3.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_TECH_DDR3_MRT3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function Constructs the technology block
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecConstructTechBlock3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 Dct;
+ UINT8 Channel;
+ for (Dct = 0; Dct < NBPtr->MCTPtr->DctCount; Dct++) {
+ NBPtr->SwitchDCT (NBPtr, Dct);
+ for (Channel = 0; Channel < NBPtr->DCTPtr->ChannelCount; Channel++) {
+ NBPtr->SwitchChannel (NBPtr, Channel);
+ NBPtr->ChannelPtr->TechType = DDR3_TECHNOLOGY;
+ }
+ }
+
+ TechPtr->NBPtr = NBPtr;
+ TechPtr->RefPtr = NBPtr->RefPtr;
+
+ TechPtr->DramInit = MemRecTDramInitSw3;
+ TechPtr->SetDramMode = MemRecTSetDramMode3;
+ TechPtr->DimmPresence = MemRecTDIMMPresence3;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the initial controller environment before training.
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTBeginTraining (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ S_UINT64 SMsr;
+ MEM_DATA_STRUCT *MemPtr;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+ MemPtr = NBPtr->MemPtr;
+
+ LibAmdReadCpuReg (CR4_REG, &TechPtr->CR4reg);
+ LibAmdWriteCpuReg (CR4_REG, TechPtr->CR4reg | ((UINT32) 1 << 9)); // enable SSE2
+
+ LibAmdMsrRead (HWCR, (UINT64 *) (&SMsr), &MemPtr->StdHeader); // HWCR
+ TechPtr->HwcrLo = SMsr.lo;
+ SMsr.lo |= 0x00020000; // turn on HWCR.wrap32dis
+ SMsr.lo &= 0xFFFF7FFF; // turn off HWCR.SSEDIS
+ LibAmdMsrWrite (HWCR, (UINT64 *) (&SMsr), &MemPtr->StdHeader);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the final controller environment after training.
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTEndTraining (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ S_UINT64 SMsr;
+ MEM_DATA_STRUCT *MemPtr;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+ MemPtr = NBPtr->MemPtr;
+
+ LibAmdWriteCpuReg (CR4_REG, TechPtr->CR4reg);
+
+ LibAmdMsrRead (HWCR, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ SMsr.lo = TechPtr->HwcrLo;
+ LibAmdMsrWrite (HWCR, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+}
+
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtrci3.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtrci3.c
new file mode 100644
index 0000000000..0d3e1de3ec
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtrci3.c
@@ -0,0 +1,244 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrtrci3.c
+ *
+ * Technology Control word initialization for DDR3 Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "OptionMemory.h"
+#include "Ids.h"
+#include "mm.h"
+#include "mn.h"
+#include "mru.h"
+#include "mt.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_TECH_DDR3_MRTRCI3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+UINT8
+STATIC
+MemRecTGetCtlWord3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 CtrlWordNum
+ );
+
+VOID
+STATIC
+MemRecTSendCtlWord3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 CmdNum,
+ IN UINT8 Value
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sends control words
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ * @return pDCT->Timings.TrwtTO updated
+ */
+
+VOID
+MemRecTDramControlRegInit3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ UINT8 RCNum;
+ UINT8 Data;
+
+ MEM_DATA_STRUCT *MemPtr;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+ MemPtr = NBPtr->MemPtr;
+
+ // wait 8us TACT must be changed to optimize to 8 MEM CLKs
+ // and wait 6us for PLL LOCK
+ MemRecUWait10ns (80 + 60, MemPtr);
+
+ // 2. Program F2x[1, 0]A8[CtrlWordCS]=bit mask for target chip selects.
+ NBPtr->SetBitField (NBPtr, BFCtrlWordCS, 3 << (NBPtr->DimmToBeUsed << 1));
+
+ for (RCNum = 0; RCNum <= 15; RCNum++) {
+ // wait 8us for TMRD, must be changed to optimize to 8 MEM CLKs
+ MemRecUWait10ns (80, MemPtr);
+
+ if ((RCNum != 6) && (RCNum != 7)) {
+ Data = MemRecTGetCtlWord3 (TechPtr, RCNum);
+ MemRecTSendCtlWord3 (TechPtr, RCNum, Data);
+ }
+ }
+
+ MemRecUWait10ns (60, MemPtr); // wait 6us for TSTAB
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function calculates the ControlRC value
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] CtrlWordNum - control Word number.
+ *
+ * @return Control Word value
+ */
+
+UINT8
+STATIC
+MemRecTGetCtlWord3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 CtrlWordNum
+ )
+{
+ UINT8 Data;
+
+ CH_DEF_STRUCT *ChannelPtr;
+
+ ChannelPtr = TechPtr->NBPtr->ChannelPtr;
+
+ Data = 0; //Default value for all control words is 0
+ switch (CtrlWordNum) {
+ case 0:
+ Data = 0x02; // DA4=1
+ break;
+ case 1:
+ Data = 0x0C; // if single rank, set DBA1 and DBA0
+ break;
+ case 3:
+ Data = ChannelPtr->CtrlWrd03[TechPtr->NBPtr->DimmToBeUsed];
+ break;
+ case 4:
+ Data = ChannelPtr->CtrlWrd04[TechPtr->NBPtr->DimmToBeUsed];
+ break;
+ case 5:
+ Data = ChannelPtr->CtrlWrd05[TechPtr->NBPtr->DimmToBeUsed];
+ break;
+ case 9:
+ Data = 0x0D;
+ break;
+ default:;
+ }
+
+ return (Data&0x0F);
+}
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sends control word command
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] CmdNum - control number.
+ * @param[in] Value - value to send
+ *
+ */
+
+VOID
+STATIC
+MemRecTSendCtlWord3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 CmdNum,
+ IN UINT8 Value
+ )
+{
+ MEM_NB_BLOCK *NBPtr;
+
+ ASSERT (CmdNum < 16);
+ ASSERT (Value < 16);
+
+ NBPtr = TechPtr->NBPtr;
+
+ // 1. Program MrsBank and MrsAddress.
+ // n = [BA2, A2, A1, A0].
+ // data = [BA1, BA0, A4, A3].
+ // Set all other bits in MrsAddress to zero.
+ //
+ NBPtr->SetBitField (NBPtr, BFMrsBank, ((CmdNum&8) >> 1) | (Value >> 2));
+ NBPtr->SetBitField (NBPtr, BFMrsAddress, ((Value&3) << 3) | (CmdNum&7));
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCS%d RC%02d %04x\n",
+ (NBPtr->GetBitField (NBPtr, BFDramInitRegReg) >> 20) & 0xF,
+ ((NBPtr->GetBitField (NBPtr, BFDramInitRegReg) >> 15) & 8) |
+ (NBPtr->GetBitField (NBPtr, BFDramInitRegReg) & 7),
+ ((NBPtr->GetBitField (NBPtr, BFDramInitRegReg) >> 14) & 0xC) |
+ ((NBPtr->GetBitField (NBPtr, BFDramInitRegReg) >> 3) & 3));
+
+ // 2.Set SendCtrlWord=1
+ NBPtr->SetBitField (NBPtr, BFSendCtrlWord, 1);
+ // 3.Wait for BFSendCtrlWord=0
+ while (NBPtr->GetBitField (NBPtr, BFSendCtrlWord) != 0) {}
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtsdi3.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtsdi3.c
new file mode 100644
index 0000000000..92a035fec7
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtsdi3.c
@@ -0,0 +1,360 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrtsdi3.c
+ *
+ * Technology Software DRAM Init for DDR3 Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "OptionMemory.h"
+#include "mm.h"
+#include "mn.h"
+#include "mru.h"
+#include "mt.h"
+#include "mrt3.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_TECH_DDR3_MRTSDI3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initiates software DRAM init
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTDramInitSw3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ UINT8 ChipSel;
+ MEM_DATA_STRUCT *MemPtr;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+ MemPtr = NBPtr->MemPtr;
+
+ // 3.Program F2x[1,0]7C[EnDramInit]=1
+ NBPtr->SetBitField (NBPtr, BFEnDramInit, 1);
+
+ // 4.wait 200us
+ MemRecUWait10ns (20000, MemPtr);
+
+ NBPtr->SetBitField (NBPtr, BFDeassertMemRstX, 1);
+
+ // 6.wait 500us
+ MemRecUWait10ns (50000, MemPtr);
+
+ // 7.NOP or deselect & take CKE high
+ NBPtr->SetBitField (NBPtr, BFAssertCke, 1);
+
+ // 8.wait 360ns
+ MemRecUWait10ns (36, MemPtr);
+
+ // The following steps are performed with registered DIMMs only and
+ // must be done for each chip select pair:
+ //
+ if (NBPtr->ChannelPtr->RegDimmPresent != 0) {
+ MemRecTDramControlRegInit3 (TechPtr);
+ }
+
+ //
+ // In recovery mode, we only need to initialize one chipsel for UDIMMs.
+ //
+ NBPtr->SetDramOdtRec (NBPtr, MISSION_MODE, 0, 0);
+
+ for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) {
+ if ((NBPtr->DCTPtr->Timings.CsPresent & (UINT16) 1 << ChipSel) != 0) {
+ NBPtr->SetBitField (NBPtr, BFMrsChipSel, ChipSel);
+ // 13.Send EMRS(2)
+ MemRecTEMRS23 (TechPtr);
+ NBPtr->SendMrsCmd (NBPtr);
+
+ // 14.Send EMRS(3). Ordinarily at this time, MrsAddress[2:0]=000b
+ MemRecTEMRS33 (TechPtr);
+ NBPtr->SendMrsCmd (NBPtr);
+
+ // 15.Send EMRS(1).
+ MemRecTEMRS13 (TechPtr);
+ NBPtr->SendMrsCmd (NBPtr);
+
+ // 16.Send MRS with MrsAddress[8]=1(reset the DLL)
+ MemRecTMRS3 (TechPtr);
+ NBPtr->SendMrsCmd (NBPtr);
+
+ //wait 500us
+ MemRecUWait10ns (50000, MemPtr);
+
+ if (NBPtr->ChannelPtr->RegDimmPresent == 0) {
+ break;
+ }
+ }
+ }
+
+ // 17.Send two ZQCL commands (to even then odd chip select)
+ NBPtr->sendZQCmd (NBPtr);
+ NBPtr->sendZQCmd (NBPtr);
+
+ // 18.Program F2x[1,0]7C[EnDramInit]=0
+ NBPtr->SetBitField (NBPtr, BFEnDramInit, 0);
+
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function calculates the EMRS1 value
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTEMRS13 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ UINT16 MrsAddress;
+ UINT8 DramTerm;
+
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+
+ // BA2=0,BA1=0,BA0=1
+ NBPtr->SetBitField (NBPtr, BFMrsBank, 1);
+
+ MrsAddress = 0;
+
+ // program MrsAddress[5,1]=output driver impedance control (DIC):
+ // based on F2x[1,0]84[DrvImpCtrl], which is 2'b01
+ MrsAddress |= ((UINT16) 1 << 1);
+
+ // program MrsAddress[9,6,2]=nominal termination resistance of ODT (RTT):
+ // based on F2x[1,0]84[DramTerm], which is 3'b001 (60 Ohms)
+ if (!(NBPtr->IsSupported[CheckDramTerm])) {
+ DramTerm = (UINT8) NBPtr->GetBitField (NBPtr, BFDramTerm);
+ } else {
+ DramTerm = NBPtr->ChannelPtr->Reserved[0];
+ }
+ if ((DramTerm & 1) != 0) {
+ MrsAddress |= ((UINT16) 1 << 2);
+ }
+ if ((DramTerm & 2) != 0) {
+ MrsAddress |= ((UINT16) 1 << 6);
+ }
+ if ((DramTerm & 4) != 0) {
+ MrsAddress |= ((UINT16) 1 << 9);
+ }
+
+ // program MrsAddress[12]=output disable (QOFF):
+ // based on F2x[1,0]84[Qoff], which is 1'b0
+
+ // program MrsAddress[11]=TDQS:
+ // based on F2x[1,0]94[RDqsEn], which is 1'b0
+
+ NBPtr->SetBitField (NBPtr, BFMrsAddress, MrsAddress);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function calculates the EMRS2 value
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTEMRS23 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ UINT16 MrsAddress;
+ UINT8 DramTermDyn;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+
+ // BA2=0,BA1=1,BA0=0
+ NBPtr->SetBitField (NBPtr, BFMrsBank, 2);
+
+ // program MrsAddress[5:3]=CAS write latency (CWL):
+ // based on F2x[1,0]84[Tcwl], which is 3'b000
+ //
+ MrsAddress = 0;
+
+ // program MrsAddress[6]=auto self refresh method (ASR):
+ // based on F2x[1,0]84[ASR], which is 1'b1
+ // program MrsAddress[7]=self refresh temperature range (SRT):
+ // based on F2x[1,0]84[SRT], which is also 1'b0
+ //
+ MrsAddress |= (UINT16) 1 << 6;
+
+ // program MrsAddress[10:9]=dynamic termination during writes (RTT_WR):
+ // based on F2x[1,0]84[DramTermDyn]
+ //
+ if (!(NBPtr->IsSupported[CheckDramTermDyn])) {
+ DramTermDyn = (UINT8) NBPtr->GetBitField (NBPtr, BFDramTermDyn);
+ } else {
+ DramTermDyn = NBPtr->ChannelPtr->Reserved[1];
+ }
+ MrsAddress |= (UINT16) DramTermDyn << 9;
+ NBPtr->SetBitField (NBPtr, BFMrsAddress, MrsAddress);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function calculates the EMRS3 value
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTEMRS33 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+
+ // BA2=0,BA1=1,BA0=1
+ NBPtr->SetBitField (NBPtr, BFMrsBank, 3);
+
+ // program MrsAddress[1:0]=multi purpose register address location
+ // (MPR Location):based on F2x[1,0]84[MprLoc], which is 0
+ // program MrsAddress[2]=multi purpose register
+ // (MPR):based on F2x[1,0]84[MprEn], which is also 0
+ //
+ NBPtr->SetBitField (NBPtr, BFMrsAddress, 0);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This sets MSS value
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTMRS3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ UINT16 MrsAddress;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+
+ // BA2=0,BA1=0,BA0=0
+ NBPtr->SetBitField (NBPtr, BFMrsBank, 0);
+
+ // program MrsAddress[1:0]=burst length and control method
+ // (BL):based on F2x[1,0]84[BurstCtrl], which is 1'b0
+ //
+ MrsAddress = 0;
+
+ // program MrsAddress[3]=1 (BT):interleaved
+ MrsAddress |= (UINT16) 1 << 3;
+
+ // program MrsAddress[6:4,2]=read CAS latency
+ // (CL):based on F2x[1,0]88[Tcl], which is 4'b0010
+ MrsAddress |= (UINT16) 2 << 4;
+
+ // program MrsAddress[11:9]=write recovery for auto-precharge
+ // (WR):based on F2x[1,0]84[Twr], which is 3'b010
+ //
+ MrsAddress |= (UINT16) 2 << 9;
+
+ // program MrsAddress[12]=0 (PPD):slow exit
+
+ // program MrsAddress[8]=1 (DLL):DLL reset
+ MrsAddress |= (UINT16) 1 << 8; // just issue DLL reset at first time
+
+ NBPtr->SetBitField (NBPtr, BFMrsAddress, MrsAddress);
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c
new file mode 100644
index 0000000000..7d20e45336
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c
@@ -0,0 +1,326 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrtspd3.c
+ *
+ * Technology SPD supporting functions for DDR3 Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "Ids.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mrtspd3.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_TECH_DDR3_MRTSPD3_FILECODE
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define _UNDEF_ 0xFF
+#define MAX_DIES_PER_SOCKET 2 ///< Set to largest of any CPU
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the DRAM mode
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ * @return TRUE - indicates that the DRAM mode is set to DDR2
+ */
+
+BOOLEAN
+MemRecTSetDramMode3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFLegacyBiosMode, 0);
+ TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFDdr3Mode, 1);
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function determines if DIMMs are present. It checks checksum and interrogates the SPDs
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ * @return TRUE - indicates that a FATAL error has not occurred
+ * @return FALL - indicates that a FATAL error has not occurred
+ */
+
+BOOLEAN
+MemRecTDIMMPresence3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ UINT8 Node;
+ UINT8 Dct;
+ UINT8 Channel;
+ UINT8 i;
+ SPD_DEF_STRUCT *SPDPtr;
+ UINT8 *SpdBufferPtr;
+ DIE_STRUCT *MCTPtr;
+ DCT_STRUCT *DCTPtr;
+ CH_DEF_STRUCT *ChannelPtr;
+ MEM_NB_BLOCK *NBPtr;
+ UINT16 MaxDimms;
+ UINT16 Value16;
+ UINT8 Devwidth;
+ UINT8 Value8;
+ UINT16 DimmMask;
+ UINT8 VoltageMap;
+ UINT8 VDDByte;
+ UINT32 V1_2XDimmMap;
+ UINT32 V1_35DimmMap;
+ UINT32 V1_5DimmMap;
+
+ NBPtr = TechPtr->NBPtr;
+ MCTPtr = NBPtr->MCTPtr;
+ VoltageMap = 0xFF;
+ V1_2XDimmMap = 0;
+ V1_35DimmMap = 0;
+ V1_5DimmMap = 0;
+
+ NBPtr->DimmToBeUsed = _UNDEF_;
+ for (Node = 0; Node < NBPtr->MemPtr->DieCount; Node++) {
+ NBPtr->SwitchNodeRec (NBPtr, Node);
+ for (Dct = 0; Dct < NBPtr->MCTPtr->DctCount; Dct++) {
+ NBPtr->SwitchDCT (NBPtr, Dct);
+ DCTPtr = NBPtr->DCTPtr;
+ for (Channel = 0; Channel < DCTPtr->ChannelCount; Channel++) {
+ NBPtr->SwitchChannel (NBPtr, Channel);
+ ChannelPtr = NBPtr->ChannelPtr;
+ SPDPtr = NBPtr->SPDPtr;
+
+ // Get the maximum number of DIMMs
+ MaxDimms = MAX_DIMMS_PER_CHANNEL;
+ for (i = 0; i < MaxDimms; i++) {
+ // Bitmask representing dimm #i.
+ DimmMask = (UINT16) 1 << i;
+
+ if (SPDPtr[i].DimmPresent) {
+ SpdBufferPtr = (UINT8 *)&(SPDPtr[i].Data);
+
+ MCTPtr->DimmPresent |= DimmMask;
+ if (SpdBufferPtr[SPD_TYPE] == JED_DDR3SDRAM) {
+ ChannelPtr->ChDimmValid |= DimmMask;
+ }
+
+ // Check module type information.
+ if (SpdBufferPtr[SPD_DIMM_TYPE] == JED_RDIMM || SpdBufferPtr[SPD_DIMM_TYPE] == JED_MINIRDIMM) {
+ ChannelPtr->RegDimmPresent |= DimmMask;
+ }
+
+ if (SpdBufferPtr[SPD_DIMM_TYPE] == JED_SODIMM) {
+ ChannelPtr->SODimmPresent |= DimmMask;
+ }
+
+ // Get the Dimm width data
+ Devwidth = SpdBufferPtr[SPD_DEV_WIDTH] & 0x7;
+ switch (Devwidth) {
+ case 0:
+ ChannelPtr->Dimmx4Present |= DimmMask;
+ Devwidth = 4;
+ break;
+ case 1:
+ ChannelPtr->Dimmx8Present |= DimmMask;
+ Devwidth = 8;
+ break;
+ case 2:
+ ChannelPtr->Dimmx16Present |= DimmMask;
+ Devwidth = 16;
+ break;
+ default:
+ IDS_ERROR_TRAP;
+ }
+
+ // Determine the page size.
+ // page_size = 2^COLBITS * Devwidth/8
+ //
+ Value16 = (((UINT16) 1 << (SpdBufferPtr[SPD_COL_SZ]&7)) * Devwidth) / 8;
+ if ((Value16 >> 11) == 0) {
+ DCTPtr->Timings.DIMM1KPage |= DimmMask;
+ }
+
+ // Calculate bus loading per Channel
+ if (Devwidth == 16) {
+ Devwidth = 4;
+ } else if (Devwidth == 4) {
+ Devwidth = 16;
+ }
+
+ // specify the number of ranks
+ Value8 = ((SpdBufferPtr[SPD_RANKS] >> 3) & 0x07) + 1;
+ if (Value8 > 2) {
+ ChannelPtr->DimmQrPresent |= DimmMask;
+ Devwidth = Devwidth << 2;
+ } else if (Value8 == 2) {
+ ChannelPtr->DimmDrPresent |= DimmMask; // Dual rank dimms
+ Devwidth = Devwidth << 1;
+ } else {
+ ChannelPtr->DimmSRPresent |= DimmMask;
+ }
+
+ ChannelPtr->Ranks = ChannelPtr->Ranks + Value8;
+ ChannelPtr->Loads = ChannelPtr->Loads + Devwidth;
+ ChannelPtr->Dimms++;
+
+ // Check address mirror support for Unbuffered Dimms only
+ if ((ChannelPtr->RegDimmPresent & DimmMask) == 0) {
+ if ((SpdBufferPtr[SPD_ADDRMAP] & 1) != 0) {
+ ChannelPtr->DimmMirrorPresent |= DimmMask;
+ }
+ }
+
+ // Get control word values for RC3, RC4 and RC5
+ ChannelPtr->CtrlWrd03[i] = SpdBufferPtr[SPD_CTLWRD03] >> 4;
+ ChannelPtr->CtrlWrd04[i] = SpdBufferPtr[SPD_CTLWRD04] & 0x0F;
+ ChannelPtr->CtrlWrd05[i] = SpdBufferPtr[SPD_CTLWRD05] >> 4;
+ //
+ // Temporarily store info. of SPD byte 63 into CtrlWrd02(s),
+ // and they will be used late to calculate real RC2 and RC8 value
+ //
+ ChannelPtr->CtrlWrd02[i] = SpdBufferPtr[SPD_ADDRMAP] & 0x03;
+
+ // Get the common voltage if possible and create the individual Dimm maps per voltage
+ VDDByte = SpdBufferPtr[SPD_MNVVDD];
+ VDDByte ^= 1;
+ VoltageMap &= VDDByte;
+ //
+ // Create the Dimms map
+ //
+ // Node: 1 0
+ // Dct: 1 0 1 0
+ // Dimm: 3210 3210 3210 3210
+ // Dimmbitmap: xxxx xxxx xxxx xxxx
+ // Ex. 0000 0001 0010 0000 (V1_2XDimmMap)
+ // This indicates Node0/Dct1/Dimm1 and Node1/Dct0/Dimm0 are 1.2XV supported.
+ if ((VDDByte & (UINT8) (1 << VOLT1_25)) != 0) {
+ V1_2XDimmMap |= (UINT32) DimmMask << ((Node * NBPtr->MCTPtr->DctCount + Dct) * MAX_DIMMS_PER_CHANNEL);
+ } else if ((VDDByte & (UINT8) (1 << VOLT1_35)) != 0) {
+ V1_35DimmMap |= (UINT32) DimmMask << ((Node * NBPtr->MCTPtr->DctCount + Dct) * MAX_DIMMS_PER_CHANNEL);
+ } else {
+ V1_5DimmMap |= (UINT32) DimmMask << ((Node * NBPtr->MCTPtr->DctCount + Dct) * MAX_DIMMS_PER_CHANNEL);
+ }
+ } // if DIMM present
+ } // Dimm loop
+ } // Channel loop
+ } // DCT loop
+ }
+
+ if (VoltageMap != 0xFF) {
+ if (VoltageMap == 0) {
+ NBPtr->RefPtr->DDR3Voltage = VOLT1_35;
+ if (V1_35DimmMap != 0) {
+ i = (UINT8) LibAmdBitScanForward (V1_35DimmMap);
+ } else {
+ i = (UINT8) LibAmdBitScanForward (V1_2XDimmMap);
+ }
+ } else {
+ NBPtr->RefPtr->DDR3Voltage = (DIMM_VOLTAGE) LibAmdBitScanReverse (VoltageMap);
+ i = (UINT8) LibAmdBitScanForward (V1_2XDimmMap | V1_35DimmMap | V1_5DimmMap);
+ // In case of 1.35V Dimms and 1.5V Dimms mixture, we initialize the 1.35V Dimm.
+ if ((V1_35DimmMap != 0) && (V1_5DimmMap != 0)) {
+ NBPtr->RefPtr->DDR3Voltage = VOLT1_35;
+ i = (UINT8) LibAmdBitScanForward (V1_35DimmMap);
+ }
+ }
+ // Find out which Dimm we are going to initialize and which Node/Dct it belongs to
+ NBPtr->DimmToBeUsed = i % MAX_DIMMS_PER_CHANNEL;
+ Node = i / (NBPtr->MCTPtr->DctCount * MAX_DIMMS_PER_CHANNEL);
+ Dct = (i / MAX_DIMMS_PER_CHANNEL) & (NBPtr->MCTPtr->DctCount - 1);
+ NBPtr->SwitchNodeRec (NBPtr, Node);
+ NBPtr->SwitchDCT (NBPtr, Dct);
+ }
+
+ // If we have DIMMs, some further general characteristics checking
+ if (NBPtr->DimmToBeUsed == _UNDEF_) {
+ // Leave with an error - no dimms on this DCT
+ // LibAmdEventLog (AGESA_FATAL, MEM_ERROR_NO_DIMM_FOUND, 0, NBPtr->Dct, NBPtr->Channel, 0); //@attention commented out since it is not defined in recovery code
+ SetMemRecError (AGESA_FATAL, MCTPtr);
+ }
+
+ return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.h
new file mode 100644
index 0000000000..1159bf9586
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.h
@@ -0,0 +1,132 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrtspd3.h
+ *
+ * Technology SPD support for DDR3 Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MTSPD3_H_
+#define _MTSPD3_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*===============================================================================
+ * Jedec DDR III
+ *===============================================================================
+ */
+#define SPD_BYTE_USED 0
+#define SPD_TYPE 2 /* SPD byte read location */
+#define JED_DDR_SDRAM 7 /* Jedec defined bit field */
+#define JED_DDR2_SDRAM 8 /* Jedec defined bit field */
+#define JED_DDR3SDRAM 0xB /* Jedec defined bit field */
+
+#define SPD_DIMM_TYPE 3
+#define SPD_ATTRIB 21
+#define JED_DIF_CK_MSK 0x20 /* Differential Clock Input */
+#define JED_RDIMM 1
+#define JED_MINIRDIMM 5
+#define JED_UDIMM 2
+#define JED_SODIMM 3
+
+#define SPD_L_BANKS 4 /* [7:4] number of [logical] banks on each device */
+#define SPD_DENSITY 4 /* bit 3:0 */
+#define SPD_ROW_SZ 5 /* bit 5:3 */
+#define SPD_COL_SZ 5 /* bit 2:0 */
+#define SPD_MNVVDD 6
+#define SPD_RANKS 7 /* bit 5:3 */
+#define SPD_DEV_WIDTH 7 /* bit 2:0 */
+#define SPD_ECCBITS 8 /* bit 4:3 */
+#define JED_ECC 8
+#define SPD_RAWCARD 62 /* bit 2:0 */
+#define SPD_ADDRMAP 63 /* bit 0 */
+
+#define SPD_CTLWRD03 70 /* bit 7:4 */
+#define SPD_CTLWRD04 71 /* bit 3:0 */
+#define SPD_CTLWRD05 71 /* bit 7:4 */
+
+#define SPD_DIVIDENT 10
+#define SPD_DIVISOR 11
+
+#define SPD_TCK 12
+#define SPD_CASLO 14
+#define SPD_CASHI 15
+#define SPD_TAA 16
+
+#define SPD_TRP 20
+#define SPD_TRRD 19
+#define SPD_TRCD 18
+#define SPD_TRAS 22
+#define SPD_TWR 17
+#define SPD_TWTR 26
+#define SPD_TRTP 27
+#define SPD_TRC 23
+#define SPD_UPPER_TRC 21 /* bit 7:4 */
+#define SPD_UPPER_TRAS 21 /* bit 3:0 */
+#define SPD_TFAW 29
+#define SPD_UPPER_TFAW 28 /* bit 3:0 */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+#endif /* _MTSPD3_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrttwl3.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrttwl3.c
new file mode 100644
index 0000000000..068c926ff3
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/DDR3/mrttwl3.c
@@ -0,0 +1,347 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrttwl3.c
+ *
+ * Technology Phy assisted write levelization for recovery DDR3
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Ids.h"
+#include "mm.h"
+#include "mn.h"
+#include "mru.h"
+#include "mt.h"
+#include "mrt3.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_TECH_DDR3_MRTTWL3_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_BYTELANES 8 /* Max Bytelanes per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecTPrepareDIMMs3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN BOOLEAN Wl
+ );
+
+VOID
+STATIC
+MemRecTProcConfig3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+VOID
+STATIC
+MemRecTBeginWLTrain3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function executed hardware based write levelization for a specific die
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTTrainDQSWriteHw3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+
+ // Disable auto refresh by configuring F2x[1, 0]8C[DisAutoRefresh] = 1.
+ NBPtr->SetBitField (NBPtr, BFDisAutoRefresh, 1);
+ // Disable ZQ calibration short command by configuring F2x[1, 0]94[ZqcsInterval] = 00b.
+ NBPtr->SetBitField (NBPtr, BFZqcsInterval, 0);
+
+ // 1. Specify the target Dimm that is to be trained by programming
+ // F2x[1, 0]9C_x08[TrDimmSel].
+ NBPtr->SetBitField (NBPtr, BFTrDimmSel, NBPtr->DimmToBeUsed);
+
+ // 2. Prepare the DIMMs for write levelization using DDR3-defined
+ // MR commands.
+ MemRecTPrepareDIMMs3 (TechPtr, TRUE);
+
+ // 3. After the DIMMs are configured, BIOS waits 40 MEMCLKs to
+ // satisfy DDR3-defined internal DRAM timing.
+ MemRecUWait10ns (10, NBPtr->MemPtr);
+
+ // 4. Configure the processor's DDR phy for write levelization training:
+ MemRecTProcConfig3 (TechPtr);
+
+ // 5. Begin write levelization training
+ MemRecTBeginWLTrain3 (TechPtr);
+
+ // 6. Configure DRAM Phy Control Register so that the phy stops driving write levelization ODT.
+ // Program WrLvOdtEn=0
+ NBPtr->SetBitField (NBPtr, BFWrLvOdtEn, 0);
+
+ // Wait 10 MEMCLKs to allow for ODT signal settling.
+ MemRecUWait10ns (3, NBPtr->MemPtr);
+
+ // 7. Program the target Dimm back to normal operation
+ MemRecTPrepareDIMMs3 (TechPtr, FALSE);
+
+ // 13.Program F2x[1, 0]8C[DisAutoRefresh] = 0.
+ NBPtr->SetBitField (NBPtr, BFDisAutoRefresh, 0);
+ // 14.Program F2x[1, 0]94[ZqcsInterval] to the proper interval for the current memory configuration.
+ NBPtr->SetBitField (NBPtr, BFZqcsInterval, 2);
+
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function prepares the DIMMS for Write Levelization
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] Wl - Indicates if WL mode should be enabled
+ *
+ */
+
+VOID
+STATIC
+MemRecTPrepareDIMMs3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN BOOLEAN Wl
+ )
+{
+ UINT8 ChipSel;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+
+ AGESA_TESTPOINT (TpProcMemWlPrepDimms, &(NBPtr->MemPtr->StdHeader));
+
+ for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) {
+ // Set Dram ODT based on current mode.
+ if ((NBPtr->DCTPtr->Timings.CsPresent & (UINT16) 1 << ChipSel) != 0) {
+ if (Wl) {
+ NBPtr->SetDramOdtRec (NBPtr, WRITE_LEVELING_MODE, ChipSel, (NBPtr->DimmToBeUsed << 1));
+ } else {
+ NBPtr->SetDramOdtRec (NBPtr, MISSION_MODE, 0, 0);
+ }
+
+ NBPtr->SetBitField (NBPtr, BFMrsChipSel, ChipSel);
+
+ // Set MR1 to F2x7C[MrsAddress], F2x7C[MrsBank]=1
+ MemRecTEMRS13 (TechPtr);
+ // Program Level
+ if (Wl) {
+ if ((ChipSel >> 1) == NBPtr->DimmToBeUsed) {
+ NBPtr->SetBitField (NBPtr, BFLevel, 1);
+ if (ChipSel & 1) {
+ NBPtr->SetBitField (NBPtr, BFMrsQoff, 1);
+ }
+ }
+ }
+ // Send command
+ NBPtr->SendMrsCmd (NBPtr);
+
+ // Set MR2 to F2x7C[MrsAddress], F2x7C[MrsBank]=1
+ MemRecTEMRS23 (TechPtr);
+ // Send command
+ NBPtr->SendMrsCmd (NBPtr);
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function configures the DIMMS for Write Levelization
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+STATIC
+MemRecTProcConfig3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ MEM_NB_BLOCK *NBPtr;
+ CH_DEF_STRUCT *ChannelPtr;
+ UINT8 ByteLane;
+ UINT8 *Seed;
+ UINT8 DefaultSeed;
+ UINT8 CurrentSeed;
+ UINT8 Dimm;
+
+ NBPtr = TechPtr->NBPtr;
+ ChannelPtr = TechPtr->NBPtr->ChannelPtr;
+
+ Dimm = NBPtr->DimmToBeUsed;
+
+ // Program WrLvOdtEn=1
+ NBPtr->SetBitField (NBPtr, BFWrLvOdtEn, 1);
+
+ // Wait 10 MEMCLKs to allow for ODT signal settling.
+ MemRecUWait10ns (3, NBPtr->MemPtr);
+
+ // Program an initialization Value to registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52 to set
+ // the gross and fine delay for all the byte lane fields. If the target frequency is different than 400MHz,
+ // BIOS must execute two training passes for each Dimm. For pass 1 at a 400MHz MEMCLK frequency,
+ // use an initial total delay Value of 01Fh. This represents a 1UI (UI=.5MEMCLK) delay and is determined
+ // by design.
+
+ // Get default seed
+ if (ChannelPtr->RegDimmPresent != 0) {
+ DefaultSeed = 0x41;
+ } else if (ChannelPtr->SODimmPresent != 0) {
+ DefaultSeed = 0x12;
+ } else {
+ DefaultSeed = 0x1A;
+ }
+
+ // Get platform override seed
+ Seed = (UINT8 *) MemRecFindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_WL_SEED, NBPtr->MCTPtr->SocketId, ChannelPtr->ChannelID);
+
+ for (ByteLane = 0; ByteLane < 8; ByteLane++) {
+ // This includes ECC as byte 8
+ CurrentSeed = ((Seed != NULL) ? Seed[ByteLane] : DefaultSeed);
+ NBPtr->SetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), CurrentSeed);
+ ChannelPtr->WrDqsDlys[Dimm * MAX_BYTELANES + ByteLane] = CurrentSeed;
+ }
+
+ // Program F2x[1, 0]9C_x08[WrtLvTrMode]=0 for phy assisted training.
+
+ // Program F2x[1, 0]9C_x08[TrNibbleSel]=0
+
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function begins WL training for a specific DIMM
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+STATIC
+MemRecTBeginWLTrain3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ MEM_NB_BLOCK *NBPtr;
+ UINT8 ByteLane;
+ UINT8 Seed;
+ UINT8 Delay;
+ UINT8 Dimm;
+
+ NBPtr = TechPtr->NBPtr;
+
+ Dimm = NBPtr->DimmToBeUsed;
+ // Program F2x[1, 0]9C_x08[WrtLlTrEn]=1.
+ NBPtr->SetBitField (NBPtr, BFWrtLvTrEn, 1);
+
+ // Wait 200 MEMCLKs. If executing pass 2, wait 32 MEMCLKs.
+ MemRecUWait10ns (50, NBPtr->MemPtr);
+
+ // Program F2x[1, 0]9C_x08[WrtLlTrEn]=0.
+ NBPtr->SetBitField (NBPtr, BFWrtLvTrEn, 0);
+
+ // Read from registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52 to get the gross and fine Delay settings
+ // for the target Dimm and save these values.
+ for (ByteLane = 0; ByteLane < 8; ByteLane++) {
+ // This includes ECC as byte 8
+ Seed = NBPtr->ChannelPtr->WrDqsDlys[(Dimm * MAX_BYTELANES) + ByteLane];
+ Delay = (UINT8)NBPtr->GetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (Dimm, ByteLane));
+ if (((Seed >> 5) == 0) && ((Delay >> 5) == 3)) {
+ // If seed has gross delay of 0 and PRE has gross delay of 3,
+ // then round the total delay of TxDqs to 0.
+ Delay = 0;
+ }
+ NBPtr->SetTrainDly (NBPtr, AccessWrDqsDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), Delay);
+ NBPtr->ChannelPtr->WrDqsDlys[(Dimm * MAX_BYTELANES) + ByteLane] = Delay;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrtthrc.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrtthrc.c
new file mode 100644
index 0000000000..0964a53518
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrtthrc.c
@@ -0,0 +1,287 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrtthrc.c
+ *
+ * Phy assisted DQS receiver enable training
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "OptionMemory.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mru.h"
+#include "mt.h"
+#include "PlatformMemoryConfiguration.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_TECH_MRTTHRC_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_BYTELANES 8 /* Max Bytelanes per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecTPrepareRcvrEnDlySeed (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 ChipSel
+ );
+
+UINT16
+STATIC
+MemRecTProgramRcvrEnDly (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 ChipSel
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function executes Phy assisted receiver enable training for current node.
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ * @pre Auto refresh and ZQCL must be disabled
+ *
+ */
+VOID
+MemRecTTrainRcvrEnHw (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ UINT8 TempBuffer[64];
+ UINT8 Count;
+ UINT32 TestAddrRJ16;
+ UINT8 ChipSel;
+ UINT16 MaxRcvrDly;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+
+ AGESA_TESTPOINT (TpProcMemReceiverEnableTraining , &(NBPtr->MemPtr->StdHeader));
+
+ // Set environment settings before training
+ MemRecTBeginTraining (TechPtr);
+
+ ChipSel = NBPtr->DimmToBeUsed << 1;
+ TestAddrRJ16 = 1 << 21;
+
+ // 1.Prepare the DIMMs for training
+ NBPtr->SetBitField (NBPtr, BFTrDimmSel, ChipSel >> 1);
+
+ // 2.Prepare the phy for DQS receiver enable training.
+ MemRecTPrepareRcvrEnDlySeed (TechPtr, ChipSel);
+
+ // 3.BIOS initiates the phy assisted receiver enable training
+ NBPtr->SetBitField (NBPtr, BFDqsRcvTrEn, 1);
+
+ // 4.BIOS begins sending out of back-to-back reads to create
+ // a continuous stream of DQS edges on the DDR interface.
+ for (Count = 0; Count < 3; Count++) {
+ NBPtr->ReadPattern (NBPtr, TempBuffer, TestAddrRJ16, 64);
+ }
+
+ // 6.Wait 200 MEMCLKs.
+ MemRecUWait10ns (200, NBPtr->MemPtr);
+
+ // 7.Program [DqsRcvTrEn]=0 to stop the DQS receive enable training.
+ NBPtr->SetBitField (NBPtr, BFDqsRcvTrEn, 0);
+
+ // 8.Get the gross and fine delay values.
+ // 9.Calculate the corresponding final delay values
+ MaxRcvrDly = MemRecTProgramRcvrEnDly (TechPtr, ChipSel);
+
+ // Set Max Latency for both channels
+ NBPtr->SetMaxLatency (NBPtr, MaxRcvrDly);
+
+ // Restore environment settings after training
+ MemRecTEndTraining (TechPtr);
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function calculates RcvEn seed value for each rank
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] ChipSel - rank to be trained
+ *
+ */
+VOID
+STATIC
+MemRecTPrepareRcvrEnDlySeed (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 ChipSel
+ )
+{
+ MEM_NB_BLOCK *NBPtr;
+ CH_DEF_STRUCT *ChannelPtr;
+ UINT16 SeedTotal;
+ UINT16 SeedFine;
+ UINT16 SeedGross;
+ UINT16 SeedPreGross;
+ UINT16 DiffSeedGrossSeedPreGross;
+ UINT8 ByteLane;
+ UINT16 *PlatEstSeed;
+
+ NBPtr = TechPtr->NBPtr;
+ ChannelPtr = TechPtr->NBPtr->ChannelPtr;
+
+ // Get platform override seed
+ PlatEstSeed = (UINT16 *) MemRecFindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_RXEN_SEED, NBPtr->MCTPtr->SocketId, ChannelPtr->ChannelID);
+
+ for (ByteLane = 0; ByteLane < 8; ByteLane++) {
+ // For Pass1, BIOS starts with the delay value obtained from the first pass of write
+ // levelization training that was done in DDR3 Training and add a delay value of 3Bh.
+ SeedTotal = ChannelPtr->WrDqsDlys[((ChipSel >> 1) * MAX_BYTELANES) + ByteLane] + (PlatEstSeed != NULL) ? PlatEstSeed[ByteLane] : 0x3B;
+ // SeedGross = SeedTotal DIV 32.
+ SeedGross = (SeedTotal & 0x60) >> 5;
+ // SeedFine = SeedTotal MOD 32.
+ SeedFine = SeedTotal & 0x1F;
+
+ // Next, determine the gross component of SeedTotal. SeedGrossPass1=SeedTotal DIV 32.
+ // Then, determine the fine delay component of SeedTotal. SeedFinePass1=SeedTotal MOD 32.
+ // Use SeedGrossPass1 to determine SeedPreGrossPass1:
+
+ if ((SeedGross & 0x1) != 0) {
+ //if SeedGross is odd
+ SeedPreGross = 1;
+ } else {
+ //if SeedGross is even
+ SeedPreGross = 2;
+ }
+
+ // (SeedGross - SeedPreGross)
+ DiffSeedGrossSeedPreGross = SeedGross - SeedPreGross;
+
+ ChannelPtr->RcvEnDlys[(ChipSel * MAX_BYTELANES) + ByteLane] = DiffSeedGrossSeedPreGross << 5;
+
+ //BIOS programs registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52) with SeedPreGrossPass1
+ //and SeedFinePass1 from the preceding steps.
+ NBPtr->SetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (ChipSel >> 1, ByteLane), (SeedPreGross << 5) | SeedFine);
+
+ // 202688: Program seed value to RcvEnDly also.
+ NBPtr->SetTrainDly (NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (ChipSel >> 1, ByteLane), SeedGross << 5);
+ }
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function calculates final RcvrEnDly for each rank
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] ChipSel - Rank to be trained
+ *
+ * @return MaxDly - The largest delay value
+ *
+ */
+UINT16
+STATIC
+MemRecTProgramRcvrEnDly (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 ChipSel
+ )
+{
+ MEM_NB_BLOCK *NBPtr;
+ CH_DEF_STRUCT *ChannelPtr;
+ UINT16 DiffSeedGrossSeedPreGross;
+ UINT8 ByteLane;
+ UINT16 RcvEnDly;
+ UINT16 MaxDly;
+ NBPtr = TechPtr->NBPtr;
+ ChannelPtr = TechPtr->NBPtr->ChannelPtr;
+ MaxDly = 0;
+ for (ByteLane = 0; ByteLane < 8; ByteLane++) {
+ DiffSeedGrossSeedPreGross = (ChannelPtr->RcvEnDlys[(ChipSel * MAX_BYTELANES) + ByteLane]) & 0x1E0;
+ RcvEnDly = (UINT8) NBPtr->GetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (ChipSel >> 1, ByteLane));
+
+ RcvEnDly = RcvEnDly + DiffSeedGrossSeedPreGross;
+
+ // Add 1 UI to get to the midpoint of preamble
+ RcvEnDly += 0x20;
+
+ if (RcvEnDly > MaxDly) {
+ MaxDly = RcvEnDly;
+ }
+
+ NBPtr->SetTrainDly (NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS ((ChipSel >> 1), ByteLane), RcvEnDly);
+ }
+
+ return MaxDly;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrttpos.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrttpos.c
new file mode 100644
index 0000000000..dda47ec3b6
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrttpos.c
@@ -0,0 +1,115 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mttpos.c
+ *
+ * Technology DQS R/W position training. Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "amdlib.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_TECH_MRTTPOS_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function hard-codes DQS position delays for all bytes
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTTrainDQSPosSw (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ //Hard Code Settings
+ MemRecTSetWrDatRdDqs (TechPtr, 0x0F);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrttsrc.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrttsrc.c
new file mode 100644
index 0000000000..a9adf798ef
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/Tech/mrttsrc.c
@@ -0,0 +1,437 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrttsrc.c
+ *
+ * Technology Software based DQS receiver enable training Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 38442 $ @e \$Date: 2010-09-24 06:39:57 +0800 (Fri, 24 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 "OptionMemory.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mm.h"
+#include "mn.h"
+#include "mru.h"
+#include "mt.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_TECH_MRTTSRC_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_BYTELANES 8 /* Max Bytelanes per channel */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+VOID
+STATIC
+MemRecTSetRcvrEnDly (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 Receiver,
+ IN UINT16 RcvEnDly
+ );
+
+VOID
+STATIC
+MemRecTLoadRcvrEnDly (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 Receiver
+ );
+
+BOOLEAN
+STATIC
+MemRecTSaveRcvrEnDly (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 Receiver,
+ IN UINT16 RcvEnDly,
+ IN UINT8 CmpResult
+ );
+
+UINT8
+STATIC
+MemRecTCompare1ClPattern (
+ IN UINT8 Buffer[],
+ IN UINT8 Pattern[],
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function executes receiver enable training for BSP
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemRecTTrainRcvrEnSw (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ )
+{
+ _16BYTE_ALIGN UINT8 PatternBuffer[3 * 64];
+ UINT8 TestBuffer[120];
+ UINT8 *PatternBufPtr[2];
+ UINT32 TestAddr[4];
+ UINT8 TestResult;
+ UINT8 Receiver;
+ UINT8 i;
+ UINT8 j;
+ UINT16 RcvrEnDly;
+
+ MEM_DATA_STRUCT *MemPtr;
+ DIE_STRUCT *MCTPtr;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+ MemPtr = NBPtr->MemPtr;
+ MCTPtr = NBPtr->MCTPtr;
+
+ AGESA_TESTPOINT (TpProcMemReceiverEnableTraining, &(MemPtr->StdHeader));
+
+ // Set environment settings before training
+ MemRecTBeginTraining (TechPtr);
+
+ PatternBufPtr[0] = PatternBuffer;
+ MemRecUFillTrainPattern (TestPattern0, PatternBufPtr[0], 64, &(MemPtr->StdHeader));
+ PatternBufPtr[1] = PatternBufPtr[0] + 128;
+ MemRecUFillTrainPattern (TestPattern1, PatternBufPtr[1], 64, &(MemPtr->StdHeader));
+
+ // Begin receiver enable training
+ MemRecTSetWrDatRdDqs (TechPtr, 0);
+
+ // there are four receiver pairs, loosely associated with chipselects.
+ Receiver = NBPtr->DimmToBeUsed << 1;
+ TechPtr->DqsRcvEnSaved = 0;
+
+ TestAddr[0] = NBPtr->GetSysAddrRec (NBPtr);
+ TestAddr[1] = TestAddr[0] + BIGPAGE_X8;
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\tDct %d\n", NBPtr->Dct);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCS %d\n", Receiver);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tWrite to addresses: %04x0000\n", TestAddr[0]);
+
+ // Sweep receiver enable delays
+ AGESA_TESTPOINT (TpProcMemRcvrStartSweep, &(MemPtr->StdHeader));
+ for (RcvrEnDly = 0; RcvrEnDly < 0xFF; RcvrEnDly++) {
+
+ TestResult = 0xFF;
+ for (i = 0; i < 2; i++) {
+
+ // Set RcvrEn delay for all byte lanes
+ AGESA_TESTPOINT (TpProcMemRcvrSetDelay, &(MemPtr->StdHeader));
+ MemRecTSetRcvrEnDly (TechPtr, Receiver, RcvrEnDly);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tDly %3x", RcvrEnDly);
+
+ // Swap the test pointers such that even and odd steps alternate.
+ j = ((RcvrEnDly & 1) != 0) ? (i ^ 1) : i;
+
+ // Write, read and compare the first beat of data
+ AGESA_TESTPOINT (TpProcMemRcvrWritePattern, &(MemPtr->StdHeader));
+ MemRecUWrite1CL (TestAddr[j], PatternBufPtr[j]);
+ AGESA_TESTPOINT (TpProcMemRcvrReadPattern, &(MemPtr->StdHeader));
+ MemRecURead1CL (TestBuffer, TestAddr[j]);
+ AGESA_TESTPOINT (TpProcMemRcvrTestPattern, &(MemPtr->StdHeader));
+ TestResult &= MemRecTCompare1ClPattern (TestBuffer, PatternBufPtr[j], &(MemPtr->StdHeader));
+ MemRecUProcIOClFlush (TestAddr[j], MemPtr);
+ }
+
+ if (MemRecTSaveRcvrEnDly (TechPtr, Receiver, RcvrEnDly, TestResult)) {
+ // if all bytelanes pass
+ break;
+ }
+ } // End of delay sweep
+
+ if (RcvrEnDly == 0xFF) {
+ // no passing window
+ // LibAmdEventLog (AGESA_ERROR, MEM_ERROR_RCVR_EN_NO_PASSING_WINDOW, 0, NBPtr->Dct, NBPtr->Channel, 0); //@attention commented out since it is not defined in recovery code
+ SetMemRecError (AGESA_ERROR, MCTPtr);
+ }
+
+ // set final delays
+ MemRecTLoadRcvrEnDly (TechPtr, Receiver);
+
+ // Clear training bit when done
+ NBPtr->SetBitField (NBPtr, BFDqsRcvEnTrain, 0);
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMaxRcvrEnDly: %03x\n", RcvrEnDly + 0x20);
+
+ // Set Max Latency for both channels
+ NBPtr->SetMaxLatency (NBPtr, RcvrEnDly + 0x20);
+
+ // Restore environment settings after training
+ MemRecTEndTraining (TechPtr);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * If WrDatDly is 0, this function sets the DQS Positions in preparation
+ * for Receiver Enable Training. (Write Position is no delay, Read Position is 1.5 Memclock delay).
+ * Otherwise it will set WrDat and RdDqs to center of data eye.
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] WrDatDly - either 0 or 0x0F
+ *
+ */
+
+VOID
+MemRecTSetWrDatRdDqs (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 WrDatDly
+ )
+{
+ UINT8 ByteLane;
+ UINT8 Dimm;
+ UINT8 WrDqs;
+ UINT8 RdDqs;
+ MEM_NB_BLOCK *NBPtr;
+
+ NBPtr = TechPtr->NBPtr;
+
+ Dimm = NBPtr->DimmToBeUsed;
+ for (ByteLane = 0; ByteLane < 8; ByteLane++) {
+ WrDqs = NBPtr->ChannelPtr->WrDqsDlys[(Dimm * MAX_BYTELANES) + ByteLane];
+ NBPtr->SetTrainDly (NBPtr, AccessWrDatDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), WrDqs + WrDatDly);
+ RdDqs = (WrDatDly == 0) ? 0x2F : 0x0F;
+ NBPtr->SetTrainDly (NBPtr, AccessRdDqsDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), RdDqs);
+ }
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function programs DqsRcvEnDly to additional index for DQS receiver enabled training
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] Receiver - Current Chip select value
+ * @param[in] RcvEnDly - receiver enable delay to be saved
+ *
+ */
+
+VOID
+STATIC
+MemRecTSetRcvrEnDly (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 Receiver,
+ IN UINT16 RcvEnDly
+ )
+{
+ UINT8 ByteLane;
+
+ ASSERT (Receiver <= MAX_CS_PER_CHANNEL);
+ for (ByteLane = 0; ByteLane < 8; ByteLane++) {
+ TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Receiver >> 1, ByteLane), RcvEnDly);
+ }
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function compares test pattern with data in buffer and return a pass/fail bitmap
+ * for 8 Bytes
+ *
+ * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare
+ * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against
+ * @param[in,out] StdHeader - The Pointer of AGESA Header.
+ *
+ * @return PASS - Bit map of results of comparison
+ */
+
+UINT8
+STATIC
+MemRecTCompare1ClPattern (
+ IN UINT8 Buffer[],
+ IN UINT8 Pattern[],
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 i;
+ UINT8 Pass;
+
+ Pass = 0xFF;
+ IDS_HDT_CONSOLE (MEM_FLOW, " -");
+ for (i = 0; i < 8; i++) {
+ if (Buffer[i] != Pattern[i]) {
+ // if bytelane n fails
+ Pass &= ~((UINT16) 1 << (i % 8)); // clear bit n
+ }
+ IDS_HDT_CONSOLE (MEM_FLOW, " %c", (Buffer[i] == Pattern[i]) ? 'P' : '.');
+ }
+
+ IDS_HDT_CONSOLE_DEBUG_CODE (
+ IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t -");
+ for (i = 0; i < 8; i++) {
+ IDS_HDT_CONSOLE (MEM_FLOW, " %02x", Buffer[i]);
+ }
+ IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t -");
+ for (i = 0; i < 8; i++) {
+ IDS_HDT_CONSOLE (MEM_FLOW, " %02x", Pattern[i]);
+ }
+ IDS_HDT_CONSOLE (MEM_FLOW, "\n\n");
+ );
+
+ return Pass;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function saves passing DqsRcvEnDly values to the stack
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] Receiver - Current Chip select value
+ * @param[in] RcvEnDly - receiver enable delay to be saved
+ * @param[in] CmpResult - compare result for Rank 0
+ *
+ * @return TRUE - All bytelanes pass
+ * @return FALSE - Some bytelanes fail
+ */
+
+BOOLEAN
+STATIC
+MemRecTSaveRcvrEnDly (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 Receiver,
+ IN UINT16 RcvEnDly,
+ IN UINT8 CmpResult
+ )
+{
+ UINT8 i;
+ UINT8 Passed;
+ UINT8 Saved;
+ UINT8 Mask;
+ UINT8 Dimm;
+
+ ASSERT (Receiver <= MAX_CS_PER_CHANNEL);
+
+ Passed = CmpResult;
+ Saved = (UINT8) (TechPtr->DqsRcvEnSaved & Passed); //@todo - false passes filter (subject to be replaced with a better solution)
+ Dimm = Receiver >> 1;
+ Mask = 1;
+ for (i = 0; i < 8; i++) {
+ if ((Passed & Mask) != 0) {
+ if ((Saved & Mask) == 0) {
+ TechPtr->NBPtr->ChannelPtr->RcvEnDlys[Dimm * MAX_BYTELANES + i] = (UINT8) (RcvEnDly + 0x20);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tBL %d = %02x", i, RcvEnDly + 0x20);
+ }
+ Saved |= Mask;
+ }
+ Mask <<= 1;
+ }
+ TechPtr->DqsRcvEnSaved = Saved;
+
+ if (Saved == 0xFF) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function loads the DqsRcvEnDly from saved data and program to additional index
+ * for DQS receiver enabled training
+ *
+ * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
+ * @param[in] Receiver - Current Chip select value
+ *
+ */
+
+VOID
+STATIC
+MemRecTLoadRcvrEnDly (
+ IN OUT MEM_TECH_BLOCK *TechPtr,
+ IN UINT8 Receiver
+ )
+{
+ UINT8 i;
+ UINT8 Dimm;
+ UINT16 Saved;
+ CH_DEF_STRUCT *ChannelPtr;
+
+ ASSERT (Receiver <= MAX_CS_PER_CHANNEL);
+ ChannelPtr = TechPtr->NBPtr->ChannelPtr;
+
+ Dimm = Receiver >> 1;
+ Saved = TechPtr->DqsRcvEnSaved;
+ for (i = 0; i < 8; i++) {
+ if ((Saved & 1) != 0) {
+ TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Receiver >> 1, i),
+ ChannelPtr->RcvEnDlys[Dimm * MAX_BYTELANES + i]);
+ }
+ Saved >>= 1;
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrdef.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrdef.c
new file mode 100644
index 0000000000..1d64e9e4a9
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrdef.c
@@ -0,0 +1,129 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mdef.c
+ *
+ * Memory Controller header file
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_MRDEF_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This is the default return function
+ */
+
+VOID
+MemRecDefRet ()
+{
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the default return function that returns TRUE
+ *
+ */
+BOOLEAN
+MemRecDefTrue ()
+{
+ return TRUE;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function programs the DCT with initial values
+ *
+ *
+ * @param[in,out] *MCTPtr - Pointer to the DIE_STRUCT
+ * @param[in] Errorval - Error value
+ */
+
+VOID
+SetMemRecError (
+ IN AGESA_STATUS Errorval,
+ IN OUT DIE_STRUCT *MCTPtr
+ )
+{
+ if (MCTPtr->ErrCode < Errorval) {
+ MCTPtr->ErrCode = Errorval;
+ }
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrinit.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrinit.c
new file mode 100644
index 0000000000..b2970ff151
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrinit.c
@@ -0,0 +1,126 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrinit.c
+ *
+ * Initializer support functions for Recovery mode
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "OptionMemory.h"
+#include "Ids.h"
+#include "mm.h"
+#include "ma.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_MRINIT_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+extern PSO_TABLE DefaultPlatformMemoryConfiguration[];
+extern MEM_PLATFORM_CFG* memRecPlatformTypeInstalled[];
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function initializes the default parameter, function pointers, build options
+ * and SPD data for memory configuration
+ *
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ *
+ */
+
+VOID
+AmdMemInitDataStructDefRecovery (
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ )
+{
+ MEM_PARAMETER_STRUCT *RefPtr;
+ UINT8 i;
+ UINT8 p;
+
+ RefPtr = MemPtr->ParameterListPtr;
+
+ // Memory Map/Mgt.
+ // Mask Bottom IO with 0xF8 to force hole size to have granularity of 128MB
+ RefPtr->BottomIo = 0xF0;
+
+ RefPtr->PlatformMemoryConfiguration = DefaultPlatformMemoryConfiguration;
+
+ i = 0;
+ for (p = 0; p < MAX_PLATFORM_TYPES; p++) {
+ if (memRecPlatformTypeInstalled[i] != NULL) {
+ MemPtr->GetPlatformCfg[p] = memRecPlatformTypeInstalled[i];
+ i++;
+ } else {
+ MemPtr->GetPlatformCfg[p] = MemRecNGetPsCfgDef;
+ }
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrm.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrm.c
new file mode 100644
index 0000000000..ce9cb655c0
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrm.c
@@ -0,0 +1,288 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrm.c
+ *
+ * Main configuration for Recovery mode
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "Ids.h"
+#include "amdlib.h"
+#include "GeneralServices.h"
+#include "heapManager.h"
+#include "cpuServices.h"
+#include "OptionMemoryRecovery.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_MRM_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define MAX_DIES_PER_SOCKET 2
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+extern MEM_REC_NB_CONSTRUCTOR* MemRecNBInstalled[];
+extern MEM_REC_TECH_CONSTRUCTOR* MemRecTechInstalled[];
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecSPDDataProcess (
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ );
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is the Recovery memory configuration function for HY DDR3
+ *
+ * Requirements:
+ *
+ * Run-Time Requirements:
+ * 1. Complete Hypertransport Bus Configuration
+ * 2. AmdMemInitDataStructDef must be run to set default values
+ * 3. MSR bit to allow access to high PCI regs set on all nodes
+ * 4. BSP in Big Real Mode
+ * 5. Stack available
+ * 6. MCG_CTL=-1, MC4_EN=0 for all CPUs
+ * 7. MCi_STS from shutdown/warm reset recorded (if desired) prior to entry
+ * 8. All var MTRRs reset to zero
+ * 9. State of NB_CFG.DisDatMsk set properly on all CPUs
+ *
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ *
+ * @return AGESA_STATUS
+ * - AGESA_ALERT
+ * - AGESA_FATAL
+ * - AGESA_SUCCESS
+ * - AGESA_WARNING
+ */
+
+AGESA_STATUS
+AmdMemRecovery (
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ )
+{
+ UINT8 Socket;
+ UINT8 Module;
+ UINT8 i;
+ AGESA_STATUS AgesaStatus;
+ PCI_ADDR Address;
+ MEM_NB_BLOCK NBBlock;
+ MEM_TECH_BLOCK TechBlock;
+ LOCATE_HEAP_PTR SocketWithMem;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+
+ //
+ // Read SPD data
+ //
+ MemRecSPDDataProcess (MemPtr);
+
+ //
+ // Get the socket id from heap.
+ //
+ SocketWithMem.BufferHandle = AMD_REC_MEM_SOCKET_HANDLE;
+ if (HeapLocateBuffer (&SocketWithMem, &MemPtr->StdHeader) == AGESA_SUCCESS) {
+ Socket = *(UINT8 *) SocketWithMem.BufferPtr;
+ } else {
+ ASSERT(FALSE); // Socket handle not found
+ return AGESA_FATAL;
+ }
+
+ //
+ // Allocate buffer for memory init structures
+ //
+ AllocHeapParams.RequestedBufferSize = MAX_DIES_PER_SOCKET * sizeof (DIE_STRUCT);
+ AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DIE_STRUCT_HANDLE, 0, 0, 0);
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
+ ASSERT(FALSE); // Heap allocation failed to allocate Die struct
+ return AGESA_FATAL;
+ }
+ MemPtr->DiesPerSystem = (DIE_STRUCT *)AllocHeapParams.BufferPtr;
+
+ //
+ // Discover populated CPUs
+ //
+ for (Module = 0; Module < MAX_DIES_PER_SOCKET; Module++) {
+ if (GetPciAddress ((VOID *)MemPtr, Socket, Module, &Address, &AgesaStatus)) {
+ MemPtr->DiesPerSystem[Module].SocketId = Socket;
+ MemPtr->DiesPerSystem[Module].DieId = Module;
+ MemPtr->DiesPerSystem[Module].PciAddr.AddressValue = Address.AddressValue;
+ }
+ }
+
+ i = 0;
+ while (MemRecNBInstalled[i] != NULL) {
+ if (MemRecNBInstalled[i] (&NBBlock, MemPtr, 0) == TRUE) {
+ break;
+ }
+ i++;
+ };
+ if (MemRecNBInstalled[i] == NULL) {
+ ASSERT(FALSE); // No NB installed
+ return AGESA_FATAL;
+ }
+ MemRecTechInstalled[0] (&TechBlock, &NBBlock);
+ NBBlock.TechPtr = &TechBlock;
+
+ return NBBlock.InitRecovery (&NBBlock);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function fills a default SPD buffer with SPD values for all DIMMs installed in the system
+ *
+ * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
+ *
+ */
+
+VOID
+STATIC
+MemRecSPDDataProcess (
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ )
+{
+ BOOLEAN FindSocketWithMem;
+ UINT8 Channel;
+ UINT8 Dimm;
+ UINT8 MaxSockets;
+ UINT8 *SocketWithMem;
+ UINT8 Socket;
+ AGESA_STATUS AgesaStatus;
+ SPD_DEF_STRUCT *DimmSPDPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+ AGESA_READ_SPD_PARAMS SpdParam;
+ ASSERT (MemPtr != NULL);
+ FindSocketWithMem = FALSE;
+ //
+ // Allocate heap to save socket number with memory on it.
+ //
+ AllocHeapParams.RequestedBufferSize = sizeof (UINT8);
+ AllocHeapParams.BufferHandle = AMD_REC_MEM_SOCKET_HANDLE;
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) == AGESA_SUCCESS) {
+ SocketWithMem = (UINT8 *) AllocHeapParams.BufferPtr;
+ *SocketWithMem = 0;
+
+ //
+ // Allocate heap for the table
+ //
+ MaxSockets = (UINT8) GetPlatformNumberOfSockets ();
+
+ AllocHeapParams.RequestedBufferSize = (MaxSockets * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL * sizeof (SPD_DEF_STRUCT));
+ AllocHeapParams.BufferHandle = AMD_MEM_SPD_HANDLE;
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) == AGESA_SUCCESS) {
+ MemPtr->SpdDataStructure = (SPD_DEF_STRUCT *) AllocHeapParams.BufferPtr;
+ //
+ // Initialize SpdParam Structure
+ //
+ LibAmdMemCopy ((VOID *)&SpdParam, (VOID *)MemPtr, (UINTN)sizeof (SpdParam.StdHeader), &MemPtr->StdHeader);
+ //
+ // Populate SPDDataBuffer
+ //
+
+ SpdParam.MemData = MemPtr;
+ for (Socket = 0; Socket < MaxSockets; Socket ++) {
+ SpdParam.SocketId = Socket;
+ for (Channel = 0; Channel < MAX_CHANNELS_PER_SOCKET; Channel++) {
+ SpdParam.MemChannelId = Channel;
+ for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) {
+ SpdParam.DimmId = Dimm;
+ DimmSPDPtr = &(MemPtr->SpdDataStructure[(Socket * MAX_CHANNELS_PER_SOCKET + Channel) * MAX_DIMMS_PER_CHANNEL + Dimm]);
+ SpdParam.Buffer = DimmSPDPtr->Data;
+ AgesaStatus = AgesaReadSpdRecovery (0, &SpdParam);
+ if (AgesaStatus == AGESA_SUCCESS) {
+ DimmSPDPtr->DimmPresent = TRUE;
+ if (!FindSocketWithMem) {
+ FindSocketWithMem = TRUE;
+ }
+ } else {
+ DimmSPDPtr->DimmPresent = FALSE;
+ }
+ }
+ }
+ if (FindSocketWithMem) {
+ *SocketWithMem = Socket;
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrport.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrport.h
new file mode 100644
index 0000000000..41b82b57e5
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrport.h
@@ -0,0 +1,82 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mport.h
+ *
+ * API's to support different OS
+ *
+ * A detailed description, giving important information about this file.
+ * Omit the detailed description if none is needed. For other than the
+ * simplest files, there should be one.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Memory
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+#ifndef _MPORT_H_
+#define _MPORT_H_
+
+///< 64 bit data structure
+///< lo - Lower 32 bits
+///< hi - Upper 32 bits
+typedef struct _S_UINT64 {
+ UINT32 lo; ///< Lower 32 bits
+ UINT32 hi; ///< Upper 32 bits
+} S_UINT64;
+/*
+ * SBDFO - Segment Bus Device Function Offset
+ * 31:28 Segment (4-bits)
+ * 27:20 Bus (8-bits)
+ * 19:15 Device (5-bits)
+ * 14:12 Function(3-bits)
+ * 11:00 Offset (12-bits)
+ */
+typedef UINT32 SBDFO;
+
+//#define MAKE_SBDFO(seg,bus,dev,fun,off) ((((UINT32)(seg))<<28) | (((UINT32)(bus))<<20) | \
+// (((UINT32)(dev))<<15) | (((UINT32)(fun))<<12) | ((UINT32)(off)))
+//#define SBDFO_SEG(x) (((UINT32)(x)>>28) & 0x0F)
+//#define SBDFO_BUS(x) (((UINT32)(x)>>20) & 0xFF)
+//#define SBDFO_DEV(x) (((UINT32)(x)>>15) & 0x1F)
+//#define SBDFO_FUN(x) (((UINT32)(x)>>12) & 0x07)
+//#define SBDFO_OFF(x) (((UINT32)(x)) & 0xFFF)
+//#define ILLEGAL_SBDFO 0xFFFFFFFF
+
+
+#define GET_SIZE_OF(x) (sizeof (x) / sizeof (x[0]))
+
+#endif /* _MPORT_H_ */
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrt3.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrt3.h
new file mode 100644
index 0000000000..478dc2b0e2
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mrt3.h
@@ -0,0 +1,121 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mrt3.h
+ *
+ * Common Technology Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRT3_H_
+#define _MRT3_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+MemRecTTrainDQSWriteHw3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+VOID
+MemRecTDramInitSw3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+BOOLEAN
+MemRecTSetDramMode3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+BOOLEAN
+MemRecTDIMMPresence3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+VOID
+MemRecTEMRS13 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+VOID
+MemRecTEMRS23 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+VOID
+MemRecTEMRS33 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+VOID
+MemRecTMRS3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+VOID
+MemRecTDramControlRegInit3 (
+ IN OUT MEM_TECH_BLOCK *TechPtr
+ );
+
+#endif /* _MRT3_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mru.asm b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mru.asm
new file mode 100644
index 0000000000..56db233be6
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mru.asm
@@ -0,0 +1,187 @@
+;*****************************************************************************
+; AMD Generic Encapsulated Software Architecture
+;
+; $Workfile:: mu.asm $ $Revision:: 237#$ $Date: 2009-12-10 07:28:37 +0800 (Thu, 10 Dec 2009) $
+; Description: Main memory controller system configuration for AGESA DDR 2
+;
+;
+;*****************************************************************************
+;
+; 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.
+;
+;*****************************************************************************
+;============================================================================
+
+
+ .XLIST
+ .LIST
+ .686p
+ .MODEL FLAT
+ .CODE
+ ASSUME FS: NOTHING
+
+
+; Define the calling convention used for the C library modules
+;@attention - This should be in a central include file
+CALLCONV EQU NEAR C
+
+
+;===============================================================================
+;MemRecUOutPort:
+;
+; Do a 32 Bit IO Out operation using edx.
+; NOTE: This function will be obsolete in the future.
+;
+; In: Port - port number
+; Value - value to be written to port
+;
+; Out:
+;
+;All registers preserved except for "Out:"
+;===============================================================================
+MemRecUOutPort PROC CALLCONV PUBLIC Port:DWORD, Value:DWORD
+ pushad
+ mov edx,Port
+ mov eax,Value
+ out dx,al
+ popad
+ ret
+MemRecUOutPort ENDP
+
+
+
+;----------------------------------------------------------------------------
+; _MFENCE();
+;
+_MFENCE macro
+ db 0Fh,0AEh,0F0h
+ endm
+
+;----------------------------------------------------------------------------
+; _EXECFENCE();
+;
+_EXECFENCE macro
+ out 0EDh,al ;prevent speculative execution of following instructions
+ endm
+
+;===============================================================================
+;MemRecUWrite1CL:
+;
+; Write data from buffer to a system address
+;
+; In: Address - System address to read from
+; Pattern - pointer pattern.
+;
+; Out:
+;
+;All registers preserved except for "Out:"
+;===============================================================================
+MemRecUWrite1CL PROC CALLCONV PUBLIC Address:DWORD, Pattern:NEAR PTR DWORD
+ pushad
+ push ds
+
+ mov eax,Address
+ push ss
+ pop ds
+ xor edx,edx
+ mov edx, DWORD PTR Pattern
+ mov esi,edx
+ mov edx,16
+ _EXECFENCE
+ mov ecx,4
+ @@:
+ db 66h,0Fh,6Fh,06 ;MOVDQA xmm0,[esi]
+ db 64h,66h,0Fh,0E7h,00 ;MOVNTDQ fs:[eax],xmm0 (xmm0 is 128 bits)
+ add eax,edx
+ add esi,edx
+ loop @B
+
+ pop ds
+ popad
+ ret
+MemRecUWrite1CL ENDP
+
+;===============================================================================
+;MemRecURead1CL:
+;
+; Read one cacheline to buffer
+;
+; In: Buffer - pointer buffer.
+; : Address - System address to read from
+;
+; Out:
+;
+;All registers preserved except for "Out:"
+;===============================================================================
+MemRecURead1CL PROC CALLCONV PUBLIC Buffer:NEAR PTR DWORD, Address:DWORD
+
+ pushad
+
+ mov esi,Address
+ xor edx,edx
+ mov edx,DWORD PTR Buffer
+ mov edi,edx
+ mov ecx,64
+ @@:
+ mov al,fs:[esi]
+ mov ss:[edi],al
+ inc esi
+ inc edi
+ loop @B
+
+ popad
+ ret
+MemRecURead1CL ENDP
+
+
+;===============================================================================
+;MemRecUFlushPattern:
+;
+; Flush one cache line
+;
+; In: Address - System address [31:0]
+; Out:
+;
+;All registers preserved except for "Out:"
+;===============================================================================
+MemRecUFlushPattern PROC CALLCONV PUBLIC Address:DWORD
+ pushad
+ mov eax,Address
+ _EXECFENCE
+ ;clflush fs:[eax]
+ db 064h ;access relative to FS BASE prefix
+ db 00Fh ;opcode
+ db 0AEh ;opcode
+ db 038h ;eax indirect addressing
+ _MFENCE
+ popad
+ ret
+MemRecUFlushPattern ENDP
+
+
+
+ END
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mru.h b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mru.h
new file mode 100644
index 0000000000..27ba3368ce
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mru.h
@@ -0,0 +1,140 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mru.h
+ *
+ * Utility support Recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _MRU_H_
+#define _MRU_H_
+
+/*----------------------------------------------------------------------------
+ * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *-----------------------------------------------------------------------------
+ */
+#ifndef PSO_ENTRY
+ #define PSO_ENTRY UINT8
+#endif
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS, STRUCTURES, ENUMS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/// Test patterns for DQS training
+typedef enum {
+ TestPattern0, ///< Test pattern used in first pass of receiver enable training
+ TestPattern1, ///< Test pattern used in first pass of receiver enable training
+ TestPattern2, ///< Test pattern used in second pass of receiver enable training
+ TestPatternJD1B, ///< 72-bit test pattern used in position training (ganged mode)
+ TestPatternJD1A, ///< 72-bit test pattern used in position training
+ TestPatternML ///< Test pattern used in first pass of max latency training
+} TRAIN_PATTERN;
+
+/*----------------------------------------------------------------------------
+ * FUNCTIONS PROTOTYPE
+ *
+ *----------------------------------------------------------------------------
+ */
+VOID
+MemRecUWrite1CL (
+ IN UINT32 Address,
+ IN UINT8 Pattern[]
+ );
+
+VOID
+MemRecURead1CL (
+ IN UINT8 Buffer[],
+ IN UINT32 Address
+ );
+
+VOID
+MemRecUFlushPattern (
+ IN UINT32 Address
+ );
+
+VOID
+MemRecUFillTrainPattern (
+ IN TRAIN_PATTERN Pattern,
+ IN UINT8 Buffer[],
+ IN UINT16 Size,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+MemRecUProcIOClFlush (
+ IN UINT32 Address,
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ );
+
+VOID
+MemRecUWait10ns (
+ IN UINT32 Count,
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ );
+
+VOID *
+MemRecFindPSOverrideEntry (
+ IN PSO_TABLE *PlatformMemoryConfiguration,
+ IN PSO_ENTRY EntryType,
+ IN UINT8 SocketID,
+ IN UINT8 ChannelID
+ );
+
+UINT8
+RecGetMaxDimmsPerChannel (
+ IN PSO_TABLE *PlatformMemoryConfiguration,
+ IN UINT8 SocketID,
+ IN UINT8 ChannelID
+ );
+
+#endif /* _MRU_H_ */
+
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mruc.c b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mruc.c
new file mode 100644
index 0000000000..95fc64b218
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/Mem/mruc.c
@@ -0,0 +1,267 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mruc.c
+ *
+ * Utility functions recovery
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Proc/Recovery/Mem)
+ * @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 "OptionMemory.h"
+#include "PlatformMemoryConfiguration.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "mrport.h"
+#include "mru.h"
+#include "Filecode.h"
+CODE_GROUP (G2_PEI)
+RDATA_GROUP (G2_PEI)
+
+#define FILECODE PROC_RECOVERY_MEM_MRUC_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemRecUResetTargetWTIO (
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ );
+
+VOID
+STATIC
+MemRecUSetTargetWTIO (
+ IN UINT32 Address,
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ );
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function returns the (Index)th UINT8
+ * from an indicated test Pattern.
+ *
+ * @param[in] Pattern - encoding of test Pattern type
+ * @param[in] Buffer[] - buffer to be filled
+ * @param[in] Size - Size of the bugger
+ * @param[in] *StdHeader - pointer to AMD_CONFIG_PARAMS
+ *
+ */
+
+VOID
+MemRecUFillTrainPattern (
+ IN TRAIN_PATTERN Pattern,
+ IN UINT8 Buffer[],
+ IN UINT16 Size,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ STATIC UINT8 PatternData[2] = {0x55, 0xAA};
+
+ LibAmdMemFill (Buffer, PatternData[Pattern == TestPattern0 ? TestPattern1 : TestPattern0], Size, StdHeader);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function flushes cache lines
+ *
+ * @param[in] Address - System Address [39:8]
+ * @param[in,out] *MemPtr - Pointer to MEM_DATA_STRUCT
+ *
+ */
+
+VOID
+MemRecUProcIOClFlush (
+ IN UINT32 Address,
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ )
+{
+ MemRecUSetTargetWTIO (Address, MemPtr);
+ MemRecUFlushPattern (Address);
+ MemRecUResetTargetWTIO (MemPtr);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function resets the target address space to Write Through IO by disabling IORRs
+ */
+
+VOID
+STATIC
+MemRecUResetTargetWTIO (
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ )
+{
+ S_UINT64 Smsr;
+ Smsr.hi = 0;
+ Smsr.lo = 0;
+ LibAmdMsrWrite (IORR0_MASK, (UINT64 *)&Smsr, &MemPtr->StdHeader);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets the target range to WT IO (using an IORR overlapping
+ * the already existing
+ * @param[in,out] *MemPtr - pointer to MEM_DATA_STRUCTURE
+ * @param[in] Address - System Address
+ *
+ */
+
+VOID
+STATIC
+MemRecUSetTargetWTIO (
+ IN UINT32 Address,
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ )
+{
+ S_UINT64 SMsr;
+
+ SMsr.lo = Address;
+ SMsr.hi = 0;
+ LibAmdMsrWrite (IORR0_BASE,(UINT64 *)&SMsr, &MemPtr->StdHeader); // ;IORR0 Base
+ SMsr.hi = 0xFFFF;
+ SMsr.lo = 0xFC000800;
+ LibAmdMsrWrite (IORR0_MASK, (UINT64 *)&SMsr, &MemPtr->StdHeader); // ;64MB Mask
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * Waits specified number of 10ns cycles
+ * @param[in,out] MemPtr - pointer to MEM_DATA_STRUCTURE
+ * @param[in] Count - Number of 10ns cycles to wait
+ *
+ */
+
+VOID
+MemRecUWait10ns (
+ IN UINT32 Count,
+ IN OUT MEM_DATA_STRUCT *MemPtr
+ )
+{
+ S_UINT64 SMsr;
+
+ LibAmdMsrRead (TSC, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ Count += SMsr.lo;
+ while (SMsr.lo < Count) {
+ LibAmdMsrRead (TSC, (UINT64 *)&SMsr, &MemPtr->StdHeader);
+ }
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * Find the entry of platform specific overriding table.
+ *
+ * @param[in] PlatformMemoryConfiguration - Platform config table
+ * @param[in] EntryType - Entry type
+ * @param[in] SocketID - Physical socket ID
+ * @param[in] ChannelID - Physical channel ID
+ *
+ * @return NULL - entry could not be found.
+ * @return Pointer - points to the entry's data.
+ *
+ * ----------------------------------------------------------------------------
+ */
+VOID *
+MemRecFindPSOverrideEntry (
+ IN PSO_TABLE *PlatformMemoryConfiguration,
+ IN PSO_ENTRY EntryType,
+ IN UINT8 SocketID,
+ IN UINT8 ChannelID
+ )
+{
+ UINT8 *Buffer;
+
+ Buffer = PlatformMemoryConfiguration;
+ while (Buffer[0] != PSO_END) {
+ if (Buffer[0] == EntryType) {
+ if ((Buffer[2] & ((UINT8) 1 << SocketID)) != 0 ) {
+ if ((Buffer[3] & ((UINT8) 1 << ChannelID)) != 0 ) {
+ ASSERT ((Buffer[0] == PSO_MAX_DIMMS) ? (Buffer[4] <= MAX_DIMMS_PER_CHANNEL) : TRUE);
+ ASSERT ((Buffer[0] == PSO_MAX_CHIPSELS) ? (Buffer[4] <= MAX_CS_PER_CHANNEL) : TRUE);
+ ASSERT ((Buffer[0] == PSO_MAX_CHNLS) ? (Buffer[4] <= MAX_CHANNELS_PER_SOCKET) : TRUE);
+ return &Buffer[4];
+ }
+ }
+ }
+ Buffer += Buffer[1] + 2;
+ }
+ return NULL;
+}
+
diff --git a/src/vendorcode/amd/agesa/Proc/Recovery/recoveryPage.h b/src/vendorcode/amd/agesa/Proc/Recovery/recoveryPage.h
new file mode 100644
index 0000000000..110f248e63
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Proc/Recovery/recoveryPage.h
@@ -0,0 +1,59 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Create outline and references for Recovery Component mainpage documentation.
+ *
+ * Design guides, maintenance guides, and general documentation, are
+ * collected using this file onto the documentation mainpage.
+ * This file contains doxygen comment blocks, only.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Documentation
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/**
+ * @page recoverymain Recovery Component Documentation
+ *
+ * Additional documentation for the Recovery component consists of
+ *
+ * - Maintenance Guides:
+ * - add here >>>
+ * - Design Guides:
+ * - add here >>>
+ *
+ */