/** Update the structure buffer of a structure node in SMBIOS database. The function lead the structure pointer for SMBIOS record changed. @param StructureNode The structure node whose structure buffer is to be enlarged. @param NewRecord The new SMBIOS record. **/ VOID SmbiosUpdateStructureBuffer ( IN OUT SMBIOS_STRUCTURE_NODE *StructureNode, IN EFI_SMBIOS_TABLE_HEADER *NewRecord ) { EFI_SMBIOS_PROTOCOL *Smbios; EFI_STATUS Status; UINT8 CountOfString; Smbios = GetSmbiosProtocol(); ASSERT (Smbios != NULL); Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle); ASSERT_EFI_ERROR (Status); // // try to use original handle to enlarge the buffer. // Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, NewRecord); ASSERT_EFI_ERROR (Status); StructureNode->Structure = GetSmbiosBufferFromHandle ( StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL ); GetSmbiosStructureSize ( StructureNode->Structure, &StructureNode->StructureSize, &CountOfString ); return ; }
/** Enlarge the structure buffer of a structure node in SMBIOS database. The function maybe lead the structure pointer for SMBIOS record changed. @param StructureNode The structure node whose structure buffer is to be enlarged. @param NewLength The new length of SMBIOS record which does not include unformat area. @param OldBufferSize The old size of SMBIOS record buffer. @param NewBufferSize The new size is targeted for enlarged. @retval EFI_OUT_OF_RESOURCES No more memory to allocate new record @retval EFI_SUCCESS Success to enlarge the record buffer size. **/ EFI_STATUS SmbiosEnlargeStructureBuffer ( IN OUT SMBIOS_STRUCTURE_NODE *StructureNode, UINT8 NewLength, UINTN OldBufferSize, UINTN NewBufferSize ) { EFI_SMBIOS_TABLE_HEADER *NewRecord; EFI_SMBIOS_PROTOCOL *Smbios; EFI_STATUS Status; UINT8 CountOfString; NewRecord = NULL; Smbios = GetSmbiosProtocol(); ASSERT (Smbios != NULL); NewRecord = (EFI_SMBIOS_TABLE_HEADER*) AllocateZeroPool (NewBufferSize); if (NewRecord == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (NewRecord, StructureNode->Structure, OldBufferSize); Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle); ASSERT_EFI_ERROR (Status); // // try to use original handle to enlarge the buffer. // NewRecord->Length = NewLength; Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, NewRecord); ASSERT_EFI_ERROR (Status); FreePool (NewRecord); StructureNode->Structure = GetSmbiosBufferFromHandle ( StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL ); GetSmbiosStructureSize ( StructureNode->Structure, &StructureNode->StructureSize, &CountOfString ); return EFI_SUCCESS; }
/** Adds SMBIOS records to tables @param[in] ImageHandle Image handle of this driver. @param[in] SystemTable Global system service table. @retval EFI_UNSUPPORTED - Could not locate SMBIOS protocol @retval EFI_OUT_OF_RESOURCES - Failed to allocate memory for SMBIOS HOB type. @retval EFI_SUCCESS - Successfully added SMBIOS records based on HOB. **/ EFI_STATUS EFIAPI DxeSmbiosDataHobLibConstructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_PEI_HOB_POINTERS Hob; EFI_SMBIOS_HANDLE SmbiosHandle; EFI_SMBIOS_PROTOCOL *Smbios; EFI_STATUS Status; UINT8 *RecordPtr; UINT16 RecordCount; RecordCount = 0; DEBUG ((DEBUG_INFO, "Adding SMBIOS records from HOB..\n")); Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios); if (Smbios == NULL) { DEBUG ((DEBUG_WARN, "Can't locate SMBIOS protocol\n")); return EFI_UNSUPPORTED; } /// /// Get SMBIOS HOB data (each hob contains one SMBIOS record) /// for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { if ((GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_GUID_EXTENSION) && (CompareGuid (&Hob.Guid->Name, &gIntelSmbiosDataHobGuid))) { RecordPtr = GET_GUID_HOB_DATA (Hob.Raw); /// /// Add generic SMBIOS HOB to SMBIOS table /// DEBUG ((DEBUG_VERBOSE, "Add SMBIOS record type: %x\n", ((EFI_SMBIOS_TABLE_HEADER *) RecordPtr)->Type)); SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) RecordPtr); if (!EFI_ERROR (Status)) { RecordCount++; } } } DEBUG ((DEBUG_INFO, "Found %d Records and added to SMBIOS table.\n", RecordCount)); return EFI_SUCCESS; }
/** Fill a standard Smbios string field. This function will convert the unicode string to single byte chars, and only English language is supported. This function changes the Structure pointer value of the structure node, which should be noted by Caller. @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed. @param Offset Offset of SMBIOS record which RecordData will be filled. @param RecordData RecordData buffer will be filled. @param RecordDataSize The size of RecordData buffer. @retval EFI_INVALID_PARAMETER RecordDataSize is too larger @retval EFI_OUT_OF_RESOURCES No memory to allocate new buffer for string @retval EFI_SUCCESS Sucess append string for a SMBIOS record. **/ EFI_STATUS SmbiosFldString ( IN OUT SMBIOS_STRUCTURE_NODE *StructureNode, IN UINT32 Offset, IN VOID *RecordData, IN UINT32 RecordDataSize ) { EFI_STATUS Status; UINT16 *Data; CHAR8 AsciiData[SMBIOS_STRING_MAX_LENGTH]; UINT8 CountOfStrings; UINTN OrigStringNumber; EFI_SMBIOS_PROTOCOL *Smbios; EFI_SMBIOS_HANDLE SmbiosHandle; UINT32 OrigStructureSize; UINTN NewStructureSize; EFI_SMBIOS_TABLE_HEADER *NewRecord; UINT32 StringLength; Status = EFI_SUCCESS; OrigStringNumber = 0; OrigStructureSize = 0; // // if we have a NULL token, // if (0 == *((STRING_REF *) RecordData)) { *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0; return EFI_SUCCESS; } // // Get the String from the Hii Database // Data = HiiGetPackageString ( &(StructureNode->ProducerName), *((EFI_STRING_ID *) RecordData), NULL ); if (Data == NULL) { return EFI_INVALID_PARAMETER; } StringLength = (UINT32)StrLen (Data); // // Count the string size including the terminating 0. // if (StringLength == 0) { *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0; FreePool (Data); return EFI_SUCCESS; } if (StringLength > SMBIOS_STRING_MAX_LENGTH) { // // Too long a string // FreePool (Data); return EFI_INVALID_PARAMETER; } Smbios = GetSmbiosProtocol(); ASSERT (Smbios != NULL); // // Convert Unicode string to Ascii string which only supported by SMBIOS. // ZeroMem (AsciiData, SMBIOS_STRING_MAX_LENGTH); UnicodeStrToAsciiStr (Data, AsciiData); // // if the field at offset is already filled with some value, // find out the string it points to // OrigStringNumber = *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset); if (OrigStringNumber != 0) { DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Update %dth string for type[%d],offset[0x%x],handle[0x%x] to [%s]\n", OrigStringNumber, StructureNode->SmbiosType, Offset, StructureNode->SmbiosHandle, AsciiData)); // // If original string number is not zero, just update string // Status = Smbios->UpdateString (Smbios, &StructureNode->SmbiosHandle, &OrigStringNumber, AsciiData); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Fail to update %dth string in offset 0x%x for handle:0x%x type:0x%x\n", OrigStringNumber, Offset, StructureNode->SmbiosHandle, StructureNode->SmbiosType)); ASSERT_EFI_ERROR (Status); return Status; } } else { // // If the string has not been filled in SMBIOS database, remove it and add again // with string appended. // Status = GetSmbiosStructureSize (StructureNode->Structure, &OrigStructureSize, &CountOfStrings); ASSERT_EFI_ERROR (Status); if (CountOfStrings == 0) { NewStructureSize = OrigStructureSize + StringLength; } else { NewStructureSize = OrigStructureSize + StringLength + 1; } NewRecord = AllocateZeroPool (NewStructureSize); if (NewRecord == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (NewRecord, StructureNode->Structure, OrigStructureSize); // // Copy new string into tail of original SMBIOS record buffer. // if (CountOfStrings == 0) { AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 2, AsciiData); } else { AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 1, AsciiData); } DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Type(%d) offset(0x%x) StringNumber:%d\n", StructureNode->SmbiosType, Offset, CountOfStrings + 1)); // // Update string reference number // *(UINT8 *) ((UINT8 *) NewRecord + Offset) = (UINT8) (CountOfStrings + 1); SmbiosHandle = StructureNode->SmbiosHandle; // // Remove original SMBIOS record and add new one // Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle); ASSERT_EFI_ERROR (Status); // // Add new SMBIOS record // Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, NewRecord); ASSERT_EFI_ERROR (Status); StructureNode->SmbiosHandle = SmbiosHandle; FreePool (NewRecord); } // // The SMBIOS record buffer maybe re-allocated in SMBIOS database, // so update cached buffer pointer in DataHub structure list. // StructureNode->Structure = GetSmbiosBufferFromHandle ( StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL ); ASSERT (StructureNode->Structure != NULL); // // The string update action maybe lead the record is re-allocated in SMBIOS database // so update cached record pointer // Status = GetSmbiosStructureSize (StructureNode->Structure, &StructureNode->StructureSize, &CountOfStrings); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** Update the banner information for the Front Page based on Smbios information. **/ VOID UpdateFrontPageBannerStrings ( VOID ) { UINT8 StrIndex; CHAR16 *NewString; CHAR16 *FirmwareVersionString; EFI_STATUS Status; EFI_SMBIOS_HANDLE SmbiosHandle; EFI_SMBIOS_PROTOCOL *Smbios; SMBIOS_TABLE_TYPE0 *Type0Record; SMBIOS_TABLE_TYPE1 *Type1Record; SMBIOS_TABLE_TYPE4 *Type4Record; SMBIOS_TABLE_TYPE19 *Type19Record; EFI_SMBIOS_TABLE_HEADER *Record; UINT64 InstalledMemory; BOOLEAN FoundCpu; InstalledMemory = 0; FoundCpu = 0; // // Update default banner string. // NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NULL); UiCustomizeFrontPageBanner (4, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NewString, NULL); FreePool (NewString); NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_RIGHT), NULL); UiCustomizeFrontPageBanner (4, FALSE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_RIGHT), NewString, NULL); FreePool (NewString); NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_LEFT), NULL); UiCustomizeFrontPageBanner (5, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_LEFT), NewString, NULL); FreePool (NewString); NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_RIGHT), NULL); UiCustomizeFrontPageBanner (5, FALSE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_RIGHT), NewString, NULL); FreePool (NewString); // // Update Front Page banner strings base on SmBios Table. // Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &Smbios); if (EFI_ERROR (Status)) { // // Smbios protocol not found, get the default value. // NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NULL); UiCustomizeFrontPageBanner (1, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL); FreePool (NewString); NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NULL); UiCustomizeFrontPageBanner (2, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL); FreePool (NewString); NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NULL); UiCustomizeFrontPageBanner (2, FALSE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL); FreePool (NewString); NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NULL); UiCustomizeFrontPageBanner (3, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL); FreePool (NewString); NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NULL); UiCustomizeFrontPageBanner (3, FALSE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NewString, NULL); FreePool (NewString); return; } SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL); while (!EFI_ERROR(Status)) { if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) { Type0Record = (SMBIOS_TABLE_TYPE0 *) Record; StrIndex = Type0Record->BiosVersion; GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString); FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString); if (*FirmwareVersionString != 0x0000 ) { FreePool (NewString); NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString); UiCustomizeFrontPageBanner (3, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL); } else { UiCustomizeFrontPageBanner (3, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL); FreePool (NewString); } } if (Record->Type == SMBIOS_TYPE_SYSTEM_INFORMATION) { Type1Record = (SMBIOS_TABLE_TYPE1 *) Record; StrIndex = Type1Record->ProductName; GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString); UiCustomizeFrontPageBanner (1, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL); FreePool (NewString); } if ((Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) && !FoundCpu) { Type4Record = (SMBIOS_TABLE_TYPE4 *) Record; // // The information in the record should be only valid when the CPU Socket is populated. // if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) { StrIndex = Type4Record->ProcessorVersion; GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString); UiCustomizeFrontPageBanner (2, TRUE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL); FreePool (NewString); ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString); UiCustomizeFrontPageBanner (2, FALSE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL); FreePool (NewString); FoundCpu = TRUE; } } if ( Record->Type == SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) { Type19Record = (SMBIOS_TABLE_TYPE19 *) Record; if (Type19Record->StartingAddress != 0xFFFFFFFF ) { InstalledMemory += RShiftU64(Type19Record->EndingAddress - Type19Record->StartingAddress + 1, 10); } else { InstalledMemory += RShiftU64(Type19Record->ExtendedEndingAddress - Type19Record->ExtendedStartingAddress + 1, 20); } } Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL); } // // Now update the total installed RAM size // ConvertMemorySizeToString ((UINT32)InstalledMemory, &NewString ); UiCustomizeFrontPageBanner (3, FALSE, &NewString); HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NewString, NULL); FreePool (NewString); }
/** Update the banner information for the Front Page based on DataHub information. **/ VOID UpdateFrontPageStrings ( VOID ) { UINT8 StrIndex; CHAR16 *NewString; BOOLEAN Find[5]; EFI_STATUS Status; EFI_STRING_ID TokenToUpdate; EFI_SMBIOS_HANDLE SmbiosHandle; EFI_SMBIOS_PROTOCOL *Smbios; SMBIOS_TABLE_TYPE0 *Type0Record; SMBIOS_TABLE_TYPE1 *Type1Record; SMBIOS_TABLE_TYPE4 *Type4Record; SMBIOS_TABLE_TYPE19 *Type19Record; EFI_SMBIOS_TABLE_HEADER *Record; ZeroMem (Find, sizeof (Find)); // // Update Front Page strings // Status = gBS->LocateProtocol ( &gEfiSmbiosProtocolGuid, NULL, (VOID **) &Smbios ); if (!EFI_ERROR (Status)) { SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; do { Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL); if (EFI_ERROR(Status)) { break; } if (Record->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) { Type0Record = (SMBIOS_TABLE_TYPE0 *) Record; StrIndex = Type0Record->BiosVersion; GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString); TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION); HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); FreePool (NewString); Find[0] = TRUE; } if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) { Type1Record = (SMBIOS_TABLE_TYPE1 *) Record; StrIndex = Type1Record->ProductName; GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString); TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL); HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); FreePool (NewString); Find[1] = TRUE; } if (Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) { Type4Record = (SMBIOS_TABLE_TYPE4 *) Record; StrIndex = Type4Record->ProcessorVersion; GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString); TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL); HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); FreePool (NewString); Find[2] = TRUE; } if (Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) { Type4Record = (SMBIOS_TABLE_TYPE4 *) Record; ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString); TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED); HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); FreePool (NewString); Find[3] = TRUE; } if ( Record->Type == EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) { Type19Record = (SMBIOS_TABLE_TYPE19 *) Record; ConvertMemorySizeToString ( (UINT32)(RShiftU64((Type19Record->EndingAddress - Type19Record->StartingAddress + 1), 10)), &NewString ); TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE); HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); FreePool (NewString); Find[4] = TRUE; } } while ( !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4])); } return ; }
/** Create SMBIOS record. Converts a fixed SMBIOS structure and an array of pointers to strings into an SMBIOS record where the strings are cat'ed on the end of the fixed record and terminated via a double NULL and add to SMBIOS table. SMBIOS_TABLE_TYPE32 gSmbiosType12 = { { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 }, 1 // StringCount }; CHAR8 *gSmbiosType12Strings[] = { "Not Found", NULL }; ... LogSmbiosData ( (EFI_SMBIOS_TABLE_HEADER*)&gSmbiosType12, gSmbiosType12Strings ); @param Template Fixed SMBIOS structure, required. @param StringArray Array of strings to convert to an SMBIOS string pack. NULL is OK. **/ EFI_STATUS LogSmbiosData ( IN EFI_SMBIOS_TABLE_HEADER *Template, IN CHAR8 **StringPack ) { EFI_STATUS Status; EFI_SMBIOS_PROTOCOL *Smbios; EFI_SMBIOS_HANDLE SmbiosHandle; EFI_SMBIOS_TABLE_HEADER *Record; UINTN Index; UINTN StringSize; UINTN Size; CHAR8 *Str; // // Locate Smbios protocol. // Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios); if (EFI_ERROR (Status)) { return Status; } // Calculate the size of the fixed record and optional string pack Size = Template->Length; if (StringPack == NULL) { // At least a double null is required Size += 2; } else { for (Index = 0; StringPack[Index] != NULL; Index++) { StringSize = AsciiStrSize (StringPack[Index]); Size += StringSize; } if (StringPack[0] == NULL) { // At least a double null is required Size += 1; } // Don't forget the terminating double null Size += 1; } // Copy over Template Record = (EFI_SMBIOS_TABLE_HEADER *)AllocateZeroPool (Size); if (Record == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (Record, Template, Template->Length); // Append string pack Str = ((CHAR8 *)Record) + Record->Length; for (Index = 0; StringPack[Index] != NULL; Index++) { StringSize = AsciiStrSize (StringPack[Index]); CopyMem (Str, StringPack[Index], StringSize); Str += StringSize; } *Str = 0; SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; Status = Smbios->Add ( Smbios, gImageHandle, &SmbiosHandle, Record ); ASSERT_EFI_ERROR (Status); FreePool (Record); return Status; }