2 Provides library functions for common SMBIOS operations. Only available to DXE
6 Copyright (c) 2012, Apple Inc. All rights reserved.
7 Portitions Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include <Library/BaseLib.h>
14 #include <Library/BaseMemoryLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/MemoryAllocationLib.h>
17 #include <Library/UefiBootServicesTableLib.h>
18 #include <Library/UefiLib.h>
19 #include <Library/SmbiosLib.h>
21 EFI_SMBIOS_PROTOCOL
*gSmbios
= NULL
;
24 Create an initial SMBIOS Table from an array of SMBIOS_TEMPLATE_ENTRY
25 entries. SMBIOS_TEMPLATE_ENTRY.NULL indicates the end of the table.
27 @param Template Array of SMBIOS_TEMPLATE_ENTRY entries.
29 @retval EFI_SUCCESS New SMBIOS tables were created.
30 @retval EFI_OUT_OF_RESOURCES New SMBIOS tables were not created.
34 SmbiosLibInitializeFromTemplate (
35 IN SMBIOS_TEMPLATE_ENTRY
*Template
41 if (Template
== NULL
) {
42 return EFI_INVALID_PARAMETER
;
47 for (Index
= 0; Template
[Index
].Entry
!= NULL
; Index
++) {
48 Status
= SmbiosLibCreateEntry (Template
[Index
].Entry
, Template
[Index
].StringArray
);
57 Converts a fixed SMBIOS structure and an array of pointers to strings into
58 an SMBIOS record where the strings are cat'ed on the end of the fixed record
59 and terminated via a double NULL and add to SMBIOS table.
61 SMBIOS_TABLE_TYPE32 gSmbiosType12 = {
62 { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 },
65 CHAR8 *gSmbiosType12Strings[] = {
72 (EFI_SMBIOS_TABLE_HEADER*)&gSmbiosType12,
76 @param SmbiosEntry Fixed SMBIOS structure
77 @param StringArray Array of strings to convert to an SMBIOS string pack.
83 SmbiosLibCreateEntry (
84 IN SMBIOS_STRUCTURE
*SmbiosEntry
,
85 IN CHAR8
**StringArray
89 EFI_SMBIOS_HANDLE SmbiosHandle
;
90 EFI_SMBIOS_TABLE_HEADER
*Record
;
96 // Calculate the size of the fixed record and optional string pack
97 Size
= SmbiosEntry
->Length
;
98 if (StringArray
== NULL
) {
99 Size
+= 2; // Min string section is double null
100 } else if (StringArray
[0] == NULL
) {
101 Size
+= 2; // Min string section is double null
103 for (Index
= 0; StringArray
[Index
] != NULL
; Index
++) {
104 StringSize
= AsciiStrSize (StringArray
[Index
]);
108 // Don't forget the terminating double null
112 // Copy over Template
113 Record
= (EFI_SMBIOS_TABLE_HEADER
*)AllocateZeroPool (Size
);
114 if (Record
== NULL
) {
115 return EFI_OUT_OF_RESOURCES
;
118 CopyMem (Record
, SmbiosEntry
, SmbiosEntry
->Length
);
120 if (StringArray
!= NULL
) {
121 // Append string pack
122 Str
= ((CHAR8
*)Record
) + Record
->Length
;
123 for (Index
= 0; StringArray
[Index
] != NULL
; Index
++) {
124 StringSize
= AsciiStrSize (StringArray
[Index
]);
125 CopyMem (Str
, StringArray
[Index
], StringSize
);
132 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
133 Status
= gSmbios
->Add (
145 Update the string associated with an existing SMBIOS record.
147 This function allows the update of specific SMBIOS strings. The number of valid strings for any
148 SMBIOS record is defined by how many strings were present when Add() was called.
150 @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated.
151 @param[in] StringNumber The non-zero string number of the string to update.
152 @param[in] String Update the StringNumber string with String.
154 @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated.
155 @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.
156 @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports.
157 @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record.
161 SmbiosLibUpdateString (
162 IN EFI_SMBIOS_HANDLE SmbiosHandle
,
163 IN SMBIOS_TABLE_STRING StringNumber
,
169 if (String
== NULL
) {
170 return EFI_INVALID_PARAMETER
;
173 if (*String
== '\0') {
174 // A string with no data is not legal in SMBIOS
175 return EFI_INVALID_PARAMETER
;
178 StringIndex
= StringNumber
;
179 return gSmbios
->UpdateString (gSmbios
, &SmbiosHandle
, &StringIndex
, String
);
183 Update the string associated with an existing SMBIOS record.
185 This function allows the update of specific SMBIOS strings. The number of valid strings for any
186 SMBIOS record is defined by how many strings were present when Add() was called.
188 @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated.
189 @param[in] StringNumber The non-zero string number of the string to update.
190 @param[in] String Update the StringNumber string with String.
192 @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated.
193 @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.
194 @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports.
195 @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record.
199 SmbiosLibUpdateUnicodeString (
200 IN EFI_SMBIOS_HANDLE SmbiosHandle
,
201 IN SMBIOS_TABLE_STRING StringNumber
,
209 if (String
== NULL
) {
210 return EFI_INVALID_PARAMETER
;
213 if (*String
== '\0') {
214 // A string with no data is not legal in SMBIOS
215 return EFI_INVALID_PARAMETER
;
218 Ascii
= AllocateZeroPool (StrSize (String
));
220 return EFI_OUT_OF_RESOURCES
;
223 UnicodeStrToAsciiStrS (String
, Ascii
, StrSize (String
));
225 StringIndex
= StringNumber
;
226 Status
= gSmbios
->UpdateString (gSmbios
, &SmbiosHandle
, &StringIndex
, Ascii
);
233 Allow caller to read a specific SMBIOS string
235 @param[in] Header SMBIOS record that contains the string.
236 @param[in[ StringNumber Instance of SMBIOS string 1 - N.
238 @retval NULL Instance of Type SMBIOS string was not found.
239 @retval Other Pointer to matching SMBIOS string.
243 SmbiosLibReadString (
244 IN SMBIOS_STRUCTURE
*Header
,
245 IN EFI_SMBIOS_STRING StringNumber
251 Data
= (CHAR8
*)Header
+ Header
->Length
;
252 for (Match
= 1; !(*Data
== 0 && *(Data
+1) == 0); ) {
253 if (StringNumber
== Match
) {
258 if (*(Data
- 1) == '\0') {
267 Allow the caller to discover a specific SMBIOS entry, and patch it if necissary.
269 @param[in] Type Type of the next SMBIOS record to return.
270 @param[in[ Instance Instance of SMBIOS record 0 - N-1.
271 @param[out] SmbiosHandle Returns SMBIOS handle for the matching record.
273 @retval NULL Instance of Type SMBIOS record was not found.
274 @retval Other Pointer to matching SMBIOS record.
279 IN EFI_SMBIOS_TYPE Type
,
281 OUT EFI_SMBIOS_HANDLE
*SmbiosHandle
285 EFI_SMBIOS_TABLE_HEADER
*Record
;
289 *SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
291 Status
= gSmbios
->GetNext (gSmbios
, SmbiosHandle
, &Type
, &Record
, NULL
);
292 if (!EFI_ERROR (Status
)) {
293 if (Match
== Instance
) {
294 return (SMBIOS_STRUCTURE
*)Record
;
299 } while (!EFI_ERROR (Status
));
305 Remove an SMBIOS record.
307 This function removes an SMBIOS record using the handle specified by SmbiosHandle.
309 @param[in] SmbiosHandle The handle of the SMBIOS record to remove.
311 @retval EFI_SUCCESS SMBIOS record was removed.
312 @retval EFI_INVALID_PARAMETER SmbiosHandle does not specify a valid SMBIOS record.
317 OUT EFI_SMBIOS_HANDLE SmbiosHandle
320 return gSmbios
->Remove (gSmbios
, SmbiosHandle
);
325 @param ImageHandle ImageHandle of the loaded driver.
326 @param SystemTable Pointer to the EFI System Table.
328 @retval EFI_SUCCESS Register successfully.
329 @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler.
333 SmbiosLibConstructor (
334 IN EFI_HANDLE ImageHandle
,
335 IN EFI_SYSTEM_TABLE
*SystemTable
338 return gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&gSmbios
);