blob: 5eb55d8da270b4938428cc82ad214edd2a0a9887 [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * AMD CPU Pstate Leveling Function.
6 *
7 * Contains code to level the Pstates 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: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
13 *
14 */
15/*****************************************************************************
16 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080017 * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc.
18 * All rights reserved.
zbao7d94cf92012-07-02 14:19:14 +080019 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080020 * 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.
zbao7d94cf92012-07-02 14:19:14 +080030 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080031 * 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.
zbao7d94cf92012-07-02 14:19:14 +080041 ******************************************************************************
42 *----------------------------------------------------------------------------
43 */
44
45
46/*
47 *----------------------------------------------------------------------------
48 * MODULES USED
49 *
50 *----------------------------------------------------------------------------
51 */
52#include "AGESA.h"
53#include "amdlib.h"
54#include "OptionPstate.h"
55#include "cpuLateInit.h"
56#include "cpuRegisters.h"
57#include "cpuPostInit.h"
58#include "Ids.h"
59#include "cpuFamilyTranslation.h"
60#include "cpuPstateTables.h"
61#include "cpuApicUtilities.h"
62#include "cpuServices.h"
63#include "GeneralServices.h"
64#include "Filecode.h"
65CODE_GROUP (G1_PEICC)
66RDATA_GROUP (G1_PEICC)
67
68#define FILECODE PROC_CPU_FEATURE_CPUPSTATELEVELING_FILECODE
69
70/*----------------------------------------------------------------------------
71 * DEFINITIONS AND MACROS
72 *
73 *----------------------------------------------------------------------------
74 */
75extern OPTION_PSTATE_POST_CONFIGURATION OptionPstatePostConfiguration; // global user config record
76extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable;
77
78/*----------------------------------------------------------------------------
79 * TYPEDEFS AND STRUCTURES
80 *
81 *----------------------------------------------------------------------------
82 */
83
84/*----------------------------------------------------------------------------
85 * PROTOTYPES OF LOCAL FUNCTIONS
86 *
87 *----------------------------------------------------------------------------
88 */
89AGESA_STATUS
90PutAllCoreInPState0 (
91 IN OUT PSTATE_LEVELING *PStateBufferPtr,
92 IN AMD_CONFIG_PARAMS *StdHeader
93 );
94
95AGESA_STATUS
96StartPstateMsrModify (
97 IN S_CPU_AMD_PSTATE *CpuAmdPState,
98 IN AMD_CONFIG_PARAMS *StdHeader
99 );
100
101VOID
102STATIC
103PutCoreInPState0 (
104 IN VOID *PStateBuffer,
105 IN AMD_CONFIG_PARAMS *StdHeader
106 );
107
108AGESA_STATUS
109PStateLevelingStub (
110 IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr,
111 IN AMD_CONFIG_PARAMS *StdHeader
112 );
113
114AGESA_STATUS
115PStateLevelingMain (
116 IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr,
117 IN AMD_CONFIG_PARAMS *StdHeader
118 );
119
120VOID
121CorePstateRegModify (
122 IN VOID *CpuAmdPState,
123 IN AMD_CONFIG_PARAMS *StdHeader
124 );
125
126/**
127 *---------------------------------------------------------------------------------------
128 *
129 * PStateLeveling
130 *
131 * Description:
132 * This function will populate the PStateBuffer, after doing the PState Leveling
133 * Note: This function should be called for every core in the system.
134 *
135 * Parameters:
136 * @param[in,out] *PStateStrucPtr
137 * @param[in] *StdHeader
138 *
139 * @retval AGESA_STATUS
140 *
141 *---------------------------------------------------------------------------------------
142 **/
143AGESA_STATUS
144PStateLeveling (
145 IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr,
146 IN AMD_CONFIG_PARAMS *StdHeader
147 )
148{
149 AGESA_TESTPOINT (TpProcCpuEntryPstateLeveling, StdHeader);
150 return ((*(OptionPstatePostConfiguration.PstateLeveling)) (PStateStrucPtr, StdHeader));
151 // Note: Split config struct into PEI/DXE halves. This one is PEI.
152}
153
154/**--------------------------------------------------------------------------------------
155 *
156 * PStateLevelingStub
157 *
158 * Description:
159 * This is the default routine for use when the PState option is NOT requested.
160 * The option install process will create and fill the transfer vector with
161 * the address of the proper routine (Main or Stub). The link optimizer will
162 * strip out of the .DLL the routine that is not used.
163 *
164 * Parameters:
165 * @param[in,out] *PStateStrucPtr
166 * @param[in] *StdHeader
167 *
168 * @retval AGESA_STATUS
169 *
170 *---------------------------------------------------------------------------------------
171 **/
172AGESA_STATUS
173PStateLevelingStub (
174 IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr,
175 IN AMD_CONFIG_PARAMS *StdHeader
176 )
177{
178 return AGESA_UNSUPPORTED;
179}
180
181/**--------------------------------------------------------------------------------------
182 *
183 * PStateLevelingMain
184 *
185 * Description:
186 * This is the common routine for creating the ACPI information tables.
187 *
188 * Parameters:
189 * @param[in,out] *PStateStrucPtr
190 * @param[in] *StdHeader
191 *
192 * @retval AGESA_STATUS
193 *
194 *---------------------------------------------------------------------------------------
195 **/
196AGESA_STATUS
197PStateLevelingMain (
198 IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr,
199 IN AMD_CONFIG_PARAMS *StdHeader
200 )
201{
202 UINT32 i;
203 UINT32 k;
204 UINT32 m;
205 UINT32 TotalIterations;
206 UINT32 LogicalSocketCount;
207 UINT32 TempVar_a;
208 UINT32 TempVar_b;
209 UINT32 TempVar_c;
210 UINT32 TempVar_d;
211 UINT32 TempVar_e;
212 UINT32 TempVar_f;
213 PCI_ADDR PciAddress;
214
215 UINT32 TempFreqArray[20];
216 UINT32 TempPowerArray[20];
217 UINT32 TempIddValueArray[20];
218 UINT32 TempIddDivArray[20];
219 UINT32 TempSocketPiArray[20];
220 UINT32 TempSwP0Array[MAX_SOCKETS_SUPPORTED];
221
222 BOOLEAN TempFlag1;
223 BOOLEAN TempFlag2;
224 BOOLEAN TempFlag3;
225 BOOLEAN TempFlag4;
226 BOOLEAN AllCoresHaveHtcCapEquToZeroFlag;
227 BOOLEAN AllCoreHaveMaxOnePStateFlag;
228 BOOLEAN PstateMaxValEquToPstateHtcLimitFlag;
229 BOOLEAN AtLeastOneCoreHasPstateHtcLimitEquToOneFlag;
230 BOOLEAN PstateMaxValMinusHtcPstateLimitLessThan2Flag;
231 PSTATE_LEVELING *PStateBufferPtr;
232 PSTATE_LEVELING *PStateBufferPtrTmp = NULL;
233 UINT32 MaxPstateInNode;
234 AGESA_STATUS Status;
235
236 TempFlag1 = FALSE;
237 TempFlag2 = FALSE;
238 TempFlag3 = FALSE;
239 TempFlag4 = FALSE;
240 AllCoresHaveHtcCapEquToZeroFlag = FALSE;
241 AllCoreHaveMaxOnePStateFlag = FALSE;
242 PstateMaxValEquToPstateHtcLimitFlag = FALSE;
243 AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = FALSE;
244 PstateMaxValMinusHtcPstateLimitLessThan2Flag = FALSE;
245 PStateBufferPtr = PStateStrucPtr->PStateLevelingStruc;
246 Status = AGESA_SUCCESS;
247
248 if (PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_1) {
249 PStateBufferPtr[0].AllCpusHaveIdenticalPStates = TRUE;
250 PStateBufferPtr[0].InitStruct = 1;
251 return AGESA_UNSUPPORTED;
252 }
253
254 LogicalSocketCount = PStateStrucPtr->TotalSocketInSystem;
255 ASSERT (LogicalSocketCount <= MAX_SOCKETS_SUPPORTED);
256
257 // This section of code will execute only for "core 0" i.e. BSP
258 // Read P-States of all the cores.
259 if (PStateBufferPtr[0].InitStruct == 0) {
260 // Determine 'software' P0 indices for each socket
261 for (i = 0; i < LogicalSocketCount; i++) {
262 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
263 TempSwP0Array[i] = (UINT32) (PStateBufferPtrTmp->PStateCoreStruct[0].NumberOfBoostedStates);
264 }
265
266 // Check if core frequency and power are same across all sockets.
267 TempFlag1 = FALSE;
268 for (i = 1; i < LogicalSocketCount; i++) {
269 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
270 if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue != PStateBufferPtr[0].PStateCoreStruct[0].PStateMaxValue)) {
271 TempFlag1 = TRUE;
272 break;
273 }
274 MaxPstateInNode = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue;
275 for (k = TempSwP0Array[i]; k <= MaxPstateInNode; k++) {
276 if ((PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[k].CoreFreq !=
277 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].CoreFreq) ||
278 (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[k].Power !=
279 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].Power)) {
280 TempFlag1 = TRUE;
281 break; // Come out of the inner FOR loop
282 }
283 }
284 if (TempFlag1) {
285 break; // Come out of the outer FOR loop
286 }
287 }
288
289 if (!TempFlag1) {
290 // No need to do pStateLeveling, or writing to pState MSR registers
291 // if all CPUs have Identical PStates
292 PStateBufferPtr[0].AllCpusHaveIdenticalPStates = TRUE;
293 PStateBufferPtr[0].InitStruct = 1;
294 PutAllCoreInPState0 (PStateBufferPtr, StdHeader);
295 return AGESA_UNSUPPORTED;
296 } else {
297 PStateBufferPtr[0].AllCpusHaveIdenticalPStates = FALSE;
298 }
299
300 // 1_b) & 1_c)
301 TempFlag1 = FALSE;
302 TempFlag2 = FALSE;
303 for (i = 0; i < LogicalSocketCount; i++) {
304 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
305 if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue == TempSwP0Array[i]) {
306 TempFlag1 = TRUE;
307 } else {
308 TempFlag2 = TRUE;
309 }
310 if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcCapable == 0) {
311 TempFlag3 = TRUE;
312 } else {
313 TempFlag4 = TRUE;
314 }
315
316 if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue -
317 PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) < 2) {
318 PstateMaxValMinusHtcPstateLimitLessThan2Flag = TRUE;
319 }
320
321 if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue ==
322 PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) {
323 PstateMaxValEquToPstateHtcLimitFlag = TRUE;
324 }
325
326 if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 1) {
327 AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = TRUE;
328 }
329 }
330
331 // Do general setup of flags, that we may use later
332 // Implementation of (1_b)
333 if (TempFlag1 && TempFlag2) {
334 //
335 //Processors with only one enabled P-state (F3xDC[PstateMaxVal]=000b) cannot be mixed in a system with
336 //processors with more than one enabled P-state (F3xDC[PstateMaxVal]!=000b).
337 //
338 PStateBufferPtr[0].InitStruct = 1;
339 PStateBufferPtr[0].CreateAcpiTables = 0;
340 PutAllCoreInPState0 (PStateBufferPtr, StdHeader);
341 return AGESA_UNSUPPORTED;
342 } else if (TempFlag1 && !TempFlag2) {
343 //
344 //all processors have only 1 enabled P-state
345 //
346 AllCoreHaveMaxOnePStateFlag = TRUE;
347 PStateBufferPtr[0].OnlyOneEnabledPState = TRUE;
348 }
349
350 // Processors with F3xE8[HTC_CAPABLE] = 1 can not be
351 // mixed in system with processors with F3xE8[HTC_CAPABLE] = 0.
352 if (TempFlag3 && TempFlag4) {
353 PStateBufferPtr[0].InitStruct = 1;
354 PStateBufferPtr[0].CreateAcpiTables = 0;
355 PutAllCoreInPState0 (PStateBufferPtr, StdHeader);
356 return AGESA_UNSUPPORTED;
357 }
358
359 if (TempFlag3) {
360 //
361 //If code run to here means that all processors do not have HTC_CAPABLE.
362 //
363 AllCoresHaveHtcCapEquToZeroFlag = TRUE;
364 }
365
366 //--------------------------------------------------------------------------------
367 // S T E P - 2
368 //--------------------------------------------------------------------------------
369 // Now run the PState Leveling Algorithm which will create mixed CPU P-State
370 // Tables.
371 // Follow the algorithm in the latest BKDG
372 // -------------------------------------------------------------------------------
373 // Match P0 CPU COF for all CPU cores to the lowest P0 CPU COF value in the
374 // coherent fabric, and match P0 power for all CPU cores to the highest P0 power
375 // value in the coherent fabric.
376 // 2_a) If all processors have only 1 enabled P-State BIOS must write the
377 // appropriate CpuFid value resulting from the matched CPU COF to all
378 // copies of MSRC001_0070[CpuFid], and exit the sequence (No further
379 // steps are executed)
380 //--------------------------------------------------------------------------------
381 // Identify the lowest P0 Frequency and maximum P0 Power
382 TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].CoreFreq;
383 TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].Power;
384 TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].IddValue;
385 TempVar_b = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].IddDiv;
386
387 for (i = 0; i < LogicalSocketCount; i++) {
388 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
389 if (TempVar_d > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq) {
390 TempVar_d = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq;
391 }
392
393 if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power) {
394 TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power;
395 TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddValue;
396 TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddDiv;
397 }
398 }
399
400 // Set P0 Frequency and Power for all CPUs
401 for (i = 0; i < LogicalSocketCount; i++) {
402 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
403 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq = TempVar_d;
404 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power = TempVar_e;
405 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddValue = TempVar_a;
406 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddDiv = TempVar_b;
407 }
408
409 // 2_a)
410 if (!AllCoreHaveMaxOnePStateFlag) {
411 //--------------------------------------------------------------------------
412 // STEP - 3
413 //--------------------------------------------------------------------------
414 // Match the CPU COF and power for P-states used by HTC. Skip to step 4
415 // is any processor reports F3xE8[HTC_Capable] = 0;
416 // 3_a) Set F3x64[HtcPstateLimit] = 001b and F3x68[StcPstateLimit] = 001b for
417 // processors with F3x64[HtcPstateLimit] = 000b.
418 // 3_b) Identify the lowest CPU COF for all processors in the P-state
419 // pointed to by [The Hardware Thermal Control (HTC) Register]
420 // F3x64[HtcPstateLimit]
421 // 3_c) Modify the CPU COF pointed to by [The Hardware Thermal Control
422 // (HTC) Register] F3x64[HtcPstateLimit] for all processors to the
423 // previously identified lowest CPU COF value.
424 // 3_d) Identify the highest power for all processors in the P-state
425 // pointed to by [The Hardware Thermal Control (HTC) Register]
426 // F3x64[HtcPstateLimit].
427 // 3_e) Modify the power pointed to by [The Hardware Thermal Control (HTC)
428 // Register] F3x64[HtcPstateLimit] to the previously identified
429 // highest power value.
430 if (!AllCoresHaveHtcCapEquToZeroFlag) {
431 // 3_a)
432 for (i = 0; i < LogicalSocketCount; i++) {
433 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
434 if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 0) {
435 // To Be Done (Set Htc and Stc PstateLimit values)
436 // for this CPU (using PCI address space)
437 for (k = 0; k < (UINT8)GetPlatformNumberOfModules (); k++) {
438 if (GetPciAddress (StdHeader, PStateBufferPtrTmp->SocketNumber, k, &PciAddress, &Status)) {
439 // Set F3x64[HtcPstateLimit] = 001b
440 PciAddress.Address.Function = FUNC_3;
441 PciAddress.Address.Register = HARDWARE_THERMAL_CTRL_REG;
442 LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
443 // Bits 30:28
444 TempVar_d = (TempVar_d & 0x8FFFFFFF) | 0x10000000;
445 LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
446
447 // Set F3x68[StcPstateLimit] = 001b
448 PciAddress.Address.Register = SOFTWARE_THERMAL_CTRL_REG;
449 LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
450 // Bits 28:30
451 TempVar_d = (TempVar_d & 0x8FFFFFFF) | 0x10000000;
452 LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
453 }
454 }
455 // Set LocalBuffer
456 PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit = 1;
457 if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1) < 2) {
458 PstateMaxValMinusHtcPstateLimitLessThan2Flag = TRUE;
459 }
460
461 if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue == 1) {
462 PstateMaxValEquToPstateHtcLimitFlag = TRUE;
463 }
464 }
465
466 if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 1) {
467 AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = TRUE;
468 }
469 }
470
471 // 3_b) and 3_d)
472 TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit;
473 TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq;
474 TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].Power;
475 TempVar_f = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue;
476 TempVar_c = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv;
477 for (i = 0; i < LogicalSocketCount; i++) {
478 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
479 for (k = 0; k < 1; k++) {
480 TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit;
481 if (TempVar_d > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq) {
482 TempVar_d = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq;
483 }
484
485 if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power) {
486 TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power;
487 TempVar_f = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddValue;
488 TempVar_c = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddDiv;
489 }
490 }
491 }
492
493 // 3_c) and 3_e)
494 for (i = 0; i < LogicalSocketCount; i++) {
495 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
496 TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit;
497 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq = TempVar_d;
498 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].Power = TempVar_e;
499 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue = TempVar_f;
500 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv = TempVar_c;
501 }
502 } // if(AllCoresHaveHtcCapEquToZeroFlag)
503
504
505 //--------------------------------------------------------------------------
506 // STEP - 4
507 //--------------------------------------------------------------------------
508 // Match the CPU COF and power for the lowest performance P-state:
509 // 4_a) If F3xDC[PstateMaxVal] = F3x64[HtcPstateLimit] for any processor,
510 // set PstateEn = 0 for all the P-states greater than
511 // F3x64[HtcPstateLimit] for all processors.
512 // 4_b) Identify the lowest CPU COF for all processors in the P-state
513 // pointed to by F3xDC[PstateMaxVal].
514 // 4_c) Modify the CPU COF for all processors in the P-state pointed to by
515 // F3xDC[PstateMaxVal] to the previously identified lowest CPU COF
516 // value.
517 // 4_d) Identify the highest power for all processors in the P-state
518 // pointed to by F3xDC[PstateMaxVal].
519 // 4_e) Modify the power for all processors in the P-state pointed to by
520 // F3xDC[PstateMaxVal] to the previously identified highest power
521 // value.
522
523 // 4_a)
524 if (PstateMaxValEquToPstateHtcLimitFlag) {
525 for (i = 0; i < LogicalSocketCount; i++) {
526 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
527 TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit + 1;
528 for (k = TempVar_b; k <= PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; k++) {
529 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0;
530 }
531 //--------------------------------------------------------------------------
532 // STEP - 5
533 //--------------------------------------------------------------------------
534 // 5_a) Modify F3xDC[PstateMaxVal] to indicate the lowest performance
535 // P-state with PstateEn set for each processor (Step 4 can disable
536 // P-states pointed to by F3xDC[PstateMaxVal])
537
538 // Use this value of HtcPstateLimit to program the
539 // F3xDC[pStateMaxValue]
540 TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit;
541 TempVar_e <<= 8;
542 // Bits 10:8
543
544 for (m = 0; m < (UINT8)GetPlatformNumberOfModules (); m++) {
545 if (GetPciAddress (StdHeader, PStateBufferPtrTmp->SocketNumber, m, &PciAddress, &Status)) {
546 PciAddress.Address.Function = FUNC_3;
547 PciAddress.Address.Register = CLOCK_POWER_TIMING_CTRL2_REG;
548 LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
549 TempVar_d = (TempVar_d & 0xFFFFF8FF) | TempVar_e;
550 LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
551 }
552 }//End of step 5
553 }
554 }// End of 4_a)
555
556 // 4_b) and 4_d)
557 TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].PStateMaxValue;
558 TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq;
559 TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].Power;
560 TempVar_f = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue;
561 TempVar_c = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv;
562
563 for (i = 0; i < LogicalSocketCount; i++) {
564 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
565 TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue;
566 if (TempVar_d >
567 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq) {
568 TempVar_d =
569 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq;
570 }
571
572 if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power) {
573 TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power;
574 TempVar_f = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddValue;
575 TempVar_c = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddDiv;
576 }
577 }
578
579 // 4_c) and 4_e)
580 for (i = 0; i < LogicalSocketCount; i++) {
581 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
582 TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue;
583 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq = TempVar_d;
584 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].Power = TempVar_e;
585 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue = TempVar_f;
586 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv = TempVar_c;
587 }
588
589
590 //--------------------------------------------------------------------------
591 // STEP - 6
592 //--------------------------------------------------------------------------
593 // Match the CPU COF and power for upper intermediate performance
594 // P-state(s):
595 // Upper intermediate PStates = PStates between (Not including) P0 and
596 // F3x64[HtcPstateLimit]
597 // 6_a) If F3x64[HtcPstateLimit] = 001b for any processor, set PstateEn = 0
598 // for enabled upper intermediate P-states for all processors with
599 // F3x64[HtcPstateLimit] > 001b and skip the remaining actions for
600 // this numbered step.
601 // 6_b) Define each of the available upper intermediate P-states; for each
602 // processor concurrently evaluate the following loop; when any
603 // processor falls out of the loop (runs out of available upper
604 // intermediate Pstates) all other processors have their remaining
605 // upper intermediate P-states invalidated (PstateEn = 0);
606 // for (i = F3x64[HtcPstateLimit] - 1; i > 0; i--)
607 // - Identify the lowest CPU COF for P(i).
608 // - Identify the highest power for P(i).
609 // - Modify P(i) CPU COF for all processors to the previously
610 // identified lowest CPU COF value.
611 // - Modify P(i) power for all processors to the previously
612 // identified highest power value.
613
614 // 6_a)
615 if (AtLeastOneCoreHasPstateHtcLimitEquToOneFlag) {
616 for (i = 0; i < LogicalSocketCount; i++) {
617 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
618 for (k = TempSwP0Array[i] + 1; k < (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit); k++) {
619 if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit > 1) {
620 // Make a function call to clear the
621 // structure values
622 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0;
623 }
624 }
625 }
626 }
627 // 6_b)
628 else {
629 // Identify Lowest Frequency and Highest Power
630 TotalIterations = 0;
631 TempFlag1 = TRUE;
632
633 for (i = 0; i < LogicalSocketCount; i++) {
634 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
635 TempSocketPiArray[i] = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit - 1;
636 }
637
638 do {
639 //For first socket, try to find a candidate
640 if (TempSocketPiArray[0] != TempSwP0Array[0]) {
641 while (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].PStateEnable == 0) {
642 TempSocketPiArray[0] = TempSocketPiArray[0] - 1;
643 if (TempSocketPiArray[0] == TempSwP0Array[0]) {
644 TempFlag1 = FALSE;
645 break;
646 }
647 }
648 } else {
649 TempFlag1 = FALSE;
650 }
651 if (TempFlag1) {
652 TempFreqArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].CoreFreq;
653 TempPowerArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].Power;
654 TempIddValueArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddValue;
655 TempIddDivArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddDiv;
656
657 //Try to find next candidate
658 for (i = 1; i < LogicalSocketCount; i++) {
659 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
660 if (TempSocketPiArray[i] != TempSwP0Array[i]) {
661 while (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].PStateEnable == 0) {
662 TempSocketPiArray[i]--;
663 if (TempSocketPiArray[i] == TempSwP0Array[i]) {
664 TempFlag1 = FALSE;
665 break;
666 }
667 }//end while
668 } else {
669 TempFlag1 = FALSE;
670 }
671
672 } //end for LogicalSocketCount
673 }
674
675 if (TempFlag1) {
676 for (i = 0; i < LogicalSocketCount; i++) {
677 //
678 //Compare
679 //
680 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
681 if (TempFreqArray[TotalIterations] > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq) {
682 TempFreqArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq;
683 }
684
685 if (TempPowerArray[TotalIterations] < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power) {
686 TempPowerArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power;
687 TempIddValueArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue;
688 TempIddDivArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv;
689 }
690 }
691 // Modify (Pi) CPU COF and Power for all the CPUs
692 for (i = 0; i < LogicalSocketCount; i++) {
693 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
694 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq = TempFreqArray[TotalIterations];
695 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power = TempPowerArray[TotalIterations];
696 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue = TempIddValueArray[TotalIterations];
697 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv = TempIddDivArray[TotalIterations];
698 TempSocketPiArray[i] = TempSocketPiArray[i] - 1;
699 }
700 } else {
701 for (i = 0; i < LogicalSocketCount; i++) {
702 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
703 for (m = TempSocketPiArray[i]; m > TempSwP0Array[i]; m--) {
704 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[m].PStateEnable = 0;
705 }
706 }
707 }
708
709 TotalIterations++;
710 } while (TempFlag1);
711
712 } // else
713
714 //--------------------------------------------------------------------------
715 // STEP - 7
716 //--------------------------------------------------------------------------
717 // Match the CPU COF and power for lower intermediate performance P - state(s)
718 // Lower Intermediate Pstates = Pstates between (not including)
719 // F3x64[HtcPstateLimit] and F3xDC[PstateMaxVal]
720 // 7_a) If F3xDC[PstateMaxVal] - F3x64[HtcPstateLimit] < 2 for any
721 // processor, set PstateEn = 0 for enabled lower intermediate P - states
722 // for all processors with (F3xDC[PstateMaxVal] -
723 // F3x64[HtcPstateLimit] > 1) and skip the remaining actions for this
724 // numbered step.
725 // 7_b) Define each of the available lower intermediate P-states; for each
726 // processor concurrently evaluate the following loop; when any
727 // processor falls out of the loop (runs out of available lower
728 // intermediate Pstates) all other processors have their remaining
729 // lower intermediate P-states invalidated (PstateEn = 0);
730 // for (i = F3xDC[PstateMaxVal]-1; i > F3x64[HtcPstateLimit]; i--)
731 // - Identify the lowest CPU COF for P-states between
732 // (not including) F3x64[HtcPstateLimit] and P(i).
733 // - Identify the highest power for P-states between
734 // (not including) F3x64[HtcPstateLimit] and P(i).
735 // - Modify P(i) CPU COF for all processors to the previously
736 // identified lowest CPU COF value.
737 // - Modify P(i) power for all processors to the previously
738 // identified highest power value.
739
740
741 // 7_a)
742 if (PstateMaxValMinusHtcPstateLimitLessThan2Flag) {
743 for (i = 0; i < LogicalSocketCount; i++) {
744 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
745
746 for (k = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1;
747 k > PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit;
748 k--) {
749 if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue -
750 PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) > 1) {
751 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0;
752 }
753 }
754 }
755 }
756
757 // 7_b)
758 else {
759 // Identify Lowest Frequency and Highest Power
760
761 TotalIterations = 0;
762 TempFlag1 = TRUE;
763
764 for (i = 0; i < LogicalSocketCount; i++) {
765 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
766 TempSocketPiArray[i] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1;
767 }
768
769 do {
770 //For first socket, try to find a candidate
771 if (TempSocketPiArray[0] != PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit) {
772 while (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].PStateEnable == 0) {
773 TempSocketPiArray[0] = TempSocketPiArray[0] - 1;
774 if (TempSocketPiArray[0] == PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit) {
775 TempFlag1 = FALSE;
776 break;
777 }
778 }
779 } else {
780 TempFlag1 = FALSE;
781 }
782 if (TempFlag1) {
783 TempFreqArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].CoreFreq;
784 TempPowerArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].Power;
785 TempIddValueArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddValue;
786 TempIddDivArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddDiv;
787
788 //Try to find next candidate
789 for (i = 1; i < LogicalSocketCount; i++) {
790 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
791 if (TempSocketPiArray[i] != PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) {
792 while (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].PStateEnable == 0) {
793 TempSocketPiArray[i]--;
794 if (TempSocketPiArray[i] == PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) {
795 TempFlag1 = FALSE;
796 break;
797 }
798 }//end while
799 } else {
800 TempFlag1 = FALSE;
801 }
802 } //end for LogicalSocketCount
803 }
804
805 if (TempFlag1) {
806 for (i = 0; i < LogicalSocketCount; i++) {
807 //
808 //Compare
809 //
810 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
811 if (TempFreqArray[TotalIterations] > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq) {
812 TempFreqArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq;
813 }
814 if (TempPowerArray[TotalIterations] < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power) {
815 TempPowerArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power;
816 TempIddValueArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue;
817 TempIddDivArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv;
818 }
819 }
820 // Modify (Pi) CPU COF and Power for all the CPUs
821 for (i = 0; i < LogicalSocketCount; i++) {
822 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
823 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq = TempFreqArray[TotalIterations];
824 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power = TempPowerArray[TotalIterations];
825 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue = TempIddValueArray[TotalIterations];
826 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv = TempIddDivArray[TotalIterations];
827 TempSocketPiArray[i] = TempSocketPiArray[i] - 1;
828 }
829 } else {
830 for (i = 0; i < LogicalSocketCount; i++) {
831 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
832 for (m = TempSocketPiArray[i]; m > PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit; m--) {
833 PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[m].PStateEnable = 0;
834 }
835 }
836 }
837 TotalIterations++;
838 } while (TempFlag1);
839 } // else
840 } // if(!AllCoreHaveMaxOnePStateFlag)
841
842 PStateBufferPtr[0].InitStruct = 1;
843 } // CurrentCore
844
845
846 // Update the pState MSRs
847 // This can be done only by individual core
848 StartPstateMsrModify (PStateStrucPtr, StdHeader);
849
850 //----------------------------------------------------------------------------------
851 // STEP - 8
852 //----------------------------------------------------------------------------------
853 // Place all cores into a valid COF and VID configuration corresponding to an
854 // enabled P-state:
855 // 8_a) Select an enabled P-state != to the P-state pointed to by
856 // MSRC001_0063[CurPstate] for each core.
857 // 8_b) Transition all cores to the selected P-states by writing the Control value
858 // from the_PSS object corresponding to the selected P-state to
859 // MSRC001_0062[PstateCmd].
860 // 8_c) Wait for all cores to report the Status value from the _PSS object
861 // corresponding to the selected P-state in MSRC001_0063[CurPstate].
862 //
863 PutAllCoreInPState0 (PStateBufferPtr, StdHeader);
864
865 return AGESA_SUCCESS;
866}
867
868
869/*----------------------------------------------------------------------------
870 * LOCAL FUNCTIONS
871 *
872 *----------------------------------------------------------------------------
873 */
874
875/**
876 *---------------------------------------------------------------------------------------
877 *
878 * PutAllCoreInPState0
879 *
880 * Description:
881 * This function will put core pstate to p0.
882 *
883 * Parameters:
884 * @param[in,out] *PStateBufferPtr
885 * @param[in] *StdHeader
886 *
887 * @retval AGESA_STATUS
888 *
889 *---------------------------------------------------------------------------------------
890 **/
891AGESA_STATUS
892PutAllCoreInPState0 (
893 IN OUT PSTATE_LEVELING *PStateBufferPtr,
894 IN AMD_CONFIG_PARAMS *StdHeader
895 )
896{
897 AP_TASK TaskPtr;
898 UINT32 BscSocket;
899 UINT32 Ignored;
900 UINT32 BscCoreNum;
901 UINT32 Core;
902 UINT32 Socket;
903 UINT32 NumberOfSockets;
904 UINT32 NumberOfCores;
905 AGESA_STATUS IgnoredSts;
906
907 TaskPtr.FuncAddress.PfApTaskI = PutCoreInPState0;
908 TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (PSTATE_LEVELING);
909 TaskPtr.ExeFlags = WAIT_FOR_CORE;
910 TaskPtr.DataTransfer.DataPtr = PStateBufferPtr;
911 TaskPtr.DataTransfer.DataTransferFlags = DATA_IN_MEMORY;
912
913 IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts);
914 NumberOfSockets = GetPlatformNumberOfSockets ();
915
916 PutCoreInPState0 (PStateBufferPtr, StdHeader);
917
918 for (Socket = 0; Socket < NumberOfSockets; Socket++) {
919 if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
920 for (Core = 0; Core < NumberOfCores; Core++) {
921 if ((Socket != (UINT32) BscSocket) || (Core != (UINT32) BscCoreNum)) {
922 ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader);
923 }
924 }
925 }
926 }
927
928 return AGESA_SUCCESS;
929}
930
931/**
932 *---------------------------------------------------------------------------------------
933 *
934 * CorePstateRegModify
935 *
936 * Description:
937 * This function will setting the Pstate MSR to each APs base on Pstate Buffer.
938 * Note: This function should be called for every core in the system.
939 *
940 * Parameters:
941 * @param[in,out] *CpuAmdPState
942 * @param[in] *StdHeader
943 *
944 * @retval VOID
945 *
946 *---------------------------------------------------------------------------------------
947 **/
948VOID
949CorePstateRegModify (
950 IN VOID *CpuAmdPState,
951 IN AMD_CONFIG_PARAMS *StdHeader
952 )
953{
954 PSTATE_CPU_FAMILY_SERVICES *FamilySpecificServices;
955 FamilySpecificServices = NULL;
956
957 GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilySpecificServices, StdHeader);
958 ASSERT (FamilySpecificServices != NULL)
959 FamilySpecificServices->SetPStateLevelReg (FamilySpecificServices, (S_CPU_AMD_PSTATE *) CpuAmdPState, StdHeader);
960}
961
962
963/*---------------------------------------------------------------------------------------*/
964/**
965 * This function will set msr on all cores of all nodes.
966 *
967 * @param[in] CpuAmdPState Pointer to S_CPU_AMD_PSTATE.
968 * @param[in] StdHeader Header for library and services.
969 *
970 * @retval AGESA_SUCCESS Always succeeds
971 *
972 */
973AGESA_STATUS
974StartPstateMsrModify (
975 IN S_CPU_AMD_PSTATE *CpuAmdPState,
976 IN AMD_CONFIG_PARAMS *StdHeader
977 )
978{
979 AP_TASK TaskPtr;
980 UINT32 BscSocket;
981 UINT32 Ignored;
982 UINT32 BscCoreNum;
983 UINT32 Core;
984 UINT32 Socket;
985 UINT32 NumberOfSockets;
986 UINT32 NumberOfCores;
987 AGESA_STATUS IgnoredSts;
988
989 TaskPtr.FuncAddress.PfApTaskI = CorePstateRegModify;
990 TaskPtr.DataTransfer.DataSizeInDwords = (UINT16) (CpuAmdPState->SizeOfBytes / 4 + 1);
991 TaskPtr.ExeFlags = WAIT_FOR_CORE;
992 TaskPtr.DataTransfer.DataPtr = CpuAmdPState;
993 TaskPtr.DataTransfer.DataTransferFlags = DATA_IN_MEMORY;
994
995 IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts);
996 NumberOfSockets = GetPlatformNumberOfSockets ();
997
998 CorePstateRegModify (CpuAmdPState, StdHeader);
999
1000 for (Socket = 0; Socket < NumberOfSockets; Socket++) {
1001 if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
1002 for (Core = 0; Core < NumberOfCores; Core++) {
1003 if ((Socket != (UINT32) BscSocket) || (Core != (UINT32) BscCoreNum)) {
1004 ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader);
1005 }
1006 }
1007 }
1008 }
1009
1010 return AGESA_SUCCESS;
1011}
1012
1013
1014/**
1015 *---------------------------------------------------------------------------------------
1016 *
1017 * CpuGetPStateLevelStructure
1018 *
1019 * Description:
1020 * Based on the LogicalSocketNumber, this function will return a pointer
1021 * point to the accurate offset of the PSTATE_LEVELING structure.
1022 *
1023 * Parameters:
1024 * @param[in,out] *PStateBufferPtr
1025 * @param[in] *CpuAmdPState
1026 * @param[in] LogicalSocketNumber
1027 * @param[in] *StdHeader
1028 *
1029 * @retval VOID
1030 *
1031 *---------------------------------------------------------------------------------------
1032 **/
1033AGESA_STATUS
1034CpuGetPStateLevelStructure (
1035 OUT PSTATE_LEVELING **PStateBufferPtr,
1036 IN S_CPU_AMD_PSTATE *CpuAmdPState,
1037 IN UINT32 LogicalSocketNumber,
1038 IN AMD_CONFIG_PARAMS *StdHeader
1039 )
1040{
1041 PSTATE_LEVELING *PStateBufferPtrTmp;
1042 UINT32 i;
1043
1044 if (LogicalSocketNumber > CpuAmdPState->TotalSocketInSystem) {
1045 return AGESA_UNSUPPORTED;
1046 }
1047
1048 PStateBufferPtrTmp = CpuAmdPState->PStateLevelingStruc;
1049
1050 for (i = 1; i <= LogicalSocketNumber; i++) {
1051 PStateBufferPtrTmp = (PSTATE_LEVELING *) ((UINT8 *) PStateBufferPtrTmp + ((UINTN) PStateBufferPtrTmp->PStateLevelingSizeOfBytes));
1052 }
1053
1054 *PStateBufferPtr = PStateBufferPtrTmp;
1055
1056 return AGESA_SUCCESS;
1057}
1058
1059
1060/**
1061 *---------------------------------------------------------------------------------------
1062 *
1063 * PutCoreInPState0
1064 *
1065 * Description:
1066 * This function will take the CPU core into P0
1067 *
1068 * Parameters:
1069 * @param[in] *PStateBuffer
1070 * @param[in] *StdHeader
1071 *
1072 * @retval VOID
1073 *
1074 *---------------------------------------------------------------------------------------
1075 **/
1076VOID
1077STATIC
1078PutCoreInPState0 (
1079 IN VOID *PStateBuffer,
1080 IN AMD_CONFIG_PARAMS *StdHeader
1081 )
1082{
1083 CPU_SPECIFIC_SERVICES *FamilySpecificServices;
1084 PSTATE_LEVELING *PStateBufferPtr;
1085
1086 PStateBufferPtr = (PSTATE_LEVELING *) PStateBuffer;
1087
1088 if ((PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_1 ) ||
1089 (PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_2)) {
1090 return;
1091 }
1092
1093 GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
1094
1095 FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) FALSE, StdHeader);
1096}