5 * AMD Family_15 Orochi IO C-state feature support functions.
7 * Provides the functions necessary to initialize the IO C-state feature.
9 * @xrefitem bom "File Content Label" "Release Content"
11 * @e sub-project: CPU/Family/0x15/OR
12 * @e \$Revision: 55600 $ @e \$Date: 2011-06-23 12:39:18 -0600 (Thu, 23 Jun 2011) $
16 ******************************************************************************
18 * Copyright (C) 2012 Advanced Micro Devices, Inc.
19 * All rights reserved.
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.
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.
43 ******************************************************************************
45 /*----------------------------------------------------------------------------------------
46 * M O D U L E S U S E D
47 *----------------------------------------------------------------------------------------
53 #include "cpuFeatures.h"
54 #include "cpuIoCstate.h"
55 #include "cpuF15PowerMgmt.h"
56 #include "cpuF15OrPowerMgmt.h"
57 #include "cpuLateInit.h"
58 #include "cpuRegisters.h"
59 #include "cpuServices.h"
60 #include "cpuApicUtilities.h"
61 #include "cpuFamilyTranslation.h"
62 #include "CommonReturns.h"
63 #include "OptionMultiSocket.h"
67 #define FILECODE PROC_CPU_FAMILY_0X15_OR_F15ORIOCSTATE_FILECODE
69 /*----------------------------------------------------------------------------------------
70 * 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
71 *----------------------------------------------------------------------------------------
75 F15OrInitializeIoCstateOnCore (
76 IN VOID *CstateBaseMsr,
77 IN AMD_CONFIG_PARAMS *StdHeader
81 F15OrIsCsdObjGenerated (
82 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
83 IN AMD_CONFIG_PARAMS *StdHeader
86 /*----------------------------------------------------------------------------------------
87 * D E F I N I T I O N S A N D M A C R O S
88 *----------------------------------------------------------------------------------------
90 extern CPU_FAMILY_SUPPORT_TABLE IoCstateFamilyServiceTable;
91 extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
93 /*----------------------------------------------------------------------------------------
94 * E X P O R T E D F U N C T I O N S
95 *----------------------------------------------------------------------------------------
98 /*---------------------------------------------------------------------------------------*/
100 * Enable IO Cstate on a family 15h Orochi CPU.
101 * Implement BIOS Requirements for Initialization of C-states
103 * @param[in] IoCstateServices Pointer to this CPU's IO Cstate family services.
104 * @param[in] EntryPoint Timepoint designator.
105 * @param[in] PlatformConfig Contains the runtime modifiable feature input data.
106 * @param[in] StdHeader Config Handle for library, services.
108 * @return AGESA_SUCCESS Always succeeds.
113 F15OrInitializeIoCstate (
114 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
115 IN UINT64 EntryPoint,
116 IN PLATFORM_CONFIGURATION *PlatformConfig,
117 IN AMD_CONFIG_PARAMS *StdHeader
120 UINT32 LocalPciRegister;
122 UINT64 LocalMsrRegister;
126 if ((EntryPoint & CPU_FEAT_AFTER_PM_INIT) != 0) {
127 // Initialize MSRC001_0073[CstateAddr] on each core to a region of
128 // the IO address map with 8 consecutive available addresses.
129 LocalMsrRegister = 0;
131 ((CSTATE_ADDRESS_MSR *) &LocalMsrRegister)->CstateAddr = PlatformConfig->CStateIoBaseAddress;
133 TaskPtr.FuncAddress.PfApTaskI = F15OrInitializeIoCstateOnCore;
134 TaskPtr.DataTransfer.DataSizeInDwords = 2;
135 TaskPtr.DataTransfer.DataPtr = &LocalMsrRegister;
136 TaskPtr.DataTransfer.DataTransferFlags = 0;
137 TaskPtr.ExeFlags = WAIT_FOR_CORE;
138 ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL);
141 // bits[0] CoreCstateMode = 0
142 // bits[1] CoreCstatePolicy = 0
143 // bits[4:2] HaltCstateIndex = 0
144 PciAddress.Address.Function = FUNC_4;
145 PciAddress.Address.Register = CSTATE_POLICY_CTRL1_REG;
146 LocalPciRegister = 0x00000000;
147 PciMask = 0xFFFFFFE0;
148 OptionMultiSocketConfiguration.ModifyCurrSocketPci (&PciAddress, PciMask, LocalPciRegister, StdHeader);
150 return AGESA_SUCCESS;
153 /*---------------------------------------------------------------------------------------*/
155 * Enable CState on a family 15h Orochi core.
157 * @param[in] CstateBaseMsr MSR value to write to C001_0073 as determined by core 0.
158 * @param[in] StdHeader Config Handle for library, services.
163 F15OrInitializeIoCstateOnCore (
164 IN VOID *CstateBaseMsr,
165 IN AMD_CONFIG_PARAMS *StdHeader
168 // Initialize MSRC001_0073[CstateAddr] on each core
169 LibAmdMsrWrite (MSR_CSTATE_ADDRESS, (UINT64 *) CstateBaseMsr, StdHeader);
172 /*---------------------------------------------------------------------------------------*/
174 * Returns the size of CST object
176 * @param[in] IoCstateServices IO Cstate services.
177 * @param[in] PlatformConfig Contains the runtime modifiable feature input data
178 * @param[in] StdHeader Config Handle for library, services.
180 * @retval CstObjSize Size of CST Object
186 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
187 IN PLATFORM_CONFIGURATION *PlatformConfig,
188 IN AMD_CONFIG_PARAMS *StdHeader
191 BOOLEAN GenerateCsdObj;
192 UINT32 CStateAcpiObjSize;
193 IO_CSTATE_FAMILY_SERVICES *FamilyServices;
194 ACPI_CST_GET_INPUT CstGetInput;
196 CstGetInput.IoCstateServices = IoCstateServices;
197 CstGetInput.PlatformConfig = PlatformConfig;
198 CstGetInput.CStateAcpiObjSizePtr = &CStateAcpiObjSize;
200 IDS_SKIP_HOOK (IDS_CST_SIZE, &CstGetInput, StdHeader) {
201 CStateAcpiObjSize = CST_HEADER_SIZE + CST_BODY_SIZE;
203 // If CSD Object is generated, add the size of CSD Object to the total size of
204 // CState ACPI Object size
205 GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
206 ASSERT (FamilyServices != NULL);
207 GenerateCsdObj = FamilyServices->IsCsdObjGenerated (FamilyServices, StdHeader);
209 if (GenerateCsdObj) {
210 CStateAcpiObjSize += CSD_HEADER_SIZE + CSD_BODY_SIZE;
213 return CStateAcpiObjSize;
216 /*---------------------------------------------------------------------------------------*/
218 * Routine to generate the C-State ACPI objects
220 * @param[in] IoCstateServices IO Cstate services.
221 * @param[in] LocalApicId Local Apic Id for each core.
222 * @param[in, out] **PstateAcpiBufferPtr Pointer to the Acpi Buffer Pointer.
223 * @param[in] StdHeader Config Handle for library, services.
228 F15OrCreateAcpiCstObj (
229 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
230 IN UINT8 LocalApicId,
231 IN OUT VOID **PstateAcpiBufferPtr,
232 IN AMD_CONFIG_PARAMS *StdHeader
236 BOOLEAN GenerateCsdObj;
237 CST_HEADER_STRUCT *CstHeaderPtr;
238 CST_BODY_STRUCT *CstBodyPtr;
239 CSD_HEADER_STRUCT *CsdHeaderPtr;
240 CSD_BODY_STRUCT *CsdBodyPtr;
241 IO_CSTATE_FAMILY_SERVICES *FamilyServices;
242 ACPI_CST_CREATE_INPUT CstInput;
244 CstInput.IoCstateServices = IoCstateServices;
245 CstInput.LocalApicId = LocalApicId;
246 CstInput.PstateAcpiBufferPtr = PstateAcpiBufferPtr;
248 IDS_SKIP_HOOK (IDS_CST_CREATE, &CstInput, StdHeader) {
249 // Read from MSR C0010073 to obtain CstateAddr
250 LibAmdMsrRead (MSR_CSTATE_ADDRESS, &MsrData, StdHeader);
252 // Typecast the pointer
253 CstHeaderPtr = (CST_HEADER_STRUCT *) *PstateAcpiBufferPtr;
256 CstHeaderPtr->NameOpcode = NAME_OPCODE;
257 CstHeaderPtr->CstName_a__ = CST_NAME__;
258 CstHeaderPtr->CstName_a_C = CST_NAME_C;
259 CstHeaderPtr->CstName_a_S = CST_NAME_S;
260 CstHeaderPtr->CstName_a_T = CST_NAME_T;
262 // Typecast the pointer
264 CstBodyPtr = (CST_BODY_STRUCT *) CstHeaderPtr;
267 CstBodyPtr->PkgOpcode = PACKAGE_OPCODE;
268 CstBodyPtr->PkgLength = CST_LENGTH;
269 CstBodyPtr->PkgElements = CST_NUM_OF_ELEMENTS;
270 CstBodyPtr->BytePrefix = BYTE_PREFIX_OPCODE;
271 CstBodyPtr->Count = CST_COUNT;
272 CstBodyPtr->PkgOpcode2 = PACKAGE_OPCODE;
273 CstBodyPtr->PkgLength2 = CST_PKG_LENGTH;
274 CstBodyPtr->PkgElements2 = CST_PKG_ELEMENTS;
275 CstBodyPtr->BufferOpcode = BUFFER_OPCODE;
276 CstBodyPtr->BufferLength = CST_SUBPKG_LENGTH;
277 CstBodyPtr->BufferElements = CST_SUBPKG_ELEMENTS;
278 CstBodyPtr->BufferOpcode2 = BUFFER_OPCODE;
279 CstBodyPtr->GdrOpcode = GENERIC_REG_DESCRIPTION;
280 CstBodyPtr->GdrLength = CST_GDR_LENGTH;
281 CstBodyPtr->AddrSpaceId = GDR_ASI_SYSTEM_IO;
282 CstBodyPtr->RegBitWidth = 0x08;
283 CstBodyPtr->RegBitOffset = 0x00;
284 CstBodyPtr->AddressSize = GDR_ASZ_BYTE_ACCESS;
285 CstBodyPtr->RegisterAddr = ((CSTATE_ADDRESS_MSR *) &MsrData)->CstateAddr + 1;
286 CstBodyPtr->EndTag = 0x0079;
287 CstBodyPtr->BytePrefix2 = BYTE_PREFIX_OPCODE;
288 CstBodyPtr->Type = CST_C2_TYPE;
289 CstBodyPtr->WordPrefix = WORD_PREFIX_OPCODE;
290 CstBodyPtr->Latency = 100;
291 CstBodyPtr->DWordPrefix = DWORD_PREFIX_OPCODE;
292 CstBodyPtr->Power = 0;
296 *PstateAcpiBufferPtr = CstBodyPtr;
299 // Check whether CSD object should be generated
300 GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
301 ASSERT (FamilyServices != NULL);
302 GenerateCsdObj = FamilyServices->IsCsdObjGenerated (FamilyServices, StdHeader);
304 if (GenerateCsdObj) {
305 CsdHeaderPtr = (CSD_HEADER_STRUCT *) *PstateAcpiBufferPtr;
308 CsdHeaderPtr->NameOpcode = NAME_OPCODE;
309 CsdHeaderPtr->CsdName_a__ = CST_NAME__;
310 CsdHeaderPtr->CsdName_a_C = CST_NAME_C;
311 CsdHeaderPtr->CsdName_a_S = CST_NAME_S;
312 CsdHeaderPtr->CsdName_a_D = CSD_NAME_D;
315 CsdBodyPtr = (CSD_BODY_STRUCT *) CsdHeaderPtr;
318 CsdBodyPtr->PkgOpcode = PACKAGE_OPCODE;
319 CsdBodyPtr->PkgLength = CSD_BODY_SIZE - 1;
320 CsdBodyPtr->PkgElements = 1;
321 CsdBodyPtr->PkgOpcode2 = PACKAGE_OPCODE;
322 CsdBodyPtr->PkgLength2 = CSD_BODY_SIZE - 4; // CSD_BODY_SIZE - Package() - Package Opcode
323 CsdBodyPtr->PkgElements2 = 6;
324 CsdBodyPtr->BytePrefix = BYTE_PREFIX_OPCODE;
325 CsdBodyPtr->NumEntries = 6;
326 CsdBodyPtr->BytePrefix2 = BYTE_PREFIX_OPCODE;
327 CsdBodyPtr->Revision = 0;
328 CsdBodyPtr->DWordPrefix = DWORD_PREFIX_OPCODE;
329 CsdBodyPtr->Domain = (LocalApicId & 0xFE) >> 1;
330 CsdBodyPtr->DWordPrefix2 = DWORD_PREFIX_OPCODE;
331 CsdBodyPtr->CoordType = CSD_COORD_TYPE_HW_ALL;
332 CsdBodyPtr->DWordPrefix3 = DWORD_PREFIX_OPCODE;
333 CsdBodyPtr->NumProcessors = 0x2;
334 CsdBodyPtr->DWordPrefix4 = DWORD_PREFIX_OPCODE;
335 CsdBodyPtr->Index = 0x0;
339 // Update the pointer
340 *PstateAcpiBufferPtr = CsdBodyPtr;
345 /*---------------------------------------------------------------------------------------*/
347 * Routine to check whether CSD object should be created.
349 * @param[in] IoCstateServices IO Cstate services.
350 * @param[in] StdHeader Config Handle for library, services.
352 * @retval TRUE CSD Object should be created.
353 * @retval FALSE CSD Object should not be created.
357 F15OrIsCsdObjGenerated (
358 IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
359 IN AMD_CONFIG_PARAMS *StdHeader
362 // CSD Object should only be created when there are two cores per compute unit
363 if (GetComputeUnitMapping (StdHeader) == EvenCoresMapping) {
369 CONST IO_CSTATE_FAMILY_SERVICES ROMDATA F15OrIoCstateSupport =
372 (PF_IO_CSTATE_IS_SUPPORTED) CommonReturnTrue,
373 F15OrInitializeIoCstate,
375 F15OrCreateAcpiCstObj,
376 F15OrIsCsdObjGenerated