alder_lake_bios/Oem/L05/FeatureCommon/InsydeL05ModulePkg/SmbiosOverride/SmbiosOverride.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;
}