QOM/QTest infrastructure fixes and device conversions

* -device / device_add assertion fix
 * QEMUMachine conversion to MachineClass
 * Device error handling improvements
 * QTest cleanups and test cases for some more PCI devices
 * PortIO memory leak fixes
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJTZ9+EAAoJEPou0S0+fgE/wAsP/RymQyMGXbvkzy89UQ+V/y8B
 YWGd+mfdNpic8ofCFP792uVNFhR9IfIEg+ZK4qJ8iI68B4MWXbJtvaAQZm+LrWJJ
 fFMUsI7Cl4mDPpCq5cXVgA1Df7YwarPG5rnq20A2XGFUANaO6pROxNt72K940sW8
 q1O7tMPZ1T//EBAKFYj6UhAbHa+C6vwYQmosaRoZ4uj8NZdP3uCZLKqhAE44QZcc
 nAQwWHsev3Qv0Tvx3DYbOjXZugXiUryKd8yX+PaKyQuHEdCaLjK/eGjMYbhUkqol
 4i44tbjnjUYPnAxZtIrYtDFDepyVaVvsLyP3K+0zHKkWhOl+nlqa+ERnycz2Q1de
 w+FXuftMOf+S/HO1kjv8JBUh4vcgLT77qrE/h1D5thXcTe4jz8WTEB/irUfZl7oa
 dGbSiAPaggrKIf/nBJVDnHaqIdCgMQ/WgNaSsRfKazP1OM04B0F7KKEVPTU9Zo6y
 rDYOKtsL3va+uD8ntf7kBCBjfhmJ2L+IZvI27xc0FISKgg9XXTwX8NhdfvM0/GIC
 F4guEGmralNAIjhBVUy+ajq6E2ku/i04CEfFyofgUVQ2kTcDMwhqSdG2WBjEQs2e
 NsteCfAu7B8EJ3lQa6F856k+/u1FiIRHDR6+Qi/qW2yAjdn3USMm7KWTtQaEQn8Y
 ZE2gvvnMmiWkzTSlmRUz
 =UrRJ
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/afaerber/tags/qom-devices-for-peter' into staging

QOM/QTest infrastructure fixes and device conversions

* -device / device_add assertion fix
* QEMUMachine conversion to MachineClass
* Device error handling improvements
* QTest cleanups and test cases for some more PCI devices
* PortIO memory leak fixes

# gpg: Signature made Mon 05 May 2014 19:59:16 BST using RSA key ID 3E7E013F
# gpg: Good signature from "Andreas Färber <afaerber@suse.de>"
# gpg:                 aka "Andreas Färber <afaerber@suse.com>"

* remotes/afaerber/tags/qom-devices-for-peter:
  PortioList: Store PortioList in device state
  tests: Add EHCI qtest
  tests: Add ioh3420 qtest
  tests: Add intel-hda qtests
  tests: Add es1370 qtest
  tests: Add ac97 qtest
  qtest: Be paranoid about accept() addrlen argument
  qtest: Add error reporting to socket_accept()
  qtest: Assure that init_socket()'s listen() does not fail
  MAINTAINERS: Document QOM
  arm: Clean up fragile use of error_is_set() in realize() methods
  qom: Clean up fragile use of error_is_set() in set() methods
  hw: Consistently name Error ** objects errp, and not err
  hw: Consistently name Error * objects err, and not errp
  machine: Remove QEMUMachine indirection from MachineClass
  machine: Replace QEMUMachine by MachineClass in accelerator configuration
  vl.c: Replace QEMUMachine with MachineClass in QEMUMachineInitArgs
  machine: Copy QEMUMachine's fields to MachineClass
  machine: Remove obsoleted field from QEMUMachine
  qdev: Fix crash by validating the object type

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-05-07 13:47:25 +01:00
commit 7f8fea8b3d
47 changed files with 463 additions and 174 deletions

View File

@ -601,6 +601,7 @@ USB
M: Gerd Hoffmann <kraxel@redhat.com> M: Gerd Hoffmann <kraxel@redhat.com>
S: Maintained S: Maintained
F: hw/usb/* F: hw/usb/*
F: tests/usb-hcd-ehci-test.c
VFIO VFIO
M: Alex Williamson <alex.williamson@redhat.com> M: Alex Williamson <alex.williamson@redhat.com>
@ -666,6 +667,9 @@ M: Gerd Hoffmann <kraxel@redhat.com>
S: Maintained S: Maintained
F: audio/ F: audio/
F: hw/audio/ F: hw/audio/
F: tests/ac97-test.c
F: tests/es1370-test.c
F: tests/intel-hda-test.c
Block Block
M: Kevin Wolf <kwolf@redhat.com> M: Kevin Wolf <kwolf@redhat.com>
@ -780,6 +784,17 @@ S: Supported
F: qapi-schema.json F: qapi-schema.json
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
QOM
M: Anthony Liguori <aliguori@amazon.com>
M: Andreas Färber <afaerber@suse.de>
S: Supported
T: git git://github.com/afaerber/qemu-cpu.git qom-next
F: include/qom/
X: include/qom/cpu.h
F: qom/
X: qom/cpu.c
F: tests/qom-test.c
QMP QMP
M: Luiz Capitulino <lcapitulino@redhat.com> M: Luiz Capitulino <lcapitulino@redhat.com>
S: Maintained S: Maintained

View File

@ -50,6 +50,7 @@ static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
{ {
RngBackend *s = RNG_BACKEND(obj); RngBackend *s = RNG_BACKEND(obj);
RngBackendClass *k = RNG_BACKEND_GET_CLASS(s); RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
Error *local_err = NULL;
if (value == s->opened) { if (value == s->opened) {
return; return;
@ -61,12 +62,14 @@ static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
} }
if (k->opened) { if (k->opened) {
k->opened(s, errp); k->opened(s, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
} }
if (!error_is_set(errp)) { s->opened = true;
s->opened = value;
}
} }
static void rng_backend_init(Object *obj) static void rng_backend_init(Object *obj)

View File

@ -112,6 +112,7 @@ static void tpm_backend_prop_set_opened(Object *obj, bool value, Error **errp)
{ {
TPMBackend *s = TPM_BACKEND(obj); TPMBackend *s = TPM_BACKEND(obj);
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s); TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
Error *local_err = NULL;
if (value == s->opened) { if (value == s->opened) {
return; return;
@ -123,12 +124,14 @@ static void tpm_backend_prop_set_opened(Object *obj, bool value, Error **errp)
} }
if (k->opened) { if (k->opened) {
k->opened(s, errp); k->opened(s, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
} }
if (!error_is_set(errp)) { s->opened = true;
s->opened = value;
}
} }
static void tpm_backend_instance_init(Object *obj) static void tpm_backend_instance_init(Object *obj)

View File

@ -40,7 +40,7 @@ DriveInfo *add_init_drive(const char *optstr)
return NULL; return NULL;
mc = MACHINE_GET_CLASS(current_machine); mc = MACHINE_GET_CLASS(current_machine);
dinfo = drive_init(opts, mc->qemu_machine->block_default_type); dinfo = drive_init(opts, mc->block_default_type);
if (!dinfo) { if (!dinfo) {
qemu_opts_del(opts); qemu_opts_del(opts);
return NULL; return NULL;

View File

@ -86,6 +86,7 @@ typedef struct {
#ifndef HAS_YMF262 #ifndef HAS_YMF262
FM_OPL *opl; FM_OPL *opl;
#endif #endif
PortioList port_list;
} AdlibState; } AdlibState;
static AdlibState *glob_adlib; static AdlibState *glob_adlib;
@ -293,7 +294,6 @@ static MemoryRegionPortio adlib_portio_list[] = {
static void adlib_realizefn (DeviceState *dev, Error **errp) static void adlib_realizefn (DeviceState *dev, Error **errp)
{ {
AdlibState *s = ADLIB(dev); AdlibState *s = ADLIB(dev);
PortioList *port_list = g_new(PortioList, 1);
struct audsettings as; struct audsettings as;
if (glob_adlib) { if (glob_adlib) {
@ -349,8 +349,8 @@ static void adlib_realizefn (DeviceState *dev, Error **errp)
adlib_portio_list[0].offset = s->port; adlib_portio_list[0].offset = s->port;
adlib_portio_list[1].offset = s->port + 8; adlib_portio_list[1].offset = s->port + 8;
portio_list_init (port_list, OBJECT(s), adlib_portio_list, s, "adlib"); portio_list_init (&s->port_list, OBJECT(s), adlib_portio_list, s, "adlib");
portio_list_add (port_list, isa_address_space_io(&s->parent_obj), 0); portio_list_add (&s->port_list, isa_address_space_io(&s->parent_obj), 0);
} }
static Property adlib_properties[] = { static Property adlib_properties[] = {

View File

@ -338,13 +338,13 @@ PropertyInfo qdev_prop_vlan = {
int qdev_prop_set_drive(DeviceState *dev, const char *name, int qdev_prop_set_drive(DeviceState *dev, const char *name,
BlockDriverState *value) BlockDriverState *value)
{ {
Error *errp = NULL; Error *err = NULL;
const char *bdrv_name = value ? bdrv_get_device_name(value) : ""; const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
object_property_set_str(OBJECT(dev), bdrv_name, object_property_set_str(OBJECT(dev), bdrv_name,
name, &errp); name, &err);
if (errp) { if (err) {
qerror_report_err(errp); qerror_report_err(err);
error_free(errp); error_free(err);
return -1; return -1;
} }
return 0; return 0;

View File

@ -751,6 +751,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, void *opaque,
Property *prop = opaque; Property *prop = opaque;
uint32_t *alenptr = qdev_get_prop_ptr(dev, prop); uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
void **arrayptr = (void *)dev + prop->arrayoffset; void **arrayptr = (void *)dev + prop->arrayoffset;
Error *local_err = NULL;
void *eltptr; void *eltptr;
const char *arrayname; const char *arrayname;
int i; int i;
@ -764,8 +765,9 @@ static void set_prop_arraylen(Object *obj, Visitor *v, void *opaque,
name); name);
return; return;
} }
visit_type_uint32(v, alenptr, name, errp); visit_type_uint32(v, alenptr, name, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }
if (!*alenptr) { if (!*alenptr) {
@ -802,8 +804,9 @@ static void set_prop_arraylen(Object *obj, Visitor *v, void *opaque,
arrayprop->prop.info->get, arrayprop->prop.info->get,
arrayprop->prop.info->set, arrayprop->prop.info->set,
array_element_release, array_element_release,
arrayprop, errp); arrayprop, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }
} }

View File

@ -174,14 +174,14 @@ int qdev_init(DeviceState *dev)
return 0; return 0;
} }
static void device_realize(DeviceState *dev, Error **err) static void device_realize(DeviceState *dev, Error **errp)
{ {
DeviceClass *dc = DEVICE_GET_CLASS(dev); DeviceClass *dc = DEVICE_GET_CLASS(dev);
if (dc->init) { if (dc->init) {
int rc = dc->init(dev); int rc = dc->init(dev);
if (rc < 0) { if (rc < 0) {
error_setg(err, "Device initialization failed."); error_setg(errp, "Device initialization failed.");
return; return;
} }
} }
@ -504,14 +504,14 @@ static void bus_unparent(Object *obj)
} }
} }
static bool bus_get_realized(Object *obj, Error **err) static bool bus_get_realized(Object *obj, Error **errp)
{ {
BusState *bus = BUS(obj); BusState *bus = BUS(obj);
return bus->realized; return bus->realized;
} }
static void bus_set_realized(Object *obj, bool value, Error **err) static void bus_set_realized(Object *obj, bool value, Error **errp)
{ {
BusState *bus = BUS(obj); BusState *bus = BUS(obj);
BusClass *bc = BUS_GET_CLASS(bus); BusClass *bc = BUS_GET_CLASS(bus);
@ -540,7 +540,7 @@ static void bus_set_realized(Object *obj, bool value, Error **err)
return; return;
error: error:
error_propagate(err, local_err); error_propagate(errp, local_err);
} }
void qbus_create_inplace(void *bus, size_t size, const char *typename, void qbus_create_inplace(void *bus, size_t size, const char *typename,
@ -724,13 +724,13 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
} }
} }
static bool device_get_realized(Object *obj, Error **err) static bool device_get_realized(Object *obj, Error **errp)
{ {
DeviceState *dev = DEVICE(obj); DeviceState *dev = DEVICE(obj);
return dev->realized; return dev->realized;
} }
static void device_set_realized(Object *obj, bool value, Error **err) static void device_set_realized(Object *obj, bool value, Error **errp)
{ {
DeviceState *dev = DEVICE(obj); DeviceState *dev = DEVICE(obj);
DeviceClass *dc = DEVICE_GET_CLASS(dev); DeviceClass *dc = DEVICE_GET_CLASS(dev);
@ -738,7 +738,7 @@ static void device_set_realized(Object *obj, bool value, Error **err)
Error *local_err = NULL; Error *local_err = NULL;
if (dev->hotplugged && !dc->hotpluggable) { if (dev->hotplugged && !dc->hotpluggable) {
error_set(err, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj)); error_set(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
return; return;
} }
@ -797,14 +797,14 @@ static void device_set_realized(Object *obj, bool value, Error **err)
} }
if (local_err != NULL) { if (local_err != NULL) {
error_propagate(err, local_err); error_propagate(errp, local_err);
return; return;
} }
dev->realized = value; dev->realized = value;
} }
static bool device_get_hotpluggable(Object *obj, Error **err) static bool device_get_hotpluggable(Object *obj, Error **errp)
{ {
DeviceClass *dc = DEVICE_GET_CLASS(obj); DeviceClass *dc = DEVICE_GET_CLASS(obj);
DeviceState *dev = DEVICE(obj); DeviceState *dev = DEVICE(obj);

View File

@ -2055,7 +2055,6 @@ static int qxl_init_primary(PCIDevice *dev)
{ {
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev); PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
VGACommonState *vga = &qxl->vga; VGACommonState *vga = &qxl->vga;
PortioList *qxl_vga_port_list = g_new(PortioList, 1);
int rc; int rc;
qxl->id = 0; qxl->id = 0;
@ -2064,10 +2063,10 @@ static int qxl_init_primary(PCIDevice *dev)
vga_common_init(vga, OBJECT(dev), true); vga_common_init(vga, OBJECT(dev), true);
vga_init(vga, OBJECT(dev), vga_init(vga, OBJECT(dev),
pci_address_space(dev), pci_address_space_io(dev), false); pci_address_space(dev), pci_address_space_io(dev), false);
portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list, portio_list_init(&qxl->vga_port_list, OBJECT(dev), qxl_vga_portio_list,
vga, "vga"); vga, "vga");
portio_list_set_flush_coalesced(qxl_vga_port_list); portio_list_set_flush_coalesced(&qxl->vga_port_list);
portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0); portio_list_add(&qxl->vga_port_list, pci_address_space_io(dev), 0x3b0);
vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl); vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
qemu_spice_display_init_common(&qxl->ssd); qemu_spice_display_init_common(&qxl->ssd);

View File

@ -32,6 +32,7 @@ enum qxl_mode {
typedef struct PCIQXLDevice { typedef struct PCIQXLDevice {
PCIDevice pci; PCIDevice pci;
PortioList vga_port_list;
SimpleSpiceDisplay ssd; SimpleSpiceDisplay ssd;
int id; int id;
uint32_t debug; uint32_t debug;

View File

@ -2355,8 +2355,6 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
{ {
MemoryRegion *vga_io_memory; MemoryRegion *vga_io_memory;
const MemoryRegionPortio *vga_ports, *vbe_ports; const MemoryRegionPortio *vga_ports, *vbe_ports;
PortioList *vga_port_list = g_new(PortioList, 1);
PortioList *vbe_port_list = g_new(PortioList, 1);
qemu_register_reset(vga_reset, s); qemu_register_reset(vga_reset, s);
@ -2371,13 +2369,13 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
1); 1);
memory_region_set_coalescing(vga_io_memory); memory_region_set_coalescing(vga_io_memory);
if (init_vga_ports) { if (init_vga_ports) {
portio_list_init(vga_port_list, obj, vga_ports, s, "vga"); portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
portio_list_set_flush_coalesced(vga_port_list); portio_list_set_flush_coalesced(&s->vga_port_list);
portio_list_add(vga_port_list, address_space_io, 0x3b0); portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
} }
if (vbe_ports) { if (vbe_ports) {
portio_list_init(vbe_port_list, obj, vbe_ports, s, "vbe"); portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
portio_list_add(vbe_port_list, address_space_io, 0x1ce); portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
} }
} }

View File

@ -124,6 +124,8 @@ typedef struct VGACommonState {
void (*get_resolution)(struct VGACommonState *s, void (*get_resolution)(struct VGACommonState *s,
int *pwidth, int *pwidth,
int *pheight); int *pheight);
PortioList vga_port_list;
PortioList vbe_port_list;
/* bochs vbe state */ /* bochs vbe state */
uint16_t vbe_index; uint16_t vbe_index;
uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; uint16_t vbe_regs[VBE_DISPI_INDEX_NB];

View File

@ -39,6 +39,7 @@ do { fprintf(stderr, "i82374 ERROR: " fmt , ## __VA_ARGS__); } while (0)
typedef struct I82374State { typedef struct I82374State {
uint8_t commands[8]; uint8_t commands[8];
qemu_irq out; qemu_irq out;
PortioList port_list;
} I82374State; } I82374State;
static const VMStateDescription vmstate_i82374 = { static const VMStateDescription vmstate_i82374 = {
@ -137,10 +138,10 @@ static void i82374_isa_realize(DeviceState *dev, Error **errp)
{ {
ISAi82374State *isa = I82374(dev); ISAi82374State *isa = I82374(dev);
I82374State *s = &isa->state; I82374State *s = &isa->state;
PortioList *port_list = g_new(PortioList, 1);
portio_list_init(port_list, OBJECT(isa), i82374_portio_list, s, "i82374"); portio_list_init(&s->port_list, OBJECT(isa), i82374_portio_list, s,
portio_list_add(port_list, isa_address_space_io(&isa->parent_obj), "i82374");
portio_list_add(&s->port_list, isa_address_space_io(&isa->parent_obj),
isa->iobase); isa->iobase);
i82374_realize(s, errp); i82374_realize(s, errp);

View File

@ -534,24 +534,24 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev); XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev);
XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM( XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
&s->rx_control_dev); &s->rx_control_dev);
Error *local_errp = NULL; Error *local_err = NULL;
object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA, object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
(Object **)&ds->dma, (Object **)&ds->dma,
object_property_allow_set_link, object_property_allow_set_link,
OBJ_PROP_LINK_UNREF_ON_RELEASE, OBJ_PROP_LINK_UNREF_ON_RELEASE,
&local_errp); &local_err);
object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA, object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA,
(Object **)&cs->dma, (Object **)&cs->dma,
object_property_allow_set_link, object_property_allow_set_link,
OBJ_PROP_LINK_UNREF_ON_RELEASE, OBJ_PROP_LINK_UNREF_ON_RELEASE,
&local_errp); &local_err);
if (local_errp) { if (local_err) {
goto xilinx_axidma_realize_fail; goto xilinx_axidma_realize_fail;
} }
object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &local_errp); object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &local_err);
object_property_set_link(OBJECT(cs), OBJECT(s), "dma", &local_errp); object_property_set_link(OBJECT(cs), OBJECT(s), "dma", &local_err);
if (local_errp) { if (local_err) {
goto xilinx_axidma_realize_fail; goto xilinx_axidma_realize_fail;
} }
@ -567,7 +567,7 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
xilinx_axidma_realize_fail: xilinx_axidma_realize_fail:
if (!*errp) { if (!*errp) {
*errp = local_errp; *errp = local_err;
} }
} }

View File

@ -797,9 +797,11 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
GICState *s = ARM_GIC(dev); GICState *s = ARM_GIC(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
ARMGICClass *agc = ARM_GIC_GET_CLASS(s); ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
Error *local_err = NULL;
agc->parent_realize(dev, errp); agc->parent_realize(dev, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }

View File

@ -517,10 +517,12 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
GICState *s = KVM_ARM_GIC(dev); GICState *s = KVM_ARM_GIC(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s); KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
Error *local_err = NULL;
int ret; int ret;
kgc->parent_realize(dev, errp); kgc->parent_realize(dev, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }

View File

@ -474,14 +474,16 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
{ {
nvic_state *s = NVIC(dev); nvic_state *s = NVIC(dev);
NVICClass *nc = NVIC_GET_CLASS(s); NVICClass *nc = NVIC_GET_CLASS(s);
Error *local_err = NULL;
/* The NVIC always has only one CPU */ /* The NVIC always has only one CPU */
s->gic.num_cpu = 1; s->gic.num_cpu = 1;
/* Tell the common code we're an NVIC */ /* Tell the common code we're an NVIC */
s->gic.revision = 0xffffffff; s->gic.revision = 0xffffffff;
s->num_irq = s->gic.num_irq; s->num_irq = s->gic.num_irq;
nc->parent_realize(dev, errp); nc->parent_realize(dev, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }
gic_init_irqs_and_distributor(&s->gic, s->num_irq); gic_init_irqs_and_distributor(&s->gic, s->num_irq);

View File

@ -412,7 +412,7 @@ static const MemoryRegionOps pic_elcr_ioport_ops = {
}, },
}; };
static void pic_realize(DeviceState *dev, Error **err) static void pic_realize(DeviceState *dev, Error **errp)
{ {
PICCommonState *s = PIC_COMMON(dev); PICCommonState *s = PIC_COMMON(dev);
PICClass *pc = PIC_GET_CLASS(dev); PICClass *pc = PIC_GET_CLASS(dev);
@ -425,7 +425,7 @@ static void pic_realize(DeviceState *dev, Error **err)
qdev_init_gpio_out(dev, s->int_out, ARRAY_SIZE(s->int_out)); qdev_init_gpio_out(dev, s->int_out, ARRAY_SIZE(s->int_out));
qdev_init_gpio_in(dev, pic_set_irq, 8); qdev_init_gpio_in(dev, pic_set_irq, 8);
pc->parent_realize(dev, err); pc->parent_realize(dev, errp);
} }
void pic_info(Monitor *mon, const QDict *qdict) void pic_info(Monitor *mon, const QDict *qdict)

View File

@ -108,15 +108,20 @@ void isa_register_portio_list(ISADevice *dev, uint16_t start,
const MemoryRegionPortio *pio_start, const MemoryRegionPortio *pio_start,
void *opaque, const char *name) void *opaque, const char *name)
{ {
PortioList *piolist = g_new(PortioList, 1); PortioList piolist;
/* START is how we should treat DEV, regardless of the actual /* START is how we should treat DEV, regardless of the actual
contents of the portio array. This is how the old code contents of the portio array. This is how the old code
actually handled e.g. the FDC device. */ actually handled e.g. the FDC device. */
isa_init_ioport(dev, start); isa_init_ioport(dev, start);
portio_list_init(piolist, OBJECT(dev), pio_start, opaque, name); /* FIXME: the device should store created PortioList in its state. Note
portio_list_add(piolist, isabus->address_space_io, start); that DEV can be NULL here and that single device can register several
portio lists. Current implementation is leaking memory allocated
in portio_list_init. The leak is not critical because it happens only
at initialization time. */
portio_list_init(&piolist, OBJECT(dev), pio_start, opaque, name);
portio_list_add(&piolist, isabus->address_space_io, start);
} }
static void isa_device_init(Object *obj) static void isa_device_init(Object *obj)

View File

@ -68,10 +68,12 @@ static void tmp105_set_temperature(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
TMP105State *s = TMP105(obj); TMP105State *s = TMP105(obj);
Error *local_err = NULL;
int64_t temp; int64_t temp;
visit_type_int(v, &temp, name, errp); visit_type_int(v, &temp, name, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }
if (temp >= 128000 || temp < -128000) { if (temp >= 128000 || temp < -128000) {

View File

@ -945,24 +945,24 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev); XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev);
XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM( XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(
&s->rx_control_dev); &s->rx_control_dev);
Error *local_errp = NULL; Error *local_err = NULL;
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet", object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
(Object **) &ds->enet, (Object **) &ds->enet,
object_property_allow_set_link, object_property_allow_set_link,
OBJ_PROP_LINK_UNREF_ON_RELEASE, OBJ_PROP_LINK_UNREF_ON_RELEASE,
&local_errp); &local_err);
object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet", object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet",
(Object **) &cs->enet, (Object **) &cs->enet,
object_property_allow_set_link, object_property_allow_set_link,
OBJ_PROP_LINK_UNREF_ON_RELEASE, OBJ_PROP_LINK_UNREF_ON_RELEASE,
&local_errp); &local_err);
if (local_errp) { if (local_err) {
goto xilinx_enet_realize_fail; goto xilinx_enet_realize_fail;
} }
object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_errp); object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_err);
object_property_set_link(OBJECT(cs), OBJECT(s), "enet", &local_errp); object_property_set_link(OBJECT(cs), OBJECT(s), "enet", &local_err);
if (local_errp) { if (local_err) {
goto xilinx_enet_realize_fail; goto xilinx_enet_realize_fail;
} }
@ -981,7 +981,7 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
xilinx_enet_realize_fail: xilinx_enet_realize_fail:
if (!*errp) { if (!*errp) {
*errp = local_errp; *errp = local_err;
} }
} }

View File

@ -361,6 +361,8 @@ static const MemoryRegionPortio prep_portio_list[] = {
PORTIO_END_OF_LIST(), PORTIO_END_OF_LIST(),
}; };
static PortioList prep_port_list;
/* PowerPC PREP hardware initialisation */ /* PowerPC PREP hardware initialisation */
static void ppc_prep_init(QEMUMachineInitArgs *args) static void ppc_prep_init(QEMUMachineInitArgs *args)
{ {
@ -375,7 +377,6 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
CPUPPCState *env = NULL; CPUPPCState *env = NULL;
nvram_t nvram; nvram_t nvram;
M48t59State *m48t59; M48t59State *m48t59;
PortioList *port_list = g_new(PortioList, 1);
#if 0 #if 0
MemoryRegion *xcsr = g_new(MemoryRegion, 1); MemoryRegion *xcsr = g_new(MemoryRegion, 1);
#endif #endif
@ -542,8 +543,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
cpu = POWERPC_CPU(first_cpu); cpu = POWERPC_CPU(first_cpu);
sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET]; sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];
portio_list_init(port_list, NULL, prep_portio_list, sysctrl, "prep"); portio_list_init(&prep_port_list, NULL, prep_portio_list, sysctrl, "prep");
portio_list_add(port_list, isa_address_space_io(isa), 0x0); portio_list_add(&prep_port_list, isa_address_space_io(isa), 0x0);
/* PowerPC control and status register group */ /* PowerPC control and status register group */
#if 0 #if 0

View File

@ -1419,19 +1419,6 @@ static int spapr_kvm_type(const char *vm_type)
exit(1); exit(1);
} }
static QEMUMachine spapr_machine = {
.name = "pseries",
.desc = "pSeries Logical Partition (PAPR compliant)",
.is_default = 1,
.init = ppc_spapr_init,
.reset = ppc_spapr_reset,
.block_default_type = IF_SCSI,
.max_cpus = MAX_CPUS,
.no_parallel = 1,
.default_boot_order = NULL,
.kvm_type = spapr_kvm_type,
};
/* /*
* Implementation of an interface to adjust firmware patch * Implementation of an interface to adjust firmware patch
* for the bootindex property handling. * for the bootindex property handling.
@ -1494,7 +1481,17 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
MachineClass *mc = MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc);
FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
mc->qemu_machine = data; mc->name = "pseries";
mc->desc = "pSeries Logical Partition (PAPR compliant)";
mc->is_default = 1;
mc->init = ppc_spapr_init;
mc->reset = ppc_spapr_reset;
mc->block_default_type = IF_SCSI;
mc->max_cpus = MAX_CPUS;
mc->no_parallel = 1;
mc->default_boot_order = NULL;
mc->kvm_type = spapr_kvm_type;
fwc->get_dev_path = spapr_get_fw_dev_path; fwc->get_dev_path = spapr_get_fw_dev_path;
} }
@ -1502,7 +1499,6 @@ static const TypeInfo spapr_machine_info = {
.name = TYPE_SPAPR_MACHINE, .name = TYPE_SPAPR_MACHINE,
.parent = TYPE_MACHINE, .parent = TYPE_MACHINE,
.class_init = spapr_machine_class_init, .class_init = spapr_machine_class_init,
.class_data = &spapr_machine,
.interfaces = (InterfaceInfo[]) { .interfaces = (InterfaceInfo[]) {
{ TYPE_FW_PATH_PROVIDER }, { TYPE_FW_PATH_PROVIDER },
{ } { }

View File

@ -322,7 +322,7 @@ static void pit_post_load(PITCommonState *s)
} }
} }
static void pit_realizefn(DeviceState *dev, Error **err) static void pit_realizefn(DeviceState *dev, Error **errp)
{ {
PITCommonState *pit = PIT_COMMON(dev); PITCommonState *pit = PIT_COMMON(dev);
PITClass *pc = PIT_GET_CLASS(dev); PITClass *pc = PIT_GET_CLASS(dev);
@ -338,7 +338,7 @@ static void pit_realizefn(DeviceState *dev, Error **err)
qdev_init_gpio_in(dev, pit_irq_control, 1); qdev_init_gpio_in(dev, pit_irq_control, 1);
pc->parent_realize(dev, err); pc->parent_realize(dev, errp);
} }
static Property pit_properties[] = { static Property pit_properties[] = {

View File

@ -142,10 +142,12 @@ static void balloon_stats_set_poll_interval(Object *obj, struct Visitor *v,
Error **errp) Error **errp)
{ {
VirtIOBalloon *s = opaque; VirtIOBalloon *s = opaque;
Error *local_err = NULL;
int64_t value; int64_t value;
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }

View File

@ -42,6 +42,8 @@ typedef struct IB700state {
ISADevice parent_obj; ISADevice parent_obj;
QEMUTimer *timer; QEMUTimer *timer;
PortioList port_list;
} IB700State; } IB700State;
/* This is the timer. We use a global here because the watchdog /* This is the timer. We use a global here because the watchdog
@ -106,14 +108,13 @@ static const MemoryRegionPortio wdt_portio_list[] = {
static void wdt_ib700_realize(DeviceState *dev, Error **errp) static void wdt_ib700_realize(DeviceState *dev, Error **errp)
{ {
IB700State *s = IB700(dev); IB700State *s = IB700(dev);
PortioList *port_list = g_new(PortioList, 1);
ib700_debug("watchdog init\n"); ib700_debug("watchdog init\n");
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ib700_timer_expired, s); s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ib700_timer_expired, s);
portio_list_init(port_list, OBJECT(s), wdt_portio_list, s, "ib700"); portio_list_init(&s->port_list, OBJECT(s), wdt_portio_list, s, "ib700");
portio_list_add(port_list, isa_address_space_io(&s->parent_obj), 0); portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj), 0);
} }
static void wdt_ib700_reset(DeviceState *dev) static void wdt_ib700_reset(DeviceState *dev)

View File

@ -3,12 +3,13 @@
#ifndef HW_BOARDS_H #ifndef HW_BOARDS_H
#define HW_BOARDS_H #define HW_BOARDS_H
#include "qemu/typedefs.h"
#include "sysemu/blockdev.h" #include "sysemu/blockdev.h"
#include "hw/qdev.h" #include "hw/qdev.h"
#include "qom/object.h" #include "qom/object.h"
typedef struct QEMUMachineInitArgs { typedef struct QEMUMachineInitArgs {
const QEMUMachine *machine; const MachineClass *machine;
ram_addr_t ram_size; ram_addr_t ram_size;
const char *boot_order; const char *boot_order;
const char *kernel_filename; const char *kernel_filename;
@ -46,7 +47,6 @@ struct QEMUMachine {
const char *default_machine_opts; const char *default_machine_opts;
const char *default_boot_order; const char *default_boot_order;
GlobalProperty *compat_props; GlobalProperty *compat_props;
struct QEMUMachine *next;
const char *hw_version; const char *hw_version;
}; };
@ -63,7 +63,6 @@ int qemu_register_machine(QEMUMachine *m);
OBJECT_CLASS_CHECK(MachineClass, (klass), TYPE_MACHINE) OBJECT_CLASS_CHECK(MachineClass, (klass), TYPE_MACHINE)
typedef struct MachineState MachineState; typedef struct MachineState MachineState;
typedef struct MachineClass MachineClass;
MachineClass *find_default_machine(void); MachineClass *find_default_machine(void);
extern MachineState *current_machine; extern MachineState *current_machine;
@ -77,7 +76,29 @@ struct MachineClass {
ObjectClass parent_class; ObjectClass parent_class;
/*< public >*/ /*< public >*/
QEMUMachine *qemu_machine; const char *name;
const char *alias;
const char *desc;
void (*init)(QEMUMachineInitArgs *args);
void (*reset)(void);
void (*hot_add_cpu)(const int64_t id, Error **errp);
int (*kvm_type)(const char *arg);
BlockInterfaceType block_default_type;
int max_cpus;
unsigned int no_serial:1,
no_parallel:1,
use_virtcon:1,
use_sclp:1,
no_floppy:1,
no_cdrom:1,
no_sdcard:1;
int is_default;
const char *default_machine_opts;
const char *default_boot_order;
GlobalProperty *compat_props;
const char *hw_version;
}; };
/** /**

View File

@ -36,7 +36,7 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
qemu_irq *xen_interrupt_controller_init(void); qemu_irq *xen_interrupt_controller_init(void);
int xen_init(QEMUMachine *machine); int xen_init(MachineClass *mc);
int xen_hvm_init(MemoryRegion **ram_memory); int xen_hvm_init(MemoryRegion **ram_memory);
void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);

View File

@ -31,6 +31,7 @@ typedef struct MemoryListener MemoryListener;
typedef struct MemoryMappingList MemoryMappingList; typedef struct MemoryMappingList MemoryMappingList;
typedef struct QEMUMachine QEMUMachine; typedef struct QEMUMachine QEMUMachine;
typedef struct MachineClass MachineClass;
typedef struct NICInfo NICInfo; typedef struct NICInfo NICInfo;
typedef struct HCIInfo HCIInfo; typedef struct HCIInfo HCIInfo;
typedef struct AudioState AudioState; typedef struct AudioState AudioState;

View File

@ -152,7 +152,7 @@ extern KVMState *kvm_state;
/* external API */ /* external API */
int kvm_init(QEMUMachine *machine); int kvm_init(MachineClass *mc);
int kvm_has_sync_mmu(void); int kvm_has_sync_mmu(void);
int kvm_has_vcpu_events(void); int kvm_has_vcpu_events(void);

View File

@ -26,7 +26,7 @@ static inline bool qtest_enabled(void)
bool qtest_driver(void); bool qtest_driver(void);
int qtest_init_accel(QEMUMachine *machine); int qtest_init_accel(MachineClass *mc);
void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp); void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
static inline int qtest_available(void) static inline int qtest_available(void)

View File

@ -1341,7 +1341,7 @@ static int kvm_max_vcpus(KVMState *s)
return (ret) ? ret : kvm_recommended_vcpus(s); return (ret) ? ret : kvm_recommended_vcpus(s);
} }
int kvm_init(QEMUMachine *machine) int kvm_init(MachineClass *mc)
{ {
static const char upgrade_note[] = static const char upgrade_note[] =
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n" "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
@ -1433,8 +1433,8 @@ int kvm_init(QEMUMachine *machine)
} }
kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type"); kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
if (machine->kvm_type) { if (mc->kvm_type) {
type = machine->kvm_type(kvm_type); type = mc->kvm_type(kvm_type);
} else if (kvm_type) { } else if (kvm_type) {
fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type); fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
goto err; goto err;

View File

@ -34,7 +34,7 @@ int kvm_init_vcpu(CPUState *cpu)
return -ENOSYS; return -ENOSYS;
} }
int kvm_init(QEMUMachine *machine) int kvm_init(MachineClass *mc)
{ {
return -ENOSYS; return -ENOSYS;
} }

View File

@ -206,7 +206,7 @@ int qdev_device_help(QemuOpts *opts)
} }
} }
if (!klass) { if (!object_class_dynamic_cast(klass, TYPE_DEVICE)) {
return 0; return 0;
} }
do { do {

4
qmp.c
View File

@ -117,8 +117,8 @@ void qmp_cpu_add(int64_t id, Error **errp)
MachineClass *mc; MachineClass *mc;
mc = MACHINE_GET_CLASS(current_machine); mc = MACHINE_GET_CLASS(current_machine);
if (mc->qemu_machine->hot_add_cpu) { if (mc->hot_add_cpu) {
mc->qemu_machine->hot_add_cpu(id, errp); mc->hot_add_cpu(id, errp);
} else { } else {
error_setg(errp, "Not supported"); error_setg(errp, "Not supported");
} }

View File

@ -500,7 +500,7 @@ static void qtest_event(void *opaque, int event)
} }
} }
int qtest_init_accel(QEMUMachine *machine) int qtest_init_accel(MachineClass *mc)
{ {
configure_icount("0"); configure_icount("0");

View File

@ -1300,10 +1300,12 @@ static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
const int64_t min = 0; const int64_t min = 0;
const int64_t max = 0xff + 0xf; const int64_t max = 0xff + 0xf;
Error *local_err = NULL;
int64_t value; int64_t value;
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }
if (value < min || value > max) { if (value < min || value > max) {
@ -1339,10 +1341,12 @@ static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
const int64_t min = 0; const int64_t min = 0;
const int64_t max = 0xff; const int64_t max = 0xff;
Error *local_err = NULL;
int64_t value; int64_t value;
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }
if (value < min || value > max) { if (value < min || value > max) {
@ -1375,10 +1379,12 @@ static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
const int64_t min = 0; const int64_t min = 0;
const int64_t max = 0xf; const int64_t max = 0xf;
Error *local_err = NULL;
int64_t value; int64_t value;
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }
if (value < min || value > max) { if (value < min || value > max) {
@ -1511,10 +1517,12 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
X86CPU *cpu = X86_CPU(obj); X86CPU *cpu = X86_CPU(obj);
const int64_t min = 0; const int64_t min = 0;
const int64_t max = INT64_MAX; const int64_t max = INT64_MAX;
Error *local_err = NULL;
int64_t value; int64_t value;
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, &local_err);
if (error_is_set(errp)) { if (local_err) {
error_propagate(errp, local_err);
return; return;
} }
if (value < min || value > max) { if (value < min || value > max) {

View File

@ -107,6 +107,10 @@ check-qtest-pci-y += tests/ne2000-test$(EXESUF)
gcov-files-pci-y += hw/net/ne2000.c gcov-files-pci-y += hw/net/ne2000.c
check-qtest-pci-y += tests/nvme-test$(EXESUF) check-qtest-pci-y += tests/nvme-test$(EXESUF)
gcov-files-pci-y += hw/block/nvme.c gcov-files-pci-y += hw/block/nvme.c
check-qtest-pci-y += tests/ac97-test$(EXESUF)
gcov-files-pci-y += hw/audio/ac97.c
check-qtest-pci-y += tests/es1370-test$(EXESUF)
gcov-files-pci-y += hw/audio/es1370.c
check-qtest-pci-y += $(check-qtest-virtio-y) check-qtest-pci-y += $(check-qtest-virtio-y)
gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c
check-qtest-pci-y += tests/tpci200-test$(EXESUF) check-qtest-pci-y += tests/tpci200-test$(EXESUF)
@ -117,6 +121,8 @@ check-qtest-pci-y += tests/display-vga-test$(EXESUF)
gcov-files-pci-y += hw/display/vga.c gcov-files-pci-y += hw/display/vga.c
gcov-files-pci-y += hw/display/cirrus_vga.c gcov-files-pci-y += hw/display/cirrus_vga.c
gcov-files-pci-y += hw/display/vga-pci.c gcov-files-pci-y += hw/display/vga-pci.c
check-qtest-pci-y += tests/intel-hda-test$(EXESUF)
gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c
check-qtest-i386-y = tests/endianness-test$(EXESUF) check-qtest-i386-y = tests/endianness-test$(EXESUF)
check-qtest-i386-y += tests/fdc-test$(EXESUF) check-qtest-i386-y += tests/fdc-test$(EXESUF)
@ -141,6 +147,11 @@ check-qtest-i386-y += tests/pvpanic-test$(EXESUF)
gcov-files-i386-y += i386-softmmu/hw/misc/pvpanic.c gcov-files-i386-y += i386-softmmu/hw/misc/pvpanic.c
check-qtest-i386-y += tests/i82801b11-test$(EXESUF) check-qtest-i386-y += tests/i82801b11-test$(EXESUF)
gcov-files-i386-y += hw/pci-bridge/i82801b11.c gcov-files-i386-y += hw/pci-bridge/i82801b11.c
check-qtest-i386-y += tests/ioh3420-test$(EXESUF)
gcov-files-i386-y += hw/pci-bridge/ioh3420.c
check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF)
gcov-files-i386-y += hw/usb/hcd-ehci.c
gcov-files-i386-y += hw/usb/hcd-uhci.c
check-qtest-x86_64-y = $(check-qtest-i386-y) check-qtest-x86_64-y = $(check-qtest-i386-y)
gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@ -292,6 +303,11 @@ tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
tests/nvme-test$(EXESUF): tests/nvme-test.o tests/nvme-test$(EXESUF): tests/nvme-test.o
tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o
tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o
tests/ac97-test$(EXESUF): tests/ac97-test.o
tests/es1370-test$(EXESUF): tests/es1370-test.o
tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o
tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o
tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o
tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
# QTest rules # QTest rules

33
tests/ac97-test.c Normal file
View File

@ -0,0 +1,33 @@
/*
* QTest testcase for AC97
*
* Copyright (c) 2014 SUSE LINUX Products GmbH
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include <glib.h>
#include <string.h>
#include "libqtest.h"
#include "qemu/osdep.h"
/* Tests only initialization so far. TODO: Replace with functional tests */
static void nop(void)
{
}
int main(int argc, char **argv)
{
int ret;
g_test_init(&argc, &argv, NULL);
qtest_add_func("/ac97/nop", nop);
qtest_start("-device AC97");
ret = g_test_run();
qtest_end();
return ret;
}

33
tests/es1370-test.c Normal file
View File

@ -0,0 +1,33 @@
/*
* QTest testcase for ES1370
*
* Copyright (c) 2014 SUSE LINUX Products GmbH
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include <glib.h>
#include <string.h>
#include "libqtest.h"
#include "qemu/osdep.h"
/* Tests only initialization so far. TODO: Replace with functional tests */
static void nop(void)
{
}
int main(int argc, char **argv)
{
int ret;
g_test_init(&argc, &argv, NULL);
qtest_add_func("/es1370/nop", nop);
qtest_start("-device ES1370");
ret = g_test_run();
qtest_end();
return ret;
}

45
tests/intel-hda-test.c Normal file
View File

@ -0,0 +1,45 @@
/*
* QTest testcase for Intel HDA
*
* Copyright (c) 2014 SUSE LINUX Products GmbH
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include <glib.h>
#include <string.h>
#include "libqtest.h"
#include "qemu/osdep.h"
#define HDA_ID "hda0"
#define CODEC_DEVICES " -device hda-output,bus=" HDA_ID ".0" \
" -device hda-micro,bus=" HDA_ID ".0" \
" -device hda-duplex,bus=" HDA_ID ".0"
/* Tests only initialization so far. TODO: Replace with functional tests */
static void ich6_test(void)
{
qtest_start("-device intel-hda,id=" HDA_ID CODEC_DEVICES);
qtest_end();
}
static void ich9_test(void)
{
qtest_start("-machine q35 -device ich9-intel-hda,bus=pcie.0,addr=1b.0,id="
HDA_ID CODEC_DEVICES);
qtest_end();
}
int main(int argc, char **argv)
{
int ret;
g_test_init(&argc, &argv, NULL);
qtest_add_func("/intel-hda/ich6", ich6_test);
qtest_add_func("/intel-hda/ich9", ich9_test);
ret = g_test_run();
return ret;
}

34
tests/ioh3420-test.c Normal file
View File

@ -0,0 +1,34 @@
/*
* QTest testcase for Intel X58 north bridge IOH
*
* Copyright (c) 2014 SUSE LINUX Products GmbH
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include <glib.h>
#include <string.h>
#include "libqtest.h"
#include "qemu/osdep.h"
/* Tests only initialization so far. TODO: Replace with functional tests */
static void nop(void)
{
}
int main(int argc, char **argv)
{
int ret;
g_test_init(&argc, &argv, NULL);
qtest_add_func("/ioh3420/nop", nop);
qtest_start("-machine q35 -device ioh3420,bus=pcie.0,addr=1c.0,port=1,"
"chassis=1,multifunction=on");
ret = g_test_run();
qtest_end();
return ret;
}

View File

@ -72,7 +72,8 @@ static int init_socket(const char *socket_path)
ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr)); ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
} while (ret == -1 && errno == EINTR); } while (ret == -1 && errno == EINTR);
g_assert_no_errno(ret); g_assert_no_errno(ret);
listen(sock, 1); ret = listen(sock, 1);
g_assert_no_errno(ret);
return sock; return sock;
} }
@ -88,10 +89,13 @@ static int socket_accept(int sock)
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout,
sizeof(timeout)); sizeof(timeout));
addrlen = sizeof(addr);
do { do {
addrlen = sizeof(addr);
ret = accept(sock, (struct sockaddr *)&addr, &addrlen); ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
} while (ret == -1 && errno == EINTR); } while (ret == -1 && errno == EINTR);
if (ret == -1) {
fprintf(stderr, "%s failed: %s\n", __func__, strerror(errno));
}
close(sock); close(sock);
return ret; return ret;

40
tests/usb-hcd-ehci-test.c Normal file
View File

@ -0,0 +1,40 @@
/*
* QTest testcase for USB EHCI
*
* Copyright (c) 2014 SUSE LINUX Products GmbH
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include <glib.h>
#include <string.h>
#include "libqtest.h"
#include "qemu/osdep.h"
/* Tests only initialization so far. TODO: Replace with functional tests */
static void pci_nop(void)
{
}
int main(int argc, char **argv)
{
int ret;
g_test_init(&argc, &argv, NULL);
qtest_add_func("/ehci/pci/nop", pci_nop);
qtest_start("-machine q35 -device ich9-usb-ehci1,bus=pcie.0,addr=1d.7,"
"multifunction=on,id=ich9-ehci-1 "
"-device ich9-usb-uhci1,bus=pcie.0,addr=1d.0,"
"multifunction=on,masterbus=ich9-ehci-1.0,firstport=0 "
"-device ich9-usb-uhci2,bus=pcie.0,addr=1d.1,"
"multifunction=on,masterbus=ich9-ehci-1.0,firstport=2 "
"-device ich9-usb-uhci3,bus=pcie.0,addr=1d.2,"
"multifunction=on,masterbus=ich9-ehci-1.0,firstport=4");
ret = g_test_run();
qtest_end();
return ret;
}

112
vl.c
View File

@ -1588,8 +1588,29 @@ MachineState *current_machine;
static void machine_class_init(ObjectClass *oc, void *data) static void machine_class_init(ObjectClass *oc, void *data)
{ {
MachineClass *mc = MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc);
QEMUMachine *qm = data;
mc->qemu_machine = data; mc->name = qm->name;
mc->alias = qm->alias;
mc->desc = qm->desc;
mc->init = qm->init;
mc->reset = qm->reset;
mc->hot_add_cpu = qm->hot_add_cpu;
mc->kvm_type = qm->kvm_type;
mc->block_default_type = qm->block_default_type;
mc->max_cpus = qm->max_cpus;
mc->no_serial = qm->no_serial;
mc->no_parallel = qm->no_parallel;
mc->use_virtcon = qm->use_virtcon;
mc->use_sclp = qm->use_sclp;
mc->no_floppy = qm->no_floppy;
mc->no_cdrom = qm->no_cdrom;
mc->no_sdcard = qm->no_sdcard;
mc->is_default = qm->is_default;
mc->default_machine_opts = qm->default_machine_opts;
mc->default_boot_order = qm->default_boot_order;
mc->compat_props = qm->compat_props;
mc->hw_version = qm->hw_version;
} }
int qemu_register_machine(QEMUMachine *m) int qemu_register_machine(QEMUMachine *m)
@ -1616,12 +1637,12 @@ static MachineClass *find_machine(const char *name)
for (el = machines; el; el = el->next) { for (el = machines; el; el = el->next) {
MachineClass *temp = el->data; MachineClass *temp = el->data;
if (!strcmp(temp->qemu_machine->name, name)) { if (!strcmp(temp->name, name)) {
mc = temp; mc = temp;
break; break;
} }
if (temp->qemu_machine->alias && if (temp->alias &&
!strcmp(temp->qemu_machine->alias, name)) { !strcmp(temp->alias, name)) {
mc = temp; mc = temp;
break; break;
} }
@ -1639,7 +1660,7 @@ MachineClass *find_default_machine(void)
for (el = machines; el; el = el->next) { for (el = machines; el; el = el->next) {
MachineClass *temp = el->data; MachineClass *temp = el->data;
if (temp->qemu_machine->is_default) { if (temp->is_default) {
mc = temp; mc = temp;
break; break;
} }
@ -1653,27 +1674,25 @@ MachineInfoList *qmp_query_machines(Error **errp)
{ {
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
MachineInfoList *mach_list = NULL; MachineInfoList *mach_list = NULL;
QEMUMachine *m;
for (el = machines; el; el = el->next) { for (el = machines; el; el = el->next) {
MachineClass *mc = el->data; MachineClass *mc = el->data;
MachineInfoList *entry; MachineInfoList *entry;
MachineInfo *info; MachineInfo *info;
m = mc->qemu_machine;
info = g_malloc0(sizeof(*info)); info = g_malloc0(sizeof(*info));
if (m->is_default) { if (mc->is_default) {
info->has_is_default = true; info->has_is_default = true;
info->is_default = true; info->is_default = true;
} }
if (m->alias) { if (mc->alias) {
info->has_alias = true; info->has_alias = true;
info->alias = g_strdup(m->alias); info->alias = g_strdup(mc->alias);
} }
info->name = g_strdup(m->name); info->name = g_strdup(mc->name);
info->cpu_max = !m->max_cpus ? 1 : m->max_cpus; info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus;
entry = g_malloc0(sizeof(*entry)); entry = g_malloc0(sizeof(*entry));
entry->value = info; entry->value = info;
@ -1879,8 +1898,8 @@ void qemu_system_reset(bool report)
mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
if (mc && mc->qemu_machine->reset) { if (mc && mc->reset) {
mc->qemu_machine->reset(); mc->reset();
} else { } else {
qemu_devices_reset(); qemu_devices_reset();
} }
@ -2689,12 +2708,11 @@ static MachineClass *machine_parse(const char *name)
printf("Supported machines are:\n"); printf("Supported machines are:\n");
for (el = machines; el; el = el->next) { for (el = machines; el; el = el->next) {
MachineClass *mc = el->data; MachineClass *mc = el->data;
QEMUMachine *m = mc->qemu_machine; if (mc->alias) {
if (m->alias) { printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
printf("%-20s %s (alias of %s)\n", m->alias, m->desc, m->name);
} }
printf("%-20s %s%s\n", m->name, m->desc, printf("%-20s %s%s\n", mc->name, mc->desc,
m->is_default ? " (default)" : ""); mc->is_default ? " (default)" : "");
} }
} }
@ -2702,7 +2720,7 @@ static MachineClass *machine_parse(const char *name)
exit(!name || !is_help_option(name)); exit(!name || !is_help_option(name));
} }
static int tcg_init(QEMUMachine *machine) static int tcg_init(MachineClass *mc)
{ {
tcg_exec_init(tcg_tb_size * 1024 * 1024); tcg_exec_init(tcg_tb_size * 1024 * 1024);
return 0; return 0;
@ -2712,7 +2730,7 @@ static struct {
const char *opt_name; const char *opt_name;
const char *name; const char *name;
int (*available)(void); int (*available)(void);
int (*init)(QEMUMachine *); int (*init)(MachineClass *mc);
bool *allowed; bool *allowed;
} accel_list[] = { } accel_list[] = {
{ "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed }, { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
@ -2721,7 +2739,7 @@ static struct {
{ "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed }, { "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
}; };
static int configure_accelerator(QEMUMachine *machine) static int configure_accelerator(MachineClass *mc)
{ {
const char *p; const char *p;
char buf[10]; char buf[10];
@ -2748,7 +2766,7 @@ static int configure_accelerator(QEMUMachine *machine)
break; break;
} }
*(accel_list[i].allowed) = true; *(accel_list[i].allowed) = true;
ret = accel_list[i].init(machine); ret = accel_list[i].init(mc);
if (ret < 0) { if (ret < 0) {
init_failed = true; init_failed = true;
fprintf(stderr, "failed to initialize %s: %s\n", fprintf(stderr, "failed to initialize %s: %s\n",
@ -2948,7 +2966,6 @@ int main(int argc, char **argv, char **envp)
const char *optarg; const char *optarg;
const char *loadvm = NULL; const char *loadvm = NULL;
MachineClass *machine_class; MachineClass *machine_class;
QEMUMachine *machine;
const char *cpu_model; const char *cpu_model;
const char *vga_model = NULL; const char *vga_model = NULL;
const char *qtest_chrdev = NULL; const char *qtest_chrdev = NULL;
@ -3976,9 +3993,8 @@ int main(int argc, char **argv, char **envp)
object_property_add_child(object_get_root(), "machine", object_property_add_child(object_get_root(), "machine",
OBJECT(current_machine), &error_abort); OBJECT(current_machine), &error_abort);
machine = machine_class->qemu_machine; if (machine_class->hw_version) {
if (machine->hw_version) { qemu_set_version(machine_class->hw_version);
qemu_set_version(machine->hw_version);
} }
if (qemu_opts_foreach(qemu_find_opts("object"), if (qemu_opts_foreach(qemu_find_opts("object"),
@ -4038,11 +4054,11 @@ int main(int argc, char **argv, char **envp)
smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL)); smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */ machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
if (smp_cpus > machine->max_cpus) { if (smp_cpus > machine_class->max_cpus) {
fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus " fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
"supported by machine `%s' (%d)\n", smp_cpus, machine->name, "supported by machine `%s' (%d)\n", smp_cpus,
machine->max_cpus); machine_class->name, machine_class->max_cpus);
exit(1); exit(1);
} }
@ -4050,9 +4066,9 @@ int main(int argc, char **argv, char **envp)
* Get the default machine options from the machine if it is not already * Get the default machine options from the machine if it is not already
* specified either by the configuration file or by the command line. * specified either by the configuration file or by the command line.
*/ */
if (machine->default_machine_opts) { if (machine_class->default_machine_opts) {
qemu_opts_set_defaults(qemu_find_opts("machine"), qemu_opts_set_defaults(qemu_find_opts("machine"),
machine->default_machine_opts, 0); machine_class->default_machine_opts, 0);
} }
qemu_opts_foreach(qemu_find_opts("device"), default_driver_check, NULL, 0); qemu_opts_foreach(qemu_find_opts("device"), default_driver_check, NULL, 0);
@ -4061,25 +4077,25 @@ int main(int argc, char **argv, char **envp)
if (!vga_model && !default_vga) { if (!vga_model && !default_vga) {
vga_interface_type = VGA_DEVICE; vga_interface_type = VGA_DEVICE;
} }
if (!has_defaults || machine->no_serial) { if (!has_defaults || machine_class->no_serial) {
default_serial = 0; default_serial = 0;
} }
if (!has_defaults || machine->no_parallel) { if (!has_defaults || machine_class->no_parallel) {
default_parallel = 0; default_parallel = 0;
} }
if (!has_defaults || !machine->use_virtcon) { if (!has_defaults || !machine_class->use_virtcon) {
default_virtcon = 0; default_virtcon = 0;
} }
if (!has_defaults || !machine->use_sclp) { if (!has_defaults || !machine_class->use_sclp) {
default_sclp = 0; default_sclp = 0;
} }
if (!has_defaults || machine->no_floppy) { if (!has_defaults || machine_class->no_floppy) {
default_floppy = 0; default_floppy = 0;
} }
if (!has_defaults || machine->no_cdrom) { if (!has_defaults || machine_class->no_cdrom) {
default_cdrom = 0; default_cdrom = 0;
} }
if (!has_defaults || machine->no_sdcard) { if (!has_defaults || machine_class->no_sdcard) {
default_sdcard = 0; default_sdcard = 0;
} }
if (!has_defaults) { if (!has_defaults) {
@ -4199,7 +4215,7 @@ int main(int argc, char **argv, char **envp)
exit(0); exit(0);
} }
configure_accelerator(machine); configure_accelerator(machine_class);
if (qtest_chrdev) { if (qtest_chrdev) {
Error *local_err = NULL; Error *local_err = NULL;
@ -4217,7 +4233,7 @@ int main(int argc, char **argv, char **envp)
kernel_cmdline = qemu_opt_get(machine_opts, "append"); kernel_cmdline = qemu_opt_get(machine_opts, "append");
bios_name = qemu_opt_get(machine_opts, "firmware"); bios_name = qemu_opt_get(machine_opts, "firmware");
boot_order = machine->default_boot_order; boot_order = machine_class->default_boot_order;
opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL); opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
if (opts) { if (opts) {
char *normal_boot_order; char *normal_boot_order;
@ -4311,11 +4327,11 @@ int main(int argc, char **argv, char **envp)
if (snapshot) if (snapshot)
qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0); qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
&machine->block_default_type, 1) != 0) { &machine_class->block_default_type, 1) != 0) {
exit(1); exit(1);
} }
default_drive(default_cdrom, snapshot, machine->block_default_type, 2, default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2,
CDROM_OPTS); CDROM_OPTS);
default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS); default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS); default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
@ -4399,15 +4415,15 @@ int main(int argc, char **argv, char **envp)
exit (i == 1 ? 1 : 0); exit (i == 1 ? 1 : 0);
} }
if (machine->compat_props) { if (machine_class->compat_props) {
qdev_prop_register_global_list(machine->compat_props); qdev_prop_register_global_list(machine_class->compat_props);
} }
qemu_add_globals(); qemu_add_globals();
qdev_machine_init(); qdev_machine_init();
current_machine->init_args = (QEMUMachineInitArgs) { current_machine->init_args = (QEMUMachineInitArgs) {
.machine = machine, .machine = machine_class,
.ram_size = ram_size, .ram_size = ram_size,
.boot_order = boot_order, .boot_order = boot_order,
.kernel_filename = kernel_filename, .kernel_filename = kernel_filename,
@ -4415,7 +4431,7 @@ int main(int argc, char **argv, char **envp)
.initrd_filename = initrd_filename, .initrd_filename = initrd_filename,
.cpu_model = cpu_model }; .cpu_model = cpu_model };
machine->init(&current_machine->init_args); machine_class->init(&current_machine->init_args);
audio_init(); audio_init();

View File

@ -1001,7 +1001,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
xs_daemon_close(state->xenstore); xs_daemon_close(state->xenstore);
} }
int xen_init(QEMUMachine *machine) int xen_init(MachineClass *mc)
{ {
xen_xc = xen_xc_interface_open(0, 0, 0); xen_xc = xen_xc_interface_open(0, 0, 0);
if (xen_xc == XC_HANDLER_INITIAL_VALUE) { if (xen_xc == XC_HANDLER_INITIAL_VALUE) {

View File

@ -47,7 +47,7 @@ qemu_irq *xen_interrupt_controller_init(void)
return NULL; return NULL;
} }
int xen_init(QEMUMachine *machine) int xen_init(MachineClass *mc)
{ {
return -ENOSYS; return -ENOSYS;
} }