LibSmbiosView.c revision ec8a502e66fe190a77546e82820e921cfa9d05e0
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
21STATIC UINT8                    mInit         = 0;
22STATIC UINT8                    m64Init       = 0;
23STATIC SMBIOS_TABLE_ENTRY_POINT     *mSmbiosTable   = NULL;
24STATIC SMBIOS_TABLE_3_0_ENTRY_POINT *mSmbios64BitTable = NULL;
25STATIC SMBIOS_STRUCTURE_POINTER m_SmbiosStruct;
26STATIC SMBIOS_STRUCTURE_POINTER *mSmbiosStruct = &m_SmbiosStruct;
27STATIC SMBIOS_STRUCTURE_POINTER m_Smbios64BitStruct;
28STATIC 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**/
35EFI_STATUS
36LibSmbiosInit (
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**/
75EFI_STATUS
76LibSmbios64BitInit (
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**/
113VOID
114LibSmbiosCleanup (
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**/
131VOID
132LibSmbios64BitCleanup (
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**/
151VOID
152LibSmbiosGetEPS (
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**/
167VOID
168LibSmbios64BitGetEPS (
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**/
187CHAR8*
188LibGetSmbiosString (
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**/
246EFI_STATUS
247LibGetSmbiosStructure (
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**/
318EFI_STATUS
319LibGetSmbios64BitStructure (
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}