summaryrefslogtreecommitdiffstats
path: root/hw/core
diff options
context:
space:
mode:
Diffstat (limited to 'hw/core')
-rw-r--r--hw/core/empty_slot.c9
-rw-r--r--hw/core/loader.c76
-rw-r--r--hw/core/machine.c157
-rw-r--r--hw/core/qdev-properties-system.c4
-rw-r--r--hw/core/qdev-properties.c249
-rw-r--r--hw/core/qdev.c22
-rw-r--r--hw/core/reset.c2
-rw-r--r--hw/core/sysbus.c15
-rw-r--r--hw/core/uboot_image.h1
9 files changed, 381 insertions, 154 deletions
diff --git a/hw/core/empty_slot.c b/hw/core/empty_slot.c
index c1b9c2b104..239f78e2a7 100644
--- a/hw/core/empty_slot.c
+++ b/hw/core/empty_slot.c
@@ -71,21 +71,20 @@ void empty_slot_init(hwaddr addr, uint64_t slot_size)
}
}
-static int empty_slot_init1(SysBusDevice *dev)
+static void empty_slot_realize(DeviceState *dev, Error **errp)
{
EmptySlot *s = EMPTY_SLOT(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &empty_slot_ops, s,
"empty-slot", s->size);
- sysbus_init_mmio(dev, &s->iomem);
- return 0;
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
}
static void empty_slot_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = empty_slot_init1;
+ dc->realize = empty_slot_realize;
}
static const TypeInfo empty_slot_info = {
diff --git a/hw/core/loader.c b/hw/core/loader.c
index aa0b3fc867..c4f62fe427 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -74,31 +74,6 @@ int64_t get_image_size(const char *filename)
}
/* return the size or -1 if error */
-/* deprecated, because caller does not specify buffer size! */
-int load_image(const char *filename, uint8_t *addr)
-{
- int fd, size;
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- size = lseek(fd, 0, SEEK_END);
- if (size == -1) {
- fprintf(stderr, "file %-20s: get size error: %s\n",
- filename, strerror(errno));
- close(fd);
- return -1;
- }
-
- lseek(fd, 0, SEEK_SET);
- if (read(fd, addr, size) != size) {
- close(fd);
- return -1;
- }
- close(fd);
- return size;
-}
-
-/* return the size or -1 if error */
ssize_t load_image_size(const char *filename, void *addr, size_t size)
{
int fd;
@@ -269,26 +244,26 @@ int load_aout(const char *filename, hwaddr addr, int max_sz,
case OMAGIC:
if (e.a_text + e.a_data > max_sz)
goto fail;
- lseek(fd, N_TXTOFF(e), SEEK_SET);
- size = read_targphys(filename, fd, addr, e.a_text + e.a_data);
- if (size < 0)
- goto fail;
- break;
+ lseek(fd, N_TXTOFF(e), SEEK_SET);
+ size = read_targphys(filename, fd, addr, e.a_text + e.a_data);
+ if (size < 0)
+ goto fail;
+ break;
case NMAGIC:
if (N_DATADDR(e, target_page_size) + e.a_data > max_sz)
goto fail;
- lseek(fd, N_TXTOFF(e), SEEK_SET);
- size = read_targphys(filename, fd, addr, e.a_text);
- if (size < 0)
- goto fail;
+ lseek(fd, N_TXTOFF(e), SEEK_SET);
+ size = read_targphys(filename, fd, addr, e.a_text);
+ if (size < 0)
+ goto fail;
ret = read_targphys(filename, fd, addr + N_DATADDR(e, target_page_size),
e.a_data);
- if (ret < 0)
- goto fail;
- size += ret;
- break;
+ if (ret < 0)
+ goto fail;
+ size += ret;
+ break;
default:
- goto fail;
+ goto fail;
}
close(fd);
return size;
@@ -638,13 +613,26 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
goto out;
if (hdr->ih_type != image_type) {
- fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
- image_type);
- goto out;
+ if (!(image_type == IH_TYPE_KERNEL &&
+ hdr->ih_type == IH_TYPE_KERNEL_NOLOAD)) {
+ fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
+ image_type);
+ goto out;
+ }
}
/* TODO: Implement other image types. */
switch (hdr->ih_type) {
+ case IH_TYPE_KERNEL_NOLOAD:
+ if (!loadaddr || *loadaddr == LOAD_UIMAGE_LOADADDR_INVALID) {
+ fprintf(stderr, "this image format (kernel_noload) cannot be "
+ "loaded on this machine type");
+ goto out;
+ }
+
+ hdr->ih_load = *loadaddr + sizeof(*hdr);
+ hdr->ih_ep += hdr->ih_load;
+ /* fall through */
case IH_TYPE_KERNEL:
address = hdr->ih_load;
if (translate_fn) {
@@ -1103,8 +1091,8 @@ static void rom_reset(void *unused)
void *host = memory_region_get_ram_ptr(rom->mr);
memcpy(host, rom->data, rom->datasize);
} else {
- cpu_physical_memory_write_rom(rom->as, rom->addr, rom->data,
- rom->datasize);
+ address_space_write_rom(rom->as, rom->addr, MEMTXATTRS_UNSPECIFIED,
+ rom->data, rom->datasize);
}
if (rom->isrom) {
/* rom needs to be written only once */
diff --git a/hw/core/machine.c b/hw/core/machine.c
index da50ad6de7..2629515363 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -21,6 +21,129 @@
#include "sysemu/numa.h"
#include "qemu/error-report.h"
#include "sysemu/qtest.h"
+#include "hw/pci/pci.h"
+
+GlobalProperty hw_compat_3_1[] = {
+ { "pcie-root-port", "x-speed", "2_5" },
+ { "pcie-root-port", "x-width", "1" },
+ { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" },
+ { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" },
+ { "tpm-crb", "ppi", "false" },
+ { "tpm-tis", "ppi", "false" },
+};
+const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1);
+
+GlobalProperty hw_compat_3_0[] = {};
+const size_t hw_compat_3_0_len = G_N_ELEMENTS(hw_compat_3_0);
+
+GlobalProperty hw_compat_2_12[] = {
+ { "migration", "decompress-error-check", "off" },
+ { "hda-audio", "use-timer", "false" },
+ { "cirrus-vga", "global-vmstate", "true" },
+ { "VGA", "global-vmstate", "true" },
+ { "vmware-svga", "global-vmstate", "true" },
+ { "qxl-vga", "global-vmstate", "true" },
+};
+const size_t hw_compat_2_12_len = G_N_ELEMENTS(hw_compat_2_12);
+
+GlobalProperty hw_compat_2_11[] = {
+ { "hpet", "hpet-offset-saved", "false" },
+ { "virtio-blk-pci", "vectors", "2" },
+ { "vhost-user-blk-pci", "vectors", "2" },
+ { "e1000", "migrate_tso_props", "off" },
+};
+const size_t hw_compat_2_11_len = G_N_ELEMENTS(hw_compat_2_11);
+
+GlobalProperty hw_compat_2_10[] = {
+ { "virtio-mouse-device", "wheel-axis", "false" },
+ { "virtio-tablet-device", "wheel-axis", "false" },
+};
+const size_t hw_compat_2_10_len = G_N_ELEMENTS(hw_compat_2_10);
+
+GlobalProperty hw_compat_2_9[] = {
+ { "pci-bridge", "shpc", "off" },
+ { "intel-iommu", "pt", "off" },
+ { "virtio-net-device", "x-mtu-bypass-backend", "off" },
+ { "pcie-root-port", "x-migrate-msix", "false" },
+};
+const size_t hw_compat_2_9_len = G_N_ELEMENTS(hw_compat_2_9);
+
+GlobalProperty hw_compat_2_8[] = {
+ { "fw_cfg_mem", "x-file-slots", "0x10" },
+ { "fw_cfg_io", "x-file-slots", "0x10" },
+ { "pflash_cfi01", "old-multiple-chip-handling", "on" },
+ { "pci-bridge", "shpc", "on" },
+ { TYPE_PCI_DEVICE, "x-pcie-extcap-init", "off" },
+ { "virtio-pci", "x-pcie-deverr-init", "off" },
+ { "virtio-pci", "x-pcie-lnkctl-init", "off" },
+ { "virtio-pci", "x-pcie-pm-init", "off" },
+ { "cirrus-vga", "vgamem_mb", "8" },
+ { "isa-cirrus-vga", "vgamem_mb", "8" },
+};
+const size_t hw_compat_2_8_len = G_N_ELEMENTS(hw_compat_2_8);
+
+GlobalProperty hw_compat_2_7[] = {
+ { "virtio-pci", "page-per-vq", "on" },
+ { "virtio-serial-device", "emergency-write", "off" },
+ { "ioapic", "version", "0x11" },
+ { "intel-iommu", "x-buggy-eim", "true" },
+ { "virtio-pci", "x-ignore-backend-features", "on" },
+};
+const size_t hw_compat_2_7_len = G_N_ELEMENTS(hw_compat_2_7);
+
+GlobalProperty hw_compat_2_6[] = {
+ { "virtio-mmio", "format_transport_address", "off" },
+ /* Optional because not all virtio-pci devices support legacy mode */
+ { "virtio-pci", "disable-modern", "on", .optional = true },
+ { "virtio-pci", "disable-legacy", "off", .optional = true },
+};
+const size_t hw_compat_2_6_len = G_N_ELEMENTS(hw_compat_2_6);
+
+GlobalProperty hw_compat_2_5[] = {
+ { "isa-fdc", "fallback", "144" },
+ { "pvscsi", "x-old-pci-configuration", "on" },
+ { "pvscsi", "x-disable-pcie", "on" },
+ { "vmxnet3", "x-old-msi-offsets", "on" },
+ { "vmxnet3", "x-disable-pcie", "on" },
+};
+const size_t hw_compat_2_5_len = G_N_ELEMENTS(hw_compat_2_5);
+
+GlobalProperty hw_compat_2_4[] = {
+ { "virtio-blk-device", "scsi", "true" },
+ { "e1000", "extra_mac_registers", "off" },
+ { "virtio-pci", "x-disable-pcie", "on" },
+ { "virtio-pci", "migrate-extra", "off" },
+ { "fw_cfg_mem", "dma_enabled", "off" },
+ { "fw_cfg_io", "dma_enabled", "off" }
+};
+const size_t hw_compat_2_4_len = G_N_ELEMENTS(hw_compat_2_4);
+
+GlobalProperty hw_compat_2_3[] = {
+ { "virtio-blk-pci", "any_layout", "off" },
+ { "virtio-balloon-pci", "any_layout", "off" },
+ { "virtio-serial-pci", "any_layout", "off" },
+ { "virtio-9p-pci", "any_layout", "off" },
+ { "virtio-rng-pci", "any_layout", "off" },
+ { TYPE_PCI_DEVICE, "x-pcie-lnksta-dllla", "off" },
+ { "migration", "send-configuration", "off" },
+ { "migration", "send-section-footer", "off" },
+ { "migration", "store-global-state", "off" },
+};
+const size_t hw_compat_2_3_len = G_N_ELEMENTS(hw_compat_2_3);
+
+GlobalProperty hw_compat_2_2[] = {};
+const size_t hw_compat_2_2_len = G_N_ELEMENTS(hw_compat_2_2);
+
+GlobalProperty hw_compat_2_1[] = {
+ { "intel-hda", "old_msi_addr", "on" },
+ { "VGA", "qemu-extended-regs", "off" },
+ { "secondary-vga", "qemu-extended-regs", "off" },
+ { "virtio-scsi-pci", "any_layout", "off" },
+ { "usb-mouse", "usb_version", "1" },
+ { "usb-kbd", "usb_version", "1" },
+ { "virtio-pci", "virtio-pci-bus-master-bug-migration", "on" },
+};
+const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
static char *machine_get_accel(Object *obj, Error **errp)
{
@@ -591,7 +714,7 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_add_bool(oc, "dump-guest-core",
machine_get_dump_guest_core, machine_set_dump_guest_core, &error_abort);
object_class_property_set_description(oc, "dump-guest-core",
- "Include guest memory in a core dump", &error_abort);
+ "Include guest memory in a core dump", &error_abort);
object_class_property_add_bool(oc, "mem-merge",
machine_get_mem_merge, machine_set_mem_merge, &error_abort);
@@ -647,14 +770,17 @@ static void machine_class_base_init(ObjectClass *oc, void *data)
assert(g_str_has_suffix(cname, TYPE_MACHINE_SUFFIX));
mc->name = g_strndup(cname,
strlen(cname) - strlen(TYPE_MACHINE_SUFFIX));
+ mc->compat_props = g_ptr_array_new();
}
}
static void machine_initfn(Object *obj)
{
MachineState *ms = MACHINE(obj);
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
ms->kernel_irqchip_allowed = true;
+ ms->kernel_irqchip_split = mc->default_kernel_irqchip_split;
ms->kvm_shadow_mem = -1;
ms->dump_guest_core = true;
ms->mem_merge = true;
@@ -834,34 +960,6 @@ void machine_run_board_init(MachineState *machine)
machine_class->init(machine);
}
-static void machine_class_finalize(ObjectClass *klass, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(klass);
-
- if (mc->compat_props) {
- g_array_free(mc->compat_props, true);
- }
- g_free(mc->name);
-}
-
-void machine_register_compat_props(MachineState *machine)
-{
- MachineClass *mc = MACHINE_GET_CLASS(machine);
- int i;
- GlobalProperty *p;
-
- if (!mc->compat_props) {
- return;
- }
-
- for (i = 0; i < mc->compat_props->len; i++) {
- p = g_array_index(mc->compat_props, GlobalProperty *, i);
- /* Machine compat_props must never cause errors: */
- p->errp = &error_abort;
- qdev_prop_register_global(p);
- }
-}
-
static const TypeInfo machine_info = {
.name = TYPE_MACHINE,
.parent = TYPE_OBJECT,
@@ -869,7 +967,6 @@ static const TypeInfo machine_info = {
.class_size = sizeof(MachineClass),
.class_init = machine_class_init,
.class_base_init = machine_class_base_init,
- .class_finalize = machine_class_finalize,
.instance_size = sizeof(MachineState),
.instance_init = machine_initfn,
.instance_finalize = machine_finalize,
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 8b22fb51c9..b45a7ef54b 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -288,10 +288,6 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
}
for (i = 0; i < queues; i++) {
- if (peers[i] == NULL) {
- err = -ENOENT;
- goto out;
- }
if (peers[i]->peer) {
err = -EEXIST;
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 35072dec1e..5da1439a8b 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1173,58 +1173,35 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
*ptr = value;
}
-static GList *global_props;
-
-void qdev_prop_register_global(GlobalProperty *prop)
+static GPtrArray *global_props(void)
{
- global_props = g_list_append(global_props, prop);
-}
-
-void register_compat_prop(const char *driver,
- const char *property,
- const char *value)
-{
- GlobalProperty *p = g_new0(GlobalProperty, 1);
-
- /* Any compat_props must never cause error */
- p->errp = &error_abort;
- p->driver = driver;
- p->property = property;
- p->value = value;
- qdev_prop_register_global(p);
-}
+ static GPtrArray *gp;
-void register_compat_props_array(GlobalProperty *prop)
-{
- for (; prop && prop->driver; prop++) {
- register_compat_prop(prop->driver, prop->property, prop->value);
+ if (!gp) {
+ gp = g_ptr_array_new();
}
+
+ return gp;
}
-void qdev_prop_register_global_list(GlobalProperty *props)
+void qdev_prop_register_global(GlobalProperty *prop)
{
- int i;
-
- for (i = 0; props[i].driver != NULL; i++) {
- qdev_prop_register_global(props+i);
- }
+ g_ptr_array_add(global_props(), prop);
}
int qdev_prop_check_globals(void)
{
- GList *l;
- int ret = 0;
+ int i, ret = 0;
- for (l = global_props; l; l = l->next) {
- GlobalProperty *prop = l->data;
+ for (i = 0; i < global_props()->len; i++) {
+ GlobalProperty *prop;
ObjectClass *oc;
DeviceClass *dc;
+
+ prop = g_ptr_array_index(global_props(), i);
if (prop->used) {
continue;
}
- if (!prop->user_provided) {
- continue;
- }
oc = object_class_by_name(prop->driver);
oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
if (!oc) {
@@ -1246,28 +1223,8 @@ int qdev_prop_check_globals(void)
void qdev_prop_set_globals(DeviceState *dev)
{
- GList *l;
-
- for (l = global_props; l; l = l->next) {
- GlobalProperty *prop = l->data;
- Error *err = NULL;
-
- if (object_dynamic_cast(OBJECT(dev), prop->driver) == NULL) {
- continue;
- }
- prop->used = true;
- object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
- if (err != NULL) {
- error_prepend(&err, "can't apply global %s.%s=%s: ",
- prop->driver, prop->property, prop->value);
- if (!dev->hotplugged && prop->errp) {
- error_propagate(prop->errp, err);
- } else {
- assert(prop->user_provided);
- warn_report_err(err);
- }
- }
- }
+ object_apply_global_props(OBJECT(dev), global_props(),
+ dev->hotplugged ? NULL : &error_fatal);
}
/* --- 64bit unsigned int 'size' type --- */
@@ -1327,3 +1284,179 @@ const PropertyInfo qdev_prop_off_auto_pcibar = {
.set = set_enum,
.set_default_value = set_default_value_enum,
};
+
+/* --- PCIELinkSpeed 2_5/5/8/16 -- */
+
+static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
+ int speed;
+
+ switch (*p) {
+ case QEMU_PCI_EXP_LNK_2_5GT:
+ speed = PCIE_LINK_SPEED_2_5;
+ break;
+ case QEMU_PCI_EXP_LNK_5GT:
+ speed = PCIE_LINK_SPEED_5;
+ break;
+ case QEMU_PCI_EXP_LNK_8GT:
+ speed = PCIE_LINK_SPEED_8;
+ break;
+ case QEMU_PCI_EXP_LNK_16GT:
+ speed = PCIE_LINK_SPEED_16;
+ break;
+ default:
+ /* Unreachable */
+ abort();
+ }
+
+ visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp);
+}
+
+static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
+ int speed;
+ Error *local_err = NULL;
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_enum(v, prop->name, &speed, prop->info->enum_table, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ switch (speed) {
+ case PCIE_LINK_SPEED_2_5:
+ *p = QEMU_PCI_EXP_LNK_2_5GT;
+ break;
+ case PCIE_LINK_SPEED_5:
+ *p = QEMU_PCI_EXP_LNK_5GT;
+ break;
+ case PCIE_LINK_SPEED_8:
+ *p = QEMU_PCI_EXP_LNK_8GT;
+ break;
+ case PCIE_LINK_SPEED_16:
+ *p = QEMU_PCI_EXP_LNK_16GT;
+ break;
+ default:
+ /* Unreachable */
+ abort();
+ }
+}
+
+const PropertyInfo qdev_prop_pcie_link_speed = {
+ .name = "PCIELinkSpeed",
+ .description = "2_5/5/8/16",
+ .enum_table = &PCIELinkSpeed_lookup,
+ .get = get_prop_pcielinkspeed,
+ .set = set_prop_pcielinkspeed,
+ .set_default_value = set_default_value_enum,
+};
+
+/* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
+
+static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
+ int width;
+
+ switch (*p) {
+ case QEMU_PCI_EXP_LNK_X1:
+ width = PCIE_LINK_WIDTH_1;
+ break;
+ case QEMU_PCI_EXP_LNK_X2:
+ width = PCIE_LINK_WIDTH_2;
+ break;
+ case QEMU_PCI_EXP_LNK_X4:
+ width = PCIE_LINK_WIDTH_4;
+ break;
+ case QEMU_PCI_EXP_LNK_X8:
+ width = PCIE_LINK_WIDTH_8;
+ break;
+ case QEMU_PCI_EXP_LNK_X12:
+ width = PCIE_LINK_WIDTH_12;
+ break;
+ case QEMU_PCI_EXP_LNK_X16:
+ width = PCIE_LINK_WIDTH_16;
+ break;
+ case QEMU_PCI_EXP_LNK_X32:
+ width = PCIE_LINK_WIDTH_32;
+ break;
+ default:
+ /* Unreachable */
+ abort();
+ }
+
+ visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp);
+}
+
+static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
+ int width;
+ Error *local_err = NULL;
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_enum(v, prop->name, &width, prop->info->enum_table, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ switch (width) {
+ case PCIE_LINK_WIDTH_1:
+ *p = QEMU_PCI_EXP_LNK_X1;
+ break;
+ case PCIE_LINK_WIDTH_2:
+ *p = QEMU_PCI_EXP_LNK_X2;
+ break;
+ case PCIE_LINK_WIDTH_4:
+ *p = QEMU_PCI_EXP_LNK_X4;
+ break;
+ case PCIE_LINK_WIDTH_8:
+ *p = QEMU_PCI_EXP_LNK_X8;
+ break;
+ case PCIE_LINK_WIDTH_12:
+ *p = QEMU_PCI_EXP_LNK_X12;
+ break;
+ case PCIE_LINK_WIDTH_16:
+ *p = QEMU_PCI_EXP_LNK_X16;
+ break;
+ case PCIE_LINK_WIDTH_32:
+ *p = QEMU_PCI_EXP_LNK_X32;
+ break;
+ default:
+ /* Unreachable */
+ abort();
+ }
+}
+
+const PropertyInfo qdev_prop_pcie_link_width = {
+ .name = "PCIELinkWidth",
+ .description = "1/2/4/8/12/16/32",
+ .enum_table = &PCIELinkWidth_lookup,
+ .get = get_prop_pcielinkwidth,
+ .set = set_prop_pcielinkwidth,
+ .set_default_value = set_default_value_enum,
+};
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 6b3cc55b27..d59071b8ed 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -158,7 +158,7 @@ DeviceState *qdev_try_create(BusState *bus, const char *type)
return dev;
}
-static QTAILQ_HEAD(device_listeners, DeviceListener) device_listeners
+static QTAILQ_HEAD(, DeviceListener) device_listeners
= QTAILQ_HEAD_INITIALIZER(device_listeners);
enum ListenerDirection { Forward, Reverse };
@@ -177,7 +177,7 @@ enum ListenerDirection { Forward, Reverse };
break; \
case Reverse: \
QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
- device_listeners, link) { \
+ link) { \
if (_listener->_callback) { \
_listener->_callback(_listener, ##_args); \
} \
@@ -970,8 +970,26 @@ static void device_initfn(Object *obj)
QLIST_INIT(&dev->gpios);
}
+void object_apply_compat_props(Object *obj)
+{
+ if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
+ MachineState *m = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(m);
+
+ if (m->accelerator) {
+ AccelClass *ac = ACCEL_GET_CLASS(m->accelerator);
+
+ if (ac->compat_props) {
+ object_apply_global_props(obj, ac->compat_props, &error_abort);
+ }
+ }
+ object_apply_global_props(obj, mc->compat_props, &error_abort);
+ }
+}
+
static void device_post_init(Object *obj)
{
+ object_apply_compat_props(obj);
qdev_prop_set_globals(DEVICE(obj));
}
diff --git a/hw/core/reset.c b/hw/core/reset.c
index 84c8869371..9c477f2bf5 100644
--- a/hw/core/reset.c
+++ b/hw/core/reset.c
@@ -35,7 +35,7 @@ typedef struct QEMUResetEntry {
void *opaque;
} QEMUResetEntry;
-static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
+static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers =
QTAILQ_HEAD_INITIALIZER(reset_handlers);
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 7ac36ad3e7..9f9edbcab9 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -201,18 +201,13 @@ void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size)
}
}
-/* TODO remove once all sysbus devices have been converted to realize */
+/* The purpose of preserving this empty realize function
+ * is to prevent the parent_realize field of some subclasses
+ * from being set to NULL to break the normal init/realize
+ * of some devices.
+ */
static void sysbus_realize(DeviceState *dev, Error **errp)
{
- SysBusDevice *sd = SYS_BUS_DEVICE(dev);
- SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd);
-
- if (!sbc->init) {
- return;
- }
- if (sbc->init(sd) < 0) {
- error_setg(errp, "Device initialization failed");
- }
}
DeviceState *sysbus_create_varargs(const char *name,
diff --git a/hw/core/uboot_image.h b/hw/core/uboot_image.h
index 34c11a70a6..608022de6e 100644
--- a/hw/core/uboot_image.h
+++ b/hw/core/uboot_image.h
@@ -124,6 +124,7 @@
#define IH_TYPE_SCRIPT 6 /* Script file */
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
+#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image (noload) */
/*
* Compression Types