1133 lines
33 KiB
C
1133 lines
33 KiB
C
/** @file
|
|
Feature SMBIOS Override core function
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2016, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "SmbiosOverride.h"
|
|
|
|
EFI_SMBIOS_PROTOCOL *mSmbiosProtocol = NULL;
|
|
EFI_HANDLE mImageHandle = NULL;
|
|
|
|
//
|
|
// Please sync table to mReviseSmbiosTypes
|
|
//
|
|
REVISE_SMBIOS_TABLE_DATA mReviseSmbiosTable [] = {
|
|
ReviseL05SmbiosType0,
|
|
ReviseL05SmbiosType01,
|
|
ReviseL05SmbiosType02,
|
|
ReviseL05SmbiosType03
|
|
};
|
|
|
|
//
|
|
// Please sync table to mReviseSmbiosTable
|
|
//
|
|
EFI_SMBIOS_TYPE mReviseSmbiosTypes [] = {
|
|
EFI_SMBIOS_TYPE_BIOS_INFORMATION, // Type 0
|
|
EFI_SMBIOS_TYPE_SYSTEM_INFORMATION, // Type 1
|
|
EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, // Type 2
|
|
EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE // TYpe 3
|
|
};
|
|
|
|
CHAR8 *mRegionCode[] = {
|
|
"MO",
|
|
"HK",
|
|
"TW"
|
|
};
|
|
|
|
ODM_SET_DMI_DATA mODMSetSMBIOSData;
|
|
|
|
UINT32 mFeatureVersion = 0;
|
|
|
|
/**
|
|
Get SMBIOS PCD type string count.
|
|
|
|
@param SmbiosPcdTypeString A pointer to the SMBIOS PCD type string.
|
|
|
|
@return StrCount Count of SMBIOS PCD type string.
|
|
**/
|
|
UINTN
|
|
GetSmbiosPcdTypeStringCount (
|
|
CHAR8 *SmbiosPcdTypeString
|
|
)
|
|
{
|
|
CHAR8 *StringPtr;
|
|
UINTN StrCount;
|
|
|
|
if (SmbiosPcdTypeString == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
StrCount = 0;
|
|
StringPtr = SmbiosPcdTypeString;
|
|
|
|
while (*StringPtr != '\0') {
|
|
if (*StringPtr == ';') {
|
|
StrCount++;
|
|
}
|
|
|
|
StringPtr++;
|
|
}
|
|
|
|
return StrCount;
|
|
}
|
|
|
|
/**
|
|
Get SMBIOS PCD type string array.
|
|
|
|
@param SmbiosPcdTypeString A pointer to the SMBIOS PCD type string.
|
|
@param SmbiosPcdTypeStringCount SMBIOS PCD type string Count.
|
|
@param SmbiosPcdTypeStringArray A pointer to the SMBIOS PCD type string Array.
|
|
|
|
@retval EFI_SUCCESS This function execute successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
GetSmbiosPcdTypeStringArray (
|
|
CHAR8 *SmbiosPcdTypeString,
|
|
UINTN SmbiosPcdTypeStringCount,
|
|
CHAR8 **SmbiosPcdTypeStringArray
|
|
)
|
|
{
|
|
CHAR8 *StringPtr;
|
|
UINTN StrCount;
|
|
UINTN StrIndex;
|
|
|
|
if (SmbiosPcdTypeString == NULL) {
|
|
return RETURN_INVALID_PARAMETER;
|
|
}
|
|
|
|
StrCount = 0;
|
|
StrIndex = 0;
|
|
StringPtr = SmbiosPcdTypeString;
|
|
|
|
while (*StringPtr != '\0') {
|
|
if (*StringPtr == ';') {
|
|
*StringPtr = '\0';
|
|
SmbiosPcdTypeStringArray[StrCount] = StringPtr - StrIndex;
|
|
StrCount++;
|
|
StrIndex = 0;
|
|
|
|
} else {
|
|
StrIndex++;
|
|
}
|
|
|
|
StringPtr++;
|
|
}
|
|
|
|
if (SmbiosPcdTypeStringCount != StrCount) {
|
|
return RETURN_INVALID_PARAMETER;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Find SMBIOS PCD type string Pointer.
|
|
|
|
@param SmbiosPcdTypeStringArray A pointer to the SMBIOS PCD type string Array.
|
|
@param SmbiosPcdTypeStringCount SMBIOS PCD type string Count.
|
|
@param FindString A pointer to the Find string.
|
|
|
|
@return String pointer of find SMBIOS PCD type string.
|
|
**/
|
|
CHAR8 *
|
|
FindSmbiosPcdTypeStringPtr (
|
|
CHAR8 **SmbiosPcdTypeStringArray,
|
|
UINTN SmbiosPcdTypeStringCount,
|
|
CHAR8 *FindString
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < SmbiosPcdTypeStringCount; Index++) {
|
|
if (AsciiStrCmp (SmbiosPcdTypeStringArray[Index], FindString) == 0) {
|
|
return SmbiosPcdTypeStringArray[Index];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
Is region code.
|
|
|
|
@param CountryCode A pointer to the country code.
|
|
|
|
@return TRUE Country code is region.
|
|
@return FALSE Country code is not region.
|
|
**/
|
|
BOOLEAN
|
|
IsRegionCode (
|
|
CHAR8 *CountryCode
|
|
)
|
|
{
|
|
BOOLEAN IsRegionCode;
|
|
UINTN Index;
|
|
|
|
IsRegionCode = FALSE;
|
|
|
|
for (Index = 0; Index < sizeof (mRegionCode) / sizeof (CHAR8 *); Index++) {
|
|
if (AsciiStrCmp (mRegionCode[Index], CountryCode) == 0) {
|
|
IsRegionCode = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return IsRegionCode;
|
|
}
|
|
|
|
/**
|
|
Remove SMBIOS PCD type strings.
|
|
|
|
@param RemoveString A pointer to the remove string.
|
|
@param SmbiosPcdTypeStringArray A pointer to the SMBIOS PCD type string Array.
|
|
@param SmbiosPcdTypeStringCount SMBIOS PCD type string Count.
|
|
@param StringCount A pointer to the string count.
|
|
@param IsNeedUpdate A pointer to is need update flag.
|
|
**/
|
|
VOID
|
|
RemoveSmbiosPcdTypeStrings (
|
|
CHAR8 *RemoveString,
|
|
CHAR8 **SmbiosPcdTypeStringArray,
|
|
UINTN SmbiosPcdTypeStringCount,
|
|
UINT8 *StringCount,
|
|
BOOLEAN *IsNeedUpdate
|
|
)
|
|
{
|
|
CHAR8 *StringPtr;
|
|
|
|
StringPtr = FindSmbiosPcdTypeStringPtr (SmbiosPcdTypeStringArray, SmbiosPcdTypeStringCount, RemoveString);
|
|
|
|
if (StringPtr == NULL) {
|
|
return;
|
|
}
|
|
|
|
*StringPtr = '\0';
|
|
(*StringCount)--;
|
|
*IsNeedUpdate = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Update SMBIOS PCD type string.
|
|
|
|
@param SmbiosPcdTypeStringArray A pointer to the SMBIOS PCD type string Array.
|
|
@param SmbiosPcdTypeStringCount SMBIOS PCD type string Count.
|
|
@param StringBuffer A pointer to the string buffer.
|
|
@param StringSize Size of string buffer.
|
|
**/
|
|
VOID
|
|
UpdateSmbiosPcdTypeString (
|
|
CHAR8 **SmbiosPcdTypeStringArray,
|
|
UINTN SmbiosPcdTypeStringCount,
|
|
CHAR8 *StringBuffer,
|
|
UINTN StringSize
|
|
)
|
|
{
|
|
CHAR8 *StringPtr;
|
|
UINTN Index;
|
|
|
|
StringPtr = StringBuffer;
|
|
|
|
for (Index = 0; Index < SmbiosPcdTypeStringCount; Index++) {
|
|
|
|
if (AsciiStrLen (SmbiosPcdTypeStringArray[Index]) == 0) {
|
|
continue;
|
|
}
|
|
|
|
AsciiStrCpyS (StringPtr, StringSize - (StringBuffer - StringPtr), SmbiosPcdTypeStringArray[Index]);
|
|
StringPtr += AsciiStrLen (SmbiosPcdTypeStringArray[Index]);
|
|
*StringPtr = ';';
|
|
StringPtr++;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
L05 update SMBIOS PCD type 11.
|
|
|
|
@param None.
|
|
**/
|
|
VOID
|
|
L05UpdateSmbiosPcdType011 (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BOOLEAN IsNeedUpdate;
|
|
SMBIOS_TABLE_TYPE11 *Type11Record;
|
|
CHAR8 *Type11Strings;
|
|
UINTN Type11StringsSize;
|
|
UINTN Type11StringsCount;
|
|
CHAR8 **Type11StringArray;
|
|
CHAR8 *CountryCode;
|
|
CHAR8 *TempStrings;
|
|
CHAR8 *StringPtr;
|
|
UINTN BufferSize;
|
|
|
|
IsNeedUpdate = FALSE;
|
|
Type11Record = NULL;
|
|
Type11Strings = NULL;
|
|
Type11StringsSize = 0;
|
|
Type11StringsCount = 0;
|
|
Type11StringArray = NULL;
|
|
TempStrings = NULL;
|
|
StringPtr = NULL;
|
|
BufferSize = 0;
|
|
|
|
Type11Record = (SMBIOS_TABLE_TYPE11 *) PcdGetPtr (PcdType011Record);
|
|
Type11Strings = (CHAR8 *) PcdGetPtr (PcdType011Strings);
|
|
Type11StringsSize = AsciiStrSize (Type11Strings);
|
|
|
|
if (Type11Record == NULL || Type11Strings == NULL || Type11StringsSize == 0) {
|
|
return;
|
|
}
|
|
|
|
Type11StringsCount = GetSmbiosPcdTypeStringCount (Type11Strings);
|
|
|
|
if (Type11StringsCount == 0) {
|
|
return;
|
|
}
|
|
|
|
Type11StringArray = AllocateZeroPool (Type11StringsCount * sizeof (CHAR8 *));
|
|
|
|
if (Type11StringArray == NULL) {
|
|
return;
|
|
}
|
|
|
|
Status = GetSmbiosPcdTypeStringArray (Type11Strings, Type11StringsCount, Type11StringArray);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
TempStrings = AllocateZeroPool (Type11StringsSize);
|
|
|
|
if (TempStrings == NULL) {
|
|
return;
|
|
}
|
|
|
|
BufferSize = AsciiStrSize (L05_SMBIOS_ISO_3166_ALPHA_2_CODE_STRING);
|
|
CountryCode = AllocateZeroPool (BufferSize);
|
|
Status = OemSvcGetCountryCode (CountryCode, BufferSize);
|
|
|
|
if (Status == EFI_MEDIA_CHANGED) {
|
|
StringPtr = FindSmbiosPcdTypeStringPtr (Type11StringArray, Type11StringsCount, L05_SMBIOS_TYPE11_COUNTRY_CODE_STRING);
|
|
|
|
if (StringPtr == NULL) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// [Lenovo China Minimum BIOS Spec V1.40]
|
|
// 3.3.5.2 Type 11 OEM string
|
|
// 4 if XX = "MO", "HK" and "TW", BIOS must change the country code string to "Region - XX".
|
|
//
|
|
if (!IsRegionCode (CountryCode)) {
|
|
AsciiStrnCpyS (StringPtr + AsciiStrLen (L05_SMBIOS_TYPE11_COUNTRY_CODE_STRING) - AsciiStrLen (L05_SMBIOS_ISO_3166_ALPHA_2_CODE_STRING), AsciiStrSize (StringPtr), CountryCode, AsciiStrLen (L05_SMBIOS_ISO_3166_ALPHA_2_CODE_STRING));
|
|
|
|
} else {
|
|
AsciiSPrint (StringPtr, AsciiStrSize (StringPtr), L05_SMBIOS_TYPE11_REGION_CODE_STRING, (CHAR8 *) CountryCode);
|
|
}
|
|
|
|
IsNeedUpdate = TRUE;
|
|
|
|
} else {
|
|
RemoveSmbiosPcdTypeStrings (
|
|
L05_SMBIOS_TYPE11_COUNTRY_CODE_STRING,
|
|
Type11StringArray,
|
|
Type11StringsCount,
|
|
&(Type11Record->StringCount),
|
|
&IsNeedUpdate
|
|
);
|
|
}
|
|
|
|
#ifndef L05_MODERN_PRELOAD_SUPPORT
|
|
//
|
|
// [BIOS and Tool Requirements for Modern Preload Support Version 1.10]
|
|
// Don't add this SMBIOS Type 11 (OEM String) if system not support Modern Preload.
|
|
//
|
|
RemoveSmbiosPcdTypeStrings (
|
|
L05_SMBIOS_TYPE11_MODERN_PRELOAD_STRING,
|
|
Type11StringArray,
|
|
Type11StringsCount,
|
|
&(Type11Record->StringCount),
|
|
&IsNeedUpdate
|
|
);
|
|
#endif
|
|
|
|
if (IsNeedUpdate) {
|
|
UpdateSmbiosPcdTypeString (Type11StringArray, Type11StringsCount, TempStrings, Type11StringsSize);
|
|
|
|
//
|
|
// [Lenovo China Minimum BIOS Spec V1.40]
|
|
// 3.3.5.2 Type 11 OEM string
|
|
// 5 if country code was not injected during manufacture process, BIOS must not build country code string in Type 11.
|
|
//
|
|
if (Type11Record->StringCount == 0) {
|
|
PcdSetBoolS (PcdActiveSmbiosType011, FALSE);
|
|
}
|
|
|
|
BufferSize = sizeof (SMBIOS_TABLE_TYPE11);
|
|
PcdSetPtrS (PcdType011Record, &BufferSize, Type11Record);
|
|
|
|
BufferSize = AsciiStrSize (TempStrings);
|
|
PcdSetPtrS (PcdType011Strings, &BufferSize, TempStrings);
|
|
}
|
|
|
|
FreePool (TempStrings);
|
|
FreePool (Type11StringArray);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
L05 update SMBIOS PCD.
|
|
|
|
@param None.
|
|
**/
|
|
VOID
|
|
L05UpdateSmbiosPcd (
|
|
VOID
|
|
)
|
|
{
|
|
L05UpdateSmbiosPcdType011 ();
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
BuildL05SmbiosType200 (
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
L05_IDEAPAD_IDENTIFY *SmbiosPtr;
|
|
UINT8 *TempSmbiosPtr;
|
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
EFI_SMBIOS_PROTOCOL *Smbios;
|
|
CHAR8 *PcdString;
|
|
UINT8 StrLength;
|
|
|
|
SmbiosPtr = NULL;
|
|
TempSmbiosPtr = NULL;
|
|
Smbios = NULL;
|
|
|
|
//
|
|
// Calculate total string length
|
|
//
|
|
PcdString = (CHAR8 *) PcdGetPtr (PcdL05Type200ID);
|
|
StrLength = (UINT8) AsciiStrLen (PcdString) + 1;
|
|
PcdString = (CHAR8 *) PcdGetPtr (PcdL05Type200MTM);
|
|
StrLength += (UINT8) AsciiStrLen (PcdString) + 1;
|
|
|
|
//
|
|
// Calculate total structure length
|
|
//
|
|
StrLength += sizeof (L05_IDEAPAD_IDENTIFY);
|
|
SmbiosPtr = AllocateZeroPool (StrLength);
|
|
|
|
SmbiosPtr->Header.Type = 0xC8; // SMBIOS Type 200
|
|
SmbiosPtr->Header.Length = sizeof (L05_IDEAPAD_IDENTIFY) - 1;
|
|
SmbiosPtr->Header.Handle = 0x00;
|
|
SmbiosPtr->ID = 0x01;
|
|
SmbiosPtr->MTM = 0x02;
|
|
|
|
//
|
|
// Others major/minor number
|
|
//
|
|
SmbiosPtr->ProductData.SpecMajorNumber = (UINT8) (mFeatureVersion / 100);
|
|
SmbiosPtr->ProductData.SpecMinorNumber = (UINT8) (mFeatureVersion % 100);
|
|
SmbiosPtr->ProductData.EepromSpecMajorNumber = PcdGet8 (PcdL05Type200EepromSpecMajorNumber);
|
|
SmbiosPtr->ProductData.EepromSpecMinorNumber = PcdGet8 (PcdL05Type200EepromSpecMinorNumber);
|
|
SmbiosPtr->ProductData.PmSpecMajorNumber = PcdGet8 (PcdL05Type200PmSpecMajorNumber);
|
|
SmbiosPtr->ProductData.PmSpecMinorNumber = PcdGet8 (PcdL05Type200PmSpecMinorNumber);
|
|
SmbiosPtr->ProductData.SmiIOPort = (UINT8) PcdGet16 (PcdSoftwareSmiPort);
|
|
SmbiosPtr->ProductData.SoftwareSmiValue = EFI_L05_VARIABLE_CALLBACK;
|
|
SmbiosPtr->ProductData.L05VarSpecMajorNumber = PcdGet8 (PcdL05Type200L05VarSpecMajorNumber);
|
|
SmbiosPtr->ProductData.L05VarSpecMinorNumber = PcdGet8 (PcdL05Type200L05VarSpecMinorNumber);
|
|
|
|
//
|
|
// ID string
|
|
//
|
|
PcdString = (CHAR8 *) PcdGetPtr (PcdL05Type200ID);
|
|
StrLength = (UINT8) AsciiStrLen (PcdString) + 1;
|
|
TempSmbiosPtr = (UINT8 *) &(SmbiosPtr->IdString);
|
|
AsciiStrCpyS (TempSmbiosPtr, StrLength, PcdString);
|
|
|
|
//
|
|
// MTM string
|
|
//
|
|
TempSmbiosPtr += StrLength;
|
|
PcdString = (CHAR8 *) PcdGetPtr (PcdL05Type200MTM);
|
|
StrLength = (UINT8) AsciiStrLen (PcdString) + 1;
|
|
AsciiStrCpyS (TempSmbiosPtr, StrLength ,PcdString);
|
|
|
|
Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &Smbios);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
|
Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) SmbiosPtr);
|
|
}
|
|
|
|
FreePool (SmbiosPtr);
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
BuildL05SmbiosType24 (
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SMBIOS_TABLE_TYPE24 *Type24Record;
|
|
UINTN StructureSize;
|
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
EFI_SMBIOS_PROTOCOL *Smbios;
|
|
UINTN DataSize;
|
|
UINT8 *PasswordBuf;
|
|
SYSTEM_CONFIGURATION SetupNvData;
|
|
UINTN BufferSize;
|
|
|
|
Smbios = NULL;
|
|
|
|
Type24Record = NULL;
|
|
StructureSize = sizeof (SMBIOS_TABLE_TYPE24) + 2; // Add the size of the terminating double null.
|
|
Type24Record = AllocateZeroPool (StructureSize);
|
|
|
|
if (Type24Record == NULL) {
|
|
return;
|
|
}
|
|
|
|
Type24Record->Hdr.Type = 0x18;
|
|
Type24Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE24);
|
|
Type24Record->Hdr.Handle = 0x00;
|
|
Type24Record->HardwareSecuritySettings = 0;
|
|
|
|
//
|
|
// Check supervisor password
|
|
//
|
|
PasswordBuf = NULL;
|
|
DataSize = FixedPcdGet32 (PcdDefaultSysPasswordMaxLength) + 2;
|
|
PasswordBuf = AllocateZeroPool (DataSize);
|
|
|
|
if (PasswordBuf == NULL) {
|
|
return;
|
|
}
|
|
|
|
Status = OemSvcGetSystemPasswords (SystemSupervisor, DataSize, PasswordBuf);
|
|
|
|
#ifndef L05_NOTEBOOK_PASSWORD_ENABLE
|
|
if (IsSystemPasswordChecksumValid (PasswordBuf)) {
|
|
#else
|
|
if (L05HaveSystemPassword (PasswordBuf)) {
|
|
#endif
|
|
Type24Record->HardwareSecuritySettings |= (0x01 << 2);
|
|
}
|
|
|
|
//
|
|
// Check Power On Password Status
|
|
//
|
|
BufferSize = sizeof (SetupNvData);
|
|
Status = gRT->GetVariable (
|
|
L"Setup",
|
|
&gSystemConfigurationGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
(VOID *) &SetupNvData
|
|
);
|
|
|
|
if (SetupNvData.PowerOnPassword == POWER_ON_PASSWORD) {
|
|
Type24Record->HardwareSecuritySettings |= (0x01 << 6);
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &Smbios);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
|
Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) Type24Record);
|
|
}
|
|
|
|
FreePool (Type24Record);
|
|
FreePool (PasswordBuf);
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
ReviseL05SmbiosRecord (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_SMBIOS_TABLE_HEADER *RecordHeader;
|
|
UINT8 ReviseCounter;
|
|
|
|
RecordHeader = NULL;
|
|
ReviseCounter = 0;
|
|
|
|
for (ReviseCounter = 0; ReviseCounter < sizeof (mReviseSmbiosTypes); ReviseCounter++) {
|
|
|
|
GetSmbiosHandle (mReviseSmbiosTypes[ReviseCounter], &RecordHeader);
|
|
mReviseSmbiosTable[ReviseCounter] (RecordHeader);
|
|
}
|
|
|
|
if (mFeatureVersion >= SUPPORT_TYPE_24_200_VERSION) {
|
|
|
|
BuildL05SmbiosType24 ();
|
|
BuildL05SmbiosType200 ();
|
|
}
|
|
|
|
gBS->CloseEvent (Event);
|
|
}
|
|
|
|
VOID
|
|
GetSmbiosHandle (
|
|
IN EFI_SMBIOS_TYPE RecordType,
|
|
IN OUT EFI_SMBIOS_TABLE_HEADER **Record
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SMBIOS_TABLE_HEADER *Buffer;
|
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
|
|
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
|
|
|
Status = mSmbiosProtocol->GetNext (
|
|
mSmbiosProtocol,
|
|
&SmbiosHandle,
|
|
&RecordType,
|
|
&Buffer,
|
|
NULL
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
*Record = Buffer;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
UpdateRecordString (
|
|
IN EFI_SMBIOS_HANDLE *SmbiosHandle,
|
|
IN CHAR16 *PcdString,
|
|
IN UINTN *StringId
|
|
)
|
|
{
|
|
UINTN StrLength;
|
|
|
|
StrLength = StrLen (PcdString);
|
|
mSmbiosProtocol->UpdateString (mSmbiosProtocol, SmbiosHandle, StringId, (CHAR8 *) PcdString);
|
|
}
|
|
|
|
VOID
|
|
ReviseL05SmbiosType0 (
|
|
IN EFI_SMBIOS_TABLE_HEADER *RecordData
|
|
)
|
|
{
|
|
EFI_L05_MISC_BIOS_CHARACTERISTICS *Charcteristics;
|
|
SMBIOS_TABLE_TYPE0 *ResviseType0Record;
|
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
UINTN StringId;
|
|
CHAR16 *PcdString;
|
|
CHAR8 *AsciiString;
|
|
UINTN StrLength;
|
|
|
|
SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *) RecordData)->Handle;
|
|
ResviseType0Record = (SMBIOS_TABLE_TYPE0 *) RecordData;
|
|
|
|
|
|
//
|
|
//Type00 - Offset 0x12 BIOS Characteristics Extension Bytes
|
|
//
|
|
Charcteristics = (EFI_L05_MISC_BIOS_CHARACTERISTICS *) ((UINT32 *) &(ResviseType0Record->BiosCharacteristics) + 1);
|
|
Charcteristics->EnclosureType = PcdGet32 (PcdL05Type00CharacterExEnclosureType);
|
|
Charcteristics->BrandType = PcdGet32 (PcdL05Type00CharacterExBrandType);
|
|
|
|
//
|
|
//Type00 - Offset 0x14 & 0x15 System BIOS
|
|
//
|
|
|
|
ResviseType0Record->SystemBiosMajorRelease = PcdGet8 (PcdL05Type00BIOSMajorRelease);
|
|
ResviseType0Record->SystemBiosMinorRelease = PcdGet8 (PcdL05Type00BIOSMinorRelease);
|
|
|
|
//
|
|
//Type00 - Offset 0x16 & 0x17 Embedded Controller Firmware
|
|
//
|
|
ResviseType0Record->EmbeddedControllerFirmwareMajorRelease = PcdGet8 (PcdL05Type00ECMajorRelease);
|
|
ResviseType0Record->EmbeddedControllerFirmwareMinorRelease = PcdGet8 (PcdL05Type00ECMinorRelease);
|
|
|
|
//
|
|
//Type0 - Offset 0x04 BIOS Vendor
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdFirmwareVendor);
|
|
StrLength = StrLen (PcdString);
|
|
AsciiString = AllocateZeroPool (StrLength + 1);
|
|
UnicodeStrToAsciiStrS (PcdString, AsciiString, StrLength + 1);
|
|
StringId = ResviseType0Record->Vendor;
|
|
UpdateRecordString (&SmbiosHandle, (CHAR16 *) AsciiString, &StringId);
|
|
FreePool (AsciiString);
|
|
|
|
//
|
|
//Type00 - Offset 0x05 BIOS Version
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
|
|
StrLength = StrLen (PcdString);
|
|
AsciiString = AllocateZeroPool (StrLength + 1);
|
|
UnicodeStrToAsciiStrS (PcdString, AsciiString, StrLength + 1);
|
|
StringId = ResviseType0Record->BiosVersion;
|
|
UpdateRecordString (&SmbiosHandle, (CHAR16 *) AsciiString, &StringId);
|
|
FreePool (AsciiString);
|
|
|
|
//
|
|
//Type00 - Offset 0x08 BIOS Release Data
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdFirmwareReleaseDateString);
|
|
StrLength = StrLen (PcdString);
|
|
AsciiString = AllocateZeroPool (StrLength + 1);
|
|
UnicodeStrToAsciiStrS (PcdString ,AsciiString, StrLength + 1);
|
|
StringId = ResviseType0Record->BiosReleaseDate;
|
|
UpdateRecordString (&SmbiosHandle, (CHAR16 *) AsciiString, &StringId);
|
|
FreePool (AsciiString);
|
|
}
|
|
|
|
VOID
|
|
ReviseL05SmbiosType01 (
|
|
IN EFI_SMBIOS_TABLE_HEADER *RecordData
|
|
)
|
|
{
|
|
SMBIOS_TABLE_TYPE1 *ResviseType01Record;
|
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
UINTN StringId;
|
|
UINT8 *UUID;
|
|
CHAR16 *PcdString;
|
|
CHAR8 *AsciiString;
|
|
UINTN StrLength;
|
|
#ifdef L05_SMB_BIOS_ENABLE
|
|
UINT8 WakeUpType;
|
|
EFI_STATUS Status;
|
|
#endif
|
|
|
|
SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *) RecordData)->Handle;
|
|
ResviseType01Record = (SMBIOS_TABLE_TYPE1 *) RecordData;
|
|
|
|
//
|
|
//Type01 - Offset 0x08 UUID
|
|
//
|
|
UUID = (UINT8 *) PcdGetPtr (PcdL05Type01UUID);
|
|
CopyMem (&(ResviseType01Record->Uuid), UUID, UUID_SIZE);
|
|
|
|
#ifdef L05_SMB_BIOS_ENABLE
|
|
//
|
|
// [Lenovo Dock BIOS Writer's Guide (BWG) V0.3]
|
|
// 3.2 Implement Guidance
|
|
// Check a wake up reason reported by EC. If system is waked up by EC due to WOL
|
|
// of Lenovo VDM , BIOS need update SMBIOS type 1 wake up type accordingly, and
|
|
// do any related actions defined by product
|
|
// 3.2.2 Flowchart
|
|
// WOL from Dock
|
|
// - Set BootTypeWOL flag Clear WOL status
|
|
// - Set SMBIOS Type 1 Wake-up Type to 0x05 'LAN Remote'
|
|
//
|
|
//Type01 - Offset 0x18 Wake up type
|
|
//
|
|
Status = OemSvcEcGetWakeUpType (&WakeUpType);
|
|
|
|
if (Status == EFI_MEDIA_CHANGED) {
|
|
ResviseType01Record->WakeUpType = WakeUpType;
|
|
}
|
|
#endif
|
|
|
|
//
|
|
//Type01 - Offset 0x04 Manufacturer
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdFirmwareVendor);
|
|
StrLength = StrLen (PcdString);
|
|
AsciiString = AllocateZeroPool (StrLength + 1);
|
|
UnicodeStrToAsciiStrS (PcdString, AsciiString, StrLength + 1);
|
|
StringId = ResviseType01Record->Manufacturer;
|
|
UpdateRecordString (&SmbiosHandle, (CHAR16 *) AsciiString, &StringId);
|
|
FreePool (AsciiString);
|
|
|
|
//
|
|
//Type01 - Offset 0x05 Product Name
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type01ProductName);
|
|
StringId = ResviseType01Record->ProductName;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type01 - Offset 0x06 Version
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type01Version);
|
|
StringId = ResviseType01Record->Version;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type01 - Offset 0x07 Serial Number
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type01SerialNumber);
|
|
StringId = ResviseType01Record->SerialNumber;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type01 - Offset 0x19 SKU Number
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type01SKUNumber);
|
|
StringId = ResviseType01Record->SKUNumber;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type01 - Offset 0x1A Family
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type01Family);
|
|
StringId = ResviseType01Record->Family;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
}
|
|
|
|
VOID
|
|
ReviseL05SmbiosType02 (
|
|
IN EFI_SMBIOS_TABLE_HEADER *RecordData
|
|
)
|
|
{
|
|
SMBIOS_TABLE_TYPE2 *ResviseType02Record;
|
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
UINTN StringId;
|
|
CHAR16 *PcdString;
|
|
CHAR8 *AsciiString;
|
|
UINTN StrLength;
|
|
|
|
SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *) RecordData)->Handle;
|
|
ResviseType02Record = (SMBIOS_TABLE_TYPE2 *) RecordData;
|
|
|
|
//
|
|
//Type02 - Offset 0x04 Manufacturer
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdFirmwareVendor);
|
|
StrLength = StrLen (PcdString);
|
|
AsciiString = AllocateZeroPool (StrLength + 1);
|
|
UnicodeStrToAsciiStrS (PcdString, AsciiString, StrLength + 1);
|
|
StringId = ResviseType02Record->Manufacturer;
|
|
UpdateRecordString (&SmbiosHandle, (CHAR16 *) AsciiString, &StringId);
|
|
FreePool (AsciiString);
|
|
|
|
//
|
|
//Type02 - Offset 0x05 Product
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type02Product);
|
|
StringId = ResviseType02Record->ProductName;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type02 - Offset 0x06 Version
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type02Version);
|
|
StringId = ResviseType02Record->Version;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type02 - Offset 0x07 Serial Number
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type02SerialNumber);
|
|
StringId = ResviseType02Record->SerialNumber;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type02 - Offset 0x08 Asset Tag
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type02AssetTag);
|
|
StringId = ResviseType02Record->AssetTag;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
}
|
|
|
|
VOID
|
|
ReviseL05SmbiosType03 (
|
|
IN EFI_SMBIOS_TABLE_HEADER *RecordData
|
|
)
|
|
{
|
|
SMBIOS_TABLE_TYPE3 *ResviseType03Record;
|
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
UINTN StringId;
|
|
CHAR16 *PcdString;
|
|
CHAR8 *AsciiString;
|
|
UINTN StrLength;
|
|
|
|
SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *) RecordData)->Handle;
|
|
ResviseType03Record = (SMBIOS_TABLE_TYPE3 *) RecordData;
|
|
|
|
//
|
|
//Type03 - Offset 0x05 Type
|
|
//
|
|
ResviseType03Record->Type = PcdGet8 (PcdL05Type03Type);
|
|
|
|
//
|
|
//Type03 - Offset 0x04 Manufacturer
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdFirmwareVendor);
|
|
StrLength = StrLen (PcdString);
|
|
AsciiString = AllocateZeroPool (StrLength + 1);
|
|
UnicodeStrToAsciiStrS (PcdString, AsciiString, StrLength + 1);
|
|
StringId = ResviseType03Record->Manufacturer;
|
|
UpdateRecordString (&SmbiosHandle, (CHAR16 *) AsciiString, &StringId);
|
|
FreePool (AsciiString);
|
|
|
|
//
|
|
//Type03 - Offset 0x06 Version
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type03Version);
|
|
StringId = ResviseType03Record->Version;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type03 - Offset 0x07 Serial Number
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type03SerialNumber);
|
|
StringId = ResviseType03Record->SerialNumber;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
|
|
//
|
|
//Type03 - Offset 0x08 Asset Tag
|
|
//
|
|
PcdString = (CHAR16 *) PcdGetPtr (PcdL05Type03AssetTag);
|
|
StringId = ResviseType03Record->AssetTag;
|
|
UpdateRecordString (&SmbiosHandle, PcdString, &StringId);
|
|
}
|
|
|
|
VOID
|
|
RemoveSmbiosRecord (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
EFI_SMBIOS_TABLE_HEADER *Record;
|
|
UINT8 RemoveType;
|
|
UINT8 RemoveSmbiosList[MAX_OF_SMBIOS_TYPE] = {0};
|
|
UINT8 MaxOfSMBIOSType;
|
|
BOOLEAN IsNeedRemoveSmbiosType;
|
|
|
|
SmbiosHandle = 0;
|
|
Record = NULL;
|
|
RemoveType = 0;
|
|
MaxOfSMBIOSType = 0xFF;
|
|
IsNeedRemoveSmbiosType = FALSE;
|
|
|
|
Status = OemSvcRemoveSmbiosType (RemoveSmbiosList);
|
|
|
|
if ((Status == EFI_UNSUPPORTED) && (!IsNeedRemoveSmbiosType)) {
|
|
return;
|
|
}
|
|
|
|
for (RemoveType = 0; RemoveType < MaxOfSMBIOSType; RemoveType++) {
|
|
if (RemoveSmbiosList[RemoveType] != DISABLE_SMBIOS_TYPE_REQUIRED) {
|
|
continue;
|
|
}
|
|
|
|
do {
|
|
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
|
|
|
Status = mSmbiosProtocol->GetNext (
|
|
mSmbiosProtocol,
|
|
&SmbiosHandle,
|
|
(EFI_SMBIOS_TYPE *) &RemoveType,
|
|
&Record,
|
|
NULL
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
mSmbiosProtocol->Remove (mSmbiosProtocol, SmbiosHandle);
|
|
}
|
|
|
|
//
|
|
// Some type have more than one handle in Smbios.
|
|
//
|
|
} while (!EFI_ERROR (Status));
|
|
}
|
|
|
|
gBS->CloseEvent (Event);
|
|
}
|
|
|
|
/**
|
|
Callback function to override SMBIOS.
|
|
|
|
@param[in] Event The event that is signaled.
|
|
@param[in] Context A pointer to the context data.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
L05SmbiosOverrideCallback (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_EVENT L05SmbiosOverrideEvent;
|
|
EFI_EVENT L05SetPcdDmiDataEvent;
|
|
VOID *EndOfSmbiosOverrideBootEventRegistration;
|
|
VOID *BdsArchEventRegistration;
|
|
EFI_L05_SMBIOS_INTERFACE_PROTOCOL *L05SmbiosInterfacePtr;
|
|
|
|
Status = EFI_SUCCESS;
|
|
EndOfSmbiosOverrideBootEventRegistration = NULL;
|
|
BdsArchEventRegistration = NULL;
|
|
L05SmbiosInterfacePtr = NULL;
|
|
|
|
mFeatureVersion = LATEST_L05_SPEC_VERSION;
|
|
|
|
//
|
|
// Check gEfiSmbiosProtocolGuid is ready.
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiSmbiosProtocolGuid,
|
|
NULL,
|
|
(VOID **) &mSmbiosProtocol
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
Status = OemSvcSwitchFeatureVersion (&mFeatureVersion);
|
|
|
|
switch (mFeatureVersion) {
|
|
|
|
case 135:
|
|
case 137:
|
|
mODMSetSMBIOSData = ODMSetDMIData135;
|
|
break;
|
|
|
|
case 138:
|
|
case 139:
|
|
default:
|
|
//
|
|
//default value always be latest function of L05 SPEC
|
|
//
|
|
mODMSetSMBIOSData = ODMSetDMIData138;
|
|
break;
|
|
}
|
|
|
|
Status = gBS->CreateEvent (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_CALLBACK,
|
|
mODMSetSMBIOSData,
|
|
NULL,
|
|
&L05SetPcdDmiDataEvent
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = gBS->RegisterProtocolNotify (
|
|
&gEfiL05BdsEntryServicesProtocolGuid,
|
|
L05SetPcdDmiDataEvent,
|
|
&BdsArchEventRegistration
|
|
);
|
|
}
|
|
|
|
Status = gBS->CreateEvent (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_CALLBACK,
|
|
ReviseL05SmbiosRecord,
|
|
NULL,
|
|
&L05SmbiosOverrideEvent
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = gBS->RegisterProtocolNotify (
|
|
&gEndOfBdsBootSelectionProtocolGuid,
|
|
L05SmbiosOverrideEvent,
|
|
&EndOfSmbiosOverrideBootEventRegistration
|
|
);
|
|
}
|
|
|
|
Status = gBS->CreateEvent (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_CALLBACK,
|
|
RemoveSmbiosRecord,
|
|
NULL,
|
|
&L05SmbiosOverrideEvent
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = gBS->RegisterProtocolNotify (
|
|
&gEndOfBdsBootSelectionProtocolGuid,
|
|
L05SmbiosOverrideEvent,
|
|
&EndOfSmbiosOverrideBootEventRegistration
|
|
);
|
|
}
|
|
|
|
//
|
|
// Install L05 SMBIOS Interface Protocol
|
|
//
|
|
L05SmbiosInterfacePtr = AllocateZeroPool (sizeof (EFI_L05_SMBIOS_INTERFACE_PROTOCOL));
|
|
|
|
if (L05SmbiosInterfacePtr == NULL) {
|
|
return;
|
|
}
|
|
|
|
L05SmbiosInterfacePtr->AddSmbiosType = AddSmbiosType;
|
|
|
|
Status = gBS->InstallProtocolInterface (
|
|
&mImageHandle,
|
|
&gEfiL05SmbiosInterfaceProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
L05SmbiosInterfacePtr
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// There is no necessary to trigger this callback function again in any case.
|
|
//
|
|
gBS->CloseEvent (Event);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
This is the declaration of an EFI image entry point. This entry point is
|
|
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
|
|
both device drivers and bus drivers.
|
|
|
|
@param ImageHandle The firmware allocated handle for the UEFI image.
|
|
@param SystemTable A pointer to the EFI System Table.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
SmbiosOverrideEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
VOID *Registration;
|
|
|
|
mImageHandle = ImageHandle;
|
|
|
|
L05UpdateSmbiosPcd ();
|
|
|
|
//
|
|
// Register gEfiSmbiosProtocolGuid protocol notify function.
|
|
//
|
|
EfiCreateProtocolNotifyEvent (
|
|
&gEfiSmbiosProtocolGuid,
|
|
TPL_NOTIFY,
|
|
L05SmbiosOverrideCallback,
|
|
NULL,
|
|
&Registration
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|