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 
26 #include <stdint.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <ipxe/settings.h>
30 #include <ipxe/init.h>
31 #include <ipxe/uuid.h>
32 #include <ipxe/smbios.h>
33 
34 /** SMBIOS settings scope */
36 
37 /**
38  * Construct SMBIOS raw-data tag
39  *
40  * @v _type SMBIOS structure type number
41  * @v _structure SMBIOS structure data type
42  * @v _field Field within SMBIOS structure data type
43  * @ret tag SMBIOS setting tag
44  */
45 #define SMBIOS_RAW_TAG( _type, _structure, _field ) \
46  ( ( (_type) << 16 ) | \
47  ( offsetof ( _structure, _field ) << 8 ) | \
48  ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
49 
50 /**
51  * Construct SMBIOS string tag
52  *
53  * @v _type SMBIOS structure type number
54  * @v _structure SMBIOS structure data type
55  * @v _field Field within SMBIOS structure data type
56  * @ret tag SMBIOS setting tag
57  */
58 #define SMBIOS_STRING_TAG( _type, _structure, _field ) \
59  ( ( (_type) << 16 ) | \
60  ( offsetof ( _structure, _field ) << 8 ) )
61 
62 /**
63  * Check applicability of SMBIOS setting
64  *
65  * @v settings Settings block
66  * @v setting Setting
67  * @ret applies Setting applies within this settings block
68  */
70  const struct setting *setting ) {
71 
72  return ( setting->scope == &smbios_settings_scope );
73 }
74 
75 /**
76  * Fetch value of SMBIOS setting
77  *
78  * @v settings Settings block, or NULL to search all blocks
79  * @v setting Setting to fetch
80  * @v data Buffer to fill with setting data
81  * @v len Length of buffer
82  * @ret len Length of setting data, or negative error
83  */
84 static int smbios_fetch ( struct settings *settings __unused,
85  struct setting *setting,
86  void *data, size_t len ) {
87  struct smbios_structure structure;
88  unsigned int tag_instance;
89  unsigned int tag_type;
90  unsigned int tag_offset;
91  unsigned int tag_len;
92  int rc;
93 
94  /* Split tag into instance, type, offset and length */
95  tag_instance = ( ( setting->tag >> 24 ) & 0xff );
96  tag_type = ( ( setting->tag >> 16 ) & 0xff );
97  tag_offset = ( ( setting->tag >> 8 ) & 0xff );
98  tag_len = ( setting->tag & 0xff );
99 
100  /* Find SMBIOS structure */
101  if ( ( rc = find_smbios_structure ( tag_type, tag_instance,
102  &structure ) ) != 0 )
103  return rc;
104 
105  {
106  uint8_t buf[structure.header.len];
107  const void *raw;
108  union uuid uuid;
109  unsigned int index;
110 
111  /* Read SMBIOS structure */
112  if ( ( rc = read_smbios_structure ( &structure, buf,
113  sizeof ( buf ) ) ) != 0 )
114  return rc;
115 
116  /* A <length> of zero indicates that the byte at
117  * <offset> contains a string index. An <offset> of
118  * zero indicates that the <length> contains a literal
119  * string index.
120  *
121  * Since the byte at offset zero can never contain a
122  * string index, and a literal string index can never
123  * be zero, the combination of both <length> and
124  * <offset> being zero indicates that the entire
125  * structure is to be read.
126  */
127  if ( ( tag_len == 0 ) && ( tag_offset == 0 ) ) {
128  tag_len = sizeof ( buf );
129  } else if ( ( tag_len == 0 ) || ( tag_offset == 0 ) ) {
130  index = ( ( tag_offset == 0 ) ?
131  tag_len : buf[tag_offset] );
132  if ( ( rc = read_smbios_string ( &structure, index,
133  data, len ) ) < 0 ) {
134  return rc;
135  }
136  if ( ! setting->type )
137  setting->type = &setting_type_string;
138  return rc;
139  }
140 
141  /* Limit length */
142  if ( tag_offset > sizeof ( buf ) ) {
143  tag_len = 0;
144  } else if ( ( tag_offset + tag_len ) > sizeof ( buf ) ) {
145  tag_len = ( sizeof ( buf ) - tag_offset );
146  }
147 
148  /* Mangle UUIDs if necessary. iPXE treats UUIDs as
149  * being in network byte order (big-endian). SMBIOS
150  * specification version 2.6 states that UUIDs are
151  * stored with little-endian values in the first three
152  * fields; earlier versions did not specify an
153  * endianness. dmidecode assumes that the byte order
154  * is little-endian if and only if the SMBIOS version
155  * is 2.6 or higher; we match this behaviour.
156  */
157  raw = &buf[tag_offset];
158  if ( ( ( setting->type == &setting_type_uuid ) ||
159  ( setting->type == &setting_type_guid ) ) &&
160  ( tag_len == sizeof ( uuid ) ) &&
161  ( smbios_version() >= SMBIOS_VERSION ( 2, 6 ) ) ) {
162  DBG ( "SMBIOS detected mangled UUID\n" );
163  memcpy ( &uuid, &buf[tag_offset], sizeof ( uuid ) );
164  uuid_mangle ( &uuid );
165  raw = &uuid;
166  }
167 
168  /* Return data */
169  if ( len > tag_len )
170  len = tag_len;
171  memcpy ( data, raw, len );
172  if ( ! setting->type )
173  setting->type = &setting_type_hex;
174  return tag_len;
175  }
176 }
177 
178 /** SMBIOS settings operations */
181  .fetch = smbios_fetch,
182 };
183 
184 /** SMBIOS settings */
185 static struct settings smbios_settings = {
186  .refcnt = NULL,
187  .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
188  .children = LIST_HEAD_INIT ( smbios_settings.children ),
190  .default_scope = &smbios_settings_scope,
191 };
192 
193 /** Initialise SMBIOS settings */
194 static void smbios_init ( void ) {
195  int rc;
196 
198  "smbios" ) ) != 0 ) {
199  DBG ( "SMBIOS could not register settings: %s\n",
200  strerror ( rc ) );
201  return;
202  }
203 }
204 
205 /** SMBIOS settings initialiser */
206 struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
208 };
209 
210 /** UUID setting obtained via SMBIOS */
211 const struct setting uuid_setting __setting ( SETTING_HOST, uuid ) = {
212  .name = "uuid",
213  .description = "UUID",
216  .type = &setting_type_uuid,
217  .scope = &smbios_settings_scope,
218 };
219 
220 /** Manufacturer name setting */
221 const struct setting manufacturer_setting __setting ( SETTING_HOST_EXTRA,
222  manufacturer ) = {
223  .name = "manufacturer",
224  .description = "Manufacturer",
227  manufacturer ),
228  .type = &setting_type_string,
229  .scope = &smbios_settings_scope,
230 };
231 
232 /** Product name setting */
233 const struct setting product_setting __setting ( SETTING_HOST_EXTRA, product )={
234  .name = "product",
235  .description = "Product name",
238  product ),
239  .type = &setting_type_string,
240  .scope = &smbios_settings_scope,
241 };
242 
243 /** Serial number setting */
244 const struct setting serial_setting __setting ( SETTING_HOST_EXTRA, serial ) = {
245  .name = "serial",
246  .description = "Serial number",
249  serial ),
250  .type = &setting_type_string,
251  .scope = &smbios_settings_scope,
252 };
253 
254 /** Asset tag setting */
255 const struct setting asset_setting __setting ( SETTING_HOST_EXTRA, asset ) = {
256  .name = "asset",
257  .description = "Asset tag",
260  asset_tag ),
261  .type = &setting_type_string,
262  .scope = &smbios_settings_scope,
263 };
264 
265 /** Board serial number setting (may differ from chassis serial number) */
266 const struct setting board_serial_setting __setting ( SETTING_HOST_EXTRA,
267  board-serial ) = {
268  .name = "board-serial",
269  .description = "Base board serial",
272  serial ),
273  .type = &setting_type_string,
274  .scope = &smbios_settings_scope,
275 };
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int smbios_fetch(struct settings *settings __unused, struct setting *setting, void *data, size_t len)
Fetch value of SMBIOS setting.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
void(* initialise)(void)
Definition: init.h:15
Error codes.
A universally unique ID.
Definition: uuid.h:15
int read_smbios_structure(struct smbios_structure *structure, void *data, size_t len)
Copy SMBIOS structure.
Definition: smbios.c:241
long index
Definition: bigint.h:61
Universally unique IDs.
#define SMBIOS_TYPE_BASE_BOARD_INFORMATION
SMBIOS base board information structure type.
Definition: smbios.h:174
#define SETTING_HOST_EXTRA
Host identity additional settings.
Definition: settings.h:76
struct smbios_header header
Copy of SMBIOS structure header.
Definition: smbios.h:131
const char * name
Name.
Definition: settings.h:28
static void uuid_mangle(union uuid *uuid)
Change UUID endianness.
Definition: uuid.h:43
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
#define INIT_NORMAL
Normal initialisation.
Definition: init.h:30
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint8_t len
Length.
Definition: smbios.h:123
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
int find_smbios_structure(unsigned int type, unsigned int instance, struct smbios_structure *structure)
Find specific structure type within SMBIOS.
Definition: smbios.c:170
An initialisation function.
Definition: init.h:14
#define SMBIOS_STRING_TAG(_type, _structure, _field)
Construct SMBIOS string tag.
#define SMBIOS_TYPE_ENCLOSURE_INFORMATION
SMBIOS enclosure information structure type.
Definition: smbios.h:193
uint8_t uuid[16]
UUID.
Definition: smbios.h:22
static void smbios_init(void)
Initialise SMBIOS settings.
int smbios_version(void)
Get SMBIOS version.
Definition: smbios.c:299
int read_smbios_string(struct smbios_structure *structure, unsigned int index, void *data, size_t len)
Find indexed string within SMBIOS structure.
Definition: smbios.c:261
const struct setting_type * type
Setting type.
Definition: settings.h:36
uint8_t asset_tag
Asset tag.
Definition: smbios.h:22
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:225
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint64_t serial
Serial number.
Definition: edd.h:30
Settings block operations.
Definition: settings.h:85
A settings block.
Definition: settings.h:132
unsigned char uint8_t
Definition: stdint.h:10
A setting scope.
Definition: settings.h:176
const struct setting uuid_setting __setting(SETTING_HOST, uuid)
UUID setting obtained via SMBIOS.
struct list_head siblings
Sibling settings blocks.
Definition: settings.h:140
uint8_t manufacturer
Manufacturer string.
Definition: smbios.h:14
A setting.
Definition: settings.h:23
System Management BIOS.
SMBIOS system information structure.
Definition: smbios.h:139
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:16
__be32 raw[7]
Definition: CIB_PRM.h:28
int(* applies)(struct settings *settings, const struct setting *setting)
Check applicability of setting.
Definition: settings.h:98
struct list_head children
Child settings blocks.
Definition: settings.h:142
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:475
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:160
struct init_fn smbios_init_fn __init_fn(INIT_NORMAL)
SMBIOS settings initialiser.
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:49
uint32_t len
Length.
Definition: ena.h:14
SMBIOS structure descriptor.
Definition: smbios.h:129
#define SMBIOS_TYPE_SYSTEM_INFORMATION
SMBIOS system information structure type.
Definition: smbios.h:157
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
SMBIOS enclosure information structure.
Definition: smbios.h:177
struct refcnt * refcnt
Reference counter.
Definition: settings.h:134
#define SETTING_HOST
Host identity settings.
Definition: settings.h:75