Add constants for fast path resume copying
[coreboot.git] / src / vendorcode / amd / agesa / f14 / Proc / CPU / cpuFamilyTranslation.c
1 /* $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.
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  */
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"
58 CODE_GROUP (G1_PEICC)
59 RDATA_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
73 CONST 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  */
118 VOID
119 STATIC
120 GetCpuServices (
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  */
131 extern CPU_FAMILY_SUPPORT_TABLE CpuSupportedFamiliesTable;
132 extern 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  */
146 VOID
147 GetLogicalIdOfSocket (
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  */
183 VOID
184 GetLogicalIdOfCurrentCore (
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  */
208 VOID
209 GetLogicalIdFromCpuid (
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++) {
252         SubFamilyIdPtr[j] ((const CPU_LOGICAL_ID_XLAT **)&CpuLogicalIdAndRevPtr, &LogicalIdEntries, &LogicalFamily, StdHeader);
253         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  */
278 VOID
279 GetCpuServicesOfSocket (
280   IN       UINT32 Socket,
281      OUT   CONST CPU_SPECIFIC_SERVICES **FunctionTable,
282   IN       AMD_CONFIG_PARAMS *StdHeader
283   )
284 {
285   GetFeatureServicesOfSocket (&CpuSupportedFamiliesTable,
286                               Socket,
287                               (const VOID **)FunctionTable,
288                               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  */
306 VOID
307 GetFeatureServicesOfSocket (
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  */
330 VOID
331 GetCpuServicesOfCurrentCore (
332      OUT   CONST CPU_SPECIFIC_SERVICES **FunctionTable,
333   IN       AMD_CONFIG_PARAMS *StdHeader
334   )
335 {
336   GetFeatureServicesOfCurrentCore (&CpuSupportedFamiliesTable,
337                                    (const VOID **)FunctionTable,
338                                    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  */
355 VOID
356 GetFeatureServicesOfCurrentCore (
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  */
380 VOID
381 GetCpuServicesFromLogicalId (
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,
389                                    (const VOID **)FunctionTable,
390                                    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  */
408 VOID
409 GetFeatureServicesFromLogicalId (
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  */
432 VOID
433 STATIC
434 GetCpuServices (
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  */
473 VOID
474 GetEmptyArray (
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 }