]>
Commit | Line | Data |
---|---|---|
803936cc | 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 | ||
8fa6b23c | 31 | /** |
32 | Create an initial SMBIOS Table from an array of SMBIOS_TEMPLATE_ENTRY | |
33 | entries. SMBIOS_TEMPLATE_ENTRY.NULL indicates the end of the table. | |
34 | ||
35 | @param Template Array of SMBIOS_TEMPLATE_ENTRY entries. | |
36 | ||
37 | @retval EFI_SUCCESS New SMBIOS tables were created. | |
38 | @retval EFI_OUT_OF_RESOURCES New SMBIOS tables were not created. | |
39 | **/ | |
803936cc | 40 | EFI_STATUS |
41 | EFIAPI | |
8fa6b23c | 42 | SmbiosLibInitializeFromTemplate ( |
803936cc | 43 | IN SMBIOS_TEMPLATE_ENTRY *Template |
44 | ) | |
45 | { | |
46 | EFI_STATUS Status; | |
47 | UINTN Index; | |
48 | ||
49 | if (Template == NULL) { | |
50 | return EFI_INVALID_PARAMETER; | |
51 | } | |
52 | ||
53 | for (Index = 0; Template[Index].Entry != NULL; Index++) { | |
8fa6b23c | 54 | Status = SmbiosLibCreateEntry (Template[Index].Entry, Template[Index].StringArray); |
803936cc | 55 | } |
56 | ||
57 | return Status; | |
58 | } | |
59 | ||
60 | ||
61 | ||
62 | /** | |
63 | Create SMBIOS record. | |
64 | ||
65 | Converts a fixed SMBIOS structure and an array of pointers to strings into | |
66 | an SMBIOS record where the strings are cat'ed on the end of the fixed record | |
67 | and terminated via a double NULL and add to SMBIOS table. | |
68 | ||
69 | SMBIOS_TABLE_TYPE32 gSmbiosType12 = { | |
70 | { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 }, | |
71 | 1 // StringCount | |
72 | }; | |
73 | CHAR8 *gSmbiosType12Strings[] = { | |
74 | "Not Found", | |
75 | NULL | |
76 | }; | |
77 | ||
78 | ... | |
79 | CreateSmbiosEntry ( | |
80 | (EFI_SMBIOS_TABLE_HEADER*)&gSmbiosType12, | |
81 | gSmbiosType12Strings | |
82 | ); | |
83 | ||
84 | @param SmbiosEntry Fixed SMBIOS structure | |
85 | @param StringArray Array of strings to convert to an SMBIOS string pack. | |
86 | NULL is OK. | |
87 | ||
88 | **/ | |
89 | EFI_STATUS | |
90 | EFIAPI | |
8fa6b23c | 91 | SmbiosLibCreateEntry ( |
803936cc | 92 | IN SMBIOS_STRUCTURE *SmbiosEntry, |
93 | IN CHAR8 **StringArray | |
94 | ) | |
95 | { | |
96 | EFI_STATUS Status; | |
97 | EFI_SMBIOS_HANDLE SmbiosHandle; | |
98 | EFI_SMBIOS_TABLE_HEADER *Record; | |
99 | UINTN Index; | |
100 | UINTN StringSize; | |
101 | UINTN Size; | |
102 | CHAR8 *Str; | |
103 | ||
104 | // Calculate the size of the fixed record and optional string pack | |
105 | Size = SmbiosEntry->Length; | |
106 | if (StringArray == NULL) { | |
107 | Size += 2; // Min string section is double null | |
108 | } else if (StringArray[0] == NULL) { | |
109 | Size += 2; // Min string section is double null | |
110 | } else { | |
111 | for (Index = 0; StringArray[Index] != NULL; Index++) { | |
112 | StringSize = AsciiStrSize (StringArray[Index]); | |
113 | Size += StringSize; | |
114 | } | |
115 | // Don't forget the terminating double null | |
116 | Size += 1; | |
117 | } | |
118 | ||
119 | // Copy over Template | |
120 | Record = (EFI_SMBIOS_TABLE_HEADER *)AllocateZeroPool (Size); | |
121 | if (Record == NULL) { | |
122 | return EFI_OUT_OF_RESOURCES; | |
123 | } | |
124 | CopyMem (Record, SmbiosEntry, SmbiosEntry->Length); | |
125 | ||
126 | if (StringArray != NULL) { | |
127 | // Append string pack | |
128 | Str = ((CHAR8 *)Record) + Record->Length; | |
129 | for (Index = 0; StringArray[Index] != NULL; Index++) { | |
130 | StringSize = AsciiStrSize (StringArray[Index]); | |
131 | CopyMem (Str, StringArray[Index], StringSize); | |
132 | Str += StringSize; | |
133 | } | |
134 | *Str = 0; | |
135 | } | |
136 | ||
137 | SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; | |
138 | Status = gSmbios->Add ( | |
139 | gSmbios, | |
140 | gImageHandle, | |
141 | &SmbiosHandle, | |
142 | Record | |
143 | ); | |
144 | ||
145 | FreePool (Record); | |
146 | return Status; | |
147 | } | |
148 | ||
149 | ||
150 | ||
151 | /** | |
152 | Update the string associated with an existing SMBIOS record. | |
153 | ||
154 | This function allows the update of specific SMBIOS strings. The number of valid strings for any | |
155 | SMBIOS record is defined by how many strings were present when Add() was called. | |
156 | ||
157 | @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated. | |
158 | @param[in] StringNumber The non-zero string number of the string to update. | |
159 | @param[in] String Update the StringNumber string with String. | |
160 | ||
161 | @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated. | |
162 | @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid. | |
163 | @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports. | |
164 | @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record. | |
165 | **/ | |
166 | EFI_STATUS | |
167 | EFIAPI | |
8fa6b23c | 168 | SmbiosLibUpdateString ( |
803936cc | 169 | IN EFI_SMBIOS_HANDLE SmbiosHandle, |
170 | IN SMBIOS_TABLE_STRING StringNumber, | |
171 | IN CHAR8 *String | |
172 | ) | |
173 | { | |
174 | UINTN StringIndex; | |
175 | ||
176 | if (String == NULL) { | |
177 | return EFI_INVALID_PARAMETER; | |
178 | } | |
179 | ||
180 | if (*String == '\0') { | |
181 | // A string with no data is not legal in SMBIOS | |
182 | return EFI_INVALID_PARAMETER; | |
183 | } | |
184 | ||
185 | StringIndex = StringNumber; | |
186 | return gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, String); | |
187 | } | |
188 | ||
189 | ||
190 | /** | |
191 | Update the string associated with an existing SMBIOS record. | |
192 | ||
193 | This function allows the update of specific SMBIOS strings. The number of valid strings for any | |
194 | SMBIOS record is defined by how many strings were present when Add() was called. | |
195 | ||
196 | @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated. | |
197 | @param[in] StringNumber The non-zero string number of the string to update. | |
198 | @param[in] String Update the StringNumber string with String. | |
199 | ||
200 | @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated. | |
201 | @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid. | |
202 | @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports. | |
203 | @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record. | |
204 | **/ | |
205 | EFI_STATUS | |
206 | EFIAPI | |
8fa6b23c | 207 | SmbiosLibUpdateUnicodeString ( |
803936cc | 208 | IN EFI_SMBIOS_HANDLE SmbiosHandle, |
209 | IN SMBIOS_TABLE_STRING StringNumber, | |
210 | IN CHAR16 *String | |
211 | ) | |
212 | { | |
213 | EFI_STATUS Status; | |
214 | UINTN StringIndex; | |
215 | CHAR8 *Ascii; | |
216 | ||
217 | if (String == NULL) { | |
218 | return EFI_INVALID_PARAMETER; | |
219 | } | |
220 | ||
221 | if (*String == '\0') { | |
222 | // A string with no data is not legal in SMBIOS | |
223 | return EFI_INVALID_PARAMETER; | |
224 | } | |
225 | ||
226 | Ascii = AllocateZeroPool (StrSize (String)); | |
227 | if (Ascii == NULL) { | |
228 | return EFI_OUT_OF_RESOURCES; | |
229 | } | |
230 | UnicodeStrToAsciiStr (String, Ascii); | |
231 | ||
232 | StringIndex = StringNumber; | |
233 | Status = gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, Ascii); | |
234 | ||
235 | FreePool (Ascii); | |
236 | return Status; | |
237 | } | |
238 | ||
239 | ||
240 | /** | |
241 | Allow caller to read a specific SMBIOS string | |
242 | ||
243 | @param[in] Header SMBIOS record that contains the string. | |
244 | @param[in[ Intance Instance of SMBIOS string 0 - N-1. | |
245 | ||
246 | @retval NULL Instance of Type SMBIOS string was not found. | |
247 | @retval Other Pointer to matching SMBIOS string. | |
248 | **/ | |
249 | CHAR8 * | |
8fa6b23c | 250 | SmbiosLibReadString ( |
803936cc | 251 | IN SMBIOS_STRUCTURE *Header, |
252 | IN UINTN Instance | |
253 | ) | |
254 | { | |
255 | CHAR8 *Data; | |
256 | UINTN NullCount; | |
257 | ||
258 | Data = (CHAR8 *)Header + Header->Length; | |
259 | for (NullCount = 0;!(*Data == 0 && *(Data+1) == 0); ) { | |
260 | if (Instance == NullCount) { | |
261 | return Data; | |
262 | } | |
263 | Data++; | |
264 | if (*(Data - 1) == '\0') { | |
265 | NullCount++; | |
266 | } | |
267 | } | |
268 | ||
269 | return NULL; | |
270 | } | |
271 | ||
272 | ||
273 | /** | |
274 | Allow the caller to discover a specific SMBIOS entry, and patch it if necissary. | |
275 | ||
276 | @param[in] Type Type of the next SMBIOS record to return. | |
277 | @param[in[ Instance Instance of SMBIOS record 0 - N-1. | |
278 | @param[out] SmbiosHandle Returns SMBIOS handle for the matching record. | |
279 | ||
280 | @retval NULL Instance of Type SMBIOS record was not found. | |
281 | @retval Other Pointer to matching SMBIOS record. | |
282 | **/ | |
283 | SMBIOS_STRUCTURE * | |
284 | EFIAPI | |
8fa6b23c | 285 | SmbiosLibGetRecord ( |
803936cc | 286 | IN EFI_SMBIOS_TYPE Type, |
287 | IN UINTN Instance, | |
288 | OUT EFI_SMBIOS_HANDLE *SmbiosHandle | |
289 | ) | |
290 | { | |
291 | EFI_STATUS Status; | |
292 | EFI_SMBIOS_TABLE_HEADER *Record; | |
293 | UINTN Match; | |
294 | ||
295 | Match = 0; | |
296 | *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; | |
297 | do { | |
298 | Status = gSmbios->GetNext (gSmbios, SmbiosHandle, &Type, &Record, NULL); | |
299 | if (!EFI_ERROR (Status)) { | |
300 | if (Match == Instance) { | |
301 | return (SMBIOS_STRUCTURE *)Record; | |
302 | } | |
303 | Match++; | |
304 | } | |
305 | } while (!EFI_ERROR (Status)); | |
306 | ||
307 | return NULL; | |
308 | } | |
309 | ||
310 | ||
311 | /** | |
312 | Remove an SMBIOS record. | |
313 | ||
314 | This function removes an SMBIOS record using the handle specified by SmbiosHandle. | |
315 | ||
316 | @param[in] SmbiosHandle The handle of the SMBIOS record to remove. | |
317 | ||
318 | @retval EFI_SUCCESS SMBIOS record was removed. | |
319 | @retval EFI_INVALID_PARAMETER SmbiosHandle does not specify a valid SMBIOS record. | |
320 | **/ | |
321 | EFI_STATUS | |
322 | EFIAPI | |
8fa6b23c | 323 | SmbiosLibRemove ( |
803936cc | 324 | OUT EFI_SMBIOS_HANDLE SmbiosHandle |
325 | ) | |
326 | { | |
327 | return gSmbios->Remove (gSmbios, SmbiosHandle); | |
328 | } | |
329 | ||
330 | ||
803936cc | 331 | |
332 | /** | |
333 | ||
803936cc | 334 | @param ImageHandle ImageHandle of the loaded driver. |
335 | @param SystemTable Pointer to the EFI System Table. | |
336 | ||
337 | @retval EFI_SUCCESS Register successfully. | |
338 | @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler. | |
339 | **/ | |
340 | EFI_STATUS | |
341 | EFIAPI | |
342 | SmbiosLibConstructor ( | |
343 | IN EFI_HANDLE ImageHandle, | |
344 | IN EFI_SYSTEM_TABLE *SystemTable | |
345 | ) | |
346 | { | |
347 | return gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&gSmbios); | |
348 | } | |
349 |