AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / Feature / cpuDmi.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD DMI Record Creation API, and related functions.
6  *
7  * Contains code that produce the DMI related information.
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:      AGESA
11  * @e sub-project:  CPU
12  * @e \$Revision: 60539 $   @e \$Date: 2011-10-17 17:11:05 -0600 (Mon, 17 Oct 2011) $
13  *
14  */
15 /*****************************************************************************
16  *
17  * Copyright (C) 2012 Advanced Micro Devices, Inc.
18  * All rights reserved.
19  *
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.
30  *
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.
41  *
42  ******************************************************************************
43  */
44
45 /*----------------------------------------------------------------------------------------
46  *                             M O D U L E S    U S E D
47  *----------------------------------------------------------------------------------------
48  */
49 #include "AGESA.h"
50 #include "amdlib.h"
51 #include "OptionDmi.h"
52 #include "cpuLateInit.h"
53 #include "cpuServices.h"
54 #include "cpuRegisters.h"
55 #include "GeneralServices.h"
56 #include "heapManager.h"
57 #include "Ids.h"
58 #include "cpuFamilyTranslation.h"
59 #include "Filecode.h"
60 CODE_GROUP (G3_DXE)
61 RDATA_GROUP (G3_DXE)
62
63 #define FILECODE PROC_CPU_FEATURE_CPUDMI_FILECODE
64 /*----------------------------------------------------------------------------------------
65  *                   D E F I N I T I O N S    A N D    M A C R O S
66  *----------------------------------------------------------------------------------------
67  */
68 extern OPTION_DMI_CONFIGURATION    OptionDmiConfiguration;  // global user config record
69
70 /*----------------------------------------------------------------------------------------
71  *                  T Y P E D E F S     A N D     S T R U C T U  R E S
72  *----------------------------------------------------------------------------------------
73  */
74
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  *----------------------------------------------------------------------------------------
78  */
79 UINT16
80 STATIC
81 AdjustGranularity (
82   IN UINT32 *CacheSizePtr
83   );
84
85 VOID
86 STATIC
87 IntToString (
88   IN OUT   CHAR8 *String,
89   IN       UINT8 *Integer,
90   IN       UINT8 SizeInByte
91 );
92
93 AGESA_STATUS
94 GetDmiInfoStub (
95   IN OUT   AMD_CONFIG_PARAMS     *StdHeader,
96   IN OUT   DMI_INFO              **DmiTable
97   );
98
99 AGESA_STATUS
100 GetDmiInfoMain (
101   IN OUT   AMD_CONFIG_PARAMS     *StdHeader,
102   IN OUT   DMI_INFO              **DmiTable
103   );
104
105 AGESA_STATUS
106 ReleaseDmiBufferStub (
107   IN OUT   AMD_CONFIG_PARAMS     *StdHeader
108   );
109
110 AGESA_STATUS
111 ReleaseDmiBuffer (
112   IN OUT   AMD_CONFIG_PARAMS     *StdHeader
113   );
114
115
116 /*----------------------------------------------------------------------------------------
117  *                          E X P O R T E D    F U N C T I O N S
118  *----------------------------------------------------------------------------------------
119  */
120
121 /*---------------------------------------------------------------------------------------
122  *                          L O C A L    F U N C T I O N S
123  *---------------------------------------------------------------------------------------
124  */
125
126 /* -----------------------------------------------------------------------------*/
127 /**
128  *
129  *  CreateDmiRecords
130  *
131  *  Description:
132  *     This function creates DMI/SMBios records pertinent to the processor
133  *     SMBIOS type 4, type 7, and type 40.
134  *
135  *  Parameters:
136  *    @param[in, out]  *StdHeader
137  *    @param[in, out]  **DmiTable
138  *
139  *    @retval         AGESA_STATUS
140  *
141  */
142
143 AGESA_STATUS
144 CreateDmiRecords (
145   IN OUT   AMD_CONFIG_PARAMS     *StdHeader,
146   IN OUT   DMI_INFO              **DmiTable
147   )
148 {
149   AGESA_TESTPOINT (TpProcCpuEntryDmi, StdHeader);
150   return ((*(OptionDmiConfiguration.DmiFeature)) (StdHeader, DmiTable));
151 }
152
153 /* -----------------------------------------------------------------------------*/
154 /**
155  *  GetDmiInfoStub
156  *
157  *  Description:
158  *     This is the default routine for use when the DMI option is NOT requested.
159  *      The option install process will create and fill the transfer vector with
160  *      the address of the proper routine (Main or Stub). The link optimizer will
161  *      strip out of the .DLL the routine that is not used.
162  *
163  *  Parameters:
164  *    @param[in, out]    *StdHeader
165  *    @param[in, out]    **DmiTable
166  *
167  *    @retval         AGESA_STATUS
168  *
169  */
170 AGESA_STATUS
171 GetDmiInfoStub (
172   IN OUT   AMD_CONFIG_PARAMS     *StdHeader,
173   IN OUT   DMI_INFO              **DmiTable
174   )
175 {
176   return  AGESA_UNSUPPORTED;
177 }
178
179 /* -----------------------------------------------------------------------------*/
180 /**
181  *  GetDmiInfoMain
182  *
183  *  Description:
184  *     This is the common routine for getting Dmi type4 and type7 CPU related information.
185  *
186  *  Parameters:
187  *    @param[in, out]  *StdHeader
188  *    @param[in, out]  **DmiTable
189  *
190  *    @retval         AGESA_STATUS
191  *
192  */
193 AGESA_STATUS
194 GetDmiInfoMain (
195   IN OUT   AMD_CONFIG_PARAMS     *StdHeader,
196   IN OUT   DMI_INFO              **DmiTable
197   )
198 {
199   UINT8  Socket;
200   UINT8  Channel;
201   UINT8  Dimm;
202   UINT16 Index;
203   UINT16 DimmIndex;
204   UINT16 NumberOfDimm;
205   UINT32 MaxCapacity;
206   UINT64 MsrData;
207   UINT64 LocalMsrRegister;
208   BOOLEAN FamilyNotFound;
209   AGESA_STATUS Flag;
210   AGESA_STATUS CalledStatus;
211   AP_EXE_PARAMS ApParams;
212   MEM_DMI_INFO *MemInfo;
213   DMI_T17_MEMORY_TYPE MemType;
214   DMI_INFO *DmiBufferPtr;
215   ALLOCATE_HEAP_PARAMS AllocateHeapParams;
216   LOCATE_HEAP_PTR LocateHeapParams;
217   CPU_LOGICAL_ID LogicalId;
218   PROC_FAMILY_TABLE *ProcData;
219   CPU_GET_MEM_INFO CpuGetMemInfo;
220
221   MsrData = 0;
222   Flag = TRUE;
223   ProcData = NULL;
224   MemInfo = NULL;
225   DmiBufferPtr = *DmiTable;
226   FamilyNotFound = TRUE;
227
228   GetLogicalIdOfCurrentCore (&LogicalId, StdHeader);
229   for (Index = 0; Index < OptionDmiConfiguration.NumEntries; Index++) {
230     ProcData = (PROC_FAMILY_TABLE *) ((*OptionDmiConfiguration.FamilyList)[Index]);
231     if ((ProcData->ProcessorFamily & LogicalId.Family) != 0) {
232       FamilyNotFound = FALSE;
233       break;
234     }
235   }
236
237   if (FamilyNotFound) {
238     return AGESA_ERROR;
239   }
240
241   if (DmiBufferPtr == NULL) {
242     //
243     // Allocate a buffer by heap function
244     //
245     AllocateHeapParams.BufferHandle = AMD_DMI_INFO_BUFFER_HANDLE;
246     AllocateHeapParams.RequestedBufferSize = sizeof (DMI_INFO);
247     AllocateHeapParams.Persist = HEAP_SYSTEM_MEM;
248
249     if (HeapAllocateBuffer (&AllocateHeapParams, StdHeader) != AGESA_SUCCESS) {
250       return AGESA_ERROR;
251     }
252
253     DmiBufferPtr = (DMI_INFO *) AllocateHeapParams.BufferPtr;
254     *DmiTable = DmiBufferPtr;
255   }
256
257   IDS_HDT_CONSOLE (CPU_TRACE, "  DMI is enabled\n");
258
259   // Fill with 0x00
260   LibAmdMemFill (DmiBufferPtr, 0x00, sizeof (DMI_INFO), StdHeader);
261
262   //
263   // Get CPU information
264   //
265
266   // Run GetType4Type7Info on all core0s.
267   ApParams.StdHeader = *StdHeader;
268   ApParams.FunctionNumber = AP_LATE_TASK_GET_TYPE4_TYPE7;
269   ApParams.RelatedDataBlock = (VOID *) DmiBufferPtr;
270   ApParams.RelatedBlockLength = sizeof (DMI_INFO);
271   CalledStatus = RunLateApTaskOnAllCore0s (&ApParams, StdHeader);
272   if (CalledStatus > Flag) {
273     Flag = CalledStatus;
274   }
275   CalledStatus = GetType4Type7Info (&ApParams);
276   if (CalledStatus > Flag) {
277     Flag = CalledStatus;
278   }
279
280   //------------------------------
281   // T Y P E 16 17 19 20
282   //------------------------------
283
284   LocateHeapParams.BufferHandle = AMD_DMI_MEM_DEV_INFO_HANDLE;
285   if (HeapLocateBuffer (&LocateHeapParams, StdHeader) != AGESA_SUCCESS) {
286     if (Flag < AGESA_ERROR) {
287       Flag = AGESA_ERROR;
288     }
289   } else {
290     NumberOfDimm = *((UINT16 *) (LocateHeapParams.BufferPtr));
291     MemType = *((DMI_T17_MEMORY_TYPE *) ((UINT8 *) (LocateHeapParams.BufferPtr) + 6));
292     MemInfo = (MEM_DMI_INFO *) ((UINT8 *) (LocateHeapParams.BufferPtr) + 6 + sizeof (DMI_T17_MEMORY_TYPE));
293     // TYPE 16
294     DmiBufferPtr->T16.Location = 0x03;
295     DmiBufferPtr->T16.Use = 0x03;
296
297     // Gather memory information
298     ProcData->DmiGetMemInfo (&CpuGetMemInfo, StdHeader);
299
300     if (CpuGetMemInfo.EccCapable) {
301       DmiBufferPtr->T16.MemoryErrorCorrection = Dmi16MultiBitEcc;
302     } else {
303       DmiBufferPtr->T16.MemoryErrorCorrection = Dmi16NoneErrCorrection;
304     }
305
306     MaxCapacity = *((UINT32 *) ((UINT8 *) (LocateHeapParams.BufferPtr) + 2));
307     // For the total size >= 2TB case, we need leave MaximumCapacity (offset 07h) to 80000000h
308     // and fill the size in bytes into ExtMaxCapacity (offset 0Fh).
309     if (MaxCapacity < 0x200000) {
310     DmiBufferPtr->T16.MaximumCapacity = MaxCapacity << 10;
311       DmiBufferPtr->T16.ExtMaxCapacity = 0;
312     } else {
313       DmiBufferPtr->T16.MaximumCapacity = 0x80000000;
314       DmiBufferPtr->T16.ExtMaxCapacity = (UINT64) MaxCapacity << 20;
315     }
316
317     DmiBufferPtr->T16.NumberOfMemoryDevices = NumberOfDimm;
318
319     // TYPE 17
320     for (DimmIndex = 0; DimmIndex < NumberOfDimm; DimmIndex++) {
321       Socket = (MemInfo + DimmIndex)->Socket;
322       Channel = (MemInfo + DimmIndex)->Channel;
323       Dimm = (MemInfo + DimmIndex)->Dimm;
324
325       DmiBufferPtr->T17[Socket][Channel][Dimm].TotalWidth = (MemInfo + DimmIndex)->TotalWidth;
326       DmiBufferPtr->T17[Socket][Channel][Dimm].DataWidth = (MemInfo + DimmIndex)->DataWidth;
327       DmiBufferPtr->T17[Socket][Channel][Dimm].MemorySize = (MemInfo + DimmIndex)->MemorySize;
328       DmiBufferPtr->T17[Socket][Channel][Dimm].FormFactor = (MemInfo + DimmIndex)->FormFactor;
329       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceSet = 0;
330
331       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[0] = 'D';
332       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[1] = 'I';
333       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[2] = 'M';
334       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[3] = 'M';
335       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[4] = ' ';
336       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[5] = Dimm + 0x30;
337       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[6] = '\0';
338       DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[7] = '\0';
339
340       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[0] = 'C';
341       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[1] = 'H';
342       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[2] = 'A';
343       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[3] = 'N';
344       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[4] = 'N';
345       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[5] = 'E';
346       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[6] = 'L';
347       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[7] = ' ';
348       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[8] = Channel + 0x41;
349       DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[9] = '\0';
350
351       DmiBufferPtr->T17[Socket][Channel][Dimm].MemoryType = MemType;
352       DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Synchronous = 1;
353       DmiBufferPtr->T17[Socket][Channel][Dimm].Speed = (MemInfo + DimmIndex)->Speed;
354
355       DmiBufferPtr->T17[Socket][Channel][Dimm].ManufacturerIdCode = (MemInfo + DimmIndex)->ManufacturerIdCode;
356
357       IntToString (DmiBufferPtr->T17[Socket][Channel][Dimm].SerialNumber, (MemInfo + DimmIndex)->SerialNumber, (sizeof DmiBufferPtr->T17[Socket][Channel][Dimm].SerialNumber - 1) / 2);
358
359       LibAmdMemCopy (&DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber, &(MemInfo + DimmIndex)->PartNumber, sizeof (DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber), StdHeader);
360       DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber[18] = 0;
361
362       DmiBufferPtr->T17[Socket][Channel][Dimm].Attributes = (MemInfo + DimmIndex)->Attributes;
363       DmiBufferPtr->T17[Socket][Channel][Dimm].ExtSize = (MemInfo + DimmIndex)->ExtSize;
364       DmiBufferPtr->T17[Socket][Channel][Dimm].ConfigSpeed = (MemInfo + DimmIndex)->ConfigSpeed;
365
366       //TYPE 20
367       DmiBufferPtr->T20[Socket][Channel][Dimm].StartingAddr = (MemInfo + DimmIndex)->StartingAddr;
368       DmiBufferPtr->T20[Socket][Channel][Dimm].EndingAddr = (MemInfo + DimmIndex)->EndingAddr;
369       // Partition Row Position - 2 for single channel memory
370       //                          0 for dual channel memory
371       DmiBufferPtr->T20[Socket][Channel][Dimm].PartitionRowPosition = CpuGetMemInfo.PartitionRowPosition;
372       DmiBufferPtr->T20[Socket][Channel][Dimm].InterleavePosition = 0xFF;
373       DmiBufferPtr->T20[Socket][Channel][Dimm].InterleavedDataDepth = 0xFF;
374       DmiBufferPtr->T20[Socket][Channel][Dimm].ExtStartingAddr = (MemInfo + DimmIndex)->ExtStartingAddr;
375       DmiBufferPtr->T20[Socket][Channel][Dimm].ExtEndingAddr = (MemInfo + DimmIndex)->ExtEndingAddr;
376     }
377
378     // TYPE 19
379     DmiBufferPtr->T19.StartingAddr = 0;
380     DmiBufferPtr->T19.ExtStartingAddr = 0;
381     DmiBufferPtr->T19.ExtEndingAddr = 0;
382
383     // If Ending Address >= 0xFFFFFFFF, update Starting Address (offset 04h) & Ending Address (offset 08h) to 0xFFFFFFFF,
384     // and use the Extended Starting Address (offset 0Fh) & Extended Ending Address (offset 17h) instead.
385     LibAmdMsrRead (TOP_MEM2, &LocalMsrRegister, StdHeader);
386     if (LocalMsrRegister == 0) {
387       LibAmdMsrRead (TOP_MEM, &LocalMsrRegister, StdHeader);
388       DmiBufferPtr->T19.EndingAddr = (UINT32) (LocalMsrRegister >> 10);
389     } else {
390       if ((LocalMsrRegister >> 10) >= (UINT64) 0xFFFFFFFF) {
391         DmiBufferPtr->T19.StartingAddr = 0xFFFFFFFF;
392         DmiBufferPtr->T19.EndingAddr = 0xFFFFFFFF;
393         DmiBufferPtr->T19.ExtEndingAddr = LocalMsrRegister;
394       } else {
395       DmiBufferPtr->T19.EndingAddr = (UINT32) (LocalMsrRegister >> 10);
396     }
397     }
398
399     DmiBufferPtr->T19.PartitionWidth = 0xFF;
400   }
401   return (Flag);
402 }
403
404 /* -----------------------------------------------------------------------------*/
405 /**
406  *
407  *  GetType4Type7Info
408  *
409  *  Description:
410  *    This routine should be run on core 0 of every socket. It creates DMI type 4 and type 7 tables.
411  *
412  *  Parameters:
413  *    @param[in] ApExeParams   Handle to config for library and services.
414  *
415  *    @retval         AGESA_STATUS
416  *
417  *  Processing:
418  *
419  */
420 AGESA_STATUS
421 GetType4Type7Info (
422   IN       AP_EXE_PARAMS *ApExeParams
423   )
424 {
425   UINT8  ByteIndexInUint64;
426   UINT16 Index;
427   UINT32 SocketNum;
428   UINT32 CacheSize;
429   UINT32 IgnoredModule;
430   UINT32 IgnoredCore;
431   UINT64 MsrData;
432   DMI_INFO *DmiBufferPtr;
433   AGESA_STATUS IgnoredSts;
434   AGESA_STATUS Flag;
435   BOOLEAN FamilyNotFound;
436   CPUID_DATA CpuId;
437   CPU_TYPE_INFO CpuInfo;
438   PROC_FAMILY_TABLE   *ProcData;
439   CPU_LOGICAL_ID LogicalID;
440   UINT8  L3Associativity;
441
442   Flag = TRUE;
443   DmiBufferPtr = (DMI_INFO *) ApExeParams->RelatedDataBlock;
444   GetLogicalIdOfCurrentCore (&LogicalID, &ApExeParams->StdHeader);
445
446   ProcData = NULL;
447   FamilyNotFound = TRUE;
448   for (Index = 0; Index < OptionDmiConfiguration.NumEntries; Index++) {
449     ProcData = (PROC_FAMILY_TABLE *) ((*OptionDmiConfiguration.FamilyList)[Index]);
450     if ((ProcData->ProcessorFamily & LogicalID.Family) != 0) {
451       FamilyNotFound = FALSE;
452       break;
453     }
454   }
455
456   if (FamilyNotFound) {
457     return AGESA_ERROR;
458   }
459
460   ProcData->DmiGetCpuInfo (&CpuInfo, &ApExeParams->StdHeader);
461
462   // ------------------------------
463   // T Y P E 4
464   // ------------------------------
465
466   IdentifyCore (&ApExeParams->StdHeader, &SocketNum, &IgnoredModule, &IgnoredCore, &IgnoredSts);
467
468   // Type 4 Offset 0x05, Processor Type
469   DmiBufferPtr->T4[SocketNum].T4ProcType = CENTRAL_PROCESSOR;
470
471   // Type 4 Offset 0x06, Processor Family
472   ProcData->DmiGetT4ProcFamily (&DmiBufferPtr->T4[SocketNum].T4ProcFamily, ProcData, &CpuInfo, &ApExeParams->StdHeader);
473
474   if (DmiBufferPtr->T4[SocketNum].T4ProcFamily == P_UPGRADE_UNKNOWN) {
475     Flag = AGESA_ERROR;
476   }
477
478   // Type4 Offset 0x08, Processor ID
479   LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuId, &ApExeParams->StdHeader);
480   DmiBufferPtr->T4[SocketNum].T4ProcId.ProcIdLsd = CpuId.EAX_Reg;
481   DmiBufferPtr->T4[SocketNum].T4ProcId.ProcIdMsd = CpuId.EDX_Reg;
482
483   // Type4 Offset 0x11, Voltage
484   DmiBufferPtr->T4[SocketNum].T4Voltage = ProcData->DmiGetVoltage (&ApExeParams->StdHeader);
485
486   // Type4 Offset 0x12, External Clock
487   DmiBufferPtr->T4[SocketNum].T4ExternalClock = ProcData->DmiGetExtClock (&ApExeParams->StdHeader);
488
489   // Type4 Offset 0x14, Max Speed
490   DmiBufferPtr->T4[SocketNum].T4MaxSpeed = ProcData->DmiGetMaxSpeed (&ApExeParams->StdHeader);
491
492   // Type4 Offset 0x16, Current Speed
493   DmiBufferPtr->T4[SocketNum].T4CurrentSpeed = DmiBufferPtr->T4[SocketNum].T4MaxSpeed;
494
495   // Type4 Offset 0x18, Status
496   DmiBufferPtr->T4[SocketNum].T4Status = SOCKET_POPULATED | CPU_STATUS_ENABLED;
497
498   // Type4 Offset 0x19, Processor Upgrade
499   DmiBufferPtr->T4[SocketNum].T4ProcUpgrade = CpuInfo.ProcUpgrade;
500
501   // Type4 Offset 0x23, 0x24 and 0x25, Core Count, Core Enabled and Thread Count
502   DmiBufferPtr->T4[SocketNum].T4CoreCount   = CpuInfo.TotalCoreNumber + 1;
503   DmiBufferPtr->T4[SocketNum].T4CoreEnabled = CpuInfo.EnabledCoreNumber + 1;
504   DmiBufferPtr->T4[SocketNum].T4ThreadCount = CpuInfo.EnabledCoreNumber + 1;
505
506   // Type4 Offset 0x26, Processor Characteristics
507   DmiBufferPtr->T4[SocketNum].T4ProcCharacteristics = P_CHARACTERISTICS;
508
509   // Type4 Offset 0x28, Processor Family 2
510   DmiBufferPtr->T4[SocketNum].T4ProcFamily2 = DmiBufferPtr->T4[SocketNum].T4ProcFamily;
511
512   // Type4 ProcVersion
513   for (Index = 0; Index <= 5; Index++) {
514     LibAmdMsrRead ((MSR_CPUID_NAME_STRING0 + Index), &MsrData, &ApExeParams->StdHeader);
515     for (ByteIndexInUint64 = 0; ByteIndexInUint64 <= 7; ByteIndexInUint64++) {
516       DmiBufferPtr->T4[SocketNum].T4ProcVersion[Index * 8 + ByteIndexInUint64] = (UINT8) (MsrData >> (8 * ByteIndexInUint64));
517     }
518   }
519
520   //------------------------------
521   // T Y P E 7
522   //------------------------------
523
524   // Type7 Offset 0x05, Cache Configuration
525   DmiBufferPtr->T7L1[SocketNum].T7CacheCfg = CACHE_CFG_L1;
526   DmiBufferPtr->T7L2[SocketNum].T7CacheCfg = CACHE_CFG_L2;
527   DmiBufferPtr->T7L3[SocketNum].T7CacheCfg = CACHE_CFG_L3;
528
529   // Type7 Offset 0x07 and 09, Maximum Cache Size and Installed Size
530
531   // Maximum L1 cache size
532   DmiBufferPtr->T7L1[SocketNum].T7MaxCacheSize = AdjustGranularity (&CpuInfo.L1CacheSize);
533
534   // Installed L1 cache size
535   DmiBufferPtr->T7L1[SocketNum].T7InstallSize = DmiBufferPtr->T7L1[SocketNum].T7MaxCacheSize;
536
537   // Maximum L2 cache size
538   DmiBufferPtr->T7L2[SocketNum].T7MaxCacheSize = AdjustGranularity (&CpuInfo.L2CacheSize);
539
540   // Installed L2 cache size
541   DmiBufferPtr->T7L2[SocketNum].T7InstallSize = DmiBufferPtr->T7L2[SocketNum].T7MaxCacheSize;
542
543   // Maximum L3 cache size
544   LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuId, &ApExeParams->StdHeader);
545   CacheSize = ((CpuId.EDX_Reg >> 18) & 0x3FFF) * 512;
546   DmiBufferPtr->T7L3[SocketNum].T7MaxCacheSize = AdjustGranularity (&CacheSize);
547
548   // Installed L3 cache size
549   DmiBufferPtr->T7L3[SocketNum].T7InstallSize = DmiBufferPtr->T7L3[SocketNum].T7MaxCacheSize;
550
551   // Type7 Offset 0x0B and 0D, Supported SRAM Type and Current SRAM Type
552   DmiBufferPtr->T7L1[SocketNum].T7SupportedSramType = SRAM_TYPE;
553   DmiBufferPtr->T7L1[SocketNum].T7CurrentSramType = SRAM_TYPE;
554   DmiBufferPtr->T7L2[SocketNum].T7SupportedSramType = SRAM_TYPE;
555   DmiBufferPtr->T7L2[SocketNum].T7CurrentSramType = SRAM_TYPE;
556   DmiBufferPtr->T7L3[SocketNum].T7SupportedSramType = SRAM_TYPE;
557   DmiBufferPtr->T7L3[SocketNum].T7CurrentSramType = SRAM_TYPE;
558
559   // Type7 Offset 0x0F, Cache Speed
560   DmiBufferPtr->T7L1[SocketNum].T7CacheSpeed = 1;
561   DmiBufferPtr->T7L2[SocketNum].T7CacheSpeed = 1;
562   DmiBufferPtr->T7L3[SocketNum].T7CacheSpeed = 1;
563
564   // Type7 Offset 0x10, Error Correction Type
565   DmiBufferPtr->T7L1[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE;
566   DmiBufferPtr->T7L2[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE;
567   DmiBufferPtr->T7L3[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE;
568
569   // Type7 Offset 0x11, System Cache Type
570   DmiBufferPtr->T7L1[SocketNum].T7SystemCacheType = CACHE_TYPE;
571   DmiBufferPtr->T7L2[SocketNum].T7SystemCacheType = CACHE_TYPE;
572   DmiBufferPtr->T7L3[SocketNum].T7SystemCacheType = CACHE_TYPE;
573
574   // Type7 Offset 0x12, Associativity
575   DmiBufferPtr->T7L1[SocketNum].T7Associativity = ASSOCIATIVE_2_WAY;
576   DmiBufferPtr->T7L2[SocketNum].T7Associativity = ASSOCIATIVE_16_WAY;
577
578   L3Associativity = (UINT8) ((CpuId.EDX_Reg >> 12) & 0x0F);
579
580   switch (L3Associativity)
581   {
582   case (CPUID_ASSOCIATIVITY_2_WAY):
583     DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_2_WAY;
584     break;
585   case (CPUID_ASSOCIATIVITY_4_WAY):
586     DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_4_WAY;
587     break;
588   case (CPUID_ASSOCIATIVITY_8_WAY):
589     DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_8_WAY;
590     break;
591   case (CPUID_ASSOCIATIVITY_16_WAY):
592     DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_16_WAY;
593     break;
594   case (CPUID_ASSOCIATIVITY_32_WAY):
595     DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_32_WAY;
596     break;
597   case (CPUID_ASSOCIATIVITY_48_WAY):
598     DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_48_WAY;
599     break;
600   case (CPUID_ASSOCIATIVITY_64_WAY):
601     DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_64_WAY;
602     break;
603   case (CPUID_ASSOCIATIVITY_96_WAY):
604   case (CPUID_ASSOCIATIVITY_128_WAY):
605   default:
606     DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_OTHER;
607     break;
608   }
609
610   return (Flag);
611 }
612
613 /* -----------------------------------------------------------------------------*/
614 /**
615  *  DmiGetT4ProcFamilyFromBrandId
616  *
617  *  Description:
618  *     This is the common routine for getting Type 4 processor family information from brand ID
619  *
620  *  Parameters:
621  *    @param[in, out]    *T4ProcFamily           Pointer to type 4 processor family information
622  *    @param[in]         *CpuDmiProcFamilyTable  Pointer to DMI family special service
623  *    @param[in]         *CpuInfo                Pointer to CPU_TYPE_INFO struct
624  *    @param[in, out]    *StdHeader              Standard Head Pointer
625  *
626  *    @retval         AGESA_STATUS
627  *
628  */
629 VOID
630 DmiGetT4ProcFamilyFromBrandId (
631   IN OUT   UINT8 *T4ProcFamily,
632   IN       PROC_FAMILY_TABLE *CpuDmiProcFamilyTable,
633   IN       CPU_TYPE_INFO *CpuInfo,
634   IN       AMD_CONFIG_PARAMS  *StdHeader
635   )
636 {
637   UINT16 Index;
638   *T4ProcFamily = P_UPGRADE_UNKNOWN;
639   if (CpuInfo->BrandId.Model != P_ENGINEERING_SAMPLE) {
640     for (Index = 0; Index < CpuDmiProcFamilyTable->LenBrandList; Index++) {
641       if ((CpuDmiProcFamilyTable->DmiBrandList[Index].PackageType == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].PackageType == CpuInfo->PackageType) &&
642           (CpuDmiProcFamilyTable->DmiBrandList[Index].PgOfBrandId == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].PgOfBrandId == CpuInfo->BrandId.Pg) &&
643           (CpuDmiProcFamilyTable->DmiBrandList[Index].NumberOfCores == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].NumberOfCores == CpuInfo->TotalCoreNumber) &&
644           (CpuDmiProcFamilyTable->DmiBrandList[Index].String1ofBrandId == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].String1ofBrandId == CpuInfo->BrandId.String1)) {
645         *T4ProcFamily = CpuDmiProcFamilyTable->DmiBrandList[Index].ValueSetToDmiTable;
646         break;
647       }
648     }
649   }
650 }
651
652 /* -----------------------------------------------------------------------------*/
653 /**
654  *
655  *  GetNameString
656  *
657  *  Description:
658  *    Get name string from MSR_C001_00[35:30]
659  *
660  *  Parameters:
661  *    @param[in, out]    *String       Pointer to name string
662  *    @param[in, out]    *StdHeader
663  *
664  */
665 VOID
666 GetNameString (
667   IN OUT   CHAR8 *String,
668   IN OUT   AMD_CONFIG_PARAMS *StdHeader
669   )
670 {
671   UINT8  i;
672   UINT8  StringIndex;
673   UINT8  MsrIndex;
674   UINT64 MsrData;
675
676   StringIndex = 0;
677   for (MsrIndex = 0; MsrIndex <= 5; MsrIndex++) {
678     LibAmdMsrRead ((MSR_CPUID_NAME_STRING0 + MsrIndex), &MsrData, StdHeader);
679     for (i = 0; i < 8; i++) {
680       String[StringIndex] = (CHAR8) (MsrData >> (8 * i));
681       StringIndex++;
682     }
683   }
684   String[StringIndex] = '\0';
685 }
686
687 /* -----------------------------------------------------------------------------*/
688 /**
689  *
690  *  IsSourceStrContainTargetStr
691  *
692  *  Description:
693  *    check if source string contains target string.
694  *
695  *  Parameters:
696  *    @param[in, out]    *SourceStr      Pointer to source CHAR array
697  *    @param[in, out]    *TargetStr      Pointer to target CHAR array
698  *    @param[in, out]    *StdHeader
699  *
700  *    @retval            TRUE             Target string is contained in the source string
701  *    @retval            FALSE            Target string is not contained in the source string
702  */
703 BOOLEAN
704 IsSourceStrContainTargetStr (
705   IN OUT   CHAR8 *SourceStr,
706   IN OUT   CONST CHAR8 *TargetStr,
707   IN OUT   AMD_CONFIG_PARAMS *StdHeader
708   )
709 {
710   BOOLEAN IsContained;
711   UINT32  SourceStrIndex;
712   UINT32  TargetStrIndex;
713   CHAR8 TargetChar;
714
715   IsContained = FALSE;
716   if ((TargetStr != NULL) && (SourceStr != NULL)) {
717     for (SourceStrIndex = 0; SourceStr[SourceStrIndex] != '\0'; SourceStrIndex++) {
718       // Compare TrgString with SrcString from frist charactor to the '\0'
719       for (TargetStrIndex = 0; TargetStr[TargetStrIndex] != '\0'; TargetStrIndex++) {
720         if (TargetStr[TargetStrIndex] != SourceStr[SourceStrIndex + TargetStrIndex]) {
721           // if it's not match, try to check the upcase/lowcase
722           TargetChar = 0;
723           if (TargetStr[TargetStrIndex] >= 'a' && TargetStr[TargetStrIndex] <= 'z') {
724             TargetChar = TargetStr[TargetStrIndex] - ('a' - 'A');
725           } else if (TargetStr[TargetStrIndex] >= 'A' && TargetStr[TargetStrIndex] <= 'Z') {
726             TargetChar = TargetStr[TargetStrIndex] + ('a' - 'A');
727           }
728           // compare again
729           if (TargetChar != SourceStr[SourceStrIndex + TargetStrIndex]) {
730             break;
731       }
732         }
733       }
734
735       if ((TargetStr[TargetStrIndex] == '\0') && (TargetStrIndex != 0)) {
736         IsContained = TRUE;
737         break;
738       }
739     }
740   }
741   return IsContained;
742 }
743
744 /* -----------------------------------------------------------------------------*/
745 /**
746  *
747  *  AdjustGranularity
748  *
749  *  Description:
750  *    If cache size is greater than or equal to 32M, then set granularity
751  *    to 64K. otherwise, set granularity to 1K
752  *
753  *  Parameters:
754  *    @param[in]    *CacheSizePtr
755  *
756  *    @retval       CacheSize
757  *
758  *  Processing:
759  *
760  */
761 UINT16
762 STATIC
763 AdjustGranularity (
764   IN UINT32 *CacheSizePtr
765   )
766 {
767   UINT16 CacheSize;
768
769   if (*CacheSizePtr >= 0x8000) {
770     CacheSize = (UINT16) (*CacheSizePtr / 64);
771     CacheSize |= 0x8000;
772   } else {
773     CacheSize = (UINT16) *CacheSizePtr;
774   }
775
776   return (CacheSize);
777 }
778
779 /* -----------------------------------------------------------------------------*/
780 /**
781  *  ReleaseDmiBufferStub
782  *
783  *  Description:
784  *     This is the default routine for use when the DMI option is NOT requested.
785  *
786  *  Parameters:
787  *    @param[in, out]    *StdHeader
788  *
789  *    @retval         AGESA_STATUS
790  *
791  */
792 AGESA_STATUS
793 ReleaseDmiBufferStub (
794   IN OUT   AMD_CONFIG_PARAMS     *StdHeader
795   )
796 {
797   return  AGESA_UNSUPPORTED;
798 }
799
800 /* -----------------------------------------------------------------------------*/
801 /**
802  *  ReleaseDmiBuffer
803  *
804  *  Description:
805  *     Deallocate DMI buffer
806  *
807  *  Parameters:
808  *    @param[in, out]    *StdHeader
809  *
810  *    @retval         AGESA_STATUS
811  *
812  */
813 AGESA_STATUS
814 ReleaseDmiBuffer (
815   IN OUT   AMD_CONFIG_PARAMS     *StdHeader
816   )
817 {
818   HeapDeallocateBuffer ((UINT32) AMD_DMI_MEM_DEV_INFO_HANDLE, StdHeader);
819
820   return  AGESA_SUCCESS;
821 }
822
823 /* -----------------------------------------------------------------------------*/
824 /**
825  *
826  *  IntToString
827  *
828  *  Description:
829  *    Translate UINT array to CHAR array.
830  *
831  *  Parameters:
832  *    @param[in, out]    *String       Pointer to CHAR array
833  *    @param[in]         *Integer      Pointer to UINT array
834  *    @param[in]         SizeInByte    The size of UINT array
835  *
836  *  Processing:
837  *
838  */
839 VOID
840 STATIC
841 IntToString (
842   IN OUT   CHAR8 *String,
843   IN       UINT8 *Integer,
844   IN       UINT8 SizeInByte
845   )
846 {
847   UINT8 Index;
848
849   for (Index = 0; Index < SizeInByte; Index++) {
850     *(String + Index * 2) = (*(Integer + Index) >> 4) & 0x0F;
851     *(String + Index * 2 + 1) = *(Integer + Index) & 0x0F;
852   }
853   for (Index = 0; Index < (SizeInByte * 2); Index++) {
854     if (*(String + Index) >= 0x0A) {
855       *(String + Index) += 0x37;
856     } else {
857       *(String + Index) += 0x30;
858     }
859   }
860   *(String + SizeInByte * 2) = 0x0;
861 }
862