summaryrefslogtreecommitdiffstats
path: root/src/vendorcode/amd
diff options
context:
space:
mode:
authorMarshall Dawson <marshalldawson3rd@gmail.com>2016-10-15 09:45:44 -0600
committerMartin Roth <martinroth@google.com>2016-11-07 20:36:34 +0100
commitf3093883f7336054f344072c5b086998dc5f72c2 (patch)
tree76adabcbba91916e9dab906e5f1b0aee345ba617 /src/vendorcode/amd
parenta04006513008ef72a863bc0eb04e6d4f729ca8ab (diff)
downloadcoreboot-f3093883f7336054f344072c5b086998dc5f72c2.tar.gz
coreboot-f3093883f7336054f344072c5b086998dc5f72c2.tar.bz2
coreboot-f3093883f7336054f344072c5b086998dc5f72c2.zip
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@gmail.com> Original-Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com> (cherry picked from commit f7ea2785d70bd6813b5b4d315b064802251d9557) Change-Id: Ie36228476a9dbd7b83f95828ca9c7252cecd8ec8 Signed-off-by: Marc Jones <marcj303@gmail.com> Reviewed-on: https://review.coreboot.org/17195 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/vendorcode/amd')
-rw-r--r--src/vendorcode/amd/pi/00670F00/AGESA.h10
-rw-r--r--src/vendorcode/amd/pi/00670F00/AMD.h66
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/CPU/Table.h915
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuFamilyTranslation.c442
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuFamilyTranslation.h861
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/CPU/cpuServices.h306
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchCommonCfg.h12
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchLib.c4
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/Fch/Common/FchPeLib.c91
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c6
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.h4
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 311e87627643..ee9c629ac0af 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 a111ceebaea4..003ac0e19a12 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 000000000000..fe3b3c07e214
--- /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 000000000000..5699d920f915
--- /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 000000000000..743b5f678d90
--- /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 000000000000..66141818cda0
--- /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 46fa1a9bdb4c..cc080c768072 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 5836e5c1763c..031027eedf8b 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 9cd0e295574b..c833a9f2a65c 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 5c2410d7d462..e49fb789eb61 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 e7f5a47d8d49..3af9c3dd99d4 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_