pc,pci,virtio,qdev fixes, tests
new tests for SMBIOS SMBIOS fixes pc, pci fixes qdev patches stayed on list for a month with no review, as I told people on KVM forum I'm merging stuch patches if they look fine. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJTkJ2iAAoJECgfDbjSjVRpk4oIALf6RC/Bm3bVaX5TSgqdt8UT 4vCf10V53KkbfhxN9dGyPluswz/gyY7M/nrOoi0BSbrQndSavgyNRCfMfBfIw1FO yvfeyrkBkKBP4ViF6uogcSr79h3vQaXsqZIGmZUsdv3ZfVrLS+7dKsigVI6PumNR 8YBveGljFjn0nrCC2+M2+LDefcPGSEu9vea9hKER0uPuz1mib8otjm1PAH30QeW/ 9q1bwFEwobFJk32vrayQrwGk5ECXCCHR8LPV1Rv9tyZLEqAbdiNrwGb4MycztLvK UHuvNFNqUHKNe/tqvp1RPmWOY2aO8+u0570kc8nhXXq2/tjJTOCmQfmodE6hh8A= =bwmA -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging pc,pci,virtio,qdev fixes, tests new tests for SMBIOS SMBIOS fixes pc, pci fixes qdev patches stayed on list for a month with no review, as I told people on KVM forum I'm merging stuch patches if they look fine. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> * remotes/mst/tags/for_upstream: qdev: Add test of qdev_prop_check_global qdev: Display warning about unused -global tests: add smbios testing tests: rename acpi-test to bios-tables-test virtio-balloon: return empty data when no stats are available pcie_host: Turn pcie_host_init() into an instance_init SMBIOS: Fix type 17 field sizes SMBIOS: Update Type 0 struct generator for machines >= 2.1 SMBIOS: Fix endian-ness when populating multi-byte fields serial-pci: Set prog interface field of pci config to 16550 compatible Conflicts: include/hw/i386/pc.h [PMM: fixed trivial conflict in pc.h] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
26edf8cc08
@ -35,7 +35,8 @@ which will return a dictionary containing:
|
||||
|
||||
o A key named last-update, which contains the last stats update
|
||||
timestamp in seconds. Since this timestamp is generated by the host,
|
||||
a buggy guest can't influence its value
|
||||
a buggy guest can't influence its value. The value is 0 if the guest
|
||||
has not updated the stats (yet).
|
||||
|
||||
It's also important to note the following:
|
||||
|
||||
@ -49,7 +50,7 @@ It's also important to note the following:
|
||||
|
||||
- Polling can be enabled even if the guest doesn't have stats support
|
||||
or the balloon driver wasn't loaded in the guest. If this is the case
|
||||
and stats are queried, an error will be returned
|
||||
and stats are queried, last-update will be 0.
|
||||
|
||||
- The polling timer is only re-armed when the guest responds to the
|
||||
statistics request. This means that if a (buggy) guest doesn't ever
|
||||
|
@ -34,6 +34,7 @@
|
||||
typedef struct PCISerialState {
|
||||
PCIDevice dev;
|
||||
SerialState state;
|
||||
uint8_t prog_if;
|
||||
} PCISerialState;
|
||||
|
||||
typedef struct PCIMultiSerialState {
|
||||
@ -44,6 +45,7 @@ typedef struct PCIMultiSerialState {
|
||||
SerialState state[PCI_SERIAL_MAX_PORTS];
|
||||
uint32_t level[PCI_SERIAL_MAX_PORTS];
|
||||
qemu_irq *irqs;
|
||||
uint8_t prog_if;
|
||||
} PCIMultiSerialState;
|
||||
|
||||
static int serial_pci_init(PCIDevice *dev)
|
||||
@ -60,6 +62,7 @@ static int serial_pci_init(PCIDevice *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pci->dev.config[PCI_CLASS_PROG] = pci->prog_if;
|
||||
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
|
||||
s->irq = pci_allocate_irq(&pci->dev);
|
||||
|
||||
@ -101,6 +104,7 @@ static int multi_serial_pci_init(PCIDevice *dev)
|
||||
assert(pci->ports > 0);
|
||||
assert(pci->ports <= PCI_SERIAL_MAX_PORTS);
|
||||
|
||||
pci->dev.config[PCI_CLASS_PROG] = pci->prog_if;
|
||||
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
|
||||
memory_region_init(&pci->iobar, OBJECT(pci), "multiserial", 8 * pci->ports);
|
||||
pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar);
|
||||
@ -177,12 +181,14 @@ static const VMStateDescription vmstate_pci_multi_serial = {
|
||||
|
||||
static Property serial_pci_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev", PCISerialState, state.chr),
|
||||
DEFINE_PROP_UINT8("prog_if", PCISerialState, prog_if, 0x02),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static Property multi_2x_serial_pci_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr),
|
||||
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
|
||||
DEFINE_PROP_UINT8("prog_if", PCIMultiSerialState, prog_if, 0x02),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@ -191,6 +197,7 @@ static Property multi_4x_serial_pci_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
|
||||
DEFINE_PROP_CHR("chardev3", PCIMultiSerialState, state[2].chr),
|
||||
DEFINE_PROP_CHR("chardev4", PCIMultiSerialState, state[3].chr),
|
||||
DEFINE_PROP_UINT8("prog_if", PCIMultiSerialState, prog_if, 0x02),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@ -439,11 +439,27 @@ PropertyInfo qdev_prop_iothread = {
|
||||
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
|
||||
{
|
||||
GlobalProperty *g;
|
||||
ObjectClass *oc;
|
||||
|
||||
g = g_malloc0(sizeof(*g));
|
||||
g->driver = qemu_opt_get(opts, "driver");
|
||||
g->property = qemu_opt_get(opts, "property");
|
||||
g->value = qemu_opt_get(opts, "value");
|
||||
oc = object_class_by_name(g->driver);
|
||||
if (oc) {
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
if (dc->hotpluggable) {
|
||||
/* If hotpluggable then skip not_used checking. */
|
||||
g->not_used = false;
|
||||
} else {
|
||||
/* Maybe a typo. */
|
||||
g->not_used = true;
|
||||
}
|
||||
} else {
|
||||
/* Maybe a typo. */
|
||||
g->not_used = true;
|
||||
}
|
||||
qdev_prop_register_global(g);
|
||||
return 0;
|
||||
}
|
||||
|
@ -955,6 +955,23 @@ void qdev_prop_register_global_list(GlobalProperty *props)
|
||||
}
|
||||
}
|
||||
|
||||
int qdev_prop_check_global(void)
|
||||
{
|
||||
GlobalProperty *prop;
|
||||
int ret = 0;
|
||||
|
||||
QTAILQ_FOREACH(prop, &global_props, next) {
|
||||
if (!prop->not_used) {
|
||||
continue;
|
||||
}
|
||||
ret = 1;
|
||||
error_report("Warning: \"-global %s.%s=%s\" not used",
|
||||
prop->driver, prop->property, prop->value);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
|
||||
Error **errp)
|
||||
{
|
||||
@ -966,6 +983,7 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
|
||||
if (strcmp(typename, prop->driver) != 0) {
|
||||
continue;
|
||||
}
|
||||
prop->not_used = false;
|
||||
object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
|
||||
if (err != NULL) {
|
||||
error_propagate(errp, err);
|
||||
|
110
hw/i386/smbios.c
110
hw/i386/smbios.c
@ -67,7 +67,7 @@ static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
|
||||
|
||||
static struct {
|
||||
const char *vendor, *version, *date;
|
||||
bool have_major_minor;
|
||||
bool have_major_minor, uefi;
|
||||
uint8_t major, minor;
|
||||
} type0;
|
||||
|
||||
@ -134,6 +134,10 @@ static const QemuOptDesc qemu_smbios_type0_opts[] = {
|
||||
.name = "release",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "revision number",
|
||||
},{
|
||||
.name = "uefi",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "uefi support",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
};
|
||||
@ -444,7 +448,7 @@ static bool smbios_skip_table(uint8_t type, bool required_table)
|
||||
\
|
||||
t->header.type = tbl_type; \
|
||||
t->header.length = sizeof(*t); \
|
||||
t->header.handle = tbl_handle; \
|
||||
t->header.handle = cpu_to_le16(tbl_handle); \
|
||||
} while (0)
|
||||
|
||||
#define SMBIOS_TABLE_SET_STR(tbl_type, field, value) \
|
||||
@ -491,19 +495,18 @@ static void smbios_build_type_0_table(void)
|
||||
SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor);
|
||||
SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version);
|
||||
|
||||
t->bios_starting_address_segment = 0xE800; /* hardcoded in SeaBIOS */
|
||||
t->bios_starting_address_segment = cpu_to_le16(0xE800); /* from SeaBIOS */
|
||||
|
||||
SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date);
|
||||
|
||||
t->bios_rom_size = 0; /* hardcoded in SeaBIOS with FIXME comment */
|
||||
|
||||
/* BIOS characteristics not supported */
|
||||
memset(t->bios_characteristics, 0, 8);
|
||||
t->bios_characteristics[0] = 0x08;
|
||||
|
||||
/* Enable targeted content distribution (needed for SVVP, per SeaBIOS) */
|
||||
t->bios_characteristics = cpu_to_le64(0x08); /* Not supported */
|
||||
t->bios_characteristics_extension_bytes[0] = 0;
|
||||
t->bios_characteristics_extension_bytes[1] = 4;
|
||||
t->bios_characteristics_extension_bytes[1] = 0x14; /* TCD/SVVP | VM */
|
||||
if (type0.uefi) {
|
||||
t->bios_characteristics_extension_bytes[1] |= 0x08; /* |= UEFI */
|
||||
}
|
||||
|
||||
if (type0.have_major_minor) {
|
||||
t->system_bios_major_release = type0.major;
|
||||
@ -551,7 +554,7 @@ static void smbios_build_type_2_table(void)
|
||||
SMBIOS_TABLE_SET_STR(2, asset_tag_number_str, type2.asset);
|
||||
t->feature_flags = 0x01; /* Motherboard */
|
||||
SMBIOS_TABLE_SET_STR(2, location_str, type2.location);
|
||||
t->chassis_handle = 0x300; /* Type 3 (System enclosure) */
|
||||
t->chassis_handle = cpu_to_le16(0x300); /* Type 3 (System enclosure) */
|
||||
t->board_type = 0x0A; /* Motherboard */
|
||||
t->contained_element_count = 0;
|
||||
|
||||
@ -571,7 +574,7 @@ static void smbios_build_type_3_table(void)
|
||||
t->power_supply_state = 0x03; /* Safe */
|
||||
t->thermal_state = 0x03; /* Safe */
|
||||
t->security_status = 0x02; /* Unknown */
|
||||
t->oem_defined = 0;
|
||||
t->oem_defined = cpu_to_le32(0);
|
||||
t->height = 0;
|
||||
t->number_of_power_cords = 0;
|
||||
t->contained_element_count = 0;
|
||||
@ -589,26 +592,27 @@ static void smbios_build_type_4_table(unsigned instance)
|
||||
snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, instance);
|
||||
SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str);
|
||||
t->processor_type = 0x03; /* CPU */
|
||||
t->processor_family = 0x01; /* Other */
|
||||
SMBIOS_TABLE_SET_STR(4, processor_manufacturer_str, type4.manufacturer);
|
||||
t->processor_id[0] = smbios_cpuid_version;
|
||||
t->processor_id[1] = smbios_cpuid_features;
|
||||
t->processor_id[0] = cpu_to_le32(smbios_cpuid_version);
|
||||
t->processor_id[1] = cpu_to_le32(smbios_cpuid_features);
|
||||
SMBIOS_TABLE_SET_STR(4, processor_version_str, type4.version);
|
||||
t->voltage = 0;
|
||||
t->external_clock = 0; /* Unknown */
|
||||
t->max_speed = 0; /* Unknown */
|
||||
t->current_speed = 0; /* Unknown */
|
||||
t->external_clock = cpu_to_le16(0); /* Unknown */
|
||||
t->max_speed = cpu_to_le16(0); /* Unknown */
|
||||
t->current_speed = cpu_to_le16(0); /* Unknown */
|
||||
t->status = 0x41; /* Socket populated, CPU enabled */
|
||||
t->processor_upgrade = 0x01; /* Other */
|
||||
t->l1_cache_handle = 0xFFFF; /* N/A */
|
||||
t->l2_cache_handle = 0xFFFF; /* N/A */
|
||||
t->l3_cache_handle = 0xFFFF; /* N/A */
|
||||
t->l1_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
|
||||
t->l2_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
|
||||
t->l3_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
|
||||
SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
|
||||
SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
|
||||
SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
|
||||
t->core_count = t->core_enabled = smp_cores;
|
||||
t->thread_count = smp_threads;
|
||||
t->processor_characteristics = 0x02; /* Unknown */
|
||||
t->processor_family = t->processor_family2 = 0x01; /* Other */
|
||||
t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
|
||||
t->processor_family2 = cpu_to_le16(0x01); /* Other */
|
||||
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
smbios_type4_count++;
|
||||
@ -631,14 +635,14 @@ static void smbios_build_type_16_table(unsigned dimm_cnt)
|
||||
t->error_correction = 0x06; /* Multi-bit ECC (for Microsoft, per SeaBIOS) */
|
||||
size_kb = QEMU_ALIGN_UP(ram_size, ONE_KB) / ONE_KB;
|
||||
if (size_kb < MAX_T16_STD_SZ) {
|
||||
t->maximum_capacity = size_kb;
|
||||
t->extended_maximum_capacity = 0;
|
||||
t->maximum_capacity = cpu_to_le32(size_kb);
|
||||
t->extended_maximum_capacity = cpu_to_le64(0);
|
||||
} else {
|
||||
t->maximum_capacity = MAX_T16_STD_SZ;
|
||||
t->extended_maximum_capacity = ram_size;
|
||||
t->maximum_capacity = cpu_to_le32(MAX_T16_STD_SZ);
|
||||
t->extended_maximum_capacity = cpu_to_le64(ram_size);
|
||||
}
|
||||
t->memory_error_information_handle = 0xFFFE; /* Not provided */
|
||||
t->number_of_memory_devices = dimm_cnt;
|
||||
t->memory_error_information_handle = cpu_to_le16(0xFFFE); /* Not provided */
|
||||
t->number_of_memory_devices = cpu_to_le16(dimm_cnt);
|
||||
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
}
|
||||
@ -653,18 +657,18 @@ static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
|
||||
|
||||
SMBIOS_BUILD_TABLE_PRE(17, 0x1100 + instance, true); /* required */
|
||||
|
||||
t->physical_memory_array_handle = 0x1000; /* Type 16 (Phys. Mem. Array) */
|
||||
t->memory_error_information_handle = 0xFFFE; /* Not provided */
|
||||
t->total_width = 0xFFFF; /* Unknown */
|
||||
t->data_width = 0xFFFF; /* Unknown */
|
||||
t->physical_memory_array_handle = cpu_to_le16(0x1000); /* Type 16 above */
|
||||
t->memory_error_information_handle = cpu_to_le16(0xFFFE); /* Not provided */
|
||||
t->total_width = cpu_to_le16(0xFFFF); /* Unknown */
|
||||
t->data_width = cpu_to_le16(0xFFFF); /* Unknown */
|
||||
size_mb = QEMU_ALIGN_UP(size, ONE_MB) / ONE_MB;
|
||||
if (size_mb < MAX_T17_STD_SZ) {
|
||||
t->size = size_mb;
|
||||
t->extended_size = 0;
|
||||
t->size = cpu_to_le16(size_mb);
|
||||
t->extended_size = cpu_to_le32(0);
|
||||
} else {
|
||||
assert(size_mb < MAX_T17_EXT_SZ);
|
||||
t->size = MAX_T17_STD_SZ;
|
||||
t->extended_size = size_mb;
|
||||
t->size = cpu_to_le16(MAX_T17_STD_SZ);
|
||||
t->extended_size = cpu_to_le32(size_mb);
|
||||
}
|
||||
t->form_factor = 0x09; /* DIMM */
|
||||
t->device_set = 0; /* Not in a set */
|
||||
@ -672,17 +676,17 @@ static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
|
||||
SMBIOS_TABLE_SET_STR(17, device_locator_str, loc_str);
|
||||
SMBIOS_TABLE_SET_STR(17, bank_locator_str, type17.bank);
|
||||
t->memory_type = 0x07; /* RAM */
|
||||
t->type_detail = 0x02; /* Other */
|
||||
t->speed = 0; /* Unknown */
|
||||
t->type_detail = cpu_to_le16(0x02); /* Other */
|
||||
t->speed = cpu_to_le16(0); /* Unknown */
|
||||
SMBIOS_TABLE_SET_STR(17, manufacturer_str, type17.manufacturer);
|
||||
SMBIOS_TABLE_SET_STR(17, serial_number_str, type17.serial);
|
||||
SMBIOS_TABLE_SET_STR(17, asset_tag_number_str, type17.asset);
|
||||
SMBIOS_TABLE_SET_STR(17, part_number_str, type17.part);
|
||||
t->attributes = 0; /* Unknown */
|
||||
t->configured_clock_speed = 0; /* Unknown */
|
||||
t->minimum_voltage = 0; /* Unknown */
|
||||
t->maximum_voltage = 0; /* Unknown */
|
||||
t->configured_voltage = 0; /* Unknown */
|
||||
t->configured_clock_speed = cpu_to_le16(0); /* Unknown */
|
||||
t->minimum_voltage = cpu_to_le16(0); /* Unknown */
|
||||
t->maximum_voltage = cpu_to_le16(0); /* Unknown */
|
||||
t->configured_voltage = cpu_to_le16(0); /* Unknown */
|
||||
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
}
|
||||
@ -699,15 +703,16 @@ static void smbios_build_type_19_table(unsigned instance,
|
||||
start_kb = start / ONE_KB;
|
||||
end_kb = end / ONE_KB;
|
||||
if (start_kb < UINT32_MAX && end_kb < UINT32_MAX) {
|
||||
t->starting_address = start_kb;
|
||||
t->ending_address = end_kb;
|
||||
t->extended_starting_address = t->extended_ending_address = 0;
|
||||
t->starting_address = cpu_to_le32(start_kb);
|
||||
t->ending_address = cpu_to_le32(end_kb);
|
||||
t->extended_starting_address =
|
||||
t->extended_ending_address = cpu_to_le64(0);
|
||||
} else {
|
||||
t->starting_address = t->ending_address = UINT32_MAX;
|
||||
t->extended_starting_address = start;
|
||||
t->extended_ending_address = end;
|
||||
t->starting_address = t->ending_address = cpu_to_le32(UINT32_MAX);
|
||||
t->extended_starting_address = cpu_to_le64(start);
|
||||
t->extended_ending_address = cpu_to_le64(end);
|
||||
}
|
||||
t->memory_array_handle = 0x1000; /* Type 16 (Phys. Mem. Array) */
|
||||
t->memory_array_handle = cpu_to_le16(0x1000); /* Type 16 above */
|
||||
t->partition_width = 1; /* One device per row */
|
||||
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
@ -794,14 +799,14 @@ static void smbios_entry_point_setup(void)
|
||||
ep.smbios_bcd_revision = 0x28;
|
||||
|
||||
/* set during table construction, but BIOS may override: */
|
||||
ep.structure_table_length = smbios_tables_len;
|
||||
ep.max_structure_size = smbios_table_max;
|
||||
ep.number_of_structures = smbios_table_cnt;
|
||||
ep.structure_table_length = cpu_to_le16(smbios_tables_len);
|
||||
ep.max_structure_size = cpu_to_le16(smbios_table_max);
|
||||
ep.number_of_structures = cpu_to_le16(smbios_table_cnt);
|
||||
|
||||
/* BIOS must recalculate: */
|
||||
ep.checksum = 0;
|
||||
ep.intermediate_checksum = 0;
|
||||
ep.structure_table_address = 0; /* where BIOS has copied smbios_tables */
|
||||
ep.structure_table_address = cpu_to_le32(0);
|
||||
}
|
||||
|
||||
void smbios_get_tables(uint8_t **tables, size_t *tables_len,
|
||||
@ -977,6 +982,7 @@ void smbios_entry_add(QemuOpts *opts)
|
||||
save_opt(&type0.vendor, opts, "vendor");
|
||||
save_opt(&type0.version, opts, "version");
|
||||
save_opt(&type0.date, opts, "date");
|
||||
type0.uefi = qemu_opt_get_bool(opts, "uefi", false);
|
||||
|
||||
val = qemu_opt_get(opts, "release");
|
||||
if (val) {
|
||||
|
@ -47,10 +47,6 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
|
||||
sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
|
||||
|
||||
if (pcie_host_init(PCIE_HOST_BRIDGE(s)) < 0) {
|
||||
error_setg(errp, "failed to initialize pcie host");
|
||||
return;
|
||||
}
|
||||
pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
|
||||
s->mch.pci_address_space, s->mch.address_space_io,
|
||||
0, TYPE_PCIE_BUS);
|
||||
|
@ -83,11 +83,11 @@ static const MemoryRegionOps pcie_mmcfg_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
int pcie_host_init(PCIExpressHost *e)
|
||||
static void pcie_host_init(Object *obj)
|
||||
{
|
||||
e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
|
||||
PCIExpressHost *e = PCIE_HOST_BRIDGE(obj);
|
||||
|
||||
return 0;
|
||||
e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
|
||||
}
|
||||
|
||||
void pcie_host_mmcfg_unmap(PCIExpressHost *e)
|
||||
@ -128,6 +128,7 @@ static const TypeInfo pcie_host_type_info = {
|
||||
.parent = TYPE_PCI_HOST_BRIDGE,
|
||||
.abstract = true,
|
||||
.instance_size = sizeof(PCIExpressHost),
|
||||
.instance_init = pcie_host_init,
|
||||
};
|
||||
|
||||
static void pcie_host_register_types(void)
|
||||
|
@ -112,11 +112,6 @@ static void balloon_stats_get_all(Object *obj, struct Visitor *v,
|
||||
VirtIOBalloon *s = opaque;
|
||||
int i;
|
||||
|
||||
if (!s->stats_last_update) {
|
||||
error_setg(errp, "guest hasn't updated any stats yet");
|
||||
return;
|
||||
}
|
||||
|
||||
visit_start_struct(v, NULL, "guest-stats", name, 0, &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
@ -378,6 +373,8 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
|
||||
s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
|
||||
s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats);
|
||||
|
||||
reset_stats(s);
|
||||
|
||||
register_savevm(dev, "virtio-balloon", -1, 1,
|
||||
virtio_balloon_save, virtio_balloon_load, s);
|
||||
|
||||
|
@ -275,6 +275,21 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
||||
.driver = "nec-usb-xhci",\
|
||||
.property = "superspeed-ports-first",\
|
||||
.value = "off",\
|
||||
},\
|
||||
{\
|
||||
.driver = "pci-serial",\
|
||||
.property = "prog_if",\
|
||||
.value = stringify(0),\
|
||||
},\
|
||||
{\
|
||||
.driver = "pci-serial-2x",\
|
||||
.property = "prof_if",\
|
||||
.value = stringify(0),\
|
||||
},\
|
||||
{\
|
||||
.driver = "pci-serial-4x",\
|
||||
.property = "prog_if",\
|
||||
.value = stringify(0),\
|
||||
}
|
||||
|
||||
#define PC_COMPAT_1_7 \
|
||||
|
@ -64,7 +64,7 @@ struct smbios_type_0 {
|
||||
uint16_t bios_starting_address_segment;
|
||||
uint8_t bios_release_date_str;
|
||||
uint8_t bios_rom_size;
|
||||
uint8_t bios_characteristics[8];
|
||||
uint64_t bios_characteristics;
|
||||
uint8_t bios_characteristics_extension_bytes[2];
|
||||
uint8_t system_bios_major_release;
|
||||
uint8_t system_bios_minor_release;
|
||||
@ -182,10 +182,10 @@ struct smbios_type_17 {
|
||||
uint8_t part_number_str;
|
||||
uint8_t attributes;
|
||||
uint32_t extended_size;
|
||||
uint32_t configured_clock_speed;
|
||||
uint32_t minimum_voltage;
|
||||
uint32_t maximum_voltage;
|
||||
uint32_t configured_voltage;
|
||||
uint16_t configured_clock_speed;
|
||||
uint16_t minimum_voltage;
|
||||
uint16_t maximum_voltage;
|
||||
uint16_t configured_voltage;
|
||||
} QEMU_PACKED;
|
||||
|
||||
/* SMBIOS type 19 - Memory Array Mapped Address (v2.7) */
|
||||
|
@ -49,7 +49,6 @@ struct PCIExpressHost {
|
||||
MemoryRegion mmio;
|
||||
};
|
||||
|
||||
int pcie_host_init(PCIExpressHost *e);
|
||||
void pcie_host_mmcfg_unmap(PCIExpressHost *e);
|
||||
void pcie_host_mmcfg_map(PCIExpressHost *e, hwaddr addr, uint32_t size);
|
||||
void pcie_host_mmcfg_update(PCIExpressHost *e,
|
||||
|
@ -239,10 +239,18 @@ struct PropertyInfo {
|
||||
ObjectPropertyRelease *release;
|
||||
};
|
||||
|
||||
/**
|
||||
* GlobalProperty:
|
||||
* @not_used: Track use of a global property. Defaults to false in all C99
|
||||
* struct initializations.
|
||||
*
|
||||
* This prevents reports of .compat_props when they are not used.
|
||||
*/
|
||||
typedef struct GlobalProperty {
|
||||
const char *driver;
|
||||
const char *property;
|
||||
const char *value;
|
||||
bool not_used;
|
||||
QTAILQ_ENTRY(GlobalProperty) next;
|
||||
} GlobalProperty;
|
||||
|
||||
|
@ -180,6 +180,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
|
||||
|
||||
void qdev_prop_register_global(GlobalProperty *prop);
|
||||
void qdev_prop_register_global_list(GlobalProperty *props);
|
||||
int qdev_prop_check_global(void);
|
||||
void qdev_prop_set_globals(DeviceState *dev, Error **errp);
|
||||
void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
|
||||
Error **errp);
|
||||
|
@ -1341,7 +1341,7 @@ ETEXI
|
||||
DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
|
||||
"-smbios file=binary\n"
|
||||
" load SMBIOS entry from binary file\n"
|
||||
"-smbios type=0[,vendor=str][,version=str][,date=str][,release=%d.%d]\n"
|
||||
"-smbios type=0[,vendor=str][,version=str][,date=str][,release=%d.%d][,uefi=on|off]\n"
|
||||
" specify SMBIOS type 0 fields\n"
|
||||
"-smbios type=1[,manufacturer=str][,product=str][,version=str][,serial=str]\n"
|
||||
" [,uuid=uuid][,sku=str][,family=str]\n"
|
||||
@ -1351,7 +1351,7 @@ STEXI
|
||||
@findex -smbios
|
||||
Load SMBIOS entry from binary file.
|
||||
|
||||
@item -smbios type=0[,vendor=@var{str}][,version=@var{str}][,date=@var{str}][,release=@var{%d.%d}]
|
||||
@item -smbios type=0[,vendor=@var{str}][,version=@var{str}][,date=@var{str}][,release=@var{%d.%d}][,uefi=on|off]
|
||||
Specify SMBIOS type 0 fields
|
||||
|
||||
@item -smbios type=1[,manufacturer=@var{str}][,product=@var{str}] [,version=@var{str}][,serial=@var{str}][,uuid=@var{uuid}][,sku=@var{str}] [,family=@var{str}]
|
||||
|
@ -133,7 +133,7 @@ check-qtest-i386-y += tests/ide-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
|
||||
gcov-files-i386-y += hw/block/hd-geometry.c
|
||||
check-qtest-i386-y += tests/boot-order-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/acpi-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/bios-tables-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/rtc-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/i440fx-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
|
||||
@ -290,7 +290,7 @@ tests/fdc-test$(EXESUF): tests/fdc-test.o
|
||||
tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
|
||||
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
|
||||
tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
|
||||
tests/acpi-test$(EXESUF): tests/acpi-test.o $(libqos-obj-y)
|
||||
tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o $(libqos-obj-y)
|
||||
tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
|
||||
tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
|
||||
tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "libqtest.h"
|
||||
#include "qemu/compiler.h"
|
||||
#include "hw/i386/acpi-defs.h"
|
||||
#include "hw/i386/smbios.h"
|
||||
#include "qemu/bitmap.h"
|
||||
|
||||
#define MACHINE_PC "pc"
|
||||
#define MACHINE_Q35 "q35"
|
||||
@ -46,6 +48,8 @@ typedef struct {
|
||||
uint32_t *rsdt_tables_addr;
|
||||
int rsdt_tables_nr;
|
||||
GArray *tables;
|
||||
uint32_t smbios_ep_addr;
|
||||
struct smbios_entry_point smbios_ep_table;
|
||||
} test_data;
|
||||
|
||||
#define LOW(x) ((x) & 0xff)
|
||||
@ -581,6 +585,124 @@ static void test_acpi_asl(test_data *data)
|
||||
free_test_data(&exp_data);
|
||||
}
|
||||
|
||||
static void test_smbios_ep_address(test_data *data)
|
||||
{
|
||||
uint32_t off;
|
||||
|
||||
/* find smbios entry point structure */
|
||||
for (off = 0xf0000; off < 0x100000; off += 0x10) {
|
||||
uint8_t sig[] = "_SM_";
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof sig - 1; ++i) {
|
||||
sig[i] = readb(off + i);
|
||||
}
|
||||
|
||||
if (!memcmp(sig, "_SM_", sizeof sig)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_cmphex(off, <, 0x100000);
|
||||
data->smbios_ep_addr = off;
|
||||
}
|
||||
|
||||
static void test_smbios_ep_table(test_data *data)
|
||||
{
|
||||
struct smbios_entry_point *ep_table = &data->smbios_ep_table;
|
||||
uint32_t addr = data->smbios_ep_addr;
|
||||
|
||||
ACPI_READ_ARRAY(ep_table->anchor_string, addr);
|
||||
g_assert(!memcmp(ep_table->anchor_string, "_SM_", 4));
|
||||
ACPI_READ_FIELD(ep_table->checksum, addr);
|
||||
ACPI_READ_FIELD(ep_table->length, addr);
|
||||
ACPI_READ_FIELD(ep_table->smbios_major_version, addr);
|
||||
ACPI_READ_FIELD(ep_table->smbios_minor_version, addr);
|
||||
ACPI_READ_FIELD(ep_table->max_structure_size, addr);
|
||||
ACPI_READ_FIELD(ep_table->entry_point_revision, addr);
|
||||
ACPI_READ_ARRAY(ep_table->formatted_area, addr);
|
||||
ACPI_READ_ARRAY(ep_table->intermediate_anchor_string, addr);
|
||||
g_assert(!memcmp(ep_table->intermediate_anchor_string, "_DMI_", 5));
|
||||
ACPI_READ_FIELD(ep_table->intermediate_checksum, addr);
|
||||
ACPI_READ_FIELD(ep_table->structure_table_length, addr);
|
||||
g_assert_cmpuint(ep_table->structure_table_length, >, 0);
|
||||
ACPI_READ_FIELD(ep_table->structure_table_address, addr);
|
||||
ACPI_READ_FIELD(ep_table->number_of_structures, addr);
|
||||
g_assert_cmpuint(ep_table->number_of_structures, >, 0);
|
||||
ACPI_READ_FIELD(ep_table->smbios_bcd_revision, addr);
|
||||
g_assert(!acpi_checksum((uint8_t *)ep_table, sizeof *ep_table));
|
||||
g_assert(!acpi_checksum((uint8_t *)ep_table + 0x10,
|
||||
sizeof *ep_table - 0x10));
|
||||
}
|
||||
|
||||
static inline bool smbios_single_instance(uint8_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 16:
|
||||
case 32:
|
||||
case 127:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_smbios_structs(test_data *data)
|
||||
{
|
||||
DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
|
||||
struct smbios_entry_point *ep_table = &data->smbios_ep_table;
|
||||
uint32_t addr = ep_table->structure_table_address;
|
||||
int i, len, max_len = 0;
|
||||
uint8_t type, prv, crt;
|
||||
uint8_t required_struct_types[] = {0, 1, 3, 4, 16, 17, 19, 32, 127};
|
||||
|
||||
/* walk the smbios tables */
|
||||
for (i = 0; i < ep_table->number_of_structures; i++) {
|
||||
|
||||
/* grab type and formatted area length from struct header */
|
||||
type = readb(addr);
|
||||
g_assert_cmpuint(type, <=, SMBIOS_MAX_TYPE);
|
||||
len = readb(addr + 1);
|
||||
|
||||
/* single-instance structs must not have been encountered before */
|
||||
if (smbios_single_instance(type)) {
|
||||
g_assert(!test_bit(type, struct_bitmap));
|
||||
}
|
||||
set_bit(type, struct_bitmap);
|
||||
|
||||
/* seek to end of unformatted string area of this struct ("\0\0") */
|
||||
prv = crt = 1;
|
||||
while (prv || crt) {
|
||||
prv = crt;
|
||||
crt = readb(addr + len);
|
||||
len++;
|
||||
}
|
||||
|
||||
/* keep track of max. struct size */
|
||||
if (max_len < len) {
|
||||
max_len = len;
|
||||
g_assert_cmpuint(max_len, <=, ep_table->max_structure_size);
|
||||
}
|
||||
|
||||
/* start of next structure */
|
||||
addr += len;
|
||||
}
|
||||
|
||||
/* total table length and max struct size must match entry point values */
|
||||
g_assert_cmpuint(ep_table->structure_table_length, ==,
|
||||
addr - ep_table->structure_table_address);
|
||||
g_assert_cmpuint(ep_table->max_structure_size, ==, max_len);
|
||||
|
||||
/* required struct types must all be present */
|
||||
for (i = 0; i < ARRAY_SIZE(required_struct_types); i++) {
|
||||
g_assert(test_bit(required_struct_types[i], struct_bitmap));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_acpi_one(const char *params, test_data *data)
|
||||
{
|
||||
char *args;
|
||||
@ -633,6 +755,10 @@ static void test_acpi_one(const char *params, test_data *data)
|
||||
}
|
||||
}
|
||||
|
||||
test_smbios_ep_address(data);
|
||||
test_smbios_ep_table(data);
|
||||
test_smbios_structs(data);
|
||||
|
||||
qtest_quit(global_qtest);
|
||||
g_free(args);
|
||||
}
|
@ -150,8 +150,10 @@ static void test_dynamic_globalprop(void)
|
||||
static GlobalProperty props[] = {
|
||||
{ TYPE_DYNAMIC_PROPS, "prop1", "101" },
|
||||
{ TYPE_DYNAMIC_PROPS, "prop2", "102" },
|
||||
{ TYPE_DYNAMIC_PROPS"-bad", "prop3", "103", true },
|
||||
{}
|
||||
};
|
||||
int all_used;
|
||||
|
||||
qdev_prop_register_global_list(props);
|
||||
|
||||
@ -160,6 +162,8 @@ static void test_dynamic_globalprop(void)
|
||||
|
||||
g_assert_cmpuint(mt->prop1, ==, 101);
|
||||
g_assert_cmpuint(mt->prop2, ==, 102);
|
||||
all_used = qdev_prop_check_global();
|
||||
g_assert_cmpuint(all_used, ==, 1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
Loading…
Reference in New Issue
Block a user