aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c
diff options
context:
space:
mode:
authorefdesign98 <efdesign98@gmail.com>2011-06-20 18:12:43 -0700
committerMarc Jones <marcj303@gmail.com>2011-06-22 01:35:45 +0200
commit621ca384a7a5efb2cc7597504dc17b741cd2df10 (patch)
tree01871adc6d39f48916b5625b3aa1a4b6d5ab9c92 /src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c
parent05a89ab922473f375820a3bd68691bb085c62448 (diff)
Move existing AMD Ffamily14 code to f14 folder
This change moves the AMD Family14 cpu Agesa code to the vendorcode/amd/agesa/f14 folder to complete the transition to the family oriented folder structure. Change-Id: I211e80ee04574cc713f38b4cc1b767dbb2bfaa59 Signed-off-by: Frank Vibrans <frank.vibrans@amd.com> Signed-off-by: efdesign98 <efdesign98@gmail.com> Reviewed-on: http://review.coreboot.org/52 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones <marcj303@gmail.com>
Diffstat (limited to 'src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c')
-rw-r--r--src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c539
1 files changed, 539 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c b/src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c
new file mode 100644
index 0000000000..f6a13e59fe
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c
@@ -0,0 +1,539 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD Family_14 specific utility functions.
+ *
+ * Provides numerous utility functions specific to family 14h.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: CPU/F14
+ * @e \$Revision: 37640 $ @e \$Date: 2010-09-08 23:01:59 +0800 (Wed, 08 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "cpuPstateTables.h"
+#include "cpuF14PowerMgmt.h"
+#include "cpuServices.h"
+#include "GeneralServices.h"
+#include "cpuF14Utilities.h"
+#include "cpuPostInit.h"
+#include "Filecode.h"
+#define FILECODE PROC_CPU_FAMILY_0X14_CPUF14UTILITIES_FILECODE
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable;
+
+/*----------------------------------------------------------------------------------------
+ * 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
+ *----------------------------------------------------------------------------------------
+ */
+VOID
+F14ConvertEnabledBitsIntoCount (
+ OUT UINT8 *EnabledCoreCountPtr,
+ IN UINT8 FusedCoreCount,
+ IN UINT8 EnabledCores
+ );
+
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+VOID
+F14ConvertEnabledBitsIntoCount (
+ OUT UINT8 *EnabledCoreCountPtr,
+ IN UINT8 FusedCoreCount,
+ IN UINT8 EnabledCores
+ )
+{
+ UINT8 i;
+ UINT8 j;
+ UINT8 EnabledCoreCount;
+
+ EnabledCoreCount = 0;
+
+ for (i = 0; i < FusedCoreCount+1; i++) {
+ j = 1;
+ if (!((BOOLEAN) (EnabledCores) & (j << i))) {
+ EnabledCoreCount++;
+ }
+ }
+
+ *EnabledCoreCountPtr = EnabledCoreCount;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Disables the desired P-state.
+ *
+ * @CpuServiceMethod{::F_CPU_DISABLE_PSTATE}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in] StateNumber The P-State to disable.
+ * @param[in] StdHeader Header for library and services
+ *
+ * @retval AGESA_SUCCESS Always succeeds.
+ */
+AGESA_STATUS
+F14DisablePstate (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN UINT8 StateNumber,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT64 MsrRegister;
+
+ ASSERT (StateNumber < NM_PS_REG);
+ LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &MsrRegister, StdHeader);
+ ((PSTATE_MSR *) &MsrRegister)->PsEnable = 0;
+ LibAmdMsrWrite (PS_REG_BASE + (UINT32) StateNumber, &MsrRegister, StdHeader);
+ return (AGESA_SUCCESS);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Transitions the executing core to the desired P-state.
+ *
+ * @CpuServiceMethod{::F_CPU_TRANSITION_PSTATE}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in] StateNumber The new P-State to make effective.
+ * @param[in] WaitForTransition True if the caller wants the transition completed upon return.
+ * @param[in] StdHeader Header for library and services
+ *
+ * @retval AGESA_SUCCESS Always Succeeds
+ */
+AGESA_STATUS
+F14TransitionPstate (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN UINT8 StateNumber,
+ IN BOOLEAN WaitForTransition,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT64 MsrRegister;
+
+ ASSERT (StateNumber < NM_PS_REG);
+ LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &MsrRegister, StdHeader);
+ ASSERT (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1);
+ LibAmdMsrRead (MSR_PSTATE_CTL, &MsrRegister, StdHeader);
+ ((PSTATE_CTRL_MSR *) &MsrRegister)->PstateCmd = (UINT64) StateNumber;
+ LibAmdMsrWrite (MSR_PSTATE_CTL, &MsrRegister, StdHeader);
+ if (WaitForTransition) {
+ do {
+ LibAmdMsrRead (MSR_PSTATE_STS, &MsrRegister, StdHeader);
+ } while (((PSTATE_STS_MSR *) &MsrRegister)->CurPstate != (UINT64) StateNumber);
+ }
+ return (AGESA_SUCCESS);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Determines the rate at which the executing core's time stamp counter is
+ * incrementing.
+ *
+ * @CpuServiceMethod{::F_CPU_GET_TSC_RATE}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[out] FrequencyInMHz TSC actual frequency.
+ * @param[in] StdHeader Header for library and services.
+ *
+ * @return The most severe status of all called services
+ */
+AGESA_STATUS
+F14GetTscRate (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ OUT UINT32 *FrequencyInMHz,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT64 MsrRegister;
+ PSTATE_CPU_FAMILY_SERVICES *FamilyServices;
+
+ FamilyServices = NULL;
+ GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, &FamilyServices, StdHeader);
+ ASSERT (FamilyServices != NULL);
+
+ LibAmdMsrRead (0xC0010015, &MsrRegister, StdHeader);
+ if ((MsrRegister & 0x01000000) != 0) {
+ return (FamilyServices->GetPstateFrequency (FamilyServices, 0, FrequencyInMHz, StdHeader));
+ } else {
+ return (FamilySpecificServices->GetCurrentNbFrequency (FamilySpecificServices, FrequencyInMHz, StdHeader));
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Determines the NB clock on the desired node.
+ *
+ * @CpuServiceMethod{::F_CPU_GET_NB_FREQ}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[out] FrequencyInMHz Northbridge clock frequency in MHz.
+ * @param[in] StdHeader Header for library and services
+ *
+ * @retval AGESA_SUCCESS Always succeeds.
+ */
+AGESA_STATUS
+F14GetCurrentNbFrequency (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ OUT UINT32 *FrequencyInMHz,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 PciRegister;
+ UINT32 MainPllFid;
+ PCI_ADDR PciAddress;
+
+ PciAddress.AddressValue = CPTC0_PCI_ADDR;
+ LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
+
+ if (((CLK_PWR_TIMING_CTRL_REGISTER *) &PciRegister)->MainPllOpFreqIdEn == 1) {
+ MainPllFid = ((CLK_PWR_TIMING_CTRL_REGISTER *) &PciRegister)->MainPllOpFreqId;
+ } else {
+ MainPllFid = 0;
+ }
+
+ *FrequencyInMHz = ((MainPllFid + 0x10) * 100);
+
+ ASSERT (*FrequencyInMHz <= 4000);
+
+ return (AGESA_SUCCESS);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Determines the NB clock on the desired node.
+ *
+ * @CpuServiceMethod{::F_CPU_GET_NB_PSTATE_INFO}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in] PlatformConfig Platform profile/build option config structure.
+ * @param[in] PciAddress The segment, bus, and device numbers of the CPU in question.
+ * @param[in] NbPstate The NB P-state number to check.
+ * @param[out] FreqNumeratorInMHz The desired node's frequency numerator in megahertz.
+ * @param[out] FreqDivisor The desired node's frequency divisor.
+ * @param[out] VoltageInuV The desired node's voltage in microvolts.
+ * @param[in] StdHeader Handle of Header for calling lib functions and services.
+ *
+ * @retval TRUE NbPstate is valid
+ * @retval FALSE NbPstate is disabled or invalid
+ */
+BOOLEAN
+F14GetNbPstateInfo (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN PLATFORM_CONFIGURATION *PlatformConfig,
+ IN PCI_ADDR *PciAddress,
+ IN UINT32 NbPstate,
+ OUT UINT32 *FreqNumeratorInMHz,
+ OUT UINT32 *FreqDivisor,
+ OUT UINT32 *VoltageInuV,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 NbVid;
+ UINT32 PciRegister;
+ UINT32 MainPllFreq;
+ BOOLEAN PstateIsValid;
+
+ PstateIsValid = FALSE;
+ if ((NbPstate == 0) || ((NbPstate == 1) && FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, PlatformConfig, StdHeader))) {
+ FamilySpecificServices->GetCurrentNbFrequency (FamilySpecificServices, &MainPllFreq, StdHeader);
+ *FreqNumeratorInMHz = (MainPllFreq * 4);
+ if (NbPstate == 0) {
+ PciAddress->Address.Function = FUNC_3;
+ PciAddress->Address.Register = CPTC2_REG;
+ LibAmdPciRead (AccessWidth32, *PciAddress, &PciRegister, StdHeader);
+ *FreqDivisor = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->NbPs0NclkDiv;
+ NbVid = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->NbPs0Vid;
+ } else {
+ PciAddress->Address.Function = FUNC_6;
+ PciAddress->Address.Register = NB_PSTATE_CFG_LOW_REG;
+ LibAmdPciRead (AccessWidth32, *PciAddress, &PciRegister, StdHeader);
+ *FreqDivisor = ((NB_PSTATE_CFG_LOW_REGISTER *) &PciRegister)->NbPs1NclkDiv;
+ NbVid = ((NB_PSTATE_CFG_LOW_REGISTER *) &PciRegister)->NbPs1Vid;
+ }
+ *VoltageInuV = (1550000 - (12500 * NbVid));
+ PstateIsValid = TRUE;
+ }
+ return PstateIsValid;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Is the Northbridge PState feature enabled?
+ *
+ * @CpuServiceMethod{::F_IS_NB_PSTATE_ENABLED}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in] PlatformConfig Platform profile/build option config structure.
+ * @param[in] StdHeader Handle of Header for calling lib functions and services.
+ *
+ * @retval TRUE The NB PState feature is enabled.
+ * @retval FALSE The NB PState feature is not enabled.
+ */
+BOOLEAN
+F14IsNbPstateEnabled (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN PLATFORM_CONFIGURATION *PlatformConfig,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 PciRegister;
+ PCI_ADDR PciAddress;
+
+ PciAddress.AddressValue = NB_PSTATE_CFG_LOW_PCI_ADDR;
+ LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
+ return ((BOOLEAN) (((NB_PSTATE_CFG_LOW_REGISTER *) &PciRegister)->NbPsCap == 1));
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Returns whether or not BIOS is responsible for configuring the NB COFVID.
+ *
+ * @CpuServiceMethod{::F_CPU_IS_NBCOF_INIT_NEEDED}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in] PciAddress The northbridge to query by pci base address.
+ * @param[out] NbCofVidUpdateRequired TRUE, perform northbridge frequency and voltage config,
+ * FALSE, do not configure them.
+ * @param[in] StdHeader Header for library and services
+ *
+ * @retval AGESA_SUCCESS Always succeeds.
+ */
+AGESA_STATUS
+F14GetNbCofVidUpdate (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN PCI_ADDR *PciAddress,
+ OUT BOOLEAN *NbCofVidUpdateRequired,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ *NbCofVidUpdateRequired = FALSE;
+ return (AGESA_SUCCESS);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Initially launches the desired core to run from the reset vector.
+ *
+ * @CpuServiceMethod{::F_CPU_AP_INITIAL_LAUNCH}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in] SocketNum The Processor on which the core is to be launched
+ * @param[in] ModuleNum The Module in that processor containing that core
+ * @param[in] CoreNum The Core to launch
+ * @param[in] PrimaryCoreNum The id of the module's primary core.
+ * @param[in] StdHeader Header for library and services
+ *
+ * @retval TRUE The core was launched
+ * @retval FALSE The core was previously launched
+ */
+BOOLEAN
+F14LaunchApCore (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN UINT32 SocketNum,
+ IN UINT32 ModuleNum,
+ IN UINT32 CoreNum,
+ IN UINT32 PrimaryCoreNum,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 NodeRelativeCoreNum;
+ UINT32 PciRegister;
+ PCI_ADDR PciAddress;
+ BOOLEAN LaunchFlag;
+
+ // Code Start
+ LaunchFlag = FALSE;
+ NodeRelativeCoreNum = CoreNum - PrimaryCoreNum;
+ PciAddress.AddressValue = MAKE_SBDFO (0, 0, PCI_DEV_BASE, FUNC_0, 0);
+
+ switch (NodeRelativeCoreNum) {
+ case 1:
+ PciAddress.Address.Register = HT_TRANS_CTRL;
+ LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
+ if ((PciRegister & HT_TRANS_CTRL_CPU1_EN) == 0) {
+ PciRegister |= HT_TRANS_CTRL_CPU1_EN;
+ LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);
+ LaunchFlag = TRUE;
+ } else {
+ LaunchFlag = FALSE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return (LaunchFlag);
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Get CPU Specific Platform Type Info.
+ *
+ * @CpuServiceMethod{::F_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO}.
+ *
+ * This function returns Returns the platform features.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in,out] Features The Features supported by this platform.
+ * @param[in] StdHeader Handle of Header for calling lib functions and services.
+ *
+ * @retval AGESA_SUCCESS Always succeeds.
+ */
+AGESA_STATUS
+F14GetPlatformTypeSpecificInfo (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN OUT PLATFORM_FEATS *Features,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ return (AGESA_SUCCESS);
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Get CPU pstate current.
+ *
+ * @CpuServiceMethod{::F_CPU_GET_IDD_MAX}.
+ *
+ * This function returns the ProcIddMax.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in] Pstate The P-state to check.
+ * @param[out] ProcIddMax P-state current in mA.
+ * @param[in] StdHeader Handle of Header for calling lib functions and services.
+ *
+ * @retval TRUE P-state is enabled
+ * @retval FALSE P-state is disabled
+ */
+BOOLEAN
+F14GetProcIddMax (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN UINT8 Pstate,
+ OUT UINT32 *ProcIddMax,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 IddDiv;
+ UINT32 CmpCap;
+ UINT32 PciRegister;
+ UINT32 MsrAddress;
+ UINT64 PstateMsr;
+ BOOLEAN IsPstateEnabled;
+ PCI_ADDR PciAddress;
+
+ IsPstateEnabled = FALSE;
+
+ MsrAddress = (UINT32) (Pstate + PS_REG_BASE);
+
+ ASSERT (MsrAddress <= PS_MAX_REG);
+
+ LibAmdMsrRead (MsrAddress, &PstateMsr, StdHeader);
+ if (((PSTATE_MSR *) &PstateMsr)->PsEnable == 1) {
+ PciAddress.AddressValue = NB_CAPS_PCI_ADDR;
+ LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); // F3xE8
+ CmpCap = (UINT32) (((NB_CAPS_REGISTER *) &PciRegister)->CmpCap);
+ CmpCap++;
+
+ switch (((PSTATE_MSR *) &PstateMsr)->IddDiv) {
+ case 0:
+ IddDiv = 1000;
+ break;
+ case 1:
+ IddDiv = 100;
+ break;
+ case 2:
+ IddDiv = 10;
+ break;
+ default: // IddDiv = 3 is reserved. Use 10
+ ASSERT (FALSE);
+ IddDiv = 10;
+ break;
+ }
+
+ *ProcIddMax = (UINT32) ((PSTATE_MSR *) &PstateMsr)->IddValue * IddDiv * CmpCap;
+ IsPstateEnabled = TRUE;
+ }
+ return IsPstateEnabled;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Get number of processor cores to be used in determining the brand string.
+ *
+ * @CpuServiceMethod{::F_CPU_NUMBER_OF_BRANDSTRING_CORES}.
+ *
+ * @param[in] FamilySpecificServices The current Family Specific Services.
+ * @param[in] StdHeader Handle of Header for calling lib functions and services.
+ *
+ * @return The number of cores to be used in brand string calculation.
+ */
+UINT8
+F14GetNumberOfCoresForBrandstring (
+ IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ CPUID_DATA CpuId;
+
+ //
+ //CPUID.80000008h.ECX.NC + 1, 000b = 1, 001b = 2, etc.
+ //
+ LibAmdCpuidRead (CPUID_LONG_MODE_ADDR, &CpuId, StdHeader);
+ return ((UINT8) ((CpuId.ECX_Reg & 0xff) + 1));
+}