diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Haswell/CpuInit/Dxe/CacheData.c | |
download | zprj-master.tar.xz |
Diffstat (limited to 'ReferenceCode/Haswell/CpuInit/Dxe/CacheData.c')
-rw-r--r-- | ReferenceCode/Haswell/CpuInit/Dxe/CacheData.c | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/CpuInit/Dxe/CacheData.c b/ReferenceCode/Haswell/CpuInit/Dxe/CacheData.c new file mode 100644 index 0000000..f68c151 --- /dev/null +++ b/ReferenceCode/Haswell/CpuInit/Dxe/CacheData.c @@ -0,0 +1,515 @@ +/** @file + Processor Cache data records. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ + +/// +/// External include files do NOT need to be explicitly specified in real EDKII +/// environment +/// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "CpuAccess.h" +#include "CacheData.h" +#endif +/// +/// This is the VFR compiler generated header file which defines the +/// string identifiers. +/// +#include "CpuInitDxeStrDefs.h" + +extern EFI_DATA_HUB_PROTOCOL *mDataHub; +extern EFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader; + +EFI_CACHE_CONVERTER mCacheConverter[] = { + { + 1, + 0x09, + 32, + EfiCacheAssociativity4Way, + EfiCacheTypeInstruction + }, + { + 1, + 0x0D, + 16, + EfiCacheAssociativity4Way, + EfiCacheTypeData + }, + { + 2, + 0x21, + 256, + EfiCacheAssociativity8Way, + EfiCacheTypeUnified + }, + { + 1, + 0x2C, + 32, + EfiCacheAssociativity8Way, + EfiCacheTypeData + }, + { + 2, + 0x40, + 0, + EfiCacheAssociativityUnknown, + EfiCacheTypeUnknown + }, + { + 3, + 0xD0, + 512, + EfiCacheAssociativity4Way, + EfiCacheTypeUnified + }, + { + 3, + 0xD1, + 1024, + EfiCacheAssociativity4Way, + EfiCacheTypeUnified + }, + { + 3, + 0xD2, + 2048, + EfiCacheAssociativity4Way, + EfiCacheTypeUnified + }, + { + 3, + 0xD3, + 4096, + EfiCacheAssociativity4Way, + EfiCacheTypeUnified + }, + { + 3, + 0xD4, + 8192, + EfiCacheAssociativity4Way, + EfiCacheTypeUnified + }, + { + 3, + 0xD6, + 1024, + EfiCacheAssociativity8Way, + EfiCacheTypeUnified + }, + { + 3, + 0xD7, + 2048, + EfiCacheAssociativity8Way, + EfiCacheTypeUnified + }, + { + 3, + 0xD8, + 4096, + EfiCacheAssociativity8Way, + EfiCacheTypeUnified + }, + { + 3, + 0xD9, + 8192, + EfiCacheAssociativity8Way, + EfiCacheTypeUnified + }, + { + 3, + 0xDA, + 12288, + EfiCacheAssociativity8Way, + EfiCacheTypeUnified + }, + { + 3, + 0xDC, + 1536, + EfiCacheAssociativity12Way, + EfiCacheTypeUnified + }, + { + 3, + 0xDD, + 3072, + EfiCacheAssociativity12Way, + EfiCacheTypeUnified + }, + { + 3, + 0xDE, + 6144, + EfiCacheAssociativity12Way, + EfiCacheTypeUnified + }, + { + 3, + 0xDF, + 12288, + EfiCacheAssociativity12Way, + EfiCacheTypeUnified + }, + { + 3, + 0xE0, + 18432, + EfiCacheAssociativity12Way, + EfiCacheTypeUnified + }, + { + 3, + 0xE2, + 2048, + EfiCacheAssociativity16Way, + EfiCacheTypeUnified + }, + { + 3, + 0xE3, + 4096, + EfiCacheAssociativity16Way, + EfiCacheTypeUnified + }, + { + 3, + 0xE4, + 8192, + EfiCacheAssociativity16Way, + EfiCacheTypeUnified + }, + { + 3, + 0xE5, + 16384, + EfiCacheAssociativity16Way, + EfiCacheTypeUnified + }, + { + 3, + 0xE6, + 24576, + EfiCacheAssociativity16Way, + EfiCacheTypeUnified + }, + { + 3, + 0xEA, + 12288, + EfiCacheAssociativity24Way, + EfiCacheTypeUnified + }, + { + 3, + 0xEB, + 18432, + EfiCacheAssociativity24Way, + EfiCacheTypeUnified + }, + { + 3, + 0xEC, + 24567, + EfiCacheAssociativity24Way, + EfiCacheTypeUnified + }, + { + 0, + 0xFF, + 0, + 0, + 0 + } +}; + +/// +/// Convert Cache Type Field to SMBIOS format +/// +#define SMBIOS_CACHE_TYPE_MAX 5 +UINT8 SmbiosCacheTypeFieldConverter[SMBIOS_CACHE_TYPE_MAX] = { + EfiCacheTypeUnknown, + EfiCacheTypeData, + EfiCacheTypeInstruction, + EfiCacheTypeUnified, + EfiCacheTypeOther +}; + +UINT8 mCacheInstance[EFI_CACHE_LMAX] = { 0, 0, 0, 0 }; + +EFI_SUBCLASS_TYPE1_HEADER mCacheDataRecordHeader = { + EFI_CACHE_SUBCLASS_VERSION, ///< Version + sizeof (EFI_SUBCLASS_TYPE1_HEADER), ///< Header Size + 0, ///< Instance, Initialize later + 0, ///< SubInstance, Initialize later to Cache Level + 0 ///< RecordType, Initialize later +}; + +/** + This function gets called with the processor number and will log all cache data to data hub + pertaining to this processor. + + @param[in] CpuNumber - Processor Number + @param[in] CacheInformation - Cache information get from cpuid instruction + + @retval EFI_OUT_OF_RESOURCES - Failed to allocate required POOL for record buffer. + @retval EFI_SUCCESS - successful to update cache data +**/ +EFI_STATUS +InitializeCacheData ( + IN UINTN CpuNumber, + IN EFI_CPUID_REGISTER *CacheInformation + ) +{ + EFI_STATUS Status; + UINT32 HeaderSize; + UINT32 TotalSize; + CPU_CACHE_DATA_RECORD_BUFFER RecordBuffer; + UINT8 Index1; + UINT8 CacheLevel; + UINT8 LxCacheType; + UINT32 Ways; + UINT32 Partitions; + UINT32 LineSets; + UINT32 Sets; + UINT32 LxCacheSize; + EFI_CPUID_REGISTER CpuidRegisters; + + /// + /// Only log CPU socket level information. + /// + if (CpuNumber != 0) { + return EFI_SUCCESS; + } + + mCacheDataRecordHeader.Instance = (UINT16) (CpuNumber + 1); + + HeaderSize = sizeof (EFI_SUBCLASS_TYPE1_HEADER); + RecordBuffer.Raw = AllocatePool (HeaderSize + CPU_CACHE_DATA_MAXIMUM_LENGTH); + if (RecordBuffer.Raw == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index1 = 0;; Index1++) { + EfiCpuidExt (CPUID_CACHE_PARAMS, Index1, &CpuidRegisters); + if ((CpuidRegisters.RegEax & V_CPUID_CACHE_TYPE_MASK) == 0) { + break; + } + + Ways = ((CpuidRegisters.RegEbx >> B_CPUID_CACHE_PARAMS_WAYS_SHIFT) & 0x3FF) + 1; + Partitions = ((CpuidRegisters.RegEbx >> B_CPUID_CACHE_PARAMS_PARTITIONS_SHIFT) & 0x3FF) + 1; + LineSets = (CpuidRegisters.RegEbx & 0xFFF) + 1; + Sets = CpuidRegisters.RegEcx + 1; + + CacheLevel = (UINT8) (CpuidRegisters.RegEax & V_CPUID_CACHE_LEVEL_MASK) >> B_CPUID_CACHE_LEVEL_SHIFT; + LxCacheSize = (Ways * Partitions * LineSets * Sets) / 1024; + LxCacheType = (UINT8) (CpuidRegisters.RegEax & V_CPUID_CACHE_TYPE_MASK); + + CopyMem (RecordBuffer.Raw, &mCacheDataRecordHeader, HeaderSize); + + mCacheInstance[CacheLevel - 1]++; + RecordBuffer.DataRecord->DataRecordHeader.Instance = mCacheInstance[CacheLevel - 1]; + RecordBuffer.DataRecord->DataRecordHeader.SubInstance = CacheLevel; + + /// + /// Record Type 1 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheSizeRecordType; + TotalSize = HeaderSize + sizeof (EFI_CACHE_SIZE_DATA); + RecordBuffer.DataRecord->VariableRecord.CacheSize.Value = (UINT16) LxCacheSize; + RecordBuffer.DataRecord->VariableRecord.CacheSize.Exponent = 10; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 2 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = MaximumSizeCacheRecordType; + TotalSize = HeaderSize + sizeof (EFI_MAXIMUM_CACHE_SIZE_DATA); + RecordBuffer.DataRecord->VariableRecord.MaximumCacheSize.Value = (UINT16) LxCacheSize; + RecordBuffer.DataRecord->VariableRecord.MaximumCacheSize.Exponent = 10; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 3 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheSpeedRecordType; + TotalSize = HeaderSize + sizeof (EFI_CACHE_SPEED_DATA); + RecordBuffer.DataRecord->VariableRecord.CacheSpeed.Exponent = 0; + RecordBuffer.DataRecord->VariableRecord.CacheSpeed.Value = 0; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 4 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheSocketRecordType; + TotalSize = HeaderSize + sizeof (EFI_CACHE_SOCKET_DATA); + RecordBuffer.DataRecord->VariableRecord.CacheSocket = 0; + /// + /// CacheDesignation[Index1]; + /// + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 5 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheSramTypeRecordType; + TotalSize = HeaderSize + sizeof (EFI_CACHE_SRAM_TYPE_DATA); + ZeroMem ( + &RecordBuffer.DataRecord->VariableRecord.CacheSramType, + sizeof (EFI_CACHE_SRAM_TYPE_DATA) + ); + RecordBuffer.DataRecord->VariableRecord.CacheSramType.Synchronous = TRUE; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 6, since record same as Type 5 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheInstalledSramTypeRecordType; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 7 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheErrorTypeRecordType; + TotalSize = HeaderSize + sizeof (EFI_CACHE_ERROR_TYPE_DATA); + RecordBuffer.DataRecord->VariableRecord.CacheErrorType = EfiCacheErrorSingleBit; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 8 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheTypeRecordType; + TotalSize = HeaderSize + sizeof (EFI_CACHE_TYPE_DATA); + /// + /// If cache type is larger or equal than 5, this is undefined type so mark it as "Other" Cache type. + /// + if (LxCacheType >= SMBIOS_CACHE_TYPE_MAX) { + LxCacheType = SMBIOS_CACHE_TYPE_MAX - 1; + } + RecordBuffer.DataRecord->VariableRecord.CacheType = SmbiosCacheTypeFieldConverter[LxCacheType]; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 9 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheAssociativityRecordType; + TotalSize = HeaderSize + sizeof (EFI_CACHE_ASSOCIATIVITY_DATA); + /// + /// Convert Associativity Ways to SMBIOS format + /// + switch (Ways) { + case 2: + Ways = EfiCacheAssociativity2Way; + break; + case 4: + Ways = EfiCacheAssociativity4Way; + break; + case 8: + Ways = EfiCacheAssociativity8Way; + break; + case 12: + Ways = EfiCacheAssociativity12Way; + break; + case 16: + Ways = EfiCacheAssociativity16Way; + break; + case 24: + Ways = EfiCacheAssociativity24Way; + break; + case 32: + Ways = EfiCacheAssociativity32Way; + break; + case 48: + Ways = EfiCacheAssociativity48Way; + break; + case 64: + Ways = EfiCacheAssociativity64Way; + break; + default: + Ways = EfiCacheAssociativityOther; + break; + } + RecordBuffer.DataRecord->VariableRecord.CacheAssociativity = Ways; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Record Type 10 + /// + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheConfigRecordType; + TotalSize = HeaderSize + sizeof (EFI_CACHE_CONFIGURATION_DATA); + RecordBuffer.DataRecord->VariableRecord.CacheConfig.Level = CacheLevel; + RecordBuffer.DataRecord->VariableRecord.CacheConfig.Socketed = EFI_CACHE_NOT_SOCKETED; + RecordBuffer.DataRecord->VariableRecord.CacheConfig.Reserved2 = 0; + RecordBuffer.DataRecord->VariableRecord.CacheConfig.Location = EfiCacheInternal; + RecordBuffer.DataRecord->VariableRecord.CacheConfig.Enable = EFI_CACHE_ENABLED; + RecordBuffer.DataRecord->VariableRecord.CacheConfig.OperationalMode = EfiCacheWriteBack; + RecordBuffer.DataRecord->VariableRecord.CacheConfig.Reserved1 = 0; + Status = LogCacheData (mDataHub, RecordBuffer.Raw, TotalSize); + + /// + /// Cache Association. Processor Record Type 17 + /// + TotalSize = HeaderSize + sizeof (EFI_CACHE_ASSOCIATION_DATA); + RecordBuffer.DataRecord->VariableRecord.CacheAssociation.ProducerName = gEfiProcessorProducerGuid; + /// + /// RecordBuffer.DataRecord->VariableRecord.CacheAssociation.ProducerInstance = (UINT16)Instance; + /// + RecordBuffer.DataRecord->VariableRecord.CacheAssociation.Instance = RecordBuffer.DataRecord->DataRecordHeader.Instance; + RecordBuffer.DataRecord->VariableRecord.CacheAssociation.SubInstance = RecordBuffer.DataRecord->DataRecordHeader.SubInstance; + CopyMem (RecordBuffer.Raw, &mCpuDataRecordHeader, HeaderSize); + RecordBuffer.DataRecord->DataRecordHeader.RecordType = CacheAssociationRecordType; + Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize); + } + + FreePool (RecordBuffer.Raw); + return EFI_SUCCESS; +} + +/** + Log cache data into data hub + + @param[in] DataHub - Pointer to the DataHub protocol that will be updated + @param[in] Buffer - Data buffer which will be updated into DataHub + @param[in] Size - The size of data buffer + + @retval EFI_STATUS - status code for logging data into dat hub +**/ +EFI_STATUS +LogCacheData ( + EFI_DATA_HUB_PROTOCOL *DataHub, + UINT8 *Buffer, + UINT32 Size + ) +{ + EFI_STATUS Status; + + Status = DataHub->LogData ( + DataHub, + &gEfiCacheSubClassGuid, + &gEfiProcessorProducerGuid, + EFI_DATA_RECORD_CLASS_DATA, + Buffer, + Size + ); + return Status; +} |