|
|
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.