|
|
1.1 root 1: /*
2: * Copyright (C) 2008 Michael Brown <[email protected]>.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17: */
18:
19: FILE_LICENCE ( GPL2_OR_LATER );
20:
21: #include <stdint.h>
22: #include <string.h>
23: #include <errno.h>
24: #include <ipxe/settings.h>
25: #include <ipxe/init.h>
26: #include <ipxe/uuid.h>
27: #include <ipxe/smbios.h>
28:
29: /** SMBIOS settings tag magic number */
30: #define SMBIOS_TAG_MAGIC 0x5B /* "SmBios" */
31:
32: /**
33: * Construct SMBIOS empty tag
34: *
35: * @ret tag SMBIOS setting tag
36: */
37: #define SMBIOS_EMPTY_TAG ( SMBIOS_TAG_MAGIC << 24 )
38:
39: /**
40: * Construct SMBIOS raw-data tag
41: *
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
46: */
47: #define SMBIOS_RAW_TAG( _type, _structure, _field ) \
48: ( ( SMBIOS_TAG_MAGIC << 24 ) | \
49: ( (_type) << 16 ) | \
50: ( offsetof ( _structure, _field ) << 8 ) | \
51: ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
52:
53: /**
54: * Construct SMBIOS string tag
55: *
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
60: */
61: #define SMBIOS_STRING_TAG( _type, _structure, _field ) \
62: ( ( SMBIOS_TAG_MAGIC << 24 ) | \
63: ( (_type) << 16 ) | \
64: ( offsetof ( _structure, _field ) << 8 ) )
65:
66: /**
67: * Check applicability of SMBIOS setting
68: *
69: * @v settings Settings block
70: * @v setting Setting
71: * @ret applies Setting applies within this settings block
72: */
73: static int smbios_applies ( struct settings *settings __unused,
74: struct setting *setting ) {
75: unsigned int tag_magic;
76:
77: /* Check tag magic */
78: tag_magic = ( setting->tag >> 24 );
79: return ( tag_magic == SMBIOS_TAG_MAGIC );
80: }
81:
82: /**
83: * Fetch value of SMBIOS setting
84: *
85: * @v settings Settings block, or NULL to search all blocks
86: * @v setting Setting to fetch
87: * @v data Buffer to fill with setting data
88: * @v len Length of buffer
89: * @ret len Length of setting data, or negative error
90: */
91: static int smbios_fetch ( struct settings *settings __unused,
92: struct setting *setting,
93: void *data, size_t len ) {
94: struct smbios_structure structure;
95: unsigned int tag_magic;
96: unsigned int tag_type;
97: unsigned int tag_offset;
98: unsigned int tag_len;
99: int rc;
100:
101: /* Split tag into type, offset and length */
102: tag_magic = ( setting->tag >> 24 );
103: tag_type = ( ( setting->tag >> 16 ) & 0xff );
104: tag_offset = ( ( setting->tag >> 8 ) & 0xff );
105: tag_len = ( setting->tag & 0xff );
106: assert ( tag_magic == SMBIOS_TAG_MAGIC );
107:
108: /* Find SMBIOS structure */
109: if ( ( rc = find_smbios_structure ( tag_type, &structure ) ) != 0 )
110: return rc;
111:
112: {
113: uint8_t buf[structure.header.len];
114:
115: /* Read SMBIOS structure */
116: if ( ( rc = read_smbios_structure ( &structure, buf,
117: sizeof ( buf ) ) ) != 0 )
118: return rc;
119:
120: if ( tag_len == 0 ) {
121: /* String */
122: return read_smbios_string ( &structure,
123: buf[tag_offset],
124: data, len );
125: } else {
126: /* Raw data */
127: if ( len > tag_len )
128: len = tag_len;
129: memcpy ( data, &buf[tag_offset], len );
130: return tag_len;
131: }
132: }
133: }
134:
135: /** SMBIOS settings operations */
136: static struct settings_operations smbios_settings_operations = {
137: .applies = smbios_applies,
138: .fetch = smbios_fetch,
139: };
140:
141: /** SMBIOS settings */
142: static struct settings smbios_settings = {
143: .refcnt = NULL,
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,
148: };
149:
150: /** Initialise SMBIOS settings */
151: static void smbios_init ( void ) {
152: int rc;
153:
154: if ( ( rc = register_settings ( &smbios_settings, NULL,
155: "smbios" ) ) != 0 ) {
156: DBG ( "SMBIOS could not register settings: %s\n",
157: strerror ( rc ) );
158: return;
159: }
160: }
161:
162: /** SMBIOS settings initialiser */
163: struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
164: .initialise = smbios_init,
165: };
166:
167: /** UUID setting obtained via SMBIOS */
168: struct setting uuid_setting __setting ( SETTING_HOST ) = {
169: .name = "uuid",
170: .description = "UUID",
171: .tag = SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
172: struct smbios_system_information, uuid ),
173: .type = &setting_type_uuid,
174: };
175:
176: /** Other SMBIOS named settings */
177: struct setting smbios_named_settings[] __setting ( SETTING_HOST_EXTRA ) = {
178: {
179: .name = "manufacturer",
180: .description = "Manufacturer",
181: .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
182: struct smbios_system_information,
183: manufacturer ),
184: .type = &setting_type_string,
185: },
186: {
187: .name = "product",
188: .description = "Product name",
189: .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
190: struct smbios_system_information,
191: product ),
192: .type = &setting_type_string,
193: },
194: {
195: .name = "serial",
196: .description = "Serial number",
197: .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
198: struct smbios_system_information,
199: serial ),
200: .type = &setting_type_string,
201: },
202: {
203: .name = "asset",
204: .description = "Asset tag",
205: .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_ENCLOSURE_INFORMATION,
206: struct smbios_enclosure_information,
207: asset_tag ),
208: .type = &setting_type_string,
209: },
210: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.