Ryan Harper wrote: > 5 files changed, 754 insertions(+), 2 deletions(-) > Makefile.target | 4 > hw/pc.c | 47 ++++ > smbios.c | 519 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > smbios_types.h | 182 +++++++++++++++++++ > sysemu.h | 4 > > > # HG changeset patch > # User Ryan Harper <[EMAIL PROTECTED]> > # Date 1197058922 21600 > # Node ID 37bf559ffcf74bfe62ec038c5818e4cf29b817f5 > # Parent 25082b761acbe8b7fa535dedb4a53e02ef74128d > export SMBIOS/DMI tables to PC machines. > > This patch introduces code to generate PC SMBIOS/DMI tables and load them > into machine memory. The resultant machine can use standard tools like > dmidecode to examine the in-memory generated table. > > Signed-off-by: Ryan Harper <[EMAIL PROTECTED]> > > diff -r 25082b761acb -r 37bf559ffcf7 Makefile.target > --- a/Makefile.target Wed Dec 05 03:23:38 2007 +0000 > +++ b/Makefile.target Fri Dec 07 14:22:02 2007 -0600 > @@ -396,7 +396,7 @@ endif > endif > > # must use static linking to avoid leaving stuff in virtual address space > -VL_OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o > +VL_OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o smbios.o >
smbios is x86 specific so you should move this down to one of the ifeq ($(TARGET_BASE_ARCH), i386) guards. > # XXX: suppress QEMU_TOOL tests > VL_OBJS+=block-raw.o > > @@ -535,7 +535,7 @@ ifndef CONFIG_DARWIN > ifndef CONFIG_DARWIN > ifndef CONFIG_WIN32 > ifndef CONFIG_SOLARIS > -VL_LIBS+=-lutil > +VL_LIBS+=-lutil -luuid > endif > endif > endif > diff -r 25082b761acb -r 37bf559ffcf7 hw/pc.c > --- a/hw/pc.c Wed Dec 05 03:23:38 2007 +0000 > +++ b/hw/pc.c Fri Dec 07 14:22:02 2007 -0600 > @@ -44,6 +44,13 @@ > > #define MAX_IDE_BUS 2 > > +/* Hole in BIOS space between 0xF0000 and 0xFFF0 for DMI entry point */ > +#define SMBIOS_ENTRY 0x000fac00 > + > +/* ensure SMBIOS tables have enough room to support MAX_CPUS number of > + * processor entries */ > +#define SMBIOS_EXTRA (5 << 12) > + > static fdctrl_t *floppy_controller; > static RTCState *rtc_state; > static PITState *pit; > @@ -832,6 +839,46 @@ static void pc_init1(int ram_size, int v > } > } > > + { > + ram_addr_t smbios_offset, entrypoint_offset, smbios_base; > + uint32_t smbios_phys; > + int smbios_size > It's better to not have these open segments in the middle of functions. You can either move the variable declarations to the top of the function or split out into a separate function. > + /* phys_ram_base + bios_offset implies 0xe0000 in guest ram */ > + smbios_base = (ram_addr_t)phys_ram_base + bios_offset; > + > + /* take a guess at smbios size */ > + smbios_size = (SMBIOS_EXTRA-1) & ~4095; > + > + /* we only have 32k of space between rombios32 and rombios16 */ > + if (smbios_size > SMBIOS_MAXIMUM_SIZE) { > + fprintf(stderr, "qemu: SMBIOS image size too big (%u), max %u\n", > + smbios_size, SMBIOS_MAXIMUM_SIZE); > + exit(1); > + } > + > + /* smbios is composed of two regions, an entry point table and > + * a second table of all of the data. These regions will live > + * at different phyiscal addresses so we need to reserve space > + * for two locations > + * NB: Entry point is a fixed size (0x1f) > + */ > + > + /* use the hole between end of rombios32 and start of > + * rombios16 @ 0xf0000 */ > + smbios_phys = 0xf0000 - smbios_size; > + smbios_offset = (ram_addr_t)(smbios_phys - 0xe0000); > + entrypoint_offset = (ram_addr_t)(SMBIOS_ENTRY - 0xe0000); > + > + ret = load_smbios_tables((uint8_t *)smbios_base + entrypoint_offset, > + (uint8_t *)smbios_base + smbios_offset, > + smbios_phys); > + if (ret < 0) { > + fprintf(stderr, "qemu: could not generate SMBIOS\n"); > + exit(1); > + } > + } > + > /* map all the bios at the top of memory */ > cpu_register_physical_memory((uint32_t)(-bios_size), > bios_size, bios_offset | IO_MEM_ROM); > diff -r 25082b761acb -r 37bf559ffcf7 smbios.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/smbios.c Fri Dec 07 14:22:02 2007 -0600 > @@ -0,0 +1,519 @@ > +/* > + * smbios.c - Generate SMBIOS tables for Xen HVM domU's. > + * - Adapted for QEMU/KVM > + * > + * 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 > + * (at your option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + * > + * Copyright (C) IBM Corporation, 2006, 2007 > + * > + * Authors: Andrew D. Ball <[EMAIL PROTECTED]> > + * Ryan Harper <[EMAIL PROTECTED]> > + */ > + > +#include <stdio.h> > +#include <stdint.h> > +#include <string.h> > +#include <uuid/uuid.h> > +#include "hw/hw.h" > +#include "sysemu.h" > +#include "smbios_types.h" > +#include "config-host.h" > + > +CPUState *first_cpu; > This should probably be static. Regards, Anthony Liguori > +/* Write a two-character hex representation of 'byte' to digits[]. > + Pre-condition: sizeof(digits) >= 2 */ > +void > +byte_to_hex(char *digits, uint8_t byte) > +{ > + uint8_t nybbel = byte >> 4; > + > + if ( nybbel > 9 ) > + digits[0] = 'a' + nybbel-10; > + else > + digits[0] = '0' + nybbel; > + > + nybbel = byte & 0x0f; > + if ( nybbel > 9 ) > + digits[1] = 'a' + nybbel-10; > + else > + digits[1] = '0' + nybbel; > +} > + > +/* Convert an array of 16 unsigned bytes to a DCE/OSF formatted UUID > + string. > + > + Pre-condition: sizeof(dest) >= 37 */ > +static void > +uuid_to_string(char *dest, uint8_t *uuid) > +{ > + int i = 0; > + char *p = dest; > + > + for ( i = 0; i < 4; i++ ) > + { > + byte_to_hex(p, uuid[i]); > + p += 2; > + } > + *p++ = '-'; > + for ( i = 4; i < 6; i++ ) > + { > + byte_to_hex(p, uuid[i]); > + p += 2; > + } > + *p++ = '-'; > + for ( i = 6; i < 8; i++ ) > + { > + byte_to_hex(p, uuid[i]); > + p += 2; > + } > + *p++ = '-'; > + for ( i = 8; i < 10; i++ ) > + { > + byte_to_hex(p, uuid[i]); > + p += 2; > + } > + *p++ = '-'; > + for ( i = 10; i < 16; i++ ) > + { > + byte_to_hex(p, uuid[i]); > + p += 2; > + } > + *p = '\0'; > +} > + > +static void > +smbios_entry_point_init(void *start, > + uint16_t max_structure_size, > + uint16_t structure_table_length, > + uint32_t structure_table_address, > + uint16_t number_of_structures) > +{ > + uint8_t sum; > + int i; > + struct smbios_entry_point *ep = (struct smbios_entry_point *)start; > + > + strncpy(ep->anchor_string, "_SM_", 4); > + ep->length = 0x1f; > + ep->smbios_major_version = 2; > + ep->smbios_minor_version = 4; > + ep->max_structure_size = max_structure_size; > + ep->entry_point_revision = 0; > + memset(ep->formatted_area, 0, 5); > + strncpy(ep->intermediate_anchor_string, "_DMI_", 5); > + > + ep->structure_table_length = structure_table_length; > + ep->structure_table_address = structure_table_address; > + ep->number_of_structures = number_of_structures; > + ep->smbios_bcd_revision = 0x24; > + > + ep->checksum = 0; > + ep->intermediate_checksum = 0; > + > + sum = 0; > + for ( i = 0; i < 0x10; i++ ) > + sum += ((int8_t *)start)[i]; > + ep->checksum = -sum; > + > + sum = 0; > + for ( i = 0x10; i < ep->length; i++ ) > + sum += ((int8_t *)start)[i]; > + ep->intermediate_checksum = -sum; > +} > + > +/* Type 0 -- BIOS Information */ > +#define RELEASE_DATE_STR "01/01/2007" > +static void * > +smbios_type_0_init(void *start, const char *version, > + uint32_t major_version, uint32_t minor_version) > +{ > + struct smbios_type_0 *p = (struct smbios_type_0 *)start; > + > + p->header.type = 0; > + p->header.length = sizeof(struct smbios_type_0); > + p->header.handle = 0; > + > + p->vendor_str = 1; > + p->version_str = 2; > + p->starting_address_segment = 0xe800; > + p->release_date_str = 3; > + p->rom_size = 0; > + > + memset(p->characteristics, 0, 8); > + p->characteristics[7] = 0x08; /* BIOS characteristics not supported */ > + p->characteristics_extension_bytes[0] = 0; > + p->characteristics_extension_bytes[1] = 0; > + > + p->major_release = (uint8_t) major_version; > + p->minor_release = (uint8_t) minor_version; > + p->embedded_controller_major = 0xff; > + p->embedded_controller_minor = 0xff; > + > + /* copy in vendor string */ > + start += sizeof(struct smbios_type_0); > + strcpy((char *)start, "QEMU"); > + > + /* copy in version string */ > + start += strlen("QEMU") + 1; > + strcpy((char *)start, version); > + > + /* copy in release date string */ > + start += strlen(version) + 1; > + strcpy((char *)start, RELEASE_DATE_STR); > + start += strlen(RELEASE_DATE_STR) +1; > + > + *((uint8_t *)start) = 0; > + return start + 1; > +} > + > +/* Type 1 -- System Information */ > +static void * > +smbios_type_1_init(void *start, const char *version, > + uint8_t uuid[16]) > +{ > + char uuid_str[37]; > + struct smbios_type_1 *p = (struct smbios_type_1 *)start; > + p->header.type = 1; > + p->header.length = sizeof(struct smbios_type_1); > + p->header.handle = 0x100; > + > + p->manufacturer_str = 1; > + p->product_name_str = 2; > + p->version_str = 3; > + p->serial_number_str = 4; > + > + memcpy(p->uuid, uuid, 16); > + > + p->wake_up_type = 0x06; /* power switch */ > + p->sku_str = 0; > + p->family_str = 0; > + > + start += sizeof(struct smbios_type_1); > + > + strcpy((char *)start, "QEMU"); > + start += strlen("QEMU") + 1; > + strcpy((char *)start, "QEMU"); > + start += strlen("QEMU") + 1; > + strcpy((char *)start, version); > + start += strlen(version) + 1; > + uuid_to_string(uuid_str, uuid); > + strcpy((char *)start, uuid_str); > + start += strlen(uuid_str) + 1; > + *((uint8_t *)start) = 0; > + > + return start+1; > +} > + > +/* Type 3 -- System Enclosure */ > +static void * > +smbios_type_3_init(void *start) > +{ > + struct smbios_type_3 *p = (struct smbios_type_3 *)start; > + > + p->header.type = 3; > + p->header.length = sizeof(struct smbios_type_3); > + p->header.handle = 0x300; > + > + p->manufacturer_str = 1; > + p->type = 0x01; /* other */ > + p->version_str = 0; > + p->serial_number_str = 0; > + p->asset_tag_str = 0; > + p->boot_up_state = 0x03; /* safe */ > + p->power_supply_state = 0x03; /* safe */ > + p->thermal_state = 0x03; /* safe */ > + p->security_status = 0x02; /* unknown */ > + > + start += sizeof(struct smbios_type_3); > + > + strcpy((char *)start, "QEMU"); > + start += strlen("QEMU") + 1; > + *((uint8_t *)start) = 0; > + return start+1; > +} > + > +/* Type 4 -- Processor Information */ > +static void * > +smbios_type_4_init(void *start, unsigned int cpu_number, char > *cpu_manufacturer) > +{ > + char buf[80]; > + struct smbios_type_4 *p = (struct smbios_type_4 *)start; > + CPUState *env = first_cpu; > + > + p->header.type = 4; > + p->header.length = sizeof(struct smbios_type_4); > + p->header.handle = 0x400 + cpu_number; > + > + p->socket_designation_str = 1; > + p->processor_type = 0x03; /* CPU */ > + p->processor_family = 0x01; /* other */ > + p->manufacturer_str = 2; > + > + p->cpuid[0] = env->cpuid_version; > + p->cpuid[1] = env->cpuid_features; > + > + p->version_str = 0; > + p->voltage = 0; > + p->external_clock = 0; > + > + p->max_speed = 0; /* unknown */ > + p->current_speed = 0; /* unknown */ > + > + p->status = 0x41; /* socket populated, CPU enabled */ > + p->upgrade = 0x01; /* other */ > + > + start += sizeof(struct smbios_type_4); > + > + /* NB: supports up to 255 cpus */ > + strncpy(buf, "CPU ", sizeof(buf)); > + if ( (sizeof(buf) - strlen("CPU ")) >= 3 ) > + snprintf(buf + strlen("CPU "), 4, "%d", cpu_number); > + > + strcpy((char *)start, buf); > + start += strlen(buf) + 1; > + > + strcpy((char *)start, cpu_manufacturer); > + start += strlen(cpu_manufacturer) + 1; > + > + *((uint8_t *)start) = 0; > + return start+1; > +} > + > +/* Type 16 -- Physical Memory Array */ > +static void * > +smbios_type_16_init(void *start, uint32_t memsize) > +{ > + struct smbios_type_16 *p = (struct smbios_type_16*)start; > + > + p->header.type = 16; > + p->header.handle = 0x1000; > + p->header.length = sizeof(struct smbios_type_16); > + > + p->location = 0x01; /* other */ > + p->use = 0x03; /* system memory */ > + p->error_correction = 0x01; /* other */ > + p->maximum_capacity = memsize * 1024; > + p->memory_error_information_handle = 0xfffe; /* none provided */ > + p->number_of_memory_devices = 1; > + > + start += sizeof(struct smbios_type_16); > + *((uint16_t *)start) = 0; > + return start + 2; > +} > + > +/* Type 17 -- Memory Device */ > +static void * > +smbios_type_17_init(void *start, uint32_t memory_size_mb) > +{ > + struct smbios_type_17 *p = (struct smbios_type_17 *)start; > + > + p->header.type = 17; > + p->header.length = sizeof(struct smbios_type_17); > + p->header.handle = 0x1100; > + > + p->physical_memory_array_handle = 0x1000; > + p->total_width = 64; > + p->data_width = 64; > + /* truncate memory_size_mb to 16 bits and clear most significant > + bit [indicates size in MB] */ > + p->size = (uint16_t) memory_size_mb & 0x7fff; > + p->form_factor = 0x09; /* DIMM */ > + p->device_set = 0; > + p->device_locator_str = 1; > + p->bank_locator_str = 0; > + p->memory_type = 0x07; /* RAM */ > + p->type_detail = 0; > + > + start += sizeof(struct smbios_type_17); > + strcpy((char *)start, "DIMM 1"); > + start += strlen("DIMM 1") + 1; > + *((uint8_t *)start) = 0; > + > + return start+1; > +} > + > +/* Type 19 -- Memory Array Mapped Address */ > +static void * > +smbios_type_19_init(void *start, uint32_t memory_size_mb) > +{ > + struct smbios_type_19 *p = (struct smbios_type_19 *)start; > + > + p->header.type = 19; > + p->header.length = sizeof(struct smbios_type_19); > + p->header.handle = 0x1300; > + > + p->starting_address = 0; > + p->ending_address = (memory_size_mb-1) * 1024; > + p->memory_array_handle = 0x1000; > + p->partition_width = 1; > + > + start += sizeof(struct smbios_type_19); > + *((uint16_t *)start) = 0; > + return start + 2; > +} > + > +/* Type 20 -- Memory Device Mapped Address */ > +static void * > +smbios_type_20_init(void *start, uint32_t memory_size_mb) > +{ > + struct smbios_type_20 *p = (struct smbios_type_20 *)start; > + > + p->header.type = 20; > + p->header.length = sizeof(struct smbios_type_20); > + p->header.handle = 0x1400; > + > + p->starting_address = 0; > + p->ending_address = (memory_size_mb-1) * 1024; > + p->memory_device_handle = 0x1100; > + p->memory_array_mapped_address_handle = 0x1300; > + p->partition_row_position = 1; > + p->interleave_position = 0; > + p->interleaved_data_depth = 0; > + > + start += sizeof(struct smbios_type_20); > + > + *((uint16_t *)start) = 0; > + return start+2; > +} > + > +/* Type 32 -- System Boot Information */ > +static void * > +smbios_type_32_init(void *start) > +{ > + struct smbios_type_32 *p = (struct smbios_type_32 *)start; > + > + p->header.type = 32; > + p->header.length = sizeof(struct smbios_type_32); > + p->header.handle = 0x2000; > + memset(p->reserved, 0, 6); > + p->boot_status = 0; /* no errors detected */ > + > + start += sizeof(struct smbios_type_32); > + *((uint16_t *)start) = 0; > + return start+2; > +} > + > +/* Type 127 -- End of Table */ > +static void * > +smbios_type_127_init(void *start) > +{ > + struct smbios_type_127 *p = (struct smbios_type_127 *)start; > + > + p->header.type = 127; > + p->header.length = sizeof(struct smbios_type_127); > + p->header.handle = 0x7f00; > + > + start += sizeof(struct smbios_type_127); > + *((uint16_t *)start) = 0; > + return start + 2; > +} > + > +static void > +get_cpu_manufacturer(char *buf, int len) > +{ > + char id[12]; > + CPUState *env = first_cpu; > + > + /* load id with cpuid(0) call */ > + memcpy(id, &(env->cpuid_vendor1), 4); > + memcpy(id+4, &(env->cpuid_vendor2), 4); > + memcpy(id+8, &(env->cpuid_vendor3), 4); > + > + if (memcmp(id, "GenuineIntel", 12) == 0) > + strncpy(buf, "Intel", len); > + else if (memcmp(id, "AuthenticAMD", 12) == 0) > + strncpy(buf, "AMD", len); > + else > + strncpy(buf, "unknown", len); > +} > + > +static int > +write_smbios_tables(uint8_t *entry, uint8_t *tables, > + uint32_t table_phys_start, > + uint32_t vcpus, uint64_t memsize, > + uint8_t uuid[16], const char *version, > + uint32_t major_version, uint32_t minor_version) > +{ > + unsigned cpu_num, nr_structs = 0, max_struct_size = 0; > + char *p, *q; > + char cpu_manufacturer[15]; > + > + get_cpu_manufacturer(cpu_manufacturer, 15); > + > + p = tables; > + > +#define do_struct(fn) do { \ > + q = (fn); \ > + nr_structs++; \ > + if ( (q - p) > max_struct_size ) \ > + max_struct_size = q - p; \ > + p = q; \ > +} while (0) > + > + do_struct(smbios_type_0_init(p, version, major_version, > + minor_version)); > + do_struct(smbios_type_1_init(p, version, uuid)); > + do_struct(smbios_type_3_init(p)); > + for ( cpu_num = 1; cpu_num <= vcpus; cpu_num++ ) > + do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer)); > + do_struct(smbios_type_16_init(p, memsize)); > + do_struct(smbios_type_17_init(p, memsize)); > + do_struct(smbios_type_19_init(p, memsize)); > + do_struct(smbios_type_20_init(p, memsize)); > + do_struct(smbios_type_32_init(p)); > + do_struct(smbios_type_127_init(p)); > + > +#undef do_struct > + > + smbios_entry_point_init(entry, max_struct_size, > + (p - (char *)tables), > + table_phys_start, nr_structs); > + > + return ((char *)p - (char *)tables); > +} > + > +/* entry point */ > +int > +load_smbios_tables(uint8_t *entry, uint8_t *table, uint32_t phys_table_start) > +{ > + int len; > + uint32_t major_version = 0; > + uint32_t minor_version = 9; > + uuid_t uuid; > + > + uuid_generate(uuid); > + > + len = write_smbios_tables(entry, table, phys_table_start, > + smp_cpus, (ram_size >> 20), > + uuid, QEMU_VERSION, > + major_version, minor_version); > + > + if (len > SMBIOS_MAXIMUM_SIZE) { > + fprintf(stderr, "SMBIOS: Could not write SMBIOS tables\n"); > + return -1; > + } > + > + return len; > +} > + > +/* > + * Local variables: > + * mode: C > + * c-set-style: "BSD" > + * c-basic-offset: 4 > + * tab-width: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff -r 25082b761acb -r 37bf559ffcf7 smbios_types.h > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/smbios_types.h Fri Dec 07 14:22:02 2007 -0600 > @@ -0,0 +1,182 @@ > +/* > + * smbios_types.h - data structure definitions for Xen HVM SMBIOS support > + * > + * 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 > + * (at your option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + * > + * Copyright (C) IBM Corporation, 2006 > + * > + * Authors: Andrew D. Ball <[EMAIL PROTECTED]> > + * > + * See the SMBIOS 2.4 spec for more detail: > + * http://www.dmtf.org/standards/smbios/ > + */ > + > +#ifndef SMBIOS_TYPES_H > +#define SMBIOS_TYPES_H > + > +#include <stdint.h> > + > +/* SMBIOS entry point -- must be written to a 16-bit aligned address > + between 0xf0000 and 0xfffff. > + */ > +struct smbios_entry_point { > + char anchor_string[4]; > + uint8_t checksum; > + uint8_t length; > + uint8_t smbios_major_version; > + uint8_t smbios_minor_version; > + uint16_t max_structure_size; > + uint8_t entry_point_revision; > + uint8_t formatted_area[5]; > + char intermediate_anchor_string[5]; > + uint8_t intermediate_checksum; > + uint16_t structure_table_length; > + uint32_t structure_table_address; > + uint16_t number_of_structures; > + uint8_t smbios_bcd_revision; > +} __attribute__ ((packed)); > + > +/* This goes at the beginning of every SMBIOS structure. */ > +struct smbios_structure_header { > + uint8_t type; > + uint8_t length; > + uint16_t handle; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 0 - BIOS Information */ > +struct smbios_type_0 { > + struct smbios_structure_header header; > + uint8_t vendor_str; > + uint8_t version_str; > + uint16_t starting_address_segment; > + uint8_t release_date_str; > + uint8_t rom_size; > + uint8_t characteristics[8]; > + uint8_t characteristics_extension_bytes[2]; > + uint8_t major_release; > + uint8_t minor_release; > + uint8_t embedded_controller_major; > + uint8_t embedded_controller_minor; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 1 - System Information */ > +struct smbios_type_1 { > + struct smbios_structure_header header; > + uint8_t manufacturer_str; > + uint8_t product_name_str; > + uint8_t version_str; > + uint8_t serial_number_str; > + uint8_t uuid[16]; > + uint8_t wake_up_type; > + uint8_t sku_str; > + uint8_t family_str; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 3 - System Enclosure */ > +struct smbios_type_3 { > + struct smbios_structure_header header; > + uint8_t manufacturer_str; > + uint8_t type; > + uint8_t version_str; > + uint8_t serial_number_str; > + uint8_t asset_tag_str; > + uint8_t boot_up_state; > + uint8_t power_supply_state; > + uint8_t thermal_state; > + uint8_t security_status; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 4 - Processor Information */ > +struct smbios_type_4 { > + struct smbios_structure_header header; > + uint8_t socket_designation_str; > + uint8_t processor_type; > + uint8_t processor_family; > + uint8_t manufacturer_str; > + uint32_t cpuid[2]; > + uint8_t version_str; > + uint8_t voltage; > + uint16_t external_clock; > + uint16_t max_speed; > + uint16_t current_speed; > + uint8_t status; > + uint8_t upgrade; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 16 - Physical Memory Array > + * Associated with one type 17 (Memory Device). > + */ > +struct smbios_type_16 { > + struct smbios_structure_header header; > + uint8_t location; > + uint8_t use; > + uint8_t error_correction; > + uint32_t maximum_capacity; > + uint16_t memory_error_information_handle; > + uint16_t number_of_memory_devices; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 17 - Memory Device > + * Associated with one type 19 > + */ > +struct smbios_type_17 { > + struct smbios_structure_header header; > + uint16_t physical_memory_array_handle; > + uint16_t memory_error_information_handle; > + uint16_t total_width; > + uint16_t data_width; > + uint16_t size; > + uint8_t form_factor; > + uint8_t device_set; > + uint8_t device_locator_str; > + uint8_t bank_locator_str; > + uint8_t memory_type; > + uint16_t type_detail; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 19 - Memory Array Mapped Address */ > +struct smbios_type_19 { > + struct smbios_structure_header header; > + uint32_t starting_address; > + uint32_t ending_address; > + uint16_t memory_array_handle; > + uint8_t partition_width; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 20 - Memory Device Mapped Address */ > +struct smbios_type_20 { > + struct smbios_structure_header header; > + uint32_t starting_address; > + uint32_t ending_address; > + uint16_t memory_device_handle; > + uint16_t memory_array_mapped_address_handle; > + uint8_t partition_row_position; > + uint8_t interleave_position; > + uint8_t interleaved_data_depth; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 32 - System Boot Information */ > +struct smbios_type_32 { > + struct smbios_structure_header header; > + uint8_t reserved[6]; > + uint8_t boot_status; > +} __attribute__ ((packed)); > + > +/* SMBIOS type 127 -- End-of-table */ > +struct smbios_type_127 { > + struct smbios_structure_header header; > +} __attribute__ ((packed)); > + > +#endif /* SMBIOS_TYPES_H */ > diff -r 25082b761acb -r 37bf559ffcf7 sysemu.h > --- a/sysemu.h Wed Dec 05 03:23:38 2007 +0000 > +++ b/sysemu.h Fri Dec 07 14:22:02 2007 -0600 > @@ -116,6 +116,10 @@ extern unsigned int nb_prom_envs; > #define BIOS_SIZE (4 * 1024 * 1024) > #endif > > +#define SMBIOS_MAXIMUM_SIZE (32 << 10) > +int load_smbios_tables(uint8_t *entry, uint8_t *table, > + uint32_t phys_table_start); > + > typedef enum { > IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD > } BlockInterfaceType; > > ------------------------------------------------------------------------- > SF.Net email is sponsored by: > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > http://sourceforge.net/services/buy/index.php > _______________________________________________ > kvm-devel mailing list > kvm-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/kvm-devel > > ------------------------------------------------------------------------- SF.Net email is sponsored by: Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel