diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h')
-rw-r--r-- | src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h | 1314 |
1 files changed, 1314 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h new file mode 100644 index 0000000000..1f6341abe9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h @@ -0,0 +1,1314 @@ +/* $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: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, 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_ + +#define MAX_ENTRY_TYPE_ITEMS32 6 // The maximum number of initializer items for UINT32 entry data types. + +/** + * @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. + * + */ +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. + HtPhyRegister, ///< Processor HT Phy registers. + HtPhyRangeRegister, ///< Processor HT Phy range of contiguous registers (ex. 40h:48h). + DeemphasisRegister, ///< Processor Deemphasis register (HT Phy special case). + HtPhyFreqRegister, ///< Processor Frequency dependent HT Phy settings. + ProfileFixup, ///< Processor Performance Profile fixups to PCI Config Registers. + HtHostPciRegister, ///< Processor Ht Host capability registers (PCI Config). + HtHostPerfPciRegister, ///< Processor Ht Host capability registers which depend on performance features. + HtTokenPciRegister, ///< Processor Ht Link Token count registers. + CoreCountsPciRegister, ///< Processor PCI Config Registers which depend on core counts. + ProcCountsPciRegister, ///< Processor PCI Config Registers which depend on processor counts. + CompUnitCountsPciRegister, ///< Processor PCI Config Registers which depend on compute unit counts. + TokenPciRegister, ///< Processor northbridge Token Count register which may be dependent on connectivity. + HtFeatPciRegister, ///< Processor HT Link feature dependant PCI Config Registers. + HtPhyProfileRegister, ///< Processor HT Phy registers which depend on performance features. + HtLinkPciRegister, ///< Processor HT Link registers (one per link) not part of HT Host capability. + CompUnitCountsMsr, ///< Processor MSRs which depend on compute unit counts. + TableEntryTypeMax ///< Not a valid entry type, use for limit checking. +} 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; + +//---------------------------------------------------------------------------- +// 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 + +// TimePoint +#define PERFORM_TP_AFTER_AP_LAUNCH 0x40000000ul // bit 30 --- the related function needs to be run after AP launch +#define PERFORM_TP_BEFORE_AP_LAUNCH 0x80000000ul // bit 31 --- the related function needs to be run before AP launch + +#define PERFORM_TP_ALL (PERFORM_TP_AFTER_AP_LAUNCH | PERFORM_TP_BEFORE_AP_LAUNCH) + +#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; + +// Sublink Types are defined so they can match each attribute against either +// sublink zero or one. The table entry must contain the correct matching +// values based on the register. This is available in the BKDG, for each register +// which sublink it controls. If the register is independent of sublink, OR values +// together or use HT_LINKTYPE_ALL to match if either sublink matches (ex. E0 - E5). +// Sublink 0 types, bits 0 thru 14 +#define HTPHY_LINKTYPE_SL0_HT3 BIT0 +#define HTPHY_LINKTYPE_SL0_HT1 BIT1 +#define HTPHY_LINKTYPE_SL0_COHERENT BIT2 +#define HTPHY_LINKTYPE_SL0_NONCOHERENT BIT3 +#define HTPHY_LINKTYPE_SL0_LINK0 BIT4 +#define HTPHY_LINKTYPE_SL0_LINK1 BIT5 +#define HTPHY_LINKTYPE_SL0_LINK2 BIT6 +#define HTPHY_LINKTYPE_SL0_LINK3 BIT7 +#define HTPHY_LINKTYPE_SL0_INTERNAL BIT8 +#define HTPHY_LINKTYPE_SL0_EXTERNAL BIT9 +#define HTPHY_LINKTYPE_SL0_AND BIT15 + +// SubLink 1 types, bits 16 thru 30 +#define HTPHY_LINKTYPE_SL1_HT3 BIT16 +#define HTPHY_LINKTYPE_SL1_HT1 BIT17 +#define HTPHY_LINKTYPE_SL1_COHERENT BIT18 +#define HTPHY_LINKTYPE_SL1_NONCOHERENT BIT19 +#define HTPHY_LINKTYPE_SL1_LINK4 BIT20 +#define HTPHY_LINKTYPE_SL1_LINK5 BIT21 +#define HTPHY_LINKTYPE_SL1_LINK6 BIT22 +#define HTPHY_LINKTYPE_SL1_LINK7 BIT23 +#define HTPHY_LINKTYPE_SL1_INTERNAL BIT24 +#define HTPHY_LINKTYPE_SL1_EXTERNAL BIT25 +#define HTPHY_LINKTYPE_SL1_AND BIT31 + +#define HTPHY_LINKTYPE_SL0_ALL (HTPHY_LINKTYPE_SL0_HT3 | \ + HTPHY_LINKTYPE_SL0_HT1 | \ + HTPHY_LINKTYPE_SL0_COHERENT | \ + HTPHY_LINKTYPE_SL0_NONCOHERENT | \ + HTPHY_LINKTYPE_SL0_LINK0 | \ + HTPHY_LINKTYPE_SL0_LINK1 | \ + HTPHY_LINKTYPE_SL0_LINK2 | \ + HTPHY_LINKTYPE_SL0_LINK3 | \ + HTPHY_LINKTYPE_SL0_INTERNAL | \ + HTPHY_LINKTYPE_SL0_EXTERNAL) +#define HTPHY_LINKTYPE_SL1_ALL (HTPHY_LINKTYPE_SL1_HT3 | \ + HTPHY_LINKTYPE_SL1_HT1 | \ + HTPHY_LINKTYPE_SL1_COHERENT | \ + HTPHY_LINKTYPE_SL1_NONCOHERENT | \ + HTPHY_LINKTYPE_SL1_LINK4 | \ + HTPHY_LINKTYPE_SL1_LINK5 | \ + HTPHY_LINKTYPE_SL1_LINK6 | \ + HTPHY_LINKTYPE_SL1_LINK7 | \ + HTPHY_LINKTYPE_SL1_INTERNAL | \ + HTPHY_LINKTYPE_SL1_EXTERNAL) +#define HTPHY_LINKTYPE_ALL (HTPHY_LINKTYPE_SL0_ALL | HTPHY_LINKTYPE_SL1_ALL) + +#define HTPHY_REGISTER_MAX 0x0000FFFFul +/** + * HT PHY Link Features + */ +typedef struct { + UINT32 HtPhySL0Ht3:1; ///< Ht Phy Sub-link 0 Ht3 + UINT32 HtPhySL0Ht1:1; ///< Ht Phy Sub-link 0 Ht1 + UINT32 HtPhySL0Coh:1; ///< Ht Phy Sub-link 0 Coherent + UINT32 HtPhySL0NonCoh:1; ///< Ht Phy Sub-link 0 NonCoherent + UINT32 HtPhySL0Link0:1; ///< Ht Phy Sub-link 0 specifically for node link 0. + UINT32 HtPhySL0Link1:1; ///< Ht Phy Sub-link 0 specifically for node link 1. + UINT32 HtPhySL0Link2:1; ///< Ht Phy Sub-link 0 specifically for node link 2. + UINT32 HtPhySL0Link3:1; ///< Ht Phy Sub-link 0 specifically for node link 3. + UINT32 HtPhySL0Internal:1; ///< Ht Phy Sub-link 0 is internal link. Intended for IDS support. + UINT32 HtPhySL0External:1; ///< Ht Phy Sub-link 0 is external link. Intended for IDS support. + UINT32 :(14 - 9); ///< Ht Phy Sub-link 0 Pad + UINT32 HtPhySL0And:1; ///< Ht Phy feature match should match all selected features, for sub-link 0. + UINT32 HtPhySL1Ht3:1; ///< Ht Phy Sub-link 1 Ht3 + UINT32 HtPhySL1Ht1:1; ///< Ht Phy Sub-link 1 Ht1 + UINT32 HtPhySL1Coh:1; ///< Ht Phy Sub-link 1 Coherent + UINT32 HtPhySL1NonCoh:1; ///< Ht Phy Sub-link 1 NonCoherent + UINT32 HtPhySL1Link4:1; ///< Ht Phy Sub-link 1 specifically for node link 4. + UINT32 HtPhySL1Link5:1; ///< Ht Phy Sub-link 1 specifically for node link 5. + UINT32 HtPhySL1Link6:1; ///< Ht Phy Sub-link 1 specifically for node link 6. + UINT32 HtPhySL1Link7:1; ///< Ht Phy Sub-link 1 specifically for node link 7. + UINT32 HtPhySL1Internal:1; ///< Ht Phy Sub-link 1 is internal link. Intended for IDS support. + UINT32 HtPhySL1External:1; ///< Ht Phy Sub-link 1 is external link. Intended for IDS support. + UINT32 :(30 - 25); ///< Ht Phy Sub-link 1 Pad + UINT32 HtPhySL1And:1; ///< Ht Phy feature match should match all selected features, for sub-link 1. +} HT_PHY_LINK_FEATURES; + +/** + * Ht Phy Link Features + */ +typedef union { + UINT32 HtPhyLinkValue; ///< Describe HY Phy Features in UINT32. + ///< This one goes first, because then initializers use it automatically for the union. + HT_PHY_LINK_FEATURES HtPhyLinkFeatures; ///< Describe HT Phy Features in structure. +} HT_PHY_LINK_FEATS; + +// DB Level for initializing Deemphasis +// This must be in sync with DEEMPHASIS_FEATURES and PLATFORM_DEEMPHASIS_LEVEL (agesa.h) +#define DEEMPHASIS_LEVEL_NONE BIT0 +#define DEEMPHASIS_LEVEL__3 BIT1 +#define DEEMPHASIS_LEVEL__6 BIT2 +#define DEEMPHASIS_LEVEL__8 BIT3 +#define DEEMPHASIS_LEVEL__11 BIT4 +#define DEEMPHASIS_LEVEL__11_8 BIT5 +#define DCV_LEVEL_NONE BIT16 +#define DCV_LEVEL__2 BIT17 +#define DCV_LEVEL__3 BIT18 +#define DCV_LEVEL__5 BIT19 +#define DCV_LEVEL__6 BIT20 +#define DCV_LEVEL__7 BIT21 +#define DCV_LEVEL__8 BIT22 +#define DCV_LEVEL__9 BIT23 +#define DCV_LEVEL__11 BIT24 +// Note that an "AND" feature doesn't make any sense, levels are mutually exclusive. + +// An error check value. +#define DEEMPHASIS_LEVELS_ALL (DEEMPHASIS_LEVEL_NONE | \ + DEEMPHASIS_LEVEL__3 | \ + DEEMPHASIS_LEVEL__6 | \ + DEEMPHASIS_LEVEL__8 | \ + DEEMPHASIS_LEVEL__11 | \ + DEEMPHASIS_LEVEL__11_8) + +#define DCV_LEVELS_ALL (DCV_LEVEL_NONE | \ + DCV_LEVEL__2 | \ + DCV_LEVEL__3 | \ + DCV_LEVEL__5 | \ + DCV_LEVEL__6 | \ + DCV_LEVEL__7 | \ + DCV_LEVEL__8 | \ + DCV_LEVEL__9 | \ + DCV_LEVEL__11) + +#define VALID_DEEMPHASIS_LEVELS (DEEMPHASIS_LEVELS_ALL | DCV_LEVELS_ALL) + +/** + * Deemphasis Ht Phy Link Deemphasis. + * + * This must be in sync with defines above and ::PLATFORM_DEEMPHASIS_LEVEL (agesa.h) + */ +typedef struct { + UINT32 DeemphasisLevelNone:1; ///< The deemphasis level None. + UINT32 DeemphasisLevelMinus3:1; ///< The deemphasis level minus 3 db. + UINT32 DeemphasisLevelMinus6:1; ///< The deemphasis level minus 6 db. + UINT32 DeemphasisLevelMinus8:1; ///< The deemphasis level minus 8 db. + UINT32 DeemphasisLevelMinus11:1; ///< The deemphasis level minus 11 db. + UINT32 DeemphasisLevelMinus11w8:1; ///< The deemphasis level minus 11 db, minus 8 precursor. + UINT32 :(15 - 5); ///< reserved. + UINT32 DcvLevelNone:1; ///< The level for DCV None. + UINT32 DcvLevelMinus2:1; ///< The level for DCV minus 2 db. + UINT32 DcvLevelMinus3:1; ///< The level for DCV minus 3 db. + UINT32 DcvLevelMinus5:1; ///< The level for DCV minus 5 db. + UINT32 DcvLevelMinus6:1; ///< The level for DCV minus 6 db. + UINT32 DcvLevelMinus7:1; ///< The level for DCV minus 7 db. + UINT32 DcvLevelMinus8:1; ///< The level for DCV minus 8 db. + UINT32 DcvLevelMinus9:1; ///< The level for DCV minus 9 db. + UINT32 DcvLevelMinus11:1; ///< The level for DCV minus 11 db. + UINT32 :(15 - 8); ///< reserved. +} DEEMPHASIS_FEATURES; + +/** + * Deemphasis Ht Phy Link Features. + */ +typedef union { + UINT32 DeemphasisValues; ///< Initialize HT Deemphasis in UINT32. + DEEMPHASIS_FEATURES DeemphasisLevels; ///< HT Deemphasis levels. +} DEEMPHASIS_FEATS; + +// Initializer bit patterns for PERFORMANCE_PROFILE_FEATS. +#define PERFORMANCE_REFRESH_REQUEST_32B BIT0 +#define PERFORMANCE_PROBEFILTER BIT1 +#define PERFORMANCE_L3_CACHE BIT2 +#define PERFORMANCE_NO_L3_CACHE BIT3 +#define PERFORMANCE_MCT_ISOC_VARIABLE BIT4 +#define PERFORMANCE_IS_WARM_RESET BIT5 +#define PERFORMANCE_VRM_HIGH_SPEED_ENABLE BIT6 +#define PERFORMANCE_NB_PSTATES_ENABLE BIT7 +#define PERFORMANCE_AND BIT31 + +#define PERFORMANCE_PROFILE_ALL (PERFORMANCE_REFRESH_REQUEST_32B | \ + PERFORMANCE_PROBEFILTER | \ + 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 ProbeFilter:1; ///< BIT_1 Probe Filter will be enabled. + UINT32 L3Cache:1; ///< BIT_2 L3 Cache is present. + UINT32 NoL3Cache:1; ///< BIT_3 L3 Cache is NOT present. + UINT32 MctIsocVariable:1; ///< BIT_4 Mct Isoc Read Priority set to variable. + UINT32 IsWarmReset:1; ///< BIT_5 This boot is on a warm reset, cold reset pass is already completed. + UINT32 VrmHighSpeed:1; ///< BIT_6 Select high speed VRM. + UINT32 NbPstates:1; ///< BIT_7 Northbridge PStates are enabled + UINT32 :(30 - 7); ///< 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; + +/** + * Package Type Features + * + */ +typedef struct { + UINT32 PkgType0:1; ///< Package Type 0 + UINT32 PkgType1:1; ///< Package Type 1 + UINT32 PkgType2:1; ///< Package Type 2 + UINT32 PkgType3:1; ///< Package Type 3 + UINT32 PkgType4:1; ///< Package Type 4 + UINT32 PkgType5:1; ///< Package Type 5 + UINT32 PkgType6:1; ///< Package Type 6 + UINT32 PkgType7:1; ///< Package Type 7 + UINT32 PkgType8:1; ///< Package Type 8 + UINT32 PkgType9:1; ///< Package Type 9 + UINT32 PkgType10:1; ///< Package Type 10 + UINT32 PkgType11:1; ///< Package Type 11 + UINT32 PkgType12:1; ///< Package Type 12 + UINT32 PkgType13:1; ///< Package Type 13 + UINT32 PkgType14:1; ///< Package Type 14 + UINT32 PkgType15:1; ///< Package Type 15 + UINT32 Reserved:15; ///< Package Type Reserved + UINT32 ReservedAndFeats:1; ///< BIT_31. AND other selected features. Always zero here. +} PACKAGE_TYPE_FEATURES; + +// Initializer Values for Package Type +#define PACKAGE_TYPE_ALL 0XFFFF ///< Package Type apply all packages + +// Initializer Values for Ht Host Pci Config Registers +#define HT_HOST_FEAT_COHERENT BIT0 +#define HT_HOST_FEAT_NONCOHERENT BIT1 +#define HT_HOST_FEAT_GANGED BIT2 +#define HT_HOST_FEAT_UNGANGED BIT3 +#define HT_HOST_FEAT_HT3 BIT4 +#define HT_HOST_FEAT_HT1 BIT5 +#define HT_HOST_AND BIT31 + +#define HT_HOST_FEATURES_ALL (HT_HOST_FEAT_COHERENT | \ + HT_HOST_FEAT_NONCOHERENT | \ + HT_HOST_FEAT_GANGED | \ + HT_HOST_FEAT_UNGANGED | \ + HT_HOST_FEAT_HT3 | \ + HT_HOST_FEAT_HT1) + +/** + * HT Host PCI register features. + * + * Links which are not connected do not match any of these features. + */ +typedef struct { + UINT32 Coherent:1; ///< BIT_0 Apply to links with a coherent connection. + UINT32 NonCoherent:1; ///< BIT_1 Apply to links with a non-coherent connection. + UINT32 Ganged:1; ///< BIT_2 Apply to links with a ganged connection. + UINT32 UnGanged:1; ///< BIT_3 Apply to links with a unganged connection. + UINT32 Ht3:1; ///< BIT_4 Apply to links with HT3 frequency (> 1000 MHz) + UINT32 Ht1:1; ///< BIT_5 Apply to links with HT1 frequency (< 1200 MHz) + UINT32 :(30 - 5); ///< Future expansion. + UINT32 AndHtHostFeats:1; ///< BIT_31. AND other selected features. +} HT_HOST_FEATURES; + +/** + * HT Host features for table data. + */ +typedef union { + UINT32 HtHostValue; ///< Initializer value. + HT_HOST_FEATURES HtHostFeatures; ///< The HT Host Features. +} HT_HOST_FEATS; + +// 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; + +/** + * Processor count ranges for table data. + * + * Provide a pair of processor count ranges. If the actual counts are included in either range (OR), + * the feature should be considered a match. + */ +typedef union { + UINT32 ProcessorCountRangeValue; ///< Initializer value. + COUNT_RANGE_FEATURE ProcessorCountRanges; ///< The Processor and Node Counts. +} PROCESSOR_COUNTS; + +/** + * 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; + +/** + * Connectivity count ranges for table data. + * + * Provide a processor count range and a system degree range. The degree of a system is + * the maximum degree of any node. The degree of a node is the number of nodes to which + * it is directly connected (not considering width or redundant links). If both the actual + * counts are included in each range (AND), the feature should be considered a match. + */ +typedef union { + UINT32 ConnectivityCountRangeValue; ///< Initializer value. + COUNT_RANGE_FEATURE ConnectivityCountRanges; ///< The Processor and Degree Counts. +} CONNECTIVITY_COUNT; + +/** + * HT Frequency Count Range. + * + * Provide a pair of Frequency count ranges, with the frequency encoded as an HT Frequency value + * (such as would be programmed into the HT Host Link Frequency register). By converting a NB freq, + * the same count can be applied for it. If the actual value is included in either range + */ +typedef union { + UINT32 HtFreqCountRangeValue; ///< Initializer value. + COUNT_RANGE_FEATURE HtFreqCountRanges; ///< The HT Freq counts. +} HT_FREQ_COUNTS; + +/*------------------------------------------------------------------------------------------*/ +/* + * The specific data for each table entry. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * Make an extra type so we can use compilers that don't support designated initializers. + * + * All the entry type unions are no more than 5 UINT32's in size. For entry types which are a struct of UINT32's, + * this type can be used so that initializers can be declared TABLE_ENTRY_FIELDS, instead of a special non-union type. + * A non-union type then has to be cast back to TABLE_ENTRY_FIELDS in order to process the table, and you can't mix + * entry types with non-union initializers in the same table with any other type. + * + * If the entry type contains anything but UINT32's, then it must have a non-union initializer type for creating the + * actual tables. For example, MSR entry has UINT64 and workaround entry has a function pointer. + */ +typedef UINT32 GENERIC_TYPE_ENTRY_INITIALIZER[MAX_ENTRY_TYPE_ITEMS32]; + +/** + * 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; + +/** + * 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; + +/** + * Table Entry Data for HT Phy Registers. + * + * Apply data to register after mask, for HT Phy registers, repeated for all active links. + */ +typedef struct { + HT_PHY_LINK_FEATS TypeFeats; ///< HT Phy Link Features + UINT32 Address; ///< Address of Ht Phy Register + 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. +} HT_PHY_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for HT Phy Register Ranges. + * + * Apply data to register after mask, for a range of HT Phy registers, repeated for all active links. + */ +typedef struct { + HT_PHY_LINK_FEATS TypeFeats; ///< HT Phy Link Features + UINT32 LowAddress; ///< Low address of Ht Phy Register range. + UINT32 HighAddress; ///< High address of register range. + 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. +} HT_PHY_RANGE_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for HT Phy Deemphasis Registers. + * + * Apply data to register after mask, for HT Phy registers, repeated for all active links. + */ +typedef struct { + DEEMPHASIS_FEATS Levels; ///< The DCV and Deemphasis levels to match + HT_PHY_TYPE_ENTRY_DATA HtPhyEntry; ///< The HT Phy Entry to set the deemphasis values +} DEEMPHASIS_HT_PHY_TYPE_ENTRY_DATA; + +/** + * Table Entry Date for HT Phy Frequency Count Register updates. + * + * Compare the NB freq to a range, the HT freq to a range, the link features. + * Apply data to register after mask, if all three matched. + */ +typedef struct { + HT_FREQ_COUNTS HtFreqCounts; ///< Specify the HT Frequency range. + HT_FREQ_COUNTS NbFreqCounts; ///< Specify the NB Frequency range. + HT_PHY_TYPE_ENTRY_DATA HtPhyEntry; ///< The HT Phy register update to perform. +} HT_PHY_FREQ_TYPE_ENTRY_DATA; + +/** + * 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; + +/** + * A variation of PCI register for the HT Host registers. + * + * A setting to the HT Host buffer counts needs to be made to all the registers for + * all the links. There are also link specific criteria to check. + */ +typedef struct { + HT_HOST_FEATS TypeFeats; ///< Link Features. + PCI_ADDR Address; ///< Address of PCI Register to Fixed Up. + 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. +} HT_HOST_PCI_TYPE_ENTRY_DATA; + +/** + * A variation of PCI register for the HT Host performance registers. + * + * A setting to the HT Host buffer counts needs to be made to all the registers for + * all the links. There are also link specific criteria to check. + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS PerformanceFeats; ///< Performance Profile features. + HT_HOST_PCI_TYPE_ENTRY_DATA HtHostEntry; ///< Link Features. +} HT_HOST_PERFORMANCE_PCI_TYPE_ENTRY_DATA; + +/** + * A variation of HT Host PCI register for the Link Token registers. + * + * Use Link Features, Performance Fixup features, and processor counts to match entries. + * Link Features are iterated through the connected links. All the matching Link Token count + * registers are updated. + */ +typedef struct { + CONNECTIVITY_COUNT ConnectivityCount; ///< Specify Processor count and Degree count range. + PERFORMANCE_PROFILE_FEATS PerformanceFeats; ///< Performance Profile features. + HT_HOST_FEATS LinkFeats; ///< Link Features. + PCI_ADDR Address; ///< Address of PCI Register to Fixed Up. + 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. +} HT_TOKEN_PCI_REGISTER; + +/** + * 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; + +/** + * Processor Count dependent PCI registers. + * + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + PROCESSOR_COUNTS ProcessorCounts; ///< Specify a processor count range. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} PROCESSOR_COUNTS_PCI_TYPE_ENTRY_DATA; + +/** + * 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; + +/** + * 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; + +/** + * System connectivity dependent PCI registers. + * + * The topology specific recommended settings are based on the different connectivity of nodes + * in each configuration: the more connections, the fewer resources each connection gets. + * The connectivity criteria translate as: + * - 2 Socket, half populated == Degree 1 + * - 4 Socket, half populated == Degree 2 + * - 2 Socket, fully populated == Degree 3 + * - 4 Socket, fully populated == Degree > 3. (4 or 5 if 3P, 6 if 4P) + * + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + CONNECTIVITY_COUNT ConnectivityCount; ///< Specify a system degree range. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} CONNECTIVITY_COUNTS_PCI_TYPE_ENTRY_DATA; + +/** + * 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 { + PF_FAM_SPECIFIC_WORKAROUND DoAction; ///< A function implementing the workaround. + UINT32 Data; ///< This data is passed to DoAction(). +} FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA; + +/** + * Package Type Features + * + * FamilyPackageType are various among CPU families. + * + */ +typedef union { + UINT32 PackageTypeValue; ///< Package Type + PACKAGE_TYPE_FEATURES FamilyPackageType; ///< Package Type of CPU family +} PACKAGE_TYPE_FEATS; + +/** + * HT Features dependent Global PCI registers. + * + */ +typedef struct { + HT_HOST_FEATS LinkFeats; ///< Link Features. + PACKAGE_TYPE_FEATS PackageType; ///< Package Type + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} HT_FEATURES_PCI_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for HT Phy Registers which depend on performance profile features. + * + * Match performance profile features and link features. + * Apply data to register after mask, for HT Phy registers, repeated for all active links. + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + HT_PHY_TYPE_ENTRY_DATA HtPhyEntry; ///< The HT Phy Entry to set the deemphasis values +} PROFILE_HT_PHY_TYPE_ENTRY_DATA; + +/** + * HT Link PCI registers that are not in the HT Host capability. + * + * Some HT Link registers have an instance per link, but are just sequential. Specify the base register + * in the table register address (link 0 sublink 0). + */ +typedef struct { + HT_HOST_FEATS LinkFeats; ///< Link Features. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} HT_LINK_PCI_TYPE_ENTRY_DATA; + +/*------------------------------------------------------------------------------------------*/ +/* + * A complete register table and table entries. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * All the available entry data types. + */ +typedef union { + GENERIC_TYPE_ENTRY_INITIALIZER InitialValues; ///< Not a valid entry type; as the first union item, + ///< it can be used with initializers. + 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. + HT_PHY_TYPE_ENTRY_DATA HtPhyEntry; ///< HT Phy entry. + HT_PHY_RANGE_TYPE_ENTRY_DATA HtPhyRangeEntry; ///< A range of Ht Phy Registers + DEEMPHASIS_HT_PHY_TYPE_ENTRY_DATA DeemphasisEntry; ///< A HT Deemphasis level's settings. + HT_PHY_FREQ_TYPE_ENTRY_DATA HtPhyFreqEntry; ///< A frequency dependent Ht Phy Register setting. + PROFILE_FIXUP_TYPE_ENTRY_DATA FixupEntry; ///< Profile Fixup entry. + HT_HOST_PCI_TYPE_ENTRY_DATA HtHostEntry; ///< HT Host PCI entry. + HT_HOST_PERFORMANCE_PCI_TYPE_ENTRY_DATA HtHostPerfEntry; ///< HT Host Performance PCI entry + HT_TOKEN_PCI_REGISTER HtTokenEntry; ///< HT Link Token Count entry. + CORE_COUNTS_PCI_TYPE_ENTRY_DATA CoreCountEntry; ///< Core count dependent settings. + PROCESSOR_COUNTS_PCI_TYPE_ENTRY_DATA ProcCountEntry; ///< Processor count entry. + COMPUTE_UNIT_COUNTS_PCI_TYPE_ENTRY_DATA CompUnitCountEntry; ///< Compute unit count dependent entry. + CONNECTIVITY_COUNTS_PCI_TYPE_ENTRY_DATA TokenPciEntry; ///< System connectivity dependent Token register. + HT_FEATURES_PCI_TYPE_ENTRY_DATA HtFeatPciEntry; ///< HT Features PCI entry. + PROFILE_HT_PHY_TYPE_ENTRY_DATA HtPhyProfileEntry; ///< Performance dependent HT Phy register. + HT_LINK_PCI_TYPE_ENTRY_DATA HtLinkPciEntry; ///< Per Link, non HT Host, PCI registers. + COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA CompUnitCountMsrEntry; ///< Compute unit count dependent MSR entry. +} TABLE_ENTRY_DATA; + +/** + * Register Table Entry common fields. + * + * All the various types of register table entries are subclasses of this object. + */ +typedef struct { + TABLE_ENTRY_TYPE EntryType; ///< The type of table entry this is. + CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria. + PLATFORM_FEATS Features; ///< Common Platform Features match criteria. + TABLE_ENTRY_DATA Entry; ///< The type dependent entry data (ex. register, data, mask). +} TABLE_ENTRY_FIELDS; + +/** + * An entire register table. + */ +typedef struct { + TABLE_CORE_SELECTOR Selector; ///< For efficiency, these cores should process this table + UINT32 TimePoint; ///< Time Point designator + UINTN NumberOfEntries; ///< The number of entries in the table. + CONST TABLE_ENTRY_FIELDS *Table; ///< The table entries. +} REGISTER_TABLE; + +/*------------------------------------------------------------------------------------------*/ +/* + * 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 TABLE_ENTRY_DATA *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 { + TABLE_ENTRY_TYPE 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; + +/*------------------------------------------------------------------------------------------*/ +/* + * Non-union initializers for entry data which is not just UINT32. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * A union of data types, that can be initialized with MSR data. + * + * This ensures the entry data is the same size as TABLE_ENTRY_DATA. + */ +typedef union { + MSR_TYPE_ENTRY_DATA MsrInitializer; ///< The data in the table initializer is assigned to this member. + TABLE_ENTRY_DATA Reserved; ///< Make sure the size is the same as the real union. +} MSR_DATA_INITIALIZER; + +/** + * A type suitable for an initializer for MSR Table entries. + */ +typedef struct { + TABLE_ENTRY_TYPE Type; ///< The type of table entry this is. + CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria. + PLATFORM_FEATS Features; ///< Common Platform Features match criteria. + MSR_DATA_INITIALIZER EntryData; ///< The special union which accepts msr data initializer. +} MSR_TYPE_ENTRY_INITIALIZER; + +/** + * A union of data types, that can be initialized with MSR CU data. + * + * This ensures the entry data is the same size as TABLE_ENTRY_DATA. + */ +typedef union { + COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA MsrInitializer; ///< The data in the table initializer is assigned to this member. + TABLE_ENTRY_DATA Reserved; ///< Make sure the size is the same as the real union. +} MSR_CU_DATA_INITIALIZER; + +/** + * A type suitable for an initializer for MSR CU count Table entries. + */ +typedef struct { + TABLE_ENTRY_TYPE Type; ///< The type of table entry this is. + CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria. + PLATFORM_FEATS Features; ///< Common Platform Features match criteria. + MSR_CU_DATA_INITIALIZER EntryData; ///< The special union which accepts msr data initializer. +} MSR_CU_TYPE_ENTRY_INITIALIZER; + +/** + * A union of data types, that can be initialized with Family Specific Workaround data. + * + * This ensures the entry data is the same size as TABLE_ENTRY_DATA. + */ +typedef union { + FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA FamSpecificInitializer; ///< The data in the table initializer is assigned to this member. + TABLE_ENTRY_DATA Reserved; ///< Make sure the size is the same as the real union. +} FAM_SPECIFIC_WORKAROUND_DATA_INITIALIZER; + +/** + * A type suitable for an initializer for Family Specific Workaround Table entries. + */ +typedef struct { + TABLE_ENTRY_TYPE Type; ///< The type of table entry this is. + CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria. + PLATFORM_FEATS Features; ///< Common Platform Features match criteria. + FAM_SPECIFIC_WORKAROUND_DATA_INITIALIZER EntryData; ///< Special union accepts family specific workaround data initializer. +} FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_INITIALIZER; + +/*------------------------------------------------------------------------------------------*/ +/* + * Table related function prototypes (many are instance of F_DO_TABLE_ENTRY method). + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * Set the registers for this core based on entries in a list of Register Tables. + */ +VOID SetRegistersFromTables ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT32 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 TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the PCI Register Entry. + */ +VOID +SetRegisterForPciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Performance Profile PCI Register Entry. + */ +VOID +SetRegisterForPerformanceProfileEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Host PCI Register Entry. + */ +VOID +SetRegisterForHtHostEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Host Performance PCI Register Entry. + */ +VOID +SetRegisterForHtHostPerfEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Set the HT Link Token Count registers. + */ +VOID +SetRegisterForHtLinkTokenEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Core Counts Performance PCI Register Entry. + */ +VOID +SetRegisterForCoreCountsPerformanceEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Processor Counts PCI Register Entry. + */ +VOID +SetRegisterForProcessorCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Compute Unit Counts PCI Register Entry. + */ +VOID +SetRegisterForComputeUnitCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Compute Unit Counts MSR Register Entry. + */ +VOID +SetMsrForComputeUnitCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Family Specific Workaround Register Entry. + */ +VOID +SetRegisterForFamSpecificWorkaroundEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Program HT Phy PCI registers. + */ +VOID +SetRegisterForHtPhyEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Program a range of HT Phy PCI registers. + */ +VOID +SetRegisterForHtPhyRangeEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Program Deemphasis registers, for the platform specified levels. + */ +VOID +SetRegisterForDeemphasisEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Program HT Phy PCI registers which have complex frequency dependencies. + */ +VOID +SetRegisterForHtPhyFreqEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Processor Token Counts PCI Register Entry. + */ +VOID +SetRegisterForTokenPciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Link Feature PCI Register Entry. + */ +VOID +SetRegisterForHtFeaturePciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Phy Performance Profile Register Entry. + */ +VOID +SetRegisterForHtPhyProfileEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Link PCI Register Entry. + */ +VOID +SetRegisterForHtLinkPciEntry ( + IN TABLE_ENTRY_DATA *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_ + |