]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/Library/SmbiosLib/SmbiosLib.c
MdeModulePkg PciBusDxe: Follow the P2P Bridge spec to detect if a P2P bridge supports...
[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.
7Portitions Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
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
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**/
89EFI_STATUS
90EFIAPI
8fa6b23c 91SmbiosLibCreateEntry (
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**/
166EFI_STATUS
167EFIAPI
8fa6b23c 168SmbiosLibUpdateString (
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**/
205EFI_STATUS
206EFIAPI
8fa6b23c 207SmbiosLibUpdateUnicodeString (
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**/
249CHAR8 *
8fa6b23c 250SmbiosLibReadString (
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**/
283SMBIOS_STRUCTURE *
284EFIAPI
8fa6b23c 285SmbiosLibGetRecord (
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**/
321EFI_STATUS
322EFIAPI
8fa6b23c 323SmbiosLibRemove (
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**/
340EFI_STATUS
341EFIAPI
342SmbiosLibConstructor (
343 IN EFI_HANDLE ImageHandle,
344 IN EFI_SYSTEM_TABLE *SystemTable
345 )
346{
347 return gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&gSmbios);
348}
349