5 * AMD CPU Family Translation functions.
8 * @xrefitem bom "File Content Label" "Release Content"
10 * @e sub-project: CPU/Interface
11 * @e \$Revision: 56322 $ @e \$Date: 2011-07-11 16:51:42 -0600 (Mon, 11 Jul 2011) $
15 ******************************************************************************
17 * Copyright (C) 2012 Advanced Micro Devices, Inc.
18 * All rights reserved.
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.
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.
42 ******************************************************************************
45 /*----------------------------------------------------------------------------------------
46 * M O D U L E S U S E D
47 *----------------------------------------------------------------------------------------
52 #include "cpuRegisters.h"
53 #include "CommonReturns.h"
54 #include "GeneralServices.h"
55 #include "cpuFamilyTranslation.h"
60 #define FILECODE PROC_CPU_CPUFAMILYTRANSLATION_FILECODE
62 /*----------------------------------------------------------------------------------------
63 * D E F I N I T I O N S A N D M A C R O S
64 *----------------------------------------------------------------------------------------
67 /*----------------------------------------------------------------------------------------
68 * T Y P E D E F S A N D S T R U C T U R E S
69 *----------------------------------------------------------------------------------------
72 CONST CPU_SPECIFIC_SERVICES ROMDATA cpuNullServices =
75 (PF_CPU_DISABLE_PSTATE) CommonReturnAgesaSuccess,
76 (PF_CPU_TRANSITION_PSTATE) CommonReturnAgesaSuccess,
77 (PF_CPU_GET_IDD_MAX) CommonReturnFalse,
78 (PF_CPU_GET_TSC_RATE) CommonReturnAgesaSuccess,
79 (PF_CPU_GET_NB_FREQ) CommonReturnAgesaSuccess,
80 (PF_CPU_GET_MIN_MAX_NB_FREQ) CommonReturnAgesaSuccess,
81 (PF_CPU_GET_NB_PSTATE_INFO) CommonReturnFalse,
82 (PF_CPU_IS_NBCOF_INIT_NEEDED) CommonReturnAgesaSuccess,
83 (PF_CPU_GET_NB_IDD_MAX) CommonReturnFalse,
84 (PF_CPU_AP_INITIAL_LAUNCH) CommonReturnFalse,
85 (PF_CPU_NUMBER_OF_PHYSICAL_CORES) CommonReturnZero8,
86 (PF_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE) CommonReturnAgesaSuccess,
87 (PF_CPU_SET_AP_CORE_NUMBER) CommonVoid,
88 (PF_CPU_GET_AP_CORE_NUMBER) CommonReturnZero32,
89 (PF_CPU_TRANSFER_AP_CORE_NUMBER) CommonVoid,
90 (PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID) CommonReturnAgesaSuccess,
91 (PF_CPU_SAVE_FEATURES) CommonReturnAgesaSuccess,
92 (PF_CPU_WRITE_FEATURES) CommonReturnAgesaSuccess,
93 (PF_CPU_SET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,
94 (PF_CPU_GET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,
102 (PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO) CommonReturnAgesaSuccess,
103 (PF_IS_NB_PSTATE_ENABLED) CommonReturnFalse,
104 (PF_NEXT_LINK_HAS_HTFPY_FEATS) CommonReturnFalse,
105 (PF_SET_HT_PHY_REGISTER) CommonVoid,
106 (PF_GET_NEXT_HT_LINK_FEATURES) CommonVoid,
112 (PF_GET_EARLY_INIT_TABLE) CommonVoid
115 /*----------------------------------------------------------------------------------------
116 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
117 *----------------------------------------------------------------------------------------
122 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
123 IN UINT64 *MatchData,
124 OUT CONST VOID **CpuServices,
125 IN AMD_CONFIG_PARAMS *StdHeader
128 /*----------------------------------------------------------------------------------------
129 * E X P O R T E D F U N C T I O N S
130 *----------------------------------------------------------------------------------------
132 extern CPU_FAMILY_SUPPORT_TABLE CpuSupportedFamiliesTable;
133 extern CPU_FAMILY_ID_XLAT_TABLE CpuSupportedFamilyIdTable;
135 /*---------------------------------------------------------------------------------------*/
138 * Returns the logical ID of the desired processor. This will be obtained by
139 * reading the CPUID and converting it into a "logical ID" which is not package
142 * @param[in] Socket Socket
143 * @param[out] LogicalId The Processor's Logical ID
144 * @param[in] StdHeader Handle of Header for calling lib functions and services.
148 GetLogicalIdOfSocket (
150 OUT CPU_LOGICAL_ID *LogicalId,
151 IN AMD_CONFIG_PARAMS *StdHeader
156 AGESA_STATUS AssumedSuccess;
160 if (GetPciAddress (StdHeader, (UINT8)Socket, 0, &PciAddress, &AssumedSuccess)) {
161 PciAddress.Address.Function = FUNC_3;
162 PciAddress.Address.Register = CPUID_FMR;
163 LibAmdPciRead (AccessWidth32, PciAddress, &RawCpuid, StdHeader);
164 GetLogicalIdFromCpuid (RawCpuid, LogicalId, StdHeader);
166 LogicalId->Family = 0;
167 LogicalId->Revision = 0;
168 // Logical ID was not found.
174 /*---------------------------------------------------------------------------------------*/
177 * Returns the logical ID of the executing core. This will be obtained by reading
178 * the CPUID and converting it into a "logical ID" which is not package dependent.
180 * @param[out] LogicalId The Processor's Logical ID
181 * @param[in] StdHeader Handle of Header for calling lib functions and services.
185 GetLogicalIdOfCurrentCore (
186 OUT CPU_LOGICAL_ID *LogicalId,
187 IN AMD_CONFIG_PARAMS *StdHeader
190 CPUID_DATA CpuidDataStruct;
192 LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuidDataStruct, StdHeader);
193 GetLogicalIdFromCpuid (CpuidDataStruct.EAX_Reg, LogicalId, StdHeader);
197 /*---------------------------------------------------------------------------------------*/
200 * Returns the logical ID of a processor with the given CPUID value. This
201 * will be obtained by converting it into a "logical ID" which is not package
204 * @param[in] RawCpuid The unprocessed CPUID value to be translated
205 * @param[out] LogicalId The Processor's Logical ID
206 * @param[in] StdHeader Handle of Header for calling lib functions and services
210 GetLogicalIdFromCpuid (
212 OUT CPU_LOGICAL_ID *LogicalId,
213 IN AMD_CONFIG_PARAMS *StdHeader
218 UINT8 NumberOfFamiliesSupported;
219 UINT8 NumberOfLogicalSubFamilies;
220 UINT8 LogicalIdEntries;
223 UINT32 CpuModelAndExtendedModel;
224 UINT64 LogicalFamily;
226 BOOLEAN FamilyNotFound;
227 CONST PF_CPU_GET_SUBFAMILY_ID_ARRAY *SubFamilyIdPtr;
228 CPU_LOGICAL_ID_XLAT *CpuLogicalIdAndRevPtr;
229 CONST CPU_LOGICAL_ID_FAMILY_XLAT *ImageSupportedId;
232 FamilyNotFound = TRUE;
233 CpuLogicalIdAndRevPtr = NULL;
234 ImageSupportedId = CpuSupportedFamilyIdTable.FamilyIdTable;
235 NumberOfFamiliesSupported = CpuSupportedFamilyIdTable.Elements;
237 RawFamily = ((RawCpuid & 0xF00) >> 8) + ((RawCpuid & 0xFF00000) >> 20);
238 RawCpuid &= (UINT32) CPU_FMS_MASK;
239 CpuModelAndExtendedModel = (UINT16) ((RawCpuid >> 8) | RawCpuid);
241 LogicalId->Family = 0;
242 LogicalId->Revision = 0;
244 for (i = 0; i < NumberOfFamiliesSupported && FamilyNotFound; i++) {
245 if (ImageSupportedId[i].Family == RawFamily) {
246 FamilyNotFound = FALSE;
247 LogicalId->Family = ImageSupportedId[i].UnknownRevision.Family;
248 LogicalId->Revision = ImageSupportedId[i].UnknownRevision.Revision;
250 NumberOfLogicalSubFamilies = ImageSupportedId[i].Elements;
251 SubFamilyIdPtr = ImageSupportedId[i].SubFamilyIdTable;
252 for (j = 0; j < NumberOfLogicalSubFamilies && IdNotFound; j++) {
253 SubFamilyIdPtr[j] ((CONST CPU_LOGICAL_ID_XLAT **)&CpuLogicalIdAndRevPtr, &LogicalIdEntries, &LogicalFamily, StdHeader);
254 ASSERT (CpuLogicalIdAndRevPtr != NULL);
255 for (k = 0; k < LogicalIdEntries; k++) {
256 if (CpuLogicalIdAndRevPtr[k].RawId == CpuModelAndExtendedModel) {
258 LogicalId->Family = LogicalFamily;
259 LogicalId->Revision = CpuLogicalIdAndRevPtr[k].LogicalId;
269 /*---------------------------------------------------------------------------------------*/
272 * Retrieves a pointer to the desired processor's family specific services structure.
274 * @param[in] Socket The Processor in this Socket.
275 * @param[out] FunctionTable The Processor's Family Specific services.
276 * @param[in] StdHeader Handle of Header for calling lib functions and services.
280 GetCpuServicesOfSocket (
282 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
283 IN AMD_CONFIG_PARAMS *StdHeader
286 GetFeatureServicesOfSocket (&CpuSupportedFamiliesTable,
288 (CONST VOID **) FunctionTable,
290 if (*FunctionTable == NULL) {
291 *FunctionTable = &cpuNullServices;
296 /*---------------------------------------------------------------------------------------*/
299 * Retrieves a pointer to the desired processor's family specific services structure.
301 * @param[in] FamilyTable The table to search in.
302 * @param[in] Socket The Processor in this Socket.
303 * @param[out] CpuServices The Processor's Family Specific services.
304 * @param[in] StdHeader Handle of Header for calling lib functions and services.
308 GetFeatureServicesOfSocket (
309 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
311 OUT CONST VOID **CpuServices,
312 IN AMD_CONFIG_PARAMS *StdHeader
315 CPU_LOGICAL_ID CpuFamilyRevision;
317 GetLogicalIdOfSocket (Socket, &CpuFamilyRevision, StdHeader);
318 GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
322 /*---------------------------------------------------------------------------------------*/
325 * Retrieves a pointer to the executing core's family specific services structure.
327 * @param[out] FunctionTable The Processor's Family Specific services.
328 * @param[in] StdHeader Handle of Header for calling lib functions and services.
332 GetCpuServicesOfCurrentCore (
333 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
334 IN AMD_CONFIG_PARAMS *StdHeader
337 GetFeatureServicesOfCurrentCore (&CpuSupportedFamiliesTable,
338 (CONST VOID **) FunctionTable,
340 if (*FunctionTable == NULL) {
341 *FunctionTable = &cpuNullServices;
345 /*---------------------------------------------------------------------------------------*/
348 * Retrieves a pointer to the family specific services structure for a processor
349 * with the given logical ID.
351 * @param[in] FamilyTable The table to search in.
352 * @param[out] CpuServices The Processor's Family Specific services.
353 * @param[in] StdHeader Handle of Header for calling lib functions and services.
357 GetFeatureServicesOfCurrentCore (
358 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
359 OUT CONST VOID **CpuServices,
360 IN AMD_CONFIG_PARAMS *StdHeader
363 CPU_LOGICAL_ID CpuFamilyRevision;
365 GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
366 GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
370 /*---------------------------------------------------------------------------------------*/
373 * Retrieves a pointer to the family specific services structure for a processor
374 * with the given logical ID.
376 * @param[in] LogicalId The Processor's logical ID.
377 * @param[out] FunctionTable The Processor's Family Specific services.
378 * @param[in] StdHeader Handle of Header for calling lib functions and services.
382 GetCpuServicesFromLogicalId (
383 IN CPU_LOGICAL_ID *LogicalId,
384 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
385 IN AMD_CONFIG_PARAMS *StdHeader
388 GetFeatureServicesFromLogicalId (&CpuSupportedFamiliesTable,
390 (CONST VOID **) FunctionTable,
392 if (*FunctionTable == NULL) {
393 *FunctionTable = &cpuNullServices;
397 /*---------------------------------------------------------------------------------------*/
400 * Retrieves a pointer to the family specific services structure for a processor
401 * with the given logical ID.
403 * @param[in] FamilyTable The table to search in.
404 * @param[in] LogicalId The Processor's logical ID.
405 * @param[out] CpuServices The Processor's Family Specific services.
406 * @param[in] StdHeader Handle of Header for calling lib functions and services.
410 GetFeatureServicesFromLogicalId (
411 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
412 IN CPU_LOGICAL_ID *LogicalId,
413 OUT CONST VOID **CpuServices,
414 IN AMD_CONFIG_PARAMS *StdHeader
417 GetCpuServices (FamilyTable, &LogicalId->Family, CpuServices, StdHeader);
421 /*---------------------------------------------------------------------------------------*/
424 * Finds a family match in the given table, and returns the pointer to the
425 * appropriate table. If no match is found in the table, NULL will be returned.
427 * @param[in] FamilyTable The table to search in.
428 * @param[in] MatchData Family data that must match.
429 * @param[out] CpuServices The Processor's Family Specific services.
430 * @param[in] StdHeader Handle of Header for calling lib functions and services.
436 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
437 IN UINT64 *MatchData,
438 OUT CONST VOID **CpuServices,
439 IN AMD_CONFIG_PARAMS *StdHeader
444 UINT8 NumberOfFamiliesSupported;
445 CONST CPU_SPECIFIC_SERVICES_XLAT *ImageSupportedFamiliesPtr;
447 ImageSupportedFamiliesPtr = FamilyTable->FamilyTable;
448 NumberOfFamiliesSupported = FamilyTable->Elements;
450 for (i = 0; i < NumberOfFamiliesSupported; i++) {
451 if ((ImageSupportedFamiliesPtr[i].Family & *MatchData) != 0) {
457 *CpuServices = ImageSupportedFamiliesPtr[i].TablePtr;
464 /*---------------------------------------------------------------------------------------*/
466 * Used to stub out various family specific tables of information.
468 * @param[in] FamilySpecificServices The current Family Specific Services.
469 * @param[in] Empty NULL, to indicate no data.
470 * @param[out] NumberOfElements Zero, to indicate no data.
471 * @param[in] StdHeader Handle of Header for calling lib functions and services.
476 IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
477 OUT CONST VOID **Empty,
478 OUT UINT8 *NumberOfElements,
479 IN AMD_CONFIG_PARAMS *StdHeader
482 *NumberOfElements = 0;