diff options
Diffstat (limited to 'qemu/roms/ipxe/src/interface/smbios')
-rw-r--r-- | qemu/roms/ipxe/src/interface/smbios/smbios.c | 252 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/interface/smbios/smbios_settings.c | 259 |
2 files changed, 0 insertions, 511 deletions
diff --git a/qemu/roms/ipxe/src/interface/smbios/smbios.c b/qemu/roms/ipxe/src/interface/smbios/smbios.c deleted file mode 100644 index 1dcf819c2..000000000 --- a/qemu/roms/ipxe/src/interface/smbios/smbios.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/uaccess.h> -#include <ipxe/smbios.h> - -/** @file - * - * System Management BIOS - * - */ - -/** SMBIOS entry point descriptor */ -static struct smbios smbios = { - .address = UNULL, -}; - -/** - * Scan for SMBIOS entry point structure - * - * @v start Start address of region to scan - * @v len Length of region to scan - * @v entry SMBIOS entry point structure to fill in - * @ret rc Return status code - */ -int find_smbios_entry ( userptr_t start, size_t len, - struct smbios_entry *entry ) { - uint8_t buf[256]; /* 256 is maximum length possible */ - static size_t offset = 0; /* Avoid repeated attempts to locate SMBIOS */ - size_t entry_len; - unsigned int i; - uint8_t sum; - - /* Try to find SMBIOS */ - for ( ; offset < len ; offset += 0x10 ) { - - /* Read start of header and verify signature */ - copy_from_user ( entry, start, offset, sizeof ( *entry ) ); - if ( entry->signature != SMBIOS_SIGNATURE ) - continue; - - /* Read whole header and verify checksum */ - entry_len = entry->len; - assert ( entry_len <= sizeof ( buf ) ); - copy_from_user ( buf, start, offset, entry_len ); - for ( i = 0, sum = 0 ; i < entry_len ; i++ ) { - sum += buf[i]; - } - if ( sum != 0 ) { - DBG ( "SMBIOS at %08lx has bad checksum %02x\n", - user_to_phys ( start, offset ), sum ); - continue; - } - - /* Fill result structure */ - DBG ( "Found SMBIOS v%d.%d entry point at %08lx\n", - entry->major, entry->minor, - user_to_phys ( start, offset ) ); - return 0; - } - - DBG ( "No SMBIOS found\n" ); - return -ENODEV; -} - -/** - * Find SMBIOS strings terminator - * - * @v offset Offset to start of strings - * @ret offset Offset to strings terminator, or 0 if not found - */ -static size_t find_strings_terminator ( size_t offset ) { - size_t max_offset = ( smbios.len - 2 ); - uint16_t nulnul; - - for ( ; offset <= max_offset ; offset++ ) { - copy_from_user ( &nulnul, smbios.address, offset, 2 ); - if ( nulnul == 0 ) - return ( offset + 1 ); - } - return 0; -} - -/** - * Find specific structure type within SMBIOS - * - * @v type Structure type to search for - * @v instance Instance of this type of structure - * @v structure SMBIOS structure descriptor to fill in - * @ret rc Return status code - */ -int find_smbios_structure ( unsigned int type, unsigned int instance, - struct smbios_structure *structure ) { - unsigned int count = 0; - size_t offset = 0; - size_t strings_offset; - size_t terminator_offset; - int rc; - - /* Find SMBIOS */ - if ( ( smbios.address == UNULL ) && - ( ( rc = find_smbios ( &smbios ) ) != 0 ) ) - return rc; - assert ( smbios.address != UNULL ); - - /* Scan through list of structures */ - while ( ( ( offset + sizeof ( structure->header ) ) < smbios.len ) - && ( count < smbios.count ) ) { - - /* Read next SMBIOS structure header */ - copy_from_user ( &structure->header, smbios.address, offset, - sizeof ( structure->header ) ); - - /* Determine start and extent of strings block */ - strings_offset = ( offset + structure->header.len ); - if ( strings_offset > smbios.len ) { - DBG ( "SMBIOS structure at offset %zx with length " - "%x extends beyond SMBIOS\n", offset, - structure->header.len ); - return -ENOENT; - } - terminator_offset = find_strings_terminator ( strings_offset ); - if ( ! terminator_offset ) { - DBG ( "SMBIOS structure at offset %zx has " - "unterminated strings section\n", offset ); - return -ENOENT; - } - structure->strings_len = ( terminator_offset - strings_offset); - - DBG ( "SMBIOS structure at offset %zx has type %d, length %x, " - "strings length %zx\n", offset, structure->header.type, - structure->header.len, structure->strings_len ); - - /* If this is the structure we want, return */ - if ( ( structure->header.type == type ) && - ( instance-- == 0 ) ) { - structure->offset = offset; - return 0; - } - - /* Move to next SMBIOS structure */ - offset = ( terminator_offset + 1 ); - count++; - } - - DBG ( "SMBIOS structure type %d not found\n", type ); - return -ENOENT; -} - -/** - * Copy SMBIOS structure - * - * @v structure SMBIOS structure descriptor - * @v data Buffer to hold SMBIOS structure - * @v len Length of buffer - * @ret rc Return status code - */ -int read_smbios_structure ( struct smbios_structure *structure, - void *data, size_t len ) { - - assert ( smbios.address != UNULL ); - - if ( len > structure->header.len ) - len = structure->header.len; - copy_from_user ( data, smbios.address, structure->offset, len ); - return 0; -} - -/** - * Find indexed string within SMBIOS structure - * - * @v structure SMBIOS structure descriptor - * @v index String index - * @v data Buffer for string - * @v len Length of string buffer - * @ret rc Length of string, or negative error - */ -int read_smbios_string ( struct smbios_structure *structure, - unsigned int index, void *data, size_t len ) { - size_t strings_start = ( structure->offset + structure->header.len ); - size_t strings_end = ( strings_start + structure->strings_len ); - size_t offset; - size_t string_len; - - assert ( smbios.address != UNULL ); - - /* String numbers start at 1 (0 is used to indicate "no string") */ - if ( ! index ) - return -ENOENT; - - for ( offset = strings_start ; offset < strings_end ; - offset += ( string_len + 1 ) ) { - /* Get string length. This is known safe, since the - * smbios_strings struct is constructed so as to - * always end on a string boundary. - */ - string_len = strlen_user ( smbios.address, offset ); - if ( --index == 0 ) { - /* Copy string, truncating as necessary. */ - if ( len > string_len ) - len = string_len; - copy_from_user ( data, smbios.address, offset, len ); - return string_len; - } - } - - DBG ( "SMBIOS string index %d not found\n", index ); - return -ENOENT; -} - -/** - * Get SMBIOS version - * - * @ret version Version, or negative error - */ -int smbios_version ( void ) { - int rc; - - /* Find SMBIOS */ - if ( ( smbios.address == UNULL ) && - ( ( rc = find_smbios ( &smbios ) ) != 0 ) ) - return rc; - assert ( smbios.address != UNULL ); - - return smbios.version; -} diff --git a/qemu/roms/ipxe/src/interface/smbios/smbios_settings.c b/qemu/roms/ipxe/src/interface/smbios/smbios_settings.c deleted file mode 100644 index 5eadfa081..000000000 --- a/qemu/roms/ipxe/src/interface/smbios/smbios_settings.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <string.h> -#include <errno.h> -#include <ipxe/settings.h> -#include <ipxe/init.h> -#include <ipxe/uuid.h> -#include <ipxe/smbios.h> - -/** SMBIOS settings scope */ -static const struct settings_scope smbios_settings_scope; - -/** - * Construct SMBIOS raw-data tag - * - * @v _type SMBIOS structure type number - * @v _structure SMBIOS structure data type - * @v _field Field within SMBIOS structure data type - * @ret tag SMBIOS setting tag - */ -#define SMBIOS_RAW_TAG( _type, _structure, _field ) \ - ( ( (_type) << 16 ) | \ - ( offsetof ( _structure, _field ) << 8 ) | \ - ( sizeof ( ( ( _structure * ) 0 )->_field ) ) ) - -/** - * Construct SMBIOS string tag - * - * @v _type SMBIOS structure type number - * @v _structure SMBIOS structure data type - * @v _field Field within SMBIOS structure data type - * @ret tag SMBIOS setting tag - */ -#define SMBIOS_STRING_TAG( _type, _structure, _field ) \ - ( ( (_type) << 16 ) | \ - ( offsetof ( _structure, _field ) << 8 ) ) - -/** - * Check applicability of SMBIOS setting - * - * @v settings Settings block - * @v setting Setting - * @ret applies Setting applies within this settings block - */ -static int smbios_applies ( struct settings *settings __unused, - const struct setting *setting ) { - - return ( setting->scope == &smbios_settings_scope ); -} - -/** - * Fetch value of SMBIOS setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int smbios_fetch ( struct settings *settings __unused, - struct setting *setting, - void *data, size_t len ) { - struct smbios_structure structure; - unsigned int tag_instance; - unsigned int tag_type; - unsigned int tag_offset; - unsigned int tag_len; - int rc; - - /* Split tag into instance, type, offset and length */ - tag_instance = ( ( setting->tag >> 24 ) & 0xff ); - tag_type = ( ( setting->tag >> 16 ) & 0xff ); - tag_offset = ( ( setting->tag >> 8 ) & 0xff ); - tag_len = ( setting->tag & 0xff ); - - /* Find SMBIOS structure */ - if ( ( rc = find_smbios_structure ( tag_type, tag_instance, - &structure ) ) != 0 ) - return rc; - - { - uint8_t buf[structure.header.len]; - const void *raw; - union uuid uuid; - unsigned int index; - - /* Read SMBIOS structure */ - if ( ( rc = read_smbios_structure ( &structure, buf, - sizeof ( buf ) ) ) != 0 ) - return rc; - - /* A <length> of zero indicates that the byte at - * <offset> contains a string index. An <offset> of - * zero indicates that the <length> contains a literal - * string index. - */ - if ( ( tag_len == 0 ) || ( tag_offset == 0 ) ) { - index = ( ( tag_offset == 0 ) ? - tag_len : buf[tag_offset] ); - if ( ( rc = read_smbios_string ( &structure, index, - data, len ) ) < 0 ) { - return rc; - } - if ( ! setting->type ) - setting->type = &setting_type_string; - return rc; - } - - /* Mangle UUIDs if necessary. iPXE treats UUIDs as - * being in network byte order (big-endian). SMBIOS - * specification version 2.6 states that UUIDs are - * stored with little-endian values in the first three - * fields; earlier versions did not specify an - * endianness. dmidecode assumes that the byte order - * is little-endian if and only if the SMBIOS version - * is 2.6 or higher; we match this behaviour. - */ - raw = &buf[tag_offset]; - if ( ( setting->type == &setting_type_uuid ) && - ( tag_len == sizeof ( uuid ) ) && - ( smbios_version() >= SMBIOS_VERSION ( 2, 6 ) ) ) { - DBG ( "SMBIOS detected mangled UUID\n" ); - memcpy ( &uuid, &buf[tag_offset], sizeof ( uuid ) ); - uuid_mangle ( &uuid ); - raw = &uuid; - } - - /* Return data */ - if ( len > tag_len ) - len = tag_len; - memcpy ( data, raw, len ); - if ( ! setting->type ) - setting->type = &setting_type_hex; - return tag_len; - } -} - -/** SMBIOS settings operations */ -static struct settings_operations smbios_settings_operations = { - .applies = smbios_applies, - .fetch = smbios_fetch, -}; - -/** SMBIOS settings */ -static struct settings smbios_settings = { - .refcnt = NULL, - .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ), - .children = LIST_HEAD_INIT ( smbios_settings.children ), - .op = &smbios_settings_operations, - .default_scope = &smbios_settings_scope, -}; - -/** Initialise SMBIOS settings */ -static void smbios_init ( void ) { - int rc; - - if ( ( rc = register_settings ( &smbios_settings, NULL, - "smbios" ) ) != 0 ) { - DBG ( "SMBIOS could not register settings: %s\n", - strerror ( rc ) ); - return; - } -} - -/** SMBIOS settings initialiser */ -struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = smbios_init, -}; - -/** UUID setting obtained via SMBIOS */ -const struct setting uuid_setting __setting ( SETTING_HOST, uuid ) = { - .name = "uuid", - .description = "UUID", - .tag = SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION, - struct smbios_system_information, uuid ), - .type = &setting_type_uuid, - .scope = &smbios_settings_scope, -}; - -/** Manufacturer name setting */ -const struct setting manufacturer_setting __setting ( SETTING_HOST_EXTRA, - manufacturer ) = { - .name = "manufacturer", - .description = "Manufacturer", - .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION, - struct smbios_system_information, - manufacturer ), - .type = &setting_type_string, - .scope = &smbios_settings_scope, -}; - -/** Product name setting */ -const struct setting product_setting __setting ( SETTING_HOST_EXTRA, product )={ - .name = "product", - .description = "Product name", - .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION, - struct smbios_system_information, - product ), - .type = &setting_type_string, - .scope = &smbios_settings_scope, -}; - -/** Serial number setting */ -const struct setting serial_setting __setting ( SETTING_HOST_EXTRA, serial ) = { - .name = "serial", - .description = "Serial number", - .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION, - struct smbios_system_information, - serial ), - .type = &setting_type_string, - .scope = &smbios_settings_scope, -}; - -/** Asset tag setting */ -const struct setting asset_setting __setting ( SETTING_HOST_EXTRA, asset ) = { - .name = "asset", - .description = "Asset tag", - .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_ENCLOSURE_INFORMATION, - struct smbios_enclosure_information, - asset_tag ), - .type = &setting_type_string, - .scope = &smbios_settings_scope, -}; - -/** Board serial number setting (may differ from chassis serial number) */ -const struct setting board_serial_setting __setting ( SETTING_HOST_EXTRA, - board_serial ) = { - .name = "board-serial", - .description = "Base board serial", - .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_BASE_BOARD_INFORMATION, - struct smbios_base_board_information, - serial ), - .type = &setting_type_string, - .scope = &smbios_settings_scope, -}; |