diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f15tn/Proc/CPU/Feature/cpuDmi.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f15tn/Proc/CPU/Feature/cpuDmi.c | 867 |
1 files changed, 867 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Feature/cpuDmi.c b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Feature/cpuDmi.c new file mode 100644 index 0000000000..23fd79f1f9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Feature/cpuDmi.c @@ -0,0 +1,867 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD DMI Record Creation API, and related functions. + * + * Contains code that produce the DMI related information. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 64351 $ @e \$Date: 2012-01-19 03:50:41 -0600 (Thu, 19 Jan 2012) $ + * + */ +/***************************************************************************** + * + * Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved. + * + * AMD is granting you permission to use this software (the Materials) + * pursuant to the terms and conditions of your Software License Agreement + * with AMD. This header does *NOT* give you permission to use the Materials + * or any rights under AMD's intellectual property. Your use of any portion + * of these Materials shall constitute your acceptance of those terms and + * conditions. If you do not agree to the terms and conditions of the Software + * License Agreement, please do not use any portion of these Materials. + * + * CONFIDENTIALITY: The Materials and all other information, identified as + * confidential and provided to you by AMD shall be kept confidential in + * accordance with the terms and conditions of the Software License Agreement. + * + * LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION + * PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE, + * OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE. + * IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER + * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS + * INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE, + * GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER + * RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE + * EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, + * THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + * + * AMD does not assume any responsibility for any errors which may appear in + * the Materials or any other related information provided to you by AMD, or + * result from use of the Materials or any related information. + * + * You agree that you will not reverse engineer or decompile the Materials. + * + * NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any + * further information, software, technical information, know-how, or show-how + * available to you. Additionally, AMD retains the right to modify the + * Materials at any time, without notice, and is not obligated to provide such + * modified Materials to you. + * + * U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with + * "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is + * subject to the restrictions as set forth in FAR 52.227-14 and + * DFAR252.227-7013, et seq., or its successor. Use of the Materials by the + * Government constitutes acknowledgement of AMD's proprietary rights in them. + * + * EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any + * direct product thereof will be exported directly or indirectly, into any + * country prohibited by the United States Export Administration Act and the + * regulations thereunder, without the required authorization from the U.S. + * government nor will be used for any purpose prohibited by the same. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "OptionDmi.h" +#include "cpuLateInit.h" +#include "cpuServices.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "heapManager.h" +#include "Ids.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FEATURE_CPUDMI_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_DMI_CONFIGURATION OptionDmiConfiguration; // global user config record + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +CHAR8 ROMDATA str_ProcManufacturer[] = "Advanced Micro Devices, Inc."; +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +UINT16 +STATIC +AdjustGranularity ( + IN UINT32 *CacheSizePtr + ); + +VOID +STATIC +IntToString ( + IN OUT CHAR8 *String, + IN UINT8 *Integer, + IN UINT8 SizeInByte +); + +AGESA_STATUS +GetDmiInfoStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ); + +AGESA_STATUS +GetDmiInfoMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ); + +AGESA_STATUS +ReleaseDmiBufferStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +ReleaseDmiBuffer ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * CreateDmiRecords + * + * Description: + * This function creates DMI/SMBios records pertinent to the processor + * SMBIOS type 4, type 7, and type 40. + * + * Parameters: + * @param[in, out] *StdHeader + * @param[in, out] **DmiTable + * + * @retval AGESA_STATUS + * + */ + +AGESA_STATUS +CreateDmiRecords ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ) +{ + AGESA_TESTPOINT (TpProcCpuEntryDmi, StdHeader); + return ((*(OptionDmiConfiguration.DmiFeature)) (StdHeader, DmiTable)); +} + +/* -----------------------------------------------------------------------------*/ +/** + * GetDmiInfoStub + * + * Description: + * This is the default routine for use when the DMI option is NOT requested. + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * Parameters: + * @param[in, out] *StdHeader + * @param[in, out] **DmiTable + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +GetDmiInfoStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ) +{ + return AGESA_UNSUPPORTED; +} + +/* -----------------------------------------------------------------------------*/ +/** + * GetDmiInfoMain + * + * Description: + * This is the common routine for getting Dmi type4 and type7 CPU related information. + * + * Parameters: + * @param[in, out] *StdHeader + * @param[in, out] **DmiTable + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +GetDmiInfoMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ) +{ + UINT8 Socket; + UINT8 Channel; + UINT8 Dimm; + UINT16 Index; + UINT16 DimmIndex; + UINT8 NumberOfDimm; + UINT32 MaxCapacity; + UINT64 MsrData; + UINT64 LocalMsrRegister; + UINT8 TypeDetail; + BOOLEAN FamilyNotFound; + AGESA_STATUS Flag; + AGESA_STATUS CalledStatus; + AP_EXE_PARAMS ApParams; + MEM_DMI_INFO *MemInfo; + DMI_T17_MEMORY_TYPE MemType; + DMI_INFO *DmiBufferPtr; + ALLOCATE_HEAP_PARAMS AllocateHeapParams; + LOCATE_HEAP_PTR LocateHeapParams; + CPU_LOGICAL_ID LogicalId; + PROC_FAMILY_TABLE *ProcData; + CPU_GET_MEM_INFO CpuGetMemInfo; + + MsrData = 0; + Flag = TRUE; + ProcData = NULL; + MemInfo = NULL; + DmiBufferPtr = *DmiTable; + FamilyNotFound = TRUE; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + for (Index = 0; Index < OptionDmiConfiguration.NumEntries; Index++) { + ProcData = (PROC_FAMILY_TABLE *) ((*OptionDmiConfiguration.FamilyList)[Index]); + if ((ProcData->ProcessorFamily & LogicalId.Family) != 0) { + FamilyNotFound = FALSE; + break; + } + } + + if (FamilyNotFound) { + return AGESA_ERROR; + } + + if (DmiBufferPtr == NULL) { + // + // Allocate a buffer by heap function + // + AllocateHeapParams.BufferHandle = AMD_DMI_INFO_BUFFER_HANDLE; + AllocateHeapParams.RequestedBufferSize = sizeof (DMI_INFO); + AllocateHeapParams.Persist = HEAP_SYSTEM_MEM; + + if (HeapAllocateBuffer (&AllocateHeapParams, StdHeader) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + + DmiBufferPtr = (DMI_INFO *) AllocateHeapParams.BufferPtr; + *DmiTable = DmiBufferPtr; + } + + IDS_HDT_CONSOLE (CPU_TRACE, " DMI is enabled\n"); + + // Fill with 0x00 + LibAmdMemFill (DmiBufferPtr, 0x00, sizeof (DMI_INFO), StdHeader); + + // + // Get CPU information + // + + // Run GetType4Type7Info on all core0s. + ApParams.StdHeader = *StdHeader; + ApParams.FunctionNumber = AP_LATE_TASK_GET_TYPE4_TYPE7; + ApParams.RelatedDataBlock = (VOID *) DmiBufferPtr; + ApParams.RelatedBlockLength = sizeof (DMI_INFO); + CalledStatus = RunLateApTaskOnAllCore0s (&ApParams, StdHeader); + if (CalledStatus > Flag) { + Flag = CalledStatus; + } + CalledStatus = GetType4Type7Info (&ApParams); + if (CalledStatus > Flag) { + Flag = CalledStatus; + } + + //------------------------------ + // T Y P E 16 17 19 20 + //------------------------------ + + LocateHeapParams.BufferHandle = AMD_DMI_MEM_DEV_INFO_HANDLE; + if (HeapLocateBuffer (&LocateHeapParams, StdHeader) != AGESA_SUCCESS) { + if (Flag < AGESA_ERROR) { + Flag = AGESA_ERROR; + } + } else { + NumberOfDimm = *((UINT8 *) (LocateHeapParams.BufferPtr)); + TypeDetail = *((UINT8 *) (LocateHeapParams.BufferPtr) + 1); + MemType = *((DMI_T17_MEMORY_TYPE *) ((UINT8 *) (LocateHeapParams.BufferPtr) + 6)); + MemInfo = (MEM_DMI_INFO *) ((UINT8 *) (LocateHeapParams.BufferPtr) + 6 + sizeof (DMI_T17_MEMORY_TYPE)); + // TYPE 16 + DmiBufferPtr->T16.Location = 0x03; + DmiBufferPtr->T16.Use = 0x03; + + // Gather memory information + ProcData->DmiGetMemInfo (&CpuGetMemInfo, StdHeader); + + if (CpuGetMemInfo.EccCapable) { + DmiBufferPtr->T16.MemoryErrorCorrection = Dmi16MultiBitEcc; + } else { + DmiBufferPtr->T16.MemoryErrorCorrection = Dmi16NoneErrCorrection; + } + + MaxCapacity = *((UINT32 *) ((UINT8 *) (LocateHeapParams.BufferPtr) + 2)); + // For the total size >= 2TB case, we need leave MaximumCapacity (offset 07h) to 80000000h + // and fill the size in bytes into ExtMaxCapacity (offset 0Fh). + if (MaxCapacity < 0x200000) { + DmiBufferPtr->T16.MaximumCapacity = MaxCapacity << 10; + DmiBufferPtr->T16.ExtMaxCapacity = 0; + } else { + DmiBufferPtr->T16.MaximumCapacity = 0x80000000; + DmiBufferPtr->T16.ExtMaxCapacity = (UINT64) MaxCapacity << 20; + } + + DmiBufferPtr->T16.NumberOfMemoryDevices = (UINT16) NumberOfDimm; + + // TYPE 17 + for (DimmIndex = 0; DimmIndex < NumberOfDimm; DimmIndex++) { + Socket = (MemInfo + DimmIndex)->Socket; + Channel = (MemInfo + DimmIndex)->Channel; + Dimm = (MemInfo + DimmIndex)->Dimm; + + DmiBufferPtr->T17[Socket][Channel][Dimm].TotalWidth = (MemInfo + DimmIndex)->TotalWidth; + DmiBufferPtr->T17[Socket][Channel][Dimm].DataWidth = (MemInfo + DimmIndex)->DataWidth; + DmiBufferPtr->T17[Socket][Channel][Dimm].MemorySize = (MemInfo + DimmIndex)->MemorySize; + DmiBufferPtr->T17[Socket][Channel][Dimm].FormFactor = (MemInfo + DimmIndex)->FormFactor; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceSet = 0; + + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[0] = 'D'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[1] = 'I'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[2] = 'M'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[3] = 'M'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[4] = ' '; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[5] = Dimm + 0x30; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[6] = '\0'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[7] = '\0'; + + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[0] = 'C'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[1] = 'H'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[2] = 'A'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[3] = 'N'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[4] = 'N'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[5] = 'E'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[6] = 'L'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[7] = ' '; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[8] = Channel + 0x41; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[9] = '\0'; + + DmiBufferPtr->T17[Socket][Channel][Dimm].MemoryType = MemType; + if ((MemInfo + DimmIndex)->MemorySize != 0) { + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Synchronous = 1; + if (TypeDetail == 1) { + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Registered = 1; + } else if (TypeDetail == 2) { + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Unbuffered = 1; + } else { + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Unknown = 1; + } + } + DmiBufferPtr->T17[Socket][Channel][Dimm].Speed = (MemInfo + DimmIndex)->Speed; + + DmiBufferPtr->T17[Socket][Channel][Dimm].ManufacturerIdCode = (MemInfo + DimmIndex)->ManufacturerIdCode; + + IntToString (DmiBufferPtr->T17[Socket][Channel][Dimm].SerialNumber, (MemInfo + DimmIndex)->SerialNumber, (sizeof DmiBufferPtr->T17[Socket][Channel][Dimm].SerialNumber - 1) / 2); + + LibAmdMemCopy (&DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber, &(MemInfo + DimmIndex)->PartNumber, sizeof (DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber), StdHeader); + DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber[18] = 0; + + DmiBufferPtr->T17[Socket][Channel][Dimm].Attributes = (MemInfo + DimmIndex)->Attributes; + DmiBufferPtr->T17[Socket][Channel][Dimm].ExtSize = (MemInfo + DimmIndex)->ExtSize; + DmiBufferPtr->T17[Socket][Channel][Dimm].ConfigSpeed = (MemInfo + DimmIndex)->ConfigSpeed; + + if ((MemInfo + DimmIndex)->MemorySize != 0) { + //TYPE 20 + DmiBufferPtr->T20[Socket][Channel][Dimm].StartingAddr = (MemInfo + DimmIndex)->StartingAddr; + DmiBufferPtr->T20[Socket][Channel][Dimm].EndingAddr = (MemInfo + DimmIndex)->EndingAddr; + DmiBufferPtr->T20[Socket][Channel][Dimm].PartitionRowPosition = 0xFF; + DmiBufferPtr->T20[Socket][Channel][Dimm].InterleavePosition = 0xFF; + DmiBufferPtr->T20[Socket][Channel][Dimm].InterleavedDataDepth = 0xFF; + DmiBufferPtr->T20[Socket][Channel][Dimm].ExtStartingAddr = (MemInfo + DimmIndex)->ExtStartingAddr; + DmiBufferPtr->T20[Socket][Channel][Dimm].ExtEndingAddr = (MemInfo + DimmIndex)->ExtEndingAddr; + } + } + + // TYPE 19 + DmiBufferPtr->T19.StartingAddr = 0; + DmiBufferPtr->T19.ExtStartingAddr = 0; + DmiBufferPtr->T19.ExtEndingAddr = 0; + + // If Ending Address >= 0xFFFFFFFF, update Starting Address (offset 04h) & Ending Address (offset 08h) to 0xFFFFFFFF, + // and use the Extended Starting Address (offset 0Fh) & Extended Ending Address (offset 17h) instead. + LibAmdMsrRead (TOP_MEM2, &LocalMsrRegister, StdHeader); + if (LocalMsrRegister == 0) { + LibAmdMsrRead (TOP_MEM, &LocalMsrRegister, StdHeader); + DmiBufferPtr->T19.EndingAddr = (UINT32) (LocalMsrRegister >> 10); + } else { + if ((LocalMsrRegister >> 10) >= ((UINT64) 0xFFFFFFFF)) { + DmiBufferPtr->T19.StartingAddr = 0xFFFFFFFFUL; + DmiBufferPtr->T19.EndingAddr = 0xFFFFFFFFUL; + DmiBufferPtr->T19.ExtEndingAddr = LocalMsrRegister; + } else { + DmiBufferPtr->T19.EndingAddr = (UINT32) (LocalMsrRegister >> 10); + } + } + + DmiBufferPtr->T19.PartitionWidth = 0xFF; + } + return (Flag); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * GetType4Type7Info + * + * Description: + * This routine should be run on core 0 of every socket. It creates DMI type 4 and type 7 tables. + * + * Parameters: + * @param[in] ApExeParams Handle to config for library and services. + * + * @retval AGESA_STATUS + * + * Processing: + * + */ +AGESA_STATUS +GetType4Type7Info ( + IN AP_EXE_PARAMS *ApExeParams + ) +{ + UINT8 ByteIndexInUint64; + UINT16 Index; + UINT32 SocketNum; + UINT32 IgnoredModule; + UINT32 IgnoredCore; + UINT64 MsrData; + DMI_INFO *DmiBufferPtr; + AGESA_STATUS IgnoredSts; + AGESA_STATUS Flag; + BOOLEAN FamilyNotFound; + CPUID_DATA CpuId; + CPU_TYPE_INFO CpuInfo; + PROC_FAMILY_TABLE *ProcData; + CPU_LOGICAL_ID LogicalID; + + Flag = TRUE; + DmiBufferPtr = (DMI_INFO *) ApExeParams->RelatedDataBlock; + GetLogicalIdOfCurrentCore (&LogicalID, &ApExeParams->StdHeader); + + ProcData = NULL; + FamilyNotFound = TRUE; + for (Index = 0; Index < OptionDmiConfiguration.NumEntries; Index++) { + ProcData = (PROC_FAMILY_TABLE *) ((*OptionDmiConfiguration.FamilyList)[Index]); + if ((ProcData->ProcessorFamily & LogicalID.Family) != 0) { + FamilyNotFound = FALSE; + break; + } + } + + if (FamilyNotFound) { + return AGESA_ERROR; + } + + ProcData->DmiGetCpuInfo (&CpuInfo, &ApExeParams->StdHeader); + + // ------------------------------ + // T Y P E 4 + // ------------------------------ + + IdentifyCore (&ApExeParams->StdHeader, &SocketNum, &IgnoredModule, &IgnoredCore, &IgnoredSts); + + // Type 4 Offset 0x05, Processor Type + DmiBufferPtr->T4[SocketNum].T4ProcType = CENTRAL_PROCESSOR; + + // Type 4 Offset 0x06, Processor Family + ProcData->DmiGetT4ProcFamily (&DmiBufferPtr->T4[SocketNum].T4ProcFamily, ProcData, &CpuInfo, &ApExeParams->StdHeader); + + if (DmiBufferPtr->T4[SocketNum].T4ProcFamily == P_UPGRADE_UNKNOWN) { + Flag = AGESA_ERROR; + } + + // Type4 Offset 0x08, Processor ID + LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuId, &ApExeParams->StdHeader); + DmiBufferPtr->T4[SocketNum].T4ProcId.ProcIdLsd = CpuId.EAX_Reg; + DmiBufferPtr->T4[SocketNum].T4ProcId.ProcIdMsd = CpuId.EDX_Reg; + + // Type4 Offset 0x11, Voltage + DmiBufferPtr->T4[SocketNum].T4Voltage = ProcData->DmiGetVoltage (&ApExeParams->StdHeader); + + // Type4 Offset 0x12, External Clock + DmiBufferPtr->T4[SocketNum].T4ExternalClock = ProcData->DmiGetExtClock (&ApExeParams->StdHeader); + + // Type4 Offset 0x14, Max Speed + DmiBufferPtr->T4[SocketNum].T4MaxSpeed = ProcData->DmiGetMaxSpeed (&ApExeParams->StdHeader); + + // Type4 Offset 0x16, Current Speed + DmiBufferPtr->T4[SocketNum].T4CurrentSpeed = DmiBufferPtr->T4[SocketNum].T4MaxSpeed; + + // Type4 Offset 0x18, Status + DmiBufferPtr->T4[SocketNum].T4Status = SOCKET_POPULATED | CPU_STATUS_ENABLED; + + // Type4 Offset 0x19, Processor Upgrade + DmiBufferPtr->T4[SocketNum].T4ProcUpgrade = CpuInfo.ProcUpgrade; + + // Type4 Offset 0x23, 0x24 and 0x25, Core Count, Core Enabled and Thread Count + DmiBufferPtr->T4[SocketNum].T4CoreCount = CpuInfo.TotalCoreNumber + 1; + DmiBufferPtr->T4[SocketNum].T4CoreEnabled = CpuInfo.EnabledCoreNumber + 1; + DmiBufferPtr->T4[SocketNum].T4ThreadCount = CpuInfo.EnabledCoreNumber + 1; + + // Type4 Offset 0x26, Processor Characteristics + DmiBufferPtr->T4[SocketNum].T4ProcCharacteristics = P_CHARACTERISTICS; + + // Type4 Offset 0x28, Processor Family 2 + DmiBufferPtr->T4[SocketNum].T4ProcFamily2 = DmiBufferPtr->T4[SocketNum].T4ProcFamily; + + // Type4 ProcVersion + for (Index = 0; Index <= 5; Index++) { + LibAmdMsrRead ((MSR_CPUID_NAME_STRING0 + Index), &MsrData, &ApExeParams->StdHeader); + for (ByteIndexInUint64 = 0; ByteIndexInUint64 <= 7; ByteIndexInUint64++) { + DmiBufferPtr->T4[SocketNum].T4ProcVersion[Index * 8 + ByteIndexInUint64] = (UINT8) (MsrData >> (8 * ByteIndexInUint64)); + } + } + + // Type4 Manufacturer + ASSERT (PROC_MANU_LENGTH >= sizeof (str_ProcManufacturer)); + LibAmdMemCopy (DmiBufferPtr->T4[SocketNum].T4ProcManufacturer, str_ProcManufacturer, sizeof (str_ProcManufacturer), &ApExeParams->StdHeader); + + //------------------------------ + // T Y P E 7 + //------------------------------ + + // Type7 Offset 0x05, Cache Configuration + DmiBufferPtr->T7L1[SocketNum].T7CacheCfg = CACHE_CFG_L1; + DmiBufferPtr->T7L2[SocketNum].T7CacheCfg = CACHE_CFG_L2; + DmiBufferPtr->T7L3[SocketNum].T7CacheCfg = CACHE_CFG_L3; + + // Type7 Offset 0x07 and 09, Maximum Cache Size and Installed Size + + // Maximum L1 cache size + DmiBufferPtr->T7L1[SocketNum].T7MaxCacheSize = AdjustGranularity (&CpuInfo.CacheInfo.L1CacheSize); + + // Installed L1 cache size + DmiBufferPtr->T7L1[SocketNum].T7InstallSize = DmiBufferPtr->T7L1[SocketNum].T7MaxCacheSize; + + // Maximum L2 cache size + DmiBufferPtr->T7L2[SocketNum].T7MaxCacheSize = AdjustGranularity (&CpuInfo.CacheInfo.L2CacheSize); + + // Installed L2 cache size + DmiBufferPtr->T7L2[SocketNum].T7InstallSize = DmiBufferPtr->T7L2[SocketNum].T7MaxCacheSize; + + // Maximum L3 cache size + DmiBufferPtr->T7L3[SocketNum].T7MaxCacheSize = AdjustGranularity (&CpuInfo.CacheInfo.L3CacheSize); + + // Installed L3 cache size + DmiBufferPtr->T7L3[SocketNum].T7InstallSize = DmiBufferPtr->T7L3[SocketNum].T7MaxCacheSize; + + // Type7 Offset 0x0B and 0D, Supported SRAM Type and Current SRAM Type + DmiBufferPtr->T7L1[SocketNum].T7SupportedSramType = SRAM_TYPE; + DmiBufferPtr->T7L1[SocketNum].T7CurrentSramType = SRAM_TYPE; + DmiBufferPtr->T7L2[SocketNum].T7SupportedSramType = SRAM_TYPE; + DmiBufferPtr->T7L2[SocketNum].T7CurrentSramType = SRAM_TYPE; + DmiBufferPtr->T7L3[SocketNum].T7SupportedSramType = SRAM_TYPE; + DmiBufferPtr->T7L3[SocketNum].T7CurrentSramType = SRAM_TYPE; + + // Type7 Offset 0x0F, Cache Speed + DmiBufferPtr->T7L1[SocketNum].T7CacheSpeed = 1; + DmiBufferPtr->T7L2[SocketNum].T7CacheSpeed = 1; + DmiBufferPtr->T7L3[SocketNum].T7CacheSpeed = 1; + + // Type7 Offset 0x10, Error Correction Type + DmiBufferPtr->T7L1[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE; + DmiBufferPtr->T7L2[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE; + DmiBufferPtr->T7L3[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE; + + // Type7 Offset 0x11, System Cache Type + DmiBufferPtr->T7L1[SocketNum].T7SystemCacheType = CACHE_TYPE; + DmiBufferPtr->T7L2[SocketNum].T7SystemCacheType = CACHE_TYPE; + DmiBufferPtr->T7L3[SocketNum].T7SystemCacheType = CACHE_TYPE; + + // Type7 Offset 0x12, Associativity + DmiBufferPtr->T7L1[SocketNum].T7Associativity = CpuInfo.CacheInfo.L1CacheAssoc; + DmiBufferPtr->T7L2[SocketNum].T7Associativity = CpuInfo.CacheInfo.L2CacheAssoc; + DmiBufferPtr->T7L3[SocketNum].T7Associativity = CpuInfo.CacheInfo.L3CacheAssoc; + + return (Flag); +} + +/* -----------------------------------------------------------------------------*/ +/** + * DmiGetT4ProcFamilyFromBrandId + * + * Description: + * This is the common routine for getting Type 4 processor family information from brand ID + * + * Parameters: + * @param[in, out] *T4ProcFamily Pointer to type 4 processor family information + * @param[in] *CpuDmiProcFamilyTable Pointer to DMI family special service + * @param[in] *CpuInfo Pointer to CPU_TYPE_INFO struct + * @param[in, out] *StdHeader Standard Head Pointer + * + * @retval AGESA_STATUS + * + */ +VOID +DmiGetT4ProcFamilyFromBrandId ( + IN OUT UINT8 *T4ProcFamily, + IN PROC_FAMILY_TABLE *CpuDmiProcFamilyTable, + IN CPU_TYPE_INFO *CpuInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 Index; + *T4ProcFamily = P_UPGRADE_UNKNOWN; + if (CpuInfo->BrandId.Model != P_ENGINEERING_SAMPLE) { + for (Index = 0; Index < CpuDmiProcFamilyTable->LenBrandList; Index++) { + if ((CpuDmiProcFamilyTable->DmiBrandList[Index].PackageType == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].PackageType == CpuInfo->PackageType) && + (CpuDmiProcFamilyTable->DmiBrandList[Index].PgOfBrandId == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].PgOfBrandId == CpuInfo->BrandId.Pg) && + (CpuDmiProcFamilyTable->DmiBrandList[Index].NumberOfCores == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].NumberOfCores == CpuInfo->TotalCoreNumber) && + (CpuDmiProcFamilyTable->DmiBrandList[Index].String1ofBrandId == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].String1ofBrandId == CpuInfo->BrandId.String1)) { + *T4ProcFamily = CpuDmiProcFamilyTable->DmiBrandList[Index].ValueSetToDmiTable; + break; + } + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * GetNameString + * + * Description: + * Get name string from MSR_C001_00[35:30] + * + * Parameters: + * @param[in, out] *String Pointer to name string + * @param[in, out] *StdHeader + * + */ +VOID +GetNameString ( + IN OUT CHAR8 *String, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 StringIndex; + UINT8 MsrIndex; + UINT64 MsrData; + + StringIndex = 0; + for (MsrIndex = 0; MsrIndex <= 5; MsrIndex++) { + LibAmdMsrRead ((MSR_CPUID_NAME_STRING0 + MsrIndex), &MsrData, StdHeader); + for (i = 0; i < 8; i++) { + String[StringIndex] = (CHAR8) (MsrData >> (8 * i)); + StringIndex++; + } + } + String[StringIndex] = '\0'; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * IsSourceStrContainTargetStr + * + * Description: + * check if source string contains target string. + * + * Parameters: + * @param[in, out] *SourceStr Pointer to source CHAR array + * @param[in, out] *TargetStr Pointer to target CHAR array + * @param[in, out] *StdHeader + * + * @retval TRUE Target string is contained in the source string + * @retval FALSE Target string is not contained in the source string + */ +BOOLEAN +IsSourceStrContainTargetStr ( + IN OUT CHAR8 *SourceStr, + IN OUT CONST CHAR8 *TargetStr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN IsContained; + UINT32 SourceStrIndex; + UINT32 TargetStrIndex; + CHAR8 TargetChar; + + IsContained = FALSE; + if ((TargetStr != NULL) && (SourceStr != NULL)) { + for (SourceStrIndex = 0; SourceStr[SourceStrIndex] != '\0'; SourceStrIndex++) { + // Compare TrgString with SrcString from frist charactor to the '\0' + for (TargetStrIndex = 0; TargetStr[TargetStrIndex] != '\0'; TargetStrIndex++) { + if (TargetStr[TargetStrIndex] != SourceStr[SourceStrIndex + TargetStrIndex]) { + // if it's not match, try to check the upcase/lowcase + TargetChar = 0; + if (TargetStr[TargetStrIndex] >= 'a' && TargetStr[TargetStrIndex] <= 'z') { + TargetChar = TargetStr[TargetStrIndex] - ('a' - 'A'); + } else if (TargetStr[TargetStrIndex] >= 'A' && TargetStr[TargetStrIndex] <= 'Z') { + TargetChar = TargetStr[TargetStrIndex] + ('a' - 'A'); + } + // compare again + if (TargetChar != SourceStr[SourceStrIndex + TargetStrIndex]) { + break; + } + } + } + + if ((TargetStr[TargetStrIndex] == '\0') && (TargetStrIndex != 0)) { + IsContained = TRUE; + break; + } + } + } + return IsContained; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * AdjustGranularity + * + * Description: + * If cache size is greater than or equal to 32M, then set granularity + * to 64K. otherwise, set granularity to 1K + * + * Parameters: + * @param[in] *CacheSizePtr + * + * @retval CacheSize + * + * Processing: + * + */ +UINT16 +STATIC +AdjustGranularity ( + IN UINT32 *CacheSizePtr + ) +{ + UINT16 CacheSize; + + if (*CacheSizePtr >= 0x8000) { + CacheSize = (UINT16) (*CacheSizePtr / 64); + CacheSize |= 0x8000; + } else { + CacheSize = (UINT16) *CacheSizePtr; + } + + return (CacheSize); +} + +/* -----------------------------------------------------------------------------*/ +/** + * ReleaseDmiBufferStub + * + * Description: + * This is the default routine for use when the DMI option is NOT requested. + * + * Parameters: + * @param[in, out] *StdHeader + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +ReleaseDmiBufferStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + return AGESA_UNSUPPORTED; +} + +/* -----------------------------------------------------------------------------*/ +/** + * ReleaseDmiBuffer + * + * Description: + * Deallocate DMI buffer + * + * Parameters: + * @param[in, out] *StdHeader + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +ReleaseDmiBuffer ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + HeapDeallocateBuffer ((UINT32) AMD_DMI_MEM_DEV_INFO_HANDLE, StdHeader); + + return AGESA_SUCCESS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * IntToString + * + * Description: + * Translate UINT array to CHAR array. + * + * Parameters: + * @param[in, out] *String Pointer to CHAR array + * @param[in] *Integer Pointer to UINT array + * @param[in] SizeInByte The size of UINT array + * + * Processing: + * + */ +VOID +STATIC +IntToString ( + IN OUT CHAR8 *String, + IN UINT8 *Integer, + IN UINT8 SizeInByte + ) +{ + UINT8 Index; + + for (Index = 0; Index < SizeInByte; Index++) { + *(String + Index * 2) = (*(Integer + Index) >> 4) & 0x0F; + *(String + Index * 2 + 1) = *(Integer + Index) & 0x0F; + } + for (Index = 0; Index < (SizeInByte * 2); Index++) { + if (*(String + Index) >= 0x0A) { + *(String + Index) += 0x37; + } else { + *(String + Index) += 0x30; + } + } + *(String + SizeInByte * 2) = 0x0; +} + |