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.
22 #include <gpxe/settings.h>
23 #include <gpxe/init.h>
24 #include <gpxe/uuid.h>
27 /** SMBIOS settings tag magic number */
28 #define SMBIOS_TAG_MAGIC 0x5B /* "SmBios" */
31 * Construct SMBIOS empty tag
33 * @ret tag SMBIOS setting tag
35 #define SMBIOS_EMPTY_TAG ( SMBIOS_TAG_MAGIC << 24 )
38 * Construct SMBIOS raw-data tag
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
45 #define SMBIOS_RAW_TAG( _type, _structure, _field ) \
46 ( ( SMBIOS_TAG_MAGIC << 24 ) | \
48 ( offsetof ( _structure, _field ) << 8 ) | \
49 ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
52 * Construct SMBIOS string tag
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
59 #define SMBIOS_STRING_TAG( _type, _structure, _field ) \
60 ( ( SMBIOS_TAG_MAGIC << 24 ) | \
62 ( offsetof ( _structure, _field ) << 8 ) )
65 * Store value of SMBIOS setting
67 * @v settings Settings block
68 * @v setting Setting to store
69 * @v data Setting data, or NULL to clear setting
70 * @v len Length of setting data
71 * @ret rc Return status code
73 static int smbios_store ( struct settings *settings __unused,
74 struct setting *setting __unused,
75 const void *data __unused, size_t len __unused ) {
76 /* Cannot write data into SMBIOS */
81 * Fetch value of SMBIOS setting
83 * @v settings Settings block, or NULL to search all blocks
84 * @v setting Setting to fetch
85 * @v data Buffer to fill with setting data
86 * @v len Length of buffer
87 * @ret len Length of setting data, or negative error
89 static int smbios_fetch ( struct settings *settings __unused,
90 struct setting *setting,
91 void *data, size_t len ) {
92 struct smbios_structure structure;
93 unsigned int tag_magic;
94 unsigned int tag_type;
95 unsigned int tag_offset;
99 /* Split tag into type, offset and length */
100 tag_magic = ( setting->tag >> 24 );
101 tag_type = ( ( setting->tag >> 16 ) & 0xff );
102 tag_offset = ( ( setting->tag >> 8 ) & 0xff );
103 tag_len = ( setting->tag & 0xff );
104 if ( tag_magic != SMBIOS_TAG_MAGIC )
107 /* Find SMBIOS structure */
108 if ( ( rc = find_smbios_structure ( tag_type, &structure ) ) != 0 )
112 uint8_t buf[structure.header.len];
114 /* Read SMBIOS structure */
115 if ( ( rc = read_smbios_structure ( &structure, buf,
116 sizeof ( buf ) ) ) != 0 )
119 if ( tag_len == 0 ) {
121 return read_smbios_string ( &structure,
128 memcpy ( data, &buf[tag_offset], len );
134 /** SMBIOS settings operations */
135 static struct settings_operations smbios_settings_operations = {
136 .store = smbios_store,
137 .fetch = smbios_fetch,
140 /** SMBIOS settings */
141 static struct settings smbios_settings = {
144 .tag_magic = SMBIOS_EMPTY_TAG,
145 .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
146 .children = LIST_HEAD_INIT ( smbios_settings.children ),
147 .op = &smbios_settings_operations,
150 /** Initialise SMBIOS settings */
151 static void smbios_init ( void ) {
154 if ( ( rc = register_settings ( &smbios_settings, NULL ) ) != 0 ) {
155 DBG ( "SMBIOS could not register settings: %s\n",
161 /** SMBIOS settings initialiser */
162 struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
163 .initialise = smbios_init,
166 /** UUID setting obtained via SMBIOS */
167 struct setting uuid_setting __setting = {
169 .description = "UUID",
170 .tag = SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
171 struct smbios_system_information, uuid ),
172 .type = &setting_type_uuid,
175 /** Other SMBIOS named settings */
176 struct setting smbios_named_settings[] __setting = {
178 .name = "manufacturer",
179 .description = "Manufacturer",
180 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
181 struct smbios_system_information,
183 .type = &setting_type_string,
187 .description = "Product name",
188 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
189 struct smbios_system_information,
191 .type = &setting_type_string,
195 .description = "Serial number",
196 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
197 struct smbios_system_information,
199 .type = &setting_type_string,