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