5 * AMD DMI Record Creation API, and related functions for Fmaily15h Orichi.
7 * Contains code that produce the DMI related information.
9 * @xrefitem bom "File Content Label" "Release Content"
11 * @e sub-project: CPU/Family/0x15/OR
12 * @e \$Revision: 58290 $ @e \$Date: 2011-08-25 00:02:47 -0600 (Thu, 25 Aug 2011) $
15 /*****************************************************************************
17 * Copyright (C) 2012 Advanced Micro Devices, Inc.
18 * All rights reserved.
20 * 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.
31 * 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.
42 ******************************************************************************
45 /*----------------------------------------------------------------------------------------
46 * M O D U L E S U S E D
47 *----------------------------------------------------------------------------------------
51 #include "cpuRegisters.h"
52 #include "cpuFamilyTranslation.h"
53 #include "cpuPstateTables.h"
54 #include "cpuLateInit.h"
55 #include "cpuF15Dmi.h"
56 #include "cpuF15PowerMgmt.h"
57 #include "cpuF15OrPowerMgmt.h"
58 #include "cpuServices.h"
63 #define FILECODE PROC_CPU_FAMILY_0X15_OR_CPUF15ORDMI_FILECODE
66 /*----------------------------------------------------------------------------------------
67 * D E F I N I T I O N S A N D M A C R O S
68 *----------------------------------------------------------------------------------------
70 extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable;
72 /*----------------------------------------------------------------------------------------
73 * T Y P E D E F S A N D S T R U C T U R E S
74 *----------------------------------------------------------------------------------------
76 CONST CHAR8 ROMDATA str_Opteron_62[] = "AMD Opteron(tm) Processor 62";
77 CONST CHAR8 ROMDATA str_Opteron_42[] = "AMD Opteron(tm) Processor 42";
78 CONST CHAR8 ROMDATA str_Opteron_3[] = "AMD Opteron(tm) Processor 3";
79 CONST CHAR8 ROMDATA str_FX_AM3[] = "AMD FX(tm)-";
80 /*---------------------------------------------------------------------------------------
81 * Processor Family Table
82 * 03Dh = "AMD Opteron(TM) 6200 Processor Family"
83 * 03Eh = "AMD Opteron(TM) 4200 Processor Family"
84 * 03Fh = "AMD FX(TM) Series Processor"
85 *-------------------------------------------------------------------------------------*/
86 CONST CPU_T4_PROC_FAMILY ROMDATA F15OrG34T4ProcFamily[] =
88 {str_Opteron_62, 0x3D}
91 CONST CPU_T4_PROC_FAMILY ROMDATA F15OrC32T4ProcFamily[] =
93 {str_Opteron_42, 0x3E}
96 CONST CPU_T4_PROC_FAMILY ROMDATA F15OrAM3T4ProcFamily[] =
101 /*----------------------------------------------------------------------------------------
102 * 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
103 *----------------------------------------------------------------------------------------
107 IN OUT CPU_TYPE_INFO *CpuInfoPtr,
108 IN AMD_CONFIG_PARAMS *StdHeader
112 DmiF15OrGetT4ProcFamily (
113 IN OUT UINT8 *T4ProcFamily,
114 IN PROC_FAMILY_TABLE *CpuDmiProcFamilyTable,
115 IN CPU_TYPE_INFO *CpuInfo,
116 IN AMD_CONFIG_PARAMS *StdHeader
121 IN AMD_CONFIG_PARAMS *StdHeader
126 IN OUT CPU_GET_MEM_INFO *CpuGetMemInfoPtr,
127 IN AMD_CONFIG_PARAMS *StdHeader
131 DmiF15OrGetExtClock (
132 IN AMD_CONFIG_PARAMS *StdHeader
135 /*----------------------------------------------------------------------------------------
136 * E X P O R T E D F U N C T I O N S
137 *----------------------------------------------------------------------------------------
140 /* -----------------------------------------------------------------------------*/
145 * Get CPU type information
147 * @param[in,out] CpuInfoPtr Pointer to CPU_TYPE_INFO struct.
148 * @param[in] StdHeader Standard Head Pointer
153 IN OUT CPU_TYPE_INFO *CpuInfoPtr,
154 IN AMD_CONFIG_PARAMS *StdHeader
157 UINT8 NumOfCoresPerCU;
159 CPU_SPECIFIC_SERVICES *FamilySpecificServices;
161 LibAmdCpuidRead (AMD_CPUID_FMF, &CpuId, StdHeader);
162 CpuInfoPtr->ExtendedFamily = (UINT8) (CpuId.EAX_Reg >> 20) & 0xFF; // bit 27:20
163 CpuInfoPtr->ExtendedModel = (UINT8) (CpuId.EAX_Reg >> 16) & 0xF; // bit 19:16
164 CpuInfoPtr->BaseFamily = (UINT8) (CpuId.EAX_Reg >> 8) & 0xF; // bit 11:8
165 CpuInfoPtr->BaseModel = (UINT8) (CpuId.EAX_Reg >> 4) & 0xF; // bit 7:4
166 CpuInfoPtr->Stepping = (UINT8) (CpuId.EAX_Reg & 0xF); // bit 3:0
168 CpuInfoPtr->PackageType = (UINT8) (CpuId.EBX_Reg >> 28) & 0xF; // bit 31:28
169 // Family 15h Orochi doesn't have CPUID_8000_0001_EBX[BrandId]
170 CpuInfoPtr->BrandId.Pg = 0;
171 CpuInfoPtr->BrandId.String1 = 0;
172 CpuInfoPtr->BrandId.Model = 0;
173 CpuInfoPtr->BrandId.String2 = 0;
175 GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
176 CpuInfoPtr->TotalCoreNumber = FamilySpecificServices->GetNumberOfPhysicalCores (FamilySpecificServices, StdHeader);
177 CpuInfoPtr->TotalCoreNumber--;
179 LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuId, StdHeader);
180 CpuInfoPtr->EnabledCoreNumber = (UINT8) (CpuId.ECX_Reg & 0xFF); // bit 7:0
182 switch (CpuInfoPtr->PackageType) {
184 CpuInfoPtr->ProcUpgrade = P_UPGRADE_AM3;
187 CpuInfoPtr->ProcUpgrade = P_UPGRADE_G34;
190 CpuInfoPtr->ProcUpgrade = P_UPGRADE_C32;
193 CpuInfoPtr->ProcUpgrade = P_UPGRADE_UNKNOWN;
197 switch (GetComputeUnitMapping (StdHeader)) {
198 case AllCoresMapping:
201 case EvenCoresMapping:
207 LibAmdCpuidRead (AMD_CPUID_TLB_L1Cache, &CpuId, StdHeader);
208 CpuInfoPtr->L1CacheSize = (UINT32) (((UINT8) ((CpuId.ECX_Reg >> 24) * NumOfCoresPerCU) + (UINT8) (CpuId.EDX_Reg >> 24)) * (CpuInfoPtr->EnabledCoreNumber + 1) / NumOfCoresPerCU);
210 LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuId, StdHeader);
211 CpuInfoPtr->L2CacheSize = (UINT32) ((UINT16) (CpuId.ECX_Reg >> 16) * (CpuInfoPtr->EnabledCoreNumber + 1) / NumOfCoresPerCU);
214 /* -----------------------------------------------------------------------------*/
217 * DmiF15OrGetT4ProcFamily
219 * Get type 4 processor family information
221 * @param[in,out] T4ProcFamily Pointer to type 4 processor family information.
222 * @param[in] *CpuDmiProcFamilyTable Pointer to DMI family special service
223 * @param[in] *CpuInfo Pointer to CPU_TYPE_INFO struct
224 * @param[in] StdHeader Standard Head Pointer
228 DmiF15OrGetT4ProcFamily (
229 IN OUT UINT8 *T4ProcFamily,
230 IN PROC_FAMILY_TABLE *CpuDmiProcFamilyTable,
231 IN CPU_TYPE_INFO *CpuInfo,
232 IN AMD_CONFIG_PARAMS *StdHeader
235 CHAR8 NameString[49];
236 CONST CHAR8 *DmiString;
237 CONST VOID *DmiStringTable;
238 UINT8 NumberOfDmiString;
241 // Get name string from MSR_C001_00[30:35]
242 GetNameString (NameString, StdHeader);
244 DmiStringTable = NULL;
245 switch (CpuInfo->PackageType) {
247 DmiStringTable = (CONST VOID *) &F15OrG34T4ProcFamily[0];
248 NumberOfDmiString = sizeof (F15OrG34T4ProcFamily) / sizeof (CPU_T4_PROC_FAMILY);
251 DmiStringTable = (CONST VOID *) &F15OrC32T4ProcFamily[0];
252 NumberOfDmiString = sizeof (F15OrC32T4ProcFamily) / sizeof (CPU_T4_PROC_FAMILY);
255 DmiStringTable = (CONST VOID *) &F15OrAM3T4ProcFamily[0];
256 NumberOfDmiString = sizeof (F15OrAM3T4ProcFamily) / sizeof (CPU_T4_PROC_FAMILY);
259 DmiStringTable = NULL;
260 NumberOfDmiString = 0;
264 // Find out which DMI string matches currect processor's name string
265 *T4ProcFamily = P_FAMILY_UNKNOWN;
266 if ((DmiStringTable != NULL) && (NumberOfDmiString != 0)) {
267 for (i = 0; i < NumberOfDmiString; i++) {
268 DmiString = (((CPU_T4_PROC_FAMILY *) DmiStringTable)[i]).Stringstart;
269 if (IsSourceStrContainTargetStr (NameString, DmiString, StdHeader)) {
270 *T4ProcFamily = (((CPU_T4_PROC_FAMILY *) DmiStringTable)[i]).T4ProcFamilySetting;
276 /* -----------------------------------------------------------------------------*/
281 * Get the voltage value according to SMBIOS SPEC's requirement.
283 * @param[in] StdHeader Standard Head Pointer
285 * @retval Voltage - CPU Voltage.
290 IN AMD_CONFIG_PARAMS *StdHeader
295 UINT8 NumberBoostStates;
296 UINT32 CurrentNodeNum;
299 CPB_CTRL_REGISTER CpbCtrl;
301 // Voltage = 0x80 + (voltage at boot time * 10)
302 GetCurrentNodeNum (&CurrentNodeNum, StdHeader);
303 TempAddr.AddressValue = MAKE_SBDFO (0, 0, (24 + CurrentNodeNum), FUNC_4, CPB_CTRL_REG);
304 LibAmdPciRead (AccessWidth32, TempAddr, &CpbCtrl, StdHeader); // F4x15C
305 NumberBoostStates = (UINT8) CpbCtrl.NumBoostStates;
307 LibAmdMsrRead ((MSR_PSTATE_0 + NumberBoostStates), &MsrData, StdHeader);
308 MaxVid = (UINT8) (((PSTATE_MSR *)&MsrData)->CpuVid);
311 if ((MaxVid >= 0x7C) && (MaxVid <= 0x7F)) {
314 Voltage = (UINT8) ((15500 - (125 * MaxVid) + 500) / 1000);
321 /* -----------------------------------------------------------------------------*/
326 * Get memory information.
328 * @param[in,out] CpuGetMemInfoPtr Pointer to CPU_GET_MEM_INFO struct.
329 * @param[in] StdHeader Standard Head Pointer
334 IN OUT CPU_GET_MEM_INFO *CpuGetMemInfoPtr,
335 IN AMD_CONFIG_PARAMS *StdHeader
341 CpuGetMemInfoPtr->EccCapable = FALSE;
342 // Orochi uses the different way of access to each DCT
346 PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_1, 0x10C);
347 LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);
348 PciData &= 0xFFFFFFFE;
349 LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader);
351 PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_2, 0x90);
352 LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);
353 // Check if F2x90[DimmEccEn] is set
354 if ((PciData & 0x00080000) != 0) {
355 CpuGetMemInfoPtr->EccCapable = TRUE;
360 PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_1, 0x10C);
361 LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);
362 PciData |= 0x00000001;
363 LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader);
365 PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_2, 0x90);
366 LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);
367 // Check if F2x90[DimmEccEn] is set
368 if ((PciData & 0x00080000) != 0) {
369 CpuGetMemInfoPtr->EccCapable = TRUE;
373 PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_1, 0x10C);
374 LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);
375 PciData &= 0xFFFFFFFE;
376 LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader);
377 // Partition Row Position - 0 is for dual channel memory
378 CpuGetMemInfoPtr->PartitionRowPosition = 0;
381 /* -----------------------------------------------------------------------------*/
384 * DmiF15OrGetExtClock
386 * Get the external clock Speed
388 * @param[in] StdHeader Standard Head Pointer
390 * @retval ExtClock - CPU external clock Speed.
394 DmiF15OrGetExtClock (
395 IN AMD_CONFIG_PARAMS *StdHeader
398 return (EXTERNAL_CLOCK_DFLT);
401 CONST PROC_FAMILY_TABLE ROMDATA ProcFamily15OrDmiTable =
403 // This table is for Processor family 15h Orochi
404 AMD_FAMILY_15_OR, // ID for Family 15h Orochi
405 DmiF15OrGetInfo, // Transfer vectors for family
406 DmiF15OrGetT4ProcFamily, // Get type 4 processor family information
407 DmiF15OrGetVoltage, // specific routines (above)
410 DmiF15OrGetMemInfo, // Get memory information
416 /*---------------------------------------------------------------------------------------
417 * L O C A L F U N C T I O N S
418 *---------------------------------------------------------------------------------------