+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
- \r\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
- \r\r
-\r
-\r
-Module Name:\r
-\r
- MiscProcessorInformationFunction.c\r
-\r
-Abstract:\r
-\r
- Onboard processor information boot time changes.\r
- SMBIOS type 4.\r
-\r
---*/\r
-\r
-#include "CommonHeader.h"\r
-\r
-#include "MiscSubclassDriver.h"\r
-\r
-#include <Protocol/MpService.h>\r
-#include <Protocol/DataHub.h>\r
-#include <Guid/DataHubRecords.h>\r
-#include <Library/CpuIA32.h>\r
-\r
-#define EfiProcessorFamilyIntelAtomProcessor 0x2B\r
-\r
-EFI_GUID mProcessorProducerGuid;\r
-\r
-\r
-/**\r
- Get cache SMBIOS record handle.\r
-\r
- @param Smbios Pointer to SMBIOS protocol instance.\r
- @param CacheLevel Level of cache, starting from one.\r
- @param Handle Returned record handle.\r
-\r
-**/\r
-\r
-VOID\r
-GetCacheHandle (\r
- IN EFI_SMBIOS_PROTOCOL *Smbios,\r
- IN UINT8 CacheLevel,\r
- OUT EFI_SMBIOS_HANDLE *Handle\r
- )\r
-{\r
- UINT16 CacheConfig;\r
- EFI_STATUS Status;\r
- EFI_SMBIOS_TYPE RecordType;\r
- EFI_SMBIOS_TABLE_HEADER *Buffer;\r
-\r
- *Handle = 0;\r
- RecordType = EFI_SMBIOS_TYPE_CACHE_INFORMATION;\r
-\r
- do {\r
- Status = Smbios->GetNext (\r
- Smbios,\r
- Handle,\r
- &RecordType,\r
- &Buffer,\r
- NULL\r
- );\r
- if (!EFI_ERROR(Status)) {\r
- CacheConfig = *(UINT16*)((UINT8*)Buffer + 5);\r
- if ((CacheConfig & 0x7) == (CacheLevel -1) ) {\r
- return;\r
- }\r
- }\r
- } while (!EFI_ERROR(Status));\r
-\r
- *Handle = 0xFFFF;\r
-}\r
-\r
-\r
-/**\r
- This function makes boot time changes to the contents of the\r
- MiscProcessorInformation (Type 4).\r
-\r
- @param RecordData Pointer to copy of RecordData from the Data Table.\r
-\r
- @retval EFI_SUCCESS All parameters were valid.\r
- @retval EFI_UNSUPPORTED Unexpected RecordType value.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter was found.\r
-\r
-**/\r
-UINT32\r
-ConvertBase10ToRaw (\r
- IN EFI_EXP_BASE10_DATA *Data)\r
-{\r
- UINTN Index;\r
- UINT32 RawData;\r
-\r
- RawData = Data->Value;\r
- for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {\r
- RawData *= 10;\r
- }\r
-\r
- return RawData;\r
-}\r
-\r
-#define BSEL_CR_OVERCLOCK_CONTROL 0xCD\r
-#define FUSE_BSEL_MASK 0x03\r
-\r
-\r
-\r
-UINT16 miFSBFrequencyTable[4] = {\r
- 83, // 83.3MHz\r
- 100, // 100MHz\r
- 133, // 133MHz\r
- 117 // 116.7MHz\r
-};\r
-\r
-/**\r
- Determine the processor core frequency\r
-\r
- @param None\r
-\r
- @retval Processor core frequency multiplied by 3\r
-\r
-\r
-**/\r
-UINT16\r
-DetermineiFsbFromMsr (\r
- VOID\r
- )\r
-{\r
- //\r
- // Determine the processor core frequency\r
- //\r
- UINT64 Temp;\r
- Temp = (EfiReadMsr (BSEL_CR_OVERCLOCK_CONTROL)) & FUSE_BSEL_MASK;\r
- return miFSBFrequencyTable[(UINT32)(Temp)];\r
-\r
-}\r
-\r
-MISC_SMBIOS_TABLE_FUNCTION (MiscProcessorInformation)\r
-{\r
- CHAR8 *OptionalStrStart;\r
- EFI_STRING SerialNumber;\r
- CHAR16 *Version=NULL;\r
- CHAR16 *Manufacturer=NULL;\r
- CHAR16 *Socket=NULL;\r
- CHAR16 *AssetTag=NULL;\r
- CHAR16 *PartNumber=NULL;\r
- UINTN SerialNumberStrLen=0;\r
- UINTN VersionStrLen=0;\r
- UINTN ManufacturerStrLen=0;\r
- UINTN SocketStrLen=0;\r
- UINTN AssetTagStrLen=0;\r
- UINTN PartNumberStrLen=0;\r
- UINTN ProcessorVoltage=0xAE;\r
- UINT32 Eax01;\r
- UINT32 Ebx01;\r
- UINT32 Ecx01;\r
- UINT32 Edx01;\r
- STRING_REF TokenToGet;\r
- EFI_STATUS Status;\r
- EFI_SMBIOS_HANDLE SmbiosHandle;\r
- SMBIOS_TABLE_TYPE4 *SmbiosRecord;\r
- EFI_CPU_DATA_RECORD *ForType4InputData;\r
- UINT16 L1CacheHandle=0;\r
- UINT16 L2CacheHandle=0;\r
- UINT16 L3CacheHandle=0;\r
- UINTN NumberOfEnabledProcessors=0 ;\r
- UINTN NumberOfProcessors=0;\r
- UINT64 Frequency = 0;\r
- EFI_MP_SERVICES_PROTOCOL *MpService;\r
- EFI_DATA_HUB_PROTOCOL *DataHub;\r
- UINT64 MonotonicCount;\r
- EFI_DATA_RECORD_HEADER *Record;\r
- EFI_SUBCLASS_TYPE1_HEADER *DataHeader;\r
- UINT8 *SrcData;\r
- EFI_PROCESSOR_VERSION_DATA *ProcessorVersion;\r
- CHAR16 *NewStringToken;\r
- STRING_REF TokenToUpdate;\r
- PROCESSOR_ID_DATA *ProcessorId = NULL;\r
-\r
-\r
- //\r
- // First check for invalid parameters.\r
- //\r
- if (RecordData == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- ForType4InputData = (EFI_CPU_DATA_RECORD *)RecordData;\r
-\r
- ProcessorId = AllocateZeroPool(sizeof(PROCESSOR_ID_DATA));\r
- if (ProcessorId == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Get the Data Hub Protocol. Assume only one instance\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiDataHubProtocolGuid,\r
- NULL,\r
- (VOID **)&DataHub\r
- );\r
- ASSERT_EFI_ERROR(Status);\r
-\r
- MonotonicCount = 0;\r
- Record = NULL;\r
-\r
- do {\r
- Status = DataHub->GetNextRecord (\r
- DataHub,\r
- &MonotonicCount,\r
- NULL,\r
- &Record\r
- );\r
- if (!EFI_ERROR(Status)) {\r
- if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {\r
-\r
- DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);\r
- SrcData = (UINT8 *)(DataHeader + 1);\r
-\r
- //\r
- // Processor\r
- //\r
- if (CompareGuid(&Record->DataRecordGuid, &gEfiProcessorSubClassGuid)) {\r
- CopyMem (&mProcessorProducerGuid, &Record->ProducerName, sizeof(EFI_GUID));\r
- switch (DataHeader->RecordType) {\r
- case ProcessorVoltageRecordType:\r
- ProcessorVoltage = (((EFI_EXP_BASE10_DATA *)SrcData)->Value)/100 + 0x80;\r
- break;\r
- case ProcessorCoreFrequencyRecordType:\r
- DEBUG ((EFI_D_ERROR, "ProcessorCoreFrequencyRecordType SrcData1 =%d\n", ConvertBase10ToRaw((EFI_EXP_BASE10_DATA *)SrcData)/1000000));\r
- Frequency = (ConvertBase10ToRaw((EFI_EXP_BASE10_DATA *)SrcData)/1000000);\r
- break;\r
- case ProcessorVersionRecordType:\r
- ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *)SrcData;\r
- NewStringToken = HiiGetPackageString(&mProcessorProducerGuid, *ProcessorVersion, NULL);\r
- TokenToUpdate = (STRING_REF)STR_MISC_PROCESSOR_VERSION;\r
- HiiSetString(mHiiHandle, TokenToUpdate, NewStringToken, NULL);\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- } while (!EFI_ERROR(Status) && (MonotonicCount != 0));\r
-\r
- //\r
- // Token to get for Socket Name\r
- //\r
- TokenToGet = STRING_TOKEN (STR_MISC_SOCKET_NAME);\r
- Socket = SmbiosMiscGetString (TokenToGet);\r
- SocketStrLen = StrLen(Socket);\r
- if (SocketStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Token to get for Processor Manufacturer\r
- //\r
- TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_MAUFACTURER);\r
- Manufacturer = SmbiosMiscGetString (TokenToGet);\r
- ManufacturerStrLen = StrLen(Manufacturer);\r
- if (ManufacturerStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Token to get for Processor Version\r
- //\r
- TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_VERSION);\r
- Version = SmbiosMiscGetString (TokenToGet);\r
- VersionStrLen = StrLen(Version);\r
- if (VersionStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Token to get for Serial Number\r
- //\r
- TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_SERIAL_NUMBER);\r
- SerialNumber = SmbiosMiscGetString (TokenToGet);\r
- SerialNumberStrLen = StrLen(SerialNumber);\r
- if (SerialNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Token to get for Assert Tag Information\r
- //\r
- TokenToGet = STRING_TOKEN (STR_MISC_ASSERT_TAG_DATA);\r
- AssetTag = SmbiosMiscGetString (TokenToGet);\r
- AssetTagStrLen = StrLen(AssetTag);\r
- if (AssetTagStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Token to get for part number Information\r
- //\r
- TokenToGet = STRING_TOKEN (STR_MISC_PART_NUMBER);\r
- PartNumber = SmbiosMiscGetString (TokenToGet);\r
- PartNumberStrLen = StrLen(PartNumber);\r
- if (PartNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Two zeros following the last string.\r
- //\r
- SmbiosRecord = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE4) + AssetTagStrLen + 1 + SocketStrLen + 1+ ManufacturerStrLen +1 + VersionStrLen+ 1+ SerialNumberStrLen + 1 + PartNumberStrLen+ 1 + 1);\r
-\r
- SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION;\r
- SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4);\r
-\r
- //\r
- // Make handle chosen by smbios protocol.add automatically.\r
- //\r
- SmbiosRecord->Hdr.Handle = 0;\r
-\r
- SmbiosRecord-> Socket= 1;\r
- SmbiosRecord -> ProcessorManufacture = 2;\r
- SmbiosRecord -> ProcessorVersion = 3;\r
- SmbiosRecord ->SerialNumber =4;\r
-\r
- SmbiosRecord-> AssetTag= 5;\r
- SmbiosRecord-> PartNumber= 6;\r
-\r
- //\r
- // Processor Type\r
- //\r
- ForType4InputData-> VariableRecord.ProcessorType= EfiCentralProcessor;\r
- SmbiosRecord -> ProcessorType = ForType4InputData-> VariableRecord.ProcessorType;\r
-\r
- //\r
- // Processor Family\r
- //\r
- ForType4InputData-> VariableRecord.ProcessorFamily= EfiProcessorFamilyIntelAtomProcessor; //0x2B;;\r
- SmbiosRecord -> ProcessorFamily = ForType4InputData-> VariableRecord.ProcessorFamily;\r
- SmbiosRecord -> ExternalClock = DetermineiFsbFromMsr();\r
-\r
- //\r
- // Processor ID\r
- //\r
- AsmCpuid(0x001, &Eax01, &Ebx01, &Ecx01, &Edx01);\r
- ProcessorId->Signature = *(PROCESSOR_SIGNATURE *)&Eax01;\r
- ProcessorId->FeatureFlags = *(PROCESSOR_FEATURE_FLAGS *)&Edx01;\r
- SmbiosRecord -> ProcessorId = *(PROCESSOR_ID_DATA *)ProcessorId;\r
-\r
- //\r
- // Processor Voltage\r
- //\r
- ForType4InputData-> VariableRecord.ProcessorVoltage= *(EFI_PROCESSOR_VOLTAGE_DATA *)&ProcessorVoltage;\r
- SmbiosRecord -> Voltage = *(PROCESSOR_VOLTAGE *) &(ForType4InputData-> VariableRecord.ProcessorVoltage);\r
-\r
- //\r
- // Status\r
- //\r
- ForType4InputData-> VariableRecord.ProcessorHealthStatus= 0x41;//0x41;\r
- SmbiosRecord -> Status = ForType4InputData-> VariableRecord.ProcessorHealthStatus;\r
-\r
- //\r
- // Processor Upgrade\r
- //\r
- SmbiosRecord -> ProcessorUpgrade = 0x008;\r
-\r
- //\r
- // Processor Family 2\r
- //\r
- SmbiosRecord -> ProcessorFamily2 = ForType4InputData-> VariableRecord.ProcessorFamily;\r
-\r
- //\r
- // Processor speed\r
- //\r
- SmbiosRecord-> CurrentSpeed = *(UINT16*) & Frequency;\r
- SmbiosRecord-> MaxSpeed = *(UINT16*) & Frequency;\r
-\r
- //\r
- // Processor Characteristics\r
- //\r
- AsmCpuid(0x8000000, NULL, NULL, NULL, &Edx01);\r
- Edx01= Edx01 >> 28;\r
- Edx01 &= 0x01;\r
- SmbiosRecord-> ProcessorCharacteristics= (UINT16)Edx01;\r
-\r
- //\r
- // Processor Core Count and Enabled core count\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiMpServiceProtocolGuid,\r
- NULL,\r
- (void **)&MpService\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Determine the number of processors\r
- //\r
- MpService->GetNumberOfProcessors (\r
- MpService,\r
- &NumberOfProcessors,\r
- &NumberOfEnabledProcessors\r
- );\r
- }\r
- SmbiosRecord-> CoreCount= (UINT8)NumberOfProcessors;\r
- SmbiosRecord-> EnabledCoreCount= (UINT8)NumberOfEnabledProcessors;\r
- SmbiosRecord-> ThreadCount= (UINT8)NumberOfEnabledProcessors;\r
- SmbiosRecord-> ProcessorCharacteristics = 0x2; // Unknown\r
-\r
- //\r
- // Processor Cache Handle\r
- //\r
- GetCacheHandle( Smbios,1, &L1CacheHandle);\r
- GetCacheHandle( Smbios,2, &L2CacheHandle);\r
- GetCacheHandle( Smbios,3, &L3CacheHandle);\r
-\r
- //\r
- // Updating Cache Handle Information\r
- //\r
- SmbiosRecord->L1CacheHandle = L1CacheHandle;\r
- SmbiosRecord->L2CacheHandle = L2CacheHandle;\r
- SmbiosRecord->L3CacheHandle = L3CacheHandle;\r
-\r
- OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);\r
- UnicodeStrToAsciiStr(Socket, OptionalStrStart);\r
- UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart + SocketStrLen + 1);\r
- UnicodeStrToAsciiStr(Version, OptionalStrStart + SocketStrLen + 1 + ManufacturerStrLen+ 1);\r
- UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + SocketStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1);\r
- UnicodeStrToAsciiStr(AssetTag, OptionalStrStart + SerialNumberStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1 + SocketStrLen + 1);\r
- UnicodeStrToAsciiStr(PartNumber, OptionalStrStart + SerialNumberStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1 + SocketStrLen + 1 + AssetTagStrLen + 1 );\r
-\r
- //\r
- // Now we have got the full Smbios record, call Smbios protocol to add this record.\r
- //\r
- SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
- Status = Smbios-> Add(\r
- Smbios,\r
- NULL,\r
- &SmbiosHandle,\r
- (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord\r
- );\r
- if (EFI_ERROR (Status)) return Status;\r
- FreePool(SmbiosRecord);\r
- return Status;\r
-\r
-}\r
-\r