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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_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  */
85 static 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 */
178  .fetch = smbios_fetch,
179 };
180 
181 /** SMBIOS settings */
182 static 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 */
191 static void smbios_init ( void ) {
192  struct settings *settings = &smbios_settings;
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 */
203 struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
204  .name = "smbios",
205  .initialise = smbios_init,
206 };
207 
208 /** UUID setting obtained via SMBIOS */
209 const 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 */
219 const 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 */
231 const 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 */
242 const 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 */
253 const 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) */
264 const 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 };
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
const char * smbios_string(const struct smbios_header *structure, unsigned int index)
Get indexed string within SMBIOS structure.
Definition: smbios.c:252
Error codes.
A universally unique ID.
Definition: uuid.h:16
#define DBGC(...)
Definition: compiler.h:505
const struct smbios_header * smbios_structure(unsigned int type, unsigned int instance)
Find specific structure type within SMBIOS.
Definition: smbios.c:183
#define ENOENT
No such file or directory.
Definition: errno.h:515
Universally unique IDs.
uint32_t string
Definition: multiboot.h:14
#define SMBIOS_TYPE_BASE_BOARD_INFORMATION
SMBIOS base board information structure type.
Definition: smbios.h:165
#define SETTING_HOST_EXTRA
Host identity additional settings.
Definition: settings.h:77
FILE_SECBOOT(PERMITTED)
const char * name
Name.
Definition: settings.h:29
static void uuid_mangle(union uuid *uuid)
Change UUID endianness.
Definition: uuid.h:44
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:44
#define INIT_NORMAL
Normal initialisation.
Definition: init.h:32
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint8_t len
Length.
Definition: smbios.h:124
An initialisation function.
Definition: init.h:15
#define SMBIOS_STRING_TAG(_type, _structure, _field)
Construct SMBIOS string tag.
#define SMBIOS_TYPE_ENCLOSURE_INFORMATION
SMBIOS enclosure information structure type.
Definition: smbios.h:184
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static const void * src
Definition: string.h:48
uint8_t uuid[16]
UUID.
Definition: smbios.h:23
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
ring len
Length.
Definition: dwmac.h:231
const char * name
Definition: init.h:16
static void smbios_init(void)
Initialise SMBIOS settings.
int smbios_version(void)
Get SMBIOS version.
Definition: smbios.c:285
const struct setting_type * type
Setting type.
Definition: settings.h:37
uint8_t asset_tag
Asset tag.
Definition: smbios.h:23
static struct settings smbios_settings
SMBIOS settings.
Configuration settings.
static int smbios_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of SMBIOS setting.
#define SMBIOS_VERSION(major, minor)
Calculate SMBIOS version.
Definition: smbios.h:216
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
uint64_t serial
Serial number.
Definition: edd.h:31
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
Settings block operations.
Definition: settings.h:86
A settings block.
Definition: settings.h:133
unsigned char uint8_t
Definition: stdint.h:10
A setting scope.
Definition: settings.h:177
const struct setting uuid_setting __setting(SETTING_HOST, uuid)
UUID setting obtained via SMBIOS.
struct list_head siblings
Sibling settings blocks.
Definition: settings.h:141
uint8_t manufacturer
Manufacturer string.
Definition: smbios.h:15
A setting.
Definition: settings.h:24
System Management BIOS.
static int smbios_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of SMBIOS setting.
An SMBIOS structure header.
Definition: smbios.h:120
SMBIOS system information structure.
Definition: smbios.h:130
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define SMBIOS_RAW_TAG(_type, _structure, _field)
Construct SMBIOS raw-data tag.
uint8_t product
Product string.
Definition: smbios.h:17
int(* applies)(struct settings *settings, const struct setting *setting)
Check applicability of setting.
Definition: settings.h:99
struct list_head children
Child settings blocks.
Definition: settings.h:143
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:476
static struct settings_operations smbios_settings_operations
SMBIOS settings operations.
static const struct settings_scope smbios_settings_scope
SMBIOS settings scope.
SMBIOS base board information structure.
Definition: smbios.h:151
struct init_fn smbios_init_fn __init_fn(INIT_NORMAL)
SMBIOS settings initialiser.
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:31
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:50
#define SMBIOS_TYPE_SYSTEM_INFORMATION
SMBIOS system information structure type.
Definition: smbios.h:148
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
String functions.
SMBIOS enclosure information structure.
Definition: smbios.h:168
struct refcnt * refcnt
Reference counter.
Definition: settings.h:135
#define SETTING_HOST
Host identity settings.
Definition: settings.h:76