00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <stdint.h>
00022 #include <string.h>
00023 #include <errno.h>
00024 #include <gpxe/settings.h>
00025 #include <gpxe/init.h>
00026 #include <gpxe/uuid.h>
00027 #include <gpxe/smbios.h>
00028
00029
00030 #define SMBIOS_TAG_MAGIC 0x5B
00031
00032
00033
00034
00035
00036
00037 #define SMBIOS_EMPTY_TAG ( SMBIOS_TAG_MAGIC << 24 )
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #define SMBIOS_RAW_TAG( _type, _structure, _field ) \
00048 ( ( SMBIOS_TAG_MAGIC << 24 ) | \
00049 ( (_type) << 16 ) | \
00050 ( offsetof ( _structure, _field ) << 8 ) | \
00051 ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #define SMBIOS_STRING_TAG( _type, _structure, _field ) \
00062 ( ( SMBIOS_TAG_MAGIC << 24 ) | \
00063 ( (_type) << 16 ) | \
00064 ( offsetof ( _structure, _field ) << 8 ) )
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 static int smbios_fetch ( struct settings *settings __unused,
00076 struct setting *setting,
00077 void *data, size_t len ) {
00078 struct smbios_structure structure;
00079 unsigned int tag_magic;
00080 unsigned int tag_type;
00081 unsigned int tag_offset;
00082 unsigned int tag_len;
00083 int rc;
00084
00085
00086 tag_magic = ( setting->tag >> 24 );
00087 tag_type = ( ( setting->tag >> 16 ) & 0xff );
00088 tag_offset = ( ( setting->tag >> 8 ) & 0xff );
00089 tag_len = ( setting->tag & 0xff );
00090 if ( tag_magic != SMBIOS_TAG_MAGIC )
00091 return -ENOENT;
00092
00093
00094 if ( ( rc = find_smbios_structure ( tag_type, &structure ) ) != 0 )
00095 return rc;
00096
00097 {
00098 uint8_t buf[structure.header.len];
00099
00100
00101 if ( ( rc = read_smbios_structure ( &structure, buf,
00102 sizeof ( buf ) ) ) != 0 )
00103 return rc;
00104
00105 if ( tag_len == 0 ) {
00106
00107 return read_smbios_string ( &structure,
00108 buf[tag_offset],
00109 data, len );
00110 } else {
00111
00112 if ( len > tag_len )
00113 len = tag_len;
00114 memcpy ( data, &buf[tag_offset], len );
00115 return tag_len;
00116 }
00117 }
00118 }
00119
00120
00121 static struct settings_operations smbios_settings_operations = {
00122 .fetch = smbios_fetch,
00123 };
00124
00125
00126 static struct settings smbios_settings = {
00127 .refcnt = NULL,
00128 .name = "smbios",
00129 .tag_magic = SMBIOS_EMPTY_TAG,
00130 .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
00131 .children = LIST_HEAD_INIT ( smbios_settings.children ),
00132 .op = &smbios_settings_operations,
00133 };
00134
00135
00136 static void smbios_init ( void ) {
00137 int rc;
00138
00139 if ( ( rc = register_settings ( &smbios_settings, NULL ) ) != 0 ) {
00140 DBG ( "SMBIOS could not register settings: %s\n",
00141 strerror ( rc ) );
00142 return;
00143 }
00144 }
00145
00146
00147 struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
00148 .initialise = smbios_init,
00149 };
00150
00151
00152 struct setting uuid_setting __setting = {
00153 .name = "uuid",
00154 .description = "UUID",
00155 .tag = SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
00156 struct smbios_system_information, uuid ),
00157 .type = &setting_type_uuid,
00158 };
00159
00160
00161 struct setting smbios_named_settings[] __setting = {
00162 {
00163 .name = "manufacturer",
00164 .description = "Manufacturer",
00165 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
00166 struct smbios_system_information,
00167 manufacturer ),
00168 .type = &setting_type_string,
00169 },
00170 {
00171 .name = "product",
00172 .description = "Product name",
00173 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
00174 struct smbios_system_information,
00175 product ),
00176 .type = &setting_type_string,
00177 },
00178 {
00179 .name = "serial",
00180 .description = "Serial number",
00181 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
00182 struct smbios_system_information,
00183 serial ),
00184 .type = &setting_type_string,
00185 },
00186 {
00187 .name = "asset",
00188 .description = "Asset tag",
00189 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_ENCLOSURE_INFORMATION,
00190 struct smbios_enclosure_information,
00191 asset_tag ),
00192 .type = &setting_type_string,
00193 },
00194 };