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)
 
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  )

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

51  {
52  const uint8_t *byte = start;
53  uint8_t sum = 0;
54 
55  /* Compute checksum */
56  while ( len-- )
57  sum += *(byte++);
58 
59  return sum;
60 }
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 69 of file smbios.c.

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

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

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

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

160  {
161  const uint16_t *nulnul __attribute__ (( aligned ( 1 ) ));
162 
163  /* Sanity checks */
164  assert ( smbios.address != NULL );
165 
166  /* Check for presence of terminating empty string */
167  for ( ; ( offset + sizeof ( *nulnul ) ) <= smbios.len ; offset++ ) {
168  nulnul = ( smbios.address + offset );
169  if ( *nulnul == 0 )
170  return ( offset + 1 );
171  }
172  return 0;
173 }
#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:201
SMBIOS entry point descriptor.
Definition: smbios.h:197
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
const void * address
Start of SMBIOS structures.
Definition: smbios.h:199
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

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

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

252  {
253  const char *string;
254  unsigned int i;
255  size_t len;
256 
257  /* Sanity check */
258  assert ( smbios.address != NULL );
259 
260  /* Step through strings */
261  string = ( ( ( const void * ) structure ) + structure->len );
262  for ( i = index ; i-- ; ) {
263  /* Get string length. This is known safe, since we
264  * check for the empty-string terminator in
265  * smbios_structure().
266  */
267  len = strlen ( string );
268  if ( ! len )
269  break;
270  if ( i == 0 )
271  return string;
272  string += ( len + 1 /* NUL */ );
273  }
274 
275  DBGC ( &smbios, "SMBIOS string index %d not found\n", index );
276  return NULL;
277 }
#define DBGC(...)
Definition: compiler.h:505
long index
Definition: bigint.h:62
uint32_t string
Definition: multiboot.h:14
SMBIOS entry point descriptor.
Definition: smbios.h:197
uint8_t len
Length.
Definition: smbios.h:123
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:199
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

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

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

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

References smbios::address, and NULL.

Variable Documentation

◆ smbios

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

SMBIOS entry point descriptor.

Definition at line 40 of file smbios.c.