blob: fe3b3c07e2142264198754b754070298ef51314d [file] [log] [blame]
Marshall Dawsonf3093882016-10-15 09:45:44 -06001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * AMD CPU Register Table Related Functions
6 *
7 * Contains code to initialize the CPU MSRs and PCI registers with BKDG recommended values
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: CPU
12 * @e \$Revision$ @e \$Date$
13 *
14 */
15 /*****************************************************************************
16 *
17 * Copyright (c) 2008 - 2016, Advanced Micro Devices, Inc.
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 * * Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * * Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 ***************************************************************************/
43
44#ifndef _CPU_TABLE_H_
45#define _CPU_TABLE_H_
46
47
48/**
49 * @page regtableimpl Register Table Implementation Guide
50 *
51 * This register table implementation is modular and extensible, so that support code as
52 * well as table data can be family specific or built out if not needed, and new types
53 * of table entries can be added with low overhead. Because many aspects are now generic,
54 * there can be common implementations for CPU revision and platform feature matching and for
55 * finding and iterating tables.
56 *
57 * @par Adding a new table entry type.
58 *
59 * To add a new table entry type follow these steps.
60 * <ul>
61 * <li> Add a member to the enum TABLE_ENTRY_TYPE which is a descriptive name of the entry's purpose
62 * or distinct characteristics.
63 *
64 * <li> Create an entry data struct with the customized data needed. For example, custom register designations,
65 * data and mask sizes, or feature comparisons. Name your struct by adding "_" and upper-casing the enum name
66 * and adding "_TYPE_ENTRY_DATA" at the end.
67 *
68 * <li> Add the entry data type as a member of the TABLE_ENTRY_DATA union. Be aware of the size of your
69 * entry data struct; all table entries in all tables will share any size increase you introduce!
70 *
71 * <li> If your data entry contains any member types except for UINT32, you can't use the generic first union member
72 * for the initializers that make up the actual tables (it's just UINT32's). The generic MSR entry is
73 * an example. Follow the steps below:
74 *
75 * <ul>
76 * <li> Make a union which has your entry data type as the first member. Use TABLE_ENTRY_DATA as the
77 * second member. Name this with your register followed by "_DATA_INITIALIZER".
78 *
79 * <li> Make a copy of TABLE_ENTRY_FIELDS, and rename it your register "_TYPE_ENTRY_INITIALIZER". Rename
80 * the TABLE_ENTRY_DATA member of that struct to have the type you created in the previous step.
81 * This type can be used to declare an array of entries and make a register table in some family specific
82 * file.
83 * </ul>
84 *
85 * <li> Add the descriptor that will link table entries of your data type to an implementation for it.
86 * <ul>
87 * <li> Find the options file which instantiates the CPU_SPECIFIC_SERVICES for each logical model that will
88 * support the new entry type.
89 *
90 * <li> From there find the instantiation of its TABLE_ENTRY_TYPE_DESCRIPTOR. Add a descriptor to the
91 * to the list for your new type. Provide the name of a function which will implement the
92 * entry data. The function name should reflect that it implements the action for the entry type.
93 * The function must be an instance of F_DO_TABLE_ENTRY.
94 * </ul>
95 *
96 * <li> Implement the function for your entry type data. (If parts of it are family specific add methods to
97 * CPU_SPECIFIC_SERVICES for that and implement them for each family or model required.) @n
98 * The definition of the function must conform to F_DO_TABLE_ENTRY.
99 * In the function preamble, include a cross reference to the entry enum:
100 * @code
101 * *
102 * * @TableEntryTypeMethod{::MyRegister}
103 * *
104 * @endcode
105 *
106 * </ul>
107 *
108 * @par Adding a new Register Table
109 *
110 * To add a new register table for a logical CPU model follow the steps below.
111 *
112 * <ul>
113 * <li> Find the options file which instantiates the CPU_SPECIFIC_SERVICES for the logical model that
114 * should include the table.
115 *
116 * <li> From there find the instantiation of its REGISTER_TABLE list. Add the name of the new register table.
117 * </ul>
118 *
119 */
120
121/*------------------------------------------------------------------------------------------*/
122/*
123 * Define the supported table entries.
124 */
125/*------------------------------------------------------------------------------------------*/
126
127/**
128 * These are the available types of table entries.
129 *
130 * Each type corresponds to:
131 * - a semantics for the type specific data, for example semantics for a Register value,
132 * Data value, and Mask value.
133 * - optionally, including a method for type specific matching criteria
134 * - a method for writing the desired update to the hardware.
135 *
136 * All types share in common a method to match CPU Family and Model and a method to match
137 * platform feature set.
138 *
139 * N O T E: We use UINT16 for storing table entry type
140 */
141typedef enum {
142 MsrRegister, ///< Processor MSR registers.
143 PciRegister, ///< Processor Config Space registers.
144 FamSpecificWorkaround, ///< Processor Family Specific Workarounds which are @b not practical using the other types.
145 ProfileFixup, ///< Processor Performance Profile fixups to PCI Config Registers.
146 CoreCountsPciRegister, ///< Processor PCI Config Registers which depend on core counts.
147 CompUnitCountsPciRegister, ///< Processor PCI Config Registers which depend on compute unit counts.
148 CompUnitCountsMsr, ///< Processor MSRs which depend on compute unit counts.
149 CpuRevPciRegister, ///< Processor PCI Config Registers which depend on family / revision.
150 CpuRevMsr, ///< Processor MSR which depend on family / revision.
151 CpuRevFamSpecificWorkaround, ///< Processor Family Specific Workarounds which depend on family / revision.
152 SmuIndexReg, ///< SMU index data registers.
153 ProfileFixupSmuIndexReg, ///< Performance Profile fixups to SMU index data registers.
154 CopyBitField, ///< Copy bitfield from register A to register B
155 TableEntryTypeMax, ///< Not a valid entry type, use for limit checking.
156 TableTerminator = 0xFFFF ///< A signature to indicate end to Jam table.
157} TABLE_ENTRY_TYPE;
158
159/*------------------------------------------------------------------------------------------*/
160/*
161 * Useful types and defines: Selectors, Platform Features, and type specific features.
162 */
163/*------------------------------------------------------------------------------------------*/
164
165/**
166 * Select tables for the current core.
167 *
168 * This allows more efficient register table processing, by allowing cores to skip
169 * redundantly setting PCI registers, for example. This feature is not intended to
170 * be relied on for function: it is valid to have a single register table with all settings
171 * processed by every core; it's just slower.
172 *
173 */
174typedef enum {
175 AllCores, ///< Select only tables which apply to all cores.
176 ComputeUnitPrimary, ///< Select tables which apply to the primary core of a compute unit (SharedC, SharedNc).
177 PrimaryCores, ///< Select tables which apply to primary cores.
178 BscCore, ///< Select tables which apply to the boot core.
179 TableCoreSelectorMax ///< Not a valid selector, use for limit checking.
180} TABLE_CORE_SELECTOR;
181
182/**
183 * Possible time points at which register tables can be processed.
184 *
185 */
186typedef enum {
187 AmdRegisterTableTpBeforeApLaunch, ///< Cpu code just prior to launching APs.
188 AmdRegisterTableTpAfterApLaunch, ///< Cpu code just after all APs have been launched.
189 AmdRegisterTableTpBeforeApLaunchSecureS3, ///< Cpu code just prior to launching APs for secure S3
190 AmdRegisterTableTpAfterApLaunchSecureS3, ///< Cpu code just after all APs have been launched for secure S3
191 MaxAmdRegisterTableTps ///< Not a valid time point, use for limit checking.
192} REGISTER_TABLE_TIME_POINT;
193
194//----------------------------------------------------------------------------
195// CPU PERFORM EARLY INIT ON CORE
196//
197//----------------------------------------------------------------------------
198/// Flag definition.
199
200// Condition
201#define PERFORM_EARLY_WARM_RESET 0x1 // bit 0 --- the related function needs to be run if it's warm reset
202#define PERFORM_EARLY_COLD_BOOT 0x2 // bit 1 --- the related function needs to be run if it's cold boot
203
204#define PERFORM_EARLY_ANY_CONDITION (PERFORM_EARLY_WARM_RESET | PERFORM_EARLY_COLD_BOOT)
205
206// Initializer bit pattern values for platform features.
207// Keep in synch with the PLATFORM_FEATURES struct!
208
209// The 5 control flow modes.
210#define AMD_PF_NFCM BIT0
211#define AMD_PF_UMA BIT1 // UMA_DR
212#define AMD_PF_UMA_IFCM BIT2
213#define AMD_PF_IFCM BIT3
214#define AMD_PF_IOMMU BIT4
215// Degree of HT connectivity possible.
216#define AMD_PF_SINGLE_LINK BIT5
217#define AMD_PF_MULTI_LINK BIT6
218// For some legacy MSRs, define a couple core count bits. Do not continue adding
219// core counts to the platform feats, if you need more than this design a table entry type.
220// Here, provide exactly 1, exactly 2, or anything else.
221#define AMD_PF_SINGLE_CORE BIT7
222#define AMD_PF_DUAL_CORE BIT8
223#define AMD_PF_MULTI_CORE BIT9
224
225// Not a platform type, but treat all others as AND
226#define AMD_PF_AND BIT31
227
228#define AMD_PF_ALL (AMD_PF_NFCM | \
229 AMD_PF_UMA | \
230 AMD_PF_UMA_IFCM | \
231 AMD_PF_IFCM | \
232 AMD_PF_IOMMU | \
233 AMD_PF_SINGLE_LINK | \
234 AMD_PF_MULTI_LINK | \
235 AMD_PF_SINGLE_CORE | \
236 AMD_PF_DUAL_CORE | \
237 AMD_PF_MULTI_CORE)
238// Do not include AMD_PF_AND in AMD_PF_ALL !
239
240/**
241 * The current platform features.
242 *
243 * Keep this in sync with defines above that are used in the initializers!
244 *
245 * The comments with the bit number are useful for the computing the reserved member size, but
246 * do not write code that assumes you know what bit number one of these members is.
247 *
248 * These platform features are standard for all logical families and models.
249 */
250typedef struct {
251 UINT32 PlatformNfcm:1; ///< BIT_0 Normal Flow Control Mode.
252 UINT32 PlatformUma:1; ///< BIT_1 UMA (Display Refresh) Flow Control.
253 UINT32 PlatformUmaIfcm:1; ///< BIT_2 UMA using Isochronous Flow Control.
254 UINT32 PlatformIfcm:1; ///< BIT_3 Isochronous Flow Control Mode (not UMA).
255 UINT32 PlatformIommu:1; ///< BIT_4 IOMMU (a special case Isochronous mode).
256 UINT32 PlatformSingleLink:1; ///< BIT_5 The processor is in a package which implements only a single HT Link.
257 UINT32 PlatformMultiLink:1; ///< BIT_6 The processor is in a package which implements more than one HT Link.
258 UINT32 PlatformSingleCore:1; ///< BIT_7 Single Core processor, for legacy entries.
259 UINT32 PlatformDualCore:1; ///< BIT_8 Dual Core processor, for legacy entries.
260 UINT32 PlatformMultiCore:1; ///< BIT_9 More than dual Core processor, for legacy entries.
261 UINT32 :(30 - 9); ///< The possibilities are (not quite) endless.
262 UINT32 AndPlatformFeats:1; ///< BIT_31
263} PLATFORM_FEATURES;
264
265/**
266 * Platform Features
267 */
268typedef union {
269 UINT32 PlatformValue; ///< Describe Platform Features in UINT32.
270 ///< This one goes first, because then initializers use it automatically for the union.
271 PLATFORM_FEATURES PlatformFeatures; ///< Describe Platform Features in structure
272} PLATFORM_FEATS;
273
274// Initializer bit patterns for PERFORMANCE_PROFILE_FEATS.
275#define PERFORMANCE_REFRESH_REQUEST_32B BIT0
276#define PERFORMANCE_L3_CACHE BIT1
277#define PERFORMANCE_NO_L3_CACHE BIT2
278#define PERFORMANCE_MCT_ISOC_VARIABLE BIT3
279#define PERFORMANCE_IS_WARM_RESET BIT4
280#define PERFORMANCE_VRM_HIGH_SPEED_ENABLE BIT5
281#define PERFORMANCE_NB_PSTATES_ENABLE BIT6
282#define PERFORMANCE_AND BIT31
283
284#define PERFORMANCE_PROFILE_ALL (PERFORMANCE_REFRESH_REQUEST_32B | \
285 PERFORMANCE_L3_CACHE | \
286 PERFORMANCE_NO_L3_CACHE | \
287 PERFORMANCE_MCT_ISOC_VARIABLE | \
288 PERFORMANCE_IS_WARM_RESET | \
289 PERFORMANCE_VRM_HIGH_SPEED_ENABLE | \
290 PERFORMANCE_NB_PSTATES_ENABLE)
291
292/**
293 * Performance Profile specific Type Features.
294 *
295 * Register settings for the different control flow modes can have additional dependencies
296 */
297typedef struct {
298 UINT32 RefreshRequest32Byte:1; ///< BIT_0. Display Refresh Requests use 32 bytes (32BE).
299 UINT32 L3Cache:1; ///< BIT_1 L3 Cache is present.
300 UINT32 NoL3Cache:1; ///< BIT_2 L3 Cache is NOT present.
301 UINT32 MctIsocVariable:1; ///< BIT_3 Mct Isoc Read Priority set to variable.
302 UINT32 IsWarmReset:1; ///< BIT_4 This boot is on a warm reset, cold reset pass is already completed.
303 UINT32 VrmHighSpeed:1; ///< BIT_5 Select high speed VRM.
304 UINT32 NbPstates:1; ///< BIT_6 Northbridge PStates are enabled
305 UINT32 :(30 - 6); ///< available for future expansion.
306 UINT32 AndPerformanceFeats:1; ///< BIT_31. AND other selected features.
307} PERFORMANCE_PROFILE_FEATURES;
308
309/**
310 * Performance Profile features.
311 */
312typedef union {
313 UINT32 PerformanceProfileValue; ///< Initializer value.
314 PERFORMANCE_PROFILE_FEATURES PerformanceProfileFeatures; ///< The performance profile features.
315} PERFORMANCE_PROFILE_FEATS;
316
317// Initializer Values for Package Type
318#define PACKAGE_TYPE_ALL 0XFFFF ///< Package Type apply all packages
319
320// Core Range Initializer values.
321#define COUNT_RANGE_LOW 0ul
322#define COUNT_RANGE_HIGH 0xFFul
323
324// A count range matching none is often useful as the second range, matching will then be
325// based on the first range. A count range all is provided as a first range for default settings.
326#define COUNT_RANGE_NONE ((((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH)) << 16)
327#define COUNT_RANGE_ALL (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_LOW))
328#define IGNORE_FREQ_0 (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH))
329#define IGNORE_PROCESSOR_0 (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH))
330
331#define CORE_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min))
332#define CORE_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
333#define PROCESSOR_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min))
334#define PROCESSOR_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
335#define DEGREE_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min))
336#define DEGREE_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
337#define FREQ_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min))
338#define FREQ_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
339#define COMPUTE_UNIT_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min))
340#define COMPUTE_UNIT_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16)
341
342/**
343 * Count Range Feature, two count ranges for core counts, processor counts, or node counts.
344 */
345typedef struct {
346 UINT32 Range0Min:8; ///< The minimum of the first count range.
347 UINT32 Range0Max:8; ///< The maximum of the first count range.
348 UINT32 Range1Min:8; ///< The minimum of the second count range.
349 UINT32 Range1Max:8; ///< The maximum of the second count range.
350} COUNT_RANGE_FEATURE;
351
352/**
353 * Core Count Ranges for table data.
354 *
355 * Provide a pair of core count ranges. If the actual core count is included in either range (OR),
356 * the feature should be considered a match.
357 */
358typedef union {
359 UINT32 CoreRangeValue; ///< Initializer value.
360 COUNT_RANGE_FEATURE CoreRanges; ///< The Core Counts.
361} CORE_COUNT_RANGES;
362
363/**
364 * Compute unit count ranges for table data.
365 *
366 * Provide a pair of compute unit count ranges. If the actual counts are included in either ranges (OR),
367 * the feature should be considered a match.
368 */
369typedef union {
370 UINT32 ComputeUnitRangeValue; ///< Initializer value.
371 COUNT_RANGE_FEATURE ComputeUnitRanges; ///< The Processor and Node Counts.
372} COMPUTE_UNIT_COUNTS;
373
374/*------------------------------------------------------------------------------------------*/
375/*
376 * The specific data for each table entry.
377 */
378/*------------------------------------------------------------------------------------------*/
379#define BSU8(u8) ((UINT8) (u8) & 0xFF)
380#define BSU16(u16) ((UINT16) (u16) & 0xFF), (((UINT16) (u16) >> 8) & 0xFF)
381#define BSU32(u32) ((UINT32) (u32) & 0xFF), (((UINT32) (u32) >> 8) & 0xFF), (((UINT32) (u32) >> 16) & 0xFF), (((UINT32) (u32) >> 24) & 0xFF)
382#define BSU64(u64) ((UINT64) (u64) & 0xFF), (((UINT64) (u64) >> 8) & 0xFF), (((UINT64) (u64) >> 16) & 0xFF), (((UINT64) (u64) >> 24) & 0xFF), \
383 (((UINT64) (u64) >> 32) & 0xFF), (((UINT64) (u64) >> 40) & 0xFF), (((UINT64) (u64) >> 48) & 0xFF), (((UINT64) (u64) >> 56) & 0xFF)
384
385#define MAKE_ENTRY_TYPE(Type) BSU16 (Type)
386#define MAKE_PERFORMANCE_PROFILE_FEATS(TypeFeats) BSU32 (TypeFeats)
387#define MAKE_CORE_COUNT_RANGES(CoreCounts) BSU32 (CoreCounts)
388#define MAKE_COMPUTE_UNIT_COUNTS(CUCounts) BSU32 (CUCounts)
389#define MAKE_CPU_LOGICAL_ID(Family, Revision) BSU16 (Family), BSU16 (Revision)
390#define MAKE_TABLE_TERMINATOR BSU16 (TableTerminator)
391
392#define NUMBER_OF_TABLE_ENTRIES(Table) ((sizeof (Table) / sizeof (Table[0])) - 1)
393
394/**
395 * Table Entry Data for MSR Registers.
396 *
397 * Apply data to register after mask, for MSRs.
398 */
399typedef struct {
400 UINT32 Address; ///< MSR address
401 UINT64 Data; ///< Data to set in the MSR
402 UINT64 Mask; ///< Mask to be applied to the MSR. Set every bit of all updated fields.
403} MSR_TYPE_ENTRY_DATA;
404#define MAKE_MSR_DATA(Address, Data, Mask) BSU32 (Address), BSU64 (Data), BSU64 (Mask)
405#define MAKE_MSR_ENTRY(Address, Data, Mask) MAKE_ENTRY_TYPE (MsrRegister), MAKE_MSR_DATA(Address, Data, Mask)
406
407/**
408 * Table Entry Data for PCI Registers.
409 *
410 * Apply data to register after mask, for PCI Config registers.
411 */
412typedef struct {
413 PCI_ADDR Address; ///< Address should contain Function, Offset only. It will apply to all CPUs
414 UINT32 Data; ///< Data to be written into PCI device
415 UINT32 Mask; ///< Mask to be used before data write. Set every bit of all updated fields.
416} PCI_TYPE_ENTRY_DATA;
417#define MAKE_PCI_DATA(Address, Data, Mask) BSU32 (Address), BSU32 (Data), BSU32 (Mask)
418#define MAKE_PCI_ENTRY(Address, Data, Mask) MAKE_ENTRY_TYPE (PciRegister), MAKE_PCI_DATA(Address, Data, Mask)
419
420/**
421 * Table Entry Data for Profile Fixup Registers.
422 *
423 * If TypeFeats matches current config, apply data to register after mask for PCI Config registers.
424 */
425typedef struct {
426 PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features.
427 PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data.
428} PROFILE_FIXUP_TYPE_ENTRY_DATA;
429#define MAKE_PROFILE_FIXUP_ENTRY(TypeFeats, Address, Data, Mask) MAKE_ENTRY_TYPE (ProfileFixup), MAKE_PERFORMANCE_PROFILE_FEATS (TypeFeats), MAKE_PCI_DATA (Address, Data, Mask)
430
431/**
432 * Core Count dependent PCI registers.
433 *
434 */
435typedef struct {
436 PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features.
437 CORE_COUNT_RANGES CoreCounts; ///< Specify up to two core count ranges to match.
438 PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data.
439} CORE_COUNTS_PCI_TYPE_ENTRY_DATA;
440#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)
441
442/**
443 * Compute Unit Count dependent PCI registers.
444 *
445 */
446typedef struct {
447 PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features.
448 COMPUTE_UNIT_COUNTS ComputeUnitCounts; ///< Specify a compute unit count range.
449 PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data.
450} COMPUTE_UNIT_COUNTS_PCI_TYPE_ENTRY_DATA;
451#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)
452
453/**
454 * Compute Unit Count dependent MSR registers.
455 *
456 */
457typedef struct {
458 COMPUTE_UNIT_COUNTS ComputeUnitCounts; ///< Specify a compute unit count range.
459 MSR_TYPE_ENTRY_DATA MsrEntry; ///< The MSR Register entry data.
460} COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA;
461#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)
462
463
464/**
465 * A Family Specific Workaround method.
466 *
467 * \@TableTypeFamSpecificInstances.
468 *
469 * When called, the entry's CPU Logical ID and Platform Features matched the current config.
470 * The method must implement any specific criteria checking for the workaround.
471 *
472 * See if you can use the other entries or make an entry specifically for the fix.
473 * After all, the purpose of having a table entry is to @b NOT have code which
474 * isn't generic feature code, but is family/model specific.
475 *
476 * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched.
477 * @param[in] StdHeader Config params for library, services.
478 */
479typedef VOID F_FAM_SPECIFIC_WORKAROUND (
480 IN UINT32 Data,
481 IN AMD_CONFIG_PARAMS *StdHeader
482 );
483/// Reference to a method.
484typedef F_FAM_SPECIFIC_WORKAROUND *PF_FAM_SPECIFIC_WORKAROUND;
485
486/**
487 * Table Entry Data for Family Specific Workarounds.
488 *
489 * See if you can use the other entries or make an entry specifically for the fix.
490 * After all, the purpose of having a table entry is to @b NOT have code which
491 * isn't generic feature code, but is family/model specific.
492 *
493 * Call DoAction passing Data.
494 */
495typedef struct {
496 UINT32 FunctionIndex; ///< A function implementing the workaround.
497 UINT32 Data; ///< This data is passed to DoAction().
498} FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA;
499#define MAKE_FAM_SPECIFIC_WORKAROUND_DATA(FunctionIndex, Data) BSU32 (FunctionIndex), BSU32 (Data)
500#define MAKE_FAM_SPECIFIC_WORKAROUND_ENTRY(FunctionIndex, Data) MAKE_ENTRY_TYPE (FamSpecificWorkaround), MAKE_FAM_SPECIFIC_WORKAROUND_DATA(FunctionIndex, Data)
501
502/**
503 * Table Entry Data for CPU revision specific PCI Registers.
504 *
505 * Apply data to register after mask, for PCI Config registers.
506 */
507typedef struct {
508 CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria.
509 PCI_ADDR Address; ///< Address should contain Function, Offset only. It will apply to all CPUs
510 UINT32 Data; ///< Data to be written into PCI device
511 UINT32 Mask; ///< Mask to be used before data write. Set every bit of all updated fields.
512} CPU_REV_PCI_TYPE_ENTRY_DATA;
513#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)
514
515/**
516 * Table Entry Data for CPU revision specific MSRs.
517 *
518 * Apply data to register after mask, for MSRs.
519 */
520typedef struct {
521 CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria.
522 UINT32 Address; ///< MSR Address
523 UINT64 Data; ///< Data to be written into MSR
524 UINT64 Mask; ///< Mask to be used before data write. Set every bit of all updated fields.
525} CPU_REV_MSR_TYPE_ENTRY_DATA;
526#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)
527
528/**
529 * Table Entry Data for Family Specific Workarounds that depend on CPU revision.
530 *
531 * See if you can use the other entries or make an entry specifically for the fix.
532 * After all, the purpose of having a table entry is to @b NOT have code which
533 * isn't generic feature code, but is family/model specific.
534 *
535 * Call DoAction passing Data.
536 */
537typedef struct {
538 CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria.
539 UINT32 FunctionIndex; ///< A function implementing the workaround.
540 UINT32 Data; ///< This data is passed to DoAction().
541} CPU_REV_FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA;
542#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)
543
544/**
545 * Table Entry Data for SMU Index/Data D0F0xBC_xxxx_xxxx Registers.
546 *
547 * Apply data to register after mask, for PCI Config registers.
548 */
549typedef struct {
550 UINT32 Index; ///< SMU index address
551 UINT32 Data; ///< Data to be written into PCI device
552 UINT32 Mask; ///< Mask to be used before data write. Set every bit of all updated fields.
553} SMU_INDEX_ENTRY_DATA;
554#define MAKE_SMU_INDEX_ENTRY_DATA(Index, Data, Mask) BSU32 (Index), BSU32 (Data), BSU32 (Mask)
555#define MAKE_SMU_INDEX_ENTRY(Index, Data, Mask) MAKE_ENTRY_TYPE (SmuIndexReg), MAKE_SMU_INDEX_ENTRY_DATA(Index, Data, Mask)
556
557#define SMU_INDEX_ADDRESS (MAKE_SBDFO (0, 0, 0, 0, 0xB8))
558
559
560/**
561 * Table Entry Data for Profile Fixup to SMU Index/Data D0F0xBC_xxxx_xxxx Registers.
562 *
563 * If TypeFeats matches current config, apply data to register after mask for SMU Index/Data D0F0xBC_xxxx_xxxx registers.
564 */
565typedef struct {
566 PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features.
567 SMU_INDEX_ENTRY_DATA SmuIndexEntry; ///< The SMU Index/Data D0F0xBC_xxxx_xxxx register entry data.
568} PROFILE_FIXUP_SMU_INDEX_ENTRY_DATA;
569#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)
570
571/**
572 * Bit field description
573 *
574 * Describe register type, address, MSB, LSB
575 */
576typedef struct {
577 UINT16 RegType; ///< Register type
578 UINT32 Address; ///< Address
579 UINT8 MSB; ///< Most Significant Bit
580 UINT8 LSB; ///< Least Significant Bit
581} COPY_BIT_FIELD_DESCRIPTION;
582#define MAKE_COPY_BIT_FIELD_DESCRIPTION(RegType, Address, Msb, Lsb) MAKE_ENTRY_TYPE (RegType), BSU32 (Address), BSU8 (Msb), BSU8 (Lsb)
583
584/**
585 * Table Entry Data for copying bitfield from register A to register B.
586 *
587 * Copy bitfield from register A to register B.
588 */
589typedef struct {
590 COPY_BIT_FIELD_DESCRIPTION Destination; ///< Destination register descriptor
591 COPY_BIT_FIELD_DESCRIPTION Source; ///< Source register descriptor
592} COPY_BIT_FIELD_ENTRY_DATA;
593#define COPY_BIT_FIELD_DEST(RegType, Address, Msb, Lsb) MAKE_COPY_BIT_FIELD_DESCRIPTION (RegType, Address, Msb, Lsb)
594#define COPY_BIT_FIELD_SOURCE(RegType, Address, Msb, Lsb) MAKE_COPY_BIT_FIELD_DESCRIPTION (RegType, Address, Msb, Lsb)
595#define MAKE_COPY_BIT_FIELD_ENTRY(Dest, Src) MAKE_ENTRY_TYPE (CopyBitField), Dest, Src
596/*------------------------------------------------------------------------------------------*/
597/*
598 * A complete register table and table entries.
599 */
600/*------------------------------------------------------------------------------------------*/
601
602/**
603 * Format of table entries :
604 *
605 * UINT16 EntryType \
606 * VariableLength EntryData / one entry
607 * UINT16 EntryType \
608 * VariableLength EntryData / one entry
609 * ... \
610 * ... / more entries...
611 */
612
613/**
614 * All the available entry data types.
615 *
616 * we use TABLE_ENTRY_DATA in copy bitfield entry
617 *
618 */
619typedef union {
620 MSR_TYPE_ENTRY_DATA MsrEntry; ///< MSR entry.
621 PCI_TYPE_ENTRY_DATA PciEntry; ///< PCI entry.
622 FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA FamSpecificEntry; ///< Family Specific Workaround entry.
623 PROFILE_FIXUP_TYPE_ENTRY_DATA FixupEntry; ///< Profile Fixup entry.
624 CORE_COUNTS_PCI_TYPE_ENTRY_DATA CoreCountEntry; ///< Core count dependent settings.
625 COMPUTE_UNIT_COUNTS_PCI_TYPE_ENTRY_DATA CompUnitCountEntry; ///< Compute unit count dependent entry.
626 COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA CompUnitCountMsrEntry; ///< Compute unit count dependent MSR entry.
627 CPU_REV_PCI_TYPE_ENTRY_DATA CpuRevPciEntry; ///< CPU revision PCI entry.
628 CPU_REV_FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA CpuRevFamSpecificEntry; ///< CPU revision Family Specific Workaround entry.
629 SMU_INDEX_ENTRY_DATA SmuIndexEntry; ///< SMU Index Data entry.
630 PROFILE_FIXUP_SMU_INDEX_ENTRY_DATA ProfileFixupSmuIndexEntry; ///< Performance Profile fixups to SMU index data registers entry.
631 COPY_BIT_FIELD_ENTRY_DATA CopyBitFieldEntry; ///< Copy bitfield entry.
632} TABLE_ENTRY_DATA;
633
634/**
635 * Register Table Entry common fields.
636 *
637 * All the various types of register table entries are subclasses of this object.
638 */
639typedef struct {
640 UINT16 EntryType; ///< The type of table entry this is.
641 TABLE_ENTRY_DATA EntryData; ///< The pointer to the first entry.
642} TABLE_ENTRY_FIELDS;
643
644/**
645 * An entire register table.
646 */
647typedef struct {
648 UINT32 Selector; ///< For efficiency, these cores should process this table
649 CONST UINT8* Table; ///< The table entries.
650} REGISTER_TABLE;
651
652/**
653 * An entire register table at given time point.
654 */
655typedef struct {
656 REGISTER_TABLE_TIME_POINT TimePoint; ///< Time point
657 CONST REGISTER_TABLE** TableList; ///< The table list.
658} REGISTER_TABLE_AT_GIVEN_TP;
659/*------------------------------------------------------------------------------------------*/
660/*
661 * Describe implementers for table entries.
662 */
663/*------------------------------------------------------------------------------------------*/
664
665/**
666 * Implement the semantics of a Table Entry Type.
667 *
668 * @TableEntryTypeInstances.
669 *
670 * @param[in] CurrentEntry The type specific entry data to be implemented (that is written).
671 * @param[in] PlatformConfig Config handle for platform specific information
672 * @param[in] StdHeader Config params for library, services.
673 */
674typedef VOID F_DO_TABLE_ENTRY (
675 IN UINT8 **CurrentEntry,
676 IN PLATFORM_CONFIGURATION *PlatformConfig,
677 IN AMD_CONFIG_PARAMS *StdHeader
678 );
679/// Reference to a method
680typedef F_DO_TABLE_ENTRY *PF_DO_TABLE_ENTRY;
681
682/**
683 * Describe the attributes of a Table Entry Type.
684 */
685typedef struct {
686 UINT16 EntryType; ///< The type of table entry this describes.
687 PF_DO_TABLE_ENTRY DoTableEntry; ///< Provide all semantics associated with TABLE_ENTRY_DATA
688} TABLE_ENTRY_TYPE_DESCRIPTOR;
689
690/*------------------------------------------------------------------------------------------*/
691/*
692 * Table related function prototypes (many are instance of F_DO_TABLE_ENTRY method).
693 */
694/*------------------------------------------------------------------------------------------*/
695
696/**
697 * Get the next register table
698 */
699REGISTER_TABLE **GetNextRegisterTable (
700 IN UINT32 Selector,
701 IN REGISTER_TABLE **RegisterTableList,
702 IN OUT REGISTER_TABLE ***RegisterTableHandle,
703 IN AMD_CONFIG_PARAMS *StdHeader
704 );
705
706/**
707 * If current core is CoreSelector core
708 */
709BOOLEAN
710IsCoreSelector (
711 IN UINT32 Selector,
712 IN AMD_CONFIG_PARAMS *StdHeader
713 );
714
715/**
716 * Set the registers for this core based on entries in a list of Register Table.
717 */
718VOID
719SetRegistersFromTable (
720 IN PLATFORM_CONFIGURATION *PlatformConfig,
721 IN UINT8 *RegisterEntry,
722 IN AMD_CONFIG_PARAMS *StdHeader
723 );
724
725/**
726 * Set the registers for this core based on entries in a list of Register Table.
727 */
728VOID
729SetRegistersFromTableList (
730 IN PLATFORM_CONFIGURATION *PlatformConfig,
731 IN REGISTER_TABLE **RegisterTableList,
732 IN AMD_CONFIG_PARAMS *StdHeader
733 );
734
735/**
736 * Processes the register table at the given time point.
737 */
738AGESA_STATUS
739SetRegistersFromTablesAtGivenTimePoint (
740 IN VOID *PlatformConfig,
741 IN REGISTER_TABLE_TIME_POINT TimePoint,
742 IN AMD_CONFIG_PARAMS *StdHeader
743 );
744
745/**
746 * Find the features of the running platform.
747 */
748VOID
749GetPlatformFeatures (
750 OUT PLATFORM_FEATS *Features,
751 IN PLATFORM_CONFIGURATION *PlatformConfig,
752 IN AMD_CONFIG_PARAMS *StdHeader
753 );
754
755/**
756 * Checks register table entry type specific criteria to the platform.
757 */
758BOOLEAN
759DoesEntryTypeSpecificInfoMatch (
760 IN UINT32 PlatformTypeSpecificFeatures,
761 IN UINT32 EntryTypeFeatures
762 );
763
764/**
765 * Perform the MSR Register Entry.
766 */
767VOID
768SetRegisterForMsrEntry (
769 IN UINT8 **Entry,
770 IN PLATFORM_CONFIGURATION *PlatformConfig,
771 IN AMD_CONFIG_PARAMS *StdHeader
772 );
773
774/**
775 * Perform the CPU Rev MSR Entry.
776 */
777VOID
778SetRegisterForCpuRevMsrEntry (
779 IN UINT8 **Entry,
780 IN PLATFORM_CONFIGURATION *PlatformConfig,
781 IN AMD_CONFIG_PARAMS *StdHeader
782 );
783
784/**
785 * Perform the PCI Register Entry.
786 */
787VOID
788SetRegisterForPciEntry (
789 IN UINT8 **Entry,
790 IN PLATFORM_CONFIGURATION *PlatformConfig,
791 IN AMD_CONFIG_PARAMS *StdHeader
792 );
793
794/**
795 * Perform the PCI Register Entry.
796 */
797VOID
798SetRegisterForCpuRevPciEntry (
799 IN UINT8 **Entry,
800 IN PLATFORM_CONFIGURATION *PlatformConfig,
801 IN AMD_CONFIG_PARAMS *StdHeader
802 );
803
804/**
805 * Perform the Performance Profile PCI Register Entry.
806 */
807VOID
808SetRegisterForPerformanceProfileEntry (
809 IN UINT8 **Entry,
810 IN PLATFORM_CONFIGURATION *PlatformConfig,
811 IN AMD_CONFIG_PARAMS *StdHeader
812 );
813
814/**
815 * Perform the Core Counts Performance PCI Register Entry.
816 */
817VOID
818SetRegisterForCoreCountsPerformanceEntry (
819 IN UINT8 **Entry,
820 IN PLATFORM_CONFIGURATION *PlatformConfig,
821 IN AMD_CONFIG_PARAMS *StdHeader
822 );
823
824/**
825 * Perform the Compute Unit Counts PCI Register Entry.
826 */
827VOID
828SetRegisterForComputeUnitCountsEntry (
829 IN UINT8 **Entry,
830 IN PLATFORM_CONFIGURATION *PlatformConfig,
831 IN AMD_CONFIG_PARAMS *StdHeader
832 );
833
834/**
835 * Perform the Compute Unit Counts MSR Register Entry.
836 */
837VOID
838SetMsrForComputeUnitCountsEntry (
839 IN UINT8 **Entry,
840 IN PLATFORM_CONFIGURATION *PlatformConfig,
841 IN AMD_CONFIG_PARAMS *StdHeader
842 );
843
844/**
845 * Perform the Family Specific Workaround Register Entry.
846 */
847VOID
848SetRegisterForFamSpecificWorkaroundEntry (
849 IN UINT8 **Entry,
850 IN PLATFORM_CONFIGURATION *PlatformConfig,
851 IN AMD_CONFIG_PARAMS *StdHeader
852 );
853
854/**
855 * Perform the Family Specific Workaround Register Entry.
856 */
857VOID
858SetRegisterForCpuRevFamSpecificWorkaroundEntry (
859 IN UINT8 **Entry,
860 IN PLATFORM_CONFIGURATION *PlatformConfig,
861 IN AMD_CONFIG_PARAMS *StdHeader
862 );
863
864/**
865 * Perform the SMU Index/Data Register Entry.
866 */
867VOID
868SetSmuIndexRegisterEntry (
869 IN UINT8 **Entry,
870 IN PLATFORM_CONFIGURATION *PlatformConfig,
871 IN AMD_CONFIG_PARAMS *StdHeader
872 );
873
874/**
875 * Perform the Performance Profile SMU Index/Data Register Entry.
876 */
877VOID
878SetSmuIndexRegisterForPerformanceEntry (
879 IN UINT8 **Entry,
880 IN PLATFORM_CONFIGURATION *PlatformConfig,
881 IN AMD_CONFIG_PARAMS *StdHeader
882 );
883
884/**
885 * Perform the Copy Bitfield Entry.
886 */
887VOID
888CopyBitFieldEntry (
889 IN UINT8 **Entry,
890 IN PLATFORM_CONFIGURATION *PlatformConfig,
891 IN AMD_CONFIG_PARAMS *StdHeader
892 );
893
894/**
895 * Compare counts to a pair of ranges.
896 */
897BOOLEAN
898IsEitherCountInRange (
899 IN UINTN FirstCount,
900 IN UINTN SecondCount,
901 IN COUNT_RANGE_FEATURE Ranges
902 );
903
904/**
905 * Returns the performance profile features list of the currently running processor core.
906 */
907VOID
908GetPerformanceFeatures (
909 OUT PERFORMANCE_PROFILE_FEATS *Features,
910 IN PLATFORM_CONFIGURATION *PlatformConfig,
911 IN AMD_CONFIG_PARAMS *StdHeader
912 );
913
914#endif // _CPU_TABLE_H_
915