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