blob: 3809b775efb28149fc2946a58eb12d9d5be7fef0 [file] [log] [blame]
Frank Vibrans2b4c8312011-02-14 18:30:54 +00001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * AMD CPU Family Translation functions.
6 *
7 *
8 * @xrefitem bom "File Content Label" "Release Content"
9 * @e project: AGESA
10 * @e sub-project: CPU/Interface
11 * @e \$Revision: 37150 $ @e \$Date: 2010-08-31 23:53:37 +0800 (Tue, 31 Aug 2010) $
12 *
13 */
14/*
15 *****************************************************************************
16 *
17 * Copyright (c) 2011, Advanced Micro Devices, Inc.
18 * All rights reserved.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100019 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000020 * 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.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100027 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 * its contributors may be used to endorse or promote products derived
Frank Vibrans2b4c8312011-02-14 18:30:54 +000029 * from this software without specific prior written permission.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100030 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000031 * 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.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100041 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000042 * ***************************************************************************
43 *
44 */
45
46/*----------------------------------------------------------------------------------------
47 * M O D U L E S U S E D
48 *----------------------------------------------------------------------------------------
49 */
50#include "AGESA.h"
51#include "amdlib.h"
52#include "Ids.h"
53#include "cpuRegisters.h"
54#include "CommonReturns.h"
55#include "GeneralServices.h"
56#include "cpuFamilyTranslation.h"
57#include "Filecode.h"
58CODE_GROUP (G1_PEICC)
59RDATA_GROUP (G1_PEICC)
60
61#define FILECODE PROC_CPU_CPUFAMILYTRANSLATION_FILECODE
62
63/*----------------------------------------------------------------------------------------
64 * D E F I N I T I O N S A N D M A C R O S
65 *----------------------------------------------------------------------------------------
66 */
67
68/*----------------------------------------------------------------------------------------
69 * T Y P E D E F S A N D S T R U C T U R E S
70 *----------------------------------------------------------------------------------------
71 */
72
73CONST CPU_SPECIFIC_SERVICES ROMDATA cpuNullServices =
74{
75 0,
76 (PF_CPU_DISABLE_PSTATE) CommonReturnAgesaSuccess,
77 (PF_CPU_TRANSITION_PSTATE) CommonReturnAgesaSuccess,
78 (PF_CPU_GET_IDD_MAX) CommonReturnFalse,
79 (PF_CPU_GET_TSC_RATE) CommonReturnAgesaSuccess,
80 (PF_CPU_GET_NB_FREQ) CommonReturnAgesaSuccess,
81 (PF_CPU_GET_NB_PSTATE_INFO) CommonReturnFalse,
82 (PF_CPU_IS_NBCOF_INIT_NEEDED) CommonReturnAgesaSuccess,
83 (PF_CPU_AP_INITIAL_LAUNCH) CommonReturnFalse,
84 (PF_CPU_NUMBER_OF_BRANDSTRING_CORES) CommonReturnZero8,
85 (PF_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE) CommonReturnAgesaSuccess,
86 (PF_CPU_SET_AP_CORE_NUMBER) CommonVoid,
87 (PF_CPU_GET_AP_CORE_NUMBER) CommonReturnZero32,
88 (PF_CPU_TRANSFER_AP_CORE_NUMBER) CommonVoid,
89 (PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID) CommonReturnAgesaSuccess,
90 (PF_CPU_SAVE_FEATURES) CommonReturnAgesaSuccess,
91 (PF_CPU_WRITE_FEATURES) CommonReturnAgesaSuccess,
92 (PF_CPU_SET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,
93 (PF_CPU_GET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,
94 GetEmptyArray,
95 GetEmptyArray,
96 GetEmptyArray,
97 GetEmptyArray,
98 GetEmptyArray,
99 GetEmptyArray,
100 GetEmptyArray,
101 (PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO) CommonReturnAgesaSuccess,
102 (PF_IS_NB_PSTATE_ENABLED) CommonReturnFalse,
103 (PF_NEXT_LINK_HAS_HTFPY_FEATS) CommonReturnFalse,
104 (PF_SET_HT_PHY_REGISTER) CommonVoid,
105 (PF_GET_NEXT_HT_LINK_FEATURES) CommonVoid,
106 NULL,
107 NULL,
108 NULL,
109 NULL,
110 InitCacheDisabled,
111 (PF_GET_EARLY_INIT_TABLE) CommonVoid
112};
113
114/*----------------------------------------------------------------------------------------
115 * 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
116 *----------------------------------------------------------------------------------------
117 */
118VOID
119STATIC
120GetCpuServices (
121 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
122 IN UINT64 *MatchData,
123 OUT CONST VOID **CpuServices,
124 IN AMD_CONFIG_PARAMS *StdHeader
125 );
126
127/*----------------------------------------------------------------------------------------
128 * E X P O R T E D F U N C T I O N S
129 *----------------------------------------------------------------------------------------
130 */
131extern CPU_FAMILY_SUPPORT_TABLE CpuSupportedFamiliesTable;
132extern CPU_FAMILY_ID_XLAT_TABLE CpuSupportedFamilyIdTable;
133
134/*---------------------------------------------------------------------------------------*/
135/**
136 *
137 * Returns the logical ID of the desired processor. This will be obtained by
138 * reading the CPUID and converting it into a "logical ID" which is not package
139 * dependent.
140 *
141 * @param[in] Socket Socket
142 * @param[out] LogicalId The Processor's Logical ID
143 * @param[in] StdHeader Handle of Header for calling lib functions and services.
144 *
145 */
146VOID
147GetLogicalIdOfSocket (
148 IN UINT32 Socket,
149 OUT CPU_LOGICAL_ID *LogicalId,
150 IN AMD_CONFIG_PARAMS *StdHeader
151 )
152{
153 UINT32 RawCpuid;
154 PCI_ADDR PciAddress;
155 AGESA_STATUS AssumedSuccess;
156
157 RawCpuid = 0;
158
159 if (GetPciAddress (StdHeader, (UINT8)Socket, 0, &PciAddress, &AssumedSuccess)) {
160 PciAddress.Address.Function = FUNC_3;
161 PciAddress.Address.Register = CPUID_FMR;
162 LibAmdPciRead (AccessWidth32, PciAddress, &RawCpuid, StdHeader);
163 GetLogicalIdFromCpuid (RawCpuid, LogicalId, StdHeader);
164 } else {
165 LogicalId->Family = 0;
166 LogicalId->Revision = 0;
167 // Logical ID was not found.
168 IDS_ERROR_TRAP;
169 }
170}
171
172
173/*---------------------------------------------------------------------------------------*/
174/**
175 *
176 * Returns the logical ID of the executing core. This will be obtained by reading
177 * the CPUID and converting it into a "logical ID" which is not package dependent.
178 *
179 * @param[out] LogicalId The Processor's Logical ID
180 * @param[in] StdHeader Handle of Header for calling lib functions and services.
181 *
182 */
183VOID
184GetLogicalIdOfCurrentCore (
185 OUT CPU_LOGICAL_ID *LogicalId,
186 IN AMD_CONFIG_PARAMS *StdHeader
187 )
188{
189 CPUID_DATA CpuidDataStruct;
190
191 LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuidDataStruct, StdHeader);
192 GetLogicalIdFromCpuid (CpuidDataStruct.EAX_Reg, LogicalId, StdHeader);
193}
194
195
196/*---------------------------------------------------------------------------------------*/
197/**
198 *
199 * Returns the logical ID of a processor with the given CPUID value. This
200 * will be obtained by converting it into a "logical ID" which is not package
201 * dependent.
202 *
203 * @param[in] RawCpuid The unprocessed CPUID value to be translated
204 * @param[out] LogicalId The Processor's Logical ID
205 * @param[in] StdHeader Handle of Header for calling lib functions and services
206 *
207 */
208VOID
209GetLogicalIdFromCpuid (
210 IN UINT32 RawCpuid,
211 OUT CPU_LOGICAL_ID *LogicalId,
212 IN AMD_CONFIG_PARAMS *StdHeader
213 )
214{
215 UINT8 i;
216 UINT8 k;
217 UINT8 NumberOfFamiliesSupported;
218 UINT8 NumberOfLogicalSubFamilies;
219 UINT8 LogicalIdEntries;
220 UINT32 j;
221 UINT32 RawFamily;
222 UINT32 CpuModelAndExtendedModel;
223 UINT64 LogicalFamily;
224 BOOLEAN IdNotFound;
225 BOOLEAN FamilyNotFound;
226 CONST PF_CPU_GET_SUBFAMILY_ID_ARRAY *SubFamilyIdPtr;
227 CPU_LOGICAL_ID_XLAT *CpuLogicalIdAndRevPtr;
228 CONST CPU_LOGICAL_ID_FAMILY_XLAT *ImageSupportedId;
229
230 IdNotFound = TRUE;
231 FamilyNotFound = TRUE;
232 CpuLogicalIdAndRevPtr = NULL;
233 ImageSupportedId = CpuSupportedFamilyIdTable.FamilyIdTable;
234 NumberOfFamiliesSupported = CpuSupportedFamilyIdTable.Elements;
235
236 RawFamily = ((RawCpuid & 0xF00) >> 8) + ((RawCpuid & 0xFF00000) >> 20);
237 RawCpuid &= (UINT32) CPU_FMS_MASK;
238 CpuModelAndExtendedModel = (UINT16) ((RawCpuid >> 8) | RawCpuid);
239
240 LogicalId->Family = 0;
241 LogicalId->Revision = 0;
242
243 for (i = 0; i < NumberOfFamiliesSupported && FamilyNotFound; i++) {
244 if (ImageSupportedId[i].Family == RawFamily) {
245 FamilyNotFound = FALSE;
246 LogicalId->Family = ImageSupportedId[i].UnknownRevision.Family;
247 LogicalId->Revision = ImageSupportedId[i].UnknownRevision.Revision;
248
249 NumberOfLogicalSubFamilies = ImageSupportedId[i].Elements;
250 SubFamilyIdPtr = ImageSupportedId[i].SubFamilyIdTable;
251 for (j = 0; j < NumberOfLogicalSubFamilies && IdNotFound; j++) {
efdesign9884cbce22011-08-04 12:09:17 -0600252 SubFamilyIdPtr[j] ((const CPU_LOGICAL_ID_XLAT **)&CpuLogicalIdAndRevPtr, &LogicalIdEntries, &LogicalFamily, StdHeader);
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000253 ASSERT (CpuLogicalIdAndRevPtr != NULL);
254 for (k = 0; k < LogicalIdEntries; k++) {
255 if (CpuLogicalIdAndRevPtr[k].RawId == CpuModelAndExtendedModel) {
256 IdNotFound = FALSE;
257 LogicalId->Family = LogicalFamily;
258 LogicalId->Revision = CpuLogicalIdAndRevPtr[k].LogicalId;
259 break;
260 }
261 }
262 }
263 }
264 }
265}
266
267
268/*---------------------------------------------------------------------------------------*/
269/**
270 *
271 * Retrieves a pointer to the desired processor's family specific services structure.
272 *
273 * @param[in] Socket The Processor in this Socket.
274 * @param[out] FunctionTable The Processor's Family Specific services.
275 * @param[in] StdHeader Handle of Header for calling lib functions and services.
276 *
277 */
278VOID
279GetCpuServicesOfSocket (
280 IN UINT32 Socket,
281 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
282 IN AMD_CONFIG_PARAMS *StdHeader
283 )
284{
285 GetFeatureServicesOfSocket (&CpuSupportedFamiliesTable,
286 Socket,
efdesign9884cbce22011-08-04 12:09:17 -0600287 (const VOID **)FunctionTable,
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000288 StdHeader);
289 if (*FunctionTable == NULL) {
290 *FunctionTable = &cpuNullServices;
291 }
292}
293
294
295/*---------------------------------------------------------------------------------------*/
296/**
297 *
298 * Retrieves a pointer to the desired processor's family specific services structure.
299 *
300 * @param[in] FamilyTable The table to search in.
301 * @param[in] Socket The Processor in this Socket.
302 * @param[out] CpuServices The Processor's Family Specific services.
303 * @param[in] StdHeader Handle of Header for calling lib functions and services.
304 *
305 */
306VOID
307GetFeatureServicesOfSocket (
308 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
309 IN UINT32 Socket,
310 OUT CONST VOID **CpuServices,
311 IN AMD_CONFIG_PARAMS *StdHeader
312 )
313{
314 CPU_LOGICAL_ID CpuFamilyRevision;
315
316 GetLogicalIdOfSocket (Socket, &CpuFamilyRevision, StdHeader);
317 GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
318}
319
320
321/*---------------------------------------------------------------------------------------*/
322/**
323 *
324 * Retrieves a pointer to the executing core's family specific services structure.
325 *
326 * @param[out] FunctionTable The Processor's Family Specific services.
327 * @param[in] StdHeader Handle of Header for calling lib functions and services.
328 *
329 */
330VOID
331GetCpuServicesOfCurrentCore (
332 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
333 IN AMD_CONFIG_PARAMS *StdHeader
334 )
335{
336 GetFeatureServicesOfCurrentCore (&CpuSupportedFamiliesTable,
efdesign9884cbce22011-08-04 12:09:17 -0600337 (const VOID **)FunctionTable,
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000338 StdHeader);
339 if (*FunctionTable == NULL) {
340 *FunctionTable = &cpuNullServices;
341 }
342}
343
344/*---------------------------------------------------------------------------------------*/
345/**
346 *
347 * Retrieves a pointer to the family specific services structure for a processor
348 * with the given logical ID.
349 *
350 * @param[in] FamilyTable The table to search in.
351 * @param[out] CpuServices The Processor's Family Specific services.
352 * @param[in] StdHeader Handle of Header for calling lib functions and services.
353 *
354 */
355VOID
356GetFeatureServicesOfCurrentCore (
357 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
358 OUT CONST VOID **CpuServices,
359 IN AMD_CONFIG_PARAMS *StdHeader
360 )
361{
362 CPU_LOGICAL_ID CpuFamilyRevision;
363
364 GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
365 GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
366}
367
368
369/*---------------------------------------------------------------------------------------*/
370/**
371 *
372 * Retrieves a pointer to the family specific services structure for a processor
373 * with the given logical ID.
374 *
375 * @param[in] LogicalId The Processor's logical ID.
376 * @param[out] FunctionTable The Processor's Family Specific services.
377 * @param[in] StdHeader Handle of Header for calling lib functions and services.
378 *
379 */
380VOID
381GetCpuServicesFromLogicalId (
382 IN CPU_LOGICAL_ID *LogicalId,
383 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
384 IN AMD_CONFIG_PARAMS *StdHeader
385 )
386{
387 GetFeatureServicesFromLogicalId (&CpuSupportedFamiliesTable,
388 LogicalId,
efdesign9884cbce22011-08-04 12:09:17 -0600389 (const VOID **)FunctionTable,
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000390 StdHeader);
391 if (*FunctionTable == NULL) {
392 *FunctionTable = &cpuNullServices;
393 }
394}
395
396/*---------------------------------------------------------------------------------------*/
397/**
398 *
399 * Retrieves a pointer to the family specific services structure for a processor
400 * with the given logical ID.
401 *
402 * @param[in] FamilyTable The table to search in.
403 * @param[in] LogicalId The Processor's logical ID.
404 * @param[out] CpuServices The Processor's Family Specific services.
405 * @param[in] StdHeader Handle of Header for calling lib functions and services.
406 *
407 */
408VOID
409GetFeatureServicesFromLogicalId (
410 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
411 IN CPU_LOGICAL_ID *LogicalId,
412 OUT CONST VOID **CpuServices,
413 IN AMD_CONFIG_PARAMS *StdHeader
414 )
415{
416 GetCpuServices (FamilyTable, &LogicalId->Family, CpuServices, StdHeader);
417}
418
419
420/*---------------------------------------------------------------------------------------*/
421/**
422 *
423 * Finds a family match in the given table, and returns the pointer to the
424 * appropriate table. If no match is found in the table, NULL will be returned.
425 *
426 * @param[in] FamilyTable The table to search in.
427 * @param[in] MatchData Family data that must match.
428 * @param[out] CpuServices The Processor's Family Specific services.
429 * @param[in] StdHeader Handle of Header for calling lib functions and services.
430 *
431 */
432VOID
433STATIC
434GetCpuServices (
435 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
436 IN UINT64 *MatchData,
437 OUT CONST VOID **CpuServices,
438 IN AMD_CONFIG_PARAMS *StdHeader
439 )
440{
441 BOOLEAN IsFamily;
442 UINT8 i;
443 UINT8 NumberOfFamiliesSupported;
444 CONST CPU_SPECIFIC_SERVICES_XLAT *ImageSupportedFamiliesPtr;
445
446 ImageSupportedFamiliesPtr = FamilyTable->FamilyTable;
447 NumberOfFamiliesSupported = FamilyTable->Elements;
448 IsFamily = FALSE;
449 for (i = 0; i < NumberOfFamiliesSupported; i++) {
450 if ((ImageSupportedFamiliesPtr[i].Family & *MatchData) != 0) {
451 IsFamily = TRUE;
452 break;
453 }
454 }
455 if (IsFamily) {
456 *CpuServices = ImageSupportedFamiliesPtr[i].TablePtr;
457 } else {
458 *CpuServices = NULL;
459 }
460}
461
462
463/*---------------------------------------------------------------------------------------*/
464/**
465 * Used to stub out various family specific tables of information.
466 *
467 * @param[in] FamilySpecificServices The current Family Specific Services.
468 * @param[in] Empty NULL, to indicate no data.
469 * @param[out] NumberOfElements Zero, to indicate no data.
470 * @param[in] StdHeader Handle of Header for calling lib functions and services.
471 *
472 */
473VOID
474GetEmptyArray (
475 IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
476 OUT CONST VOID **Empty,
477 OUT UINT8 *NumberOfElements,
478 IN AMD_CONFIG_PARAMS *StdHeader
479 )
480{
481 *NumberOfElements = 0;
482 *Empty = NULL;
483}