diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/OR/F15OrEarlySamples.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/OR/F15OrEarlySamples.c | 834 |
1 files changed, 834 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/OR/F15OrEarlySamples.c b/src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/OR/F15OrEarlySamples.c new file mode 100644 index 0000000000..2f7a061df0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/OR/F15OrEarlySamples.c @@ -0,0 +1,834 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_15 OR early sample support. + * + * Provides the code and data required to support pre-production silicon. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x15/OR + * @e \$Revision: 56279 $ @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $ + * + */ +/* + ***************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "cpuEarlyInit.h" +#include "cpuFamilyTranslation.h" +#include "F15OrUtilities.h" +#include "cpuF15Utilities.h" +#include "cpuF15PowerMgmt.h" +#include "cpuF15OrPowerMgmt.h" +#include "GeneralServices.h" +#include "OptionMultiSocket.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X15_OR_F15OREARLYSAMPLES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +typedef union { + UINT64 RawData; + PATCH_LOADER_MSR BitFields; +} PATCH_LOADER; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +BOOLEAN +F15OrEarlySamplesLoadMicrocode ( + IN MICROCODE_PATCH *MicrocodePatchPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F15OrHtcInitEarlySampleHook ( + IN OUT UINT32 *HtcRegister, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F15OrIsCpbDisabledEarlySample ( + IN OUT BOOLEAN *IsEnabled, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F15OrIsC6DisabledEarlySample ( + IN OUT BOOLEAN *IsEnabled, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F15OrEarlySamplesAvoidNbCyclesStart ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT UINT64 *SavedMsrValue + ); + +VOID +F15OrEarlySamplesAvoidNbCyclesEnd ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN UINT64 *SavedMsrValue + ); + +VOID +F15OrEarlySamplesAfterPatchLoaded ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN BOOLEAN IsPatchLoaded + ); + +BOOLEAN +F15OrEarlySamplesLoadMicrocodePatch ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + + + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +F15OrB0WeightsInit ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * D A T A D E C L A R A T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------- + * Early Sample PCI registers + *----------------------------- + */ + +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F15OrEarlySamplePciRegisters[] = +{ +// F3x188 - NB Configuration 2 Register +// bit[30] Reserved = 1 Erratum #620, only on OR A0, A1 and B0 + { + PciRegister, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_LT_B1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x188), // Address + 0x40000000, // regData + 0x40000000, // regMask + }} + }, +// F3x18C - Reserved +// bit[31] Reserved = 1 Erratum #603, only on OR A0, A1 and B0 + { + PciRegister, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_LT_B1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x18C), // Address + 0x80000000, // regData + 0x80000000, // regMask + }} + }, + +// F3x1B8 - L3 Control 1 +// bit[7] Reserved = 1, Erratum #574 +// bit[29] Reserved = 1, Erratum #574 + { + ProfileFixup, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_Ax // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_L3_CACHE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1B8), // Address + 0x20000080, // regData + 0x20000080, // regMask + }} + }, +// F4x110 - Sample and Residency Timers +// bits[20:13] MinResTmr = 0x64 + { + PciRegister, + { + AMD_FAMILY_15_OR, // CpuFamily + AMD_F15_OR_Ax // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x110), // Address + 0x000C8000, // regData + 0x001FE000, // regMask + }} + }, +// F4x1A0 - Reserved +// bits[31:0] Reserved = 4 + { + ProfileFixup, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_A0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_L3_CACHE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x1A0), // Address + 0x00000004, // regData + 0xFFFFFFFF, // regMask + }} + }, +// F4x1A4 - Reserved +// bits[31:0] Reserved = 0x24 Erratum #553 + { + ProfileFixup, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_A0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_L3_CACHE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x1A4), // Address + 0x00000024, // regData + 0xFFFFFFFF, // regMask + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F15OrEarlySamplePciRegisterTable = { + PrimaryCores, + (sizeof (F15OrEarlySamplePciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F15OrEarlySamplePciRegisters, +}; + +/*----------------------------- + * Early Sample MSR registers + *----------------------------- + */ + +STATIC CONST MSR_TYPE_ENTRY_INITIALIZER ROMDATA F15OrEarlySampleMsrRegisters[] = +{ +// MSR_LS_CFG (0xC0011020) +// bit[0] = 1, Erratum #500 for OR-A0 only +// bit[4] = 1, Erratum #501 for OR-A0 only +// bit[28] DisSS = 1, Erratum #495, #496 for OR-A0 only +// bit[30] = 1, Erratum #544 for OR-A0 only +// bit[62] = 1, Erratum #494 for OR-A0 only + { + MsrRegister, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_A0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_LS_CFG, // MSR Address + 0x4000000050000011, // OR Mask + 0x4000000050000011, // NAND Mask + }} + }, +// MSR_DC_CFG (0xC0011022) +// bit[13] DisHwPf = 1, Erratum #498, OR-A0 only +// bit[10] = 1, Erratum #575, OR-A0 only + { + MsrRegister, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_A0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_DC_CFG, // MSR Address + 0x0000000000002400, // OR Mask + 0x0000000000002400, // NAND Mask + }} + }, +// MSR_DE_CFG (0xC0011029) +// bit[7:2] = 111111b, Erratum #497, OR-A0 only + { + MsrRegister, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_A0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_DE_CFG, // MSR Address - Shared + 0x00000000000000FC, // OR Mask + 0x00000000000000FC, // NAND Mask + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F15OrEarlySampleMsrRegisterTable = { + AllCores, + (sizeof (F15OrEarlySampleMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F15OrEarlySampleMsrRegisters, +}; + +/*----------------------------- + * Early Sample Shared MSR registers + *----------------------------- + */ + +STATIC CONST MSR_TYPE_ENTRY_INITIALIZER ROMDATA F15OrEarlySampleSharedMsrRegisters[] = +{ +// MSR_CU_CFG2 (0xC001102A) +// bit[27] = 1, Erratum #572, OR-Ax only + { + MsrRegister, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_Ax // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_CU_CFG2, // MSR Address - Shared + 0x0000000008000000, // OR Mask + 0x0000000008000000, // NAND Mask + }} + }, + +// MSR_CU_CFG3 (0xC001102B) +// bit[34] Reserved = 1, Erratum #568, OR-Ax only + { + MsrRegister, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_Ax // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_CU_CFG3, // MSR Address + 0x0000000400000000, // OR Mask + 0x0000000400000000, // NAND Mask + }} + }, +// MSR_C001_1070 +// bit[41] = 0, Erratum #597, OR-Ax only + { + MsrRegister, + { + AMD_FAMILY_15, // CpuFamily + AMD_F15_OR_Ax // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_C001_1070, // MSR Address - Shared + 0x0000000000000000, // OR Mask + 0x0000020000000000, // NAND Mask + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F15OrEarlySampleSharedMsrRegisterTable = { + CorePairPrimary, + (sizeof (F15OrEarlySampleSharedMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F15OrEarlySampleSharedMsrRegisters, +}; + +/*----------------------------- + * Early Sample Workarounds + *----------------------------- + */ + +STATIC CONST FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_INITIALIZER ROMDATA F15OrEarlySampleWorkarounds[] = +{ + // HT PHY DLL Compensation setting for Ax + { + FamSpecificWorkaround, + { + AMD_FAMILY_15, + AMD_F15_OR_Ax + }, + {AMD_PF_ALL}, + {{ + F15HtPhyOverrideDllCompensation, + 0x00000000 + }} + }, + // CPU TDP Limit 2 setting for Ax + { + FamSpecificWorkaround, + { + AMD_FAMILY_15, + AMD_F15_OR_Ax + }, + {AMD_PF_ALL}, + {{ + F15OrOverrideNodeTdpLimit, + 0x00000000 + }} + }, + // CPU Node TDP Accumulator Throttle Threshold setting for Ax + { + FamSpecificWorkaround, + { + AMD_FAMILY_15_OR, + AMD_F15_OR_Ax + }, + {AMD_PF_ALL}, + {{ + F15OrOverrideNodeTdpAccumulatorThrottleThreshold, + 0x00000000 + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F15OrEarlySampleWorkaroundsTable = { + PrimaryCores, + (sizeof (F15OrEarlySampleWorkarounds) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *)F15OrEarlySampleWorkarounds, +}; + +/*----------------------------- + * Early Sample shared MSRs with Special Programming Requirements Table + *----------------------------- + */ + +STATIC CONST FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_INITIALIZER ROMDATA F15OrEarlySampleSharedMsrWorkarounds[] = +{ + // MSRC001_1072 + { + FamSpecificWorkaround, + { + AMD_FAMILY_15_OR, + AMD_F15_OR_B0 + }, + {AMD_PF_ALL}, + {{ + F15OrB0WeightsInit, + 0x00000000 + }} + } +}; + +CONST REGISTER_TABLE ROMDATA F15OrEarlySampleSharedMsrWorkaroundTable = { + CorePairPrimary, + (sizeof (F15OrEarlySampleSharedMsrWorkarounds) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F15OrEarlySampleSharedMsrWorkarounds, +}; + + +CONST UINT32 ROMDATA F15OrB0WeightsTable [] = { + 0x1300005A, //MSRC001_1072_x00 + 0x10ABD100, //MSRC001_1072_x01 + 0xBF1A1A44, //MSRC001_1072_x02 + 0xC4DABEA4, //MSRC001_1072_x03 + 0x147B7B6A, //MSRC001_1072_x04 + 0x320C0C00, //MSRC001_1072_x05 + 0xE6D6C6DC, //MSRC001_1072_x06 + 0x00911C06, //MSRC001_1072_x07 + 0x1F473727, //MSRC001_1072_x08 + 0x9FA3A32B, //MSRC001_1072_x09 + 0xDFCFBFAF, //MSRC001_1072_x0A + 0xCFBFAF9F, //MSRC001_1072_x0B + 0x606060DF, //MSRC001_1072_x0C + 0x00000060, //MSRC001_1072_x0D + 0xBAAA9A00, //MSRC001_1072_x0E + 0xFF00DACA, //MSRC001_1072_x0F + 0xFEFEFF64, //MSRC001_1072_x10 + 0x41FCFEFE, //MSRC001_1072_x11 + 0xE14C2F0D, //MSRC001_1072_x12 + 0x95A371EA, //MSRC001_1072_x13 + 0x002EE260, //MSRC001_1072_x14 + 0x00F907D2, //MSRC001_1072_x15 + 0xF9F2A5A5, //MSRC001_1072_x16 + 0x97C100E3, //MSRC001_1072_x17 + 0x91C5B577, //MSRC001_1072_x18 + 0x95C1B1A1, //MSRC001_1072_x19 + 0x68584800, //MSRC001_1072_x1A + 0x67000000, //MSRC001_1072_x1B + 0xB2003109, //MSRC001_1072_x1C + 0x3F8DCDC4, //MSRC001_1072_x1D + 0xD2D4D409, //MSRC001_1072_x1E + 0x090000D2, //MSRC001_1072_x1F + 0x00160000, //MSRC001_1072_x20 + 0x0000E300 //MSRC001_1072_x21 +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Early sample hook point during HTC initialization + * + * @param[in,out] HtcRegister Value of F3x64 to be written. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +F15OrHtcInitEarlySampleHook ( + IN OUT UINT32 *HtcRegister, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MsrAddr; + UINT64 Msr; + + if (((HTC_REGISTER *) HtcRegister)->HtcPstateLimit == 0) { + // HtcPstateLimit is set to Pb0. Reprogram it to the minimum enabled P-state with + // with NbPstate = 0 + for (MsrAddr = PS_MAX_REG; MsrAddr > PS_MIN_REG; MsrAddr--) { + LibAmdMsrRead (MsrAddr, &Msr, StdHeader); + if ((((PSTATE_MSR *) &Msr)->PsEnable == 1) && (((PSTATE_MSR *) &Msr)->NbPstate == 0)) { + break; + } + } + ((HTC_REGISTER *) HtcRegister)->HtcPstateLimit = (MsrAddr - PS_MIN_REG); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Is CPB supported on this CPU + * + * @param[in,out] IsEnabled Whether or not CPB should be enabled. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +F15OrIsCpbDisabledEarlySample ( + IN OUT BOOLEAN *IsEnabled, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_LOGICAL_ID LogicalId; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + // Check if this CPU is OR A0, then disable CPB support. + if ((LogicalId.Revision & AMD_F15_OR_A0) != 0) { + *IsEnabled = FALSE; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Is C6 supported on this CPU + * + * @param[in,out] IsEnabled Whether or not C6 should be enabled. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +F15OrIsC6DisabledEarlySample ( + IN OUT BOOLEAN *IsEnabled, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_LOGICAL_ID LogicalId; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + // Check if this CPU is OR A0, then disable C6 support. + if ((LogicalId.Revision & AMD_F15_OR_A0) != 0) { + *IsEnabled = FALSE; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Update the weights for affected OR B0 CPUs. + * + * This function implements a workaround for OR B0 when applicable. + * + * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F15OrB0WeightsInit ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 i; + UINT32 ProductInfo; + UINT64 LocalMsr; + PCI_ADDR PciAddress; + + if (IsWarmReset (StdHeader)) { + OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader); + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = PRCT_INFO_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &ProductInfo, StdHeader); + + if ((ProductInfo & BIT31) == 0) { + for (i = 0; i < ((sizeof F15OrB0WeightsTable) / (sizeof F15OrB0WeightsTable[0])); i++) { + LocalMsr = (((((UINT64) F15OrB0WeightsTable[i]) << 32) | i) | BIT14); + LibAmdMsrWrite (0xC0011072, &LocalMsr, StdHeader); + } + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * Workaround to avoid patch loading from causing NB cycles + * + * + * @param[in,out] StdHeader - Config handle for library and services. + * @param[in,out] SavedMsrValue - Saved a MSR value + * + */ +VOID +F15OrEarlySamplesAvoidNbCyclesStart ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT UINT64 *SavedMsrValue + ) +{ + UINT64 MsrValue; + CPU_LOGICAL_ID LogicalId; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + // Check if this CPU is OR Ax, expected fix in OR-B0 + if ((LogicalId.Revision & AMD_F15_OR_Ax) != 0) { + // Workaround for F15 OR-Ax workaround to avoid patch loading from causing NB cycles + // Start - Set MSR C001_102A [8] + LibAmdMsrRead (MSR_BU_CFG2, SavedMsrValue, StdHeader); + MsrValue = *SavedMsrValue | BIT8; + LibAmdMsrWrite (MSR_BU_CFG2, &MsrValue, StdHeader); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * Workaround to avoid patch loading from causing NB cycles + * + * + * @param[in,out] StdHeader - Config handle for library and services. + * @param[in] SavedMsrValue - Saved a MSR value + * + */ +VOID +F15OrEarlySamplesAvoidNbCyclesEnd ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN UINT64 *SavedMsrValue + ) +{ + CPU_LOGICAL_ID LogicalId; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + if ((LogicalId.Revision & AMD_F15_OR_Ax) != 0) { + // Restore Workaround for F15 OR-Ax workaround to avoid patch loading from causing NB cycles + // End - Restore MSR C001_102A + LibAmdMsrWrite (MSR_BU_CFG2, SavedMsrValue, StdHeader); + } + +} + +/* -----------------------------------------------------------------------------*/ +/** + * Workaround for Ax processors after patch is loaded. + * + * + * @param[in] StdHeader - Config handle for library and services. + * @param[in] IsPatchLoaded - Is patch loaded + * + */ +VOID +F15OrEarlySamplesAfterPatchLoaded ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN BOOLEAN IsPatchLoaded + ) +{ + UINT64 MsrValue; + CPU_LOGICAL_ID LogicalId; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + + // MSR C001_1023[4:3] = 11b + // Erratum #502, OR-A0 only after microcode patch has been loaded + if (((LogicalId.Revision & AMD_F15_OR_A0) != 0) && (IsPatchLoaded)) { + LibAmdMsrRead (MSR_CU_CFG, &MsrValue, StdHeader); + MsrValue |= 0x18; + LibAmdMsrWrite (MSR_CU_CFG, &MsrValue, StdHeader); + } + + // Erratum #590, OR-A1 only, if any patch is applied + // MSR C001_0028 = 0x2E00_0080 + // MSR C001_0029 = 0xFE00_0080 + // MSR C001_002C = 0x0400_1029 + if (((LogicalId.Revision & AMD_F15_OR_A1) != 0) && (IsPatchLoaded)) { + MsrValue = 0x2E000080; + LibAmdMsrWrite (0xC0010028, &MsrValue, StdHeader); + + MsrValue = 0xFE000080; + LibAmdMsrWrite (0xC0010029, &MsrValue, StdHeader); + + MsrValue = 0x04001029; + LibAmdMsrWrite (0xC001002C, &MsrValue, StdHeader); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * Update microcode patch in current processor. + * + * Then reads the patch id, and compare it to the expected, in the Microprocessor + * patch block. + * + * @param[in] StdHeader - Config handle for library and services. + * + * @retval TRUE - Patch Loaded Successfully. + * @retval FALSE - Patch Did Not Get Loaded. + * + */ +BOOLEAN +F15OrEarlySamplesLoadMicrocodePatch ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PatchNumber; + UINT8 TotalPatches; + UINT16 ProcessorEquivalentId; + BOOLEAN Status; + MICROCODE_PATCH **MicrocodePatchPtr; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + Status = FALSE; + + if (IsCorePairPrimary (FirstCoreIsComputeUnitPrimary, StdHeader)) { + // Get the patch pointer + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetMicroCodePatchesStruct (FamilySpecificServices, (const VOID **) &MicrocodePatchPtr, &TotalPatches, StdHeader); + + IDS_OPTION_HOOK (IDS_UCODE, &TotalPatches, StdHeader); + + // Get the processor microcode path equivalent ID + if (GetPatchEquivalentId (&ProcessorEquivalentId, StdHeader)) { + // parse the patch table to see if we have one for the current cpu + for (PatchNumber = 0; PatchNumber < TotalPatches; PatchNumber++) { + if (ValidateMicrocode (MicrocodePatchPtr[PatchNumber], ProcessorEquivalentId, StdHeader)) { + if (F15OrEarlySamplesLoadMicrocode (MicrocodePatchPtr[PatchNumber], StdHeader)) { + Status = TRUE; + } else { + PutEventLog (AGESA_ERROR, + CPU_ERROR_MICRO_CODE_PATCH_IS_NOT_LOADED, + 0, 0, 0, 0, StdHeader); + } + break; // Once we find a microcode patch that matches the processor, exit the for loop + } + } + } + } + return Status; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * F15OrEarlySamplesLoadMicrocode + * + * Update microcode patch in current processor, then reads the + * patch id, and compare it to the expected, in the Microprocessor + * patch block. + * + * Note: This is a special version of the normal LoadMicrocode() + * function which lives in cpuMicrocodePatch.c. This version + * implements a workaround (on Or-B0 only) before applying the + * microcode patch. + * + * @param[in] MicrocodePatchPtr - Pointer to Microcode Patch. + * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + * @retval TRUE - Patch Loaded Successfully. + * @retval FALSE - Patch Did Not Get Loaded. + * + */ +BOOLEAN +F15OrEarlySamplesLoadMicrocode ( + IN MICROCODE_PATCH *MicrocodePatchPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MicrocodeVersion; + UINT64 MsrData; + PATCH_LOADER PatchLoaderMsr; + CPU_LOGICAL_ID LogicalId; + + // Load microcode patch into CPU + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + PatchLoaderMsr.RawData = (UINT64) MicrocodePatchPtr; + PatchLoaderMsr.BitFields.SBZ = 0; + // Check if this CPU is OR-B0, expected fix in OR-B1 + if ((LogicalId.Revision & AMD_F15_OR_B0) != 0) { + LibAmdMsrRead (MSR_BR_FROM, &MsrData, StdHeader); + } + + LibAmdMsrWrite (MSR_PATCH_LOADER, &PatchLoaderMsr.RawData, StdHeader); + + // Do ucode patch Authentication + // Read microcode version back from CPU, determine if + // it is the same patch level as contained in the source + // microprocessor patch block passed in + GetMicrocodeVersion (&MicrocodeVersion, StdHeader); + if (MicrocodeVersion == MicrocodePatchPtr->PatchID) { + return (TRUE); + } else { + return (FALSE); + } +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + |