AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / Feature / cpuFeatureLeveling.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD CPU Feature Leveling Function.
6  *
7  * Contains code to Level the Feature in a multi-socket system
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:      AGESA
11  * @e sub-project:  CPU
12  * @e \$Revision: 56279 $   @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
13  *
14  */
15 /*
16  ******************************************************************************
17  *
18  * Copyright (C) 2012 Advanced Micro Devices, Inc.
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions are met:
23  *     * Redistributions of source code must retain the above copyright
24  *       notice, this list of conditions and the following disclaimer.
25  *     * Redistributions in binary form must reproduce the above copyright
26  *       notice, this list of conditions and the following disclaimer in the
27  *       documentation and/or other materials provided with the distribution.
28  *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
29  *       its contributors may be used to endorse or promote products derived
30  *       from this software without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35  * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  ******************************************************************************
44  *----------------------------------------------------------------------------
45  */
46
47
48 /*
49  *----------------------------------------------------------------------------
50  *                                MODULES USED
51  *
52  *----------------------------------------------------------------------------
53  */
54 #include "AGESA.h"
55 #include "amdlib.h"
56 #include "cpuRegisters.h"
57 #include "GeneralServices.h"
58 #include "cpuServices.h"
59 #include "cpuPostInit.h"
60 #include "cpuApicUtilities.h"
61 #include "cpuFamilyTranslation.h"
62 #include "Filecode.h"
63 CODE_GROUP (G1_PEICC)
64 RDATA_GROUP (G2_PEI)
65
66 #define FILECODE PROC_CPU_FEATURE_CPUFEATURELEVELING_FILECODE
67 /*----------------------------------------------------------------------------
68  *                          DEFINITIONS AND MACROS
69  *
70  *----------------------------------------------------------------------------
71  */
72
73
74 /*----------------------------------------------------------------------------
75  *                           TYPEDEFS AND STRUCTURES
76  *
77  *----------------------------------------------------------------------------
78  */
79
80 /*----------------------------------------------------------------------------------------
81  *                          E X P O R T E D    F U N C T I O N S
82  *----------------------------------------------------------------------------------------
83  */
84
85 /*----------------------------------------------------------------------------
86  *                        PROTOTYPES OF LOCAL FUNCTIONS
87  *
88  *----------------------------------------------------------------------------
89  */
90 VOID
91 STATIC
92 SaveFeatures (
93   IN OUT   VOID *cpuFeatureListPtr,
94   IN OUT   AMD_CONFIG_PARAMS *StdHeader
95   );
96
97 VOID
98 STATIC
99 WriteFeatures (
100   IN OUT   VOID *cpuFeatureListPtr,
101   IN OUT   AMD_CONFIG_PARAMS *StdHeader
102   );
103
104 VOID
105 STATIC
106 GetGlobalCpuFeatureListAddress (
107      OUT   UINT64            **Address,
108   IN       AMD_CONFIG_PARAMS *StdHeader
109   );
110
111 /*----------------------------------------------------------------------------------------
112  *                          P U B L I C     F U N C T I O N S
113  *----------------------------------------------------------------------------------------
114  */
115
116 /* -----------------------------------------------------------------------------*/
117 /**
118  *
119  *  FeatureLeveling
120  *
121  *    CPU feature leveling. Set least common features set of all CPUs
122  *
123  *    @param[in,out]   StdHeader   - Pointer to AMD_CONFIG_PARAMS struct.
124  *
125  */
126 VOID
127 FeatureLeveling (
128   IN OUT   AMD_CONFIG_PARAMS *StdHeader
129   )
130 {
131   UINT32 BscSocket;
132   UINT32 Ignored;
133   UINT32 BscCoreNum;
134   UINT32 Socket;
135   UINT32 Core;
136   UINT32 NumberOfSockets;
137   UINT32 NumberOfCores;
138   BOOLEAN *FirstTime;
139   BOOLEAN *NeedLeveling;
140   AGESA_STATUS IgnoredSts;
141   CPU_FEATURES_LIST *globalCpuFeatureList;
142   AP_TASK  TaskPtr;
143
144   ASSERT (IsBsp (StdHeader, &IgnoredSts));
145
146   GetGlobalCpuFeatureListAddress ((UINT64 **) &globalCpuFeatureList, StdHeader);
147   FirstTime = (BOOLEAN *) ((UINT8 *) globalCpuFeatureList + sizeof (CPU_FEATURES_LIST));
148   NeedLeveling = (BOOLEAN *) ((UINT8 *) globalCpuFeatureList + sizeof (CPU_FEATURES_LIST) + sizeof (BOOLEAN));
149
150   *FirstTime = TRUE;
151   *NeedLeveling = FALSE;
152
153   LibAmdMemFill (globalCpuFeatureList, 0xFF, sizeof (CPU_FEATURES_LIST), StdHeader);
154   IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts);
155   NumberOfSockets = GetPlatformNumberOfSockets ();
156
157   TaskPtr.FuncAddress.PfApTaskI = SaveFeatures;
158   TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (CPU_FEATURES_LIST);
159   TaskPtr.ExeFlags = WAIT_FOR_CORE;
160   TaskPtr.DataTransfer.DataPtr = globalCpuFeatureList;
161   TaskPtr.DataTransfer.DataTransferFlags = DATA_IN_MEMORY;
162
163   for (Socket = 0; Socket < NumberOfSockets; Socket++) {
164     if (IsProcessorPresent (Socket, StdHeader)) {
165       if (Socket !=  BscSocket) {
166         ApUtilRunCodeOnSocketCore ((UINT8)Socket, 0, &TaskPtr, StdHeader);
167       }
168     }
169   }
170   ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, NULL);
171
172   if (*NeedLeveling) {
173     TaskPtr.FuncAddress.PfApTaskI  = WriteFeatures;
174     for (Socket = 0; Socket < NumberOfSockets; Socket++) {
175       if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
176         for (Core = 0; Core < NumberOfCores; Core++) {
177           if ((Socket != BscSocket) || (Core != BscCoreNum)) {
178             ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8)Core, &TaskPtr, StdHeader);
179           }
180         }
181       }
182     }
183     ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, NULL);
184   }
185 }
186
187 /*----------------------------------------------------------------------------------------
188  *                          L O C A L      F U N C T I O N S
189  *----------------------------------------------------------------------------------------
190  */
191
192 /* -----------------------------------------------------------------------------*/
193 /**
194  *
195  *  SaveFeatures
196  *
197  *    save least common features set of all CPUs
198  *
199  *    @param[in,out]  cpuFeatureListPtr  - Pointer to CPU Feature List.
200  *    @param[in,out]  StdHeader          - Pointer to AMD_CONFIG_PARAMS struct.
201  *
202  */
203 VOID
204 STATIC
205 SaveFeatures (
206   IN OUT   VOID *cpuFeatureListPtr,
207   IN OUT   AMD_CONFIG_PARAMS *StdHeader
208   )
209 {
210   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
211   FamilySpecificServices = NULL;
212
213   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
214   FamilySpecificServices->SaveFeatures (FamilySpecificServices, cpuFeatureListPtr, StdHeader);
215 }
216
217 /* -----------------------------------------------------------------------------*/
218 /**
219  *
220  *  WriteFeatures
221  *
222  *    Write out least common features set of all CPUs
223  *
224  *    @param[in,out]  cpuFeatureListPtr  - Pointer to CPU Feature List.
225  *    @param[in,out]  StdHeader          - Pointer to AMD_CONFIG_PARAMS struct.
226  *
227  */
228 VOID
229 STATIC
230 WriteFeatures (
231   IN OUT   VOID *cpuFeatureListPtr,
232   IN OUT   AMD_CONFIG_PARAMS *StdHeader
233   )
234 {
235   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
236   FamilySpecificServices = NULL;
237
238   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
239   FamilySpecificServices->WriteFeatures (FamilySpecificServices, cpuFeatureListPtr, StdHeader);
240 }
241
242 /*---------------------------------------------------------------------------------------*/
243 /**
244  *
245  *  GetGlobalCpuFeatureListAddress
246  *
247  *   Determines the address in system DRAM that should be used for CPU feature leveling.
248  *
249  * @param[out] Address           Address to utilize
250  * @param[in]  StdHeader         Config handle for library and services
251  *
252  *
253  */
254 VOID
255 STATIC
256 GetGlobalCpuFeatureListAddress (
257      OUT   UINT64            **Address,
258   IN       AMD_CONFIG_PARAMS *StdHeader
259   )
260 {
261   UINT64 AddressValue;
262
263   AddressValue = GLOBAL_CPU_FEATURE_LIST_TEMP_ADDR;
264
265   *Address = (UINT64 *)(AddressValue);
266 }