/*++ Copyright (c) 1999 - 2020, Intel Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent Module Name: MiscOemType0x94Function.c Abstract: The function that processes the Smbios data type 0x94. --*/ #include "CommonHeader.h" #include "MiscSubclassDriver.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Valleyview.h" #include "VlvAccess.h" #include "PchAccess.h" #include "SetupMode.h" #include "PchCommonDefinitions.h" #include typedef struct { UINT8 RevId; CHAR8 String[16]; } SB_REV; // // Silicon Steppings // SB_REV SBRevisionTable[] = { {V_PCH_LPC_RID_0, "(A0 Stepping)"}, {V_PCH_LPC_RID_1, "(A0 Stepping)"}, {V_PCH_LPC_RID_2, "(A1 Stepping)"}, {V_PCH_LPC_RID_3, "(A1 Stepping)"}, {V_PCH_LPC_RID_4, "(B0 Stepping)"}, {V_PCH_LPC_RID_5, "(B0 Stepping)"}, {V_PCH_LPC_RID_6, "(B1 Stepping)"}, {V_PCH_LPC_RID_7, "(B1 Stepping)"}, {V_PCH_LPC_RID_8, "(B2 Stepping)"}, {V_PCH_LPC_RID_9, "(B2 Stepping)"}, {V_PCH_LPC_RID_A, "(B3 Stepping)"}, {V_PCH_LPC_RID_B, "(B3 Stepping)"} }; #define LEFT_JUSTIFY 0x01 #define PREFIX_SIGN 0x02 #define PREFIX_BLANK 0x04 #define COMMA_TYPE 0x08 #define LONG_TYPE 0x10 #define PREFIX_ZERO 0x20 #define ICH_REG_REV 0x08 #define CHARACTER_NUMBER_FOR_VALUE 30 UINT8 ReadBuffer[20]; //Version report length UINT8 WriteBuffer[22] = {0x40,0x01,0x14,0x00,0x06,0x51,0x02,0x07,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //Version request /** VSPrint worker function that prints a Value as a decimal number in Buffer @param Buffer Location to place ascii decimal number string of Value. @param Value Decimal value to convert to a string in Buffer. @param Flags Flags to use in printing decimal string, see file header for details. @param Width Width of hex value. @retval Number of characters printed. **/ UINTN EfiValueToString ( IN OUT CHAR16 *Buffer, IN INT64 Value, IN UINTN Flags, IN UINTN Width ) { CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE]; CHAR16 *TempStr; CHAR16 *BufferPtr; UINTN Count; UINTN ValueCharNum; UINTN Remainder; CHAR16 Prefix; UINTN Index; BOOLEAN ValueIsNegative; UINT64 TempValue; TempStr = TempBuffer; BufferPtr = Buffer; Count = 0; ValueCharNum = 0; ValueIsNegative = FALSE; if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) { Width = CHARACTER_NUMBER_FOR_VALUE - 1; } if (Value < 0) { Value = -Value; ValueIsNegative = TRUE; } do { TempValue = Value; Value = (INT64)DivU64x32 ((UINT64)Value, 10); Remainder = (UINTN)((UINT64)TempValue - 10 * Value); *(TempStr++) = (CHAR16)(Remainder + '0'); ValueCharNum++; Count++; if ((Flags & COMMA_TYPE) == COMMA_TYPE) { if (ValueCharNum % 3 == 0 && Value != 0) { *(TempStr++) = ','; Count++; } } } while (Value != 0); if (ValueIsNegative) { *(TempStr++) = '-'; Count++; } if ((Flags & PREFIX_ZERO) && !ValueIsNegative) { Prefix = '0'; } else { Prefix = ' '; } Index = Count; if (!(Flags & LEFT_JUSTIFY)) { for (; Index < Width; Index++) { *(TempStr++) = Prefix; } } // // Reverse temp string into Buffer. // if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) { TempStr = TempBuffer + Width; } Index = 0; while (TempStr != TempBuffer) { *(BufferPtr++) = *(--TempStr); Index++; } *BufferPtr = 0; return Index; } static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' }; /** VSPrint worker function that prints a Value as a hex number in Buffer @param Buffer Location to place ascii hex string of Value. @param Value Hex value to convert to a string in Buffer. @param Flags Flags to use in printing Hex string, see file header for details. @param Width Width of hex value. @retval Number of characters printed. **/ UINTN EfiValueToHexStr ( IN OUT CHAR16 *Buffer, IN UINT64 Value, IN UINTN Flags, IN UINTN Width ) { CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE]; CHAR16 *TempStr; CHAR16 Prefix; CHAR16 *BufferPtr; UINTN Count; UINTN Index; TempStr = TempBuffer; BufferPtr = Buffer; // // Count starts at one since we will null terminate. Each iteration of the // loop picks off one nibble. Oh yea TempStr ends up backwards // Count = 0; if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) { Width = CHARACTER_NUMBER_FOR_VALUE - 1; } do { Index = ((UINTN)Value & 0xf); *(TempStr++) = mHexStr[Index]; Value = RShiftU64 (Value, 4); Count++; } while (Value != 0); if (Flags & PREFIX_ZERO) { Prefix = '0'; } else { Prefix = ' '; } Index = Count; if (!(Flags & LEFT_JUSTIFY)) { for (; Index < Width; Index++) { *(TempStr++) = Prefix; } } // // Reverse temp string into Buffer. // if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) { TempStr = TempBuffer + Width; } Index = 0; while (TempStr != TempBuffer) { *(BufferPtr++) = *(--TempStr); Index++; } *BufferPtr = 0; return Index; } /** Converts MAC address to Unicode string. The value is 64-bit and the resulting string will be 12 digit hex number in pairs of digits separated by dashes. @param String - string that will contain the value @param Val - value to convert **/ CHAR16 * StrMacToString ( OUT CHAR16 *String, IN EFI_MAC_ADDRESS *MacAddr, IN UINT32 AddrSize ) { UINT32 i; for (i = 0; i < AddrSize; i++) { EfiValueToHexStr ( &String[2 * i], MacAddr->Addr[i] & 0xFF, PREFIX_ZERO, 2 ); } // // Terminate the string. // String[2 * AddrSize] = L'\0'; return String; } EFI_STATUS TJudgeHandleIsPCIDevice( EFI_HANDLE Handle, UINT8 Device, UINT8 Funs ) { EFI_STATUS Status; EFI_DEVICE_PATH *DPath; EFI_DEVICE_PATH *DevicePath; Status = gBS->HandleProtocol ( Handle, &gEfiDevicePathProtocolGuid, (VOID **) &DPath ); if(!EFI_ERROR(Status)) { DevicePath = DPath; while(!IsDevicePathEnd(DPath)) { if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP)) { PCI_DEVICE_PATH *PCIPath; PCIPath = (PCI_DEVICE_PATH*) DPath; DPath = NextDevicePathNode(DPath); if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs)) { return EFI_SUCCESS; } } else { DPath = NextDevicePathNode(DPath); } } } return EFI_UNSUPPORTED; } EFI_STATUS TSearchChildHandle( EFI_HANDLE Father, EFI_HANDLE *Child ) { EFI_STATUS Status; UINTN HandleIndex; EFI_GUID **ProtocolGuidArray = NULL; UINTN ArrayCount; UINTN ProtocolIndex; UINTN OpenInfoCount; UINTN OpenInfoIndex; EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo = NULL; UINTN mHandleCount; EFI_HANDLE *mHandleBuffer= NULL; // // Retrieve the list of all handles from the handle database // Status = gBS->LocateHandleBuffer ( AllHandles, NULL, NULL, &mHandleCount, &mHandleBuffer ); for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) { // // Retrieve the list of all the protocols on each handle // Status = gBS->ProtocolsPerHandle ( mHandleBuffer[HandleIndex], &ProtocolGuidArray, &ArrayCount ); if (!EFI_ERROR (Status)) { for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) { Status = gBS->OpenProtocolInformation ( mHandleBuffer[HandleIndex], ProtocolGuidArray[ProtocolIndex], &OpenInfo, &OpenInfoCount ); if (!EFI_ERROR (Status)) { for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) { if(OpenInfo[OpenInfoIndex].AgentHandle == Father) { if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) { *Child = mHandleBuffer[HandleIndex]; Status = EFI_SUCCESS; goto TryReturn; } } } Status = EFI_NOT_FOUND; } } if(OpenInfo != NULL) { FreePool(OpenInfo); OpenInfo = NULL; } } FreePool (ProtocolGuidArray); ProtocolGuidArray = NULL; } TryReturn: if(OpenInfo != NULL) { FreePool (OpenInfo); OpenInfo = NULL; } if(ProtocolGuidArray != NULL) { FreePool(ProtocolGuidArray); ProtocolGuidArray = NULL; } if(mHandleBuffer != NULL) { FreePool (mHandleBuffer); mHandleBuffer = NULL; } return Status; } EFI_STATUS TGetDriverName( EFI_HANDLE Handle, CHAR16 *Name ) { EFI_DRIVER_BINDING_PROTOCOL *BindHandle = NULL; EFI_STATUS Status; UINT32 Version; UINT16 *Ptr; Status = gBS->OpenProtocol( Handle, &gEfiDriverBindingProtocolGuid, (VOID**)&BindHandle, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR(Status)) { return EFI_NOT_FOUND; } Version = BindHandle->Version; Ptr = (UINT16*)&Version; UnicodeSPrint(Name, 40, L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr)); return EFI_SUCCESS; } EFI_STATUS TGetGOPDriverName( CHAR16 *Name ) { UINTN HandleCount; EFI_HANDLE *Handles= NULL; UINTN Index; EFI_STATUS Status; EFI_HANDLE Child = 0; Status = gBS->LocateHandleBuffer( ByProtocol, &gEfiDriverBindingProtocolGuid, NULL, &HandleCount, &Handles ); for (Index = 0; Index < HandleCount ; Index++) { Status = TSearchChildHandle(Handles[Index], &Child); if(!EFI_ERROR(Status)) { Status = TJudgeHandleIsPCIDevice(Child, 0x02, 0x00); if(!EFI_ERROR(Status)) { return TGetDriverName(Handles[Index], Name); } } } return EFI_UNSUPPORTED; } EFI_STATUS TGetTouchFirmwareVersion( ) { EFI_STATUS rc=EFI_SUCCESS; UINTN TouchVer = 0; UINTN Size = sizeof(UINTN); CHAR16 Buffer[40]; rc = gRT->GetVariable( L"TouchVer", &gEfiVlv2VariableGuid, NULL, &Size, &TouchVer ); if(!EFI_ERROR(rc)){ UnicodeSPrint(Buffer, sizeof(Buffer), L"%02x.%02x", (TouchVer&0xFFFF)>>8,TouchVer&0xFF); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_TOUCH_VERSION), Buffer, NULL); } return EFI_SUCCESS; } EFI_STATUS UpdatePlatformInformation ( ) { UINT32 MicroCodeVersion; CHAR16 Buffer[40]; EFI_STATUS Status; UINT8 CpuFlavor=0; EFI_PEI_HOB_POINTERS GuidHob; EFI_PLATFORM_INFO_HOB *mPlatformInfo=NULL; UINTN NumHandles; EFI_HANDLE *HandleBuffer; UINTN Index; DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy; UINTN PciD31F0RegBase; UINT8 count; UINT8 Data8; UINT8 Data8_1; CHAR16 Name[40]; UINT32 MrcVersion; UINT8 KscFwRevH =0; UINT8 KscFwRevL =0; // // Get the HOB list. If it is not present, then ASSERT. // GuidHob.Raw = GetHobList (); if (GuidHob.Raw != NULL) { if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) { mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid); } } Status = TGetGOPDriverName(Name); if(!EFI_ERROR(Status)) { HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_GOP_VERSION), Name, NULL); } // //CpuFlavor // //VLV //VLV-DC Tablet 000 //VLV-QC Notebook 001 //VLV-QC Desktop 010 // //CPU flavor // CpuFlavor = RShiftU64 (AsmReadMsr64 (MSR_IA32_PLATFORM_ID), 50) & 0x07; switch(CpuFlavor){ case 0x0: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-DC Tablet", CpuFlavor); break; case 0x01: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor); break; case 0x02: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Desktop", CpuFlavor); break; case 0x03: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor); break; default: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU", CpuFlavor); break; } HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_CPU_FLAVOR_VALUE), Buffer, NULL); if ( NULL != mPlatformInfo) { // // Board Id // UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardId); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_BOARD_ID_VALUE), Buffer, NULL); // // FAB ID // UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardRev); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_FAB_ID_VALUE), Buffer, NULL); } // //Update MRC Version // MrcVersion = MmioRead32 (MmPciAddress (0, 0, 0, 0, 0xF0)); MrcVersion &= 0xffff; Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0); StrCatS (Buffer, sizeof (Buffer) / sizeof (CHAR16), L"."); EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO, 0); EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO, 0); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_MRC_VERSION_VALUE), Buffer, NULL); // //Update Soc Version // // // Retrieve all instances of PCH Platform Policy protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gDxePchPlatformPolicyProtocolGuid, NULL, &NumHandles, &HandleBuffer ); if (!EFI_ERROR (Status)) { // // Find the matching PCH Policy protocol // for (Index = 0; Index < NumHandles; Index++) { Status = gBS->HandleProtocol ( HandleBuffer[Index], &gDxePchPlatformPolicyProtocolGuid, (VOID **) &PchPlatformPolicy ); if (!EFI_ERROR (Status)) { PciD31F0RegBase = MmPciAddress ( 0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0 ); Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC); count = ARRAY_SIZE (SBRevisionTable); for (Index = 0; Index < count; Index++) { if(Data8 == SBRevisionTable[Index].RevId) { UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8, SBRevisionTable[Index].String); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SOC_VALUE), Buffer, NULL); break; } } break; } } } // // Microcode Revision // AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0); AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL); MicroCodeVersion = (UINT32) RShiftU64 (AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID), 32); UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PROCESSOR_MICROCODE_VALUE), Buffer, NULL); // //Secure boot // Data8 = SystemConfiguration.SecureBoot; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_SECURE_BOOT), Buffer, NULL); // //Bootmode // BootMode = GetBootModeHob(); UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", BootMode); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_BOOT_MODE), Buffer, NULL); // //SpeedStep // Data8 = 1; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_SPEED_STEP), Buffer, NULL); // //CPU Turbo // Data8 = 2; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_CPU_TURBO), Buffer, NULL); // //CState // Data8 = 3; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_CSTATE), Buffer, NULL); // //GFX Turbo // Data8 = SystemConfiguration.IgdTurboEnabled; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_GFX_TURBO), Buffer, NULL); Data8 = 0; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_S0IX_VALUE), Buffer, NULL); // //RC6 // Data8 = 0; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_RC6_VALUE), Buffer, NULL); // // Punit Version // Data8 = 0; UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PUNIT_FW_VALUE), Buffer, NULL); // // PMC Version // Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>16)&0x00FF); Data8_1 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>24)&0x00FF); UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X", Data8_1, Data8); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PMC_FW_VALUE), Buffer, NULL); // //PMIC Version // Status = ByteReadI2C(PMICI2cBus, PMICI2cAdd, PMICVendorOffset, 1, &Data8); if(!EFI_ERROR(Status)){ Status = ByteReadI2C(PMICI2cBus, PMICI2cAdd, PMICRevOffset, 1, &Data8_1); if(!EFI_ERROR(Status)){ UnicodeSPrint(Buffer, sizeof(Buffer), L"%02x.%02x", Data8, Data8_1); HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_PMIC_VERSION), Buffer, NULL); } } TGetTouchFirmwareVersion(); return EFI_SUCCESS; } /** Smbios OEM type 0x94 callback. @param Event Event whose notification function is being invoked. @param Context Pointer to the notification functions context, which is implementation dependent. @retval None **/ VOID AddSmbiosT0x94Callback ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; UINTN SECVerStrLen = 0; UINTN uCodeVerStrLen = 0; UINTN GOPStrLen = 0; UINTN MRCVersionStrLen = 0; UINTN PMCVersionStrLen = 0; UINTN ULPMCVersionStrLen = 0; UINTN PUNITVersionStrLen = 0; UINTN SOCVersionStrLen = 0; UINTN BOARDVersionStrLen = 0; UINTN FABVersionStrLen = 0; UINTN CPUFLAVORStrLen = 0; UINTN BIOSVersionStrLen = 0; UINTN PMICVersionStrLen = 0; UINTN TOUCHVersionStrLen = 0; UINTN SecureBootModeLen = 0; UINTN BootModeLen = 0; UINTN SpeedStepModeLen = 0; UINTN MaxCStateLen = 0; UINTN CpuTurboLen = 0; UINTN GfxTurboLen = 0; UINTN IdleReserveLen = 0; UINTN RC6Len = 0; SMBIOS_TABLE_TYPE94 *SmbiosRecord; EFI_SMBIOS_HANDLE SmbiosHandle; EFI_MISC_OEM_TYPE_0x94 *ForType94InputData; CHAR16 *SECVer; CHAR16 *uCodeVer; CHAR16 *GOPVer; CHAR16 *MrcVer; CHAR16 *PmcVer; CHAR16 *UlpmcVer; CHAR16 *PunitVer; CHAR16 *SocVer; CHAR16 *BoardVer; CHAR16 *FabVer; CHAR16 *CpuFlavor; CHAR16 *BiosVer; CHAR16 *PmicVer; CHAR16 *TouchVer = L"15.16"; CHAR16 *SecureBootMode; CHAR16 *BootMode; CHAR16 *SpeedStepMode; CHAR16 *MaxCState; CHAR16 *CpuTurbo; CHAR16 *GfxTurbo; CHAR16 *IdleReserve; CHAR16 *RC6; UINTN RecordLen = 0; UINTN StrIdx = 0; STRING_REF TokenToGet; CHAR8 *OptionalStrStart; EFI_SMBIOS_PROTOCOL *SmbiosProtocol; ForType94InputData = (EFI_MISC_OEM_TYPE_0x94 *)Context; DEBUG ((EFI_D_INFO, "Executing SMBIOS T0x94 callback.\n")); gBS->CloseEvent (Event); // Unload this event. // // First check for invalid parameters. // if (Context == NULL) { return; } UpdatePlatformInformation(); Status = gBS->LocateProtocol ( &gEfiSmbiosProtocolGuid, NULL, (VOID **) &SmbiosProtocol ); ASSERT_EFI_ERROR (Status); TokenToGet = STRING_TOKEN (STR_MISC_SEC_VERSION); SECVer = SmbiosMiscGetString (TokenToGet); SECVerStrLen = StrLen(SECVer); if (SECVerStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_UCODE_VERSION); uCodeVer = SmbiosMiscGetString (TokenToGet); uCodeVerStrLen = StrLen(uCodeVer); if (uCodeVerStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_GOP_VERSION); GOPVer = SmbiosMiscGetString (TokenToGet); GOPStrLen = StrLen(GOPVer); if (GOPStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_MRC_VERSION_VALUE); MrcVer = SmbiosMiscGetString (TokenToGet); MRCVersionStrLen = StrLen(MrcVer); if (MRCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_PMC_FW_VALUE); PmcVer = SmbiosMiscGetString (TokenToGet); PMCVersionStrLen = StrLen(PmcVer); if (PMCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_ULPMC_FW_VALUE); UlpmcVer = SmbiosMiscGetString (TokenToGet); ULPMCVersionStrLen = StrLen(UlpmcVer); if (ULPMCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_PUNIT_FW_VALUE); PunitVer = SmbiosMiscGetString (TokenToGet); PUNITVersionStrLen = StrLen(PunitVer); if (PUNITVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_SOC_VALUE); SocVer = SmbiosMiscGetString (TokenToGet); SOCVersionStrLen = StrLen(SocVer); if (SOCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_BOARD_ID_VALUE); BoardVer = SmbiosMiscGetString (TokenToGet); BOARDVersionStrLen = StrLen(BoardVer); if (BOARDVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_FAB_ID_VALUE); FabVer = SmbiosMiscGetString (TokenToGet); FABVersionStrLen = StrLen(FabVer); if (FABVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_CPU_FLAVOR_VALUE); CpuFlavor = SmbiosMiscGetString (TokenToGet); CPUFLAVORStrLen = StrLen(CpuFlavor); if (CPUFLAVORStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION); BiosVer = SmbiosMiscGetString (TokenToGet); BIOSVersionStrLen = StrLen(BiosVer); if (BIOSVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_PMIC_VERSION); PmicVer = SmbiosMiscGetString (TokenToGet); PMICVersionStrLen = StrLen(PmicVer); if (PMICVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_TOUCH_VERSION); TouchVer = SmbiosMiscGetString (TokenToGet); TOUCHVersionStrLen = StrLen(TouchVer); if (TOUCHVersionStrLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_SECURE_BOOT); SecureBootMode = SmbiosMiscGetString(TokenToGet); SecureBootModeLen = StrLen(SecureBootMode); if (SecureBootModeLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_BOOT_MODE); BootMode = SmbiosMiscGetString(TokenToGet); BootModeLen = StrLen(BootMode); if (BootModeLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_SPEED_STEP); SpeedStepMode = SmbiosMiscGetString(TokenToGet); SpeedStepModeLen = StrLen(SpeedStepMode); if (SpeedStepModeLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_CPU_TURBO); CpuTurbo = SmbiosMiscGetString(TokenToGet); CpuTurboLen = StrLen(CpuTurbo); if (CpuTurboLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_CSTATE); MaxCState = SmbiosMiscGetString(TokenToGet); MaxCStateLen = StrLen(MaxCState); if (MaxCStateLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_GFX_TURBO); GfxTurbo = SmbiosMiscGetString(TokenToGet); GfxTurboLen = StrLen(GfxTurbo); if (GfxTurboLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_S0IX_VALUE); IdleReserve = SmbiosMiscGetString(TokenToGet); IdleReserveLen = StrLen(IdleReserve); if (S0ixLen > SMBIOS_STRING_MAX_LENGTH) { return; } TokenToGet = STRING_TOKEN (STR_MISC_RC6_VALUE); RC6 = SmbiosMiscGetString(TokenToGet); RC6Len = StrLen(RC6); if (RC6Len > SMBIOS_STRING_MAX_LENGTH) { return; } RecordLen = sizeof (SMBIOS_TABLE_TYPE94) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + PMCVersionStrLen + 1 + \ TOUCHVersionStrLen + 1 + PMICVersionStrLen + 1 + BIOSVersionStrLen + 1 + CPUFLAVORStrLen + 1 + \ BOARDVersionStrLen + 1 + FABVersionStrLen + 1 + PUNITVersionStrLen+ 1 + ULPMCVersionStrLen + 1 + \ MRCVersionStrLen + 1 + SOCVersionStrLen + 1 + SecureBootModeLen + 1 + BootModeLen + 1 + \ SpeedStepModeLen + 1 + CpuTurboLen + 1 + MaxCStateLen + 1 + GfxTurboLen + 1 + + RC6Len + 1 + 1; SmbiosRecord = AllocatePool(RecordLen); ZeroMem(SmbiosRecord, RecordLen); SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_MISC_VERSION_INFO; SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE94); // // Make handle chosen by smbios protocol.add automatically. // SmbiosRecord->Hdr.Handle = 0; SmbiosRecord->GopVersion = 1; SmbiosRecord->SECVersion = 2; SmbiosRecord->MRCVersion = 3; SmbiosRecord->uCodeVersion = 4; SmbiosRecord->PUnitVersion = 5; SmbiosRecord->PMCVersion = 6; SmbiosRecord->ULPMCVersion = 7; SmbiosRecord->SoCVersion = 8; SmbiosRecord->BoardVersion = 9; SmbiosRecord->FabVersion = 10; SmbiosRecord->CPUFlavor = 11; SmbiosRecord->BiosVersion = 12; SmbiosRecord->PmicVersion = 13; SmbiosRecord->TouchVersion = 14; SmbiosRecord->SecureBoot = 15; SmbiosRecord->BootMode = 16; SmbiosRecord->SpeedStepMode= 17; SmbiosRecord->CPUTurboMode = 18; SmbiosRecord->MaxCState = 19; SmbiosRecord->GfxTurbo = 20; SmbiosRecord->IdleReserve = 21; SmbiosRecord->RC6 = 22; OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); RecordLen -= sizeof (SMBIOS_TABLE_TYPE94); UnicodeStrToAsciiStrS (GOPVer, OptionalStrStart, RecordLen); StrIdx += GOPStrLen + 1; RecordLen -= GOPStrLen + 1; UnicodeStrToAsciiStrS (SECVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += SECVerStrLen + 1; RecordLen -= SECVerStrLen + 1; UnicodeStrToAsciiStrS (MrcVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += MRCVersionStrLen + 1; RecordLen -= MRCVersionStrLen + 1; UnicodeStrToAsciiStrS (uCodeVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += uCodeVerStrLen + 1; RecordLen -= uCodeVerStrLen + 1; UnicodeStrToAsciiStrS (PunitVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += PUNITVersionStrLen + 1; RecordLen -= PUNITVersionStrLen + 1; UnicodeStrToAsciiStrS (PmcVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += PMCVersionStrLen + 1; RecordLen -= PMCVersionStrLen + 1; UnicodeStrToAsciiStrS (UlpmcVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += ULPMCVersionStrLen + 1; RecordLen -= ULPMCVersionStrLen + 1; UnicodeStrToAsciiStrS (SocVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += SOCVersionStrLen +1; RecordLen -= SOCVersionStrLen +1; UnicodeStrToAsciiStrS (BoardVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += BOARDVersionStrLen + 1; RecordLen -= BOARDVersionStrLen + 1; UnicodeStrToAsciiStrS (FabVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += FABVersionStrLen + 1; RecordLen -= FABVersionStrLen + 1; UnicodeStrToAsciiStrS (CpuFlavor, OptionalStrStart + StrIdx, RecordLen); StrIdx += CPUFLAVORStrLen + 1; RecordLen -= CPUFLAVORStrLen + 1; UnicodeStrToAsciiStrS (BiosVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += BIOSVersionStrLen + 1; RecordLen -= BIOSVersionStrLen + 1; UnicodeStrToAsciiStrS (PmicVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += PMICVersionStrLen + 1; RecordLen -= PMICVersionStrLen + 1; UnicodeStrToAsciiStrS (TouchVer, OptionalStrStart + StrIdx, RecordLen); StrIdx += TOUCHVersionStrLen + 1; RecordLen -= TOUCHVersionStrLen + 1; UnicodeStrToAsciiStrS (SecureBootMode, OptionalStrStart + StrIdx, RecordLen); StrIdx += SecureBootModeLen + 1; RecordLen -= SecureBootModeLen + 1; UnicodeStrToAsciiStrS (BootMode, OptionalStrStart + StrIdx, RecordLen); StrIdx += BootModeLen + 1; RecordLen -= BootModeLen + 1; UnicodeStrToAsciiStrS (SpeedStepMode, OptionalStrStart + StrIdx, RecordLen); StrIdx += SpeedStepModeLen + 1; RecordLen -= SpeedStepModeLen + 1; UnicodeStrToAsciiStrS (CpuTurbo, OptionalStrStart + StrIdx, RecordLen); StrIdx += CpuTurboLen + 1; RecordLen -= CpuTurboLen + 1; UnicodeStrToAsciiStrS (MaxCState, OptionalStrStart + StrIdx, RecordLen); StrIdx += MaxCStateLen + 1; RecordLen -= MaxCStateLen + 1; UnicodeStrToAsciiStrS (GfxTurbo, OptionalStrStart + StrIdx, RecordLen); StrIdx += GfxTurboLen + 1; RecordLen -= GfxTurboLen + 1; UnicodeStrToAsciiStrS (IdleReserve, OptionalStrStart + StrIdx, RecordLen); StrIdx += S0ixLen + 1; RecordLen -= S0ixLen + 1; UnicodeStrToAsciiStrS (RC6, OptionalStrStart + StrIdx, RecordLen); StrIdx += RC6Len + 1; RecordLen -= RC6Len + 1; // // Now we have got the full smbios record, call smbios protocol to add this record. // SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; Status = SmbiosProtocol-> Add ( SmbiosProtocol, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord ); FreePool(SmbiosRecord); return; } /** This function makes boot time changes to the contents of the MiscOemType0x94 (Type 0x94). @param RecordData Pointer to copy of RecordData from the Data Table. @retval EFI_SUCCESS All parameters were valid. @retval EFI_UNSUPPORTED Unexpected RecordType value. @retval EFI_INVALID_PARAMETER Invalid parameter was found. **/ MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x94) { EFI_STATUS Status; EFI_EVENT AddSmbiosT0x94CallbackEvent; Status = EfiCreateEventReadyToBootEx ( TPL_CALLBACK, AddSmbiosT0x94Callback, RecordData, &AddSmbiosT0x94CallbackEvent ); ASSERT_EFI_ERROR (Status); return Status; }