[coreboot-gerrit] New patch to review for coreboot: vendorcode/amd: Modify 0067F00 for binaryPI

Marc Jones (marc@marcjonesconsulting.com) gerrit at coreboot.org
Sun Oct 30 21:03:03 CET 2016


Marc Jones (marc at marcjonesconsulting.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17195

-gerrit

commit b8cbc1bf80e03c9e330e0e524e59c550c7f84a55
Author: Marshall Dawson <marshalldawson3rd at gmail.com>
Date:   Sat Oct 15 09:45:44 2016 -0600

    vendorcode/amd: Modify 0067F00 for binaryPI
    
    Make changes to the vendorcode files that allow them to work
    with the binaryPI.  This fixes various compile issues and
    establishes a common calling convention between coreboot and
    AGESA.
    
    Original-Signed-off-by: Marc Jones <marcj303 at gmail.com>
    Original-Signed-off-by: Marshall Dawson <marshalldawson3rd at gmail.com>
    (cherry picked from commit f7ea2785d70bd6813b5b4d315b064802251d9557)
    
    Change-Id: Ie36228476a9dbd7b83f95828ca9c7252cecd8ec8
    Signed-off-by: Marc Jones <marcj303 at gmail.com>
---
 src/vendorcode/amd/pi/00670F00/AGESA.h             |  10 +-
 src/vendorcode/amd/pi/00670F00/AMD.h               |  66 +-
 src/vendorcode/amd/pi/00670F00/Proc/CPU/Table.h    | 915 +++++++++++++++++++++
 .../pi/00670F00/Proc/CPU/cpuFamilyTranslation.c    | 442 ++++++++++
 .../pi/00670F00/Proc/CPU/cpuFamilyTranslation.h    | 861 +++++++++++++++++++
 .../amd/pi/00670F00/Proc/CPU/cpuServices.h         | 306 +++++++
 .../amd/pi/00670F00/Proc/Fch/Common/FchCommonCfg.h |  12 +-
 .../amd/pi/00670F00/Proc/Fch/Common/FchLib.c       |   4 +-
 .../amd/pi/00670F00/Proc/Fch/Common/FchPeLib.c     |  91 --
 .../pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c   |   6 +-
 .../pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.h   |   4 +-
 11 files changed, 2582 insertions(+), 135 deletions(-)

diff --git a/src/vendorcode/amd/pi/00670F00/AGESA.h b/src/vendorcode/amd/pi/00670F00/AGESA.h
index 311e876..ee9c629 100644
--- a/src/vendorcode/amd/pi/00670F00/AGESA.h
+++ b/src/vendorcode/amd/pi/00670F00/AGESA.h
@@ -610,8 +610,8 @@ typedef struct {
                                                            * @li @b Bit31 - last descriptor in topology
                                                            */
   IN       UINT32               SocketId;                 ///< Socket Id
-  IN       PCIe_PORT_DESCRIPTOR *PciePortList;            ///< Pointer to array of PCIe port descriptors or NULL (Last element of array must be terminated with DESCRIPTOR_TERMINATE_LIST).
-  IN       PCIe_DDI_DESCRIPTOR  *DdiLinkList;             ///< Pointer to array DDI link descriptors (Last element of array must be terminated with DESCRIPTOR_TERMINATE_LIST).
+  IN       const PCIe_PORT_DESCRIPTOR *PciePortList;      ///< Pointer to array of PCIe port descriptors or NULL (Last element of array must be terminated with DESCRIPTOR_TERMINATE_LIST).
+  IN       const PCIe_DDI_DESCRIPTOR  *DdiLinkList;       ///< Pointer to array DDI link descriptors (Last element of array must be terminated with DESCRIPTOR_TERMINATE_LIST).
   IN       VOID                 *Reserved;                ///< Reserved for future use
 } PCIe_COMPLEX_DESCRIPTOR;
 
@@ -829,7 +829,7 @@ mInitOffsetCancellation, mDFEControl, mLEQControl, mDynamicOffsetCalibration, mF
 {mPortPresent, mChannelType, mDevAddress, mDevFunction, mMaxLinkSpeed, mAspm, mHotplug, mResetId, {0, mMaxLinkCap, 0, mClkPmSupport}, {0, 0, 0}, EndpointDetect, \
 {mInitOffsetCancellation, mDFEControl, mLEQControl, mDynamicOffsetCalibration, mFOMCalculation, mPIOffsetCalibration}}
 #define  PCIE_DDI_DATA_INITIALIZER(mConnectorType, mAuxIndex, mHpdIndex ) \
-{mConnectorType, mAuxIndex, mHpdIndex, {0, 0}, 0, 0}
+{mConnectorType, mAuxIndex, mHpdIndex, {{0}, {0}}, 0, 0}
 #define  PCIE_DDI_DATA_INITIALIZER_V1(mConnectorType, mAuxIndex, mHpdIndex, mMapping0, mMapping1, mPNInversion) \
 {mConnectorType, mAuxIndex, mHpdIndex, {mMapping0, mMapping1}, mPNInversion, 0}
 #define  PCIE_DDI_DATA_INITIALIZER_V2(mConnectorType, mAuxIndex, mHpdIndex, mMapping0, mMapping1, mPNInversion, mFlags) \
@@ -913,7 +913,7 @@ typedef union _DISPLAY_MISC_CONTROL {
 /// HD Audio Codec table list
 typedef struct _CODEC_VERB_TABLE_LIST {
   IN  UINT32           CodecId;             ///<  CodecID - Codec ID
-  IN  UINT32           CodecTablePtr;       ///<  CodecTablePtr - Codec table pointer
+  IN  CONST VOID *     CodecTablePtr;       ///<  CodecTablePtr - Codec table pointer
 } CODEC_VERB_TABLE_LIST;
 
 /// POST Configuration settings for GNB.
@@ -1019,7 +1019,7 @@ typedef struct {
 
 /// GNB configuration info
 typedef struct {
-  IN       PCIe_COMPLEX_DESCRIPTOR  *PcieComplexList;  /**< Pointer to array of structures describe PCIe topology on each processor package or NULL.
+  IN       const PCIe_COMPLEX_DESCRIPTOR  *PcieComplexList;  /**< Pointer to array of structures describe PCIe topology on each processor package or NULL.
                                                         * Last element of array must be terminated with DESCRIPTOR_TERMINATE_LIST
                                                         * Example of topology definition for single socket system:
                                                         * @code
diff --git a/src/vendorcode/amd/pi/00670F00/AMD.h b/src/vendorcode/amd/pi/00670F00/AMD.h
index a111cee..003ac0e 100644
--- a/src/vendorcode/amd/pi/00670F00/AMD.h
+++ b/src/vendorcode/amd/pi/00670F00/AMD.h
@@ -40,12 +40,15 @@
  *
  ***************************************************************************/
 
-
 #ifndef _AMD_H_
 #define _AMD_H_
 
+#define Int16FromChar(a,b) (UINT16)((a) << 0 | (b) << 8)
+#define Int32FromChar(a,b,c,d) (UINT32)((a) << 0 | (b) << 8 | (c) << 16 | (d) << 24)
+#define Int64FromChar(a,b,c,d,e,f,g,h) ((UINT64)(Int32FromChar(a,b,c,d)<<32) | (UINT64)Int32FromChar(e,f,g,h))
+
 #define AGESA_REVISION  "Arch2008"
-#define AGESA_ID        "AGESA"
+#define AGESA_ID        {'A', 'G', 'E', 'S', 'A', 0x00, 0x00, 0x00}
 
 //
 //
@@ -53,7 +56,8 @@
 //
 //
 #define LAST_ENTRY          0xFFFFFFFFul
-#define IMAGE_SIGNATURE     'DMA$'
+#define IMAGE_SIGNATURE     Int32FromChar ('$', 'A', 'M', 'D')
+#define MODULE_SIGNATURE    Int32FromChar ('$', 'M', 'O', 'D')
 #define IOCF8 0xCF8
 #define IOCFC 0xCFC
 
@@ -124,27 +128,37 @@ typedef enum ACCESS_WIDTH {
 /// AGESA struct name
 typedef enum {
   // AGESA BASIC FUNCTIONS
-  AMD_INIT_RECOVERY = 0x00020000,                           ///< AmdInitRecovery entry point handle
-  AMD_CREATE_STRUCT,                                        ///< AmdCreateStruct handle
-  AMD_INIT_EARLY,                                           ///< AmdInitEarly entry point handle
-  AMD_INIT_ENV,                                             ///< AmdInitEnv entry point handle
-  AMD_INIT_LATE,                                            ///< AmdInitLate entry point handle
-  AMD_INIT_MID,                                             ///< AmdInitMid entry point handle
-  AMD_INIT_POST,                                            ///< AmdInitPost entry point handle
-  AMD_INIT_RESET,                                           ///< AmdInitReset entry point handle
-  AMD_INIT_RESUME,                                          ///< AmdInitResume entry point handle
-  AMD_RELEASE_STRUCT,                                       ///< AmdReleaseStruct handle
-  AMD_S3LATE_RESTORE,                                       ///< AmdS3LateRestore entry point handle
-  AMD_GET_APIC_ID,                                          ///< AmdGetApicId entry point handle
-  AMD_GET_PCI_ADDRESS,                                      ///< AmdGetPciAddress entry point handle
-  AMD_IDENTIFY_CORE,                                        ///< AmdIdentifyCore general service handle
-  AMD_READ_EVENT_LOG,                                       ///< AmdReadEventLog general service handle
-  AMD_GET_EXECACHE_SIZE,                                    ///< AmdGetAvailableExeCacheSize general service handle
-  AMD_LATE_RUN_AP_TASK,                                     ///< AmdLateRunApTask entry point handle
-  AMD_IDENTIFY_DIMMS,                                       ///< AmdIdentifyDimm general service handle
-  AMD_GET_2D_DATA_EYE,                                      ///< AmdGet2DDataEye general service handle
-  AMD_S3FINAL_RESTORE,                                      ///< AmdS3FinalRestore entry point handle
-  AMD_INIT_RTB                                              ///< AmdInitRtb entry point handle
+  AMD_INIT_RECOVERY          = 0x00021000,                  ///< AmdInitRecovery entry point handle
+  AMD_CREATE_STRUCT          = 0x00022000,                  ///< AmdCreateStruct handle
+  AMD_INIT_EARLY             = 0x00023000,                  ///< AmdInitEarly entry point handle
+  AMD_INIT_ENV               = 0x00024000,                  ///< AmdInitEnv entry point handle
+  AMD_INIT_LATE              = 0x00025000,                  ///< AmdInitLate entry point handle
+  AMD_INIT_MID               = 0x00026000,                  ///< AmdInitMid entry point handle
+  AMD_INIT_POST              = 0x00027000,                  ///< AmdInitPost entry point handle
+  AMD_INIT_RESET             = 0x00028000,                  ///< AmdInitReset entry point handle
+  AMD_INIT_RESUME            = 0x00029000,                  ///< AmdInitResume entry point handle
+  AMD_RELEASE_STRUCT         = 0x0002A000,                  ///< AmdReleaseStruct handle
+  AMD_S3LATE_RESTORE         = 0x0002B000,                  ///< AmdS3LateRestore entry point handle
+  AMD_GET_APIC_ID            = 0x0002C000,                  ///< AmdGetApicId entry point handle
+  AMD_GET_PCI_ADDRESS        = 0x0002D000,                  ///< AmdGetPciAddress entry point handle
+  AMD_IDENTIFY_CORE          = 0x0002E000,                  ///< AmdIdentifyCore general service handle
+  AMD_READ_EVENT_LOG         = 0x0002F000,                  ///< AmdReadEventLog general service handle
+  AMD_GET_EXECACHE_SIZE      = 0x00030000,                  ///< AmdGetAvailableExeCacheSize general service handle
+  AMD_LATE_RUN_AP_TASK       = 0x00031000,                  ///< AmdLateRunApTask entry point handle
+  AMD_IDENTIFY_DIMMS         = 0x00032000,                  ///< AmdIdentifyDimm general service handle
+  AMD_GET_2D_DATA_EYE        = 0x00033000,                  ///< AmdGet2DDataEye general service handle
+  AMD_S3FINAL_RESTORE        = 0x00034000,                  ///< AmdS3FinalRestore entry point handle
+  AMD_INIT_RTB               = 0x00035000,                  ///< AmdInitRtb entry point handle
+  AMD_HEAP_ALLOCATE_BUFFER   = 0x00038000,
+  AMD_HEAP_DEALLOCATE_BUFFER = 0x00039000,
+  FCH_INIT_RESET             = 0x00040000,
+  FCH_INIT_ENV               = 0x00041000,
+  FCH_INIT_MID               = 0x00042000,
+  FCH_INIT_LATE              = 0x00043000,
+  FCH_INIT_S3_EARLY_RESTORE  = 0x00044000,
+  FCH_INIT_S3_LATE_RESTORE   = 0x00045000,
+  AMD_SET_VALUE              = 0x00081000,
+  AMD_GET_VALUE              = 0x00082000
 } AGESA_STRUCT_NAME;
 
   /*  ResetType constant values */
@@ -159,9 +173,9 @@ typedef enum {
 /// The standard header for all AGESA services.
 /// For internal AGESA naming conventions, see @ref amdconfigparamname .
 typedef struct {
-  IN       UINT32          ImageBasePtr;     ///< The AGESA Image base address.
+  IN       VOID *          ImageBasePtr;     ///< The AGESA Image base address.
   IN       UINT32          Func;             ///< The service desired
-  IN       UINT32          AltImageBasePtr;  ///< Alternate Image location
+  IN       VOID *          AltImageBasePtr;  ///< Alternate Image location
   IN       CALLOUT_ENTRY   CalloutPtr;       ///< For Callout from AGESA
   IN       UINT8           HeapStatus;       ///< For heap status from boot time slide.
   IN       UINT64          HeapBasePtr;      ///< Location of the heap
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/CPU/Table.h b/src/vendorcode/amd/pi/00670F00/Proc/CPU/Table.h
new file mode 100644
index 0000000..fe3b3c0
--- /dev/null
+++ b/src/vendorcode/amd/pi/00670F00/Proc/CPU/Table.h
@@ -0,0 +1,915 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD CPU Register Table Related Functions
+ *
+ * Contains code to initialize the CPU MSRs and PCI registers with BKDG recommended values
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project:      AGESA
+ * @e sub-project:  CPU
+ * @e \$Revision$   @e \$Date$
+ *
+ */
+ /*****************************************************************************
+ *
+ * Copyright (c) 2008 - 2016, 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.
+ *
+ ***************************************************************************/
+
+#ifndef _CPU_TABLE_H_
+#define _CPU_TABLE_H_
+
+
+/**
+ * @page regtableimpl Register Table Implementation Guide
+ *
+ * This register table implementation is modular and extensible, so that support code as
+ * well as table data can be family specific or built out if not needed, and new types
+ * of table entries can be added with low overhead.  Because many aspects are now generic,
+ * there can be common implementations for CPU revision and platform feature matching and for
+ * finding and iterating tables.
+ *
+ * @par Adding a new table entry type.
+ *
+ * To add a new table entry type follow these steps.
+ * <ul>
+ * <li>  Add a member to the enum TABLE_ENTRY_TYPE which is a descriptive name of the entry's purpose
+ *       or distinct characteristics.
+ *
+ * <li>  Create an entry data struct with the customized data needed.  For example, custom register designations,
+ *       data and mask sizes, or feature comparisons.  Name your struct by adding "_" and upper-casing the enum name
+ *       and adding "_TYPE_ENTRY_DATA" at the end.
+ *
+ * <li>  Add the entry data type as a member of the TABLE_ENTRY_DATA union.  Be aware of the size of your
+ *       entry data struct; all table entries in all tables will share any size increase you introduce!
+ *
+ * <li>  If your data entry contains any member types except for UINT32, you can't use the generic first union member
+ *       for the initializers that make up the actual tables (it's just UINT32's). The generic MSR entry is
+ *       an example. Follow the steps below:
+ *
+ *       <ul>
+ *       <li>  Make a union which has your entry data type as the first member.  Use TABLE_ENTRY_DATA as the
+ *             second member.  Name this with your register followed by "_DATA_INITIALIZER".
+ *
+ *       <li>  Make a copy of TABLE_ENTRY_FIELDS, and rename it your register "_TYPE_ENTRY_INITIALIZER".  Rename
+ *             the TABLE_ENTRY_DATA member of that struct to have the type you created in the previous step.
+ *             This type can be used to declare an array of entries and make a register table in some family specific
+ *             file.
+ *       </ul>
+ *
+ * <li>  Add the descriptor that will link table entries of your data type to an implementation for it.
+ *       <ul>
+ *       <li>  Find the options file which instantiates the CPU_SPECIFIC_SERVICES for each logical model that will
+ *             support the new entry type.
+ *
+ *       <li> From there find the instantiation of its TABLE_ENTRY_TYPE_DESCRIPTOR.  Add a descriptor to the
+ *            to the list for your new type.  Provide the name of a function which will implement the
+ *            entry data.  The function name should reflect that it implements the action for the entry type.
+ *            The function must be an instance of F_DO_TABLE_ENTRY.
+ *       </ul>
+ *
+ * <li>  Implement the function for your entry type data.  (If parts of it are family specific add methods to
+ *       CPU_SPECIFIC_SERVICES for that and implement them for each family or model required.)  @n
+ *       The definition of the function must conform to F_DO_TABLE_ENTRY.
+ *       In the function preamble, include a cross reference to the entry enum:
+ *       @code
+ *       *
+ *       * @TableEntryTypeMethod{::MyRegister}
+ *       *
+ *       @endcode
+ *
+ * </ul>
+ *
+ * @par  Adding a new Register Table
+ *
+ * To add a new register table for a logical CPU model follow the steps below.
+ *
+ * <ul>
+ * <li>  Find the options file which instantiates the CPU_SPECIFIC_SERVICES for the logical model that
+ *       should include the table.
+ *
+ * <li>  From there find the instantiation of its REGISTER_TABLE list. Add the name of the new register table.
+ * </ul>
+ *
+ */
+
+/*------------------------------------------------------------------------------------------*/
+/*
+ * Define the supported table entries.
+ */
+/*------------------------------------------------------------------------------------------*/
+
+/**
+ * These are the available types of table entries.
+ *
+ * Each type corresponds to:
+ * - a semantics for the type specific data, for example semantics for a Register value,
+ * Data value, and Mask value.
+ * - optionally, including a method for type specific matching criteria
+ * - a method for writing the desired update to the hardware.
+ *
+ * All types share in common a method to match CPU Family and Model and a method to match
+ * platform feature set.
+ *
+ * N O T E: We use UINT16 for storing table entry type
+ */
+typedef enum {
+  MsrRegister,                 ///< Processor MSR registers.
+  PciRegister,                 ///< Processor Config Space registers.
+  FamSpecificWorkaround,       ///< Processor Family Specific Workarounds which are @b not practical using the other types.
+  ProfileFixup,                ///< Processor Performance Profile fixups to PCI Config Registers.
+  CoreCountsPciRegister,       ///< Processor PCI Config Registers which depend on core counts.
+  CompUnitCountsPciRegister,   ///< Processor PCI Config Registers which depend on compute unit counts.
+  CompUnitCountsMsr,           ///< Processor MSRs which depend on compute unit counts.
+  CpuRevPciRegister,           ///< Processor PCI Config Registers which depend on family / revision.
+  CpuRevMsr,                   ///< Processor MSR which depend on family / revision.
+  CpuRevFamSpecificWorkaround, ///< Processor Family Specific Workarounds which depend on family / revision.
+  SmuIndexReg,                 ///< SMU index data registers.
+  ProfileFixupSmuIndexReg,     ///< Performance Profile fixups to SMU index data registers.
+  CopyBitField,                ///< Copy bitfield from register A to register B
+  TableEntryTypeMax,           ///< Not a valid entry type, use for limit checking.
+  TableTerminator = 0xFFFF     ///< A signature to indicate end to Jam table.
+} TABLE_ENTRY_TYPE;
+
+/*------------------------------------------------------------------------------------------*/
+/*
+ * Useful types and defines: Selectors, Platform Features, and type specific features.
+ */
+/*------------------------------------------------------------------------------------------*/
+
+/**
+ * Select tables for the current core.
+ *
+ * This allows more efficient register table processing, by allowing cores to skip
+ * redundantly setting PCI registers, for example.  This feature is not intended to
+ * be relied on for function:  it is valid to have a single register table with all settings
+ * processed by every core; it's just slower.
+ *
+ */
+typedef enum {
+  AllCores,                   ///< Select only tables which apply to all cores.
+  ComputeUnitPrimary,         ///< Select tables which apply to the primary core of a compute unit (SharedC, SharedNc).
+  PrimaryCores,               ///< Select tables which apply to primary cores.
+  BscCore,                    ///< Select tables which apply to the boot core.
+  TableCoreSelectorMax        ///< Not a valid selector, use for limit checking.
+} TABLE_CORE_SELECTOR;
+
+/**
+ * Possible time points at which register tables can be processed.
+ *
+ */
+typedef enum {
+  AmdRegisterTableTpBeforeApLaunch,     ///< Cpu code just prior to launching APs.
+  AmdRegisterTableTpAfterApLaunch,      ///< Cpu code just after all APs have been launched.
+  AmdRegisterTableTpBeforeApLaunchSecureS3, ///< Cpu code just prior to launching APs for secure S3
+  AmdRegisterTableTpAfterApLaunchSecureS3, ///< Cpu code just after all APs have been launched for secure S3
+  MaxAmdRegisterTableTps                ///< Not a valid time point, use for limit checking.
+} REGISTER_TABLE_TIME_POINT;
+
+//----------------------------------------------------------------------------
+//                         CPU PERFORM EARLY INIT ON CORE
+//
+//----------------------------------------------------------------------------
+/// Flag definition.
+
+// Condition
+#define PERFORM_EARLY_WARM_RESET    0x1          // bit  0 --- the related function needs to be run if it's warm reset
+#define PERFORM_EARLY_COLD_BOOT     0x2          // bit  1 --- the related function needs to be run if it's cold boot
+
+#define PERFORM_EARLY_ANY_CONDITION (PERFORM_EARLY_WARM_RESET | PERFORM_EARLY_COLD_BOOT)
+
+// Initializer bit pattern values for platform features.
+// Keep in synch with the PLATFORM_FEATURES struct!
+
+// The 5 control flow modes.
+#define AMD_PF_NFCM           BIT0
+#define AMD_PF_UMA            BIT1    // UMA_DR
+#define AMD_PF_UMA_IFCM       BIT2
+#define AMD_PF_IFCM           BIT3
+#define AMD_PF_IOMMU          BIT4
+// Degree of HT connectivity possible.
+#define AMD_PF_SINGLE_LINK    BIT5
+#define AMD_PF_MULTI_LINK     BIT6
+// For some legacy MSRs, define a couple core count bits.  Do not continue adding
+// core counts to the platform feats, if you need more than this design a table entry type.
+// Here, provide exactly 1, exactly 2, or anything else.
+#define AMD_PF_SINGLE_CORE    BIT7
+#define AMD_PF_DUAL_CORE      BIT8
+#define AMD_PF_MULTI_CORE     BIT9
+
+// Not a platform type, but treat all others as AND
+#define AMD_PF_AND            BIT31
+
+#define AMD_PF_ALL    (AMD_PF_NFCM          | \
+                       AMD_PF_UMA           | \
+                       AMD_PF_UMA_IFCM      | \
+                       AMD_PF_IFCM          | \
+                       AMD_PF_IOMMU         | \
+                       AMD_PF_SINGLE_LINK   | \
+                       AMD_PF_MULTI_LINK    | \
+                       AMD_PF_SINGLE_CORE   | \
+                       AMD_PF_DUAL_CORE     | \
+                       AMD_PF_MULTI_CORE)
+// Do not include AMD_PF_AND in AMD_PF_ALL !
+
+/**
+ * The current platform features.
+ *
+ * Keep this in sync with defines above that are used in the initializers!
+ *
+ * The comments with the bit number are useful for the computing the reserved member size, but
+ * do not write code that assumes you know what bit number one of these members is.
+ *
+ * These platform features are standard for all logical families and models.
+ */
+typedef struct {
+  UINT32          PlatformNfcm:1;             ///< BIT_0 Normal Flow Control Mode.
+  UINT32          PlatformUma:1;              ///< BIT_1 UMA (Display Refresh) Flow Control.
+  UINT32          PlatformUmaIfcm:1;          ///< BIT_2 UMA using Isochronous Flow Control.
+  UINT32          PlatformIfcm:1;             ///< BIT_3 Isochronous Flow Control Mode (not UMA).
+  UINT32          PlatformIommu:1;            ///< BIT_4 IOMMU (a special case Isochronous mode).
+  UINT32          PlatformSingleLink:1;       ///< BIT_5 The processor is in a package which implements only a single HT Link.
+  UINT32          PlatformMultiLink:1;        ///< BIT_6 The processor is in a package which implements more than one HT Link.
+  UINT32          PlatformSingleCore:1;       ///< BIT_7 Single Core processor, for legacy entries.
+  UINT32          PlatformDualCore:1;         ///< BIT_8 Dual Core processor, for legacy entries.
+  UINT32          PlatformMultiCore:1;        ///< BIT_9 More than dual Core processor, for legacy entries.
+  UINT32          :(30 - 9);                  ///< The possibilities are (not quite) endless.
+  UINT32          AndPlatformFeats:1;         ///< BIT_31
+} PLATFORM_FEATURES;
+
+/**
+ * Platform Features
+ */
+typedef union {
+  UINT32            PlatformValue;            ///< Describe Platform Features in UINT32.
+  ///< This one goes first, because then initializers use it automatically for the union.
+  PLATFORM_FEATURES PlatformFeatures;         ///< Describe Platform Features in structure
+} PLATFORM_FEATS;
+
+// Initializer bit patterns for PERFORMANCE_PROFILE_FEATS.
+#define PERFORMANCE_REFRESH_REQUEST_32B       BIT0
+#define PERFORMANCE_L3_CACHE                  BIT1
+#define PERFORMANCE_NO_L3_CACHE               BIT2
+#define PERFORMANCE_MCT_ISOC_VARIABLE         BIT3
+#define PERFORMANCE_IS_WARM_RESET             BIT4
+#define PERFORMANCE_VRM_HIGH_SPEED_ENABLE     BIT5
+#define PERFORMANCE_NB_PSTATES_ENABLE         BIT6
+#define PERFORMANCE_AND                       BIT31
+
+#define PERFORMANCE_PROFILE_ALL   (PERFORMANCE_REFRESH_REQUEST_32B | \
+                                   PERFORMANCE_L3_CACHE            | \
+                                   PERFORMANCE_NO_L3_CACHE         | \
+                                   PERFORMANCE_MCT_ISOC_VARIABLE   | \
+                                   PERFORMANCE_IS_WARM_RESET       | \
+                                   PERFORMANCE_VRM_HIGH_SPEED_ENABLE | \
+                                   PERFORMANCE_NB_PSTATES_ENABLE)
+
+/**
+ * Performance Profile specific Type Features.
+ *
+ * Register settings for the different control flow modes can have additional dependencies
+ */
+typedef struct {
+  UINT32       RefreshRequest32Byte:1;         ///< BIT_0.   Display Refresh Requests use 32 bytes (32BE).
+  UINT32       L3Cache:1;                      ///< BIT_1    L3 Cache is present.
+  UINT32       NoL3Cache:1;                    ///< BIT_2    L3 Cache is NOT present.
+  UINT32       MctIsocVariable:1;              ///< BIT_3    Mct Isoc Read Priority set to variable.
+  UINT32       IsWarmReset:1;                  ///< BIT_4    This boot is on a warm reset, cold reset pass is already completed.
+  UINT32       VrmHighSpeed:1;                 ///< BIT_5    Select high speed VRM.
+  UINT32       NbPstates:1;                    ///< BIT_6    Northbridge PStates are enabled
+  UINT32       :(30 - 6);                      ///< available for future expansion.
+  UINT32       AndPerformanceFeats:1;          ///< BIT_31.  AND other selected features.
+} PERFORMANCE_PROFILE_FEATURES;
+
+/**
+ * Performance Profile features.
+ */
+typedef union {
+  UINT32                        PerformanceProfileValue;     ///< Initializer value.
+  PERFORMANCE_PROFILE_FEATURES  PerformanceProfileFeatures;  ///< The performance profile features.
+} PERFORMANCE_PROFILE_FEATS;
+
+// Initializer Values for Package Type
+#define PACKAGE_TYPE_ALL              0XFFFF       ///< Package Type apply all packages
+
+// Core Range Initializer values.
+#define COUNT_RANGE_LOW            0ul
+#define COUNT_RANGE_HIGH           0xFFul
+
+// A count range matching none is often useful as the second range, matching will then be
+// based on the first range.  A count range all is provided as a first range for default settings.
+#define COUNT_RANGE_NONE           ((((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH)) << 16)
+#define COUNT_RANGE_ALL            (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_LOW))
+#define IGNORE_FREQ_0              (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH))
+#define IGNORE_PROCESSOR_0         (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH))
+
+#define CORE_RANGE_0(min, max)            ((((UINT32)(max)) << 8) | (UINT32)(min))
+#define CORE_RANGE_1(min, max)            (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
+#define PROCESSOR_RANGE_0(min, max)       ((((UINT32)(max)) << 8) | (UINT32)(min))
+#define PROCESSOR_RANGE_1(min, max)       (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
+#define DEGREE_RANGE_0(min, max)          ((((UINT32)(max)) << 8) | (UINT32)(min))
+#define DEGREE_RANGE_1(min, max)          (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
+#define FREQ_RANGE_0(min, max)            ((((UINT32)(max)) << 8) | (UINT32)(min))
+#define FREQ_RANGE_1(min, max)            (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
+#define COMPUTE_UNIT_RANGE_0(min, max)    ((((UINT32)(max)) << 8) | (UINT32)(min))
+#define COMPUTE_UNIT_RANGE_1(min, max)    (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
+
+/**
+ * Count Range Feature, two count ranges for core counts, processor counts, or node counts.
+ */
+typedef struct {
+  UINT32       Range0Min:8;           ///< The minimum of the first count range.
+  UINT32       Range0Max:8;           ///< The maximum of the first count range.
+  UINT32       Range1Min:8;           ///< The minimum of the second count range.
+  UINT32       Range1Max:8;           ///< The maximum of the second count range.
+} COUNT_RANGE_FEATURE;
+
+/**
+ * Core Count Ranges for table data.
+ *
+ * Provide a pair of core count ranges. If the actual core count is included in either range (OR),
+ * the feature should be considered a match.
+ */
+typedef union {
+  UINT32       CoreRangeValue;          ///< Initializer value.
+  COUNT_RANGE_FEATURE CoreRanges;       ///< The Core Counts.
+} CORE_COUNT_RANGES;
+
+/**
+ * Compute unit count ranges for table data.
+ *
+ * Provide a pair of compute unit count ranges. If the actual counts are included in either ranges (OR),
+ * the feature should be considered a match.
+ */
+typedef union {
+  UINT32    ComputeUnitRangeValue;                ///< Initializer value.
+  COUNT_RANGE_FEATURE ComputeUnitRanges;          ///< The Processor and Node Counts.
+} COMPUTE_UNIT_COUNTS;
+
+/*------------------------------------------------------------------------------------------*/
+/*
+ * The specific data for each table entry.
+ */
+/*------------------------------------------------------------------------------------------*/
+#define BSU8(u8)      ((UINT8) (u8)  & 0xFF)
+#define BSU16(u16)    ((UINT16) (u16) & 0xFF), (((UINT16) (u16) >> 8) & 0xFF)
+#define BSU32(u32)    ((UINT32) (u32) & 0xFF), (((UINT32) (u32) >> 8) & 0xFF), (((UINT32) (u32) >> 16) & 0xFF), (((UINT32) (u32) >> 24) & 0xFF)
+#define BSU64(u64)    ((UINT64) (u64) & 0xFF), (((UINT64) (u64) >> 8) & 0xFF), (((UINT64) (u64) >> 16) & 0xFF), (((UINT64) (u64) >> 24) & 0xFF), \
+                      (((UINT64) (u64) >> 32) & 0xFF), (((UINT64) (u64) >> 40) & 0xFF), (((UINT64) (u64) >> 48) & 0xFF), (((UINT64) (u64) >> 56) & 0xFF)
+
+#define MAKE_ENTRY_TYPE(Type)                      BSU16 (Type)
+#define MAKE_PERFORMANCE_PROFILE_FEATS(TypeFeats)  BSU32 (TypeFeats)
+#define MAKE_CORE_COUNT_RANGES(CoreCounts)         BSU32 (CoreCounts)
+#define MAKE_COMPUTE_UNIT_COUNTS(CUCounts)         BSU32 (CUCounts)
+#define MAKE_CPU_LOGICAL_ID(Family, Revision)      BSU16 (Family), BSU16 (Revision)
+#define MAKE_TABLE_TERMINATOR BSU16 (TableTerminator)
+
+#define NUMBER_OF_TABLE_ENTRIES(Table) ((sizeof (Table) / sizeof (Table[0])) - 1)
+
+/**
+ * Table Entry Data for MSR Registers.
+ *
+ * Apply data to register after mask, for MSRs.
+ */
+typedef struct {
+  UINT32  Address;                    ///< MSR address
+  UINT64  Data;                       ///< Data to set in the MSR
+  UINT64  Mask;                       ///< Mask to be applied to the MSR. Set every bit of all updated fields.
+} MSR_TYPE_ENTRY_DATA;
+#define MAKE_MSR_DATA(Address, Data, Mask) BSU32 (Address), BSU64 (Data), BSU64 (Mask)
+#define MAKE_MSR_ENTRY(Address, Data, Mask) MAKE_ENTRY_TYPE (MsrRegister), MAKE_MSR_DATA(Address, Data, Mask)
+
+/**
+ * Table Entry Data for PCI Registers.
+ *
+ * Apply data to register after mask, for PCI Config registers.
+ */
+typedef struct {
+  PCI_ADDR  Address;                  ///< Address should contain Function, Offset only.  It will apply to all CPUs
+  UINT32    Data;                     ///< Data to be written into PCI device
+  UINT32    Mask;                     ///< Mask to be used before data write. Set every bit of all updated fields.
+} PCI_TYPE_ENTRY_DATA;
+#define MAKE_PCI_DATA(Address, Data, Mask) BSU32 (Address), BSU32 (Data), BSU32 (Mask)
+#define MAKE_PCI_ENTRY(Address, Data, Mask) MAKE_ENTRY_TYPE (PciRegister), MAKE_PCI_DATA(Address, Data, Mask)
+
+/**
+ * Table Entry Data for Profile Fixup Registers.
+ *
+ * If TypeFeats matches current config, apply data to register after mask for PCI Config registers.
+ */
+typedef struct {
+  PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features.
+  PCI_TYPE_ENTRY_DATA PciEntry;        ///< The PCI Register entry data.
+} PROFILE_FIXUP_TYPE_ENTRY_DATA;
+#define MAKE_PROFILE_FIXUP_ENTRY(TypeFeats, Address, Data, Mask) MAKE_ENTRY_TYPE (ProfileFixup), MAKE_PERFORMANCE_PROFILE_FEATS (TypeFeats), MAKE_PCI_DATA (Address, Data, Mask)
+
+/**
+ * Core Count dependent PCI registers.
+ *
+ */
+typedef struct {
+  PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features.
+  CORE_COUNT_RANGES CoreCounts;        ///< Specify up to two core count ranges to match.
+  PCI_TYPE_ENTRY_DATA PciEntry;        ///< The PCI Register entry data.
+} CORE_COUNTS_PCI_TYPE_ENTRY_DATA;
+#define MAKE_CORE_COUNTS_PCI_ENTRY(TypeFeats, CoreCounts, Address, Data, Mask) MAKE_ENTRY_TYPE (CoreCountsPciRegister), MAKE_PERFORMANCE_PROFILE_FEATS (TypeFeats), MAKE_CORE_COUNT_RANGES (CoreCounts), MAKE_PCI_DATA (Address, Data, Mask)
+
+/**
+ * Compute Unit Count dependent PCI registers.
+ *
+ */
+typedef struct {
+  PERFORMANCE_PROFILE_FEATS TypeFeats;         ///< Profile Fixup Features.
+  COMPUTE_UNIT_COUNTS       ComputeUnitCounts; ///< Specify a compute unit count range.
+  PCI_TYPE_ENTRY_DATA       PciEntry;          ///< The PCI Register entry data.
+} COMPUTE_UNIT_COUNTS_PCI_TYPE_ENTRY_DATA;
+#define MAKE_COMPUTE_UNIT_COUNTS_PCI_ENTRY(TypeFeats, CUCounts, Address, Data, Mask) MAKE_ENTRY_TYPE (CompUnitCountsPciRegister), MAKE_PERFORMANCE_PROFILE_FEATS (TypeFeats), MAKE_COMPUTE_UNIT_COUNTS (CUCounts), MAKE_PCI_DATA (Address, Data, Mask)
+
+/**
+ * Compute Unit Count dependent MSR registers.
+ *
+ */
+typedef struct {
+  COMPUTE_UNIT_COUNTS       ComputeUnitCounts; ///< Specify a compute unit count range.
+  MSR_TYPE_ENTRY_DATA       MsrEntry;          ///< The MSR Register entry data.
+} COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA;
+#define MAKE_COMPUTE_UNIT_COUNTS_MSR_ENTRY(CUCounts, Address, Data, Mask) MAKE_ENTRY_TYPE (CompUnitCountsMsr), MAKE_COMPUTE_UNIT_COUNTS (CUCounts), MAKE_MSR_DATA (Address, Data, Mask)
+
+
+/**
+ * A Family Specific Workaround method.
+ *
+ * \@TableTypeFamSpecificInstances.
+ *
+ * When called, the entry's CPU Logical ID and Platform Features matched the current config.
+ * The method must implement any specific criteria checking for the workaround.
+ *
+ * See if you can use the other entries or make an entry specifically for 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 specific.
+ *
+ * @param[in]     Data       The table data value, for example to indicate which CPU and Platform types matched.
+ * @param[in]     StdHeader  Config params for library, services.
+ */
+typedef VOID F_FAM_SPECIFIC_WORKAROUND (
+  IN       UINT32              Data,
+  IN       AMD_CONFIG_PARAMS   *StdHeader
+  );
+/// Reference to a method.
+typedef F_FAM_SPECIFIC_WORKAROUND *PF_FAM_SPECIFIC_WORKAROUND;
+
+/**
+ * Table Entry Data for Family Specific Workarounds.
+ *
+ * See if you can use the other entries or make an entry specifically for 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 specific.
+ *
+ * Call DoAction passing Data.
+ */
+typedef struct {
+  UINT32    FunctionIndex;            ///< A function implementing the workaround.
+  UINT32    Data;                     ///< This data is passed to DoAction().
+} FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA;
+#define MAKE_FAM_SPECIFIC_WORKAROUND_DATA(FunctionIndex, Data) BSU32 (FunctionIndex), BSU32 (Data)
+#define MAKE_FAM_SPECIFIC_WORKAROUND_ENTRY(FunctionIndex, Data) MAKE_ENTRY_TYPE (FamSpecificWorkaround), MAKE_FAM_SPECIFIC_WORKAROUND_DATA(FunctionIndex, Data)
+
+/**
+ * Table Entry Data for CPU revision specific PCI Registers.
+ *
+ * Apply data to register after mask, for PCI Config registers.
+ */
+typedef struct {
+  CPU_LOGICAL_ID  CpuRevision;        ///< Common CPU Logical ID match criteria.
+  PCI_ADDR        Address;            ///< Address should contain Function, Offset only.  It will apply to all CPUs
+  UINT32          Data;               ///< Data to be written into PCI device
+  UINT32          Mask;               ///< Mask to be used before data write. Set every bit of all updated fields.
+} CPU_REV_PCI_TYPE_ENTRY_DATA;
+#define MAKE_CPU_REV_PCI_ENTRY(Family, Revision, Address, Data, Mask) MAKE_ENTRY_TYPE (CpuRevPciRegister), MAKE_CPU_LOGICAL_ID (Family, Revision), MAKE_PCI_DATA (Address, Data, Mask)
+
+/**
+ * Table Entry Data for CPU revision specific MSRs.
+ *
+ * Apply data to register after mask, for MSRs.
+ */
+typedef struct {
+  CPU_LOGICAL_ID  CpuRevision;        ///< Common CPU Logical ID match criteria.
+  UINT32          Address;            ///< MSR Address
+  UINT64          Data;               ///< Data to be written into MSR
+  UINT64          Mask;               ///< Mask to be used before data write. Set every bit of all updated fields.
+} CPU_REV_MSR_TYPE_ENTRY_DATA;
+#define MAKE_CPU_REV_MSR_ENTRY(Family, Revision, Address, Data, Mask) MAKE_ENTRY_TYPE (CpuRevMsr), MAKE_CPU_LOGICAL_ID (Family, Revision), MAKE_MSR_DATA (Address, Data, Mask)
+
+/**
+ * Table Entry Data for Family Specific Workarounds that depend on CPU revision.
+ *
+ * See if you can use the other entries or make an entry specifically for 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 specific.
+ *
+ * Call DoAction passing Data.
+ */
+typedef struct {
+  CPU_LOGICAL_ID        CpuRevision;        ///< Common CPU Logical ID match criteria.
+  UINT32                FunctionIndex;      ///< A function implementing the workaround.
+  UINT32                Data;               ///< This data is passed to DoAction().
+} CPU_REV_FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA;
+#define MAKE_CPU_REV_FAM_SPECIFIC_WORKAROUND_ENTRY(Family, Revision, FunctionIndex, Data) MAKE_ENTRY_TYPE (CpuRevFamSpecificWorkaround), MAKE_CPU_LOGICAL_ID (Family, Revision), MAKE_FAM_SPECIFIC_WORKAROUND_DATA (FunctionIndex, Data)
+
+/**
+ * Table Entry Data for SMU Index/Data D0F0xBC_xxxx_xxxx Registers.
+ *
+ * Apply data to register after mask, for PCI Config registers.
+ */
+typedef struct {
+  UINT32    Index;                    ///< SMU index address
+  UINT32    Data;                     ///< Data to be written into PCI device
+  UINT32    Mask;                     ///< Mask to be used before data write. Set every bit of all updated fields.
+} SMU_INDEX_ENTRY_DATA;
+#define MAKE_SMU_INDEX_ENTRY_DATA(Index, Data, Mask) BSU32 (Index), BSU32 (Data), BSU32 (Mask)
+#define MAKE_SMU_INDEX_ENTRY(Index, Data, Mask) MAKE_ENTRY_TYPE (SmuIndexReg), MAKE_SMU_INDEX_ENTRY_DATA(Index, Data, Mask)
+
+#define SMU_INDEX_ADDRESS (MAKE_SBDFO (0, 0, 0, 0, 0xB8))
+
+
+/**
+ * Table Entry Data for Profile Fixup to SMU Index/Data D0F0xBC_xxxx_xxxx Registers.
+ *
+ * If TypeFeats matches current config, apply data to register after mask for SMU Index/Data D0F0xBC_xxxx_xxxx registers.
+ */
+typedef struct {
+  PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features.
+  SMU_INDEX_ENTRY_DATA SmuIndexEntry;  ///< The SMU Index/Data D0F0xBC_xxxx_xxxx register entry data.
+} PROFILE_FIXUP_SMU_INDEX_ENTRY_DATA;
+#define MAKE_PROFILE_FIXUP_SMU_INDEX_ENTRY(TypeFeats, Index, Data, Mask) MAKE_ENTRY_TYPE (ProfileFixupSmuIndexReg), MAKE_PERFORMANCE_PROFILE_FEATS (TypeFeats), MAKE_SMU_INDEX_ENTRY_DATA (Index, Data, Mask)
+
+/**
+ * Bit field description
+ *
+ * Describe register type, address, MSB, LSB
+ */
+typedef struct {
+  UINT16           RegType;            ///< Register type
+  UINT32           Address;            ///< Address
+  UINT8            MSB;                ///< Most Significant Bit
+  UINT8            LSB;                ///< Least Significant Bit
+} COPY_BIT_FIELD_DESCRIPTION;
+#define MAKE_COPY_BIT_FIELD_DESCRIPTION(RegType, Address, Msb, Lsb) MAKE_ENTRY_TYPE (RegType), BSU32 (Address), BSU8 (Msb), BSU8 (Lsb)
+
+/**
+ * Table Entry Data for copying bitfield from register A to register B.
+ *
+ * Copy bitfield from register A to register B.
+ */
+typedef struct {
+  COPY_BIT_FIELD_DESCRIPTION Destination; ///< Destination register descriptor
+  COPY_BIT_FIELD_DESCRIPTION Source;      ///< Source register descriptor
+} COPY_BIT_FIELD_ENTRY_DATA;
+#define COPY_BIT_FIELD_DEST(RegType, Address, Msb, Lsb) MAKE_COPY_BIT_FIELD_DESCRIPTION (RegType, Address, Msb, Lsb)
+#define COPY_BIT_FIELD_SOURCE(RegType, Address, Msb, Lsb) MAKE_COPY_BIT_FIELD_DESCRIPTION (RegType, Address, Msb, Lsb)
+#define MAKE_COPY_BIT_FIELD_ENTRY(Dest, Src) MAKE_ENTRY_TYPE (CopyBitField), Dest, Src
+/*------------------------------------------------------------------------------------------*/
+/*
+ * A complete register table and table entries.
+ */
+/*------------------------------------------------------------------------------------------*/
+
+/**
+ * Format of table entries :
+ *
+ *  UINT16          EntryType \
+ *  VariableLength  EntryData / one entry
+ *  UINT16          EntryType \
+ *  VariableLength  EntryData / one entry
+ *  ...                       \
+ *  ...                       / more entries...
+ */
+
+/**
+ * All the available entry data types.
+ *
+ * we use TABLE_ENTRY_DATA in copy bitfield entry
+ *
+ */
+typedef union {
+  MSR_TYPE_ENTRY_DATA                              MsrEntry;                ///< MSR entry.
+  PCI_TYPE_ENTRY_DATA                              PciEntry;                ///< PCI entry.
+  FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA          FamSpecificEntry;        ///< Family Specific Workaround entry.
+  PROFILE_FIXUP_TYPE_ENTRY_DATA                    FixupEntry;              ///< Profile Fixup entry.
+  CORE_COUNTS_PCI_TYPE_ENTRY_DATA                  CoreCountEntry;          ///< Core count dependent settings.
+  COMPUTE_UNIT_COUNTS_PCI_TYPE_ENTRY_DATA          CompUnitCountEntry;      ///< Compute unit count dependent entry.
+  COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA          CompUnitCountMsrEntry;   ///< Compute unit count dependent MSR entry.
+  CPU_REV_PCI_TYPE_ENTRY_DATA                      CpuRevPciEntry;          ///< CPU revision PCI entry.
+  CPU_REV_FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA  CpuRevFamSpecificEntry;  ///< CPU revision Family Specific Workaround entry.
+  SMU_INDEX_ENTRY_DATA                             SmuIndexEntry;           ///< SMU Index Data entry.
+  PROFILE_FIXUP_SMU_INDEX_ENTRY_DATA               ProfileFixupSmuIndexEntry; ///< Performance Profile fixups to SMU index data registers entry.
+  COPY_BIT_FIELD_ENTRY_DATA                        CopyBitFieldEntry;       ///< Copy bitfield entry.
+} TABLE_ENTRY_DATA;
+
+/**
+ * Register Table Entry common fields.
+ *
+ * All the various types of register table entries are subclasses of this object.
+ */
+typedef struct {
+  UINT16                 EntryType;                  ///< The type of table entry this is.
+  TABLE_ENTRY_DATA       EntryData;                  ///< The pointer to the first entry.
+} TABLE_ENTRY_FIELDS;
+
+/**
+ * An entire register table.
+ */
+typedef struct {
+  UINT32               Selector;                     ///< For efficiency, these cores should process this table
+  CONST UINT8*         Table;                        ///< The table entries.
+} REGISTER_TABLE;
+
+/**
+ * An entire register table at given time point.
+ */
+typedef struct {
+  REGISTER_TABLE_TIME_POINT TimePoint;               ///< Time point
+  CONST REGISTER_TABLE**    TableList;               ///< The table list.
+} REGISTER_TABLE_AT_GIVEN_TP;
+/*------------------------------------------------------------------------------------------*/
+/*
+ * Describe implementers for table entries.
+ */
+/*------------------------------------------------------------------------------------------*/
+
+/**
+ * Implement the semantics of a Table Entry Type.
+ *
+ * @TableEntryTypeInstances.
+ *
+ * @param[in]       CurrentEntry        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.
+ */
+typedef VOID F_DO_TABLE_ENTRY (
+  IN       UINT8                 **CurrentEntry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+/// Reference to a method
+typedef F_DO_TABLE_ENTRY *PF_DO_TABLE_ENTRY;
+
+/**
+ * Describe the attributes of a Table Entry Type.
+ */
+typedef struct {
+  UINT16                 EntryType;                  ///< The type of table entry this describes.
+  PF_DO_TABLE_ENTRY      DoTableEntry;               ///< Provide all semantics associated with TABLE_ENTRY_DATA
+} TABLE_ENTRY_TYPE_DESCRIPTOR;
+
+/*------------------------------------------------------------------------------------------*/
+/*
+ * Table related function prototypes (many are instance of F_DO_TABLE_ENTRY method).
+ */
+/*------------------------------------------------------------------------------------------*/
+
+/**
+ * Get the next register table
+ */
+REGISTER_TABLE **GetNextRegisterTable (
+  IN       UINT32                  Selector,
+  IN       REGISTER_TABLE        **RegisterTableList,
+  IN OUT   REGISTER_TABLE       ***RegisterTableHandle,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * If current core is CoreSelector core
+ */
+BOOLEAN
+IsCoreSelector (
+  IN       UINT32                    Selector,
+  IN       AMD_CONFIG_PARAMS        *StdHeader
+  );
+
+/**
+ * Set the registers for this core based on entries in a list of Register Table.
+ */
+VOID
+SetRegistersFromTable (
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       UINT8                  *RegisterEntry,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Set the registers for this core based on entries in a list of Register Table.
+ */
+VOID
+SetRegistersFromTableList (
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       REGISTER_TABLE         **RegisterTableList,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Processes the register table at the given time point.
+ */
+AGESA_STATUS
+SetRegistersFromTablesAtGivenTimePoint (
+  IN       VOID                      *PlatformConfig,
+  IN       REGISTER_TABLE_TIME_POINT  TimePoint,
+  IN       AMD_CONFIG_PARAMS         *StdHeader
+  );
+
+/**
+ * Find the features of the running platform.
+ */
+VOID
+GetPlatformFeatures (
+     OUT   PLATFORM_FEATS    *Features,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ * Checks register table entry type specific criteria to the platform.
+ */
+BOOLEAN
+DoesEntryTypeSpecificInfoMatch (
+  IN       UINT32   PlatformTypeSpecificFeatures,
+  IN       UINT32   EntryTypeFeatures
+  );
+
+/**
+ * Perform the MSR Register Entry.
+ */
+VOID
+SetRegisterForMsrEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the CPU Rev MSR Entry.
+ */
+VOID
+SetRegisterForCpuRevMsrEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the PCI Register Entry.
+ */
+VOID
+SetRegisterForPciEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the PCI Register Entry.
+ */
+VOID
+SetRegisterForCpuRevPciEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the Performance Profile PCI Register Entry.
+ */
+VOID
+SetRegisterForPerformanceProfileEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the Core Counts Performance PCI Register Entry.
+ */
+VOID
+SetRegisterForCoreCountsPerformanceEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the Compute Unit Counts PCI Register Entry.
+ */
+VOID
+SetRegisterForComputeUnitCountsEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the Compute Unit Counts MSR Register Entry.
+ */
+VOID
+SetMsrForComputeUnitCountsEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the Family Specific Workaround Register Entry.
+ */
+VOID
+SetRegisterForFamSpecificWorkaroundEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the Family Specific Workaround Register Entry.
+ */
+VOID
+SetRegisterForCpuRevFamSpecificWorkaroundEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the SMU Index/Data Register Entry.
+ */
+VOID
+SetSmuIndexRegisterEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the Performance Profile SMU Index/Data Register Entry.
+ */
+VOID
+SetSmuIndexRegisterForPerformanceEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Perform the Copy Bitfield Entry.
+ */
+VOID
+CopyBitFieldEntry (
+  IN       UINT8                 **Entry,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/**
+ * Compare counts to a pair of ranges.
+ */
+BOOLEAN
+IsEitherCountInRange (
+  IN       UINTN                FirstCount,
+  IN       UINTN                SecondCount,
+  IN       COUNT_RANGE_FEATURE  Ranges
+  );
+
+/**
+ * Returns the performance profile features list of the currently running processor core.
+ */
+VOID
+GetPerformanceFeatures (
+     OUT   PERFORMANCE_PROFILE_FEATS    *Features,
+  IN       PLATFORM_CONFIGURATION       *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS            *StdHeader
+  );
+
+#endif  // _CPU_TABLE_H_
+
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuFamilyTranslation.c b/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuFamilyTranslation.c
new file mode 100644
index 0000000..5699d92
--- /dev/null
+++ b/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuFamilyTranslation.c
@@ -0,0 +1,442 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD CPU Family Translation functions.
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project:      AGESA
+ * @e sub-project:  CPU/Interface
+ * @e \$Revision$   @e \$Date$
+ *
+ */
+ /*****************************************************************************
+ *
+ * Copyright (c) 2008 - 2016, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ *       its contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ *                             M O D U L E S    U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuRegisters.h"
+#include "CommonReturns.h"
+#include "GeneralServices.h"
+#include "cpuFamilyTranslation.h"
+#include "Filecode.h"
+CODE_GROUP (G1_PEICC)
+RDATA_GROUP (G1_PEICC)
+
+#define FILECODE PROC_CPU_CPUFAMILYTRANSLATION_FILECODE
+
+/*----------------------------------------------------------------------------------------
+ *                   D E F I N I T I O N S    A N D    M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+#define RAW_TO_XLAT_MASK (UINT32) (CPUID_EXT_FAMILY_MASK | CPUID_EXT_MODEL_MASK | CPUID_BASE_FAMILY_MASK)
+#define RAW_TO_LOGICAL_MASK (UINT32) (CPUID_EXT_FAMILY_MASK | CPUID_EXT_MODEL_MASK | CPUID_BASE_MODEL_MASK | CPUID_STEPPING_MASK)
+
+/*----------------------------------------------------------------------------------------
+ *                  T Y P E D E F S     A N D     S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+CONST CPU_SPECIFIC_SERVICES ROMDATA cpuNullServices =
+{
+  0,                                                                      // Revision
+  (PF_CPU_DISABLE_PSTATE) CommonReturnAgesaSuccess,                       // DisablePstate
+  (PF_CPU_TRANSITION_PSTATE) CommonReturnAgesaSuccess,                    // TransitionPstate
+  (PF_CPU_GET_IDD_MAX) CommonReturnFalse,                                 // GetProcIddMax
+  (PF_CPU_GET_TSC_RATE) CommonReturnAgesaSuccess,                         // GetTscRate
+  (PF_CPU_GET_NB_FREQ) CommonReturnAgesaSuccess,                          // GetCurrentNbFrequency
+  (PF_CPU_GET_MIN_MAX_NB_FREQ) CommonReturnAgesaSuccess,                  // GetMinMaxNbFrequency
+  (PF_CPU_GET_NB_PSTATE_INFO) CommonReturnFalse,                          // GetNbPstateInfo
+  (PF_CPU_IS_NBCOF_INIT_NEEDED) CommonReturnAgesaSuccess,                 // IsNbCofInitNeeded
+  (PF_CPU_GET_NB_IDD_MAX) CommonReturnFalse,                              // GetNbIddMax
+  (PF_CPU_AP_INITIAL_LAUNCH) CommonReturnFalse,                           // LaunchApCore
+  (PF_CPU_NUMBER_OF_PHYSICAL_CORES) CommonReturnZero8,                    // GetNumberOfPhysicalCores
+  (PF_CPU_GET_AP_CORE_NUMBER) CommonReturnZero32,                         // GetApCoreNumber
+  (PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID) CommonReturnAgesaSuccess,      // CoreIdPositionInInitialApicId
+  (PF_CPU_SET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,                  // SetWarmResetFlag
+  (PF_CPU_GET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,                  // GetWarmResetFlag
+  GetEmptyArray,                                                          // GetMicroCodePatchesStruct
+  GetEmptyArray,                                                          // GetMicrocodeEquivalenceTable
+  GetEmptyArray,                                                          // GetCacheInfo
+  GetEmptyArray,                                                          // GetSysPmTableStruct
+  GetEmptyArray,                                                          // GetWheaInitData
+  (PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO) CommonReturnAgesaSuccess,      // GetPlatformTypeSpecificInfo
+  (PF_IS_NB_PSTATE_ENABLED) CommonReturnFalse,                            // IsNbPstateEnabled
+  {
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[MsrRegister]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[PciRegister]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[FamSpecificWorkaround]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[ProfileFixup]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[CoreCountsPciRegister]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[CompUnitCountsPciRegister]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[CompUnitCountsMsr]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[CpuRevPciRegister]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[CpuRevMsr]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[CpuRevFamSpecificWorkaround]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[SmuIndexReg]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[ProfileFixupSmuIndexReg]
+    (PF_DO_TABLE_ENTRY) CommonAssert,                                     // DoTableEntry[CopyBitField]
+  },
+  (PF_GET_REGISTER_TABLE_LIST) CommonReturnNULL,                          // GetRegisterTableList
+  (PF_GET_WORKAROUND_TABLE) CommonReturnNULL,                             // GetWorkaroundTable
+  NULL,                                                                   // ComputeUnitMap
+  InitCacheDisabled,                                                      // InitCacheDisabled
+  (PF_GET_EARLY_INIT_TABLE) CommonVoid,                                   // GetEarlyInitBeforeApLaunchOnCoreTable
+  (PF_GET_EARLY_INIT_TABLE) CommonVoid,                                   // GetEarlyInitAfterApLaunchOnCoreTable
+  (PF_IS_SECURE_S3) CommonReturnFalse,                                    // IsSecureS3
+  FALSE                                                                   // PatchLoaderIsSharedByCU
+};
+
+/*----------------------------------------------------------------------------------------
+ *           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
+STATIC
+GetCpuServices (
+  IN       CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
+  IN       UINT16            *MatchData,
+     OUT   CONST VOID        **CpuServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/*----------------------------------------------------------------------------------------
+ *                          E X P O R T E D    F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+extern CPU_FAMILY_SUPPORT_TABLE CpuSupportedFamiliesTable;
+extern CPU_FAMILY_ID_XLAT_TABLE CpuSupportedFamilyIdTable;
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ *  Returns the logical ID of the desired processor. This will be obtained by
+ *  reading the CPUID and converting it into a "logical ID" which is not package
+ *  dependent.
+ *
+ *  @param[in]      Socket             Socket
+ *  @param[out]     LogicalId          The Processor's Logical ID
+ *  @param[in]      StdHeader          Handle of Header for calling lib functions and services.
+ *
+ */
+VOID
+GetLogicalIdOfSocket (
+  IN       UINT32 Socket,
+     OUT   CPU_LOGICAL_ID *LogicalId,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  UINT32      RawCpuid;
+  PCI_ADDR    PciAddress;
+  AGESA_STATUS AssumedSuccess;
+
+  RawCpuid = 0;
+
+  if (GetPciAddress (StdHeader, (UINT8)Socket, 0, &PciAddress, &AssumedSuccess)) {
+    PciAddress.Address.Function = FUNC_3;
+    PciAddress.Address.Register = CPUID_FMR;
+    LibAmdPciRead (AccessWidth32, PciAddress, &RawCpuid, StdHeader);
+    GetLogicalIdFromCpuid (RawCpuid, LogicalId, StdHeader);
+  } else {
+    LogicalId->Family = 0;
+    LogicalId->Revision = 0;
+    // Logical ID was not found.
+    IDS_ERROR_TRAP;
+  }
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ *  Returns the logical ID of the executing core. This will be obtained by reading
+ *  the CPUID and converting it into a "logical ID" which is not package dependent.
+ *
+ *  @param[out]     LogicalId          The Processor's Logical ID
+ *  @param[in]      StdHeader          Handle of Header for calling lib functions and services.
+ *
+ */
+VOID
+GetLogicalIdOfCurrentCore (
+     OUT   CPU_LOGICAL_ID *LogicalId,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  CPUID_DATA  CpuidDataStruct;
+
+  LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuidDataStruct, StdHeader);
+  GetLogicalIdFromCpuid (CpuidDataStruct.EAX_Reg, LogicalId, StdHeader);
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ *  Returns the logical ID of a processor with the given CPUID value. This
+ *  will be obtained by converting it into a "logical ID" which is not package
+ *  dependent.
+ *
+ *  @param[in]      RawCpuid           The unprocessed CPUID value to be translated
+ *  @param[out]     LogicalId          The Processor's Logical ID
+ *  @param[in]      StdHeader          Handle of Header for calling lib functions and services
+ *
+ */
+VOID
+GetLogicalIdFromCpuid (
+  IN       UINT32 RawCpuid,
+     OUT   CPU_LOGICAL_ID *LogicalId,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  UINT8       i;
+  UINT8       k;
+  UINT8       NumberOfFamiliesSupported;
+  UINT8       NumberOfLogicalSubFamilies;
+  UINT8       LogicalIdEntries;
+  UINT16      LogicalFamily;
+  UINT16      HighestSupportedLogicalId;
+  UINT32      j;
+  UINT32      RawFamily;
+  UINT32      CpuModelAndExtendedModel;
+  BOOLEAN     IdNotFound;
+  BOOLEAN     FamilyNotFound;
+  CONST PF_CPU_GET_SUBFAMILY_ID_ARRAY *SubFamilyIdPtr;
+  CPU_LOGICAL_ID_XLAT *CpuLogicalIdAndRevPtr;
+  CONST CPU_LOGICAL_ID_FAMILY_XLAT *ImageSupportedId;
+
+  IdNotFound = TRUE;
+  FamilyNotFound = TRUE;
+  CpuLogicalIdAndRevPtr = NULL;
+  ImageSupportedId = CpuSupportedFamilyIdTable.FamilyIdTable;
+  NumberOfFamiliesSupported = CpuSupportedFamilyIdTable.Elements;
+
+  RawFamily = RawCpuid & RAW_TO_XLAT_MASK;
+  RawCpuid &= RAW_TO_LOGICAL_MASK;
+  CpuModelAndExtendedModel = (UINT16) ((RawCpuid >> 8) | RawCpuid);
+
+  LogicalId->Family = 0;
+  LogicalId->Revision = 0;
+  HighestSupportedLogicalId = 0;
+
+  for (i = 0; i < NumberOfFamiliesSupported && FamilyNotFound; i++) {
+    if (ImageSupportedId[i].Family == RawFamily) {
+      FamilyNotFound = FALSE;
+      LogicalId->Family = ImageSupportedId[i].UnknownRevision.Family;
+      LogicalId->Revision = ImageSupportedId[i].UnknownRevision.Revision;
+
+      NumberOfLogicalSubFamilies = ImageSupportedId[i].Elements;
+      SubFamilyIdPtr = ImageSupportedId[i].SubFamilyIdTable;
+      for (j = 0; j < NumberOfLogicalSubFamilies && IdNotFound; j++) {
+        SubFamilyIdPtr[j] (&CpuLogicalIdAndRevPtr, &LogicalIdEntries, &LogicalFamily, &HighestSupportedLogicalId, StdHeader);
+        ASSERT (CpuLogicalIdAndRevPtr != NULL);
+        for (k = 0; k < LogicalIdEntries; k++) {
+          if (CpuLogicalIdAndRevPtr[k].RawId == CpuModelAndExtendedModel) {
+            IdNotFound = FALSE;
+            LogicalId->Family = LogicalFamily;
+            LogicalId->Revision = CpuLogicalIdAndRevPtr[k].LogicalId;
+            break;
+          }
+        }
+      }
+      if (LogicalId->Revision == ImageSupportedId[i].UnknownRevision.Revision) {
+        LogicalId->Revision = HighestSupportedLogicalId;
+      }
+    }
+  }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ *  Retrieves a pointer to the executing core's family specific services structure.
+ *
+ *  @param[out]     FunctionTable      The Processor's Family Specific services.
+ *  @param[in]      StdHeader          Handle of Header for calling lib functions and services.
+ *
+ */
+VOID
+GetCpuServicesOfCurrentCore (
+     OUT   CONST CPU_SPECIFIC_SERVICES **FunctionTable,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  GetFeatureServicesOfCurrentCore (&CpuSupportedFamiliesTable,
+                                   (CONST VOID **) FunctionTable,
+                                   StdHeader);
+  if (*FunctionTable == NULL) {
+    *FunctionTable = &cpuNullServices;
+  }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ *  Retrieves a pointer to the family specific services structure for a processor
+ *  with the given logical ID.
+ *
+ *  @param[in]      FamilyTable        The table to search in.
+ *  @param[out]     CpuServices        The Processor's Family Specific services.
+ *  @param[in]      StdHeader          Handle of Header for calling lib functions and services.
+ *
+ */
+VOID
+GetFeatureServicesOfCurrentCore (
+  IN       CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
+     OUT   CONST VOID        **CpuServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  CPU_LOGICAL_ID CpuFamilyRevision;
+
+  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
+  GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ *  Retrieves a pointer to the family specific services structure for a processor
+ *  with the given logical ID.
+ *
+ *  @param[in]      LogicalId          The Processor's logical ID.
+ *  @param[out]     FunctionTable      The Processor's Family Specific services.
+ *  @param[in]      StdHeader          Handle of Header for calling lib functions and services.
+ *
+ */
+VOID
+GetCpuServicesFromLogicalId (
+  IN       CPU_LOGICAL_ID *LogicalId,
+     OUT   CONST CPU_SPECIFIC_SERVICES **FunctionTable,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  GetFeatureServicesFromLogicalId (&CpuSupportedFamiliesTable,
+                                   LogicalId,
+                                   (CONST VOID **) FunctionTable,
+                                   StdHeader);
+  if (*FunctionTable == NULL) {
+    *FunctionTable = &cpuNullServices;
+  }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ *  Retrieves a pointer to the family specific services structure for a processor
+ *  with the given logical ID.
+ *
+ *  @param[in]      FamilyTable        The table to search in.
+ *  @param[in]      LogicalId          The Processor's logical ID.
+ *  @param[out]     CpuServices        The Processor's Family Specific services.
+ *  @param[in]      StdHeader          Handle of Header for calling lib functions and services.
+ *
+ */
+VOID
+GetFeatureServicesFromLogicalId (
+  IN       CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
+  IN       CPU_LOGICAL_ID    *LogicalId,
+     OUT   CONST VOID        **CpuServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  GetCpuServices (FamilyTable, &LogicalId->Family, CpuServices, StdHeader);
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ *  Finds a family match in the given table, and returns the pointer to the
+ *  appropriate table.  If no match is found in the table, NULL will be returned.
+ *
+ *  @param[in]      FamilyTable        The table to search in.
+ *  @param[in]      MatchData          Family data that must match.
+ *  @param[out]     CpuServices        The Processor's Family Specific services.
+ *  @param[in]      StdHeader          Handle of Header for calling lib functions and services.
+ *
+ */
+VOID
+STATIC
+GetCpuServices (
+  IN       CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
+  IN       UINT16            *MatchData,
+     OUT   CONST VOID        **CpuServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  BOOLEAN IsFamily;
+  UINT8   i;
+  UINT8   NumberOfFamiliesSupported;
+  CONST CPU_SPECIFIC_SERVICES_XLAT *ImageSupportedFamiliesPtr;
+
+  ImageSupportedFamiliesPtr = FamilyTable->FamilyTable;
+  NumberOfFamiliesSupported = FamilyTable->Elements;
+  IsFamily = FALSE;
+  for (i = 0; i < NumberOfFamiliesSupported; i++) {
+    if ((ImageSupportedFamiliesPtr[i].Family & *MatchData) != 0) {
+      IsFamily = TRUE;
+      break;
+    }
+  }
+  if (IsFamily) {
+    *CpuServices = ImageSupportedFamiliesPtr[i].TablePtr;
+  } else {
+    *CpuServices = NULL;
+  }
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *  Used to stub out various family specific tables of information.
+ *
+ *  @param[in]      FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]      Empty                   NULL, to indicate no data.
+ *  @param[out]     NumberOfElements        Zero, to indicate no data.
+ *  @param[in]      StdHeader               Handle of Header for calling lib functions and services.
+ *
+ */
+VOID
+GetEmptyArray (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+     OUT   CONST VOID **Empty,
+     OUT   UINT8 *NumberOfElements,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  )
+{
+  *NumberOfElements = 0;
+  *Empty = NULL;
+}
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuFamilyTranslation.h b/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuFamilyTranslation.h
new file mode 100644
index 0000000..743b5f6
--- /dev/null
+++ b/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuFamilyTranslation.h
@@ -0,0 +1,861 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD CPU Family Translation functions.
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project:      AGESA
+ * @e sub-project:  CPU
+ * @e \$Revision$   @e \$Date$
+ *
+ */
+ /*****************************************************************************
+ *
+ * Copyright (c) 2008 - 2016, 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.
+ *
+ ***************************************************************************/
+
+#ifndef _CPU_FAMILY_TRANSLATION_H_
+#define _CPU_FAMILY_TRANSLATION_H_
+
+/**
+ * @page cpuimplfss CPU Family Specific Services Implementation Guide
+ *
+ * CPU Family Specific Services provides access to supported family service functions and data,
+ * in a manner that isolates calling code from knowledge about particular families or which
+ * families are supported in the current build.
+ *
+ * @par Adding a Method to Family Specific Services
+ *
+ * To add a new method to Family Specific Services, follow these steps.
+ * <ul>
+ * <li> Create a typedef for the Method with the correct parameters and return type.
+ *
+ *   <ul>
+ *   <li> Name the method typedef (*PF_METHOD_NAME)(), where METHOD_NAME is the same name as the method table item,
+ *     but with "_"'s and UPPERCASE, rather than mixed case.
+ *     @n <tt> typedef VOID (*PF_METHOD_NAME)(); </tt> @n
+ *
+ *   <li> [Optionally make the type F_<name> and provide a separate:
+ *     @n <tt> typedef F_METHOD_NAME *PF_METHOD_NAME> </tt> @n
+ *     and provide a single line "///" doxygen comment brief description on the PF_ type.]
+ *   </ul>
+ *
+ * <li> The first parameter to @b all Family Specific Service Methods is @b required to be a reference to
+ *   their Family Service struct.
+ *   @n <tt> IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices </tt> @n
+ *
+ * <li> Provide a standard doxygen function preamble for the Method typedef.  Begin the
+ *   detailed description by provide a reference to the method instances page by including
+ *   the lines below:
+ *   @code
+ *   *
+ *   * @CpuServiceInstances
+ *   *
+ *   @endcode
+ *   @note It is important to provide documentation for the method type, because the method may not
+ *   have an implementation in any families supported by the current package. @n
+ *
+ * <li> Add to the CPU_SPECIFIC_SERVICES struct an item for the Method:
+ *   @n <tt>  PF_METHOD_NAME MethodName; ///< Method: description. </tt> @n
+ * </ul>
+ *
+ * @par Implementing a Family Specific Instance of the method.
+ *
+ * To implement an instance of a method for a specific family follow these steps.
+ *
+ * - In appropriate files in the family specific directory, implement the method with the return type
+ *   and parameters matching the method typedef.
+ *
+ * - Name the function FnnMethodName(), where nn is the family number.
+ *
+ * - Create a doxygen function preamble for the method instance.  Begin the detailed description with
+ *   an Implements command to reference the method type and add this instance to the Method Instances page.
+ *   @code
+ *   *
+ *   *  @CpuServiceMethod{::F_METHOD_NAME}.
+ *   *
+ *   @endcode
+ *
+ * - To access other family specific services as part of the method implementation, the function
+ *   @b must use FamilySpecificServices->OtherMethod().  Do not directly call other family specific
+ *   routines, because in the table there may be overrides or this routine may be shared by multiple families.
+ *
+ * - Do @b not call Family translation services from a family specific instance.  Use the parameter.
+ *
+ * - Add the instance to the family specific CPU_SPECIFIC_SERVICES instance.
+ *
+ * - If a family does not need an instance of the method use one of the CommonReturns from
+ *   CommonReturns.h with the same return type.
+ *
+ * @par Invoking Family Specific Services.
+ *
+ * The following example shows how to invoke a family specific method.
+ * @n @code
+ *        CPU_SPECIFIC_SERVICES *FamilyServices;
+ *
+ *        GetCpuServicesOfCurrentCore (&FamilyServices, StdHeader);
+ *        ASSERT (FamilyServices != NULL);
+ *        FamilyServices->MethodName (FamilyServices, StdHeader);
+ * @endcode
+ *
+ */
+
+
+/*---------------------------------------------------------------------------------------
+ *          M I X E D   (Definitions And Macros / Typedefs, Structures, Enums)
+ *---------------------------------------------------------------------------------------
+ */
+/* #include "cpuPostInit.h" */
+/* #include "cpuEnvInit.h" */
+#include "cpuRegisters.h"
+#include "cpuServices.h"
+#include "Table.h"
+#include "Ids.h"
+/* #include "Topology.h" */
+
+//  Forward declaration needed for multi-structure mutual references.
+AGESA_FORWARD_DECLARATION (CPU_SPECIFIC_SERVICES);
+/*---------------------------------------------------------------------------------------
+ *                 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,   S T R U C T U R E S,    E N U M S
+ *---------------------------------------------------------------------------------------
+ */
+
+/**
+ *  Disable the desired P-state.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     StateNumber             Hardware P-state number.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ */
+typedef AGESA_STATUS F_CPU_DISABLE_PSTATE (
+  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+  IN       UINT8 StateNumber,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_DISABLE_PSTATE *PF_CPU_DISABLE_PSTATE;
+
+
+/**
+ *  Transition the current core to the desired P-state.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     StateNumber             Software P-state number.
+ *  @param[in]     WaitForChange           Wait/don't wait for P-state change to complete.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ */
+typedef AGESA_STATUS F_CPU_TRANSITION_PSTATE (
+  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+  IN       UINT8 StateNumber,
+  IN       BOOLEAN WaitForChange,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_TRANSITION_PSTATE *PF_CPU_TRANSITION_PSTATE;
+
+
+/**
+ *  Get the desired P-state's maximum current required in milliamps.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     StateNumber             The desired hardware P-state number.
+ *  @param[out]    ProcIddMax              The P-state's maximum current.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ *  @retval        TRUE                    The P-state is enabled, and ProcIddMax is valid.
+ *  @retval        FALSE                   The P-state is disabled.
+ *
+ */
+typedef BOOLEAN F_CPU_GET_IDD_MAX (
+  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+  IN       UINT8 StateNumber,
+     OUT   UINT32 *ProcIddMax,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_GET_IDD_MAX *PF_CPU_GET_IDD_MAX;
+
+
+/**
+ *  Returns the rate at which the current core's timestamp counter increments in megahertz.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[out]    FreqInMHz               The rate at which the TSC increments in megahertz.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ */
+typedef AGESA_STATUS F_CPU_GET_TSC_RATE (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+     OUT   UINT32 *FreqInMHz,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_GET_TSC_RATE *PF_CPU_GET_TSC_RATE;
+
+
+/**
+ *  Returns the processor north bridge's clock rate in megahertz.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[out]    FreqInMHz               The desired node's frequency in megahertz.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ *  @retval        AGESA_SUCCESS           FreqInMHz is valid.
+ */
+typedef AGESA_STATUS F_CPU_GET_NB_FREQ (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+     OUT   UINT32 *FreqInMHz,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_GET_NB_FREQ *PF_CPU_GET_NB_FREQ;
+
+
+/**
+ *  Returns the node's minimum and maximum northbridge frequency.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     PlatformConfig          Platform profile/build option config structure.
+ *  @param[in]     PciAddress              The segment, bus, and device numbers of the CPU in question.
+ *  @param[out]    MinFreqInMHz            The minimum north bridge frequency.
+ *  @param[out]    MaxFreqInMHz            The maximum north bridge frequency.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ *  @retval        AGESA_STATUS            Northbridge frequency is valid
+ */
+typedef AGESA_STATUS F_CPU_GET_MIN_MAX_NB_FREQ (
+  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       PCI_ADDR *PciAddress,
+     OUT   UINT32 *MinFreqInMHz,
+     OUT   UINT32 *MaxFreqInMHz,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_GET_MIN_MAX_NB_FREQ *PF_CPU_GET_MIN_MAX_NB_FREQ;
+
+
+/**
+ *  Returns the processor north bridge's P-state settings.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     PlatformConfig          Platform profile/build option config structure.
+ *  @param[in]     PciAddress              The segment, bus, and device numbers of the CPU in question.
+ *  @param[in]     NbPstate                The NB P-state number to check.
+ *  @param[out]    FreqNumeratorInMHz      The desired node's frequency numerator in megahertz.
+ *  @param[out]    FreqDivisor             The desired node's frequency divisor.
+ *  @param[out]    VoltageInuV             The desired node's voltage in microvolts.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ *  @retval        TRUE                    NbPstate is valid
+ *  @retval        FALSE                   NbPstate is disabled or invalid
+ */
+typedef BOOLEAN F_CPU_GET_NB_PSTATE_INFO (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       PCI_ADDR *PciAddress,
+  IN       UINT32 NbPstate,
+     OUT   UINT32 *FreqNumeratorInMHz,
+     OUT   UINT32 *FreqDivisor,
+     OUT   UINT32 *VoltageInuV,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_GET_NB_PSTATE_INFO *PF_CPU_GET_NB_PSTATE_INFO;
+
+
+/**
+ *  Returns whether or not the NB frequency initialization sequence is required
+ *  to be performed by the BIOS.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     PciAddress              The northbridge to query by pci base address.
+ *  @param[out]    NbVidUpdateAll          Do all NbVids need to be updated as well.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ */
+typedef BOOLEAN F_CPU_IS_NBCOF_INIT_NEEDED (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       PCI_ADDR *PciAddress,
+     OUT   BOOLEAN *NbVidUpdateAll,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_IS_NBCOF_INIT_NEEDED *PF_CPU_IS_NBCOF_INIT_NEEDED;
+
+
+/**
+ *  Get the desired NB P-state's maximum current required in milliamps.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     StateNumber             The desired hardware P-state number.
+ *  @param[out]    NbIddMax                The NB P-state's maximum current.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ *  @retval        TRUE                    The NB P-state is enabled, and NbIddMax is valid.
+ *  @retval        FALSE                   The NB P-state is disabled.
+ *
+ */
+typedef BOOLEAN F_CPU_GET_NB_IDD_MAX (
+  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
+  IN       UINT8 StateNumber,
+     OUT   UINT32 *NbIddMax,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_GET_NB_IDD_MAX *PF_CPU_GET_NB_IDD_MAX;
+
+
+/**
+ *  Launches the desired core from the reset vector.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     CoreNumber              The desired core's die relative core number.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ *  @retval        TRUE                    The core was launched successfully.
+ *  @retval        FALSE                   The core was previously launched, or has a problem.
+ */
+typedef BOOLEAN F_CPU_AP_INITIAL_LAUNCH (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       UINT32 CoreNumber,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_AP_INITIAL_LAUNCH *PF_CPU_AP_INITIAL_LAUNCH;
+
+
+/**
+ *  Returns the appropriate number of physical processor cores
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ *  @return        One-based number of physical cores on current processor
+ */
+typedef UINT8 F_CPU_NUMBER_OF_PHYSICAL_CORES (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_NUMBER_OF_PHYSICAL_CORES *PF_CPU_NUMBER_OF_PHYSICAL_CORES;
+
+
+/**
+ *  Get the AP core number from hardware.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ *  @return        The AP's unique core number
+ */
+typedef UINT32 (F_CPU_GET_AP_CORE_NUMBER) (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/// Reference to a method
+typedef F_CPU_GET_AP_CORE_NUMBER *PF_CPU_GET_AP_CORE_NUMBER;
+
+
+/**
+ * Core ID position in the initial APIC ID, reflected as a number zero or one.
+ */
+typedef enum {
+  CoreIdPositionZero, ///< Zero, the Core Id bits are the Most Significant bits.
+  CoreIdPositionOne,  ///< One, the Core Id bits are the Least Significant bits.
+  CoreIdPositionMax   ///< Limit check.
+} CORE_ID_POSITION;
+
+/**
+ * Return a number zero or one, based on the Core ID position in the initial APIC Id.
+ *
+ * @CpuServiceInstances
+ *
+ * @param[in]     FamilySpecificServices  The current Family Specific Services.
+ * @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ * @retval        CoreIdPositionZero      Core Id is not low
+ * @retval        CoreIdPositionOne       Core Id is low
+ */
+typedef CORE_ID_POSITION F_CORE_ID_POSITION_IN_INITIAL_APIC_ID (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/// Reference to a method
+typedef F_CORE_ID_POSITION_IN_INITIAL_APIC_ID *PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID;
+
+
+/**
+ *  Set Warm Reset Flag
+ *
+ *  @CpuServiceInstances
+ *
+ * @param[in]      FamilySpecificServices  The current Family Specific Services.
+ * @param[in]      StdHeader     Header for library and services.
+ * @param[in]      Request       Value to set the flags to.
+ *
+ */
+typedef VOID (F_CPU_SET_WARM_RESET_FLAG) (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader,
+  IN       WARM_RESET_REQUEST *Request
+  );
+
+/// Reference to a method
+typedef F_CPU_SET_WARM_RESET_FLAG *PF_CPU_SET_WARM_RESET_FLAG;
+
+
+/**
+ *  Get Warm Reset Flag
+ *
+ *  @CpuServiceInstances
+ *
+ * @param[in]      FamilySpecificServices  The current Family Specific Services.
+ * @param[in]      StdHeader     Header for library and services.
+ * @param[out]     BiosRstDet    Indicate warm reset status.
+ *
+ */
+typedef VOID (F_CPU_GET_WARM_RESET_FLAG) (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader,
+     OUT   WARM_RESET_REQUEST *Request
+  );
+
+/// Reference to a method
+typedef F_CPU_GET_WARM_RESET_FLAG *PF_CPU_GET_WARM_RESET_FLAG;
+
+
+/**
+ *  Returns a family specific table of information pointer and size.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices  The current Family Specific Services.
+ *  @param[out]    FamilySpecificArray     Pointer to the appropriate list for the core.
+ *  @param[out]    NumberOfElements        Number of valid entries FamilySpecificArray.
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ */
+typedef VOID F_CPU_GET_FAMILY_SPECIFIC_ARRAY (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+     OUT   CONST VOID **FamilySpecificArray,
+     OUT   UINT8 *NumberOfElements,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_GET_FAMILY_SPECIFIC_ARRAY *PF_CPU_GET_FAMILY_SPECIFIC_ARRAY;
+
+
+/**
+ *  Get CPU Specific Platform Type Info.
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     FamilySpecificServices         The current Family Specific Services.
+ *  @param[in,out] FeaturesUnion                  The Features supported by this platform.
+ *  @param[in]     StdHeader                      Handle of Header for calling lib functions and services.
+ *
+ */
+typedef AGESA_STATUS F_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN OUT   PLATFORM_FEATS         *FeaturesUnion,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO *PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO;
+
+
+/**
+ * Is the Northbridge PState feature enabled?
+ *
+ * @CpuServiceInstances
+ *
+ * @param[in]      FamilySpecificServices         The current Family Specific Services.
+ * @param[in]      PlatformConfig                 Platform profile/build option config structure.
+ * @param[in]      StdHeader                      Handle of Header for calling lib functions and services.
+ *
+ * @retval         TRUE                           The NB PState feature is enabled.
+ * @retval         FALSE                          The NB PState feature is not enabled.
+ */
+typedef BOOLEAN F_IS_NB_PSTATE_ENABLED (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+  IN       PLATFORM_CONFIGURATION *PlatformConfig,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+/// Reference to a method
+typedef F_IS_NB_PSTATE_ENABLED *PF_IS_NB_PSTATE_ENABLED;
+
+
+/**
+ * Returns the register tables list
+ *
+ *  @CpuServiceInstances
+ *
+ * @param[in]  FamilyServices                  The current Family Specific Services.
+ * @param[in]  StdHeader                       Config handle for library and services
+ *
+ */
+typedef REGISTER_TABLE_AT_GIVEN_TP *F_GET_REGISTER_TABLE_LIST (
+  IN       CPU_SPECIFIC_SERVICES                *FamilyServices,
+  IN       AMD_CONFIG_PARAMS                    *StdHeader
+  );
+/// Reference to a Method.
+typedef F_GET_REGISTER_TABLE_LIST *PF_GET_REGISTER_TABLE_LIST;
+
+
+/**
+ * Returns the workaround tables that the executing core should
+ * process at the given point in time.
+ *
+ *  @CpuServiceInstances
+ *
+ * @param[in]  FamilyServices                  The current Family Specific Services.
+ * @param[out] NumberOfWorkaroundTableEntries  Number of workaround table entries
+ * @param[in]  StdHeader                       Config handle for library and services
+ *
+ */
+typedef F_FAM_SPECIFIC_WORKAROUND **F_GET_WORKAROUND_TABLE (
+  IN       CPU_SPECIFIC_SERVICES                *FamilyServices,
+     OUT   UINT16                               *NumberOfWorkaroundTableEntries,
+  IN       AMD_CONFIG_PARAMS                    *StdHeader
+  );
+/// Reference to a Method.
+typedef F_GET_WORKAROUND_TABLE *PF_GET_WORKAROUND_TABLE;
+
+
+/// Cache Enable / Disable policy before giving control back to OS.
+typedef enum {
+  InitCacheDisabled,            ///<Disable cache CR0.CD bit
+  InitCacheEnabled              ///<Enable cache CR0.CD bit
+} FAMILY_CACHE_INIT_POLICY;
+
+
+/**
+ * Performs an early initialization function on the executing core.
+ *
+ * @param[in]  FamilyServices            The current Family Specific Services.
+ * @param[in]  EarlyParams               CPU module early paramters.
+ * @param[in]  StdHeader                 Config handle for library and services
+ *
+ */
+typedef VOID F_PERFORM_EARLY_INIT_ON_CORE (
+  IN       CPU_SPECIFIC_SERVICES  *FamilyServices,
+  IN       AMD_CPU_EARLY_PARAMS   *EarlyParams,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+/// Reference to a Method.
+typedef F_PERFORM_EARLY_INIT_ON_CORE *PF_PERFORM_EARLY_INIT_ON_CORE;
+
+/**
+ * A struct that contains function pointer and function flag
+ *
+ * the flag indicates if the function need to be run.
+ */
+typedef struct _S_PERFORM_EARLY_INIT_ON_CORE {
+  PF_PERFORM_EARLY_INIT_ON_CORE PerformEarlyInitOnCore; ///< Function Pointer, which points to the function need to be run at early stage
+  UINT32 PerformEarlyInitFlag; ///< Function Flag, which indicates if the function need to be run.
+} S_PERFORM_EARLY_INIT_ON_CORE;
+
+/**
+ * Returns the initialization steps that the executing core should
+ * perform at AmdInitEarly.
+ *
+ *  @CpuServiceInstances
+ *
+ * @param[in]  FamilyServices            The current Family Specific Services.
+ * @param[out] Table                     Table of appropriate init steps for the executing core.
+ * @param[in]  EarlyParams               CPU module early paramters.
+ * @param[in]  StdHeader                 Config handle for library and services
+ *
+ */
+typedef VOID F_GET_EARLY_INIT_TABLE (
+  IN       CPU_SPECIFIC_SERVICES                *FamilyServices,
+     OUT   CONST S_PERFORM_EARLY_INIT_ON_CORE   **Table,
+  IN       AMD_CPU_EARLY_PARAMS                 *EarlyParams,
+  IN       AMD_CONFIG_PARAMS                    *StdHeader
+  );
+/// Reference to a Method.
+typedef F_GET_EARLY_INIT_TABLE *PF_GET_EARLY_INIT_TABLE;
+
+
+/**
+ *  Returns if it's SecureS3
+ *
+ *  @CpuServiceInstances
+ *
+ *  @param[in]     StdHeader               Handle of Header for calling lib functions and services.
+ *
+ */
+typedef BOOLEAN F_IS_SECURE_S3 (
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a Method.
+typedef F_IS_SECURE_S3 *PF_IS_SECURE_S3;
+
+
+/**
+ *  Returns a model specific list of logical IDs.
+ *
+ *  @param[out]    LogicalIdXlat             Installed logical ID table.
+ *  @param[out]    NumberOfElements          Number of entries in the Logical ID translate table.
+ *  @param[out]    LogicalFamily             Base logical family bit mask.
+ *  @param[out]    HighestSupportedLogicalId Highest supported stepping
+ *  @param[in]     StdHeader                 Handle of Header for calling lib functions and services.
+ *
+ */
+typedef VOID F_CPU_GET_SUBFAMILY_ID_ARRAY (
+     OUT   CONST CPU_LOGICAL_ID_XLAT **LogicalIdXlat,
+     OUT   UINT8 *NumberOfElements,
+     OUT   UINT16 *LogicalFamily,
+     OUT   UINT16 *HighestSupportedLogicalId,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/// Reference to a method.
+typedef F_CPU_GET_SUBFAMILY_ID_ARRAY *PF_CPU_GET_SUBFAMILY_ID_ARRAY;
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Provide the interface to all cpu Family Specific Services.
+ *
+ * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!).
+ * Each supported Family must provide an implementation for all methods in this interface, even if the
+ * implementation is a CommonReturn().
+ * See CPU Family Specific Services Implementation Guide for adding new services.
+ */
+struct _CPU_SPECIFIC_SERVICES {                                                // See the Forwaqrd Declaration above
+  UINT16                                    Revision;                          ///< Interface version
+  // Public Methods.
+  PF_CPU_DISABLE_PSTATE                     DisablePstate;                     ///< Method: Disable the desired P-state.
+  PF_CPU_TRANSITION_PSTATE                  TransitionPstate;                  ///< Method: Transition the current core to the desired P-state.
+  PF_CPU_GET_IDD_MAX                        GetProcIddMax;                     ///< Method: Gets P-state maximum current required.
+  PF_CPU_GET_TSC_RATE                       GetTscRate;                        ///< Method: Returns the rate at which the current core's timestamp counter increments in megahertz.
+  PF_CPU_GET_NB_FREQ                        GetCurrentNbFrequency;             ///< Method: Returns the processor north bridge's clock rate in megahertz.
+  PF_CPU_GET_MIN_MAX_NB_FREQ                GetMinMaxNbFrequency;              ///< Method: Returns the node's minimum and maximum northbridge frequency.
+  PF_CPU_GET_NB_PSTATE_INFO                 GetNbPstateInfo;                   ///< Method: Returns information about the processor north bridge's P-states.
+  PF_CPU_IS_NBCOF_INIT_NEEDED               IsNbCofInitNeeded;                 ///< Method: Returns whether or not the NB frequency initialization sequence is required to be performed by the BIOS.
+  PF_CPU_GET_NB_IDD_MAX                     GetNbIddMax;                       ///< Method: Gets NB P-state maximum current required.
+  PF_CPU_AP_INITIAL_LAUNCH                  LaunchApCore;                      ///< Method: Launches the desired core from the reset vector.
+  PF_CPU_NUMBER_OF_PHYSICAL_CORES           GetNumberOfPhysicalCores;          ///< Method: Get the number of physical cores of current processor.
+  PF_CPU_GET_AP_CORE_NUMBER                 GetApCoreNumber;                   ///< Method: Get the AP's core number from hardware.
+  PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID    CoreIdPositionInInitialApicId;     ///< Method: Which bits in initial APIC Id are the Core Id.
+  PF_CPU_SET_WARM_RESET_FLAG                SetWarmResetFlag;                  ///< Method: Set Warm Reset Flag.
+  PF_CPU_GET_WARM_RESET_FLAG                GetWarmResetFlag;                  ///< Method: Get Warm Reset Flag.
+  PF_CPU_GET_FAMILY_SPECIFIC_ARRAY          GetMicroCodePatchesStruct;         ///< Method: Get microcode patches.
+  PF_CPU_GET_FAMILY_SPECIFIC_ARRAY          GetMicrocodeEquivalenceTable;      ///< Method: Get CPU equivalence for loading microcode patches.
+  PF_CPU_GET_FAMILY_SPECIFIC_ARRAY          GetCacheInfo;                      ///< Method: Get setup for cache use and initialization.
+  PF_CPU_GET_FAMILY_SPECIFIC_ARRAY          GetSysPmTableStruct;               ///< Method: Get Power Management settings.
+  PF_CPU_GET_FAMILY_SPECIFIC_ARRAY          GetWheaInitData;                   ///< Method: Get Whea Initial Data.
+  PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO    GetPlatformTypeSpecificInfo;       ///< Method: Get Specific platform Type features.
+  PF_IS_NB_PSTATE_ENABLED                   IsNbPstateEnabled;                 ///< Method: Get whether Northbridge PStates feature is enabled.
+  PF_DO_TABLE_ENTRY                         DoTableEntry[TableEntryTypeMax];   ///< Method: Table Entry Implementers
+  PF_GET_REGISTER_TABLE_LIST                GetRegisterTableList;              ///< Method: Returns the RegisterTableList.
+  PF_GET_WORKAROUND_TABLE                   GetWorkaroundTable;                ///< Method: Returns the workaround tables
+  COMPUTE_UNIT_MAP                          *ComputeUnitMap;                   ///< Public Data: Translate compute unit core pairing, or NULL.
+  FAMILY_CACHE_INIT_POLICY                  InitCacheDisabled;                 ///< Public Data: Family related information.
+  PF_GET_EARLY_INIT_TABLE                   GetEarlyInitBeforeApLaunchOnCoreTable; ///< Method: Get the initialization steps needed before AP launch.
+  PF_GET_EARLY_INIT_TABLE                   GetEarlyInitAfterApLaunchOnCoreTable; ///< Method: Get the initialization steps needed after AP launch.
+  PF_IS_SECURE_S3                           IsSecureS3;                        ///< Method: Check if it's SecureS3.
+  BOOLEAN                                   PatchLoaderIsSharedByCU;           ///< Public Data: Indicate if patch loader is shared by Compute Unit.
+};
+
+/**
+ * A Family Id and an interface to it's implementations of Family Specific Services.
+ *
+ * Note that this is a logical family id, which may specify family, model (or even stepping).
+ */
+typedef struct {
+  UINT64          Family;                         ///< The Family to which this interface belongs.
+  CONST VOID      *TablePtr;                      ///< The interface to its Family Specific Services.
+} CPU_SPECIFIC_SERVICES_XLAT;
+
+/**
+ * A collection of Family specific interfaces to Family Specific services.
+ */
+typedef struct {
+  UINT8  Elements;                                       ///< The number of tables to search.
+  CONST    CPU_SPECIFIC_SERVICES_XLAT *FamilyTable;      ///< The family interfaces.
+} CPU_FAMILY_SUPPORT_TABLE;
+
+/**
+ * Implement the translation of a logical CPU id to an id that can be used to get Family specific services.
+ */
+typedef struct {
+  UINT32 Family;                                              ///< Provide translation for this family
+  CPU_LOGICAL_ID UnknownRevision;                             ///< In this family, unrecognized models (or steppings) are treated as though they were this model and stepping.
+  CONST    PF_CPU_GET_SUBFAMILY_ID_ARRAY *SubFamilyIdTable;   ///< Method: Get family specific model (and stepping) resolution.
+  UINT8  Elements;                                            ///< The number of family specific model tables pointed to by SubFamilyIdTable
+} CPU_LOGICAL_ID_FAMILY_XLAT;
+
+/**
+ * A collection of all available family id translations.
+ */
+typedef struct {
+  UINT8  Elements;                                            ///< The number of family translation items to search.
+  CONST    CPU_LOGICAL_ID_FAMILY_XLAT *FamilyIdTable;         ///< The family translation items.
+} CPU_FAMILY_ID_XLAT_TABLE;
+
+/*---------------------------------------------------------------------------------------
+ *                        F U N C T I O N    P R O T O T Y P E
+ *---------------------------------------------------------------------------------------
+ */
+
+/**
+ * Get a logical identifier for the specified processor, based on CPUID, but independent of CPUID formatting.
+ */
+VOID
+GetLogicalIdOfSocket (
+  IN       UINT32 Socket,
+     OUT   CPU_LOGICAL_ID *LogicalId,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ * Get a logical identifier for the executing core, based on CPUID, but independent of CPUID formatting.
+ */
+VOID
+GetLogicalIdOfCurrentCore (
+     OUT   CPU_LOGICAL_ID *LogicalId,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ * Get a logical identifier for the specified CPUID value.
+ */
+VOID
+GetLogicalIdFromCpuid (
+  IN       UINT32 RawCpuid,
+     OUT   CPU_LOGICAL_ID *LogicalId,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ *  Retrieves a pointer to the executing core's family specific services structure.
+ */
+VOID
+GetCpuServicesOfCurrentCore (
+     OUT   CONST CPU_SPECIFIC_SERVICES **FunctionTable,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ *  Retrieves a pointer to the executing core's family specific services structure.
+ */
+VOID
+GetFeatureServicesOfCurrentCore (
+  IN       CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
+     OUT   CONST VOID        **CpuServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ *  Retrieves a pointer to the family specific services structure for a processor
+ *  with the given logical ID.
+ */
+VOID
+GetCpuServicesFromLogicalId (
+  IN       CPU_LOGICAL_ID *LogicalId,
+     OUT   CONST CPU_SPECIFIC_SERVICES **FunctionTable,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ *  Retrieves a pointer to the family specific services structure for a processor
+ *  with the given logical ID.
+ */
+VOID
+GetFeatureServicesFromLogicalId (
+  IN       CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
+  IN       CPU_LOGICAL_ID    *LogicalId,
+     OUT   CONST VOID        **CpuServices,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ * Used by logical families which don't need a certain register setting table or other data array.
+ */
+VOID
+GetEmptyArray (
+  IN       CPU_SPECIFIC_SERVICES  *FamilySpecificServices,
+     OUT   CONST VOID **Empty,
+     OUT   UINT8 *NumberOfElements,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+#endif  // _CPU_FAMILY_TRANSLATION_H_
+
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuServices.h b/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuServices.h
new file mode 100644
index 0000000..6614181
--- /dev/null
+++ b/src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuServices.h
@@ -0,0 +1,306 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD CPU Services
+ *
+ * Related to the General Services API's, but for the CPU component.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project:      AGESA
+ * @e sub-project:  CPU
+ * @e \$Revision$   @e \$Date$
+ *
+ */
+ /*****************************************************************************
+ *
+ * Copyright (c) 2008 - 2016, 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.
+ *
+ ***************************************************************************/
+
+#ifndef _CPU_SERVICES_H_
+#define _CPU_SERVICES_H_
+
+#include "Topology.h"
+
+/*----------------------------------------------------------------------------------------
+ *          M I X E D   (Definitions And Macros / Typedefs, Structures, Enums)
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ *                 D E F I N I T I O N S     A N D     M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+ /// WARM RESET STATE_BITS
+#define WR_STATE_COLD  00
+#define WR_STATE_RESET 01
+#define WR_STATE_EARLY 02
+#define WR_STATE_POST  03
+
+/*----------------------------------------------------------------------------------------
+ *               T Y P E D E F S,   S T R U C T U R E S,    E N U M S
+ *----------------------------------------------------------------------------------------
+ */
+
+/**
+ * The role of primary core for each compute unit can be relative to the cores' launch order.
+ *
+ * One core of a compute unit is always given the role as primary.  In different feature algorithms
+ * the core performing the primary core role can be designated relative to compute order.  In most cases,
+ * the primary core is the first core of a compute unit to execute.  However, in some cases the primary core
+ * role is associated with the last core to execute.
+ *
+ * If the launch order is strictly ascending, then first core is the lowest number and last core is highest.
+ * But if the launch order is not ascending, the first and last core follow the launch order, not the numbering order.
+ *
+ * Note that for compute units with only one core (AllCoresMapping), that core is primary for both orderings.
+ * (This includes processors without hardware compute units.)
+ *
+ */
+typedef enum {
+  FirstCoreIsComputeUnitPrimary,                   ///< the primary core role associates with the first core.
+  LastCoreIsComputeUnitPrimary,                    ///< the primary core role associates with the last core.
+  MaxComputeUnitPrimarySelector,                   ///< limit check.
+} COMPUTE_UNIT_PRIMARY_SELECTOR;
+
+/**
+ * The supported Core to Compute unit mappings.
+ */
+typedef enum {
+  AllCoresMapping,                            ///< All Cores are primary cores
+  EvenCoresMapping,                           ///< Compute units are even/odd core pairs.
+  TripleCoresMapping,                         ///< Compute units has three cores enabled.
+  QuadCoresMapping,                           ///< Compute units has four cores enabled.
+  BitMapMapping,                              ///< Currently not supported by any family, arbitrary core
+                                              ///< to compute unit mapping.
+  MaxComputeUnitMapping                       ///< Not a mapping, use for limit check.
+} COMPUTE_UNIT_MAPPING;
+
+/**
+ * Compute unit status register.
+ */
+
+/**
+ * Compute Unit Map entry.
+ * Provide for interpreting the core pairing for the processor's compute units.
+ *
+ * HT_LIST_TERMINAL as an Enabled value means the end of a list of map structs.
+ * Zero as an Enabled value implies Compute Units are not supported by the processor
+ * and the mapping is assumed to be AllCoresMapping.
+ *
+ */
+typedef struct {
+  UINT8 Enabled;                              ///< The value of the Enabled Compute Units
+  UINT8 DualCore;                             ///< The value of the Dual Core Compute Units
+  UINT8 TripleCore;                           ///< the value of the Triple Core Compute Units
+  UINT8 QuadCore;                             ///< the value of the Quad Core Compute Units
+  COMPUTE_UNIT_MAPPING Mapping;               ///< When the processor module matches these values, use this mapping method.
+} COMPUTE_UNIT_MAP;
+
+//----------------------------------------------------------------------------
+//                         CPU SYSTEM INFO TYPEDEFS, STRUCTURES, ENUMS
+//
+//----------------------------------------------------------------------------
+/// SYSTEM INFO
+typedef struct _SYSTEM_INFO {
+  UINT32            TotalNumberOfSockets;               ///< Total Number of Sockets
+  UINT32            TotalNumberOfCores;                 ///< Total Number Of Cores
+  UINT32            CurrentSocketNum;                   ///< Current Socket Number
+  UINT32            CurrentCoreNum;                     ///< Current Core Number
+  UINT32            CurrentCoreApicId;                  ///< Current Core Apic ID
+  UINT32            CurrentLogicalCpuId;                ///< Current Logical CPU ID
+} SYSTEM_INFO;
+
+/// WARM_RESET_REQUEST
+typedef struct _WARM_RESET_REQUEST {
+  UINT8             RequestBit:1;                       ///< Request Bit
+  UINT8             StateBits:2;                        ///< State Bits
+  UINT8             PostStage:2;                        ///< Post Stage
+  UINT8             Reserved:(8 - 5);                   ///< Reserved
+} WARM_RESET_REQUEST;
+/*----------------------------------------------------------------------------------------
+ *                        F U N C T I O N    P R O T O T Y P E
+ *----------------------------------------------------------------------------------------
+ */
+
+/**
+ * Get the current Platform's number of Sockets, regardless of how many are populated.
+ *
+ */
+UINT32
+GetPlatformNumberOfSockets ( VOID );
+
+/**
+ * Get the number of Modules to check presence in each Processor.
+ *
+ */
+UINT32
+GetPlatformNumberOfModules ( VOID );
+
+BOOLEAN
+IsProcessorPresent (
+  IN       UINT32            Socket,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ * For a specific Node, get its Socket and Module ids.
+ *
+ */
+BOOLEAN
+GetSocketModuleOfNode (
+  IN       UINT32    Node,
+     OUT   UINT32    *Socket,
+     OUT   UINT32    *Module,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ * Get the current core's Processor APIC Index.
+ */
+UINT32
+GetProcessorApicIndex (
+  IN       UINT32            Node,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ * Provide the number of installed processors (not Nodes! and not Sockets!)
+ */
+UINT32
+GetNumberOfProcessors (
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+VOID
+GetActiveCoresInCurrentSocket (
+     OUT   UINT32 *CoreCount,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+UINTN
+GetActiveCoresInCurrentModule (
+  IN       AMD_CONFIG_PARAMS  *StdHeader
+  );
+
+UINTN
+GetNumberOfCompUnitsInCurrentModule (
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+BOOLEAN
+GetGivenModuleCoreRange (
+  IN       UINT32            Socket,
+  IN       UINT32            Module,
+     OUT   UINT32            *LowCore,
+     OUT   UINT32            *HighCore,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+VOID
+GetCurrentCore (
+     OUT   UINT32 *Core,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+VOID
+GetCurrentNodeAndCore (
+     OUT   UINT32 *Node,
+     OUT   UINT32 *Core,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+BOOLEAN
+IsCurrentCorePrimary (
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+
+BOOLEAN
+GetNodeId (
+  IN       UINT32  SocketId,
+  IN       UINT32  ModuleId,
+     OUT   UINT8   *NodeId,
+  IN       AMD_CONFIG_PARAMS      *StdHeader
+  );
+
+VOID
+WaitMicroseconds (
+  IN       UINT32 Microseconds,
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+/**
+ * Get the compute unit mapping algorithm.
+ */
+COMPUTE_UNIT_MAPPING
+GetComputeUnitMapping (
+  IN      AMD_CONFIG_PARAMS    *StdHeader
+  );
+
+/**
+ * Does the current core have the role of primary core for the compute unit?
+ */
+BOOLEAN
+IsCoreComputeUnitPrimary (
+  IN       COMPUTE_UNIT_PRIMARY_SELECTOR Selector,
+  IN       AMD_CONFIG_PARAMS    *StdHeader
+  );
+
+VOID
+SetWarmResetFlag (
+  IN       AMD_CONFIG_PARAMS *StdHeader,
+  IN       WARM_RESET_REQUEST *Request
+  );
+
+VOID
+GetWarmResetFlag (
+  IN       AMD_CONFIG_PARAMS *StdHeader,
+     OUT   WARM_RESET_REQUEST *Request
+  );
+
+BOOLEAN
+IsWarmReset (
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+AGESA_STATUS
+CheckBistStatus (
+  IN       AMD_CONFIG_PARAMS *StdHeader
+  );
+
+VOID
+SetWarmResetAtEarly (
+  IN      UINT32            Data,
+  IN      AMD_CONFIG_PARAMS *StdHeader
+);
+
+#ifndef CPU_DEADLOOP
+  #define CPU_DEADLOOP()    { volatile UINTN __i; __i = 1; while (__i); }
+#endif
+
+#endif  // _CPU_SERVICES_H_
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchCommonCfg.h b/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchCommonCfg.h
index 46fa1a9..cc080c7 100644
--- a/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchCommonCfg.h
+++ b/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchCommonCfg.h
@@ -165,7 +165,7 @@ typedef struct _CODEC_ENTRY {
 ///
 typedef struct _CODEC_TBL_LIST {
   UINT32                CodecId;                        /// CodecID - Codec ID
-  CODEC_ENTRY*          CodecTablePtr;                  /// CodecTablePtr - Codec table pointer
+  const CODEC_ENTRY*    CodecTablePtr;                  /// CodecTablePtr - Codec table pointer
 } CODEC_TBL_LIST;
 
 ///
@@ -234,12 +234,12 @@ typedef struct {
 ///
 /// AZOEMTBL - Azalia Controller OEM Codec Table Pointer
 ///
-  CODEC_TBL_LIST        *AzaliaOemCodecTablePtr;        /// AzaliaOemCodecTablePtr - Oem Azalia Codec Table Pointer
+  const CODEC_TBL_LIST  *AzaliaOemCodecTablePtr;        /// AzaliaOemCodecTablePtr - Oem Azalia Codec Table Pointer
 
 ///
 /// AZOEMFPTBL - Azalia Controller Front Panel OEM Table Pointer
 ///
-  VOID                  *AzaliaOemFpCodecTablePtr;      /// AzaliaOemFpCodecTablePtr - Oem Front Panel Codec Table Pointer
+  const VOID            *AzaliaOemFpCodecTablePtr;      /// AzaliaOemFpCodecTablePtr - Oem Front Panel Codec Table Pointer
 } FCH_AZALIA;
 
 ///
@@ -1475,15 +1475,15 @@ typedef struct _FCH_RESET_DATA_BLOCK {
   BOOLEAN               FchOscout1ClkContinous;         ///< FCH OSCOUT1_CLK Continous
   UINT8                 LpcClockDriveStrength;          ///< Lpc Clock Drive Strength
   FCH_PT                Promontory;                     ///< Promontory structure
-  VOID*                 EarlyOemGpioTable;              /// Pointer of Early OEM GPIO table
+  const VOID*           EarlyOemGpioTable;              /// Pointer of Early OEM GPIO table
 //  VOID*                 OemSpiDeviceTable;              /// Pointer of OEM Spi Device table
 } FCH_RESET_DATA_BLOCK;
 
 
 /// Private: FCH_DATA_BLOCK
 typedef struct _FCH_DATA_BLOCK {
-  FCH_RUNTIME           FchRunTime;                     ///< FCH Run Time Parameters
   AMD_CONFIG_PARAMS     *StdHeader;                     ///< Header structure
+  FCH_RUNTIME           FchRunTime;                     ///< FCH Run Time Parameters
 
   FCH_ACPI              HwAcpi;                         ///< ACPI structure
   FCH_AB                Ab;                             ///< AB structure
@@ -1505,7 +1505,7 @@ typedef struct _FCH_DATA_BLOCK {
   FCH_MISC              Misc;                           ///< MISC structure
   FCH_IOMUX             IoMux;                          ///< MISC structure
   FCH_PT                Promontory;                     ///< Promontory structure
-  VOID*                 PostOemGpioTable;              /// Pointer of Post OEM GPIO table
+  const VOID*           PostOemGpioTable;               /// Pointer of Post OEM GPIO table
 } FCH_DATA_BLOCK;
 
 #pragma pack (pop)
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchLib.c b/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchLib.c
index 5836e5c..031027e 100644
--- a/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchLib.c
+++ b/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchLib.c
@@ -375,7 +375,7 @@ RwAlink (
     WriteAlink ((FCH_AX_INDXP_REG38 | AccessType), Index & 0x1FFFFFFF, StdHeader);
     Index = FCH_AX_DATAP_REG3C | AccessType;
   }
-  WriteAlink (Index, ReadAlink (Index, StdHeader) & AndMask | OrMask, StdHeader);
+  WriteAlink (Index, (ReadAlink (Index, StdHeader) & AndMask) | OrMask, StdHeader);
 }
 
 
@@ -669,4 +669,4 @@ ClearAllSmiStatus (
   for ( Index = 0; Index < 20; Index++ ) {
     ACPIMMIO8 (0xfed80280 + Index) |= 0;
   }
-}
\ No newline at end of file
+}
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchPeLib.c b/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchPeLib.c
index 9cd0e29..c833a9f 100644
--- a/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchPeLib.c
+++ b/src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchPeLib.c
@@ -579,94 +579,3 @@ FchGetScratchFuse (
 
   return TempData64;
 }
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Allocates space for a new buffer in the heap
- *
- *
- * @param[in]      Handle            Buffer handle
- * @param[in]      Length            Buffer length
- * @param[in]      StdHeader         Standard configuration header
- *
- * @retval         NULL              Buffer allocation fail
- *
- */
-
-VOID *
-FchAllocateHeapBuffer (
-  IN      UINT32              Handle,
-  IN      UINTN               Length,
-  IN      AMD_CONFIG_PARAMS   *StdHeader
-  )
-{
-  AGESA_STATUS          Status;
-  ALLOCATE_HEAP_PARAMS  AllocHeapParams;
-
-  AllocHeapParams.RequestedBufferSize = (UINT32) Length;
-  AllocHeapParams.BufferHandle = Handle;
-  AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
-  Status = HeapAllocateBuffer (&AllocHeapParams, StdHeader);
-  if (Status != AGESA_SUCCESS) {
-    return NULL;
-  }
-  return AllocHeapParams.BufferPtr;
-}
-
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Allocates space for a new buffer in the heap and clear it
- *
- *
- * @param[in]      Handle            Buffer handle
- * @param[in]      Length            Buffer length
- * @param[in]      StdHeader         Standard configuration header
- *
- * @retval         NULL              Buffer allocation fail
- *
- */
-
-VOID *
-FchAllocateHeapBufferAndClear (
-  IN      UINT32              Handle,
-  IN      UINTN               Length,
-  IN      AMD_CONFIG_PARAMS   *StdHeader
-  )
-{
-  VOID  *Buffer;
-  Buffer = FchAllocateHeapBuffer (Handle, Length, StdHeader);
-  if (Buffer != NULL) {
-    LibAmdMemFill (Buffer, 0x00, Length, StdHeader);
-  }
-  return Buffer;
-}
-
-/*---------------------------------------------------------------------------------------*/
-/**
- * Locates a previously allocated buffer on the heap.
- *
- *
- * @param[in]      Handle            Buffer handle
- * @param[in]      StdHeader         Standard configuration header
- *
- * @retval         NULL              Buffer handle not found
- *
- */
-
-VOID *
-MemLocateHeapBuffer (
-  IN      UINT32              Handle,
-  IN      AMD_CONFIG_PARAMS   *StdHeader
-  )
-{
-  AGESA_STATUS          Status;
-  LOCATE_HEAP_PTR       LocHeapParams;
-  LocHeapParams.BufferHandle = Handle;
-  Status = HeapLocateBuffer (&LocHeapParams, StdHeader);
-  if (Status != AGESA_SUCCESS) {
-    return NULL;
-  }
-  return LocHeapParams.BufferPtr;
-}
-
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c b/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c
index 5c2410d..e49fb78 100644
--- a/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c
+++ b/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c
@@ -155,7 +155,7 @@ typedef enum {
   UNSUPPORTED_PROGRAM = 0xFF,   ///< Program ID for unsupported
 } PROGRAM_ID;
 
-PROGRAM_ID
+static PROGRAM_ID
 PspGetProgarmId (
   VOID
   )
@@ -291,7 +291,7 @@ PspSoftWareFuseInfo (
   return (FALSE);
 }
 
-UINT32 Fletcher32 (
+static UINT32 Fletcher32 (
   IN OUT   UINT16  *data,
   IN       UINTN   words
   )
@@ -567,7 +567,7 @@ ReleasePspSmiRegMutex (
 
 
 UINT8
-PspLibAccessWidth (
+static PspLibAccessWidth (
   IN       ACCESS_WIDTH AccessWidth
   )
 {
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.h b/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.h
index e7f5a47..3af9c3d 100644
--- a/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.h
+++ b/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.h
@@ -211,7 +211,7 @@ GetPspMboxStatus (
 
 
 BOOLEAN
-PspBarInitEarly ();
+PspBarInitEarly (VOID);
 
 VOID
 PspLibPciIndirectRead (
@@ -230,7 +230,7 @@ PspLibPciIndirectWrite (
   );
 
 BOOLEAN
-IsS3Resume ();
+IsS3Resume (VOID);
 
 
 #endif // _AMD_LIB_H_



More information about the coreboot-gerrit mailing list