/* $NoKeywords:$ */
/**
 * @file
 *
 * AMD CPU Register Table Related Functions
 *
 * Set registers according to a set of register tables
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:      AGESA
 * @e sub-project:  CPU
 * @e \$Revision: 38402 $   @e \$Date: 2010-09-24 02:11:44 +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.
 *
 * ***************************************************************************
 *
 */

/*----------------------------------------------------------------------------------------
 *                            M O D U L E S    U S E D
 *----------------------------------------------------------------------------------------
 */
#include "AGESA.h"
#include "amdlib.h"
#include "Ids.h"
#include "Topology.h"
#include "OptionMultiSocket.h"
#include "cpuRegisters.h"
#include "cpuFamilyTranslation.h"
#include "Table.h"
#include "GeneralServices.h"
#include "cpuServices.h"
#include "cpuFeatures.h"
#include "CommonReturns.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G1_PEICC)

#define FILECODE PROC_CPU_TABLE_FILECODE

extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;

/*----------------------------------------------------------------------------------------
 *                   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
 *----------------------------------------------------------------------------------------
 */

VOID
SetRegistersFromTablesAtEarly (
  IN       CPU_SPECIFIC_SERVICES  *FamilyServices,
  IN       AMD_CPU_EARLY_PARAMS   *EarlyParams,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  );

/*----------------------------------------------------------------------------------------
 *                          E X P O R T E D    F U N C T I O N S
 *----------------------------------------------------------------------------------------
 */
extern BUILD_OPT_CFG UserOptions;

/*---------------------------------------------------------------------------------------*/
/**
 * An iterator for all the Family and Model Register Tables.
 *
 * RegisterTableHandle should be set to NULL to begin iteration, the first time the method is
 * invoked.  Register tables can be processed, until this method returns NULL.  RegisterTableHandle
 * should simply be passed back to the method without modification or use by the caller.
 * The table selector allows the relevant tables for different cores to be iterated, if the family separates
 * tables.  For example, MSRs can be in a table processed by all cores and PCI registers in a table processed by
 * primary cores.
 *
 * @param[in]     FamilySpecificServices  The current Family Specific Services.
 * @param[in]     Selector                Select whether to iterate over tables for either all cores, primary cores, bsp, ....
 * @param[in,out] RegisterTableHandle     IN: The handle of the current register table, or NULL if Begin.
 *                                        OUT: The handle of the next register table, if not End.
 * @param[out]    NumberOfEntries         The number of entries in the table returned, if not End.
 * @param[in]     StdHeader               Handle of Header for calling lib functions and services.
 *
 * @return        The pointer to the next Register Table, or NULL if End.
 */
TABLE_ENTRY_FIELDS
STATIC
*GetNextRegisterTable (
  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
  IN       TABLE_CORE_SELECTOR     Selector,
  IN OUT   REGISTER_TABLE       ***RegisterTableHandle,
     OUT   UINTN                  *NumberOfEntries,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  REGISTER_TABLE **NextTable;
  TABLE_ENTRY_FIELDS *Entries;

  ASSERT ((FamilySpecificServices != NULL) && (StdHeader != NULL));
  ASSERT (Selector < TableCoreSelectorMax);

  NextTable = *RegisterTableHandle;
  if (NextTable == NULL) {
    // Begin
    NextTable = FamilySpecificServices->RegisterTableList;
    IDS_OPTION_HOOK (IDS_REG_TABLE, &NextTable, StdHeader);
  } else {
    NextTable++;
  }
  // skip if not selected
  while ((*NextTable != NULL) && (*NextTable)->Selector != Selector) {
    NextTable++;
  }
  if (*NextTable == NULL) {
    // End
    *RegisterTableHandle = NULL;
    Entries = NULL;
  } else {
    // Iterate next table
    *RegisterTableHandle = NextTable;
    *NumberOfEntries = (*NextTable)->NumberOfEntries;
    Entries = (TABLE_ENTRY_FIELDS *) (*NextTable)->Table;
  }
  return Entries;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Compare counts to a pair of ranges.
 *
 * @param[in]       FirstCount       The actual count to be compared to the first range.
 * @param[in]       SecondCount      The actual count to be compared to the second range.
 * @param[in]       Ranges           The ranges which the counts are compared to.
 *
 * @retval          TRUE             Either one, or both, of the counts is in the range given.
 * @retval          FALSE            Neither count is in the range given.
 */
BOOLEAN
IsEitherCountInRange (
  IN       UINTN                FirstCount,
  IN       UINTN                SecondCount,
  IN       COUNT_RANGE_FEATURE  Ranges
  )
{
  // Errors: Entire Range value is zero, Min and Max reversed or not <=, ranges overlap (OK if first range is all),
  // the real counts are too big.
  ASSERT ((Ranges.Range0Min <= Ranges.Range0Max) &&
          (Ranges.Range1Min <= Ranges.Range1Max) &&
          (Ranges.Range0Max != 0) &&
          (Ranges.Range1Max != 0) &&
          ((Ranges.Range0Max == COUNT_RANGE_HIGH) || (Ranges.Range0Max < Ranges.Range1Min)) &&
          ((FirstCount < COUNT_RANGE_HIGH) && (SecondCount < COUNT_RANGE_HIGH)));

  return (BOOLEAN) (((FirstCount <= Ranges.Range0Max) && (FirstCount >= Ranges.Range0Min)) ||
                   ((SecondCount <= Ranges.Range1Max) && (SecondCount >= Ranges.Range1Min)));
}

/*-------------------------------------------------------------------------------------*/
/**
 * Returns the performance profile features list of the currently running processor core.
 *
 * @param[out]      Features          The performance profile features supported by this platform
 * @param[in]       PlatformConfig    Config handle for platform specific information
 * @param[in]       StdHeader         Header for library and services
 *
 */
VOID
GetPerformanceFeatures (
     OUT   PERFORMANCE_PROFILE_FEATS    *Features,
  IN       PLATFORM_CONFIGURATION       *PlatformConfig,
  IN       AMD_CONFIG_PARAMS            *StdHeader
  )
{
  CPUID_DATA  CpuidDataStruct;
  CPU_SPECIFIC_SERVICES  *FamilySpecificServices;

  Features->PerformanceProfileValue = 0;
  // Reflect Probe Filter Configuration.
  Features->PerformanceProfileFeatures.ProbeFilter = 0;
  if (IsFeatureEnabled (HtAssist, PlatformConfig, StdHeader)) {
    Features->PerformanceProfileFeatures.ProbeFilter = 1;
  }

  // Reflect Display Refresh Requests use 32 bytes Configuration.
  Features->PerformanceProfileFeatures.RefreshRequest32Byte = 0;
  if (PlatformConfig->PlatformProfile.Use32ByteRefresh) {
    Features->PerformanceProfileFeatures.RefreshRequest32Byte = 1;
  }
  // Reflect Mct Isoc Read Priority set to variable Configuration.
  Features->PerformanceProfileFeatures.MctIsocVariable = 0;
  if (PlatformConfig->PlatformProfile.UseVariableMctIsocPriority) {
    Features->PerformanceProfileFeatures.MctIsocVariable = 1;
  }
  // Indicate if this boot is a warm reset.
  Features->PerformanceProfileFeatures.IsWarmReset = 0;
  if (IsWarmReset (StdHeader)) {
    Features->PerformanceProfileFeatures.IsWarmReset = 1;
  }

  // Get L3 Cache present as indicated by CPUID
  Features->PerformanceProfileFeatures.L3Cache = 0;
  Features->PerformanceProfileFeatures.NoL3Cache = 1;
  LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuidDataStruct, StdHeader);
  if (((CpuidDataStruct.EDX_Reg & 0xFFFC0000) >> 18) != 0) {
    Features->PerformanceProfileFeatures.L3Cache = 1;
    Features->PerformanceProfileFeatures.NoL3Cache = 0;
  }

  // Get VRM select high speed from build option.
  Features->PerformanceProfileFeatures.VrmHighSpeed = 0;
  if (PlatformConfig->VrmProperties[CoreVrm].HiSpeedEnable) {
    Features->PerformanceProfileFeatures.VrmHighSpeed = 1;
  }

  // Get some family, model specific performance type info.
  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  ASSERT (FamilySpecificServices != NULL);

  // Is the Northbridge P-State feature enabled
  Features->PerformanceProfileFeatures.NbPstates = 0;
  if (FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, PlatformConfig, StdHeader)) {
    Features->PerformanceProfileFeatures.NbPstates = 1;
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the MSR Register Entry.
 *
 * @TableEntryTypeMethod{::MsrRegister}.
 *
 * Read - Modify - Write the MSR, clearing masked bits, and setting the data bits.
 *
 * @param[in]     Entry             The MSR register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForMsrEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT64          MsrData;

  // Even for only single bit fields, use those in the mask.  "Mask nothing" is a bug, even if just by policy.
  ASSERT (Entry->MsrEntry.Mask != 0);

  LibAmdMsrRead (Entry->MsrEntry.Address, &MsrData, StdHeader);
  MsrData = MsrData & (~(Entry->MsrEntry.Mask));
  MsrData = MsrData | Entry->MsrEntry.Data;
  LibAmdMsrWrite (Entry->MsrEntry.Address, &MsrData, StdHeader);
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the PCI Register Entry.
 *
 * @TableEntryTypeMethod{::PciRegister}.
 *
 * Make the current core's PCI address with the function and register for the entry.
 * Read - Modify - Write the PCI register, clearing masked bits, and setting the data bits.
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForPciEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32          TempVar32_a;
  UINT32          MySocket;
  UINT32          MyModule;
  UINT32          Ignored;
  PCI_ADDR        MyPciAddress;
  AGESA_STATUS    IgnoredSts;
  TABLE_ENTRY_DATA  PciEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  // Even for only single bit fields, use those in the mask.  "Mask nothing" is a bug, even if just by policy.
  ASSERT ((Entry->InitialValues[4] == 0) &&
          (Entry->InitialValues[3] == 0) &&
          (Entry->PciEntry.Mask != 0));

  LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
  PciEntry.PciEntry = Entry->PciEntry;

  IDS_OPTION_HOOK (IDS_SET_PCI_REGISTER_ENTRY, &PciEntry, StdHeader);

  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredSts);
  GetPciAddress (StdHeader, MySocket, MyModule, &MyPciAddress, &IgnoredSts);
  MyPciAddress.Address.Function = PciEntry.PciEntry.Address.Address.Function;
  MyPciAddress.Address.Register = PciEntry.PciEntry.Address.Address.Register;
  LibAmdPciRead (AccessWidth32, MyPciAddress, &TempVar32_a, StdHeader);
  TempVar32_a = TempVar32_a & (~(PciEntry.PciEntry.Mask));
  TempVar32_a = TempVar32_a | PciEntry.PciEntry.Data;
  LibAmdPciWrite (AccessWidth32, MyPciAddress, &TempVar32_a, StdHeader);
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the Family Specific Workaround Register Entry.
 *
 * @TableEntryTypeMethod{::FamSpecificWorkaround}.
 *
 * Call the function, passing the data.
 *
 * See if you can use the other entries or make an entry that covers the fix.
 * After all, the purpose of having a table entry is to @b NOT have code which
 * isn't generic feature code, but is family/model code specific to one case.
 *
 * @param[in]     Entry             The Family Specific Workaround register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForFamSpecificWorkaroundEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  ASSERT (Entry->FamSpecificEntry.DoAction != NULL);

  Entry->FamSpecificEntry.DoAction (Entry->FamSpecificEntry.Data, StdHeader);
}

/*---------------------------------------------------------------------------------------*/
/**
 * Program HT Phy PCI registers using BKDG values.
 *
 * @TableEntryTypeMethod{::HtPhyRegister}.
 *
 *
 * @param[in]       Entry               The type specific entry data to be implemented (that is written).
 * @param[in]       PlatformConfig      Config handle for platform specific information
 * @param[in]       StdHeader           Config params for library, services.
 *
 */
VOID
SetRegisterForHtPhyEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32                Link;
  UINT32                MySocket;
  UINT32                MyModule;
  AGESA_STATUS          IgnoredStatus;
  UINT32                Ignored;
  CPU_LOGICAL_ID        CpuFamilyRevision;
  PCI_ADDR              CapabilitySet;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  BOOLEAN               MatchedSublink1;
  HT_FREQUENCIES        Freq0;
  HT_FREQUENCIES        Freq1;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT ((Entry->InitialValues[4] == 0) &&
          ((Entry->HtPhyEntry.TypeFeats.HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0) &&
          (Entry->HtPhyEntry.Address < HTPHY_REGISTER_MAX));

  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus);
  GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus);
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  GetCpuServicesFromLogicalId (&CpuFamilyRevision, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  Link = 0;
  while (FamilySpecificServices->NextLinkHasHtPhyFeats (
           FamilySpecificServices,
           &CapabilitySet,
           &Link,
           &Entry->HtPhyEntry.TypeFeats,
           &MatchedSublink1,
           &Freq0,
           &Freq1,
           StdHeader)) {
    FamilySpecificServices->SetHtPhyRegister (FamilySpecificServices, &Entry->HtPhyEntry, CapabilitySet, Link, StdHeader);
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Program a range of HT Phy PCI registers using BKDG values.
 *
 * @TableEntryTypeMethod{::HtPhyRangeRegister}.
 *
 *
 * @param[in]       Entry               The type specific entry data to be implemented (that is written).
 * @param[in]       PlatformConfig      Config handle for platform specific information
 * @param[in]       StdHeader           Config params for library, services.
 *
 */
VOID
SetRegisterForHtPhyRangeEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32                Link;
  UINT32                MySocket;
  UINT32                MyModule;
  AGESA_STATUS          IgnoredStatus;
  UINT32                Ignored;
  CPU_LOGICAL_ID        CpuFamilyRevision;
  PCI_ADDR              CapabilitySet;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  HT_PHY_TYPE_ENTRY_DATA CurrentHtPhyRegister;
  BOOLEAN                MatchedSublink1;
  HT_FREQUENCIES        Freq0;
  HT_FREQUENCIES        Freq1;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->HtPhyRangeEntry.TypeFeats.HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0) &&
          (Entry->HtPhyRangeEntry.LowAddress <= Entry->HtPhyRangeEntry.HighAddress) &&
          (Entry->HtPhyRangeEntry.HighAddress < HTPHY_REGISTER_MAX) &&
          (Entry->HtPhyRangeEntry.HighAddress != 0));

  CurrentHtPhyRegister.Mask = Entry->HtPhyRangeEntry.Mask;
  CurrentHtPhyRegister.Data = Entry->HtPhyRangeEntry.Data;
  CurrentHtPhyRegister.TypeFeats = Entry->HtPhyRangeEntry.TypeFeats;

  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus);
  GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus);
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  GetCpuServicesFromLogicalId (&CpuFamilyRevision, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  Link = 0;
  while (FamilySpecificServices->NextLinkHasHtPhyFeats (
           FamilySpecificServices,
           &CapabilitySet,
           &Link,
           &Entry->HtPhyRangeEntry.TypeFeats,
           &MatchedSublink1,
           &Freq0,
           &Freq1,
           StdHeader)) {
    for (CurrentHtPhyRegister.Address = Entry->HtPhyRangeEntry.LowAddress;
         CurrentHtPhyRegister.Address <= Entry->HtPhyRangeEntry.HighAddress;
         CurrentHtPhyRegister.Address++) {
      FamilySpecificServices->SetHtPhyRegister (FamilySpecificServices, &CurrentHtPhyRegister, CapabilitySet, Link, StdHeader);
    }
  }
}

/*----------------------------------------------------------------------------------------*/
/**
 * Is PackageLink an Internal Link?
 *
 * This is a test for the logical link match codes in the user interface, not a test for
 * the actual northbridge links.
 *
 * @param[in]    PackageLink   The link
 *
 * @retval       TRUE          This is an internal link
 * @retval       FALSE         This is not an internal link
 */
BOOLEAN
STATIC
IsDeemphasisLinkInternal (
  IN       UINT32  PackageLink
  )
{
  return (BOOLEAN) ((PackageLink <= HT_LIST_MATCH_INTERNAL_LINK_2) && (PackageLink >= HT_LIST_MATCH_INTERNAL_LINK_0));
}

/*----------------------------------------------------------------------------------------*/
/**
 * Get the Package Link number, for the current node and real link number.
 *
 * Based on the link to package link mapping from BKDG, look up package link for
 * the input link on the internal node number corresponding to the current core's node.
 * For single module processors, the northbridge link and package link are the same.
 *
 * @param[in]   Link                      the link on the current node.
 * @param[in]   FamilySpecificServices    CPU specific support interface.
 * @param[in]   StdHeader                 Config params for library, services.
 *
 * @return      the Package Link, HT_LIST_TERMINAL Not connected in package, HT_LIST_MATCH_INTERNAL_LINK package internal link.
 *
 */
UINT32
STATIC
LookupPackageLink (
  IN       UINT32                 Link,
  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
  IN       AMD_CONFIG_PARAMS     *StdHeader
  )
{
  UINT32 PackageLinkMapItem;
  UINT32 PackageLink;
  AP_MAIL_INFO ApMailbox;

  PackageLink = HT_LIST_TERMINAL;

  GetApMailbox (&ApMailbox.Info, StdHeader);

  if (ApMailbox.Fields.ModuleType != 0) {
    ASSERT (FamilySpecificServices->PackageLinkMap != NULL);
    // Use table to find this module's package link
    PackageLinkMapItem = 0;
    while ((*FamilySpecificServices->PackageLinkMap)[PackageLinkMapItem].Link != HT_LIST_TERMINAL) {
      if (((*FamilySpecificServices->PackageLinkMap)[PackageLinkMapItem].Module == ApMailbox.Fields.Module) &&
          ((*FamilySpecificServices->PackageLinkMap)[PackageLinkMapItem].Link == Link)) {
        PackageLink = (*FamilySpecificServices->PackageLinkMap)[PackageLinkMapItem].PackageLink;
        break;
      }
      PackageLinkMapItem++;
    }
  } else {
    PackageLink = Link;
  }
  return PackageLink;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Get the platform's specified deemphasis levels for the current link.
 *
 * Search the platform's list for a match to the current link and also matching frequency.
 * If a match is found, use the specified deemphasis levels.
 *
 * @param[in]       Socket                    The current Socket.
 * @param[in]       Link                      The link on that socket.
 * @param[in]       Frequency                 The frequency the link is set to.
 * @param[in]       PlatformConfig            Config handle for platform specific information
 * @param[in]       FamilySpecificServices    CPU specific support interface.
 * @param[in]       StdHeader                 Config params for library, services.
 *
 * @return          The Deemphasis values for the link.
 */
UINT32
STATIC
GetLinkDeemphasis (
  IN       UINT32                  Socket,
  IN       UINT32                  Link,
  IN       HT_FREQUENCIES          Frequency,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32 Result;
  CPU_HT_DEEMPHASIS_LEVEL *Match;
  UINT32 PackageLink;

  PackageLink = LookupPackageLink (Link, FamilySpecificServices, StdHeader);
  // All External and Internal links have deemphasis level none as the default.
  // However, it is expected that the platform BIOS will provide deemphasis levels for the external links.
  Result = ((DCV_LEVEL_NONE) | (DEEMPHASIS_LEVEL_NONE));

  if (PlatformConfig->PlatformDeemphasisList != NULL) {
    Match = PlatformConfig->PlatformDeemphasisList;
    while (Match->Socket != HT_LIST_TERMINAL) {
      if (((Match->Socket == Socket) || (Match->Socket == HT_LIST_MATCH_ANY)) &&
          ((Match->Link == PackageLink) ||
           ((Match->Link == HT_LIST_MATCH_ANY) && (!IsDeemphasisLinkInternal (PackageLink))) ||
           ((Match->Link == HT_LIST_MATCH_INTERNAL_LINK) && (IsDeemphasisLinkInternal (PackageLink)))) &&
          ((Match->LoFreq <= Frequency) && (Match->HighFreq >= Frequency))) {
        // Found a match, get the deemphasis value.
        ASSERT ((MaxPlatformDeemphasisLevel > Match->DcvDeemphasis) | (MaxPlatformDeemphasisLevel > Match->ReceiverDeemphasis));
        Result = ((1 << Match->DcvDeemphasis) | (1 << Match->ReceiverDeemphasis));
        break;
      } else {
        Match++;
      }
    }
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Program Deemphasis registers using BKDG values, for the platform specified levels.
 *
 * @TableEntryTypeMethod{::DeemphasisRegister}.
 *
 *
 * @param[in]    Entry            The type specific entry data to be implemented (that is written).
 * @param[in]    PlatformConfig   Config handle for platform specific information
 * @param[in]    StdHeader        Config params for library, services.
 *
 */
VOID
SetRegisterForDeemphasisEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32                Link;
  UINT32                MySocket;
  UINT32                MyModule;
  AGESA_STATUS          IgnoredStatus;
  UINT32                Ignored;
  CPU_LOGICAL_ID        CpuFamilyRevision;
  PCI_ADDR              CapabilitySet;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  BOOLEAN               MatchedSublink1;
  HT_FREQUENCIES        Freq0;
  HT_FREQUENCIES        Freq1;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->DeemphasisEntry.Levels.DeemphasisValues & ~(VALID_DEEMPHASIS_LEVELS)) == 0) &&
          ((Entry->DeemphasisEntry.HtPhyEntry.TypeFeats.HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0) &&
          (Entry->DeemphasisEntry.HtPhyEntry.Address < HTPHY_REGISTER_MAX));

  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus);
  GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus);
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  GetCpuServicesFromLogicalId (&CpuFamilyRevision, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  Link = 0;
  while (FamilySpecificServices->NextLinkHasHtPhyFeats (
           FamilySpecificServices,
           &CapabilitySet,
           &Link,
           &Entry->DeemphasisEntry.HtPhyEntry.TypeFeats,
           &MatchedSublink1,
           &Freq0,
           &Freq1,
           StdHeader)) {
    if (DoesEntryTypeSpecificInfoMatch (
          GetLinkDeemphasis (
            MySocket,
            (MatchedSublink1 ? (Link + 4) : Link),
            (MatchedSublink1 ? Freq1 : Freq0),
            PlatformConfig,
            FamilySpecificServices,
            StdHeader),
          Entry->DeemphasisEntry.Levels.DeemphasisValues)) {
      FamilySpecificServices->SetHtPhyRegister (
        FamilySpecificServices,
        &Entry->DeemphasisEntry.HtPhyEntry,
        CapabilitySet,
        Link,
        StdHeader
        );
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Program HT Phy PCI registers which have complex frequency dependencies.
 *
 * @TableEntryTypeMethod{::HtPhyFreqRegister}.
 *
 * After matching a link for HT Features, check if the HT frequency matches the given range.
 * If it does, get the northbridge frequency limits for implemented NB P-states and check if
 * each matches the given range - range 0 and range 1 for each NB frequency, respectively.
 * If all matches, apply the entry.
 *
 * @param[in]       Entry               The type specific entry data to be implemented (that is written).
 * @param[in]       PlatformConfig      Config handle for platform specific information
 * @param[in]       StdHeader           Config params for library, services.
 *
 */
VOID
SetRegisterForHtPhyFreqEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32                Link;
  UINT32                MySocket;
  UINT32                MyModule;
  AGESA_STATUS          IgnoredStatus;
  UINT32                Ignored;
  CPU_LOGICAL_ID        CpuFamilyRevision;
  PCI_ADDR              CapabilitySet;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  BOOLEAN               MatchedSublink1;
  HT_FREQUENCIES        Freq0;
  HT_FREQUENCIES        Freq1;
  BOOLEAN               Temp1;
  BOOLEAN               Temp2;
  UINT32                NbFreq0;
  UINT32                NbFreq1;
  UINT32                NbDivisor0;
  UINT32                NbDivisor1;

  // Errors:  extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->HtPhyFreqEntry.HtPhyEntry.TypeFeats.HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0) &&
          (Entry->HtPhyFreqEntry.HtPhyEntry.Address < HTPHY_REGISTER_MAX));

  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus);
  GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus);
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  GetCpuServicesFromLogicalId (&CpuFamilyRevision, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  Link = 0;
  while (FamilySpecificServices->NextLinkHasHtPhyFeats (
           FamilySpecificServices,
           &CapabilitySet,
           &Link,
           &Entry->HtPhyFreqEntry.HtPhyEntry.TypeFeats,
           &MatchedSublink1,
           &Freq0,
           &Freq1,
           StdHeader)) {
    // Check the HT Frequency for match to the range.
    if (IsEitherCountInRange (
          (MatchedSublink1 ? Freq1 : Freq0),
          (MatchedSublink1 ? Freq1 : Freq0),
          Entry->HtPhyFreqEntry.HtFreqCounts.HtFreqCountRanges)) {
      // Get the NB Frequency, convert to 100's of MHz, then convert to equivalent HT encoding.  This supports
      // NB frequencies from 800 MHz to 2600 MHz, which is currently greater than any processor supports.
      OptionMultiSocketConfiguration.GetSystemNbPstateSettings (
        (UINT32) 0,
        PlatformConfig,
        &NbFreq0,
        &NbDivisor0,
        &Temp1,
        &Temp2,
        StdHeader);

      if (OptionMultiSocketConfiguration.GetSystemNbPstateSettings (
            (UINT32) 1,
            PlatformConfig,
            &NbFreq1,
            &NbDivisor1,
            &Temp1,
            &Temp2,
            StdHeader)) {
        ASSERT (NbDivisor1 != 0);
        NbFreq1 = (NbFreq1 / NbDivisor1);
        NbFreq1 = (NbFreq1 / 100);
        NbFreq1 = (NbFreq1 / 2) + 1;
      } else {
        NbFreq1 = 0;
      }

      ASSERT (NbDivisor0 != 0);
      NbFreq0 = (NbFreq0 / NbDivisor0);
      NbFreq0 = (NbFreq0 / 100);
      NbFreq0 = (NbFreq0 / 2) + 1;
      if (IsEitherCountInRange (NbFreq0, NbFreq1, Entry->HtPhyFreqEntry.NbFreqCounts.HtFreqCountRanges)) {
        FamilySpecificServices->SetHtPhyRegister (
          FamilySpecificServices,
          &Entry->HtPhyFreqEntry.HtPhyEntry,
          CapabilitySet,
          Link,
          StdHeader);
      }
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the Performance Profile PCI Register Entry.
 *
 * @TableEntryTypeMethod{::ProfileFixup}.
 *
 * Check the entry's performance profile features to the platform's and do the
 * PCI register entry if they match.
 *
 * @param[in]     Entry             The Performance Profile register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForPerformanceProfileEntry (
  IN       TABLE_ENTRY_DATA      *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS     *StdHeader
  )
{
  PERFORMANCE_PROFILE_FEATS PlatformProfile;
  TABLE_ENTRY_DATA          PciEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->TokenPciEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0) &&
          (Entry->InitialValues[4] == 0));

  GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader);
  if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue,
                                      Entry->FixupEntry.TypeFeats.PerformanceProfileValue)) {
    LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
    PciEntry.PciEntry = Entry->FixupEntry.PciEntry;
    SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader);
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the HT Phy Performance Profile Register Entry.
 *
 * @TableEntryTypeMethod{::HtPhyProfileRegister}.
 *
 * @param[in]     Entry             The HT Phy register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForHtPhyProfileEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PERFORMANCE_PROFILE_FEATS PlatformProfile;
  TABLE_ENTRY_DATA          HtPhyEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->HtPhyProfileEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0) &&
          (Entry->InitialValues[5] == 0));

  GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader);
  if (DoesEntryTypeSpecificInfoMatch (
        PlatformProfile.PerformanceProfileValue,
        Entry->HtPhyProfileEntry.TypeFeats.PerformanceProfileValue)) {
    LibAmdMemFill (&HtPhyEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
    HtPhyEntry.HtPhyEntry = Entry->HtPhyProfileEntry.HtPhyEntry;
    SetRegisterForHtPhyEntry (&HtPhyEntry, PlatformConfig, StdHeader);
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the HT Host PCI Register Entry.
 *
 * @TableEntryTypeMethod{::HtHostPciRegister}.
 *
 * Make the current core's PCI address with the function and register for the entry.
 * For all HT links, check the link's feature set for a match to the entry.
 * Read - Modify - Write the PCI register, clearing masked bits, and setting the data bits.
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForHtHostEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINTN                 Link;
  UINT32                MySocket;
  UINT32                MyModule;
  AGESA_STATUS          IgnoredStatus;
  UINT32                Ignored;
  CPU_LOGICAL_ID        CpuFamilyRevision;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  PCI_ADDR              CapabilitySet;
  PCI_ADDR              PciAddress;
  HT_HOST_FEATS         HtHostFeats;
  UINT32                RegisterData;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT ((Entry->InitialValues[4] == 0) &&
          ((Entry->HtHostEntry.TypeFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0) &&
          (Entry->HtHostEntry.Address.Address.Register < HT_LINK_HOST_CAP_MAX));

  HtHostFeats.HtHostValue = 0;
  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus);
  GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus);
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  GetCpuServicesFromLogicalId (&CpuFamilyRevision, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  Link = 0;
  while (FamilySpecificServices->GetNextHtLinkFeatures (FamilySpecificServices, &Link, &CapabilitySet, &HtHostFeats, StdHeader)) {
    if (DoesEntryTypeSpecificInfoMatch (HtHostFeats.HtHostValue, Entry->HtHostEntry.TypeFeats.HtHostValue)) {
      // Do the HT Host PCI register update.
      PciAddress = CapabilitySet;
      PciAddress.Address.Register += Entry->HtHostEntry.Address.Address.Register;
      LibAmdPciRead (AccessWidth32, PciAddress, &RegisterData, StdHeader);
      RegisterData = RegisterData & (~(Entry->HtHostEntry.Mask));
      RegisterData = RegisterData | Entry->HtHostEntry.Data;
      LibAmdPciWrite (AccessWidth32, PciAddress, &RegisterData, StdHeader);
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the HT Host Performance PCI Register Entry.
 *
 * @TableEntryTypeMethod{::HtHostPerfPciRegister}.
 *
 * Make the current core's PCI address with the function and register for the entry.
 * For all HT links, check the link's feature set for a match to the entry.
 * Read - Modify - Write the PCI register, clearing masked bits, and setting the data bits.
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForHtHostPerfEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PERFORMANCE_PROFILE_FEATS PlatformProfile;
  TABLE_ENTRY_DATA HtHostPciTypeEntryData;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT ((Entry->InitialValues[5] == 0) &&
          ((Entry->HtHostEntry.TypeFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0) &&
          (Entry->HtHostEntry.Address.Address.Register < HT_LINK_HOST_CAP_MAX));

  // Check for any performance profile features.
  GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader);
  if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue,
                                      Entry->HtHostPerfEntry.PerformanceFeats.PerformanceProfileValue)) {
    // Perform HT Host entry process.
    LibAmdMemFill (&HtHostPciTypeEntryData, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
    HtHostPciTypeEntryData.HtHostEntry = Entry->HtHostPerfEntry.HtHostEntry;
    SetRegisterForHtHostEntry (&HtHostPciTypeEntryData, PlatformConfig, StdHeader);
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Set the HT Link Token Count registers.
 *
 * @TableEntryTypeMethod{::HtTokenPciRegister}.
 *
 * Make the current core's PCI address with the function and register for the entry.
 * Check the performance profile features.
 * For all HT links, check the link's feature set for a match to the entry.
 * Read - Modify - Write the PCI register, clearing masked bits, and setting the data bits.
 *
 * @param[in]     Entry             The Link Token register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForHtLinkTokenEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINTN                 Link;
  UINT32                MySocket;
  UINT32                MyModule;
  AGESA_STATUS          IgnoredStatus;
  UINT32                Ignored;
  CPU_LOGICAL_ID        CpuFamilyRevision;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  PCI_ADDR              CapabilitySet;
  HT_HOST_FEATS         HtHostFeats;
  PERFORMANCE_PROFILE_FEATS PlatformProfile;
  UINTN                 ProcessorCount;
  UINTN                     SystemDegree;
  UINT32                RegisterData;
  PCI_ADDR              PciAddress;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->HtTokenEntry.LinkFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0) &&
          ((Entry->HtTokenEntry.PerformanceFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0) &&
          (Entry->HtTokenEntry.Mask != 0));

  HtHostFeats.HtHostValue = 0;
  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus);
  GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus);
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  GetCpuServicesFromLogicalId (&CpuFamilyRevision, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);

  // Check if the actual processor count and SystemDegree are in either range.
  ProcessorCount = GetNumberOfProcessors (StdHeader);
  SystemDegree = GetSystemDegree (StdHeader);
  if (IsEitherCountInRange (ProcessorCount, SystemDegree, Entry->HtTokenEntry.ConnectivityCount.ConnectivityCountRanges)) {
    // Check for any performance profile features.
    GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader);
    if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue,
                                        Entry->HtTokenEntry.PerformanceFeats.PerformanceProfileValue)) {
      // Check the link features.
      Link = 0;
      while (FamilySpecificServices->GetNextHtLinkFeatures (FamilySpecificServices, &Link, &CapabilitySet, &HtHostFeats, StdHeader)) {
        if (DoesEntryTypeSpecificInfoMatch (HtHostFeats.HtHostValue, Entry->HtTokenEntry.LinkFeats.HtHostValue)) {
          // Do the HT Host PCI register update. Token register are four registers, sublink 0 and 1 share fields.
          // If sublink 0 is unconnected, we should let sublink 1 match.  If the links are ganged, of course only sublink 0 matches.
          // If the links are unganged and both connected, the BKDG settings are for both coherent.
          PciAddress = CapabilitySet;
          PciAddress.Address.Register = Entry->HtTokenEntry.Address.Address.Register +
            ((Link > 3) ? (((UINT32)Link - 4) * 4) : ((UINT32)Link * 4));
          PciAddress.Address.Function = Entry->HtTokenEntry.Address.Address.Function;
          LibAmdPciRead (AccessWidth32, PciAddress, &RegisterData, StdHeader);
          RegisterData = RegisterData & (~(Entry->HtTokenEntry.Mask));
          RegisterData = RegisterData | Entry->HtTokenEntry.Data;
          LibAmdPciWrite (AccessWidth32, PciAddress, &RegisterData, StdHeader);
        }
      }
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the Core Counts Performance PCI Register Entry.
 *
 * @TableEntryTypeMethod{::CoreCountsPciRegister}.
 *
 * Check the performance profile.
 * Check the actual core count to the range pair given, and apply if matched.
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForCoreCountsPerformanceEntry (
  IN       TABLE_ENTRY_DATA      *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS     *StdHeader
  )
{
  PERFORMANCE_PROFILE_FEATS PlatformProfile;
  UINTN ActualCoreCount;
  TABLE_ENTRY_DATA          PciEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->CoreCountEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0));

  GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader);
  if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, Entry->CoreCountEntry.TypeFeats.PerformanceProfileValue)) {
    ActualCoreCount = GetActiveCoresInCurrentModule (StdHeader);
    // Check if the actual core count is in either range.
    if (IsEitherCountInRange (ActualCoreCount, ActualCoreCount, Entry->CoreCountEntry.CoreCounts.CoreRanges)) {
      LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
      PciEntry.PciEntry = Entry->CoreCountEntry.PciEntry;
      SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader);
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the Processor Counts PCI Register Entry.
 *
 * @TableEntryTypeMethod{::ProcCountsPciRegister}.
 *
 * Check the performance profile.
 * Check the actual processor count (not node count!) to the range pair given, and apply if matched.
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForProcessorCountsEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PERFORMANCE_PROFILE_FEATS PlatformProfile;
  UINTN ProcessorCount;
  TABLE_ENTRY_DATA          PciEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->ProcCountEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0));

  GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader);
  if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, Entry->ProcCountEntry.TypeFeats.PerformanceProfileValue)) {
    ProcessorCount = GetNumberOfProcessors (StdHeader);
    // Check if the actual processor count is in either range.
    if (IsEitherCountInRange (ProcessorCount, ProcessorCount, Entry->ProcCountEntry.ProcessorCounts.ProcessorCountRanges)) {
      LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
      PciEntry.PciEntry = Entry->ProcCountEntry.PciEntry;
      SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader);
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the Compute Unit Counts PCI Register Entry.
 *
 * @TableEntryTypeMethod{::CompUnitCountsPciRegister}.
 *
 * Check the entry's performance profile features and the compute unit count
 * to the platform's and do the PCI register entry if they match.
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForComputeUnitCountsEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PERFORMANCE_PROFILE_FEATS PlatformProfile;
  UINTN ComputeUnitCount;
  TABLE_ENTRY_DATA          PciEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->CompUnitCountEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0));

  GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader);
  if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, Entry->CompUnitCountEntry.TypeFeats.PerformanceProfileValue)) {
    ComputeUnitCount = GetNumberOfCompUnitsInCurrentModule (StdHeader);
    // Check if the actual compute unit count is in either range.
    if (IsEitherCountInRange (ComputeUnitCount, ComputeUnitCount, Entry->CompUnitCountEntry.ComputeUnitCounts.ComputeUnitRanges)) {
      LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
      PciEntry.PciEntry = Entry->ProcCountEntry.PciEntry;
      SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader);
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the Processor Token Counts PCI Register Entry.
 *
 * @TableEntryTypeMethod{::TokenPciRegister}.
 *
 * The table criteria then translate as:
 * - 2 Socket, half populated  ==   Degree 1
 * - 4 Socket, half populated   ==  Degree 2
 * - 2 Socket, fully populated  ==  Degree 3
 * - 4 Socket, fully populated  ==  Degree > 3.  (4 or 5 if 3P, 6 if 4P)
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForTokenPciEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PERFORMANCE_PROFILE_FEATS PlatformProfile;
  UINTN                     SystemDegree;
  TABLE_ENTRY_DATA          PciEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT (((Entry->TokenPciEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0));

  GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader);
  if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, Entry->TokenPciEntry.TypeFeats.PerformanceProfileValue)) {
    SystemDegree = GetSystemDegree (StdHeader);
    // Check if the system degree is in the range.
    if (IsEitherCountInRange (SystemDegree, SystemDegree, Entry->TokenPciEntry.ConnectivityCount.ConnectivityCountRanges)) {
      LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
      PciEntry.PciEntry = Entry->TokenPciEntry.PciEntry;
      SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader);
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the HT Link Feature PCI Register Entry.
 *
 * @TableEntryTypeMethod{::HtFeatPciRegister}.
 *
 * Set a single field (that is, the register field is not in HT Host capability or a
 * set of per link registers) in PCI config, based on HT link features and package type.
 * This code is used for two cases: single link processors and multilink processors.
 * For single link cases, the link will be tested for a match to the HT Features for the link.
 * For multilink processors, the entry will match if @b any link is found which matches.
 * For example, a setting can be applied based on coherent HT3 by matching coherent AND HT3.
 *
 * Make the core's PCI address.  Check the package type (currently more important to the single link case),
 * and if matching, iterate through all links checking for an HT feature match until found or exhausted.
 * If a match was found, pass the PCI entry data to the implementer for writing for the current core.
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForHtFeaturePciEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINTN                 Link;
  UINT32                MySocket;
  UINT32                MyModule;
  AGESA_STATUS          IgnoredStatus;
  UINT32                Ignored;
  CPU_LOGICAL_ID        CpuFamilyRevision;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  PCI_ADDR              CapabilitySet;
  HT_HOST_FEATS         HtHostFeats;
  UINT32                ProcessorPackageType;
  BOOLEAN               IsMatch;
  TABLE_ENTRY_DATA      PciEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT ((Entry->HtFeatPciEntry.PciEntry.Mask != 0) &&
          ((Entry->HtFeatPciEntry.LinkFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0));

  HtHostFeats.HtHostValue = 0;
  LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
  PciEntry.PciEntry = Entry->HtFeatPciEntry.PciEntry;
  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus);
  GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus);
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  GetCpuServicesFromLogicalId (&CpuFamilyRevision, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);

  ASSERT ((Entry->HtFeatPciEntry.PackageType.PackageTypeValue & ~(PACKAGE_TYPE_ALL)) == 0);

  ProcessorPackageType = LibAmdGetPackageType (StdHeader);
  if (DoesEntryTypeSpecificInfoMatch (ProcessorPackageType, Entry->HtFeatPciEntry.PackageType.PackageTypeValue)) {
    IsMatch = FALSE;
    while (FamilySpecificServices->GetNextHtLinkFeatures (FamilySpecificServices, &Link, &CapabilitySet, &HtHostFeats, StdHeader)) {
      if (DoesEntryTypeSpecificInfoMatch (HtHostFeats.HtHostValue, Entry->HtFeatPciEntry.LinkFeats.HtHostValue)) {
        IsMatch = TRUE;
        break;
      }
    }
    if (IsMatch) {
      // Do the PCI register update.
      SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader);
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Perform the HT Link PCI Register Entry.
 *
 * @TableEntryTypeMethod{::HtLinkPciRegister}.
 *
 * Make the current core's PCI address with the function and register for the entry.
 * Registers are processed for match per link, assuming sequential PCI address per link.
 * Read - Modify - Write each matching link's PCI register, clearing masked bits, and setting the data bits.
 *
 * @param[in]     Entry             The PCI register entry to perform
 * @param[in]     PlatformConfig    Config handle for platform specific information
 * @param[in]     StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegisterForHtLinkPciEntry (
  IN       TABLE_ENTRY_DATA       *Entry,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINTN                 Link;
  UINT32                MySocket;
  UINT32                MyModule;
  AGESA_STATUS          IgnoredStatus;
  UINT32                Ignored;
  CPU_LOGICAL_ID        CpuFamilyRevision;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  PCI_ADDR              CapabilitySet;
  HT_HOST_FEATS         HtHostFeats;
  TABLE_ENTRY_DATA      PciEntry;

  // Errors:  Possible values in unused entry space, extra type features, value range checks.
  // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry.
  ASSERT ((Entry->HtLinkPciEntry.PciEntry.Mask != 0) &&
          ((Entry->HtLinkPciEntry.LinkFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0));

  HtHostFeats.HtHostValue = 0;
  LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader);
  PciEntry.PciEntry = Entry->HtLinkPciEntry.PciEntry;
  IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus);
  GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus);
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  GetCpuServicesFromLogicalId (&CpuFamilyRevision, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);

  Link = 0;
  while (FamilySpecificServices->GetNextHtLinkFeatures (FamilySpecificServices, &Link, &CapabilitySet, &HtHostFeats, StdHeader)) {
    if (DoesEntryTypeSpecificInfoMatch (HtHostFeats.HtHostValue, Entry->HtLinkPciEntry.LinkFeats.HtHostValue)) {
      // Do the update to the link's non-Host PCI register, based on the entry address.
      PciEntry.PciEntry.Address = Entry->HtLinkPciEntry.PciEntry.Address;
      PciEntry.PciEntry.Address.Address.Register = PciEntry.PciEntry.Address.Address.Register + ((UINT32)Link * 4);
      SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader);
    }
  }
}

/* -----------------------------------------------------------------------------*/
/**
 * Returns the platform features list of the currently running processor core.
 *
 * @param[out]      Features          The Features supported by this platform
 * @param[in]       PlatformConfig    Config handle for platform specific information
 * @param[in]       StdHeader         Header for library and services
 *
 */
VOID
GetPlatformFeatures (
     OUT   PLATFORM_FEATS         *Features,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PCI_ADDR  PciAddress;
  UINT32    CapabilityReg;
  UINT32     Link;
  CPU_SPECIFIC_SERVICES  *FamilySpecificServices;
  UINT32     CoreCount;

  // Start with none.
  Features->PlatformValue = 0;

  switch (PlatformConfig->PlatformProfile.PlatformControlFlowMode) {
  case Nfcm:
    Features->PlatformFeatures.PlatformNfcm = 1;
    break;
  case UmaDr:
    Features->PlatformFeatures.PlatformUma = 1;
    break;
  case UmaIfcm:
    Features->PlatformFeatures.PlatformUmaIfcm = 1;
    break;
  case Ifcm:
    Features->PlatformFeatures.PlatformIfcm = 1;
    break;
  case Iommu:
    Features->PlatformFeatures.PlatformIommu = 1;
    break;
  default:
    ASSERT (FALSE);
  }
  // Check - Single Link?
  // This is based on the implemented links on the package regardless of their
  // connection status.  All processors must match the BSP, so we only check it and
  // not the current node.  We don't care exactly how many links there are, as soon
  // as we find more than one we are done.
  Link = 0;
  PciAddress.AddressValue = MAKE_SBDFO (0, 0, PCI_DEV_BASE, FUNC_0, 0);
  // Until either all capabilities are done or until the desired link is found,
  // keep looking for HT Host Capabilities.
  while (Link < 2) {
    LibAmdPciFindNextCap (&PciAddress, StdHeader);
    if (PciAddress.AddressValue != ILLEGAL_SBDFO) {
      LibAmdPciRead (AccessWidth32, PciAddress, &CapabilityReg, StdHeader);
      if ((CapabilityReg & 0xE00000FF) == 0x20000008) {
        Link++;
      }
      // A capability other than an HT capability, keep looking.
    } else {
      // end of capabilities
      break;
    }
  }
  if (Link < 2) {
    Features->PlatformFeatures.PlatformSingleLink = 1;
  } else {
    Features->PlatformFeatures.PlatformMultiLink = 1;
  }

  // Set the legacy core count bits.
  GetActiveCoresInCurrentSocket (&CoreCount, StdHeader);
  switch (CoreCount) {
  case 1:
    Features->PlatformFeatures.PlatformSingleCore = 1;
    break;
  case 2:
    Features->PlatformFeatures.PlatformDualCore = 1;
    break;
  default:
    Features->PlatformFeatures.PlatformMultiCore = 1;
  }

  //
  // Get some specific platform type info, VC...etc.
  //
  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  ASSERT (FamilySpecificServices != NULL);
  FamilySpecificServices->GetPlatformTypeSpecificInfo (FamilySpecificServices, Features, StdHeader);

}

/*---------------------------------------------------------------------------------------*/
/**
 * Checks if a register table entry applies to the executing core.
 *
 * This function uses a combination of logical ID and platform features to
 * determine whether or not a register table entry applies to the executing core.
 *
 * @param[in]     CoreCpuRevision         The current core's logical ID
 * @param[in]     EntryCpuRevision        The entry's desired logical IDs
 * @param[in]     PlatformFeatures        The platform features
 * @param[in]     EntryFeatures           The entry's desired platform features
 *
 * @retval        TRUE           This entry should be applied
 * @retval        FALSE          This entry does not apply
 *
 */
BOOLEAN
STATIC
DoesEntryMatchPlatform (
  IN       CPU_LOGICAL_ID   CoreCpuRevision,
  IN       CPU_LOGICAL_ID   EntryCpuRevision,
  IN       PLATFORM_FEATS   PlatformFeatures,
  IN       PLATFORM_FEATS   EntryFeatures
  )
{
  BOOLEAN Result;

  Result = FALSE;

  if (((CoreCpuRevision.Family & EntryCpuRevision.Family) != 0) &&
      ((CoreCpuRevision.Revision & EntryCpuRevision.Revision) != 0)) {
    if (EntryFeatures.PlatformFeatures.AndPlatformFeats == 0) {
      // Match if ANY entry feats match a platform feat (an OR test)
      if ((EntryFeatures.PlatformValue & PlatformFeatures.PlatformValue) != 0) {
        Result = TRUE;
      }
    } else {
      // Match if ALL entry feats match a platform feat (an AND test)
      if ((EntryFeatures.PlatformValue & ~(AMD_PF_AND)) ==
          (EntryFeatures.PlatformValue & PlatformFeatures.PlatformValue)) {
        Result = TRUE;
      }
    }
  }

  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Checks register table entry type specific criteria to the platform.
 *
 * Entry Data Type implementer methods can use this generically to check their own
 * specific criteria.  The method collects the actual platform characteristics and
 * provides them along with the table entry's criteria to this service.
 *
 * There are a couple considerations for any implementer method using this service.
 * The criteria value has to be representable as a UINT32.  The MSB, Bit 31, has to
 * be used as a AND test request if set in the entry.  (The platform value should never
 * have that bit set.)
 *
 * @param[in]     PlatformTypeSpecificFeatures        The platform features
 * @param[in]     EntryTypeFeatures                   The entry's desired platform features
 *
 * @retval        TRUE                                This entry should be applied
 * @retval        FALSE                               This entry does not apply
 *
 */
BOOLEAN
DoesEntryTypeSpecificInfoMatch (
  IN       UINT32   PlatformTypeSpecificFeatures,
  IN       UINT32   EntryTypeFeatures
  )
{
  BOOLEAN Result;

  Result = FALSE;

  if ((EntryTypeFeatures & BIT31) == 0) {
    // Match if ANY entry feats match a platform feat (an OR test)
    if ((EntryTypeFeatures & PlatformTypeSpecificFeatures) != 0) {
      Result = TRUE;
    }
  } else {
    // Match if ALL entry feats match a platform feat (an AND test)
    if ((EntryTypeFeatures & ~(BIT31)) == (EntryTypeFeatures & PlatformTypeSpecificFeatures)) {
      Result = TRUE;
    }
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Determine this core's Selector matches.
 *
 * @param[in]  Selector    Is the current core this selector type?
 * @param[in]  StdHeader   Config handle for library and services.
 *
 * @retval  TRUE           Yes, it is.
 * @retval  FALSE          No, it is not.
 */
BOOLEAN
STATIC
IsCoreSelector (
  IN       TABLE_CORE_SELECTOR       Selector,
  IN       AMD_CONFIG_PARAMS        *StdHeader
  )
{
  BOOLEAN Result;
  AGESA_STATUS  CalledStatus;

  Result = TRUE;
  ASSERT (Selector < TableCoreSelectorMax);

  if ((Selector == PrimaryCores) && !IsCurrentCorePrimary (StdHeader)) {
    Result = FALSE;
  }
  if ((Selector == CorePairPrimary) && !IsCorePairPrimary (FirstCoreIsComputeUnitPrimary, StdHeader)) {
    Result = FALSE;
  }
  if ((Selector == BscCore) && (!IsBsp (StdHeader, &CalledStatus))) {
    Result = FALSE;
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Set the registers for this core based on entries in a list of Register Tables.
 *
 * Determine the platform features and this core's logical id.  Get the specific table
 * entry type implementations for the logical model, which may be either generic (the ones
 * in this file) or specific.
 *
 * Scan the tables starting the with ones for all cores and progressively narrowing the selection
 * based on this core's role (ex. primary core).  For a selected table, check for each entry
 * matching the current core and platform, and call the implementer method to perform the
 * register set operation if it matches.
 *
 * @param[in]  PlatformConfig    Config handle for platform specific information
 * @param[in]  StdHeader         Config handle for library and services.
 *
 */
VOID
SetRegistersFromTables (
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  CPU_LOGICAL_ID         CpuLogicalId;
  PLATFORM_FEATS         PlatformFeatures;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  TABLE_ENTRY_FIELDS    *Entries;
  TABLE_CORE_SELECTOR    Selector;
  TABLE_ENTRY_TYPE       EntryType;
  REGISTER_TABLE       **TableHandle;
  UINTN                  NumberOfEntries;
  UINTN                  CurrentEntryCount;
  TABLE_ENTRY_TYPE_DESCRIPTOR *TypeImplementer;
  PF_DO_TABLE_ENTRY       DoTableEntry[TableEntryTypeMax];

  // Did you really mean to increase the size of ALL table entries??!!
  // While it is not necessarily a bug to increase the size of table entries:
  //   - Is this warning a surprise?  Please fix it.
  //   - If expected, is this really a feature which is worth the increase?  Then let other entries also use the space.
  ASSERT (sizeof (TABLE_ENTRY_DATA) == (MAX_ENTRY_TYPE_ITEMS32 * sizeof (UINT32)));

  PlatformFeatures.PlatformValue = 0;
  GetLogicalIdOfCurrentCore (&CpuLogicalId, StdHeader);
  GetPlatformFeatures (&PlatformFeatures, PlatformConfig, StdHeader);
  GetCpuServicesFromLogicalId (&CpuLogicalId, (const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);

  // Build a non-sparse table of implementer methods, so we don't have to keep searching.
  // It is a bug to not include a descriptor for a type that is in the table (but the
  // descriptor can point to a non-assert stub).
  // Also, it is not a bug to have no register table implementations, but it is a bug to have none and call this routine.
  for (EntryType = MsrRegister; EntryType < TableEntryTypeMax; EntryType++) {
    DoTableEntry[EntryType] = (PF_DO_TABLE_ENTRY)CommonAssert;
  }
  TypeImplementer = FamilySpecificServices->TableEntryTypeDescriptors;
  ASSERT (TypeImplementer != NULL);
  while (TypeImplementer->EntryType < TableEntryTypeMax) {
    DoTableEntry[TypeImplementer->EntryType] = TypeImplementer->DoTableEntry;
    TypeImplementer++;
  }

  for (Selector = AllCores; Selector < TableCoreSelectorMax; Selector++) {
    if (IsCoreSelector (Selector, StdHeader)) {
      // If the current core is the selected type of core, work the table list for tables for that type of core.
      TableHandle = NULL;
      Entries = GetNextRegisterTable (FamilySpecificServices, Selector, &TableHandle, &NumberOfEntries, StdHeader);
      while (Entries != NULL) {
        for (CurrentEntryCount = 0; CurrentEntryCount < NumberOfEntries; CurrentEntryCount++, Entries++) {
          if (DoesEntryMatchPlatform (CpuLogicalId, Entries->CpuRevision, PlatformFeatures, Entries->Features)) {
            // The entry matches this config, Do It!
            // Find the implementer for this entry type and pass the entry data to it.
            ASSERT (Entries->EntryType < TableEntryTypeMax);
            DoTableEntry[Entries->EntryType] (&Entries->Entry, PlatformConfig, StdHeader);
          }
        }
        Entries = GetNextRegisterTable (FamilySpecificServices, Selector, &TableHandle, &NumberOfEntries, StdHeader);
      }
    } else {
      // Once a selector does not match the current core, quit looking.
      break;
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Set the registers for this core based on entries in a list of Register Tables.
 *
 * This function acts as a wrapper for calling the SetRegistersFromTables
 * routine at AmdInitEarly.
 *
 *  @param[in]   FamilyServices      The current Family Specific Services.
 *  @param[in]   EarlyParams         Service parameters.
 *  @param[in]   StdHeader           Config handle for library and services.
 *
 */
VOID
SetRegistersFromTablesAtEarly (
  IN       CPU_SPECIFIC_SERVICES  *FamilyServices,
  IN       AMD_CPU_EARLY_PARAMS   *EarlyParams,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  AGESA_TESTPOINT (TpProcCpuProcessRegisterTables, StdHeader);
  SetRegistersFromTables (&EarlyParams->PlatformConfig, StdHeader);
}
