+++ /dev/null
-/*++\r
-\r
-Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.\r
- \r\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
- \r\r
-\r
-\r
-\r
-Module Name:\r
-\r
- MiscOemType0x88Function.c\r
-\r
-Abstract:\r
-\r
- The function that processes the Smbios data type 0x88 before they\r
- are submitted to Data Hub\r
-\r
---*/\r
-\r
-#include "CommonHeader.h"\r
-\r
-#include "MiscSubclassDriver.h"\r
-#include <Library/PrintLib.h>\r
-#include <Library/CpuIA32.h>\r
-#include <Protocol/DxeSmmReadyToLock.h>\r
-\r
-\r
-VOID\r
-GetCPUStepping ( )\r
-{\r
- CHAR16 Buffer[40];\r
-\r
- UINT16 FamilyId;\r
- UINT8 Model;\r
- UINT8 SteppingId;\r
- UINT8 ProcessorType;\r
-\r
-\r
- EfiCpuVersion (&FamilyId, &Model, &SteppingId, &ProcessorType);\r
-\r
- //\r
- //we need raw Model data\r
- //\r
- Model = Model & 0xf;\r
-\r
- //\r
- //Family/Model/Step\r
- //\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"%d/%d/%d", FamilyId, Model, SteppingId);\r
- HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PROCESSOR_STEPPING), Buffer, NULL);\r
-\r
-}\r
-\r
-EFI_STATUS\r
-SearchChildHandle(\r
- EFI_HANDLE Father,\r
- EFI_HANDLE *Child\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleIndex;\r
- EFI_GUID **ProtocolGuidArray = NULL;\r
- UINTN ArrayCount;\r
- UINTN ProtocolIndex;\r
- UINTN OpenInfoCount;\r
- UINTN OpenInfoIndex;\r
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo = NULL;\r
- UINTN mHandleCount;\r
- EFI_HANDLE *mHandleBuffer= NULL;\r
-\r
- //\r
- // Retrieve the list of all handles from the handle database\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- AllHandles,\r
- NULL,\r
- NULL,\r
- &mHandleCount,\r
- &mHandleBuffer\r
- );\r
-\r
- for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) {\r
- //\r
- // Retrieve the list of all the protocols on each handle\r
- //\r
- Status = gBS->ProtocolsPerHandle (\r
- mHandleBuffer[HandleIndex],\r
- &ProtocolGuidArray,\r
- &ArrayCount\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
- Status = gBS->OpenProtocolInformation (\r
- mHandleBuffer[HandleIndex],\r
- ProtocolGuidArray[ProtocolIndex],\r
- &OpenInfo,\r
- &OpenInfoCount\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
- if(OpenInfo[OpenInfoIndex].AgentHandle == Father) {\r
- if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
- *Child = mHandleBuffer[HandleIndex];\r
- Status = EFI_SUCCESS;\r
- goto TryReturn;\r
- }\r
- }\r
- }\r
- Status = EFI_NOT_FOUND;\r
- }\r
- }\r
- if(OpenInfo != NULL) {\r
- FreePool(OpenInfo);\r
- OpenInfo = NULL;\r
- }\r
- }\r
- if(ProtocolGuidArray != NULL) {\r
- FreePool (ProtocolGuidArray);\r
- ProtocolGuidArray = NULL;\r
- }\r
- }\r
-TryReturn:\r
- if(OpenInfo != NULL) {\r
- FreePool (OpenInfo);\r
- OpenInfo = NULL;\r
- }\r
- if(ProtocolGuidArray != NULL) {\r
- FreePool(ProtocolGuidArray);\r
- ProtocolGuidArray = NULL;\r
- }\r
- if(mHandleBuffer != NULL) {\r
- FreePool (mHandleBuffer);\r
- mHandleBuffer = NULL;\r
- }\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-JudgeHandleIsPCIDevice(\r
- EFI_HANDLE Handle,\r
- UINT8 Device,\r
- UINT8 Funs\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH *DPath;\r
-\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &DPath\r
- );\r
- if(!EFI_ERROR(Status)) {\r
- while(!IsDevicePathEnd(DPath)) {\r
- if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP)) {\r
- PCI_DEVICE_PATH *PCIPath;\r
- PCIPath = (PCI_DEVICE_PATH*) DPath;\r
- DPath = NextDevicePathNode(DPath);\r
-\r
- if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs)) {\r
- return EFI_SUCCESS;\r
- }\r
- } else {\r
- DPath = NextDevicePathNode(DPath);\r
- }\r
- }\r
- }\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-GetDriverName(\r
- EFI_HANDLE Handle\r
-)\r
-{\r
- EFI_DRIVER_BINDING_PROTOCOL *BindHandle = NULL;\r
- EFI_STATUS Status;\r
- UINT32 Version;\r
- UINT16 *Ptr;\r
- CHAR16 Buffer[40];\r
- STRING_REF TokenToUpdate;\r
- Status = gBS->OpenProtocol(\r
- Handle,\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID**)&BindHandle,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR(Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Version = BindHandle->Version;\r
- Ptr = (UINT16*)&Version;\r
- UnicodeSPrint(Buffer, sizeof (Buffer), L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr));\r
-\r
- TokenToUpdate = (STRING_REF)STR_MISC_GOP_VERSION;\r
- HiiSetString(mHiiHandle, TokenToUpdate, Buffer, NULL);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetGOPDriverName()\r
-{\r
- UINTN HandleCount;\r
- EFI_HANDLE *Handles= NULL;\r
- UINTN Index;\r
- EFI_STATUS Status;\r
- EFI_HANDLE Child = 0;\r
-\r
- Status = gBS->LocateHandleBuffer(\r
- ByProtocol,\r
- &gEfiDriverBindingProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &Handles\r
- );\r
-\r
- for (Index = 0; Index < HandleCount ; Index++) {\r
- Status = SearchChildHandle(Handles[Index], &Child);\r
- if(!EFI_ERROR(Status)) {\r
- Status = JudgeHandleIsPCIDevice(Child, 0x02, 0x00);\r
- if(!EFI_ERROR(Status)) {\r
- return GetDriverName(Handles[Index]);\r
- }\r
- }\r
- }\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-VOID\r
-GetUcodeVersion()\r
-{\r
- UINT32 MicroCodeVersion;\r
- CHAR16 Buffer[40];\r
-\r
- //\r
- // Microcode Revision\r
- //\r
- EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);\r
- EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);\r
- MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32);\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);\r
- HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_UCODE_VERSION), Buffer, NULL);\r
-}\r
-\r
-/**\r
- Publish the smbios OEM type 0x90.\r
-\r
- @param Event - Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid).\r
- @param Context - Pointer to the notification functions context, which is implementation dependent.\r
-\r
- @retval None\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AddSmbiosT0x90Callback (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN SECVerStrLen = 0;\r
- UINTN uCodeVerStrLen = 0;\r
- UINTN GOPStrLen = 0;\r
- UINTN SteppingStrLen = 0;\r
- SMBIOS_TABLE_TYPE90 *SmbiosRecord;\r
- EFI_SMBIOS_HANDLE SmbiosHandle;\r
- CHAR16 *SECVer;\r
- CHAR16 *uCodeVer;\r
- CHAR16 *GOPVer;\r
- CHAR16 *Stepping;\r
- STRING_REF TokenToGet;\r
- CHAR8 *OptionalStrStart;\r
- EFI_SMBIOS_PROTOCOL *SmbiosProtocol;\r
-\r
- DEBUG ((EFI_D_INFO, "Executing SMBIOS T0x90 callback.\n"));\r
-\r
- gBS->CloseEvent (Event); // Unload this event.\r
-\r
- //\r
- // First check for invalid parameters.\r
- //\r
- if (Context == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = gBS->LocateProtocol (\r
- &gEfiSmbiosProtocolGuid,\r
- NULL,\r
- (VOID *) &SmbiosProtocol\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- GetUcodeVersion();\r
- GetGOPDriverName();\r
- GetCPUStepping();\r
-\r
- TokenToGet = STRING_TOKEN (STR_MISC_SEC_VERSION);\r
- SECVer = SmbiosMiscGetString (TokenToGet);\r
- SECVerStrLen = StrLen(SECVer);\r
- if (SECVerStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- TokenToGet = STRING_TOKEN (STR_MISC_UCODE_VERSION);\r
- uCodeVer = SmbiosMiscGetString (TokenToGet);\r
- uCodeVerStrLen = StrLen(uCodeVer);\r
- if (uCodeVerStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- TokenToGet = STRING_TOKEN (STR_MISC_GOP_VERSION);\r
- GOPVer = SmbiosMiscGetString (TokenToGet);\r
- GOPStrLen = StrLen(GOPVer);\r
- if (GOPStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING);\r
- Stepping = SmbiosMiscGetString (TokenToGet);\r
- SteppingStrLen = StrLen(Stepping);\r
-\r
-\r
- if (SteppingStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE90) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + SteppingStrLen + 1 + 1);\r
- ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE90) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + SteppingStrLen + 1 + 1);\r
-\r
- SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO;\r
- SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE90);\r
-\r
- //\r
- // Make handle chosen by smbios protocol.add automatically.\r
- //\r
- SmbiosRecord->Hdr.Handle = 0;\r
-\r
- //\r
- // SEC VERSION will be the 1st optional string following the formatted structure.\r
- //\r
- SmbiosRecord->SECVersion = 0;\r
-\r
- //\r
- // Microcode VERSION will be the 2nd optional string following the formatted structure.\r
- //\r
- SmbiosRecord->uCodeVersion = 2;\r
-\r
- //\r
- // GOP VERSION will be the 3rd optional string following the formatted structure.\r
- //\r
- SmbiosRecord->GOPVersion = 3;\r
-\r
- //\r
- // CPU Stepping will be the 4th optional string following the formatted structure.\r
- //\r
- SmbiosRecord->CpuStepping = 4;\r
-\r
- OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);\r
- UnicodeStrToAsciiStr(SECVer, OptionalStrStart);\r
- UnicodeStrToAsciiStr(uCodeVer, OptionalStrStart + SECVerStrLen + 1);\r
- UnicodeStrToAsciiStr(GOPVer, OptionalStrStart + SECVerStrLen + 1 + uCodeVerStrLen + 1);\r
- UnicodeStrToAsciiStr(Stepping, OptionalStrStart + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 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 = SmbiosProtocol-> Add(\r
- SmbiosProtocol,\r
- NULL,\r
- &SmbiosHandle,\r
- (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord\r
- );\r
-\r
- FreePool(SmbiosRecord);\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- This function makes boot time changes to the contents of the\r
- MiscOemType0x90 (Type 0x90).\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
-MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x90)\r
-{\r
- EFI_STATUS Status;\r
- static BOOLEAN CallbackIsInstalledT0x90 = FALSE;\r
- VOID *AddSmbiosT0x90CallbackNotifyReg;\r
- EFI_EVENT AddSmbiosT0x90CallbackEvent;\r
-\r
- //\r
- // This callback will create a OEM Type 0x90 record.\r
- //\r
- if (CallbackIsInstalledT0x90 == FALSE) {\r
- CallbackIsInstalledT0x90 = TRUE; // Prevent more than 1 callback.\r
- DEBUG ((EFI_D_INFO, "Create Smbios T0x90 callback.\n"));\r
-\r
- //\r
- // gEfiDxeSmmReadyToLockProtocolGuid is ready\r
- //\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- (EFI_EVENT_NOTIFY)AddSmbiosT0x90Callback,\r
- RecordData,\r
- &AddSmbiosT0x90CallbackEvent\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
-\r
- }\r
-\r
- Status = gBS->RegisterProtocolNotify (\r
- &gEfiDxeSmmReadyToLockProtocolGuid,\r
- AddSmbiosT0x90CallbackEvent,\r
- &AddSmbiosT0x90CallbackNotifyReg\r
- );\r
-\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r