iPXE
Functions | Variables
smbios.c File Reference

System Management BIOS. More...

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

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int find_smbios_entry (userptr_t start, size_t len, struct smbios_entry *entry)
 Scan for SMBIOS entry point structure.
static size_t find_strings_terminator (size_t offset)
 Find SMBIOS strings terminator.
int find_smbios_structure (unsigned int type, unsigned int instance, 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.
int smbios_version (void)
 Get SMBIOS version.

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_OR_UBDL  )
int find_smbios_entry ( userptr_t  start,
size_t  len,
struct smbios_entry entry 
)

Scan for SMBIOS entry point structure.

Parameters:
startStart address of region to scan
lenLength of region to scan
entrySMBIOS entry point structure to fill in
Return values:
rcReturn status code

Definition at line 52 of file smbios.c.

References assert, copy_from_user(), DBG, ENODEV, smbios_entry::len, len, smbios_entry::major, smbios_entry::minor, offset, smbios_entry::signature, SMBIOS_SIGNATURE, and user_to_phys().

Referenced by bios_find_smbios().

                                                     {
        uint8_t buf[256]; /* 256 is maximum length possible */
        static size_t offset = 0; /* Avoid repeated attempts to locate SMBIOS */
        size_t entry_len;
        unsigned int i;
        uint8_t sum;

        /* Try to find SMBIOS */
        for ( ; offset < len ; offset += 0x10 ) {

                /* Read start of header and verify signature */
                copy_from_user ( entry, start, offset, sizeof ( *entry ) );
                if ( entry->signature != SMBIOS_SIGNATURE )
                        continue;

                /* Read whole header and verify checksum */
                entry_len = entry->len;
                assert ( entry_len <= sizeof ( buf ) );
                copy_from_user ( buf, start, offset, entry_len );
                for ( i = 0, sum = 0 ; i < entry_len ; i++ ) {
                        sum += buf[i];
                }
                if ( sum != 0 ) {
                        DBG ( "SMBIOS at %08lx has bad checksum %02x\n",
                              user_to_phys ( start, offset ), sum );
                        continue;
                }

                /* Fill result structure */
                DBG ( "Found SMBIOS v%d.%d entry point at %08lx\n",
                      entry->major, entry->minor,
                      user_to_phys ( start, offset ) );
                return 0;
        }

        DBG ( "No SMBIOS found\n" );
        return -ENODEV;
}
static size_t find_strings_terminator ( size_t  offset) [static]

Find SMBIOS strings terminator.

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

Definition at line 98 of file smbios.c.

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

Referenced by find_smbios_structure().

                                                        {
        size_t max_offset = ( smbios.len - 2 );
        uint16_t nulnul;

        for ( ; offset <= max_offset ; offset++ ) {
                copy_from_user ( &nulnul, smbios.address, offset, 2 );
                if ( nulnul == 0 )
                        return ( offset + 1 );
        }
        return 0;
}
int find_smbios_structure ( unsigned int  type,
unsigned int  instance,
struct smbios_structure structure 
)

Find specific structure type within SMBIOS.

Parameters:
typeStructure type to search for
instanceInstance of this type of structure
structureSMBIOS structure descriptor to fill in
Return values:
rcReturn status code

Definition at line 118 of file smbios.c.

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

Referenced by smbios_fetch(), and smsc95xx_vm3_fetch_mac().

                                                                 {
        unsigned int count = 0;
        size_t offset = 0;
        size_t strings_offset;
        size_t terminator_offset;
        int rc;

        /* Find SMBIOS */
        if ( ( smbios.address == UNULL ) &&
             ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
                return rc;
        assert ( smbios.address != UNULL );

        /* Scan through list of structures */
        while ( ( ( offset + sizeof ( structure->header ) ) < smbios.len )
                && ( count < smbios.count ) ) {

                /* Read next SMBIOS structure header */
                copy_from_user ( &structure->header, smbios.address, offset,
                                 sizeof ( structure->header ) );

                /* Determine start and extent of strings block */
                strings_offset = ( offset + structure->header.len );
                if ( strings_offset > smbios.len ) {
                        DBG ( "SMBIOS structure at offset %zx with length "
                              "%x extends beyond SMBIOS\n", offset,
                              structure->header.len );
                        return -ENOENT;
                }
                terminator_offset = find_strings_terminator ( strings_offset );
                if ( ! terminator_offset ) {
                        DBG ( "SMBIOS structure at offset %zx has "
                              "unterminated strings section\n", offset );
                        return -ENOENT;
                }
                structure->strings_len = ( terminator_offset - strings_offset);

                DBG ( "SMBIOS structure at offset %zx has type %d, length %x, "
                      "strings length %zx\n", offset, structure->header.type,
                      structure->header.len, structure->strings_len );

                /* If this is the structure we want, return */
                if ( ( structure->header.type == type ) &&
                     ( instance-- == 0 ) ) {
                        structure->offset = offset;
                        return 0;
                }

                /* Move to next SMBIOS structure */
                offset = ( terminator_offset + 1 );
                count++;
        }

        DBG ( "SMBIOS structure type %d not found\n", type );
        return -ENOENT;
}
int read_smbios_structure ( struct smbios_structure structure,
void *  data,
size_t  len 
)

Copy SMBIOS structure.

Parameters:
structureSMBIOS structure descriptor
dataBuffer to hold SMBIOS structure
lenLength of buffer
Return values:
rcReturn status code

Definition at line 184 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(), and smsc95xx_vm3_fetch_mac().

                                                     {

        assert ( smbios.address != UNULL );

        if ( len > structure->header.len )
                len = structure->header.len;
        copy_from_user ( data, smbios.address, structure->offset, len );
        return 0;
}
int read_smbios_string ( struct smbios_structure structure,
unsigned int  index,
void *  data,
size_t  len 
)

Find indexed string within SMBIOS structure.

Parameters:
structureSMBIOS structure descriptor
indexString index
dataBuffer for string
lenLength of string buffer
Return values:
rcLength of string, or negative error

Definition at line 204 of file smbios.c.

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

Referenced by smbios_fetch(), and smsc95xx_vm3_fetch_mac().

                                                                      {
        size_t strings_start = ( structure->offset + structure->header.len );
        size_t strings_end = ( strings_start + structure->strings_len );
        size_t offset;
        size_t string_len;

        assert ( smbios.address != UNULL );

        /* String numbers start at 1 (0 is used to indicate "no string") */
        if ( ! index )
                return -ENOENT;

        for ( offset = strings_start ; offset < strings_end ;
              offset += ( string_len + 1 ) ) {
                /* Get string length.  This is known safe, since the
                 * smbios_strings struct is constructed so as to
                 * always end on a string boundary.
                 */
                string_len = strlen_user ( smbios.address, offset );
                if ( --index == 0 ) {
                        /* Copy string, truncating as necessary. */
                        if ( len > string_len )
                                len = string_len;
                        copy_from_user ( data, smbios.address, offset, len );
                        return string_len;
                }
        }

        DBG ( "SMBIOS string index %d not found\n", index );
        return -ENOENT;
}
int smbios_version ( void  )

Get SMBIOS version.

Return values:
versionVersion, or negative error

Definition at line 242 of file smbios.c.

References smbios::address, assert, find_smbios(), rc, UNULL, and smbios::version.

Referenced by smbios_fetch().

                            {
        int rc;

        /* Find SMBIOS */
        if ( ( smbios.address == UNULL ) &&
             ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
                return rc;
        assert ( smbios.address != UNULL );

        return smbios.version;
}

Variable Documentation

struct smbios smbios [static]
Initial value:
 {
        .address = UNULL,
}

SMBIOS entry point descriptor.

Definition at line 40 of file smbios.c.