]> git.proxmox.com Git - mirror_edk2.git/blob - EmulatorPkg/Library/SmbiosLib/SmbiosLib.c
Oops missed these items in 12966. Also forgot the signoff, this signoff includes...
[mirror_edk2.git] / EmulatorPkg / Library / SmbiosLib / SmbiosLib.c
1 /** @file
2 Provides library functions for common SMBIOS operations. Only available to DXE
3 and UEFI module types.
4
5
6 Copyright (c) 2012, Apple Inc. All rights reserved.
7 Portitions Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials are licensed and made available under
9 the terms and conditions of the BSD License that accompanies this distribution.
10 The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php.
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16 **/
17
18 #include <PiDxe.h>
19 #include <Library/BaseLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/MemoryAllocationLib.h>
23 #include <Library/UefiBootServicesTableLib.h>
24 #include <Library/UefiLib.h>
25 #include <Library/SmbiosLib.h>
26
27
28 EFI_SMBIOS_PROTOCOL *gSmbios = NULL;
29
30
31 EFI_STATUS
32 EFIAPI
33 InitializeSmbiosTableFromTemplate (
34 IN SMBIOS_TEMPLATE_ENTRY *Template
35 )
36 {
37 EFI_STATUS Status;
38 UINTN Index;
39
40 if (Template == NULL) {
41 return EFI_INVALID_PARAMETER;
42 }
43
44 for (Index = 0; Template[Index].Entry != NULL; Index++) {
45 Status = CreateSmbiosEntry (Template[Index].Entry, Template[Index].StringArray);
46 }
47
48 return Status;
49 }
50
51
52
53 /**
54 Create SMBIOS record.
55
56 Converts a fixed SMBIOS structure and an array of pointers to strings into
57 an SMBIOS record where the strings are cat'ed on the end of the fixed record
58 and terminated via a double NULL and add to SMBIOS table.
59
60 SMBIOS_TABLE_TYPE32 gSmbiosType12 = {
61 { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 },
62 1 // StringCount
63 };
64 CHAR8 *gSmbiosType12Strings[] = {
65 "Not Found",
66 NULL
67 };
68
69 ...
70 CreateSmbiosEntry (
71 (EFI_SMBIOS_TABLE_HEADER*)&gSmbiosType12,
72 gSmbiosType12Strings
73 );
74
75 @param SmbiosEntry Fixed SMBIOS structure
76 @param StringArray Array of strings to convert to an SMBIOS string pack.
77 NULL is OK.
78
79 **/
80 EFI_STATUS
81 EFIAPI
82 CreateSmbiosEntry (
83 IN SMBIOS_STRUCTURE *SmbiosEntry,
84 IN CHAR8 **StringArray
85 )
86 {
87 EFI_STATUS Status;
88 EFI_SMBIOS_HANDLE SmbiosHandle;
89 EFI_SMBIOS_TABLE_HEADER *Record;
90 UINTN Index;
91 UINTN StringSize;
92 UINTN Size;
93 CHAR8 *Str;
94
95 // Calculate the size of the fixed record and optional string pack
96 Size = SmbiosEntry->Length;
97 if (StringArray == NULL) {
98 Size += 2; // Min string section is double null
99 } else if (StringArray[0] == NULL) {
100 Size += 2; // Min string section is double null
101 } else {
102 for (Index = 0; StringArray[Index] != NULL; Index++) {
103 StringSize = AsciiStrSize (StringArray[Index]);
104 Size += StringSize;
105 }
106 // Don't forget the terminating double null
107 Size += 1;
108 }
109
110 // Copy over Template
111 Record = (EFI_SMBIOS_TABLE_HEADER *)AllocateZeroPool (Size);
112 if (Record == NULL) {
113 return EFI_OUT_OF_RESOURCES;
114 }
115 CopyMem (Record, SmbiosEntry, SmbiosEntry->Length);
116
117 if (StringArray != NULL) {
118 // Append string pack
119 Str = ((CHAR8 *)Record) + Record->Length;
120 for (Index = 0; StringArray[Index] != NULL; Index++) {
121 StringSize = AsciiStrSize (StringArray[Index]);
122 CopyMem (Str, StringArray[Index], StringSize);
123 Str += StringSize;
124 }
125 *Str = 0;
126 }
127
128 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
129 Status = gSmbios->Add (
130 gSmbios,
131 gImageHandle,
132 &SmbiosHandle,
133 Record
134 );
135
136 FreePool (Record);
137 return Status;
138 }
139
140
141
142 /**
143 Update the string associated with an existing SMBIOS record.
144
145 This function allows the update of specific SMBIOS strings. The number of valid strings for any
146 SMBIOS record is defined by how many strings were present when Add() was called.
147
148 @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated.
149 @param[in] StringNumber The non-zero string number of the string to update.
150 @param[in] String Update the StringNumber string with String.
151
152 @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated.
153 @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.
154 @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports.
155 @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record.
156 **/
157 EFI_STATUS
158 EFIAPI
159 SmbiosUpdateString (
160 IN EFI_SMBIOS_HANDLE SmbiosHandle,
161 IN SMBIOS_TABLE_STRING StringNumber,
162 IN CHAR8 *String
163 )
164 {
165 UINTN StringIndex;
166
167 if (String == NULL) {
168 return EFI_INVALID_PARAMETER;
169 }
170
171 if (*String == '\0') {
172 // A string with no data is not legal in SMBIOS
173 return EFI_INVALID_PARAMETER;
174 }
175
176 StringIndex = StringNumber;
177 return gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, String);
178 }
179
180
181 /**
182 Update the string associated with an existing SMBIOS record.
183
184 This function allows the update of specific SMBIOS strings. The number of valid strings for any
185 SMBIOS record is defined by how many strings were present when Add() was called.
186
187 @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated.
188 @param[in] StringNumber The non-zero string number of the string to update.
189 @param[in] String Update the StringNumber string with String.
190
191 @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated.
192 @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.
193 @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports.
194 @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record.
195 **/
196 EFI_STATUS
197 EFIAPI
198 SmbiosUpdateUnicodeString (
199 IN EFI_SMBIOS_HANDLE SmbiosHandle,
200 IN SMBIOS_TABLE_STRING StringNumber,
201 IN CHAR16 *String
202 )
203 {
204 EFI_STATUS Status;
205 UINTN StringIndex;
206 CHAR8 *Ascii;
207
208 if (String == NULL) {
209 return EFI_INVALID_PARAMETER;
210 }
211
212 if (*String == '\0') {
213 // A string with no data is not legal in SMBIOS
214 return EFI_INVALID_PARAMETER;
215 }
216
217 Ascii = AllocateZeroPool (StrSize (String));
218 if (Ascii == NULL) {
219 return EFI_OUT_OF_RESOURCES;
220 }
221 UnicodeStrToAsciiStr (String, Ascii);
222
223 StringIndex = StringNumber;
224 Status = gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, Ascii);
225
226 FreePool (Ascii);
227 return Status;
228 }
229
230
231 /**
232 Allow caller to read a specific SMBIOS string
233
234 @param[in] Header SMBIOS record that contains the string.
235 @param[in[ Intance Instance of SMBIOS string 0 - N-1.
236
237 @retval NULL Instance of Type SMBIOS string was not found.
238 @retval Other Pointer to matching SMBIOS string.
239 **/
240 CHAR8 *
241 SmbiosReadString (
242 IN SMBIOS_STRUCTURE *Header,
243 IN UINTN Instance
244 )
245 {
246 CHAR8 *Data;
247 UINTN NullCount;
248
249 Data = (CHAR8 *)Header + Header->Length;
250 for (NullCount = 0;!(*Data == 0 && *(Data+1) == 0); ) {
251 if (Instance == NullCount) {
252 return Data;
253 }
254 Data++;
255 if (*(Data - 1) == '\0') {
256 NullCount++;
257 }
258 }
259
260 return NULL;
261 }
262
263
264 /**
265 Allow the caller to discover a specific SMBIOS entry, and patch it if necissary.
266
267 @param[in] Type Type of the next SMBIOS record to return.
268 @param[in[ Instance Instance of SMBIOS record 0 - N-1.
269 @param[out] SmbiosHandle Returns SMBIOS handle for the matching record.
270
271 @retval NULL Instance of Type SMBIOS record was not found.
272 @retval Other Pointer to matching SMBIOS record.
273 **/
274 SMBIOS_STRUCTURE *
275 EFIAPI
276 SmbiosGetRecord (
277 IN EFI_SMBIOS_TYPE Type,
278 IN UINTN Instance,
279 OUT EFI_SMBIOS_HANDLE *SmbiosHandle
280 )
281 {
282 EFI_STATUS Status;
283 EFI_SMBIOS_TABLE_HEADER *Record;
284 UINTN Match;
285
286 Match = 0;
287 *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
288 do {
289 Status = gSmbios->GetNext (gSmbios, SmbiosHandle, &Type, &Record, NULL);
290 if (!EFI_ERROR (Status)) {
291 if (Match == Instance) {
292 return (SMBIOS_STRUCTURE *)Record;
293 }
294 Match++;
295 }
296 } while (!EFI_ERROR (Status));
297
298 return NULL;
299 }
300
301
302 /**
303 Remove an SMBIOS record.
304
305 This function removes an SMBIOS record using the handle specified by SmbiosHandle.
306
307 @param[in] SmbiosHandle The handle of the SMBIOS record to remove.
308
309 @retval EFI_SUCCESS SMBIOS record was removed.
310 @retval EFI_INVALID_PARAMETER SmbiosHandle does not specify a valid SMBIOS record.
311 **/
312 EFI_STATUS
313 EFIAPI
314 SmbiosRemove (
315 OUT EFI_SMBIOS_HANDLE SmbiosHandle
316 )
317 {
318 return gSmbios->Remove (gSmbios, SmbiosHandle);
319 }
320
321
322 EFI_STATUS
323 EFIAPI
324 SmbiosGetVersion (
325 OUT UINT8 *SmbiosMajorVersion,
326 OUT UINT8 *SmbiosMinorVersion
327 )
328 {
329 if (SmbiosMajorVersion != NULL) {
330 *SmbiosMajorVersion = gSmbios->MajorVersion;
331 }
332 if (SmbiosMinorVersion != NULL) {
333 *SmbiosMinorVersion = gSmbios->MinorVersion;
334 }
335 return EFI_SUCCESS;
336 }
337
338
339 /**
340
341
342 @param ImageHandle ImageHandle of the loaded driver.
343 @param SystemTable Pointer to the EFI System Table.
344
345 @retval EFI_SUCCESS Register successfully.
346 @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler.
347 **/
348 EFI_STATUS
349 EFIAPI
350 SmbiosLibConstructor (
351 IN EFI_HANDLE ImageHandle,
352 IN EFI_SYSTEM_TABLE *SystemTable
353 )
354 {
355 return gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&gSmbios);
356 }
357