summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/CpuInit/Dxe/ProcessorData.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Haswell/CpuInit/Dxe/ProcessorData.c')
-rw-r--r--ReferenceCode/Haswell/CpuInit/Dxe/ProcessorData.c795
1 files changed, 795 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/CpuInit/Dxe/ProcessorData.c b/ReferenceCode/Haswell/CpuInit/Dxe/ProcessorData.c
new file mode 100644
index 0000000..f3a47a5
--- /dev/null
+++ b/ReferenceCode/Haswell/CpuInit/Dxe/ProcessorData.c
@@ -0,0 +1,795 @@
+/** @file
+ Produces CPU data records.
+
+Revision History
+
+@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
+
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "ProcessorData.h"
+#include "MpCommon.h"
+#include "MpService.h"
+
+///
+/// This is the VFR compiler generated header file which defines the
+/// string identifiers.
+///
+#include "CpuInitDxeStrDefs.h"
+
+#endif
+
+extern MP_SYSTEM_DATA *mMPSystemData;
+extern DXE_CPU_PLATFORM_POLICY_PROTOCOL *mPlatformCpu;
+
+#if (EFI_SPECIFICATION_VERSION < 0x2000A)
+extern EFI_HII_PROTOCOL *mHii;
+#endif
+extern EFI_DATA_HUB_PROTOCOL *mDataHub;
+extern DXE_CPU_PLATFORM_POLICY_PROTOCOL *mPlatformCpu;
+extern EFI_HII_HANDLE mStringHandle;
+
+EFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader = {
+ EFI_PROCESSOR_SUBCLASS_VERSION, ///< Version
+ sizeof (EFI_SUBCLASS_TYPE1_HEADER), ///< Header Size
+ 0, ///< Instance, Initialize later
+ EFI_SUBCLASS_INSTANCE_NON_APPLICABLE, ///< SubInstance
+ 0 ///< RecordType, Initialize later
+};
+
+EFI_STATUS
+LogCpuData (
+ EFI_DATA_HUB_PROTOCOL *DataHub,
+ UINT8 *Buffer,
+ UINT32 Size
+ );
+
+typedef struct _PROCESSOR_FAMILY_FIELD {
+ CHAR8 ProcessorFamily[48];
+ UINT16 ProcessorEnum;
+} PROCESSOR_FAMILY_FIELD;
+
+PROCESSOR_FAMILY_FIELD ProcessorFamilyField[] = {
+ {
+ "Intel(R) Core(TM) i7",
+ 0xC6
+ },
+ {
+ "Intel(R) Core(TM) i5",
+ 0xCD
+ },
+ {
+ "Intel(R) Core(TM) i3",
+ 0xCE
+ },
+ {
+ "Intel(R) Xeon(R) CPU",
+ 0xB3
+ },
+ {
+ "Intel(R) Pentium(R) CPU",
+ 0x0B
+ },
+ {
+ "Intel(R) Celeron(R) CPU",
+ 0x0F
+ },
+};
+
+/**
+ Converts an ascii string to unicode string 16 chars at a time.
+
+ @param[in] AsciiString - Pointer to input Ascii string.
+ @param[in] UnicodeString - Pointer to output Unicode string buffer.
+**/
+VOID
+AsciiToUnicode (
+ IN CHAR8 *AsciiString,
+ IN OUT CHAR16 *UnicodeString
+ )
+{
+ UINT8 Index;
+
+ for (Index = 0; Index < 16; Index++) {
+ UnicodeString[Index] = (CHAR16) AsciiString[Index];
+ }
+
+ return;
+}
+///
+/// Processor-specific routines
+///
+/**
+ Returns the procesor version string token installed in the system.
+
+ @retval Processor Version string token
+**/
+VOID
+GetProcessorVersion (
+ OUT PROCESSOR_VERSION_INFORMATION *Version
+ )
+{
+ CHAR16 BrandIdString[MAXIMUM_CPU_BRAND_STRING_LENGTH + 1];
+ EFI_CPUID_REGISTER CpuExtendedSupport;
+ EFI_CPUID_REGISTER CpuBrandString;
+ UINT8 Index;
+
+ ///
+ /// Create the string using Brand ID String.
+ ///
+ Version->StringValid = FALSE;
+
+ if (IsIntelProcessor ()) {
+ Version->StringRef = STRING_TOKEN (STR_INTEL_GENUINE_PROCESSOR);
+
+ AsmCpuid (
+ CPUID_EXTENDED_FUNCTION,
+ &CpuExtendedSupport.RegEax,
+ &CpuExtendedSupport.RegEbx,
+ &CpuExtendedSupport.RegEcx,
+ &CpuExtendedSupport.RegEdx
+ );
+ AsmCpuid (
+ CPUID_BRAND_STRING1,
+ &CpuBrandString.RegEax,
+ &CpuBrandString.RegEbx,
+ &CpuBrandString.RegEcx,
+ &CpuBrandString.RegEdx
+ );
+ ///
+ /// Check if Brand ID String is supported or filled up
+ ///
+ if (CpuExtendedSupport.RegEax != 0 && CpuBrandString.RegEax != 0) {
+ AsciiToUnicode ((CHAR8 *) &CpuBrandString, (CHAR16 *) &BrandIdString[0]);
+ AsmCpuid (
+ CPUID_BRAND_STRING2,
+ &CpuBrandString.RegEax,
+ &CpuBrandString.RegEbx,
+ &CpuBrandString.RegEcx,
+ &CpuBrandString.RegEdx
+ );
+ AsciiToUnicode ((CHAR8 *) &CpuBrandString, (CHAR16 *) &BrandIdString[16]);
+ AsmCpuid (
+ CPUID_BRAND_STRING3,
+ &CpuBrandString.RegEax,
+ &CpuBrandString.RegEbx,
+ &CpuBrandString.RegEcx,
+ &CpuBrandString.RegEdx
+ );
+ AsciiToUnicode ((CHAR8 *) &CpuBrandString, (CHAR16 *) &BrandIdString[32]);
+
+ ///
+ /// Remove preceeding spaces
+ ///
+ Index = 0;
+ while (BrandIdString[Index] == 0x20) {
+ Index++;
+ if (Index >= MAXIMUM_CPU_BRAND_STRING_LENGTH) {
+ break;
+ }
+ }
+
+ CopyMem (
+ Version->BrandString,
+ &BrandIdString[Index],
+ (MAXIMUM_CPU_BRAND_STRING_LENGTH - Index) * sizeof (CHAR16)
+ );
+ Version->BrandString[MAXIMUM_CPU_BRAND_STRING_LENGTH - Index] = 0;
+ Version->StringValid = TRUE;
+ }
+ } else {
+ Version->StringRef = STRING_TOKEN (STR_UNKNOWN);
+ }
+}
+
+/**
+ Returns the procesor manufaturer string token installed in the system.
+
+ @retval Processor Manufacturer string token
+**/
+EFI_PROCESSOR_MANUFACTURER_DATA
+GetProcessorManufacturer (
+ VOID
+ )
+{
+
+ if (IsIntelProcessor ()) {
+ return STRING_TOKEN (STR_INTEL_CORPORATION);
+ } else {
+ return STRING_TOKEN (STR_UNKNOWN);
+ }
+}
+
+/**
+ Returns if processor is Intel or not.
+
+ @retval TRUE - Intel Processor.
+ @retval FALSE - Not Intel Processor.
+**/
+BOOLEAN
+IsIntelProcessor (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Reg;
+
+ AsmCpuid (CPUID_SIGNATURE, &Reg.RegEax, &Reg.RegEbx, &Reg.RegEcx, &Reg.RegEdx);
+
+ if ((Reg.RegEbx != 'uneG') || (Reg.RegEdx != 'Ieni') || (Reg.RegEcx != 'letn')) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/**
+ Returns the processor family of the processor installed in the system.
+
+ @retval Processor Family
+**/
+EFI_PROCESSOR_FAMILY_DATA
+GetProcessorFamily (
+ VOID
+ )
+{
+
+ UINTN j;
+ UINTN Index;
+ EFI_CPUID_REGISTER CpuExtendedSupport;
+ EFI_CPUID_REGISTER CpuBrandString;
+ CHAR8 BrandString[MAXIMUM_CPU_BRAND_STRING_LENGTH + 1];
+ UINT16 ProcessorFamily;
+ ProcessorFamily = EfiProcessorFamilyUnknown;
+ Index = 0;
+
+ if (IsIntelProcessor ()) {
+ ///
+ /// Get Brand string
+ ///
+ AsmCpuid (
+ CPUID_EXTENDED_FUNCTION,
+ &CpuExtendedSupport.RegEax,
+ &CpuExtendedSupport.RegEbx,
+ &CpuExtendedSupport.RegEcx,
+ &CpuExtendedSupport.RegEdx
+ );
+ AsmCpuid (
+ CPUID_BRAND_STRING1,
+ &CpuBrandString.RegEax,
+ &CpuBrandString.RegEbx,
+ &CpuBrandString.RegEcx,
+ &CpuBrandString.RegEdx
+ );
+
+ if (CpuExtendedSupport.RegEax != 0 && CpuBrandString.RegEax != 0) {
+ EfiAsciiStrCpy (&BrandString[0], (CHAR8 *) &CpuBrandString);
+ AsmCpuid (
+ CPUID_BRAND_STRING2,
+ &CpuBrandString.RegEax,
+ &CpuBrandString.RegEbx,
+ &CpuBrandString.RegEcx,
+ &CpuBrandString.RegEdx
+ );
+ EfiAsciiStrCpy (&BrandString[16], (CHAR8 *) &CpuBrandString);
+ AsmCpuid (
+ CPUID_BRAND_STRING3,
+ &CpuBrandString.RegEax,
+ &CpuBrandString.RegEbx,
+ &CpuBrandString.RegEcx,
+ &CpuBrandString.RegEdx
+ );
+ EfiAsciiStrCpy (&BrandString[32], (CHAR8 *) &CpuBrandString);
+
+ ///
+ /// Remove preceeding spaces
+ ///
+ while (BrandString[Index] == 0x20) {
+ Index++;
+ }
+
+ BrandString[MAXIMUM_CPU_BRAND_STRING_LENGTH - Index] = 0;
+ }
+
+ ProcessorFamily = 0xC6;
+
+ for (j = 0; j < sizeof (ProcessorFamilyField) / sizeof (PROCESSOR_FAMILY_FIELD); j++) {
+ if (EfiAsciiStrnCmp (
+ &BrandString[Index],
+ ProcessorFamilyField[j].ProcessorFamily,
+ (EfiAsciiStrLen (ProcessorFamilyField[j].ProcessorFamily))
+ ) == 0) {
+ ProcessorFamily = ProcessorFamilyField[j].ProcessorEnum;
+ break;
+ }
+ }
+ } else {
+ ProcessorFamily = EfiProcessorFamilyOther;
+ }
+
+ return ProcessorFamily;
+}
+
+/**
+ Returns the processor voltage of the processor installed in the system.
+
+ @retval Processor Voltage
+**/
+INT16
+GetProcessorVoltage (
+ VOID
+ )
+{
+ INT16 VoltageInmV;
+ UINT64 MsrValue;
+
+ VoltageInmV = 0;
+ MsrValue = 0;
+
+ ///
+ /// Core voltage = (float) IA32_PERF_STS(47:32) * (float) 1/(2^13)
+ ///
+ MsrValue = AsmReadMsr64 (MSR_IA32_PERF_STS);
+ MsrValue = RShiftU64(MsrValue, 32);
+ MsrValue &= 0x0FFFF;
+
+ ///
+ /// Convert unit to mV
+ ///
+ MsrValue = MultU64x32(MsrValue, 1000);
+ MsrValue = RShiftU64 (MsrValue, 13);
+ VoltageInmV = (UINT16) MsrValue;
+
+ return VoltageInmV;
+}
+
+/**
+ Returns the processor microcode revision of the processor installed in the system.
+
+ @retval Processor Microcode Revision
+**/
+UINT32
+GetCpuUcodeRevision (
+ VOID
+ )
+{
+ AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
+ EfiCpuid (CPUID_VERSION_INFO, NULL);
+ return (UINT32) RShiftU64 (AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID), 32);
+}
+
+/**
+ Get processor status by specific CPU number
+
+ @param[in] CpuNumber - indicate which CPU status are requested
+
+ @retval EFI_PROCESSOR_STATUS_DATA for specific CPU number
+**/
+EFI_PROCESSOR_STATUS_DATA
+GetProcessorStatus (
+ IN UINTN CpuNumber
+ )
+{
+ EFI_PROCESSOR_STATUS_DATA ProcessorStatus;
+ CPU_DATA_BLOCK *CpuData;
+
+ CpuData = &mMPSystemData->CpuData[CpuNumber];
+
+ ProcessorStatus.Reserved1 = 0;
+ ProcessorStatus.Reserved2 = 0;
+ ProcessorStatus.Reserved3 = 0;
+
+ ProcessorStatus.CpuStatus = EfiCpuStatusEnabled;
+ if (CpuData->State == CPU_STATE_DISABLED) {
+ switch (mMPSystemData->DisableCause[CpuNumber]) {
+ case CPU_CAUSE_USER_SELECTION:
+ case CPU_CAUSE_BY_ASSOCIATION:
+ ProcessorStatus.CpuStatus = EfiCpuStatusDisabledByUser;
+ break;
+
+ case CPU_CAUSE_INTERNAL_ERROR:
+ case CPU_CAUSE_THERMAL_ERROR:
+ case CPU_CAUSE_SELFTEST_FAILURE:
+ case CPU_CAUSE_PREBOOT_TIMEOUT:
+ case CPU_CAUSE_CONFIG_ERROR:
+ ProcessorStatus.CpuStatus = EfiCpuStatusDisabledbyBios;
+ break;
+
+ case CPU_CAUSE_FAILED_TO_START:
+ case CPU_CAUSE_UNSPECIFIED:
+ default:
+ ProcessorStatus.CpuStatus = EfiCpuStatusOther;
+ break;
+ }
+ }
+
+ ProcessorStatus.SocketPopulated = TRUE;
+ ProcessorStatus.ApicEnable = 1;
+
+ if (mMPSystemData->BSP == CpuNumber) {
+ ProcessorStatus.BootApplicationProcessor = 1;
+ } else {
+ ProcessorStatus.BootApplicationProcessor = 0;
+ }
+
+ return ProcessorStatus;
+}
+
+/**
+ This function gets called with the processor number and will log all data to data hub
+ pertaining to this processor.
+
+ @param[in] CpuNumber - Processor Number
+ @param[in] CpuDataForDatahub - Contains CPU data which is collected for data hub
+
+ @retval EFI_OUT_OF_RESOURCES - failed to allocate pool for CPU data
+ @retval EFI_SUCCESS - CPU data Hub has been created successfully
+**/
+EFI_STATUS
+InitializeProcessorData (
+ IN UINTN CpuNumber,
+ IN CPU_DATA_FOR_DATAHUB *CpuDataForDatahub
+ )
+{
+ EFI_STATUS Status;
+ EFI_CPU_DATA_RECORD_BUFFER RecordBuffer;
+ UINT32 HeaderSize;
+ UINT32 TotalSize;
+ PLATFORM_CPU_INFORMATION PlatformCpuInfo;
+ STRING_REF Token;
+ UINT64 MsrValue;
+ UINT64 ProcessorCoreCount;
+ UINT64 ProcessorThreadCount;
+
+ mCpuDataRecordHeader.Instance = (UINT16) (CpuNumber + 1);
+
+ HeaderSize = sizeof (EFI_SUBCLASS_TYPE1_HEADER);
+ RecordBuffer.Raw = AllocatePool (HeaderSize + EFI_CPU_DATA_MAXIMUM_LENGTH);
+ if (RecordBuffer.Raw == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (&PlatformCpuInfo, sizeof (PLATFORM_CPU_INFORMATION));
+ CopyMem (RecordBuffer.Raw, &mCpuDataRecordHeader, HeaderSize);
+
+ ///
+ /// Record following data by socket base
+ ///
+ if (CpuNumber == 0) {
+ ///
+ /// Record Type 1
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorCoreFrequencyRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Value = (UINT16) CpuDataForDatahub->IntendCoreFrequency;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Exponent = 6;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_CORE_FREQUENCY_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 2
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorFsbFrequencyRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorFsbFrequency.Value = 100;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorFsbFrequency.Exponent = 6;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_FSB_FREQUENCY_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 3
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorVersionRecordType;
+ if (CpuDataForDatahub->Version.StringValid) {
+ Token = 0;
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ Status = IfrLibNewString (mStringHandle, &Token, CpuDataForDatahub->Version.BrandString);
+#else
+ Status = mHii->NewString (mHii, NULL, mStringHandle, &Token, CpuDataForDatahub->Version.BrandString);
+#endif
+ if (EFI_ERROR (Status)) {
+ Token = CpuDataForDatahub->Version.StringRef;
+ }
+ } else {
+ Token = CpuDataForDatahub->Version.StringRef;
+ }
+
+ RecordBuffer.DataRecord->VariableRecord.ProcessorVersion = Token;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_VERSION_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 4
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorManufacturerRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorManufacturer = CpuDataForDatahub->Manufacturer;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_MANUFACTURER_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 6.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorIdRecordType;
+ CopyMem (
+ &RecordBuffer.DataRecord->VariableRecord.ProcessorId,
+ &CpuDataForDatahub->CpuidData,
+ sizeof (CpuDataForDatahub->CpuidData)
+ );
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_ID_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 7.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorTypeRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorType = EfiCentralProcessor;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_TYPE_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 8.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorFamilyRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorFamily = CpuDataForDatahub->Family;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_FAMILY_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 9.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorVoltageRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorVoltage.Value = CpuDataForDatahub->Voltage;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorVoltage.Exponent = -3;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_VOLTAGE_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+ }
+ ///
+ /// log data by socket base
+ ///
+ /// Record Type 10.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorApicBaseAddressRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorApicBase = CpuDataForDatahub->ApicBase;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_APIC_BASE_ADDRESS_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 11.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorApicIdRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorApicId = CpuDataForDatahub->ApicID;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_APIC_ID_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 12.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorApicVersionNumberRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorApicVersionNumber = CpuDataForDatahub->ApicVersion;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_APIC_VERSION_NUMBER_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 13.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = CpuUcodeRevisionDataRecordType;
+ RecordBuffer.DataRecord->VariableRecord.CpuUcodeRevisionData.ProcessorMicrocodeType = EfiProcessorIa32Microcode;
+ RecordBuffer.DataRecord->VariableRecord.CpuUcodeRevisionData.ProcessorMicrocodeRevisionNumber = CpuDataForDatahub->MicrocodeRevision;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_MICROCODE_REVISION_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record following data by socket base
+ ///
+ if (CpuNumber == 0) {
+ ///
+ /// Record Type 14.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorStatusRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorStatus = CpuDataForDatahub->Status;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_STATUS_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 17(0x11). Set in Cache File
+ ///
+ ///
+ /// Record Type 21(0x15). zero based
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorPackageNumberRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorPackageNumber = CpuDataForDatahub->Location.Package;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_PACKAGE_NUMBER_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 24(0x18).
+ /// Health definition in DataHub spec is not the same as BIST format, so add 1 to convert
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorHealthStatusRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorHealthStatus = CpuDataForDatahub->Health.Uint32 + 1;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_HEALTH_STATUS);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+ }
+ ///
+ /// log data by socket base
+ ///
+ /// The following record data comes from platform driver:
+ ///
+ PlatformCpuInfo.StringHandle = mStringHandle;
+ PlatformCpuInfo.ApicID = CpuDataForDatahub->ApicID;
+ Status = mPlatformCpu->CpuConfig->GetCpuInfo (
+ mPlatformCpu,
+ &CpuDataForDatahub->Location,
+ &PlatformCpuInfo
+ );
+
+ ///
+ /// Record following data by socket base
+ ///
+ if (CpuNumber == 0) {
+ ///
+ /// Record Type 5. (Processor Serial Number: this feature is only available on PIII, not support here)
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorSerialNumberRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorAssetTag = PlatformCpuInfo.SerialNumber;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_SERIAL_NUMBER_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 15.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorSocketTypeRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorSocketType = PlatformCpuInfo.SocketType;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_SOCKET_TYPE_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 16(0x10).
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorSocketNameRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorSocketName = PlatformCpuInfo.SocketName;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_SOCKET_NAME_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 18(0x12).
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorMaxCoreFrequencyRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorMaxCoreFrequency = PlatformCpuInfo.MaxCoreFrequency;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_MAX_CORE_FREQUENCY_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 19(0x13).
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorAssetTagRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorAssetTag = PlatformCpuInfo.AssetTag;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_ASSET_TAG_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+ }
+ ///
+ /// log data by socket base
+ ///
+ /// Record Type 20(0x14).
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorMaxFsbFrequencyRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorMaxFsbFrequency = PlatformCpuInfo.MaxFsbFrequency;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_MAX_FSB_FREQUENCY_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 22(0x16).
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorCoreFrequencyListRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequencyList = PlatformCpuInfo.PlatformCoreFrequencyList;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_CORE_FREQUENCY_LIST_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 23(0x17).
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorFsbFrequencyListRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorFsbFrequencyList = PlatformCpuInfo.PlatformFsbFrequencyList;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_FSB_FREQUENCY_LIST_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record following data by socket base
+ ///
+ if (CpuNumber == 0) {
+ ///
+ /// Record Type 30. (Processor Part Number)
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorPartNumberRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorAssetTag = PlatformCpuInfo.PartNumber;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_PART_NUMBER_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 28.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorCharacteristicsRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorCharacteristics.Reserved2 = 0;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorCharacteristics.Reserved = 0;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorCharacteristics.Unknown = 0;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorCharacteristics.Capable64Bit = 1;
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_CHARACTERISTICS_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ MsrValue = AsmReadMsr64 (MSR_CORE_THREAD_COUNT);
+ ProcessorThreadCount = MsrValue & 0xffff;
+ ProcessorCoreCount = (MsrValue >> 16) & 0xffff;
+
+ ///
+ /// Record Type 25.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorCoreCountRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorCoreCount = (UINT8) (ProcessorCoreCount);
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_CORE_COUNT_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 26.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorEnabledCoreCountRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorEnabledCoreCount = (UINT8) (ProcessorCoreCount);
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_ENABLED_CORE_COUNT_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+
+ ///
+ /// Record Type 27.
+ ///
+ RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorThreadCountRecordType;
+ RecordBuffer.DataRecord->VariableRecord.ProcessorThreadCount = (UINT8) (ProcessorThreadCount);
+ TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_THREAD_COUNT_DATA);
+ Status = LogCpuData (mDataHub, RecordBuffer.Raw, TotalSize);
+ }
+ ///
+ /// log data by socket base
+ ///
+ FreePool (RecordBuffer.Raw);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Log CPU data into data hub
+
+ @param[in] DataHub - point to data hub that will be updated
+ @param[in] Buffer - the buffer which will be updated into data hub
+ @param[in] Size - size of the buffer
+
+ @retval EFI_STATUS - status returned when updating Data hub
+**/
+EFI_STATUS
+LogCpuData (
+ EFI_DATA_HUB_PROTOCOL *DataHub,
+ UINT8 *Buffer,
+ UINT32 Size
+ )
+{
+ EFI_STATUS Status;
+
+ Status = DataHub->LogData (
+ DataHub,
+ &gEfiProcessorSubClassGuid,
+ &gEfiProcessorProducerGuid,
+ EFI_DATA_RECORD_CLASS_DATA,
+ Buffer,
+ Size
+ );
+ return Status;
+
+}