iPXE
smbios_settings.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <string.h>
29#include <errno.h>
30#include <ipxe/settings.h>
31#include <ipxe/init.h>
32#include <ipxe/uuid.h>
33#include <ipxe/smbios.h>
34
35/** SMBIOS settings scope */
37
38/**
39 * Construct SMBIOS raw-data tag
40 *
41 * @v _type SMBIOS structure type number
42 * @v _structure SMBIOS structure data type
43 * @v _field Field within SMBIOS structure data type
44 * @ret tag SMBIOS setting tag
45 */
46#define SMBIOS_RAW_TAG( _type, _structure, _field ) \
47 ( ( (_type) << 16 ) | \
48 ( offsetof ( _structure, _field ) << 8 ) | \
49 ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
50
51/**
52 * Construct SMBIOS string tag
53 *
54 * @v _type SMBIOS structure type number
55 * @v _structure SMBIOS structure data type
56 * @v _field Field within SMBIOS structure data type
57 * @ret tag SMBIOS setting tag
58 */
59#define SMBIOS_STRING_TAG( _type, _structure, _field ) \
60 ( ( (_type) << 16 ) | \
61 ( offsetof ( _structure, _field ) << 8 ) )
62
63/**
64 * Check applicability of SMBIOS setting
65 *
66 * @v settings Settings block
67 * @v setting Setting
68 * @ret applies Setting applies within this settings block
69 */
71 const struct setting *setting ) {
72
73 return ( setting->scope == &smbios_settings_scope );
74}
75
76/**
77 * Fetch value of SMBIOS setting
78 *
79 * @v settings Settings block, or NULL to search all blocks
80 * @v setting Setting to fetch
81 * @v data Buffer to fill with setting data
82 * @v len Length of buffer
83 * @ret len Length of setting data, or negative error
84 */
85static int smbios_fetch ( struct settings *settings, struct setting *setting,
86 void *data, size_t len ) {
87 const struct smbios_header *structure;
88 unsigned int tag_instance;
89 unsigned int tag_type;
90 unsigned int tag_offset;
91 unsigned int tag_len;
92 const void *src;
93 size_t src_len;
94 unsigned int string;
95 union uuid uuid;
96
97 /* Split tag into instance, type, offset and length */
98 tag_instance = ( ( setting->tag >> 24 ) & 0xff );
99 tag_type = ( ( setting->tag >> 16 ) & 0xff );
100 tag_offset = ( ( setting->tag >> 8 ) & 0xff );
101 tag_len = ( setting->tag & 0xff );
102
103 /* Find SMBIOS structure */
104 structure = smbios_structure ( tag_type, tag_instance );
105 if ( ! structure )
106 return -ENOENT;
107 src = structure;
108 src_len = structure->len;
109 string = 0;
110
111 /* A <length> of zero indicates that the byte at <offset>
112 * contains a string index. An <offset> of zero indicates
113 * that the <length> contains a literal string index.
114 *
115 * Since the byte at offset zero can never contain a string
116 * index, and a literal string index can never be zero, the
117 * combination of both <length> and <offset> being zero
118 * indicates that the entire structure is to be read.
119 */
120 if ( ( tag_len == 0 ) && ( tag_offset == 0 ) ) {
121 /* Read whole structure */
122 } else if ( ( tag_len == 0 ) || ( tag_offset == 0 ) ) {
123 /* Read string */
124 string = tag_len;
125 if ( ( string == 0 ) && ( tag_offset < src_len ) )
126 string = *( ( uint8_t * ) src + tag_offset );
127 src = smbios_string ( structure, string );
128 if ( ! src )
129 return -ENOENT;
130 assert ( string > 0 );
131 src_len = strlen ( src );
132 } else if ( tag_offset > src_len ) {
133 /* Empty read beyond end of structure */
134 src_len = 0;
135 } else {
136 /* Read partial structure */
137 src += tag_offset;
138 src_len -= tag_offset;
139 if ( src_len > tag_len )
140 src_len = tag_len;
141 }
142
143 /* Mangle UUIDs if necessary. iPXE treats UUIDs as being in
144 * network byte order (big-endian). SMBIOS specification
145 * version 2.6 states that UUIDs are stored with little-endian
146 * values in the first three fields; earlier versions did not
147 * specify an endianness. dmidecode assumes that the byte
148 * order is little-endian if and only if the SMBIOS version is
149 * 2.6 or higher; we match this behaviour.
150 */
151 if ( ( ( setting->type == &setting_type_uuid ) ||
152 ( setting->type == &setting_type_guid ) ) &&
153 ( src_len == sizeof ( uuid ) ) &&
154 ( smbios_version() >= SMBIOS_VERSION ( 2, 6 ) ) ) {
155 DBGC ( settings, "SMBIOS detected mangled UUID\n" );
156 memcpy ( &uuid, src, sizeof ( uuid ) );
157 uuid_mangle ( &uuid );
158 src = &uuid;
159 }
160
161 /* Return data */
162 if ( len > src_len )
163 len = src_len;
164 memcpy ( data, src, len );
165
166 /* Set default type */
167 if ( ! setting->type ) {
168 setting->type = ( string ? &setting_type_string :
169 &setting_type_hex );
170 }
171
172 return src_len;
173}
174
175/** SMBIOS settings operations */
177 .applies = smbios_applies,
178 .fetch = smbios_fetch,
179};
180
181/** SMBIOS settings */
182static struct settings smbios_settings = {
183 .refcnt = NULL,
184 .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
185 .children = LIST_HEAD_INIT ( smbios_settings.children ),
187 .default_scope = &smbios_settings_scope,
188};
189
190/** Initialise SMBIOS settings */
191static void smbios_init ( void ) {
193 int rc;
194
195 if ( ( rc = register_settings ( settings, NULL, "smbios" ) ) != 0 ) {
196 DBGC ( settings, "SMBIOS could not register settings: %s\n",
197 strerror ( rc ) );
198 return;
199 }
200}
201
202/** SMBIOS settings initialiser */
203struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
204 .name = "smbios",
205 .initialise = smbios_init,
206};
207
208/** UUID setting obtained via SMBIOS */
209const struct setting uuid_setting __setting ( SETTING_HOST, uuid ) = {
210 .name = "uuid",
211 .description = "UUID",
214 .type = &setting_type_uuid,
215 .scope = &smbios_settings_scope,
216};
217
218/** Manufacturer name setting */
219const struct setting manufacturer_setting __setting ( SETTING_HOST_EXTRA,
220 manufacturer ) = {
221 .name = "manufacturer",
222 .description = "Manufacturer",
225 manufacturer ),
226 .type = &setting_type_string,
227 .scope = &smbios_settings_scope,
228};
229
230/** Product name setting */
231const struct setting product_setting __setting ( SETTING_HOST_EXTRA, product )={
232 .name = "product",
233 .description = "Product name",
236 product ),
237 .type = &setting_type_string,
238 .scope = &smbios_settings_scope,
239};
240
241/** Serial number setting */
242const struct setting serial_setting __setting ( SETTING_HOST_EXTRA, serial ) = {
243 .name = "serial",
244 .description = "Serial number",
247 serial ),
248 .type = &setting_type_string,
249 .scope = &smbios_settings_scope,
250};
251
252/** Asset tag setting */
253const struct setting asset_setting __setting ( SETTING_HOST_EXTRA, asset ) = {
254 .name = "asset",
255 .description = "Asset tag",
258 asset_tag ),
259 .type = &setting_type_string,
260 .scope = &smbios_settings_scope,
261};
262
263/** Board serial number setting (may differ from chassis serial number) */
264const struct setting board_serial_setting __setting ( SETTING_HOST_EXTRA,
265 board-serial ) = {
266 .name = "board-serial",
267 .description = "Base board serial",
270 serial ),
271 .type = &setting_type_string,
272 .scope = &smbios_settings_scope,
273};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned char uint8_t
Definition stdint.h:10
static const void * src
Definition string.h:48
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
ring len
Length.
Definition dwmac.h:226
uint64_t serial
Serial number.
Definition edd.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGC(...)
Definition compiler.h:505
#define INIT_NORMAL
Normal initialisation.
Definition init.h:32
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOENT
No such file or directory.
Definition errno.h:515
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define SETTING_HOST_EXTRA
Host identity additional settings.
Definition settings.h:77
#define SETTING_HOST
Host identity settings.
Definition settings.h:76
Configuration settings.
#define __setting(setting_order, name)
Declare a configuration setting.
Definition settings.h:57
System Management BIOS.
uint8_t product
Product string.
Definition smbios.h:5
uint8_t asset_tag
Asset tag.
Definition smbios.h:11
#define SMBIOS_TYPE_SYSTEM_INFORMATION
SMBIOS system information structure type.
Definition smbios.h:148
#define SMBIOS_TYPE_ENCLOSURE_INFORMATION
SMBIOS enclosure information structure type.
Definition smbios.h:184
uint8_t manufacturer
Manufacturer string.
Definition smbios.h:3
#define SMBIOS_VERSION(major, minor)
Calculate SMBIOS version.
Definition smbios.h:216
#define SMBIOS_TYPE_BASE_BOARD_INFORMATION
SMBIOS base board information structure type.
Definition smbios.h:165
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define __init_fn(init_order)
Declare an initialisation functon.
Definition init.h:24
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
uint32_t string
Definition multiboot.h:2
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition settings.c:476
const char * smbios_string(const struct smbios_header *structure, unsigned int index)
Get indexed string within SMBIOS structure.
Definition smbios.c:252
const struct smbios_header * smbios_structure(unsigned int type, unsigned int instance)
Find specific structure type within SMBIOS.
Definition smbios.c:183
int smbios_version(void)
Get SMBIOS version.
Definition smbios.c:285
#define SMBIOS_RAW_TAG(_type, _structure, _field)
Construct SMBIOS raw-data tag.
static struct settings_operations smbios_settings_operations
SMBIOS settings operations.
static void smbios_init(void)
Initialise SMBIOS settings.
static struct settings smbios_settings
SMBIOS settings.
static const struct settings_scope smbios_settings_scope
SMBIOS settings scope.
static int smbios_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of SMBIOS setting.
static int smbios_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of SMBIOS setting.
#define SMBIOS_STRING_TAG(_type, _structure, _field)
Construct SMBIOS string tag.
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
An initialisation function.
Definition init.h:15
A setting.
Definition settings.h:24
const struct settings_scope * scope
Setting scope (or NULL)
Definition settings.h:50
const struct setting_type * type
Setting type.
Definition settings.h:37
uint64_t tag
Setting tag, if applicable.
Definition settings.h:44
Settings block operations.
Definition settings.h:86
A setting scope.
Definition settings.h:177
A settings block.
Definition settings.h:133
SMBIOS base board information structure.
Definition smbios.h:151
SMBIOS enclosure information structure.
Definition smbios.h:168
An SMBIOS structure header.
Definition smbios.h:120
uint8_t len
Length.
Definition smbios.h:124
SMBIOS system information structure.
Definition smbios.h:130
A universally unique ID.
Definition uuid.h:16
Universally unique IDs.
static void uuid_mangle(union uuid *uuid)
Change UUID endianness.
Definition uuid.h:44