5 * AMD DMI Record Creation API, and related functions.
7 * Contains code that produce the DMI related information.
9 * @xrefitem bom "File Content Label" "Release Content"
12 * @e \$Revision: 58105 $ @e \$Date: 2011-08-19 17:46:09 -0600 (Fri, 19 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 "cpuF10PowerMgmt.h"
56 #include "cpuServices.h"
57 #include "GeneralServices.h"
58 #include "cpuF10Utilities.h"
63 #define FILECODE PROC_CPU_FAMILY_0X10_CPUF10DMI_FILECODE
65 /*----------------------------------------------------------------------------------------
66 * D E F I N I T I O N S A N D M A C R O S
67 *----------------------------------------------------------------------------------------
69 extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable;
70 /*----------------------------------------------------------------------------------------
71 * T Y P E D E F S A N D S T R U C T U R E S
72 *----------------------------------------------------------------------------------------
75 /*----------------------------------------------------------------------------------------
76 * 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
77 *----------------------------------------------------------------------------------------
81 IN OUT CPU_TYPE_INFO *CpuInfoPtr,
82 IN AMD_CONFIG_PARAMS *StdHeader
87 IN AMD_CONFIG_PARAMS *StdHeader
92 IN AMD_CONFIG_PARAMS *StdHeader
97 IN AMD_CONFIG_PARAMS *StdHeader
102 IN OUT CPU_GET_MEM_INFO *CpuGetMemInfoPtr,
103 IN AMD_CONFIG_PARAMS *StdHeader
108 F10Translate7BitVidTo6Bit (
109 IN OUT UINT8 * MaxVidPtr
112 /*----------------------------------------------------------------------------------------
113 * E X P O R T E D F U N C T I O N S
114 *----------------------------------------------------------------------------------------
117 /* -----------------------------------------------------------------------------*/
122 * Get CPU type information
124 * @param[in,out] CpuInfoPtr Pointer to CPU_TYPE_INFO struct.
125 * @param[in] StdHeader Standard Head Pointer
130 IN OUT CPU_TYPE_INFO *CpuInfoPtr,
131 IN AMD_CONFIG_PARAMS *StdHeader
135 CPU_SPECIFIC_SERVICES *FamilySpecificServices;
137 LibAmdCpuidRead (AMD_CPUID_FMF, &CpuId, StdHeader);
138 CpuInfoPtr->ExtendedFamily = (UINT8) (CpuId.EAX_Reg >> 20) & 0xFF; // bit 27:20
139 CpuInfoPtr->ExtendedModel = (UINT8) (CpuId.EAX_Reg >> 16) & 0xF; // bit 19:16
140 CpuInfoPtr->BaseFamily = (UINT8) (CpuId.EAX_Reg >> 8) & 0xF; // bit 11:8
141 CpuInfoPtr->BaseModel = (UINT8) (CpuId.EAX_Reg >> 4) & 0xF; // bit 7:4
142 CpuInfoPtr->Stepping = (UINT8) (CpuId.EAX_Reg & 0xF); // bit 3:0
144 CpuInfoPtr->PackageType = (UINT8) (CpuId.EBX_Reg >> 28) & 0xF; // bit 31:28
145 CpuInfoPtr->BrandId.Pg = (UINT8) (CpuId.EBX_Reg >> 15) & 0x1; // bit 15
146 CpuInfoPtr->BrandId.String1 = (UINT8) (CpuId.EBX_Reg >> 11) & 0xF; // bit 14:11
147 CpuInfoPtr->BrandId.Model = (UINT8) (CpuId.EBX_Reg >> 4) & 0x7F; // bit 10:4
148 CpuInfoPtr->BrandId.String2 = (UINT8) (CpuId.EBX_Reg & 0xF); // bit 3:0
150 GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
151 CpuInfoPtr->TotalCoreNumber = FamilySpecificServices->GetNumberOfPhysicalCores (FamilySpecificServices, StdHeader);
152 CpuInfoPtr->TotalCoreNumber--;
154 LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuId, StdHeader);
155 CpuInfoPtr->EnabledCoreNumber = (UINT8) (CpuId.ECX_Reg & 0xFF); // bit 7:0
157 switch (CpuInfoPtr->PackageType) {
159 CpuInfoPtr->ProcUpgrade = P_UPGRADE_F1207;
162 CpuInfoPtr->ProcUpgrade = P_UPGRADE_AM3;
165 CpuInfoPtr->ProcUpgrade = P_UPGRADE_S1GX;
168 CpuInfoPtr->ProcUpgrade = P_UPGRADE_G34;
171 CpuInfoPtr->ProcUpgrade = P_UPGRADE_NONE;
174 CpuInfoPtr->ProcUpgrade = P_UPGRADE_C32;
177 CpuInfoPtr->ProcUpgrade = P_UPGRADE_UNKNOWN;
181 LibAmdCpuidRead (AMD_CPUID_TLB_L1Cache, &CpuId, StdHeader);
182 CpuInfoPtr->L1CacheSize = (UINT32) (((UINT8) (CpuId.ECX_Reg >> 24) + (UINT8) (CpuId.EDX_Reg >> 24)) * (CpuInfoPtr->EnabledCoreNumber + 1));
184 LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuId, StdHeader);
185 CpuInfoPtr->L2CacheSize = (UINT32) ((UINT16) (CpuId.ECX_Reg >> 16) * (CpuInfoPtr->EnabledCoreNumber + 1));
188 /* -----------------------------------------------------------------------------*/
193 * Get the voltage value according to SMBIOS SPEC's requirement.
195 * @param[in] StdHeader Standard Head Pointer
197 * @retval Voltage - CPU Voltage.
202 IN AMD_CONFIG_PARAMS *StdHeader
207 UINT8 NumberBoostStates;
209 UINT32 CurrentNodeNum;
212 CPU_LOGICAL_ID CpuFamilyRevision;
213 CPB_CTRL_REGISTER CpbCtrl;
215 // Voltage = 0x80 + (voltage at boot time * 10)
216 GetCurrentNodeNum (&CurrentNodeNum, StdHeader);
217 TempAddr.AddressValue = MAKE_SBDFO (0, 0, (24 + CurrentNodeNum), FUNC_3, PW_CTL_MISC_REG);
218 LibAmdPciReadBits (TempAddr, 8, 8, &Pvimode, (VOID *)StdHeader);
219 //Pvimode is a 1-bit register field: 1-PVI 0-SVI
221 GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
222 if ((CpuFamilyRevision.Revision & AMD_F10_PH_ALL) != 0) {
223 TempAddr.AddressValue = MAKE_SBDFO (0, 0, (24 + CurrentNodeNum), FUNC_4, CPB_CTRL_REG);
224 LibAmdPciRead (AccessWidth32, TempAddr, &CpbCtrl, StdHeader); // F4x15C
225 NumberBoostStates = (UINT8) CpbCtrl.NumBoostStates;
227 NumberBoostStates = 0;
230 LibAmdMsrRead ((MSR_PSTATE_0 + NumberBoostStates), &MsrData, StdHeader);
231 MaxVid = (UINT8) (((PSTATE_MSR *)&MsrData)->CpuVid);
235 F10Translate7BitVidTo6Bit (&MaxVid);
236 if (MaxVid >= 0x20) {
237 Voltage = (UINT8) ((7625 - (125 * (MaxVid - 0x20)) + 500) / 1000);
239 Voltage = (UINT8) ((1550 - (25 * MaxVid) + 50) / 100);
243 if ((MaxVid >= 0x7C) && (MaxVid <= 0x7F)) {
246 Voltage = (UINT8) ((15500 - (125 * MaxVid) + 500) / 1000);
254 /* -----------------------------------------------------------------------------*/
261 * @param[in] StdHeader Standard Head Pointer
263 * @retval MaxSpeed - CPU Max Speed.
268 IN AMD_CONFIG_PARAMS *StdHeader
271 UINT8 NumBoostStates;
273 PSTATE_CPU_FAMILY_SERVICES *FamilyServices;
275 FamilyServices = NULL;
276 GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
277 ASSERT (FamilyServices != NULL);
278 NumBoostStates = F10GetNumberOfBoostedPstatesOnCore (StdHeader);
280 FamilyServices->GetPstateFrequency (FamilyServices, NumBoostStates, &P0Frequency, StdHeader);
281 return ((UINT16) P0Frequency);
284 /* -----------------------------------------------------------------------------*/
289 * Get the external clock Speed
291 * @param[in] StdHeader Standard Head Pointer
293 * @retval ExtClock - CPU external clock Speed.
298 IN AMD_CONFIG_PARAMS *StdHeader
301 return (EXTERNAL_CLOCK_DFLT);
304 /* -----------------------------------------------------------------------------*/
309 * Get memory information.
311 * @param[in,out] CpuGetMemInfoPtr Pointer to CPU_GET_MEM_INFO struct.
312 * @param[in] StdHeader Standard Head Pointer
317 IN OUT CPU_GET_MEM_INFO *CpuGetMemInfoPtr,
318 IN AMD_CONFIG_PARAMS *StdHeader
324 CpuGetMemInfoPtr->EccCapable = FALSE;
327 PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_2, 0x90);
328 LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);
329 // Check if F2x90[DimmEccEn] is set
330 if ((PciData & 0x00080000) != 0) {
331 CpuGetMemInfoPtr->EccCapable = TRUE;
334 PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_2, 0x190);
335 LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader);
336 // Check if F2x190[DimmEccEn] is set
337 if ((PciData & 0x00080000) != 0) {
338 CpuGetMemInfoPtr->EccCapable = TRUE;
342 // Partition Row Position - 0 is for dual channel memory
343 CpuGetMemInfoPtr->PartitionRowPosition = 0;
346 /*---------------------------------------------------------------------------------------
347 * Processor Family Table
349 * Note: 'x' means we don't care this field
351 * 038h = "AMD Turion(TM) II Ultra Dual-Core Mobile M Processor Family"
352 * 039h = "AMD Turion(TM) II Dual-Core Mobile M Processor Family"
353 * 03Ah = "AMD Athlon(TM) II Dual-Core M Processor Family"
354 * 083h = "AMD Athlon(tm) 64 Processor Family"
355 * 084h = "AMD Opteron(TM) Processor Family"
356 * 085h = "AMD Sempron(tm) Processor Family"
357 * 087h = "Dual-Core AMD Opteron Processor Family"
358 * 08Ah = "Quad-Core AMD Opteron Processor Family"
359 * 08Ch = "AMD Phenom FX Quad-Core Processor Family"
360 * 08Dh = "AMD Phenom X4 Quad-Core Processor Family"
361 * 08Eh = "AMD Phenom X2 Dual-Core Processor Family"
362 * 08Fh = "AMD Athlon X2 Dual-Core Processor Family"
363 * 0E6h = "Embedded AMD Opteron Processor Family"
364 * 0E7h = "AMD Phenom Triple-Core Processor Family"
365 * 0ECh = "AMD Phenom(TM) II Processor Family"
366 * 0EDh = "AMD Athlon(TM) II Processor Family"
367 * 0EEh = "Six-Core AMD Opteron(TM) Processor Family"
368 * 0EFh = "AMD Sempron(TM) M Processor Family"
369 *-------------------------------------------------------------------------------------*/
370 CONST DMI_BRAND_ENTRY ROMDATA Family10BrandList[] =
372 // Brand --> DMI ID translation table
373 // PackageType, PgOfBrandId, NumberOfCores, String1ofBrandId, ValueSetToDmiTable
374 // {'x', 'x', 'x', 'x', 0x02} MUST be the last one.
402 {1, 0, 1, 0xA, 0xEC},
403 {1, 0, 1, 0xB, 0xEC},
404 {1, 0, 1, 0xC, 0x85},
415 {1, 0, 2, 0xA, 0xED},
426 {1, 0, 3, 0xA, 0xED},
427 {1, 0, 3, 0xB, 0xED},
428 {1, 0, 3, 0xC, 0xED},
429 {1, 0, 3, 0xD, 0xED},
430 {1, 0, 3, 0xE, 0xEC},
431 {1, 0, 3, 0xF, 0xED},
459 {3, 0, 0xB, 0, 0x84},
473 {'x', 'x', 'x', 'x', P_FAMILY_UNKNOWN}
476 CONST PROC_FAMILY_TABLE ROMDATA ProcFamily10DmiTable =
478 // This table is for Processor family 10h
479 AMD_FAMILY_10, // ID for Family 10h
480 DmiF10GetInfo, // Transfer vectors for family
481 DmiGetT4ProcFamilyFromBrandId, // Get type 4 processor family information from CPUID_8000_0001_EBX[BrandId]
482 DmiF10GetVoltage, // specific routines (above)
485 DmiF10GetMemInfo, // Get memory information
486 (sizeof (Family10BrandList) / sizeof (Family10BrandList[0])), // Number of entries in following table
487 &Family10BrandList[0]
491 /*---------------------------------------------------------------------------------------
492 * L O C A L F U N C T I O N S
493 *---------------------------------------------------------------------------------------
496 /* -----------------------------------------------------------------------------*/
499 * F10Translate7BitVidTo6Bit
501 * translate 7 bit VID to 6 bit VID
503 * @param[in, out] MaxVidPtr - Pointer to MaxVid.
507 F10Translate7BitVidTo6Bit (
508 IN OUT UINT8 * MaxVidPtr
511 if ((*MaxVidPtr >= 0x5E) && (*MaxVidPtr <= 0x7F)) {
513 } else if ((*MaxVidPtr >= 0x3F) && (*MaxVidPtr <= 0x5D)) {
514 *MaxVidPtr = *MaxVidPtr - 0x1F;
515 } else if (*MaxVidPtr <= 0x3E) {
516 *MaxVidPtr = (*MaxVidPtr & 0x7E) >> 1;