diff options
Diffstat (limited to 'tools/firmware/hvmloader/smbios.c')
-rw-r--r-- | tools/firmware/hvmloader/smbios.c | 818 |
1 files changed, 393 insertions, 425 deletions
diff --git a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.c index 57618b2098..df25999c3a 100644 --- a/tools/firmware/hvmloader/smbios.c +++ b/tools/firmware/hvmloader/smbios.c @@ -28,39 +28,31 @@ #include "util.h" #include "hypercall.h" -/* write SMBIOS tables starting at 'start', without writing more - than 'max_size' bytes. - - Return the number of bytes written -*/ static size_t -write_smbios_tables(void *start, size_t max_size, - uint32_t vcpus, uint64_t memsize, - uint8_t uuid[16], char *xen_version, - uint32_t xen_major_version, uint32_t xen_minor_version); +write_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 void get_cpu_manufacturer(char *buf, int len); -static size_t -smbios_table_size(uint32_t vcpus, const char *xen_version, - const char *processor_manufacturer); -static void * +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); + 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); + 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]); + 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); + char *cpu_manufacturer); static void * smbios_type_16_init(void *start, uint32_t memory_size_mb); static void * @@ -71,109 +63,70 @@ static void * smbios_type_20_init(void *start, uint32_t memory_size_mb); static void * smbios_type_32_init(void *start); -void * +static void * smbios_type_127_init(void *start); static void get_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); -} - - -/* Calculate the size of the SMBIOS structure table. -*/ -static size_t -smbios_table_size(uint32_t vcpus, const char *xen_version, - const char *processor_manufacturer) -{ - size_t size; - - /* first compute size without strings or terminating 0 bytes */ - size = sizeof(struct smbios_type_0) + sizeof(struct smbios_type_1) + - sizeof(struct smbios_type_3) + sizeof(struct smbios_type_4)*vcpus + - sizeof(struct smbios_type_16) + sizeof(struct smbios_type_17) + - sizeof(struct smbios_type_19) + sizeof(struct smbios_type_20) + - sizeof(struct smbios_type_32) + sizeof(struct smbios_type_127); - - /* 5 structures with no strings, 2 null bytes each */ - size += 10; - - /* Need to include 1 null byte per structure with strings (first - terminating null byte comes from the string terminator of the - last string). */ - size += 4 + vcpus; - - /* type 0: "Xen", xen_version, and release_date */ - size += strlen("Xen") + strlen(xen_version) + 2; - /* type 1: "Xen", xen_version, "HVM domU", UUID as string for - serial number */ - size += strlen("Xen") + strlen("HVM domU") + strlen(xen_version) + - 36 + 4; - /* type 3: "Xen" */ - size += strlen("Xen") + 1; - /* type 4: socket designation ("CPU n"), processor_manufacturer */ - size += vcpus * (strlen("CPU n") + strlen(processor_manufacturer) + 2); - /* Make room for two-digit CPU numbers if necessary -- doesn't handle - vcpus > 99 */ - if (vcpus > 9) - size += vcpus - 9; - /* type 17: device locator string ("DIMM 1") */ - size += strlen("DIMM 1") + 1; - - return size; + 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 size_t -write_smbios_tables(void *start, size_t max_size, - uint32_t vcpus, uint64_t memsize, - uint8_t uuid[16], char *xen_version, - uint32_t xen_major_version, uint32_t xen_minor_version) +write_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; - void *p = start; - char cpu_manufacturer[15]; - size_t structure_table_length; - - get_cpu_manufacturer(cpu_manufacturer, 15); - - - structure_table_length = smbios_table_size(vcpus, xen_version, - cpu_manufacturer); - - if (structure_table_length + sizeof(struct smbios_entry_point) > max_size) - return 0; - - p = smbios_entry_point_init(p, sizeof(struct smbios_type_4), - structure_table_length, - (uint32_t)start + - sizeof(struct smbios_entry_point), - 9 + vcpus); - - p = smbios_type_0_init(p, xen_version, xen_major_version, - xen_minor_version); - p = smbios_type_1_init(p, xen_version, uuid); - p = smbios_type_3_init(p); - for (cpu_num = 1; cpu_num <= vcpus; ++cpu_num) - p = smbios_type_4_init(p, cpu_num, cpu_manufacturer); - p = smbios_type_16_init(p, memsize); - p = smbios_type_17_init(p, memsize); - p = smbios_type_19_init(p, memsize); - p = smbios_type_20_init(p, memsize); - p = smbios_type_32_init(p); - p = smbios_type_127_init(p); - - return (size_t)((char*)p - (char*)start); + 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 (size_t)((char *)p - (char *)start); } /* This tries to figure out how much pseudo-physical memory (in MB) @@ -189,424 +142,439 @@ write_smbios_tables(void *start, size_t max_size, static uint64_t get_memsize(void) { - struct e820entry *map = NULL; - uint8_t num_entries = 0; - uint64_t memsize = 0; - uint8_t i; - - map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET); - num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET)); - - /* 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. */ - if (memsize & ((1<<20)-1)) - memsize = (memsize >> 20) + 1; - else - memsize = (memsize >> 20); - - return memsize; + struct e820entry *map = NULL; + uint8_t num_entries = 0; + uint64_t memsize = 0; + uint8_t i; + + map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET); + num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET)); + + /* 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. */ + if ( memsize & ((1<<20)-1) ) + memsize = (memsize >> 20) + 1; + else + memsize = (memsize >> 20); + + return memsize; } void hvm_write_smbios_tables(void) { - uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is - not uint8_t[16]. ** */ - 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 = NULL; /* holds result of itoa() */ - unsigned tmp_len; /* length of next string to add */ - - hypercall_xen_version(XENVER_guest_handle, uuid); - - /* 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'; - - write_smbios_tables((void *) SMBIOS_PHYSICAL_ADDRESS, - SMBIOS_SIZE_LIMIT, get_vcpu_nr(), get_memsize(), - uuid, xen_version_str, - xen_major_version, xen_minor_version); - return; + uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is + not uint8_t[16]. ** */ + 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 = NULL; /* holds result of itoa() */ + unsigned tmp_len; /* length of next string to add */ + + hypercall_xen_version(XENVER_guest_handle, uuid); + + /* 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_SIZE_LIMIT ) + goto error_out; + /* Okay, not too large: copy out of scratch to final location. */ + memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len); + + return; error_out: - puts("Could not write SMBIOS tables, error in hvmloader.c:" - "hvm_write_smbios_tables()\n"); + printf("Could not write SMBIOS tables, error in hvmloader.c:" + "hvm_write_smbios_tables()\n"); } -static void * +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) + 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); + 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->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; + 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; - - return (char *)start + sizeof(struct smbios_entry_point); + 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) + uint32_t xen_major_version, uint32_t xen_minor_version) { - struct smbios_type_0 *p = (struct smbios_type_0 *)start; + 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->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 = 0; - p->rom_size = 0; + p->vendor_str = 1; + p->version_str = 2; + p->starting_address_segment = 0xe800; + p->release_date_str = 0; + 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; + 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) xen_major_version; - p->minor_release = (uint8_t) xen_minor_version; - p->embedded_controller_major = 0xff; - p->embedded_controller_minor = 0xff; - - start += sizeof(struct smbios_type_0); - strcpy((char *)start, "Xen"); - start += strlen("Xen") + 1; - strcpy((char *)start, xen_version); - start += strlen(xen_version) + 1; - - *((uint8_t *)start) = 0; - return start + 1; + p->major_release = (uint8_t) xen_major_version; + p->minor_release = (uint8_t) xen_minor_version; + p->embedded_controller_major = 0xff; + p->embedded_controller_minor = 0xff; + + start += sizeof(struct smbios_type_0); + strcpy((char *)start, "Xen"); + start += strlen("Xen") + 1; + strcpy((char *)start, xen_version); + start += strlen(xen_version) + 1; + + *((uint8_t *)start) = 0; + return start + 1; } /* Type 1 -- System Information */ static void * smbios_type_1_init(void *start, const char *xen_version, - uint8_t uuid[16]) + 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; + 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); + memcpy(p->uuid, uuid, 16); - p->wake_up_type = 0x06; /* power switch */ - p->sku_str = 0; - p->family_str = 0; + p->wake_up_type = 0x06; /* power switch */ + p->sku_str = 0; + p->family_str = 0; - start += sizeof(struct smbios_type_1); + start += sizeof(struct smbios_type_1); - strcpy((char *)start, "Xen"); - start += strlen("Xen") + 1; - strcpy((char *)start, "HVM domU"); - start += strlen("HVM domU") + 1; - strcpy((char *)start, xen_version); - start += strlen(xen_version) + 1; - uuid_to_string(uuid_str, uuid); - strcpy((char *)start, uuid_str); - start += strlen(uuid_str) + 1; - *((uint8_t *)start) = 0; + strcpy((char *)start, "Xen"); + start += strlen("Xen") + 1; + strcpy((char *)start, "HVM domU"); + start += strlen("HVM domU") + 1; + strcpy((char *)start, xen_version); + start += strlen(xen_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; + 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; + 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); + 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, "Xen"); - start += strlen("Xen") + 1; - *((uint8_t *)start) = 0; - return start+1; + strcpy((char *)start, "Xen"); + start += strlen("Xen") + 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; - uint32_t eax, ebx, ecx, edx; + char buf[80]; + struct smbios_type_4 *p = (struct smbios_type_4 *)start; + uint32_t eax, ebx, ecx, edx; - p->header.type = 4; - p->header.length = sizeof(struct smbios_type_4); - p->header.handle = 0x400 + cpu_number; + 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->socket_designation_str = 1; + p->processor_type = 0x03; /* CPU */ + p->processor_family = 0x01; /* other */ + p->manufacturer_str = 2; - cpuid(1, &eax, &ebx, &ecx, &edx); + cpuid(1, &eax, &ebx, &ecx, &edx); - p->cpuid[0] = eax; - p->cpuid[1] = edx; + p->cpuid[0] = eax; + p->cpuid[1] = edx; - p->version_str = 0; - p->voltage = 0; - p->external_clock = 0; + p->version_str = 0; + p->voltage = 0; + p->external_clock = 0; - p->max_speed = 0; /* unknown */ - p->current_speed = 0; /* unknown */ + p->max_speed = 0; /* unknown */ + p->current_speed = 0; /* unknown */ - p->status = 0x41; /* socket populated, CPU enabled */ - p->upgrade = 0x01; /* other */ + p->status = 0x41; /* socket populated, CPU enabled */ + p->upgrade = 0x01; /* other */ - start += sizeof(struct smbios_type_4); + start += sizeof(struct smbios_type_4); - strncpy(buf, "CPU ", sizeof(buf)); - if ((sizeof(buf) - strlen("CPU ")) >= 3) - itoa(buf + strlen("CPU "), cpu_number); + strncpy(buf, "CPU ", sizeof(buf)); + if ( (sizeof(buf) - strlen("CPU ")) >= 3 ) + itoa(buf + strlen("CPU "), cpu_number); - strcpy((char *)start, buf); - start += strlen(buf) + 1; + strcpy((char *)start, buf); + start += strlen(buf) + 1; - strcpy((char *)start, cpu_manufacturer); - start += strlen(buf) + 1; + strcpy((char *)start, cpu_manufacturer); + start += strlen(cpu_manufacturer) + 1; - *((uint8_t *)start) = 0; - return start+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; + 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->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; + 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; + 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; + 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; + 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; + 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; + 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->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; + 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); + start += sizeof(struct smbios_type_20); - *((uint16_t *)start) = 0; - return start+2; + *((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; + 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 */ + 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; + start += sizeof(struct smbios_type_32); + *((uint16_t *)start) = 0; + return start+2; } /* Type 127 -- End of Table */ -void * +static void * smbios_type_127_init(void *start) { - struct smbios_type_127 *p = (struct smbios_type_127 *)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; + 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; + start += sizeof(struct smbios_type_127); + *((uint16_t *)start) = 0; + return start + 2; } + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ |