]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/Library/SmbiosLib/SmbiosLib.c
EmulatorPkg: Fix Visual Studio build for IA32 & X64
[mirror_edk2.git] / EmulatorPkg / Library / SmbiosLib / SmbiosLib.c
CommitLineData
803936cc 1/** @file
2 Provides library functions for common SMBIOS operations. Only available to DXE
3 and UEFI module types.
4
5
6Copyright (c) 2012, Apple Inc. All rights reserved.
e148512e 7Portitions Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
803936cc 8This program and the accompanying materials are licensed and made available under
9the terms and conditions of the BSD License that accompanies this distribution.
10The full text of the license may be found at
11http://opensource.org/licenses/bsd-license.php.
12
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14WITHOUT 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
28EFI_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 40EFI_STATUS
41EFIAPI
8fa6b23c 42SmbiosLibInitializeFromTemplate (
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**/
91EFI_STATUS
92EFIAPI
8fa6b23c 93SmbiosLibCreateEntry (
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**/
168EFI_STATUS
169EFIAPI
8fa6b23c 170SmbiosLibUpdateString (
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**/
207EFI_STATUS
208EFIAPI
8fa6b23c 209SmbiosLibUpdateUnicodeString (
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**/
251CHAR8 *
79b3ce7e 252EFIAPI
8fa6b23c 253SmbiosLibReadString (
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**/
286SMBIOS_STRUCTURE *
287EFIAPI
8fa6b23c 288SmbiosLibGetRecord (
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**/
324EFI_STATUS
325EFIAPI
8fa6b23c 326SmbiosLibRemove (
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**/
343EFI_STATUS
344EFIAPI
345SmbiosLibConstructor (
346 IN EFI_HANDLE ImageHandle,
347 IN EFI_SYSTEM_TABLE *SystemTable
348 )
349{
350 return gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&gSmbios);
351}
352