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. More...
 
static size_t find_strings_terminator (size_t offset)
 Find SMBIOS strings terminator. More...
 
int find_smbios_structure (unsigned int type, unsigned int instance, struct smbios_structure *structure)
 Find specific structure type within SMBIOS. More...
 
int read_smbios_structure (struct smbios_structure *structure, void *data, size_t len)
 Copy SMBIOS structure. More...
 
int read_smbios_string (struct smbios_structure *structure, unsigned int index, void *data, size_t len)
 Find indexed string within SMBIOS structure. More...
 
int smbios_version (void)
 Get SMBIOS version. 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  )

◆ find_smbios_entry()

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.

53  {
54  uint8_t buf[256]; /* 256 is maximum length possible */
55  static size_t offset = 0; /* Avoid repeated attempts to locate SMBIOS */
56  size_t entry_len;
57  unsigned int i;
58  uint8_t sum;
59 
60  /* Try to find SMBIOS */
61  for ( ; offset < len ; offset += 0x10 ) {
62 
63  /* Read start of header and verify signature */
64  copy_from_user ( entry, start, offset, sizeof ( *entry ) );
65  if ( entry->signature != SMBIOS_SIGNATURE )
66  continue;
67 
68  /* Read whole header and verify checksum */
69  entry_len = entry->len;
70  assert ( entry_len <= sizeof ( buf ) );
71  copy_from_user ( buf, start, offset, entry_len );
72  for ( i = 0, sum = 0 ; i < entry_len ; i++ ) {
73  sum += buf[i];
74  }
75  if ( sum != 0 ) {
76  DBG ( "SMBIOS at %08lx has bad checksum %02x\n",
77  user_to_phys ( start, offset ), sum );
78  continue;
79  }
80 
81  /* Fill result structure */
82  DBG ( "Found SMBIOS v%d.%d entry point at %08lx\n",
83  entry->major, entry->minor,
84  user_to_phys ( start, offset ) );
85  return 0;
86  }
87 
88  DBG ( "No SMBIOS found\n" );
89  return -ENODEV;
90 }
#define SMBIOS_SIGNATURE
Signature for SMBIOS entry point.
Definition: smbios.h:35
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
unsigned long user_to_phys(userptr_t userptr, off_t offset)
Convert user pointer to physical address.
uint32_t start
Starting offset.
Definition: netvsc.h:12
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
#define ENODEV
No such device.
Definition: errno.h:509
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498

References assert(), copy_from_user(), DBG, ENODEV, entry, len, offset, SMBIOS_SIGNATURE, start, and user_to_phys().

Referenced by bios_find_smbios().

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

98  {
99  size_t max_offset = ( smbios.len - 2 );
100  uint16_t nulnul;
101 
102  for ( ; offset <= max_offset ; offset++ ) {
103  copy_from_user ( &nulnul, smbios.address, offset, 2 );
104  if ( nulnul == 0 )
105  return ( offset + 1 );
106  }
107  return 0;
108 }
unsigned short uint16_t
Definition: stdint.h:11
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
size_t len
Length of SMBIOS structures.
Definition: smbios.h:168
SMBIOS entry point descriptor.
Definition: smbios.h:164
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
userptr_t address
Start of SMBIOS structures.
Definition: smbios.h:166

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

Referenced by find_smbios_structure().

◆ find_smbios_structure()

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.

119  {
120  unsigned int count = 0;
121  size_t offset = 0;
122  size_t strings_offset;
123  size_t terminator_offset;
124  int rc;
125 
126  /* Find SMBIOS */
127  if ( ( smbios.address == UNULL ) &&
128  ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
129  return rc;
130  assert ( smbios.address != UNULL );
131 
132  /* Scan through list of structures */
133  while ( ( ( offset + sizeof ( structure->header ) ) < smbios.len )
134  && ( count < smbios.count ) ) {
135 
136  /* Read next SMBIOS structure header */
137  copy_from_user ( &structure->header, smbios.address, offset,
138  sizeof ( structure->header ) );
139 
140  /* Determine start and extent of strings block */
141  strings_offset = ( offset + structure->header.len );
142  if ( strings_offset > smbios.len ) {
143  DBG ( "SMBIOS structure at offset %zx with length "
144  "%x extends beyond SMBIOS\n", offset,
145  structure->header.len );
146  return -ENOENT;
147  }
148  terminator_offset = find_strings_terminator ( strings_offset );
149  if ( ! terminator_offset ) {
150  DBG ( "SMBIOS structure at offset %zx has "
151  "unterminated strings section\n", offset );
152  return -ENOENT;
153  }
154  structure->strings_len = ( terminator_offset - strings_offset);
155 
156  DBG ( "SMBIOS structure at offset %zx has type %d, length %x, "
157  "strings length %zx\n", offset, structure->header.type,
158  structure->header.len, structure->strings_len );
159 
160  /* If this is the structure we want, return */
161  if ( ( structure->header.type == type ) &&
162  ( instance-- == 0 ) ) {
163  structure->offset = offset;
164  return 0;
165  }
166 
167  /* Move to next SMBIOS structure */
168  offset = ( terminator_offset + 1 );
169  count++;
170  }
171 
172  DBG ( "SMBIOS structure type %d not found\n", type );
173  return -ENOENT;
174 }
size_t strings_len
Length of strings section.
Definition: smbios.h:95
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned int count
Number of SMBIOS structures.
Definition: smbios.h:170
uint8_t type
Type.
Definition: ena.h:16
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
size_t len
Length of SMBIOS structures.
Definition: smbios.h:168
#define ENOENT
No such file or directory.
Definition: errno.h:514
SMBIOS entry point descriptor.
Definition: smbios.h:164
struct smbios_header header
Copy of SMBIOS structure header.
Definition: smbios.h:91
int find_smbios(struct smbios *smbios)
uint8_t len
Length.
Definition: smbios.h:83
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
uint8_t type
Type.
Definition: smbios.h:81
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36
userptr_t address
Start of SMBIOS structures.
Definition: smbios.h:166
uint16_t count
Number of entries.
Definition: ena.h:22
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static size_t find_strings_terminator(size_t offset)
Find SMBIOS strings terminator.
Definition: smbios.c:98
size_t offset
Offset of structure within SMBIOS.
Definition: smbios.h:93

References smbios::address, assert(), copy_from_user(), count, smbios::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, type, smbios_header::type, and UNULL.

Referenced by smbios_fetch(), and smsc95xx_vm3_fetch_mac().

◆ read_smbios_structure()

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.

185  {
186 
187  assert ( smbios.address != UNULL );
188 
189  if ( len > structure->header.len )
190  len = structure->header.len;
191  copy_from_user ( data, smbios.address, structure->offset, len );
192  return 0;
193 }
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
SMBIOS entry point descriptor.
Definition: smbios.h:164
struct smbios_header header
Copy of SMBIOS structure header.
Definition: smbios.h:91
uint8_t len
Length.
Definition: smbios.h:83
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36
uint32_t len
Length.
Definition: ena.h:14
userptr_t address
Start of SMBIOS structures.
Definition: smbios.h:166
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
size_t offset
Offset of structure within SMBIOS.
Definition: smbios.h:93

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

Referenced by smbios_fetch(), and smsc95xx_vm3_fetch_mac().

◆ read_smbios_string()

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.

205  {
206  size_t strings_start = ( structure->offset + structure->header.len );
207  size_t strings_end = ( strings_start + structure->strings_len );
208  size_t offset;
209  size_t string_len;
210 
211  assert ( smbios.address != UNULL );
212 
213  /* String numbers start at 1 (0 is used to indicate "no string") */
214  if ( ! index )
215  return -ENOENT;
216 
217  for ( offset = strings_start ; offset < strings_end ;
218  offset += ( string_len + 1 ) ) {
219  /* Get string length. This is known safe, since the
220  * smbios_strings struct is constructed so as to
221  * always end on a string boundary.
222  */
223  string_len = strlen_user ( smbios.address, offset );
224  if ( --index == 0 ) {
225  /* Copy string, truncating as necessary. */
226  if ( len > string_len )
227  len = string_len;
229  return string_len;
230  }
231  }
232 
233  DBG ( "SMBIOS string index %d not found\n", index );
234  return -ENOENT;
235 }
size_t strings_len
Length of strings section.
Definition: smbios.h:95
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define ENOENT
No such file or directory.
Definition: errno.h:514
SMBIOS entry point descriptor.
Definition: smbios.h:164
struct smbios_header header
Copy of SMBIOS structure header.
Definition: smbios.h:91
uint8_t len
Length.
Definition: smbios.h:83
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
size_t strlen_user(userptr_t userptr, off_t offset)
Find length of NUL-terminated string in user buffer.
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36
uint32_t len
Length.
Definition: ena.h:14
userptr_t address
Start of SMBIOS structures.
Definition: smbios.h:166
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21
size_t offset
Offset of structure within SMBIOS.
Definition: smbios.h:93

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

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

242  {
243  int rc;
244 
245  /* Find SMBIOS */
246  if ( ( smbios.address == UNULL ) &&
247  ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
248  return rc;
249  assert ( smbios.address != UNULL );
250 
251  return smbios.version;
252 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
SMBIOS entry point descriptor.
Definition: smbios.h:164
int find_smbios(struct smbios *smbios)
uint16_t version
SMBIOS version.
Definition: smbios.h:172
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36
userptr_t address
Start of SMBIOS structures.
Definition: smbios.h:166

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

Referenced by smbios_fetch().

Variable Documentation

◆ smbios

struct smbios smbios
static
Initial value:
= {
.address = UNULL,
}
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36

SMBIOS entry point descriptor.

Definition at line 40 of file smbios.c.