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)
 
 FILE_SECBOOT (PERMITTED)
 
static uint8_t smbios_checksum (const void *start, size_t len)
 Calculate SMBIOS entry point structure checksum. More...
 
const struct smbios_entryfind_smbios_entry (const void *start, size_t len)
 Scan for SMBIOS 32-bit entry point structure. More...
 
const struct smbios3_entryfind_smbios3_entry (const void *start, size_t len)
 Scan for SMBIOS 64-bit entry point structure. More...
 
static size_t find_strings_terminator (size_t offset)
 Find SMBIOS strings terminator. More...
 
const struct smbios_headersmbios_structure (unsigned int type, unsigned int instance)
 Find specific structure type within SMBIOS. More...
 
const char * smbios_string (const struct smbios_header *structure, unsigned int index)
 Get indexed string within SMBIOS structure. More...
 
int smbios_version (void)
 Get SMBIOS version. More...
 
void smbios_clear (void)
 Clear SMBIOS entry point descriptor. More...
 

Variables

static struct smbios smbios
 SMBIOS entry point descriptor. More...
 

Detailed Description

System Management BIOS.

Definition in file smbios.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ smbios_checksum()

static uint8_t smbios_checksum ( const void *  start,
size_t  len 
)
static

Calculate SMBIOS entry point structure checksum.

Parameters
startStart address of region
lenLength of entry point structure
Return values
sumByte checksum

Definition at line 52 of file smbios.c.

52  {
53  const uint8_t *byte = start;
54  uint8_t sum = 0;
55 
56  /* Compute checksum */
57  while ( len-- )
58  sum += *(byte++);
59 
60  return sum;
61 }
uint32_t start
Starting offset.
Definition: netvsc.h:12
ring len
Length.
Definition: dwmac.h:231
unsigned char uint8_t
Definition: stdint.h:10

References len, and start.

Referenced by find_smbios3_entry(), and find_smbios_entry().

◆ find_smbios_entry()

const struct smbios_entry* find_smbios_entry ( const void *  start,
size_t  len 
)

Scan for SMBIOS 32-bit entry point structure.

Parameters
startStart address of region to scan
lenLength of region to scan
Return values
entrySMBIOS entry point structure, or NULL if not found

Definition at line 70 of file smbios.c.

71  {
72  static size_t offset = 0; /* Avoid repeated attempts to locate SMBIOS */
73  const struct smbios_entry *entry;
74  uint8_t sum;
75 
76  /* Try to find SMBIOS */
77  for ( ; ( offset + sizeof ( *entry ) ) <= len ; offset += 0x10 ) {
78 
79  /* Verify signature */
80  entry = ( start + offset );
81  if ( entry->signature != SMBIOS_SIGNATURE )
82  continue;
83 
84  /* Verify length */
85  if ( ( entry->len < sizeof ( *entry ) ) ||
86  ( ( offset + entry->len ) > len ) ) {
87  DBGC ( &smbios, "SMBIOS at %#08lx has bad length "
88  "%#02x\n", virt_to_phys ( entry ), entry->len );
89  continue;
90  }
91 
92  /* Verify checksum */
93  if ( ( sum = smbios_checksum ( entry, entry->len ) ) != 0 ) {
94  DBGC ( &smbios, "SMBIOS at %#08lx has bad checksum "
95  "%#02x\n", virt_to_phys ( entry ), sum );
96  continue;
97  }
98 
99  /* Fill result structure */
100  DBGC ( &smbios, "Found SMBIOS v%d.%d entry point at %#08lx\n",
101  entry->major, entry->minor, virt_to_phys ( entry ) );
102  return entry;
103  }
104 
105  DBGC ( &smbios, "No SMBIOS found\n" );
106  return NULL;
107 }
uint32_t signature
Signature.
Definition: smbios.h:55
#define SMBIOS_SIGNATURE
Signature for 32-bit SMBIOS entry point.
Definition: smbios.h:36
#define DBGC(...)
Definition: compiler.h:505
SMBIOS entry point descriptor.
Definition: smbios.h:198
uint32_t start
Starting offset.
Definition: netvsc.h:12
ring len
Length.
Definition: dwmac.h:231
SMBIOS 32-bit entry point.
Definition: smbios.h:50
unsigned char uint8_t
Definition: stdint.h:10
uint8_t minor
Minor version.
Definition: smbios.h:63
uint8_t len
Length.
Definition: smbios.h:59
static uint8_t smbios_checksum(const void *start, size_t len)
Calculate SMBIOS entry point structure checksum.
Definition: smbios.c:52
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
uint8_t major
Major version.
Definition: smbios.h:61
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References DBGC, smbios_entry::len, len, smbios_entry::major, smbios_entry::minor, NULL, offset, smbios_entry::signature, smbios_checksum(), SMBIOS_SIGNATURE, and start.

Referenced by bios_find_smbios2().

◆ find_smbios3_entry()

const struct smbios3_entry* find_smbios3_entry ( const void *  start,
size_t  len 
)

Scan for SMBIOS 64-bit entry point structure.

Parameters
startStart address of region to scan
lenLength of region to scan
Return values
entrySMBIOS entry point structure, or NULL if not found

Definition at line 116 of file smbios.c.

117  {
118  static size_t offset = 0; /* Avoid repeated attempts to locate SMBIOS */
119  const struct smbios3_entry *entry;
120  uint8_t sum;
121 
122  /* Try to find SMBIOS */
123  for ( ; ( offset + sizeof ( *entry ) ) <= len ; offset += 0x10 ) {
124 
125  /* Verify signature */
126  entry = ( start + offset );
127  if ( entry->signature != SMBIOS3_SIGNATURE )
128  continue;
129 
130  /* Verify length */
131  if ( ( entry->len < sizeof ( *entry ) ) ||
132  ( ( offset + entry->len ) > len ) ) {
133  DBGC ( &smbios, "SMBIOS at %#08lx has bad length "
134  "%#02x\n", virt_to_phys ( entry ), entry->len );
135  continue;
136  }
137 
138  /* Verify checksum */
139  if ( ( sum = smbios_checksum ( entry, entry->len ) ) != 0 ) {
140  DBGC ( &smbios, "SMBIOS3 at %#08lx has bad checksum "
141  "%#02x\n", virt_to_phys ( entry ), sum );
142  continue;
143  }
144 
145  /* Fill result structure */
146  DBGC ( &smbios, "Found SMBIOS3 v%d.%d entry point at %#08lx\n",
147  entry->major, entry->minor, virt_to_phys ( entry ) );
148  return entry;
149  }
150 
151  DBGC ( &smbios, "No SMBIOS3 found\n" );
152  return NULL;
153 }
#define DBGC(...)
Definition: compiler.h:505
SMBIOS entry point descriptor.
Definition: smbios.h:198
#define SMBIOS3_SIGNATURE
Signature for 64-bit SMBIOS entry point.
Definition: smbios.h:40
uint32_t start
Starting offset.
Definition: netvsc.h:12
uint8_t len
Length.
Definition: smbios.h:102
uint32_t signature
Signature.
Definition: smbios.h:96
ring len
Length.
Definition: dwmac.h:231
unsigned char uint8_t
Definition: stdint.h:10
uint8_t minor
Minor version.
Definition: smbios.h:106
static uint8_t smbios_checksum(const void *start, size_t len)
Calculate SMBIOS entry point structure checksum.
Definition: smbios.c:52
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
uint8_t major
Major version.
Definition: smbios.h:104
SMBIOS 64-bit entry point.
Definition: smbios.h:91

References DBGC, smbios3_entry::len, len, smbios3_entry::major, smbios3_entry::minor, NULL, offset, smbios3_entry::signature, SMBIOS3_SIGNATURE, smbios_checksum(), and start.

Referenced by bios_find_smbios3().

◆ find_strings_terminator()

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 161 of file smbios.c.

161  {
162  const uint16_t *nulnul __attribute__ (( aligned ( 1 ) ));
163 
164  /* Sanity checks */
165  assert ( smbios.address != NULL );
166 
167  /* Check for presence of terminating empty string */
168  for ( ; ( offset + sizeof ( *nulnul ) ) <= smbios.len ; offset++ ) {
169  nulnul = ( smbios.address + offset );
170  if ( *nulnul == 0 )
171  return ( offset + 1 );
172  }
173  return 0;
174 }
#define __attribute__(x)
Definition: compiler.h:10
unsigned short uint16_t
Definition: stdint.h:11
size_t len
Length of SMBIOS structures.
Definition: smbios.h:202
SMBIOS entry point descriptor.
Definition: smbios.h:198
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
const void * address
Start of SMBIOS structures.
Definition: smbios.h:200
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References __attribute__, smbios::address, assert(), smbios::len, NULL, and offset.

Referenced by smbios_structure().

◆ smbios_structure()

const struct smbios_header* smbios_structure ( unsigned int  type,
unsigned int  instance 
)

Find specific structure type within SMBIOS.

Parameters
typeStructure type to search for
instanceInstance of this type of structure
Return values
structureSMBIOS structure header, or NULL if not found

Definition at line 183 of file smbios.c.

184  {
185  const struct smbios_header *structure;
186  unsigned int count = 0;
187  size_t offset = 0;
188  size_t strings_offset;
189  size_t terminator_offset;
190  size_t strings_len;
191  int rc;
192 
193  /* Find SMBIOS */
194  if ( ( smbios.address == NULL ) &&
195  ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
196  return NULL;
197  assert ( smbios.address != NULL );
198 
199  /* Scan through list of structures */
200  while ( ( ( offset + sizeof ( *structure ) ) < smbios.len ) &&
201  ( ( smbios.count == 0 ) || ( count < smbios.count ) ) ) {
202 
203  /* Access next SMBIOS structure header */
204  structure = ( smbios.address + offset );
205 
206  /* Determine start and extent of strings block */
207  strings_offset = ( offset + structure->len );
208  if ( strings_offset > smbios.len ) {
209  DBGC ( &smbios, "SMBIOS structure at offset %#zx "
210  "with length %#x extends beyond SMBIOS\n",
211  offset, structure->len );
212  return NULL;
213  }
214  terminator_offset = find_strings_terminator ( strings_offset );
215  if ( ! terminator_offset ) {
216  DBGC ( &smbios, "SMBIOS structure at offset %#zx has "
217  "unterminated strings section\n", offset );
218  return NULL;
219  }
220  strings_len = ( terminator_offset - strings_offset);
221  DBGC ( &smbios, "SMBIOS structure at offset %#zx has type %d, "
222  "length %#x, strings length %#zx\n", offset,
223  structure->type, structure->len, strings_len );
224 
225  /* Stop if we have reached an end-of-table marker */
226  if ( ( smbios.count == 0 ) &&
227  ( structure->type == SMBIOS_TYPE_END ) )
228  break;
229 
230  /* If this is the structure we want, return */
231  if ( ( structure->type == type ) &&
232  ( instance-- == 0 ) ) {
233  return structure;
234  }
235 
236  /* Move to next SMBIOS structure */
237  offset = ( terminator_offset + 1 );
238  count++;
239  }
240 
241  DBGC ( &smbios, "SMBIOS structure type %d not found\n", type );
242  return NULL;
243 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned int count
Number of SMBIOS structures.
Definition: smbios.h:204
#define SMBIOS_TYPE_END
SMBIOS end of table type.
Definition: smbios.h:190
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
size_t len
Length of SMBIOS structures.
Definition: smbios.h:202
SMBIOS entry point descriptor.
Definition: smbios.h:198
int find_smbios(struct smbios *smbios)
uint8_t len
Length.
Definition: smbios.h:124
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static unsigned int count
Number of entries.
Definition: dwmac.h:225
const void * address
Start of SMBIOS structures.
Definition: smbios.h:200
An SMBIOS structure header.
Definition: smbios.h:120
uint8_t type
Type.
Definition: smbios.h:122
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static size_t find_strings_terminator(size_t offset)
Find SMBIOS strings terminator.
Definition: smbios.c:161

References smbios::address, assert(), smbios::count, count, DBGC, find_smbios(), find_strings_terminator(), smbios_header::len, smbios::len, NULL, offset, rc, SMBIOS_TYPE_END, type, and smbios_header::type.

Referenced by smbios_fetch(), and smsc95xx_vm3_fetch_mac().

◆ smbios_string()

const char* smbios_string ( const struct smbios_header structure,
unsigned int  index 
)

Get indexed string within SMBIOS structure.

Parameters
structureSMBIOS structure header
indexString index
Return values
stringSMBIOS string, or NULL if not fond

Definition at line 252 of file smbios.c.

253  {
254  const char *string;
255  unsigned int i;
256  size_t len;
257 
258  /* Sanity check */
259  assert ( smbios.address != NULL );
260 
261  /* Step through strings */
262  string = ( ( ( const void * ) structure ) + structure->len );
263  for ( i = index ; i-- ; ) {
264  /* Get string length. This is known safe, since we
265  * check for the empty-string terminator in
266  * smbios_structure().
267  */
268  len = strlen ( string );
269  if ( ! len )
270  break;
271  if ( i == 0 )
272  return string;
273  string += ( len + 1 /* NUL */ );
274  }
275 
276  DBGC ( &smbios, "SMBIOS string index %d not found\n", index );
277  return NULL;
278 }
#define DBGC(...)
Definition: compiler.h:505
long index
Definition: bigint.h:65
uint32_t string
Definition: multiboot.h:14
SMBIOS entry point descriptor.
Definition: smbios.h:198
uint8_t len
Length.
Definition: smbios.h:124
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
const void * address
Start of SMBIOS structures.
Definition: smbios.h:200
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References smbios::address, assert(), DBGC, index, smbios_header::len, len, NULL, string, and strlen().

Referenced by smbios_fetch(), and smsc95xx_vm3_fetch_mac().

◆ smbios_version()

int smbios_version ( void  )

Get SMBIOS version.

Return values
versionVersion, or negative error

Definition at line 285 of file smbios.c.

285  {
286  int rc;
287 
288  /* Find SMBIOS */
289  if ( ( smbios.address == NULL ) &&
290  ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
291  return rc;
292  assert ( smbios.address != NULL );
293 
294  return smbios.version;
295 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
SMBIOS entry point descriptor.
Definition: smbios.h:198
int find_smbios(struct smbios *smbios)
uint16_t version
SMBIOS version.
Definition: smbios.h:206
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
const void * address
Start of SMBIOS structures.
Definition: smbios.h:200
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

Referenced by smbios_fetch().

◆ smbios_clear()

void smbios_clear ( void  )

Clear SMBIOS entry point descriptor.

Definition at line 301 of file smbios.c.

301  {
302 
303  /* Clear address */
304  smbios.address = NULL;
305 }
SMBIOS entry point descriptor.
Definition: smbios.h:198
const void * address
Start of SMBIOS structures.
Definition: smbios.h:200
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References smbios::address, and NULL.

Variable Documentation

◆ smbios

struct smbios smbios
static
Initial value:
= {
.address = NULL,
}
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

SMBIOS entry point descriptor.

Definition at line 41 of file smbios.c.