1 /** @file
2 API for SMBIOS table.
3
4 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15
16 #include "../UefiShellDebug1CommandsLib.h"
17 #include <Guid/SmBios.h>
18 #include "LibSmbiosView.h"
19 #include "SmbiosView.h"
20
21 STATIC UINT8 mInit = 0;
22 STATIC UINT8 m64Init = 0;
23 STATIC SMBIOS_TABLE_ENTRY_POINT *mSmbiosTable = NULL;
24 STATIC SMBIOS_TABLE_3_0_ENTRY_POINT *mSmbios64BitTable = NULL;
25 STATIC SMBIOS_STRUCTURE_POINTER m_SmbiosStruct;
26 STATIC SMBIOS_STRUCTURE_POINTER *mSmbiosStruct = &m_SmbiosStruct;
27 STATIC SMBIOS_STRUCTURE_POINTER m_Smbios64BitStruct;
28 STATIC SMBIOS_STRUCTURE_POINTER *mSmbios64BitStruct = &m_Smbios64BitStruct;
29
30 /**
31 Init the SMBIOS VIEW API's environment.
32
33 @retval EFI_SUCCESS Successful to init the SMBIOS VIEW Lib.
34 **/
35 EFI_STATUS
LibSmbiosInit(VOID)36 LibSmbiosInit (
37 VOID
38 )
39 {
40 EFI_STATUS Status;
41
42 //
43 // Init only once
44 //
45 if (mInit == 1) {
46 return EFI_SUCCESS;
47 }
48 //
49 // Get SMBIOS table from System Configure table
50 //
51 Status = GetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID**)&mSmbiosTable);
52
53 if (mSmbiosTable == NULL) {
54 return EFI_NOT_FOUND;
55 }
56
57 if (EFI_ERROR (Status)) {
58 ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_GET_TABLE_ERROR), gShellDebug1HiiHandle, Status);
59 return Status;
60 }
61 //
62 // Init SMBIOS structure table address
63 //
64 mSmbiosStruct->Raw = (UINT8 *) (UINTN) (mSmbiosTable->TableAddress);
65
66 mInit = 1;
67 return EFI_SUCCESS;
68 }
69
70 /**
71 Init the SMBIOS VIEW API's environment.
72
73 @retval EFI_SUCCESS Successful to init the SMBIOS VIEW Lib.
74 **/
75 EFI_STATUS
LibSmbios64BitInit(VOID)76 LibSmbios64BitInit (
77 VOID
78 )
79 {
80 EFI_STATUS Status;
81
82 //
83 // Init only once
84 //
85 if (m64Init == 1) {
86 return EFI_SUCCESS;
87 }
88 //
89 // Get SMBIOS table from System Configure table
90 //
91 Status = GetSystemConfigurationTable (&gEfiSmbios3TableGuid, (VOID**)&mSmbios64BitTable);
92
93 if (mSmbios64BitTable == NULL) {
94 return EFI_NOT_FOUND;
95 }
96
97 if (EFI_ERROR (Status)) {
98 ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_GET_TABLE_ERROR), gShellDebug1HiiHandle, Status);
99 return Status;
100 }
101 //
102 // Init SMBIOS structure table address
103 //
104 mSmbios64BitStruct->Raw = (UINT8 *) (UINTN) (mSmbios64BitTable->TableAddress);
105
106 m64Init = 1;
107 return EFI_SUCCESS;
108 }
109
110 /**
111 Cleanup the Smbios information.
112 **/
113 VOID
LibSmbiosCleanup(VOID)114 LibSmbiosCleanup (
115 VOID
116 )
117 {
118 //
119 // Release resources
120 //
121 if (mSmbiosTable != NULL) {
122 mSmbiosTable = NULL;
123 }
124
125 mInit = 0;
126 }
127
128 /**
129 Cleanup the Smbios information.
130 **/
131 VOID
LibSmbios64BitCleanup(VOID)132 LibSmbios64BitCleanup (
133 VOID
134 )
135 {
136 //
137 // Release resources
138 //
139 if (mSmbios64BitTable != NULL) {
140 mSmbios64BitTable = NULL;
141 }
142
143 m64Init = 0;
144 }
145
146 /**
147 Get the entry point structure for the table.
148
149 @param[out] EntryPointStructure The pointer to populate.
150 **/
151 VOID
LibSmbiosGetEPS(OUT SMBIOS_TABLE_ENTRY_POINT ** EntryPointStructure)152 LibSmbiosGetEPS (
153 OUT SMBIOS_TABLE_ENTRY_POINT **EntryPointStructure
154 )
155 {
156 //
157 // return SMBIOS Table address
158 //
159 *EntryPointStructure = mSmbiosTable;
160 }
161
162 /**
163 Get the entry point structure for the table.
164
165 @param[out] EntryPointStructure The pointer to populate.
166 **/
167 VOID
LibSmbios64BitGetEPS(OUT SMBIOS_TABLE_3_0_ENTRY_POINT ** EntryPointStructure)168 LibSmbios64BitGetEPS (
169 OUT SMBIOS_TABLE_3_0_ENTRY_POINT **EntryPointStructure
170 )
171 {
172 //
173 // return SMBIOS Table address
174 //
175 *EntryPointStructure = mSmbios64BitTable;
176 }
177
178 /**
179 Return SMBIOS string for the given string number.
180
181 @param[in] Smbios Pointer to SMBIOS structure.
182 @param[in] StringNumber String number to return. -1 is used to skip all strings and
183 point to the next SMBIOS structure.
184
185 @return Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == -1
186 **/
187 CHAR8*
LibGetSmbiosString(IN SMBIOS_STRUCTURE_POINTER * Smbios,IN UINT16 StringNumber)188 LibGetSmbiosString (
189 IN SMBIOS_STRUCTURE_POINTER *Smbios,
190 IN UINT16 StringNumber
191 )
192 {
193 UINT16 Index;
194 CHAR8 *String;
195
196 ASSERT (Smbios != NULL);
197
198 //
199 // Skip over formatted section
200 //
201 String = (CHAR8 *) (Smbios->Raw + Smbios->Hdr->Length);
202
203 //
204 // Look through unformated section
205 //
206 for (Index = 1; Index <= StringNumber; Index++) {
207 if (StringNumber == Index) {
208 return String;
209 }
210 //
211 // Skip string
212 //
213 for (; *String != 0; String++);
214 String++;
215
216 if (*String == 0) {
217 //
218 // If double NULL then we are done.
219 // Return pointer to next structure in Smbios.
220 // if you pass in a -1 you will always get here
221 //
222 Smbios->Raw = (UINT8 *)++String;
223 return NULL;
224 }
225 }
226
227 return NULL;
228 }
229
230 /**
231 Get SMBIOS structure for the given Handle,
232 Handle is changed to the next handle or 0xFFFF when the end is
233 reached or the handle is not found.
234
235 @param[in, out] Handle 0xFFFF: get the first structure
236 Others: get a structure according to this value.
237 @param[out] Buffer The pointer to the pointer to the structure.
238 @param[out] Length Length of the structure.
239
240 @retval DMI_SUCCESS Handle is updated with next structure handle or
241 0xFFFF(end-of-list).
242
243 @retval DMI_INVALID_HANDLE Handle is updated with first structure handle or
244 0xFFFF(end-of-list).
245 **/
246 EFI_STATUS
LibGetSmbiosStructure(IN OUT UINT16 * Handle,OUT UINT8 ** Buffer,OUT UINT16 * Length)247 LibGetSmbiosStructure (
248 IN OUT UINT16 *Handle,
249 OUT UINT8 **Buffer,
250 OUT UINT16 *Length
251 )
252 {
253 SMBIOS_STRUCTURE_POINTER Smbios;
254 SMBIOS_STRUCTURE_POINTER SmbiosEnd;
255 UINT8 *Raw;
256
257 if (*Handle == INVALID_HANDLE) {
258 *Handle = mSmbiosStruct->Hdr->Handle;
259 return DMI_INVALID_HANDLE;
260 }
261
262 if ((Buffer == NULL) || (Length == NULL)) {
263 ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUFF_LEN_SPEC), gShellDebug1HiiHandle);
264 return DMI_INVALID_HANDLE;
265 }
266
267 *Length = 0;
268 Smbios.Hdr = mSmbiosStruct->Hdr;
269 SmbiosEnd.Raw = Smbios.Raw + mSmbiosTable->TableLength;
270 while (Smbios.Raw < SmbiosEnd.Raw) {
271 if (Smbios.Hdr->Handle == *Handle) {
272 Raw = Smbios.Raw;
273 //
274 // Walk to next structure
275 //
276 LibGetSmbiosString (&Smbios, (UINT16) (-1));
277 //
278 // Length = Next structure head - this structure head
279 //
280 *Length = (UINT16) (Smbios.Raw - Raw);
281 *Buffer = Raw;
282 //
283 // update with the next structure handle.
284 //
285 if (Smbios.Raw < SmbiosEnd.Raw) {
286 *Handle = Smbios.Hdr->Handle;
287 } else {
288 *Handle = INVALID_HANDLE;
289 }
290 return DMI_SUCCESS;
291 }
292 //
293 // Walk to next structure
294 //
295 LibGetSmbiosString (&Smbios, (UINT16) (-1));
296 }
297
298 *Handle = INVALID_HANDLE;
299 return DMI_INVALID_HANDLE;
300 }
301
302 /**
303 Get SMBIOS structure for the given Handle,
304 Handle is changed to the next handle or 0xFFFF when the end is
305 reached or the handle is not found.
306
307 @param[in, out] Handle 0xFFFF: get the first structure
308 Others: get a structure according to this value.
309 @param[out] Buffer The pointer to the pointer to the structure.
310 @param[out] Length Length of the structure.
311
312 @retval DMI_SUCCESS Handle is updated with next structure handle or
313 0xFFFF(end-of-list).
314
315 @retval DMI_INVALID_HANDLE Handle is updated with first structure handle or
316 0xFFFF(end-of-list).
317 **/
318 EFI_STATUS
LibGetSmbios64BitStructure(IN OUT UINT16 * Handle,OUT UINT8 ** Buffer,OUT UINT16 * Length)319 LibGetSmbios64BitStructure (
320 IN OUT UINT16 *Handle,
321 OUT UINT8 **Buffer,
322 OUT UINT16 *Length
323 )
324 {
325 SMBIOS_STRUCTURE_POINTER Smbios;
326 SMBIOS_STRUCTURE_POINTER SmbiosEnd;
327 UINT8 *Raw;
328
329 if (*Handle == INVALID_HANDLE) {
330 *Handle = mSmbios64BitStruct->Hdr->Handle;
331 return DMI_INVALID_HANDLE;
332 }
333
334 if ((Buffer == NULL) || (Length == NULL)) {
335 ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUFF_LEN_SPEC), gShellDebug1HiiHandle);
336 return DMI_INVALID_HANDLE;
337 }
338
339 *Length = 0;
340 Smbios.Hdr = mSmbios64BitStruct->Hdr;
341
342 SmbiosEnd.Raw = Smbios.Raw + mSmbios64BitTableLength;
343 while (Smbios.Raw < SmbiosEnd.Raw) {
344 if (Smbios.Hdr->Handle == *Handle) {
345 Raw = Smbios.Raw;
346 //
347 // Walk to next structure
348 //
349 LibGetSmbiosString (&Smbios, (UINT16) (-1));
350 //
351 // Length = Next structure head - this structure head
352 //
353 *Length = (UINT16) (Smbios.Raw - Raw);
354 *Buffer = Raw;
355 //
356 // update with the next structure handle.
357 //
358 if (Smbios.Raw < SmbiosEnd.Raw) {
359 *Handle = Smbios.Hdr->Handle;
360 } else {
361 *Handle = INVALID_HANDLE;
362 }
363 return DMI_SUCCESS;
364 }
365 //
366 // Walk to next structure
367 //
368 LibGetSmbiosString (&Smbios, (UINT16) (-1));
369 }
370
371 *Handle = INVALID_HANDLE;
372 return DMI_INVALID_HANDLE;
373 }
374