aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2010-06-21 09:46:19 -0600
committerKevin O'Connor <kevin@koconnor.net>2010-07-10 13:37:15 -0400
commit17d3e46511aeedc9f09a8216d194d749187b80aa (patch)
treef590acb089b8956debd565ba10e9b99b1ee9f6ea
parent0d6b8d5ff2df9dea30003b03c6af6e6bfb461ce9 (diff)
downloadseabios-hppa-17d3e46511aeedc9f09a8216d194d749187b80aa.zip
seabios-hppa-17d3e46511aeedc9f09a8216d194d749187b80aa.tar.gz
seabios-hppa-17d3e46511aeedc9f09a8216d194d749187b80aa.tar.bz2
smbios: Allow all fields to be set via qemu_cfg_smbios_load_field()
The protocol we use between qemu and seabios already allows any field to be specified (via smbios_add_field() in qemu). This patch makes seabios look for qemu specified values for nearly every field we set in the types 0,1,3,4,16,17,32 smbios tables. No change in current default values for any fields. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-rw-r--r--src/smbios.c222
1 files changed, 141 insertions, 81 deletions
diff --git a/src/smbios.c b/src/smbios.c
index e19a62d..8df0f2d 100644
--- a/src/smbios.c
+++ b/src/smbios.c
@@ -61,7 +61,7 @@ smbios_entry_point_init(u16 max_structure_size,
p->field = ++str_index; \
} while (0)
-#define load_str_field_or_skip(type, field) \
+#define load_str_field_or_skip(type, field) \
do { \
size = qemu_cfg_smbios_load_field(type, \
offsetof(struct smbios_type_##type, \
@@ -74,6 +74,15 @@ smbios_entry_point_init(u16 max_structure_size,
} \
} while (0)
+#define set_field_with_default(type, field, def) \
+ do { \
+ if (!qemu_cfg_smbios_load_field(type, \
+ offsetof(struct smbios_type_##type, \
+ field), &p->field)) { \
+ p->field = def; \
+ } \
+ } while (0)
+
/* Type 0 -- BIOS Information */
#define RELEASE_DATE_STR "01/01/2007"
static void *
@@ -97,24 +106,26 @@ smbios_init_type_0(void *start)
p->bios_rom_size = 0; /* FIXME */
- memset(p->bios_characteristics, 0, 8);
- p->bios_characteristics[0] = 0x08; /* BIOS characteristics not supported */
- p->bios_characteristics_extension_bytes[0] = 0;
- /* Enable targeted content distribution. Needed for SVVP */
- p->bios_characteristics_extension_bytes[1] = 4;
-
if (!qemu_cfg_smbios_load_field(0, offsetof(struct smbios_type_0,
- system_bios_major_release),
- &p->system_bios_major_release))
- p->system_bios_major_release = 1;
+ bios_characteristics),
+ &p->bios_characteristics)) {
+ memset(p->bios_characteristics, 0, 8);
+ /* BIOS characteristics not supported */
+ p->bios_characteristics[0] = 0x08;
+ }
if (!qemu_cfg_smbios_load_field(0, offsetof(struct smbios_type_0,
- system_bios_minor_release),
- &p->system_bios_minor_release))
- p->system_bios_minor_release = 0;
+ bios_characteristics_extension_bytes),
+ &p->bios_characteristics_extension_bytes)) {
+ p->bios_characteristics_extension_bytes[0] = 0;
+ /* Enable targeted content distribution. Needed for SVVP */
+ p->bios_characteristics_extension_bytes[1] = 4;
+ }
- p->embedded_controller_major_release = 0xff;
- p->embedded_controller_minor_release = 0xff;
+ set_field_with_default(0, system_bios_major_release, 1);
+ set_field_with_default(0, system_bios_minor_release, 0);
+ set_field_with_default(0, embedded_controller_major_release, 0xff);
+ set_field_with_default(0, embedded_controller_minor_release, 0xff);
*end = 0;
end++;
@@ -140,12 +151,12 @@ smbios_init_type_1(void *start)
load_str_field_or_skip(1, version_str);
load_str_field_or_skip(1, serial_number_str);
- size = qemu_cfg_smbios_load_field(1, offsetof(struct smbios_type_1,
- uuid), &p->uuid);
- if (size == 0)
+ if (!qemu_cfg_smbios_load_field(1, offsetof(struct smbios_type_1,
+ uuid), &p->uuid)) {
memset(p->uuid, 0, 16);
+ }
- p->wake_up_type = 0x06; /* power switch */
+ set_field_with_default(1, wake_up_type, 0x06); /* power switch */
load_str_field_or_skip(1, sku_number_str);
load_str_field_or_skip(1, family_str);
@@ -165,29 +176,39 @@ static void *
smbios_init_type_3(void *start)
{
struct smbios_type_3 *p = (struct smbios_type_3 *)start;
+ char *end = (char *)start + sizeof(struct smbios_type_3);
+ size_t size;
+ int str_index = 0;
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_number_str = 0;
- p->boot_up_state = 0x03; /* safe */
- p->power_supply_state = 0x03; /* safe */
- p->thermal_state = 0x03; /* safe */
- p->security_status = 0x02; /* unknown */
- p->oem_defined = 0;
- p->height = 0;
- p->number_of_power_cords = 0;
- p->contained_element_count = 0;
-
- start += sizeof(struct smbios_type_3);
- memcpy((char *)start, CONFIG_APPNAME"\0\0", sizeof(CONFIG_APPNAME) + 1);
-
- return start + sizeof(CONFIG_APPNAME) + 1;
+ load_str_field_with_default(3, manufacturer_str, CONFIG_APPNAME);
+ set_field_with_default(3, type, 0x01); /* other */
+
+ load_str_field_or_skip(3, version_str);
+ load_str_field_or_skip(3, serial_number_str);
+ load_str_field_or_skip(3, asset_tag_number_str);
+
+ set_field_with_default(3, boot_up_state, 0x03); /* safe */
+ set_field_with_default(3, power_supply_state, 0x03); /* safe */
+ set_field_with_default(3, thermal_state, 0x03); /* safe */
+ set_field_with_default(3, security_status, 0x02); /* unknown */
+
+ set_field_with_default(3, oem_defined, 0);
+ set_field_with_default(3, height, 0);
+ set_field_with_default(3, number_of_power_cords, 0);
+ set_field_with_default(3, contained_element_count, 0);
+
+ *end = 0;
+ end++;
+ if (!str_index) {
+ *end = 0;
+ end++;
+ }
+
+ return end;
}
/* Type 4 -- Processor Information */
@@ -195,42 +216,63 @@ static void *
smbios_init_type_4(void *start, unsigned int cpu_number)
{
struct smbios_type_4 *p = (struct smbios_type_4 *)start;
+ char *end = (char *)start + sizeof(struct smbios_type_4);
+ size_t size;
+ int str_index = 0;
+ char name[1024];
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->processor_manufacturer_str = 2;
-
- u32 cpuid_signature, ebx, ecx, cpuid_features;
- cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
- p->processor_id[0] = cpuid_signature;
- p->processor_id[1] = cpuid_features;
-
- p->processor_version_str = 0;
- p->voltage = 0;
- p->external_clock = 0;
+ size = qemu_cfg_smbios_load_field(4, offsetof(struct smbios_type_4,
+ socket_designation_str),
+ name);
+ if (size)
+ snprintf(name + size - 1, sizeof(name) - size, "%2x", cpu_number);
+ else
+ snprintf(name, sizeof(name), "CPU%2x", cpu_number);
+
+ memcpy(end, name, strlen(name) + 1);
+ end += strlen(name) + 1;
+ p->socket_designation_str = ++str_index;
+
+ set_field_with_default(4, processor_type, 0x03); /* CPU */
+ set_field_with_default(4, processor_family, 0x01); /* other */
+
+ load_str_field_with_default(4, processor_manufacturer_str, CONFIG_APPNAME);
+
+ if (!qemu_cfg_smbios_load_field(4, offsetof(struct smbios_type_4,
+ processor_id), p->processor_id)) {
+ u32 cpuid_signature, ebx, ecx, cpuid_features;
+ cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
+ p->processor_id[0] = cpuid_signature;
+ p->processor_id[1] = cpuid_features;
+ }
- p->max_speed = 2000;
- p->current_speed = 2000;
+ load_str_field_or_skip(4, processor_version_str);
+ set_field_with_default(4, voltage, 0);
+ set_field_with_default(4, external_clock, 0);
- p->status = 0x41; /* socket populated, CPU enabled */
- p->processor_upgrade = 0x01; /* other */
+ set_field_with_default(4, max_speed, 2000);
+ set_field_with_default(4, current_speed, 2000);
- p->l1_cache_handle = 0xffff; /* cache information structure not provided */
- p->l2_cache_handle = 0xffff;
- p->l3_cache_handle = 0xffff;
+ set_field_with_default(4, status, 0x41); /* socket populated, CPU enabled */
+ set_field_with_default(4, processor_upgrade, 0x01); /* other */
- start += sizeof(struct smbios_type_4);
+ /* cache information structure not provided */
+ p->l1_cache_handle = 0xffff;
+ p->l2_cache_handle = 0xffff;
+ p->l3_cache_handle = 0xffff;
- snprintf((char*)start, 6, "CPU%2x", cpu_number);
- start += 6;
- memcpy((char *)start, CONFIG_APPNAME"\0\0", sizeof(CONFIG_APPNAME) + 1);
+ *end = 0;
+ end++;
+ if (!str_index) {
+ *end = 0;
+ end++;
+ }
- return start + sizeof(CONFIG_APPNAME) + 1;
+ return end;
}
/* Type 16 -- Physical Memory Array */
@@ -243,9 +285,10 @@ smbios_init_type_16(void *start, u32 memory_size_mb, int nr_mem_devs)
p->header.length = sizeof(struct smbios_type_16);
p->header.handle = 0x1000;
- p->location = 0x01; /* other */
- p->use = 0x03; /* system memory */
- p->error_correction = 0x06; /* Multi-bit ECC to make Microsoft happy */
+ set_field_with_default(16, location, 0x01); /* other */
+ set_field_with_default(16, use, 0x03); /* system memory */
+ /* Multi-bit ECC to make Microsoft happy */
+ set_field_with_default(16, error_correction, 0x06);
/* 0x80000000 = unknown, accept sizes < 2TB - TODO multiple arrays */
p->maximum_capacity = memory_size_mb < 2 << 20 ?
memory_size_mb << 10 : 0x80000000;
@@ -263,30 +306,47 @@ static void *
smbios_init_type_17(void *start, u32 size_mb, int instance)
{
struct smbios_type_17 *p = (struct smbios_type_17 *)start;
+ char *end = (char *)start + sizeof(struct smbios_type_17);
+ size_t size;
+ int str_index = 0;
+ char name[1024];
p->header.type = 17;
p->header.length = sizeof(struct smbios_type_17);
p->header.handle = 0x1100 + instance;
p->physical_memory_array_handle = 0x1000;
- p->total_width = 64;
- p->data_width = 64;
+ set_field_with_default(17, total_width, 64);
+ set_field_with_default(17, data_width, 64);
/* TODO: should assert in case something is wrong ASSERT((memory_size_mb & ~0x7fff) == 0); */
p->size = size_mb;
- p->form_factor = 0x09; /* DIMM */
+ set_field_with_default(17, 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);
- memcpy((char *)start, "DIMM 0", 7);
- ((char*)start)[5] += instance;
- start += 7;
- *((u8 *)start) = 0;
-
- return start+1;
+
+ size = qemu_cfg_smbios_load_field(17, offsetof(struct smbios_type_17,
+ device_locator_str),
+ name);
+ if (size)
+ snprintf(name + size - 1, sizeof(name) - size, "%d", instance);
+ else
+ snprintf(name, sizeof(name), "DIMM %d", instance);
+
+ memcpy(end, name, strlen(name) + 1);
+ end += strlen(name) + 1;
+ p->device_locator_str = ++str_index;
+
+ load_str_field_or_skip(17, bank_locator_str);
+ set_field_with_default(17, memory_type, 0x07); /* RAM */
+ set_field_with_default(17, type_detail, 0);
+
+ *end = 0;
+ end++;
+ if (!str_index) {
+ *end = 0;
+ end++;
+ }
+
+ return end;
}
/* Type 19 -- Memory Array Mapped Address */
@@ -345,7 +405,7 @@ smbios_init_type_32(void *start)
p->header.length = sizeof(struct smbios_type_32);
p->header.handle = 0x2000;
memset(p->reserved, 0, 6);
- p->boot_status = 0; /* no errors detected */
+ set_field_with_default(32, boot_status, 0); /* no errors detected */
start += sizeof(struct smbios_type_32);
*((u16 *)start) = 0;