/* $NoKeywords:$ */
/**
 * @file
 *
 * Implement External, AGESA Common, and CPU component General Services.
 *
 * Contains implementation of the interfaces: General Services API in AGESA.h,
 * GeneralServices.h, and cpuServices.h.
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:      AGESA
 * @e sub-project:  CPU
 * @e \$Revision: 36208 $   @e \$Date: 2010-08-13 22:55:05 +0800 (Fri, 13 Aug 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 "Options.h"
#include "Topology.h"
#include "cpuRegisters.h"
#include "GeneralServices.h"
#include "cpuFamilyTranslation.h"
#include "cpuServices.h"
#include "heapManager.h"
#include "cpuApicUtilities.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G1_PEICC)

#define FILECODE PROC_CPU_CPUGENERALSERVICES_FILECODE
/*----------------------------------------------------------------------------------------
 *                   D E F I N I T I O N S    A N D    M A C R O S
 *----------------------------------------------------------------------------------------
 */
extern OPTIONS_CONFIG_TOPOLOGY TopologyConfiguration;
extern BUILD_OPT_CFG UserOptions;

/*----------------------------------------------------------------------------------------
 *                  T Y P E D E F S     A N D     S T R U C T U  R E S
 *----------------------------------------------------------------------------------------
 */

/*----------------------------------------------------------------------------------------
 *           P R O T O T Y P E S     O F     L O C A L     F U  N C T I O N S
 *----------------------------------------------------------------------------------------
 */

/*----------------------------------------------------------------------------------------
 *            E X P O R T E D    F U N C T I O N S - External General Services API
 *----------------------------------------------------------------------------------------
 */

/**
 * Get a specified Core's APIC ID.
 *
 * Invoke corresponding Cpu Service for external user.
 *
 * @param[in,out]    AmdParamApic    Our interface struct
 *
 * @return         The most severe status of any called service.
 */
AGESA_STATUS
AmdGetApicId (
  IN OUT   AMD_APIC_PARAMS *AmdParamApic
  )
{
  AGESA_STATUS AgesaStatus;

  AGESA_TESTPOINT (TpIfAmdGetApicIdEntry, &AmdParamApic->StdHeader);
  AmdParamApic->StdHeader.HeapBasePtr = HeapGetBaseAddress (&AmdParamApic->StdHeader);

  AmdParamApic->IsPresent = GetApicId (
    &AmdParamApic->StdHeader,
    AmdParamApic->Socket,
    AmdParamApic->Core,
    &AmdParamApic->ApicAddress,
    &AgesaStatus
    );

  AGESA_TESTPOINT (TpIfAmdGetApicIdExit, &AmdParamApic->StdHeader);
  return AgesaStatus;
}

/**
 * Get Processor Module's PCI Config Space address.
 *
 * Invoke corresponding Cpu Service for external user.
 *
 * @param[in,out]    AmdParamGetPci    Our interface struct
 *
 * @return         The most severe status of any called service.
 */
AGESA_STATUS
AmdGetPciAddress (
  IN OUT   AMD_GET_PCI_PARAMS *AmdParamGetPci
  )
{
  AGESA_STATUS AgesaStatus;

  AGESA_TESTPOINT (TpIfAmdGetPciAddressEntry, &AmdParamGetPci->StdHeader);
  AmdParamGetPci->StdHeader.HeapBasePtr = HeapGetBaseAddress (&AmdParamGetPci->StdHeader);

  AmdParamGetPci->IsPresent = GetPciAddress (
    &AmdParamGetPci->StdHeader,
    AmdParamGetPci->Socket,
    AmdParamGetPci->Module,
    &AmdParamGetPci->PciAddress,
    &AgesaStatus
    );

  AGESA_TESTPOINT (TpIfAmdGetPciAddressExit, &AmdParamGetPci->StdHeader);
  return AgesaStatus;
}

/**
 * "Who am I" for the current running core.
 *
 * Invoke corresponding Cpu Service for external user.
 *
 * @param[in,out]    AmdParamIdentify    Our interface struct
 *
 * @return         The most severe status of any called service.
 */
AGESA_STATUS
AmdIdentifyCore (
  IN OUT   AMD_IDENTIFY_PARAMS *AmdParamIdentify
  )
{
  AGESA_STATUS AgesaStatus;
  UINT32 Socket;
  UINT32 Module;
  UINT32 Core;

  AGESA_TESTPOINT (TpIfAmdIdentifyCoreEntry, &AmdParamIdentify->StdHeader);
  AmdParamIdentify->StdHeader.HeapBasePtr = HeapGetBaseAddress (&AmdParamIdentify->StdHeader);

  IdentifyCore (
    &AmdParamIdentify->StdHeader,
    &Socket,
    &Module,
    &Core,
    &AgesaStatus
    );
  AmdParamIdentify->Socket = (UINT8)Socket;
  AmdParamIdentify->Module = (UINT8)Module;
  AmdParamIdentify->Core = (UINT8)Core;

  AGESA_TESTPOINT (TpIfAmdIdentifyCoreExit, &AmdParamIdentify->StdHeader);
  return AgesaStatus;
}

/*----------------------------------------------------------------------------------------
 *            E X P O R T E D    F U N C T I O N S - AGESA common General Services
 *----------------------------------------------------------------------------------------
 */

/*---------------------------------------------------------------------------------------*/
/**
 * Get a specified Core's APIC ID.
 *
 * Code sync: This calculation MUST match the assignment
 *    calculation done in LocalApicInitializationAtEarly function.
 *
 * @param[in]    StdHeader    Header for library and services.
 * @param[in]    Socket       The socket in which the Core's Processor is installed.
 * @param[in]    Core         The Core id.
 * @param[out]   ApicAddress  The Core's APIC ID.
 * @param[out]   AgesaStatus  Aggregates AGESA_STATUS for external interface, Always Succeeds.
 *
 * @retval       TRUE         The core is present, APIC Id valid
 * @retval       FALSE        The core is not present, APIC Id not valid.
*/
BOOLEAN
GetApicId (
  IN       AMD_CONFIG_PARAMS *StdHeader,
  IN       UINT32            Socket,
  IN       UINT32            Core,
     OUT   UINT8             *ApicAddress,
     OUT   AGESA_STATUS      *AgesaStatus
  )
{
  BOOLEAN ReturnValue;
  UINT32  CoreCount;
  UINT32  ApicID;

  ReturnValue = FALSE;
  if (GetActiveCoresInGivenSocket (Socket, &CoreCount, StdHeader)) {
    if (Core < CoreCount) {
      ReturnValue = TRUE;
      GetLocalApicIdForCore (Socket, Core, &ApicID, StdHeader);
      *ApicAddress = (UINT8) ApicID;
    }
  }

  // Always Succeeds.
  *AgesaStatus = AGESA_SUCCESS;

  return ReturnValue;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Get Processor Module's PCI Config Space address.
 *
 * @param[in]    StdHeader    Header for library and services.
 * @param[in]    Socket       The Core's Socket.
 * @param[in]    Module       The Module in that Processor
 * @param[out]   PciAddress   The Processor's PCI Config Space address (Function 0, Register 0)
 * @param[out]   AgesaStatus  Aggregates AGESA_STATUS for external interface, Always Succeeds.
 *
 * @retval       TRUE         The core is present, PCI Address valid
 * @retval       FALSE        The core is not present, PCI Address not valid.
 */
BOOLEAN
GetPciAddress (
  IN       AMD_CONFIG_PARAMS *StdHeader,
  IN       UINT32            Socket,
  IN       UINT32            Module,
     OUT   PCI_ADDR          *PciAddress,
     OUT   AGESA_STATUS      *AgesaStatus
  )
{
  UINT8        Node;
  BOOLEAN      Result;

  ASSERT (Socket < MAX_SOCKETS);
  ASSERT (Module < MAX_DIES);

  Result = TRUE;
  // Always Succeeds.
  *AgesaStatus = AGESA_SUCCESS;

  if (GetNodeId (Socket, Module, &Node, StdHeader)) {
    // socket is populated
    PciAddress->AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
    PciAddress->Address.Device = PciAddress->Address.Device + Node;
  } else {
    // socket is not populated
    PciAddress->AddressValue = ILLEGAL_SBDFO;
    Result = FALSE;
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * "Who am I" for the current running core.
 *
 * @param[in]    StdHeader    Header for library and services.
 * @param[out]   Socket       The current Core's Socket
 * @param[out]   Module       The current Core's Processor Module
 * @param[out]   Core         The current Core's core id.
 * @param[out]   AgesaStatus  Aggregates AGESA_STATUS for external interface, Always Succeeds.
 *
 */
VOID
IdentifyCore (
  IN       AMD_CONFIG_PARAMS *StdHeader,
     OUT   UINT32            *Socket,
     OUT   UINT32            *Module,
     OUT   UINT32            *Core,
     OUT   AGESA_STATUS      *AgesaStatus
  )
{
  AP_MAIL_INFO ApMailboxInfo;
  UINT32 CurrentCore;

  // Always Succeeds.
  *AgesaStatus = AGESA_SUCCESS;

  GetApMailbox (&ApMailboxInfo.Info, StdHeader);
  ASSERT (ApMailboxInfo.Fields.Socket < MAX_SOCKETS);
  ASSERT (ApMailboxInfo.Fields.Module < MAX_DIES);
  *Socket = (UINT8)ApMailboxInfo.Fields.Socket;
  *Module = (UINT8)ApMailboxInfo.Fields.Module;

  // Get Core Id
  GetCurrentCore (&CurrentCore, StdHeader);
  *Core = (UINT8)CurrentCore;
}


/*----------------------------------------------------------------------------------------
 *            E X P O R T E D    F U N C T I O N S - cpu component General Services
 *----------------------------------------------------------------------------------------
 */

/*---------------------------------------------------------------------------------------*/
/**
 * Get the current Platform's number of Sockets, regardless of how many are populated.
 *
 * The Options component can provide how many sockets are available in system.
 * This can be used to avoid testing presence of Processors in Sockets which don't exist.
 * The result can be one socket to the maximum possible sockets of any supported processor family.
 * You cannot assume that all sockets contain a processor or that the sockets have processors
 * installed in any particular order.  Do not convert this number to a number of nodes.
 *
 * @return   The number of available sockets for the platform.
 *
 */
UINT32
GetPlatformNumberOfSockets ()
{
  return TopologyConfiguration.PlatformNumberOfSockets;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Get the number of Modules to check presence in each Processor.
 *
 * The Options component can provide how many modules need to be check for presence in each
 * processor, regardless whether all, or any, processor have that many modules present on this boot.
 * The result can be one module to the maximum possible modules of any supported processor family.
 * You cannot assume that Modules are in any particular order, especially with respect to node id.
 *
 * @return   The maximum number of modules in each processor.
 *
 */
UINT32
GetPlatformNumberOfModules ()
{
  return TopologyConfiguration.PlatformNumberOfModules;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Is a processor present in Socket?
 *
 * Check to see if any possible module of the processor is present.  This provides
 * support for a few cases where a PCI address isn't needed, but code still needs to
 * iterate by Socket.
 *
 * @param[in]   Socket  The socket which is being tested
 * @param[in]   StdHeader    Header for library and services.
 *
 * @retval      TRUE    The socket has a processor installed
 * @retval      FALSE   The socket is empty (or the processor is dead).
 *
 */
BOOLEAN
IsProcessorPresent (
  IN       UINT32             Socket,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  SOCKET_DIE_TO_NODE_MAP  pSocketDieMap;
  LOCATE_HEAP_PTR  SocketDieHeapDataBlock;
  BOOLEAN Result;
  UINT32 Module;
  AGESA_STATUS Status;

  ASSERT (Socket < MAX_SOCKETS);
  Result = FALSE;
  SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE;

  //  Get data block from heap
  Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader);
  pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr;
  ASSERT ((pSocketDieMap != NULL) && (Status == AGESA_SUCCESS));
  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if ((*pSocketDieMap)[Socket][Module].Node != 0xFF) {
      Result = TRUE;
      break;
    }
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Provide the number of installed processors (not Nodes! and not Sockets!)
 *
 * Iterate over the Socket, Module to Node Map, counting the number of present nodes.
 * Do not use this as a Node Count!  Do not use this as the number of Sockets!  (This
 * is for APIC ID utilities.)
 *
 * @param[in]   StdHeader    Header for library and services.
 *
 * @return      the number of processors installed
 *
 */
UINT32
GetNumberOfProcessors (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  SOCKET_DIE_TO_NODE_MAP  pSocketDieMap;
  LOCATE_HEAP_PTR  SocketDieHeapDataBlock;
  UINT32 Result;
  UINT32 Socket;
  UINT32 Module;
  AGESA_STATUS Status;

  Result = 0;
  SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE;

  //  Get data block from heap
  Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader);
  pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr;
  ASSERT ((pSocketDieMap != NULL) && (Status == AGESA_SUCCESS));
  for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
    for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
      if ((*pSocketDieMap)[Socket][Module].Node != 0xFF) {
        Result++;
        break;
      }
    }
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * For a specific Node, get its Socket and Module ids.
 *
 * If asking for the current running Node, read the mailbox socket, module. Specific Node,
 * locate the Node to Socket/Module Map in heap, and return the ids, if present.
 *
 * @param[in]    Node         What Socket and Module is this Node?
 * @param[out]   Socket       The Socket containing that Node.
 * @param[out]   Module       The Processor Module of that Node.
 * @param[in]    StdHeader    Header for library and services.
 *
 * @retval TRUE Node is present, Socket, Module are valid.
 * @retval FALSE Node is not present, why do you ask?
 */
BOOLEAN
GetSocketModuleOfNode (
  IN       UINT32    Node,
     OUT   UINT32    *Socket,
     OUT   UINT32    *Module,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  NODE_TO_SOCKET_DIE_MAP  pNodeMap;
  LOCATE_HEAP_PTR  SocketDieHeapDataBlock;
  BOOLEAN Result;
  AGESA_STATUS Status;

  Result = FALSE;

  ASSERT (Node < MAX_NODES);

  //  Get Map from heap
  SocketDieHeapDataBlock.BufferHandle = NODE_ID_MAP_HANDLE;
  Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader);
  pNodeMap = (NODE_TO_SOCKET_DIE_MAP)SocketDieHeapDataBlock.BufferPtr;
  ASSERT ((pNodeMap != NULL) && (Status == AGESA_SUCCESS));
  *Socket = (*pNodeMap)[Node].Socket;
  *Module = (*pNodeMap)[Node].Die;
  if ((*pNodeMap)[Node].Socket != 0xFF) {
    Result = TRUE;
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Get the current core's Processor APIC Index.
 *
 * The Processor APIC Index is the position of the current processor in the APIC id
 * assignment.  Processors are ordered in node id order.  This is not the same, however,
 * as the node id of the current socket and module or the current socket id.
 *
 * @param[in]    Node      The current desired core's node id (usually the current core).
 * @param[in]    StdHeader Header for library and services.
 *
 * @return  Processor APIC Index
 *
 */
UINT32
GetProcessorApicIndex (
  IN       UINT32            Node,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 ProcessorApicIndex;
  UINT32 PreviousSocket;
  UINT32 CurrentSocket;
  UINT32 Ignored;
  UINT32 i;

  ASSERT (Node < MAX_NODES);

  // Calculate total APIC devices up to Current Node, Core.
  ProcessorApicIndex = 0;
  PreviousSocket = 0xFF;
  for (i = 0; i < (Node + 1); i++) {
    GetSocketModuleOfNode (i, &CurrentSocket, &Ignored, StdHeader);
    if (CurrentSocket != PreviousSocket) {
      ProcessorApicIndex++;
      PreviousSocket = CurrentSocket;
    }
  }
  // Convert to Index (zero based) from count (one based).
  ProcessorApicIndex--;
  return ProcessorApicIndex;
}

/*---------------------------------------------------------------------------------------*/
/**
 *  Returns current node number
 *
 *  @param[out]      Node       This Core's Node id
 *  @param[in]        StdHeader  Header for library and services.
 *
 */
VOID
GetCurrentNodeNum (
     OUT   UINT32 *Node,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  AP_MAIL_INFO ApMailboxInfo;

  // Get the Node Id from the Mailbox.
  GetApMailbox (&ApMailboxInfo.Info, StdHeader);
  ASSERT (ApMailboxInfo.Fields.Node < MAX_NODES);
  *Node = ApMailboxInfo.Fields.Node;
}

/*---------------------------------------------------------------------------------------*/
/**
 *  Writes to all nodes on the executing core's socket.
 *
 *  @param[in]     PciAddress    The Function and Register to update
 *  @param[in]     Mask          The bitwise AND mask to apply to the current register value
 *  @param[in]     Data          The bitwise OR mask to apply to the current register value
 *  @param[in]     StdHeader     Header for library and services.
 *
 */
VOID
ModifyCurrentSocketPci (
  IN       PCI_ADDR          *PciAddress,
  IN       UINT32            Mask,
  IN       UINT32            Data,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 Socket;
  UINT32 Module;
  UINT32 Core;
  UINT32 PciReg;
  AGESA_STATUS AgesaStatus;
  PCI_ADDR Reg;

  IdentifyCore (StdHeader, &Socket, &Module, &Core, &AgesaStatus);

  for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) {
    if (GetPciAddress (StdHeader, Socket, Module, &Reg, &AgesaStatus)) {
      Reg.Address.Function = PciAddress->Address.Function;
      Reg.Address.Register = PciAddress->Address.Register;
      LibAmdPciRead (AccessWidth32, Reg, &PciReg, StdHeader);
      PciReg &= Mask;
      PciReg |= Data;
      LibAmdPciWrite (AccessWidth32, Reg, &PciReg, StdHeader);
    }
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Returns Total number of active cores in the current socket
 *
 * @param[out]     CoreCount    The cores in this processor.
 * @param[in]      StdHeader    Header for library and services.
 *
 */
VOID
GetActiveCoresInCurrentSocket (
     OUT   UINT32 *CoreCount,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  CPUID_DATA  CpuidDataStruct;
  UINT32 TotalCoresCount;

  LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuidDataStruct, StdHeader);
  TotalCoresCount = (CpuidDataStruct.ECX_Reg & 0x000000FF) + 1;
  *CoreCount = TotalCoresCount;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Provides the Total number of active cores in the current core's node.
 *
 * @param[in]      StdHeader   Header for library and services.
 *
 * @return         The current node core count
 */
UINTN
GetActiveCoresInCurrentModule (
  IN       AMD_CONFIG_PARAMS  *StdHeader
  )
{
  UINT32 Socket;
  UINT32 Module;
  UINT32 Core;
  UINT32 LowCore;
  UINT32 HighCore;
  UINT32 ProcessorCoreCount;
  AGESA_STATUS AgesaStatus;

  ProcessorCoreCount = 0;

  IdentifyCore (StdHeader, &Socket, &Module, &Core, &AgesaStatus);
  if (GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader)) {
    ProcessorCoreCount = ((HighCore - LowCore) + 1);
  }
  return ProcessorCoreCount;
}

/**
 * Provide the number of compute units on current module.
 *
 *
 * @param[in]   StdHeader    Header for library and services.
 *
 * @return      The current compute unit counts.
 *
 */
UINTN
GetNumberOfCompUnitsInCurrentModule (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32                 Socket;
  UINT32                 Module;
  UINT32                 CurrentCore;
  UINT32                 ComputeUnitCount;
  UINT32                 Enabled;
  AGESA_STATUS           IgnoredSts;
  LOCATE_HEAP_PTR        SocketDieHeapDataBlock;
  SOCKET_DIE_TO_NODE_MAP pSocketDieMap;

  ComputeUnitCount = 0;

  ASSERT ((GetComputeUnitMapping (StdHeader) == AllCoresMapping) ||
          (GetComputeUnitMapping (StdHeader) == EvenCoresMapping));

  IdentifyCore (StdHeader, &Socket, &Module, &CurrentCore, &IgnoredSts);
  //  Get data block from heap
  SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE;
  IgnoredSts = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader);
  pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr;
  ASSERT ((pSocketDieMap != NULL) && (IgnoredSts == AGESA_SUCCESS));
  // Current Core's socket, module must be present.
  ASSERT ((*pSocketDieMap)[Socket][Module].Node != 0xFF);
  // Process compute unit info
  Enabled = (*pSocketDieMap)[Socket][Module].EnabledComputeUnits;

  while (Enabled > 0) {
    if ((Enabled & 0x1) != 0) {
      ComputeUnitCount++;
    }
    Enabled >>= 1;
  }

  return ComputeUnitCount;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Provides the Total number of active cores in the given socket.
 *
 * @param[in]      Socket      Get a core count for the processor in this socket.
 * @param[out]     CoreCount   Its core count
 * @param[in]      StdHeader   Header for library and services.
 *
 * @retval     TRUE    A processor is present in the Socket and the CoreCount is valid.
 * @retval     FALSE   The Socket does not have a Processor
 */
BOOLEAN
GetActiveCoresInGivenSocket (
  IN       UINT32             Socket,
     OUT   UINT32             *CoreCount,
  IN       AMD_CONFIG_PARAMS  *StdHeader
  )
{
  UINT32 Module;
  UINT32 LowCore;
  UINT32 HighCore;
  UINT32 ProcessorCoreCount;
  BOOLEAN Result;

  Result = FALSE;
  ProcessorCoreCount = 0;

  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if (GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader)) {
      ProcessorCoreCount = ProcessorCoreCount + ((HighCore - LowCore) + 1);
      Result = TRUE;
    } else {
      break;
    }
  }
  *CoreCount = ProcessorCoreCount;
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Provides the range of Cores in a Processor which are in a Module.
 *
 * Cores are named uniquely in a processor, 0 to TotalCores.  Any module in the processor has
 * a set of those cores, named from LowCore to HighCore.
 *
 * @param[in]      Socket      Get a core range for the processor in this socket.
 * @param[in]      Module      Get a core range for this Module in the processor.
 * @param[out]     LowCore     The lowest Processor Core in the Module.
 * @param[out]     HighCore    The highest Processor Core in the Module.
 * @param[in]      StdHeader   Header for library and services.
 *
 * @retval     TRUE    A processor is present in the Socket and the Core Range is valid.
 * @retval     FALSE   The Socket does not have a Processor
 */
BOOLEAN
GetGivenModuleCoreRange (
  IN       UINT32            Socket,
  IN       UINT32            Module,
     OUT   UINT32            *LowCore,
     OUT   UINT32            *HighCore,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  SOCKET_DIE_TO_NODE_MAP  pSocketDieMap;
  LOCATE_HEAP_PTR  SocketDieHeapDataBlock;
  BOOLEAN Result;
  AGESA_STATUS Status;

  ASSERT (Socket < MAX_SOCKETS);
  ASSERT (Module < MAX_DIES);
  Result = FALSE;
  SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE;

  //  Get data block from heap
  Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader);
  pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr;
  ASSERT ((pSocketDieMap != NULL) && (Status == AGESA_SUCCESS));
  *LowCore = (*pSocketDieMap)[Socket][Module].LowCore;
  *HighCore = (*pSocketDieMap)[Socket][Module].HighCore;
  if ((*pSocketDieMap)[Socket][Module].Node != 0xFF) {
    Result = TRUE;
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Returns the current running core number.
 *
 * @param[out]     Core       The core id.
 * @param[in]      StdHeader  Header for library and services.
 *
 */
VOID
GetCurrentCore (
     OUT   UINT32 *Core,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  CPUID_DATA  CpuidDataStruct;
  UINT32      LocalApicId;
  UINT32      ApicIdCoreIdSize;
  CORE_ID_POSITION      InitApicIdCpuIdLo;
  CPU_SPECIFIC_SERVICES *FamilyServices;

  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader);
  ASSERT (FamilyServices != NULL);

  //  Read CPUID ebx[31:24] to get initial APICID
  LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuidDataStruct, StdHeader);
  LocalApicId = (CpuidDataStruct.EBX_Reg & 0xFF000000) >> 24;

  // Find the core ID size.
  LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuidDataStruct, StdHeader);
  ApicIdCoreIdSize = (CpuidDataStruct.ECX_Reg & 0x0000F000) >> 12;

  InitApicIdCpuIdLo = FamilyServices->CoreIdPositionInInitialApicId (FamilyServices, StdHeader);
  ASSERT (InitApicIdCpuIdLo < CoreIdPositionMax);

  // Now extract the core ID from the Apic ID by right justifying the id and masking off non-core Id bits.
  *Core = ((LocalApicId >> ((1 - (UINT32)InitApicIdCpuIdLo) * (MAX_CORE_ID_SIZE - ApicIdCoreIdSize))) &
             (MAX_CORE_ID_MASK >> (MAX_CORE_ID_SIZE - ApicIdCoreIdSize)));
}

/*---------------------------------------------------------------------------------------*/
/**
 * Returns current node, and core number.
 *
 * @param[out]     Node         The node id of the current core's node.
 * @param[out]     Core         The core id if the current core.
 * @param[in]      StdHeader    Config handle for library and services.
 *
 */
VOID
GetCurrentNodeAndCore (
     OUT   UINT32 *Node,
     OUT   UINT32 *Core,
  IN       AMD_CONFIG_PARAMS  *StdHeader
  )
{
  // Get Node Id
  GetCurrentNodeNum (Node, StdHeader);

  // Get Core Id
  GetCurrentCore (Core, StdHeader);
}

/*---------------------------------------------------------------------------------------*/
/**
 *  Is the current core a primary core of it's node?
 *
 *  @param[in]  StdHeader   Config handle for library and services.
 *
 *  @retval        TRUE  Is Primary Core
 *  @retval        FALSE Is not Primary Core
 *
 */
BOOLEAN
IsCurrentCorePrimary (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  BOOLEAN Result;
  UINT32 Core;
  UINT32 Socket;
  UINT32 Module;
  UINT32 PrimaryCore;
  UINT32 IgnoredCore;
  AGESA_STATUS IgnoredSts;

  Result = FALSE;

  IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts);
  GetGivenModuleCoreRange (Socket, Module, &PrimaryCore, &IgnoredCore, StdHeader);
  if (Core == PrimaryCore) {
    Result = TRUE;
  }
  return Result;
}


/*---------------------------------------------------------------------------------------*/
/**
 * Returns node id based on SocketId and ModuleId.
 *
 * @param[in]  SocketId       The socket to look up
 * @param[in]  ModuleId       The module in that socket
 * @param[out] NodeId         Provide the corresponding Node Id.
 * @param[in]  StdHeader   Handle of Header for calling lib functions and services.
 *
 * @retval     TRUE       The socket is populated
 * @retval     FALSE      The socket is not populated
 *
 */
BOOLEAN
GetNodeId (
  IN       UINT32  SocketId,
  IN       UINT32  ModuleId,
     OUT   UINT8   *NodeId,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  SOCKET_DIE_TO_NODE_MAP  pSocketDieMap;
  LOCATE_HEAP_PTR  SocketDieHeapDataBlock;
  BOOLEAN Result;
  AGESA_STATUS Status;

  Result = FALSE;
  SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE;

  //  Get data block from heap
  Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader);
  pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr;
  ASSERT ((pSocketDieMap != NULL) && (Status == AGESA_SUCCESS));
  *NodeId = (*pSocketDieMap)[SocketId][ModuleId].Node;
  if ((*pSocketDieMap)[SocketId][ModuleId].Node != 0xFF) {
    Result = TRUE;
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Get the cached AP Mailbox Info if available, or read the info from the hardware.
 *
 * Locate the known AP Mailbox Info Cache buffer in this core's local heap.  If it
 * doesn't exist, read the hardware to get the info.
 * This routine gets the main AP mailbox, not the system degree.
 *
 * @param[out]    ApMailboxInfo  Provide the info in this AP core's mailbox
 * @param[in]     StdHeader      Config handle for library and services.
 *
 */
VOID
GetApMailbox (
     OUT   UINT32               *ApMailboxInfo,
  IN       AMD_CONFIG_PARAMS    *StdHeader
  )
{
  AGESA_STATUS     Ignored;
  LOCATE_HEAP_PTR  LocalApMailboxCache;
  CPU_SPECIFIC_SERVICES *FamilyServices;
  AP_MAILBOXES     ApMailboxes;
  BOOLEAN IamBsp;

  IamBsp = IsBsp (StdHeader, &Ignored);
  LocalApMailboxCache.BufferHandle = LOCAL_AP_MAIL_BOX_CACHE_HANDLE;
  if (((StdHeader->HeapStatus == HEAP_LOCAL_CACHE) || IamBsp) &&
      (HeapLocateBuffer (&LocalApMailboxCache, StdHeader) == AGESA_SUCCESS)) {
    // If during HEAP_LOCAL_CACHE stage, we always try to get ApMailbox from heap
    // If we're not in HEAP_LOCAL_CACHE stage, only BSP can get ApMailbox from heap
    *ApMailboxInfo = ((AP_MAILBOXES *) LocalApMailboxCache.BufferPtr)->ApMailInfo.Info;
  } else if (!IamBsp) {
    // If this is an AP, the hardware register should be good.
    GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader);
    ASSERT (FamilyServices != NULL);
    FamilyServices->GetApMailboxFromHardware (FamilyServices, &ApMailboxes, StdHeader);
    *ApMailboxInfo = ApMailboxes.ApMailInfo.Info;
  } else {
    // This is the BSC.  The hardware mailbox has not been set up yet.
    ASSERT (FALSE);
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Cache the Ap Mailbox info in our local heap for later use.
 *
 * This enables us to use the info even after the mailbox register is initialized
 * with operational values.  Get all the AP mailboxes and keep them in one buffer.
 *
 * @param[in]     StdHeader   Config handle for library and services.
 *
 */
VOID
CacheApMailbox (
  IN       AMD_CONFIG_PARAMS    *StdHeader
  )
{
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  AP_MAILBOXES ApMailboxes;
  CPU_SPECIFIC_SERVICES *FamilyServices;

  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader);
  ASSERT (FamilyServices != NULL);

  // Get mailbox from hardware.
  FamilyServices->GetApMailboxFromHardware (FamilyServices, &ApMailboxes, StdHeader);

  // Allocate heap for the info
  AllocHeapParams.RequestedBufferSize = sizeof (AP_MAILBOXES);
  AllocHeapParams.BufferHandle = LOCAL_AP_MAIL_BOX_CACHE_HANDLE;
  AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
  if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
    *(AP_MAILBOXES *)AllocHeapParams.BufferPtr = ApMailboxes;
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * Compute the degree of the system.
 *
 * The degree of a system is the maximum degree of any node.  The degree of a node is the
 * number of nodes to which it is directly connected (not considering width or redundant
 * links).
 *
 * @param[in]     StdHeader            Config handle for library and services.
 *
 */
UINTN
GetSystemDegree (
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  AP_MAILBOXES *ApMailboxes;
  LOCATE_HEAP_PTR  LocalApMailboxCache;
  AGESA_STATUS Status;

  //  Get data block from heap
  LocalApMailboxCache.BufferHandle = LOCAL_AP_MAIL_BOX_CACHE_HANDLE;
  Status = HeapLocateBuffer (&LocalApMailboxCache, StdHeader);
  // non-Success handled by ASSERT not NULL below.
  ApMailboxes = (AP_MAILBOXES *)LocalApMailboxCache.BufferPtr;
  ASSERT ((ApMailboxes != NULL) && (Status == AGESA_SUCCESS));
  return ApMailboxes->ApMailExtInfo.Fields.SystemDegree;
}

/*---------------------------------------------------------------------------------------*/
/**
 *  Spins until the number of microseconds specified have
 *  expired regardless of CPU operational frequency.
 *
 *  @param[in]   Microseconds  Wait time in microseconds
 *  @param[in]   StdHeader     Header for library and services
 *
 */
VOID
WaitMicroseconds (
  IN       UINT32 Microseconds,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 TscRateInMhz;
  UINT64 NumberOfTicks;
  UINT64 InitialTsc;
  UINT64 CurrentTsc;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  LibAmdMsrRead (TSC, &InitialTsc, StdHeader);
  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetTscRate (FamilySpecificServices, &TscRateInMhz, StdHeader);
  NumberOfTicks = Microseconds * TscRateInMhz;
  do {
    LibAmdMsrRead (TSC, &CurrentTsc, StdHeader);
  } while ((CurrentTsc - InitialTsc) < NumberOfTicks);
}

/*---------------------------------------------------------------------------------------*/
/**
 *  A boolean function determine executed CPU is BSP core.
 *
 *  @param[in,out]   StdHeader        Header for library and services
 *  @param[out]      AgesaStatus      Aggregates AGESA_STATUS for external interface, Always Succeeds.
 *
 */
BOOLEAN
IsBsp (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader,
     OUT   AGESA_STATUS      *AgesaStatus
  )
{
  UINT64 MsrData;

  // Always Succeeds.
  *AgesaStatus = AGESA_SUCCESS;

  //  Read APIC_BASE register (0x1B), bit[8] returns 1 for BSP
  LibAmdMsrRead (MSR_APIC_BAR, &MsrData, StdHeader);
  if ((MsrData & BIT8) != 0 ) {
    return TRUE;
  } else {
    return FALSE;
  }

}

/*---------------------------------------------------------------------------------------*/
/**
 * Get the compute unit mapping algorithm.
 *
 * Look up the compute unit values for the current core's socket/module and find the matching
 * core pair map item.  This will tell us how to determine the core's status.
 *
 * @param[in]   StdHeader        Header for library and services
 *
 * @retval      AllCoresMapping  Each core is in a compute unit of its own.
 * @retval      EvenCoresMapping Even/Odd pairs of cores are in each compute unit.
 */
COMPUTE_UNIT_MAPPING
GetComputeUnitMapping (
  IN      AMD_CONFIG_PARAMS    *StdHeader
  )
{
  UINT32  CurrentCore;
  UINT32  Module;
  UINT32  Socket;
  UINT8   Enabled;
  UINT8   DualCore;
  AGESA_STATUS  IgnoredSts;
  SOCKET_DIE_TO_NODE_MAP  pSocketDieMap;
  LOCATE_HEAP_PTR  SocketDieHeapDataBlock;
  CPU_SPECIFIC_SERVICES *FamilyServices;
  CORE_PAIR_MAP *CorePairMap;
  COMPUTE_UNIT_MAPPING Result;

  // Invalid mapping, unless we find one.
  Result = MaxComputeUnitMapping;

  IdentifyCore (StdHeader, &Socket, &Module, &CurrentCore, &IgnoredSts);
  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader);
  ASSERT (FamilyServices != NULL);

  //  Get data block from heap
  SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE;
  IgnoredSts = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader);
  pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr;
  ASSERT ((pSocketDieMap != NULL) && (IgnoredSts == AGESA_SUCCESS));
  // Current Core's socket, module must be present.
  ASSERT ((*pSocketDieMap)[Socket][Module].Node != 0xFF);

  // Process compute unit info
  Enabled = (*pSocketDieMap)[Socket][Module].EnabledComputeUnits;
  DualCore = (*pSocketDieMap)[Socket][Module].DualCoreComputeUnits;
  CorePairMap = FamilyServices->CorePairMap;
  if ((Enabled != 0) && (CorePairMap != NULL)) {
    while (CorePairMap->Enabled != 0xFF) {
      if ((Enabled == CorePairMap->Enabled) && (DualCore == CorePairMap->DualCore)) {
        break;
      }
      CorePairMap++;
    }
    // The assert is for finding a processor configured in a way the core pair map doesn't support.
    ASSERT (CorePairMap->Enabled != 0xFF);
    Result = CorePairMap->Mapping;
  } else {
    // Families that don't have compute units act as though each core is in its own compute unit
    // and all cores are primary
    Result = AllCoresMapping;
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Is current core the primary core of its compute unit?
 *
 * Get the mapping algorithm and the current core number.  Selecting First/Last ordering for
 * primary @b ASSUMES cores are launched in ascending core number order.
 *
 * @param[in]   Selector         Select whether first or last core has the primary core role.
 * @param[in]   StdHeader        Header for library and services
 *
 * @retval       TRUE             This is the primary core of a compute unit.
 * @retval       FALSE            This is the second shared core of a compute unit.
 *
 */
BOOLEAN
IsCorePairPrimary (
  IN       COMPUTE_UNIT_PRIMARY_SELECTOR Selector,
  IN       AMD_CONFIG_PARAMS            *StdHeader
  )
{
  BOOLEAN Result;
  UINT32  CurrentCore;
  UINT32  Module;
  UINT32  Socket;
  AGESA_STATUS  IgnoredSts;

  IdentifyCore (StdHeader, &Socket, &Module, &CurrentCore, &IgnoredSts);

  Result = FALSE;
  switch (GetComputeUnitMapping (StdHeader)) {
  case AllCoresMapping:
    // All cores are primaries
    Result = TRUE;
    break;
  case EvenCoresMapping:
    // Even core numbers are first to execute, odd cores are last to execute
    if (Selector == FirstCoreIsComputeUnitPrimary) {
      Result = (BOOLEAN) ((CurrentCore & 1) == 0);
    } else {
      Result = (BOOLEAN) ((CurrentCore & 1) != 0);
    }
    break;
  default:
    ASSERT (FALSE);
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 * Are the two specified cores shared in a compute unit?
 *
 * Look up the compute unit values for the current core's socket/module and find the matching
 * core pair map item.  This will tell us how to determine the core's status.
 *
 * @param[in]   Socket           The processor in this socket is to be checked
 * @param[in]   Module           The processor in this module is to be checked
 * @param[in]   CoreA            One of the two cores to check
 * @param[in]   CoreB            The other core to be checked
 * @param[in]   StdHeader        Header for library and services
 *
 * @retval       TRUE            The cores are in the same compute unit.
 * @retval       FALSE           The cores are not in the same compute unit, or the processor does
 *                               not have compute units.
 *
 */
BOOLEAN
AreCoresPaired (
  IN       UINT32  Socket,
  IN       UINT32  Module,
  IN       UINT32  CoreA,
  IN       UINT32  CoreB,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  BOOLEAN Result;

  Result = FALSE;
  switch (GetComputeUnitMapping (StdHeader)) {
  case AllCoresMapping:
    // No cores are sharing a compute unit
    Result = FALSE;
    break;
  case EvenCoresMapping:
    // Even core numbers are paired with odd core numbers, n with n + 1
    if ((CoreA & 1) == 0) {
      Result = (BOOLEAN) (CoreA == (CoreB - 1));
    } else {
      Result = (BOOLEAN) (CoreA == (CoreB + 1));
    }
    break;
  default:
    ASSERT (FALSE);
  }
  return Result;
}

/*---------------------------------------------------------------------------------------*/
/**
 *
 * This routine programs the registers necessary to get the PCI MMIO mechanism
 * up and functioning.
 *
 * @param[in]      StdHeader               Pointer to structure containing the function call
 *                                         whose parameter structure is to be created, the
 *                                         allocation method, and a pointer to the newly
 *                                         created structure.
 *
 */
VOID
InitializePciMmio (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT8        EncodedSize;
  UINT64       MsrReg;

  // Make sure that Standard header is valid
  ASSERT (StdHeader != NULL);

  if ((UserOptions.CfgPciMmioAddress != 0) && (UserOptions.CfgPciMmioSize != 0)) {
    EncodedSize = LibAmdBitScanForward (UserOptions.CfgPciMmioSize);
    MsrReg = ((UserOptions.CfgPciMmioAddress | BIT0) | (EncodedSize << 2));
    LibAmdMsrWrite (MSR_MMIO_Cfg_Base, &MsrReg, StdHeader);
  }
}
