smbios.c File Reference

System Management BIOS. More...

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <gpxe/uaccess.h>
#include <gpxe/smbios.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static size_t find_strings_terminator (size_t offset)
 Find SMBIOS strings terminator.
int find_smbios_structure (unsigned int type, struct smbios_structure *structure)
 Find specific structure type within SMBIOS.
int read_smbios_structure (struct smbios_structure *structure, void *data, size_t len)
 Copy SMBIOS structure.
int read_smbios_string (struct smbios_structure *structure, unsigned int index, void *data, size_t len)
 Find indexed string within SMBIOS structure.

Variables

static struct smbios smbios
 SMBIOS entry point descriptor.


Detailed Description

System Management BIOS.

Definition in file smbios.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static size_t find_strings_terminator ( size_t  offset  )  [static]

Find SMBIOS strings terminator.

Parameters:
offset Offset to start of strings
Return values:
offset Offset to strings terminator, or 0 if not found

Definition at line 45 of file smbios.c.

References smbios::address, copy_from_user(), and smbios::len.

Referenced by find_smbios_structure().

00045                                                         {
00046         size_t max_offset = ( smbios.len - 2 );
00047         uint16_t nulnul;
00048 
00049         for ( ; offset <= max_offset ; offset++ ) {
00050                 copy_from_user ( &nulnul, smbios.address, offset, 2 );
00051                 if ( nulnul == 0 )
00052                         return ( offset + 1 );
00053         }
00054         return 0;
00055 }

int find_smbios_structure ( unsigned int  type,
struct smbios_structure structure 
)

Find specific structure type within SMBIOS.

Parameters:
type Structure type to search for
structure SMBIOS structure descriptor to fill in
Return values:
rc Return status code

Definition at line 64 of file smbios.c.

References smbios::address, assert, copy_from_user(), smbios::count, DBG, ENOENT, find_smbios(), find_strings_terminator(), smbios_structure::header, smbios_header::len, smbios::len, smbios_structure::offset, offset, smbios_structure::strings_len, smbios_header::type, and UNULL.

Referenced by smbios_fetch().

00065                                                                  {
00066         unsigned int count = 0;
00067         size_t offset = 0;
00068         size_t strings_offset;
00069         size_t terminator_offset;
00070         int rc;
00071 
00072         /* Find SMBIOS */
00073         if ( ( smbios.address == UNULL ) &&
00074              ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
00075                 return rc;
00076         assert ( smbios.address != UNULL );
00077 
00078         /* Scan through list of structures */
00079         while ( ( ( offset + sizeof ( structure->header ) ) < smbios.len )
00080                 && ( count < smbios.count ) ) {
00081 
00082                 /* Read next SMBIOS structure header */
00083                 copy_from_user ( &structure->header, smbios.address, offset,
00084                                  sizeof ( structure->header ) );
00085 
00086                 /* Determine start and extent of strings block */
00087                 strings_offset = ( offset + structure->header.len );
00088                 if ( strings_offset > smbios.len ) {
00089                         DBG ( "SMBIOS structure at offset %zx with length "
00090                               "%x extends beyond SMBIOS\n", offset,
00091                               structure->header.len );
00092                         return -ENOENT;
00093                 }
00094                 terminator_offset = find_strings_terminator ( strings_offset );
00095                 if ( ! terminator_offset ) {
00096                         DBG ( "SMBIOS structure at offset %zx has "
00097                               "unterminated strings section\n", offset );
00098                         return -ENOENT;
00099                 }
00100                 structure->strings_len = ( terminator_offset - strings_offset);
00101 
00102                 DBG ( "SMBIOS structure at offset %zx has type %d, length %x, "
00103                       "strings length %zx\n", offset, structure->header.type,
00104                       structure->header.len, structure->strings_len );
00105 
00106                 /* If this is the structure we want, return */
00107                 if ( structure->header.type == type ) {
00108                         structure->offset = offset;
00109                         return 0;
00110                 }
00111 
00112                 /* Move to next SMBIOS structure */
00113                 offset = ( terminator_offset + 1 );
00114                 count++;
00115         }
00116 
00117         DBG ( "SMBIOS structure type %d not found\n", type );
00118         return -ENOENT;
00119 }

int read_smbios_structure ( struct smbios_structure structure,
void *  data,
size_t  len 
)

Copy SMBIOS structure.

Parameters:
structure SMBIOS structure descriptor
data Buffer to hold SMBIOS structure
len Length of buffer
Return values:
rc Return status code

Definition at line 129 of file smbios.c.

References smbios::address, assert, copy_from_user(), smbios_structure::header, smbios_header::len, smbios_structure::offset, and UNULL.

Referenced by smbios_fetch().

00130                                                      {
00131 
00132         assert ( smbios.address != UNULL );
00133 
00134         if ( len > structure->header.len )
00135                 len = structure->header.len;
00136         copy_from_user ( data, smbios.address, structure->offset, len );
00137         return 0;
00138 }

int read_smbios_string ( struct smbios_structure structure,
unsigned int  index,
void *  data,
size_t  len 
)

Find indexed string within SMBIOS structure.

Parameters:
structure SMBIOS structure descriptor
index String index
data Buffer for string
len Length of string buffer
Return values:
rc Length of string, or negative error

Definition at line 149 of file smbios.c.

References smbios::address, assert, copy_from_user(), DBG, ENOENT, smbios_structure::header, smbios_header::len, offset, smbios_structure::offset, smbios_structure::strings_len, strlen_user(), and UNULL.

Referenced by smbios_fetch().

00150                                                                       {
00151         size_t strings_start = ( structure->offset + structure->header.len );
00152         size_t strings_end = ( strings_start + structure->strings_len );
00153         size_t offset;
00154         size_t string_len;
00155 
00156         assert ( smbios.address != UNULL );
00157 
00158         /* String numbers start at 1 (0 is used to indicate "no string") */
00159         if ( ! index )
00160                 return -ENOENT;
00161 
00162         for ( offset = strings_start ; offset < strings_end ;
00163               offset += ( string_len + 1 ) ) {
00164                 /* Get string length.  This is known safe, since the
00165                  * smbios_strings struct is constructed so as to
00166                  * always end on a string boundary.
00167                  */
00168                 string_len = strlen_user ( smbios.address, offset );
00169                 if ( --index == 0 ) {
00170                         /* Copy string, truncating as necessary. */
00171                         if ( len > string_len )
00172                                 len = string_len;
00173                         copy_from_user ( data, smbios.address, offset, len );
00174                         return string_len;
00175                 }
00176         }
00177 
00178         DBG ( "SMBIOS string index %d not found\n", index );
00179         return -ENOENT;
00180 }


Variable Documentation

struct smbios smbios [static]

Initial value:

 {
        .address = UNULL,
}
SMBIOS entry point descriptor.

Definition at line 35 of file smbios.c.


Generated on Tue Apr 6 20:01:54 2010 for gPXE by  doxygen 1.5.7.1