2 Library to add SMBIOS data records from HOB to SMBIOS table.
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License which accompanies this distribution.
8 The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 @par Specification Reference:
15 System Management BIOS (SMBIOS) Reference Specification v3.0.0
16 dated 2015-Feb-12 (DSP0134)
17 http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf
20 #include <IndustryStandard/SmBios.h>
21 #include <Library/UefiLib.h>
22 #include <Library/BaseLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/MemoryAllocationLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/HobLib.h>
27 #include <Library/UefiBootServicesTableLib.h>
28 #include <Protocol/Smbios.h>
32 Get the full size of SMBIOS structure including optional strings that follow the formatted structure.
33 @note: This function is copy from SmbiosDxe in MdeModulePkg.
35 @param[in] This The EFI_SMBIOS_PROTOCOL instance.
36 @param[in] Head Pointer to the beginning of SMBIOS structure.
37 @param[out] Size The returned size.
38 @param[out] NumberOfStrings The returned number of optional strings that follow the formatted structure.
40 @retval EFI_SUCCESS Size returned in Size.
41 @retval EFI_INVALID_PARAMETER Input SMBIOS structure mal-formed or Size is NULL.
46 GetSmbiosStructureSize (
47 IN CONST EFI_SMBIOS_PROTOCOL
*This
,
48 IN EFI_SMBIOS_TABLE_HEADER
*Head
,
50 OUT UINTN
*NumberOfStrings
58 if (Size
== NULL
|| NumberOfStrings
== NULL
) {
59 return EFI_INVALID_PARAMETER
;
62 FullSize
= Head
->Length
;
63 CharInStr
= (INT8
*)Head
+ Head
->Length
;
69 // look for the two consecutive zeros, check the string limit by the way.
71 while (*CharInStr
!= 0 || *(CharInStr
+1) != 0) {
72 if (*CharInStr
== 0) {
77 if (This
->MajorVersion
< 2 || (This
->MajorVersion
== 2 && This
->MinorVersion
< 7)) {
78 MaxLen
= SMBIOS_STRING_MAX_LENGTH
;
79 } else if (This
->MajorVersion
< 3) {
81 // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.
82 // However, the length of the entire structure table (including all strings) must be reported
83 // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,
84 // which is a WORD field limited to 65,535 bytes.
86 MaxLen
= SMBIOS_TABLE_MAX_LENGTH
;
89 // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.
90 // Locate the end of string as long as possible.
92 MaxLen
= SMBIOS_3_0_TABLE_MAX_LENGTH
;
95 for (StrLen
= 0 ; StrLen
< MaxLen
; StrLen
++) {
96 if (*(CharInStr
+StrLen
) == 0) {
101 if (StrLen
== MaxLen
) {
102 return EFI_INVALID_PARAMETER
;
106 // forward the pointer
110 *NumberOfStrings
+= 1;
114 // count ending two zeros.
121 Adds SMBIOS records to tables
123 @param[in] ImageHandle Image handle of this driver.
124 @param[in] SystemTable Global system service table.
126 @retval EFI_UNSUPPORTED - Could not locate SMBIOS protocol
127 @retval EFI_OUT_OF_RESOURCES - Failed to allocate memory for SMBIOS HOB type.
128 @retval EFI_SUCCESS - Successfully added SMBIOS records based on HOB.
132 DxeSmbiosDataHobLibConstructor (
133 IN EFI_HANDLE ImageHandle
,
134 IN EFI_SYSTEM_TABLE
*SystemTable
137 EFI_PEI_HOB_POINTERS Hob
;
138 EFI_SMBIOS_HANDLE SmbiosHandle
;
139 EFI_SMBIOS_PROTOCOL
*Smbios
;
141 UINTN InstalledPayloadSize
;
142 UINTN MaxPayloadSize
;
146 UINTN NumberOfStrings
;
150 DEBUG ((DEBUG_INFO
, "Adding SMBIOS records from HOB..\n"));
152 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&Smbios
);
153 if (Smbios
== NULL
) {
154 DEBUG ((DEBUG_WARN
, " Can't locate SMBIOS protocol\n"));
155 return EFI_UNSUPPORTED
;
159 /// Get SMBIOS HOB data
161 for (Hob
.Raw
= GetHobList (); !END_OF_HOB_LIST(Hob
); Hob
.Raw
= GET_NEXT_HOB (Hob
)) {
162 if ((GET_HOB_TYPE (Hob
) == EFI_HOB_TYPE_GUID_EXTENSION
) && (CompareGuid (&Hob
.Guid
->Name
, &gIntelSmbiosDataHobGuid
))) {
163 RecordPtr
= (UINT8
*)Hob
.Raw
+ sizeof (EFI_HOB_GUID_TYPE
);
164 MaxPayloadSize
= Hob
.Guid
->Header
.HobLength
- sizeof (EFI_HOB_GUID_TYPE
);
166 InstalledPayloadSize
= 0;
169 Status
= GetSmbiosStructureSize (Smbios
, (EFI_SMBIOS_TABLE_HEADER
*)RecordPtr
, &StructureSize
, &NumberOfStrings
);
170 if ((Status
== EFI_SUCCESS
) && (InstalledPayloadSize
+ StructureSize
<= MaxPayloadSize
)) {
171 InstalledPayloadSize
+= StructureSize
;
174 /// Add generic SMBIOS HOB to SMBIOS table
176 DEBUG ((DEBUG_VERBOSE
, " Add SMBIOS record type: %x\n", ((EFI_SMBIOS_TABLE_HEADER
*) RecordPtr
)->Type
));
177 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
178 Status
= Smbios
->Add (Smbios
, NULL
, &SmbiosHandle
, (EFI_SMBIOS_TABLE_HEADER
*) RecordPtr
);
179 if (!EFI_ERROR (Status
)) {
180 RecordPtr
+= StructureSize
;
189 DEBUG ((DEBUG_INFO
, " Found %d Records and added to SMBIOS table.\n", RecordCount
));