/* $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: 44324 $ @e \$Date: 2010-12-22 02:16:51 -0700 (Wed, 22 Dec 2010) $ * **/ /***************************************************************************** * * Copyright (C) 2012 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 "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; }