blob: a9ad343ec3a94c73e7eb7d4eacbc15e0fc6092e3 [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * AMD Family_15 Trinity IO C-state feature support functions.
6 *
7 * Provides the functions necessary to initialize the IO C-state feature.
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: CPU/Family/0x15/TN
12 * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
13 *
14 */
15/*
16 ******************************************************************************
17 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080018 * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc.
19 * All rights reserved.
zbao7d94cf92012-07-02 14:19:14 +080020 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080021 * 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.
zbao7d94cf92012-07-02 14:19:14 +080031 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080032 * 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.
zbao7d94cf92012-07-02 14:19:14 +080042 ******************************************************************************
43 */
44/*----------------------------------------------------------------------------------------
45 * M O D U L E S U S E D
46 *----------------------------------------------------------------------------------------
47 */
48
49#include "AGESA.h"
50#include "amdlib.h"
51#include "Ids.h"
52#include "cpuFeatures.h"
53#include "cpuIoCstate.h"
54#include "cpuF15PowerMgmt.h"
55#include "cpuF15TnPowerMgmt.h"
56#include "cpuLateInit.h"
57#include "cpuRegisters.h"
58#include "cpuServices.h"
59#include "cpuApicUtilities.h"
60#include "cpuFamilyTranslation.h"
61#include "CommonReturns.h"
62#include "Filecode.h"
63CODE_GROUP (G3_DXE)
64RDATA_GROUP (G3_DXE)
65#define FILECODE PROC_CPU_FAMILY_0X15_TN_F15TNIOCSTATE_FILECODE
66
67/*----------------------------------------------------------------------------------------
68 * 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
69 *----------------------------------------------------------------------------------------
70 */
71VOID
72STATIC
73F15TnInitializeIoCstateOnCore (
74 IN VOID *CstateBaseMsr,
75 IN AMD_CONFIG_PARAMS *StdHeader
76 );
77
78BOOLEAN
79F15TnIsCsdObjGenerated (
80 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
81 IN AMD_CONFIG_PARAMS *StdHeader
82 );
83
84/*----------------------------------------------------------------------------------------
85 * D E F I N I T I O N S A N D M A C R O S
86 *----------------------------------------------------------------------------------------
87 */
88extern CPU_FAMILY_SUPPORT_TABLE IoCstateFamilyServiceTable;
89
90/*----------------------------------------------------------------------------------------
91 * E X P O R T E D F U N C T I O N S
92 *----------------------------------------------------------------------------------------
93 */
94
95/*---------------------------------------------------------------------------------------*/
96/**
97 * Enable IO Cstate on a family 15h Trinity CPU.
98 * Implement BIOS Requirements for Initialization of C-states
99 *
100 * @param[in] IoCstateServices Pointer to this CPU's IO Cstate family services.
101 * @param[in] EntryPoint Timepoint designator.
102 * @param[in] PlatformConfig Contains the runtime modifiable feature input data.
103 * @param[in] StdHeader Config Handle for library, services.
104 *
105 * @return AGESA_SUCCESS Always succeeds.
106 *
107 */
108AGESA_STATUS
109STATIC
110F15TnInitializeIoCstate (
111 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
112 IN UINT64 EntryPoint,
113 IN PLATFORM_CONFIGURATION *PlatformConfig,
114 IN AMD_CONFIG_PARAMS *StdHeader
115 )
116{
117 UINT64 LocalMsrRegister;
118 AP_TASK TaskPtr;
119 PCI_ADDR PciAddress;
120 CSTATE_POLICY_CTRL1_REGISTER CstatePolicyCtrl1;
121
122 if ((EntryPoint & CPU_FEAT_AFTER_PM_INIT) != 0) {
123 // Initialize F4x128
124 // bit[1] CoreCstatePolicy = 0
125 // bit[4:2] HaltCstateIndex = 0
126 // bit[31] CstateMsgDis = 1
127 PciAddress.AddressValue = CSTATE_POLICY_CTRL1_PCI_ADDR;
128 LibAmdPciRead (AccessWidth32, PciAddress, &CstatePolicyCtrl1, StdHeader);
129 CstatePolicyCtrl1.CoreCstatePolicy = 0;
130 CstatePolicyCtrl1.HaltCstateIndex = 0;
131 CstatePolicyCtrl1.CstateMsgDis = 1;
132 LibAmdPciWrite (AccessWidth32, PciAddress, &CstatePolicyCtrl1, StdHeader);
133
134 // Initialize MSRC001_0073[CstateAddr] on each core to a region of
135 // the IO address map with 8 consecutive available addresses.
136 LocalMsrRegister = 0;
137
138 IDS_HDT_CONSOLE (CPU_TRACE, " Init IO C-state Base at 0x%x\n", PlatformConfig->CStateIoBaseAddress);
139 ((CSTATE_ADDRESS_MSR *) &LocalMsrRegister)->CstateAddr = PlatformConfig->CStateIoBaseAddress;
140
141 TaskPtr.FuncAddress.PfApTaskI = F15TnInitializeIoCstateOnCore;
142 TaskPtr.DataTransfer.DataSizeInDwords = 2;
143 TaskPtr.DataTransfer.DataPtr = &LocalMsrRegister;
144 TaskPtr.DataTransfer.DataTransferFlags = 0;
145 TaskPtr.ExeFlags = WAIT_FOR_CORE;
146 ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL);
147 }
148 return AGESA_SUCCESS;
149}
150
151/*---------------------------------------------------------------------------------------*/
152/**
153 * Enable CState on a family 15h Trinity core.
154 *
155 * @param[in] CstateBaseMsr MSR value to write to C001_0073 as determined by core 0.
156 * @param[in] StdHeader Config Handle for library, services.
157 *
158 */
159VOID
160STATIC
161F15TnInitializeIoCstateOnCore (
162 IN VOID *CstateBaseMsr,
163 IN AMD_CONFIG_PARAMS *StdHeader
164 )
165{
166 // Initialize MSRC001_0073[CstateAddr] on each core
167 LibAmdMsrWrite (MSR_CSTATE_ADDRESS, (UINT64 *) CstateBaseMsr, StdHeader);
168}
169
170/*---------------------------------------------------------------------------------------*/
171/**
172 * Returns the size of CST object
173 *
174 * @param[in] IoCstateServices IO Cstate services.
175 * @param[in] PlatformConfig Contains the runtime modifiable feature input data
176 * @param[in] StdHeader Config Handle for library, services.
177 *
178 * @retval CstObjSize Size of CST Object
179 *
180 */
181UINT32
182STATIC
183F15TnGetAcpiCstObj (
184 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
185 IN PLATFORM_CONFIGURATION *PlatformConfig,
186 IN AMD_CONFIG_PARAMS *StdHeader
187 )
188{
189 BOOLEAN GenerateCsdObj;
190 UINT32 CStateAcpiObjSize;
191 IO_CSTATE_FAMILY_SERVICES *FamilyServices;
192 ACPI_CST_GET_INPUT CstGetInput;
193
194 CstGetInput.IoCstateServices = IoCstateServices;
195 CstGetInput.PlatformConfig = PlatformConfig;
196 CstGetInput.CStateAcpiObjSizePtr = &CStateAcpiObjSize;
197
198 IDS_SKIP_HOOK (IDS_CST_SIZE, &CstGetInput, StdHeader) {
199 CStateAcpiObjSize = CST_HEADER_SIZE + CST_BODY_SIZE;
200
201 // If CSD Object is generated, add the size of CSD Object to the total size of
202 // CState ACPI Object size
203 GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
204 ASSERT (FamilyServices != NULL);
205 GenerateCsdObj = FamilyServices->IsCsdObjGenerated (FamilyServices, StdHeader);
206
207 if (GenerateCsdObj) {
208 CStateAcpiObjSize += CSD_HEADER_SIZE + CSD_BODY_SIZE;
209 }
210 }
211 return CStateAcpiObjSize;
212}
213
214/*---------------------------------------------------------------------------------------*/
215/**
216 * Routine to generate the C-State ACPI objects
217 *
218 * @param[in] IoCstateServices IO Cstate services.
219 * @param[in] LocalApicId Local Apic Id for each core.
220 * @param[in, out] **PstateAcpiBufferPtr Pointer to the Acpi Buffer Pointer.
221 * @param[in] StdHeader Config Handle for library, services.
222 *
223 */
224VOID
225STATIC
226F15TnCreateAcpiCstObj (
227 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
228 IN UINT8 LocalApicId,
229 IN OUT VOID **PstateAcpiBufferPtr,
230 IN AMD_CONFIG_PARAMS *StdHeader
231 )
232{
233 UINT64 MsrData;
234 BOOLEAN GenerateCsdObj;
235 CST_HEADER_STRUCT *CstHeaderPtr;
236 CST_BODY_STRUCT *CstBodyPtr;
237 CSD_HEADER_STRUCT *CsdHeaderPtr;
238 CSD_BODY_STRUCT *CsdBodyPtr;
239 IO_CSTATE_FAMILY_SERVICES *FamilyServices;
240 ACPI_CST_CREATE_INPUT CstInput;
241
242 CstInput.IoCstateServices = IoCstateServices;
243 CstInput.LocalApicId = LocalApicId;
244 CstInput.PstateAcpiBufferPtr = PstateAcpiBufferPtr;
245
246 IDS_SKIP_HOOK (IDS_CST_CREATE, &CstInput, StdHeader) {
247 // Read from MSR C0010073 to obtain CstateAddr
248 LibAmdMsrRead (MSR_CSTATE_ADDRESS, &MsrData, StdHeader);
249
250 // Typecast the pointer
251 CstHeaderPtr = (CST_HEADER_STRUCT *) *PstateAcpiBufferPtr;
252
253 // Set CST Header
254 CstHeaderPtr->NameOpcode = NAME_OPCODE;
255 CstHeaderPtr->CstName_a__ = CST_NAME__;
256 CstHeaderPtr->CstName_a_C = CST_NAME_C;
257 CstHeaderPtr->CstName_a_S = CST_NAME_S;
258 CstHeaderPtr->CstName_a_T = CST_NAME_T;
259
260 // Typecast the pointer
261 CstHeaderPtr++;
262 CstBodyPtr = (CST_BODY_STRUCT *) CstHeaderPtr;
263
264 // Set CST Body
265 CstBodyPtr->PkgOpcode = PACKAGE_OPCODE;
266 CstBodyPtr->PkgLength = CST_LENGTH;
267 CstBodyPtr->PkgElements = CST_NUM_OF_ELEMENTS;
268 CstBodyPtr->BytePrefix = BYTE_PREFIX_OPCODE;
269 CstBodyPtr->Count = CST_COUNT;
270 CstBodyPtr->PkgOpcode2 = PACKAGE_OPCODE;
271 CstBodyPtr->PkgLength2 = CST_PKG_LENGTH;
272 CstBodyPtr->PkgElements2 = CST_PKG_ELEMENTS;
273 CstBodyPtr->BufferOpcode = BUFFER_OPCODE;
274 CstBodyPtr->BufferLength = CST_SUBPKG_LENGTH;
275 CstBodyPtr->BufferElements = CST_SUBPKG_ELEMENTS;
276 CstBodyPtr->BufferOpcode2 = BUFFER_OPCODE;
277 CstBodyPtr->GdrOpcode = GENERIC_REG_DESCRIPTION;
278 CstBodyPtr->GdrLength = CST_GDR_LENGTH;
279 CstBodyPtr->AddrSpaceId = GDR_ASI_SYSTEM_IO;
280 CstBodyPtr->RegBitWidth = 0x08;
281 CstBodyPtr->RegBitOffset = 0x00;
282 CstBodyPtr->AddressSize = GDR_ASZ_BYTE_ACCESS;
283 CstBodyPtr->RegisterAddr = ((CSTATE_ADDRESS_MSR *) &MsrData)->CstateAddr + 1;
284 CstBodyPtr->EndTag = 0x0079;
285 CstBodyPtr->BytePrefix2 = BYTE_PREFIX_OPCODE;
286 CstBodyPtr->Type = CST_C2_TYPE;
287 CstBodyPtr->WordPrefix = WORD_PREFIX_OPCODE;
288 CstBodyPtr->Latency = 100;
289 CstBodyPtr->DWordPrefix = DWORD_PREFIX_OPCODE;
290 CstBodyPtr->Power = 0;
291
292 CstBodyPtr++;
293 //Update the pointer
294 *PstateAcpiBufferPtr = CstBodyPtr;
295
296
297 // Check whether CSD object should be generated
298 GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
299 ASSERT (FamilyServices != NULL);
300 GenerateCsdObj = FamilyServices->IsCsdObjGenerated (FamilyServices, StdHeader);
301
302 if (GenerateCsdObj) {
303 CsdHeaderPtr = (CSD_HEADER_STRUCT *) *PstateAcpiBufferPtr;
304
305 // Set CSD Header
306 CsdHeaderPtr->NameOpcode = NAME_OPCODE;
307 CsdHeaderPtr->CsdName_a__ = CST_NAME__;
308 CsdHeaderPtr->CsdName_a_C = CST_NAME_C;
309 CsdHeaderPtr->CsdName_a_S = CST_NAME_S;
310 CsdHeaderPtr->CsdName_a_D = CSD_NAME_D;
311
312 CsdHeaderPtr++;
313 CsdBodyPtr = (CSD_BODY_STRUCT *) CsdHeaderPtr;
314
315 // Set CSD Body
316 CsdBodyPtr->PkgOpcode = PACKAGE_OPCODE;
317 CsdBodyPtr->PkgLength = CSD_BODY_SIZE - 1;
318 CsdBodyPtr->PkgElements = 1;
319 CsdBodyPtr->PkgOpcode2 = PACKAGE_OPCODE;
320 CsdBodyPtr->PkgLength2 = CSD_BODY_SIZE - 4; // CSD_BODY_SIZE - Package() - Package Opcode
321 CsdBodyPtr->PkgElements2 = 6;
322 CsdBodyPtr->BytePrefix = BYTE_PREFIX_OPCODE;
323 CsdBodyPtr->NumEntries = 6;
324 CsdBodyPtr->BytePrefix2 = BYTE_PREFIX_OPCODE;
325 CsdBodyPtr->Revision = 0;
326 CsdBodyPtr->DWordPrefix = DWORD_PREFIX_OPCODE;
327 CsdBodyPtr->Domain = (LocalApicId & 0xFE) >> 1;
328 CsdBodyPtr->DWordPrefix2 = DWORD_PREFIX_OPCODE;
329 CsdBodyPtr->CoordType = CSD_COORD_TYPE_HW_ALL;
330 CsdBodyPtr->DWordPrefix3 = DWORD_PREFIX_OPCODE;
331 CsdBodyPtr->NumProcessors = 0x2;
332 CsdBodyPtr->DWordPrefix4 = DWORD_PREFIX_OPCODE;
333 CsdBodyPtr->Index = 0x0;
334
335 CsdBodyPtr++;
336
337 // Update the pointer
338 *PstateAcpiBufferPtr = CsdBodyPtr;
339 }
340 }
341}
342
343/*---------------------------------------------------------------------------------------*/
344/**
345 * Routine to check whether CSD object should be created.
346 *
347 * @param[in] IoCstateServices IO Cstate services.
348 * @param[in] StdHeader Config Handle for library, services.
349 *
350 * @retval TRUE CSD Object should be created.
351 * @retval FALSE CSD Object should not be created.
352 *
353 */
354BOOLEAN
355F15TnIsCsdObjGenerated (
356 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
357 IN AMD_CONFIG_PARAMS *StdHeader
358 )
359{
360 // CSD Object should only be created when there are two cores per compute unit
361 if (GetComputeUnitMapping (StdHeader) == EvenCoresMapping) {
362 return TRUE;
363 }
364 return FALSE;
365}
366
367CONST IO_CSTATE_FAMILY_SERVICES ROMDATA F15TnIoCstateSupport =
368{
369 0,
370 (PF_IO_CSTATE_IS_SUPPORTED) CommonReturnTrue,
371 F15TnInitializeIoCstate,
372 F15TnGetAcpiCstObj,
373 F15TnCreateAcpiCstObj,
374 F15TnIsCsdObjGenerated
375};