2 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 FILE_LICENCE ( GPL2_OR_LATER
);
24 #include <gpxe/settings.h>
25 #include <gpxe/init.h>
26 #include <gpxe/uuid.h>
27 #include <gpxe/smbios.h>
29 /** SMBIOS settings tag magic number */
30 #define SMBIOS_TAG_MAGIC 0x5B /* "SmBios" */
33 * Construct SMBIOS empty tag
35 * @ret tag SMBIOS setting tag
37 #define SMBIOS_EMPTY_TAG ( SMBIOS_TAG_MAGIC << 24 )
40 * Construct SMBIOS raw-data tag
42 * @v _type SMBIOS structure type number
43 * @v _structure SMBIOS structure data type
44 * @v _field Field within SMBIOS structure data type
45 * @ret tag SMBIOS setting tag
47 #define SMBIOS_RAW_TAG( _type, _structure, _field ) \
48 ( ( SMBIOS_TAG_MAGIC << 24 ) | \
50 ( offsetof ( _structure, _field ) << 8 ) | \
51 ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
54 * Construct SMBIOS string tag
56 * @v _type SMBIOS structure type number
57 * @v _structure SMBIOS structure data type
58 * @v _field Field within SMBIOS structure data type
59 * @ret tag SMBIOS setting tag
61 #define SMBIOS_STRING_TAG( _type, _structure, _field ) \
62 ( ( SMBIOS_TAG_MAGIC << 24 ) | \
64 ( offsetof ( _structure, _field ) << 8 ) )
67 * Fetch value of SMBIOS setting
69 * @v settings Settings block, or NULL to search all blocks
70 * @v setting Setting to fetch
71 * @v data Buffer to fill with setting data
72 * @v len Length of buffer
73 * @ret len Length of setting data, or negative error
75 static int smbios_fetch ( struct settings
*settings __unused
,
76 struct setting
*setting
,
77 void *data
, size_t len
) {
78 struct smbios_structure structure
;
79 unsigned int tag_magic
;
80 unsigned int tag_type
;
81 unsigned int tag_offset
;
85 /* Split tag into type, offset and length */
86 tag_magic
= ( setting
->tag
>> 24 );
87 tag_type
= ( ( setting
->tag
>> 16 ) & 0xff );
88 tag_offset
= ( ( setting
->tag
>> 8 ) & 0xff );
89 tag_len
= ( setting
->tag
& 0xff );
90 if ( tag_magic
!= SMBIOS_TAG_MAGIC
)
93 /* Find SMBIOS structure */
94 if ( ( rc
= find_smbios_structure ( tag_type
, &structure
) ) != 0 )
98 uint8_t buf
[structure
.header
.len
];
100 /* Read SMBIOS structure */
101 if ( ( rc
= read_smbios_structure ( &structure
, buf
,
102 sizeof ( buf
) ) ) != 0 )
105 if ( tag_len
== 0 ) {
107 return read_smbios_string ( &structure
,
114 memcpy ( data
, &buf
[tag_offset
], len
);
120 /** SMBIOS settings operations */
121 static struct settings_operations smbios_settings_operations
= {
122 .fetch
= smbios_fetch
,
125 /** SMBIOS settings */
126 static struct settings smbios_settings
= {
129 .tag_magic
= SMBIOS_EMPTY_TAG
,
130 .siblings
= LIST_HEAD_INIT ( smbios_settings
.siblings
),
131 .children
= LIST_HEAD_INIT ( smbios_settings
.children
),
132 .op
= &smbios_settings_operations
,
135 /** Initialise SMBIOS settings */
136 static void smbios_init ( void ) {
139 if ( ( rc
= register_settings ( &smbios_settings
, NULL
) ) != 0 ) {
140 DBG ( "SMBIOS could not register settings: %s\n",
146 /** SMBIOS settings initialiser */
147 struct init_fn smbios_init_fn
__init_fn ( INIT_NORMAL
) = {
148 .initialise
= smbios_init
,
151 /** UUID setting obtained via SMBIOS */
152 struct setting uuid_setting __setting
= {
154 .description
= "UUID",
155 .tag
= SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION
,
156 struct smbios_system_information
, uuid
),
157 .type
= &setting_type_uuid
,
160 /** Other SMBIOS named settings */
161 struct setting smbios_named_settings
[] __setting
= {
163 .name
= "manufacturer",
164 .description
= "Manufacturer",
165 .tag
= SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION
,
166 struct smbios_system_information
,
168 .type
= &setting_type_string
,
172 .description
= "Product name",
173 .tag
= SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION
,
174 struct smbios_system_information
,
176 .type
= &setting_type_string
,
180 .description
= "Serial number",
181 .tag
= SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION
,
182 struct smbios_system_information
,
184 .type
= &setting_type_string
,
188 .description
= "Asset tag",
189 .tag
= SMBIOS_STRING_TAG ( SMBIOS_TYPE_ENCLOSURE_INFORMATION
,
190 struct smbios_enclosure_information
,
192 .type
= &setting_type_string
,