⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smbios.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * smbios.c - Generate SMBIOS tables for Xen HVM domU's. * * 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 <aball@us.ibm.com> */#include <stdint.h>#include <xen/version.h>#include "smbios_types.h"#include "util.h"#include "hypercall.h"#include "e820.h"static intwrite_smbios_tables(void *start,                    uint32_t vcpus, uint64_t memsize,                    uint8_t uuid[16], char *xen_version,                    uint32_t xen_major_version, uint32_t xen_minor_version);static voidget_cpu_manufacturer(char *buf, int len);static voidsmbios_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);static void *smbios_type_0_init(void *start, const char *xen_version,                   uint32_t xen_major_version, uint32_t xen_minor_version);static void *smbios_type_1_init(void *start, const char *xen_version,                    uint8_t uuid[16]);static void *smbios_type_3_init(void *start);static void *smbios_type_4_init(void *start, unsigned int cpu_number,                   char *cpu_manufacturer);static void *smbios_type_16_init(void *start, uint32_t memory_size_mb);static void *smbios_type_17_init(void *start, uint32_t memory_size_mb);static void *smbios_type_19_init(void *start, uint32_t memory_size_mb);static void *smbios_type_20_init(void *start, uint32_t memory_size_mb);static void *smbios_type_32_init(void *start);static void *smbios_type_127_init(void *start);static voidget_cpu_manufacturer(char *buf, int len){    char id[12];    uint32_t eax = 0;    cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8],          (uint32_t *)&id[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 intwrite_smbios_tables(void *start,                    uint32_t vcpus, uint64_t memsize,                    uint8_t uuid[16], char *xen_version,                    uint32_t xen_major_version, uint32_t xen_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 = (char *)start + sizeof(struct smbios_entry_point);#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, xen_version, xen_major_version,                                 xen_minor_version));    do_struct(smbios_type_1_init(p, xen_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(        start, max_struct_size,        (p - (char *)start) - sizeof(struct smbios_entry_point),        SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),        nr_structs);    return ((char *)p - (char *)start);}/* Calculate how much pseudo-physical memory (in MB) is allocated to us. */static uint64_tget_memsize(void){    struct e820entry *map = HVM_E820;    uint8_t num_entries = *HVM_E820_NR;    uint64_t memsize = 0;    int i;    /*     * Walk through e820map, ignoring any entries that aren't marked     * as usable or reserved.     */    for ( i = 0; i < num_entries; i++ )    {        if ( (map->type == E820_RAM) || (map->type == E820_RESERVED) )            memsize += map->size;        map++;    }    /*     * Round up to the nearest MB.  The user specifies domU pseudo-physical      * memory in megabytes, so not doing this could easily lead to reporting      * one less MB than the user specified.     */    return (memsize + (1 << 20) - 1) >> 20;}inthvm_write_smbios_tables(void){    xen_domain_handle_t uuid;    uint16_t xen_major_version, xen_minor_version;    uint32_t xen_version;    char xen_extra_version[XEN_EXTRAVERSION_LEN];    /* guess conservatively on buffer length for Xen version string */    char xen_version_str[80];    /* temporary variables used to build up Xen version string */    char *p = NULL; /* points to next point of insertion */    unsigned len = 0; /* length of string already composed */    char tmp[16]; /* holds result of itoa() */    unsigned tmp_len; /* length of next string to add */    hypercall_xen_version(XENVER_guest_handle, uuid);    BUILD_BUG_ON(sizeof(xen_domain_handle_t) != 16);    /* xen_version major and minor */    xen_version = hypercall_xen_version(XENVER_version, NULL);    xen_major_version = (uint16_t) (xen_version >> 16);    xen_minor_version = (uint16_t) xen_version;    hypercall_xen_version(XENVER_extraversion, xen_extra_version);    /* build up human-readable Xen version string */    p = xen_version_str;    len = 0;    itoa(tmp, xen_major_version);    tmp_len = strlen(tmp);    len += tmp_len;    if ( len >= sizeof(xen_version_str) )        goto error_out;    strcpy(p, tmp);    p += tmp_len;    len++;    if ( len >= sizeof(xen_version_str) )        goto error_out;    *p = '.';    p++;    itoa(tmp, xen_minor_version);    tmp_len = strlen(tmp);    len += tmp_len;    if ( len >= sizeof(xen_version_str) )        goto error_out;    strcpy(p, tmp);    p += tmp_len;    tmp_len = strlen(xen_extra_version);    len += tmp_len;    if ( len >= sizeof(xen_version_str) )        goto error_out;    strcpy(p, xen_extra_version);    p += tmp_len;    xen_version_str[sizeof(xen_version_str)-1] = '\0';    /* NB. 0xC0000 is a safe large memory area for scratch. */    len = write_smbios_tables((void *)0xC0000,                              get_vcpu_nr(), get_memsize(),                              uuid, xen_version_str,                              xen_major_version, xen_minor_version);    if ( len > SMBIOS_MAXIMUM_SIZE )        goto error_out;    /* Okay, not too large: copy out of scratch to final location. */    memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len);    return len; error_out:    printf("Could not write SMBIOS tables, error in hvmloader.c:"           "hvm_write_smbios_tables()\n");    return 0;}static voidsmbios_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 */static void *smbios_type_0_init(void *start, const char *xen_version,                   uint32_t xen_major_version, uint32_t xen_minor_version){    struct smbios_type_0 *p = (struct smbios_type_0 *)start;    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -