AMD Agesa macro expansion fix
[coreboot.git] / src / vendorcode / amd / agesa / f12 / Proc / CPU / cpuPowerMgmt.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD CPU Power Management functions.
6  *
7  * Contains code for doing early power management
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:      AGESA
11  * @e sub-project:  CPU
12  * @e \$Revision: 44324 $   @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 2010) $
13  *
14  */
15 /*
16  ****************************************************************************
17  *
18  * Copyright (c) 2011, 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  *                             M O D U L E S    U S E D
47  *----------------------------------------------------------------------------------------
48  */
49
50 #include "AGESA.h"
51 #include "amdlib.h"
52 #include "cpuRegisters.h"
53 #include "cpuFamilyTranslation.h"
54 #include "OptionMultiSocket.h"
55 #include "cpuApicUtilities.h"
56 #include "cpuEarlyInit.h"
57 #include "cpuPowerMgmtSystemTables.h"
58 #include "cpuServices.h"
59 #include "Filecode.h"
60 CODE_GROUP (G1_PEICC)
61 RDATA_GROUP (G1_PEICC)
62
63 #define FILECODE PROC_CPU_CPUPOWERMGMT_FILECODE
64 /*----------------------------------------------------------------------------------------
65  *                   D E F I N I T I O N S    A N D    M A C R O S
66  *----------------------------------------------------------------------------------------
67  */
68
69 /*----------------------------------------------------------------------------------------
70  *                  T Y P E D E F S     A N D     S T R U C T U R E S
71  *----------------------------------------------------------------------------------------
72  */
73
74 /*----------------------------------------------------------------------------------------
75  *           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
76  *----------------------------------------------------------------------------------------
77  */
78 VOID
79 STATIC
80 PerformThisPmStep (
81   IN       VOID *Step,
82   IN       AMD_CONFIG_PARAMS    *StdHeader,
83   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
84   );
85
86 VOID
87 STATIC
88 GoToMemInitPstateCore0 (
89   IN       AMD_CONFIG_PARAMS *StdHeader,
90   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
91   );
92
93 VOID
94 STATIC
95 GoToMemInitPstateCore (
96   IN       AMD_CONFIG_PARAMS *StdHeader,
97   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
98   );
99
100 /*----------------------------------------------------------------------------------------
101  *                          E X P O R T E D    F U N C T I O N S
102  *----------------------------------------------------------------------------------------
103  */
104 extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
105
106 /*---------------------------------------------------------------------------------------*/
107 /**
108  * Perform the "BIOS Requirements for P-State Initialization and Transitions."
109  *
110  * This is the generic arbiter code to be executed by the BSC.  The system power
111  * management init tables will be traversed.  This must be run by the system BSC
112  * only.
113  *
114  * @param[in]  CpuEarlyParams    Required input parameters for early CPU initialization
115  * @param[in]  StdHeader         Config handle for library and services
116  *
117  * @return     Most severe AGESA_STATUS level that any system processor encountered
118  *
119  */
120 AGESA_STATUS
121 PmInitializationAtEarly (
122   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParams,
123   IN       AMD_CONFIG_PARAMS    *StdHeader
124   )
125 {
126   UINT8              i;
127   UINT8              NumberOfSystemWideSteps;
128   AP_TASK            TaskPtr;
129   AGESA_STATUS       ReturnCode;
130   WARM_RESET_REQUEST Request;
131
132   // Determine the number of steps to perform
133   OptionMultiSocketConfiguration.GetNumberOfSystemPmSteps (&NumberOfSystemWideSteps, StdHeader);
134
135   // Traverse the PM init table
136   TaskPtr.FuncAddress.PfApTaskIC = PerformThisPmStep;
137   TaskPtr.DataTransfer.DataSizeInDwords = 1;
138   TaskPtr.DataTransfer.DataPtr = &i;
139   TaskPtr.DataTransfer.DataTransferFlags = 0;
140   TaskPtr.ExeFlags = PASS_EARLY_PARAMS;
141   for (i = 0; i < NumberOfSystemWideSteps; ++i) {
142     IDS_HDT_CONSOLE (CPU_TRACE, "  Perform PM init step %d\n", i);
143     OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, CpuEarlyParams);
144   }
145
146   // GoToMemInitPstateCore0 only if there is no pending warm reset.
147   GetWarmResetFlag (StdHeader, &Request);
148   if (Request.RequestBit == FALSE) {
149     TaskPtr.FuncAddress.PfApTaskC = GoToMemInitPstateCore0;
150     TaskPtr.DataTransfer.DataSizeInDwords = 0;
151     TaskPtr.ExeFlags = PASS_EARLY_PARAMS;
152     IDS_HDT_CONSOLE (CPU_TRACE, "  Transition all cores to POST P-state\n");
153     OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, CpuEarlyParams);
154   }
155
156   // Retrieve/Process any errors
157   ReturnCode = OptionMultiSocketConfiguration.BscRetrievePmEarlyInitErrors (StdHeader);
158
159   return (ReturnCode);
160 }
161
162
163 /*---------------------------------------------------------------------------------------*/
164 /**
165  * Performs the next step in the executing core 0's family specific power
166  * management table.
167  *
168  * This function determines if the input step is valid, and invokes the power
169  * management step if appropriate.  This must be run by processor core 0s only.
170  *
171  * @param[in]  Step              Zero based step number
172  * @param[in]  StdHeader         Config handle for library and services
173  * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
174  *
175  */
176 VOID
177 STATIC
178 PerformThisPmStep (
179   IN       VOID *Step,
180   IN       AMD_CONFIG_PARAMS    *StdHeader,
181   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
182   )
183 {
184   UINT8  MyNumberOfSteps;
185   SYS_PM_TBL_STEP *FamilyTablePtr;
186   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
187
188   GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
189   FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (const VOID **)&FamilyTablePtr, &MyNumberOfSteps, StdHeader);
190
191   if (*(UINT8 *)Step < MyNumberOfSteps) {
192     if (FamilyTablePtr[*(UINT8 *)Step].FuncPtr != NULL) {
193       if (!(BOOLEAN) (FamilyTablePtr[*(UINT8 *)Step].ExeFlags & PM_EXEFLAGS_WARM_ONLY) ||
194           IsWarmReset (StdHeader)) {
195         FamilyTablePtr[*(UINT8 *)Step].FuncPtr (FamilySpecificServices, CpuEarlyParamsPtr, StdHeader);
196       }
197     }
198   }
199 }
200
201
202 /*---------------------------------------------------------------------------------------*/
203 /**
204  * Transitions the executing processor to the desired P-state.
205  *
206  * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is
207  * run by all processor core 0s.
208  *
209  * @param[in]  StdHeader         Config handle for library and services
210  * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
211  *
212  */
213 VOID
214 STATIC
215 GoToMemInitPstateCore0 (
216   IN       AMD_CONFIG_PARAMS *StdHeader,
217   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
218   )
219 {
220   AP_TASK      TaskPtr;
221
222   TaskPtr.FuncAddress.PfApTaskC = GoToMemInitPstateCore;
223   TaskPtr.DataTransfer.DataSizeInDwords = 0;
224   TaskPtr.ExeFlags = WAIT_FOR_CORE | PASS_EARLY_PARAMS;
225   ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr);
226 }
227
228
229 /*---------------------------------------------------------------------------------------*/
230 /**
231  * Transitions the executing core to the desired P-state.
232  *
233  * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is
234  * run by all system cores.
235  *
236  * @param[in]  StdHeader         Config handle for library and services
237  * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
238  *
239  */
240 VOID
241 STATIC
242 GoToMemInitPstateCore (
243   IN       AMD_CONFIG_PARAMS    *StdHeader,
244   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
245   )
246 {
247   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
248
249   GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
250   FamilySpecificServices->TransitionPstate (FamilySpecificServices, CpuEarlyParamsPtr->MemInitPState, (BOOLEAN) FALSE, StdHeader);
251 }