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

Variables

static struct smbios smbios
 SMBIOS entry point descriptor.

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

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}
unsigned char uint8_t
Definition stdint.h:10
ring len
Length.
Definition dwmac.h:226
uint32_t start
Starting offset.
Definition netvsc.h:1

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}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define DBGC(...)
Definition compiler.h:505
#define SMBIOS_SIGNATURE
Signature for 32-bit SMBIOS entry point.
Definition smbios.h:36
static uint8_t smbios_checksum(const void *start, size_t len)
Calculate SMBIOS entry point structure checksum.
Definition smbios.c:52
SMBIOS 32-bit entry point.
Definition smbios.h:50
uint8_t minor
Minor version.
Definition smbios.h:63
uint32_t signature
Signature.
Definition smbios.h:55
uint8_t major
Major version.
Definition smbios.h:61
uint8_t len
Length.
Definition smbios.h:59
SMBIOS entry point descriptor.
Definition smbios.h:198

References DBGC, len, smbios_entry::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 SMBIOS3_SIGNATURE
Signature for 64-bit SMBIOS entry point.
Definition smbios.h:40
SMBIOS 64-bit entry point.
Definition smbios.h:91
uint8_t major
Major version.
Definition smbios.h:104
uint8_t len
Length.
Definition smbios.h:102
uint8_t minor
Minor version.
Definition smbios.h:106
uint32_t signature
Signature.
Definition smbios.h:96

References DBGC, len, smbios3_entry::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()

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}
unsigned short uint16_t
Definition stdint.h:11
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define __attribute__(x)
Definition compiler.h:10
size_t len
Length of SMBIOS structures.
Definition smbios.h:202
const void * address
Start of SMBIOS structures.
Definition smbios.h:200

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:3
uint32_t type
Operating system type.
Definition ena.h:1
static unsigned int count
Number of entries.
Definition dwmac.h:220
int find_smbios(struct smbios *smbios)
#define SMBIOS_TYPE_END
SMBIOS end of table type.
Definition smbios.h:190
static size_t find_strings_terminator(size_t offset)
Find SMBIOS strings terminator.
Definition smbios.c:161
An SMBIOS structure header.
Definition smbios.h:120
uint8_t len
Length.
Definition smbios.h:124
uint8_t type
Type.
Definition smbios.h:122
unsigned int count
Number of SMBIOS structures.
Definition smbios.h:204

References smbios::address, assert, count, smbios::count, DBGC, find_smbios(), find_strings_terminator(), smbios::len, smbios_header::len, NULL, offset, rc, SMBIOS_TYPE_END, smbios_header::type, and 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}
long index
Definition bigint.h:65
uint32_t string
Definition multiboot.h:2
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

References smbios::address, assert, DBGC, index, len, smbios_header::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}
uint16_t version
SMBIOS version.
Definition smbios.h:206

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 */
305}

References smbios::address, and NULL.

Variable Documentation

◆ smbios

struct smbios smbios
static
Initial value:
= {
.address = NULL,
}

SMBIOS entry point descriptor.

Definition at line 41 of file smbios.c.

41 {
42 .address = NULL,
43};