QOM/QTest infrastructure fixes and device conversions
* QTest cleanups and test cases for some virtio devices * QTest for sPAPR PCI host bridge * qom-test now tests reading all properties beneath /machine * QOM API leak fixes * QOM cleanups for SSI devices * QOM conversion of QEMUMachine * QOM realize for buses * sPAPR PCI bus name change -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJTIPpQAAoJEPou0S0+fgE/waAQAImhHJ9NE9l9ba7xsuZRmr+B 8LvYDQ6VhiYG0sRQ+wn6GbU9yY91l+OgY2M/AaPRLSnqP84c5ypmRSq33777x19T Mvnh6kWwVHFTWTaLpeb7G6rb67fbinx79QOdiNd7QI/WKrEl14meMlIxqDtGH/tk e++GYQLzQbhkl13pNGfuqEu7Zwj1cvoPyZYiRmqRkONVoDuZg+3y0Joo9fYnl57p lAcw4SxKA9K/mdjZrDJRjpZ8pDuoMx3ILaKDhEscZGSi6/vSRHUHnfqYehWbCFl4 64V4QmAYuSHEiPjOdHxMaeAUgk5RYgvMTjsu7uDCCbrI1np5j0ELzjrU/X9BGiTP X1vYgCXRLmC9yNr4Bs4heIzdvEs7bw4XbM2IQ3ox102q1ZuYnS8BtGTr5G1nS/VE p7gdQ9tbfBnuZYE5ahI/nVM853xKWYkgQvYEbFKyCjTtPCN2c/2cbCpptBFUBhHN Ud6N3i3x39BuwDRIWXiFmrHEOa4jOcoorTVWmJyoXbE7NLp4cDZPTXEzU3R6aB4v KtzFcJAUUQsbXRJCllVieVjfDyuL3WdUdIpLTnXsgcr+495FKVeZI+98Jxi8ncVv s8J/OnXoZgE9Uwq9kZFRHTA7knsfxcFtAjTkbT8P/cLLK03o+c95d1m0OeXAl+FM RdFERQ0NZP8dRuOTQ3Fn =2uZO -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/afaerber/tags/qom-devices-for-peter' into staging QOM/QTest infrastructure fixes and device conversions * QTest cleanups and test cases for some virtio devices * QTest for sPAPR PCI host bridge * qom-test now tests reading all properties beneath /machine * QOM API leak fixes * QOM cleanups for SSI devices * QOM conversion of QEMUMachine * QOM realize for buses * sPAPR PCI bus name change # gpg: Signature made Thu 13 Mar 2014 00:22:40 GMT 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: (31 commits) libqtest: Fix possible deadlock in qtest initialization pci: Move VMState registration/unregistration to QOM realize/unrealize qdev: Realize buses on device realization qdev: Prepare realize/unrealize hooks for BusState tests: Add spapr-pci-host-bridge qtest virtio-serial-port: Convert to QOM realize/unrealize virtio-console: QOM cast cleanup for VirtConsole tests: Add virtio-console qtest tests: Add virtio-serial qtest tests: Add virtio-scsi qtest tests: Add virtio-rng qtest tests: Add virtio-balloon qtest tests: Add virtio-blk qtest tests: Clean up IndustryPack TPCI200 gcov paths qom-test: Test QOM properties hw/boards: Convert current_machine to MachineState vl: Use MachineClass instead of global QEMUMachine list hw/core: Introduce QEMU machine as QOM object qdev-monitor-test: Don't test human-readable error message qdev-monitor-test: Simplify using g_assert_cmpstr() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
						commit
						c8d146aecc
					
				@ -33,12 +33,14 @@ DriveInfo *add_init_drive(const char *optstr)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    DriveInfo *dinfo;
 | 
					    DriveInfo *dinfo;
 | 
				
			||||||
    QemuOpts *opts;
 | 
					    QemuOpts *opts;
 | 
				
			||||||
 | 
					    MachineClass *mc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    opts = drive_def(optstr);
 | 
					    opts = drive_def(optstr);
 | 
				
			||||||
    if (!opts)
 | 
					    if (!opts)
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dinfo = drive_init(opts, current_machine->block_default_type);
 | 
					    mc = MACHINE_GET_CLASS(current_machine);
 | 
				
			||||||
 | 
					    dinfo = drive_init(opts, mc->qemu_machine->block_default_type);
 | 
				
			||||||
    if (!dinfo) {
 | 
					    if (!dinfo) {
 | 
				
			||||||
        qemu_opts_del(opts);
 | 
					        qemu_opts_del(opts);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
				
			|||||||
@ -658,14 +658,15 @@ static void spitz_adc_temp_on(void *opaque, int line, int level)
 | 
				
			|||||||
        max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
 | 
					        max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int corgi_ssp_init(SSISlave *dev)
 | 
					static int corgi_ssp_init(SSISlave *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
 | 
					    DeviceState *dev = DEVICE(d);
 | 
				
			||||||
 | 
					    CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qdev_init_gpio_in(&dev->qdev, corgi_ssp_gpio_cs, 3);
 | 
					    qdev_init_gpio_in(dev, corgi_ssp_gpio_cs, 3);
 | 
				
			||||||
    s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
 | 
					    s->bus[0] = ssi_create_bus(dev, "ssi0");
 | 
				
			||||||
    s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
 | 
					    s->bus[1] = ssi_create_bus(dev, "ssi1");
 | 
				
			||||||
    s->bus[2] = ssi_create_bus(&dev->qdev, "ssi2");
 | 
					    s->bus[2] = ssi_create_bus(dev, "ssi2");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -241,7 +241,8 @@ typedef enum {
 | 
				
			|||||||
} CMDState;
 | 
					} CMDState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Flash {
 | 
					typedef struct Flash {
 | 
				
			||||||
    SSISlave ssidev;
 | 
					    SSISlave parent_obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint32_t r;
 | 
					    uint32_t r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BlockDriverState *bdrv;
 | 
					    BlockDriverState *bdrv;
 | 
				
			||||||
@ -545,7 +546,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static int m25p80_cs(SSISlave *ss, bool select)
 | 
					static int m25p80_cs(SSISlave *ss, bool select)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Flash *s = FROM_SSI_SLAVE(Flash, ss);
 | 
					    Flash *s = M25P80(ss);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (select) {
 | 
					    if (select) {
 | 
				
			||||||
        s->len = 0;
 | 
					        s->len = 0;
 | 
				
			||||||
@ -561,7 +562,7 @@ static int m25p80_cs(SSISlave *ss, bool select)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
 | 
					static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Flash *s = FROM_SSI_SLAVE(Flash, ss);
 | 
					    Flash *s = M25P80(ss);
 | 
				
			||||||
    uint32_t r = 0;
 | 
					    uint32_t r = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (s->state) {
 | 
					    switch (s->state) {
 | 
				
			||||||
@ -610,7 +611,7 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
 | 
				
			|||||||
static int m25p80_init(SSISlave *ss)
 | 
					static int m25p80_init(SSISlave *ss)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DriveInfo *dinfo;
 | 
					    DriveInfo *dinfo;
 | 
				
			||||||
    Flash *s = FROM_SSI_SLAVE(Flash, ss);
 | 
					    Flash *s = M25P80(ss);
 | 
				
			||||||
    M25P80Class *mc = M25P80_GET_CLASS(s);
 | 
					    M25P80Class *mc = M25P80_GET_CLASS(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->pi = mc->pi;
 | 
					    s->pi = mc->pi;
 | 
				
			||||||
 | 
				
			|||||||
@ -15,8 +15,13 @@
 | 
				
			|||||||
#include "trace.h"
 | 
					#include "trace.h"
 | 
				
			||||||
#include "hw/virtio/virtio-serial.h"
 | 
					#include "hw/virtio/virtio-serial.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TYPE_VIRTIO_CONSOLE "virtconsole"
 | 
				
			||||||
 | 
					#define VIRTIO_CONSOLE(obj) \
 | 
				
			||||||
 | 
					    OBJECT_CHECK(VirtConsole, (obj), TYPE_VIRTIO_CONSOLE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct VirtConsole {
 | 
					typedef struct VirtConsole {
 | 
				
			||||||
    VirtIOSerialPort port;
 | 
					    VirtIOSerialPort parent_obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CharDriverState *chr;
 | 
					    CharDriverState *chr;
 | 
				
			||||||
    guint watch;
 | 
					    guint watch;
 | 
				
			||||||
} VirtConsole;
 | 
					} VirtConsole;
 | 
				
			||||||
@ -31,7 +36,7 @@ static gboolean chr_write_unblocked(GIOChannel *chan, GIOCondition cond,
 | 
				
			|||||||
    VirtConsole *vcon = opaque;
 | 
					    VirtConsole *vcon = opaque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vcon->watch = 0;
 | 
					    vcon->watch = 0;
 | 
				
			||||||
    virtio_serial_throttle_port(&vcon->port, false);
 | 
					    virtio_serial_throttle_port(VIRTIO_SERIAL_PORT(vcon), false);
 | 
				
			||||||
    return FALSE;
 | 
					    return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -39,7 +44,7 @@ static gboolean chr_write_unblocked(GIOChannel *chan, GIOCondition cond,
 | 
				
			|||||||
static ssize_t flush_buf(VirtIOSerialPort *port,
 | 
					static ssize_t flush_buf(VirtIOSerialPort *port,
 | 
				
			||||||
                         const uint8_t *buf, ssize_t len)
 | 
					                         const uint8_t *buf, ssize_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 | 
					    VirtConsole *vcon = VIRTIO_CONSOLE(port);
 | 
				
			||||||
    ssize_t ret;
 | 
					    ssize_t ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!vcon->chr) {
 | 
					    if (!vcon->chr) {
 | 
				
			||||||
@ -75,7 +80,7 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
 | 
				
			|||||||
/* Callback function that's called when the guest opens/closes the port */
 | 
					/* Callback function that's called when the guest opens/closes the port */
 | 
				
			||||||
static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)
 | 
					static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 | 
					    VirtConsole *vcon = VIRTIO_CONSOLE(port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!vcon->chr) {
 | 
					    if (!vcon->chr) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
@ -88,45 +93,49 @@ static int chr_can_read(void *opaque)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    VirtConsole *vcon = opaque;
 | 
					    VirtConsole *vcon = opaque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return virtio_serial_guest_ready(&vcon->port);
 | 
					    return virtio_serial_guest_ready(VIRTIO_SERIAL_PORT(vcon));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Send data from a char device over to the guest */
 | 
					/* Send data from a char device over to the guest */
 | 
				
			||||||
static void chr_read(void *opaque, const uint8_t *buf, int size)
 | 
					static void chr_read(void *opaque, const uint8_t *buf, int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtConsole *vcon = opaque;
 | 
					    VirtConsole *vcon = opaque;
 | 
				
			||||||
 | 
					    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    trace_virtio_console_chr_read(vcon->port.id, size);
 | 
					    trace_virtio_console_chr_read(port->id, size);
 | 
				
			||||||
    virtio_serial_write(&vcon->port, buf, size);
 | 
					    virtio_serial_write(port, buf, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void chr_event(void *opaque, int event)
 | 
					static void chr_event(void *opaque, int event)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtConsole *vcon = opaque;
 | 
					    VirtConsole *vcon = opaque;
 | 
				
			||||||
 | 
					    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    trace_virtio_console_chr_event(vcon->port.id, event);
 | 
					    trace_virtio_console_chr_event(port->id, event);
 | 
				
			||||||
    switch (event) {
 | 
					    switch (event) {
 | 
				
			||||||
    case CHR_EVENT_OPENED:
 | 
					    case CHR_EVENT_OPENED:
 | 
				
			||||||
        virtio_serial_open(&vcon->port);
 | 
					        virtio_serial_open(port);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case CHR_EVENT_CLOSED:
 | 
					    case CHR_EVENT_CLOSED:
 | 
				
			||||||
        if (vcon->watch) {
 | 
					        if (vcon->watch) {
 | 
				
			||||||
            g_source_remove(vcon->watch);
 | 
					            g_source_remove(vcon->watch);
 | 
				
			||||||
            vcon->watch = 0;
 | 
					            vcon->watch = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        virtio_serial_close(&vcon->port);
 | 
					        virtio_serial_close(port);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int virtconsole_initfn(VirtIOSerialPort *port)
 | 
					static void virtconsole_realize(DeviceState *dev, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 | 
					    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
 | 
				
			||||||
    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 | 
					    VirtConsole *vcon = VIRTIO_CONSOLE(dev);
 | 
				
			||||||
 | 
					    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (port->id == 0 && !k->is_console) {
 | 
					    if (port->id == 0 && !k->is_console) {
 | 
				
			||||||
        error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility.");
 | 
					        error_setg(errp, "Port number 0 on virtio-serial devices reserved "
 | 
				
			||||||
        return -1;
 | 
					                   "for virtconsole devices for backward compatibility.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (vcon->chr) {
 | 
					    if (vcon->chr) {
 | 
				
			||||||
@ -134,19 +143,15 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
 | 
				
			|||||||
        qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
 | 
					        qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
 | 
				
			||||||
                              vcon);
 | 
					                              vcon);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int virtconsole_exitfn(VirtIOSerialPort *port)
 | 
					static void virtconsole_unrealize(DeviceState *dev, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 | 
					    VirtConsole *vcon = VIRTIO_CONSOLE(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (vcon->watch) {
 | 
					    if (vcon->watch) {
 | 
				
			||||||
        g_source_remove(vcon->watch);
 | 
					        g_source_remove(vcon->watch);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Property virtconsole_properties[] = {
 | 
					static Property virtconsole_properties[] = {
 | 
				
			||||||
@ -160,15 +165,15 @@ static void virtconsole_class_init(ObjectClass *klass, void *data)
 | 
				
			|||||||
    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 | 
					    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    k->is_console = true;
 | 
					    k->is_console = true;
 | 
				
			||||||
    k->init = virtconsole_initfn;
 | 
					    k->realize = virtconsole_realize;
 | 
				
			||||||
    k->exit = virtconsole_exitfn;
 | 
					    k->unrealize = virtconsole_unrealize;
 | 
				
			||||||
    k->have_data = flush_buf;
 | 
					    k->have_data = flush_buf;
 | 
				
			||||||
    k->set_guest_connected = set_guest_connected;
 | 
					    k->set_guest_connected = set_guest_connected;
 | 
				
			||||||
    dc->props = virtconsole_properties;
 | 
					    dc->props = virtconsole_properties;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const TypeInfo virtconsole_info = {
 | 
					static const TypeInfo virtconsole_info = {
 | 
				
			||||||
    .name          = "virtconsole",
 | 
					    .name          = TYPE_VIRTIO_CONSOLE,
 | 
				
			||||||
    .parent        = TYPE_VIRTIO_SERIAL_PORT,
 | 
					    .parent        = TYPE_VIRTIO_SERIAL_PORT,
 | 
				
			||||||
    .instance_size = sizeof(VirtConsole),
 | 
					    .instance_size = sizeof(VirtConsole),
 | 
				
			||||||
    .class_init    = virtconsole_class_init,
 | 
					    .class_init    = virtconsole_class_init,
 | 
				
			||||||
@ -184,8 +189,8 @@ static void virtserialport_class_init(ObjectClass *klass, void *data)
 | 
				
			|||||||
    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
					    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
				
			||||||
    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 | 
					    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    k->init = virtconsole_initfn;
 | 
					    k->realize = virtconsole_realize;
 | 
				
			||||||
    k->exit = virtconsole_exitfn;
 | 
					    k->unrealize = virtconsole_unrealize;
 | 
				
			||||||
    k->have_data = flush_buf;
 | 
					    k->have_data = flush_buf;
 | 
				
			||||||
    k->set_guest_connected = set_guest_connected;
 | 
					    k->set_guest_connected = set_guest_connected;
 | 
				
			||||||
    dc->props = virtserialport_properties;
 | 
					    dc->props = virtserialport_properties;
 | 
				
			||||||
 | 
				
			|||||||
@ -808,13 +808,14 @@ static void remove_port(VirtIOSerial *vser, uint32_t port_id)
 | 
				
			|||||||
    send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_REMOVE, 1);
 | 
					    send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_REMOVE, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int virtser_port_qdev_init(DeviceState *qdev)
 | 
					static void virtser_port_device_realize(DeviceState *dev, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
 | 
					    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
 | 
				
			||||||
    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 | 
					    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 | 
				
			||||||
    VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
 | 
					    VirtIOSerialBus *bus = VIRTIO_SERIAL_BUS(qdev_get_parent_bus(dev));
 | 
				
			||||||
    int ret, max_nr_ports;
 | 
					    int max_nr_ports;
 | 
				
			||||||
    bool plugging_port0;
 | 
					    bool plugging_port0;
 | 
				
			||||||
 | 
					    Error *err = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    port->vser = bus->vser;
 | 
					    port->vser = bus->vser;
 | 
				
			||||||
    port->bh = qemu_bh_new(flush_queued_data_bh, port);
 | 
					    port->bh = qemu_bh_new(flush_queued_data_bh, port);
 | 
				
			||||||
@ -829,9 +830,9 @@ static int virtser_port_qdev_init(DeviceState *qdev)
 | 
				
			|||||||
    plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0);
 | 
					    plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (find_port_by_id(port->vser, port->id)) {
 | 
					    if (find_port_by_id(port->vser, port->id)) {
 | 
				
			||||||
        error_report("virtio-serial-bus: A port already exists at id %u",
 | 
					        error_setg(errp, "virtio-serial-bus: A port already exists at id %u",
 | 
				
			||||||
                     port->id);
 | 
					                   port->id);
 | 
				
			||||||
        return -1;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (port->id == VIRTIO_CONSOLE_BAD_ID) {
 | 
					    if (port->id == VIRTIO_CONSOLE_BAD_ID) {
 | 
				
			||||||
@ -840,22 +841,24 @@ static int virtser_port_qdev_init(DeviceState *qdev)
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            port->id = find_free_port_id(port->vser);
 | 
					            port->id = find_free_port_id(port->vser);
 | 
				
			||||||
            if (port->id == VIRTIO_CONSOLE_BAD_ID) {
 | 
					            if (port->id == VIRTIO_CONSOLE_BAD_ID) {
 | 
				
			||||||
                error_report("virtio-serial-bus: Maximum port limit for this device reached");
 | 
					                error_setg(errp, "virtio-serial-bus: Maximum port limit for "
 | 
				
			||||||
                return -1;
 | 
					                                 "this device reached");
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    max_nr_ports = tswap32(port->vser->config.max_nr_ports);
 | 
					    max_nr_ports = tswap32(port->vser->config.max_nr_ports);
 | 
				
			||||||
    if (port->id >= max_nr_ports) {
 | 
					    if (port->id >= max_nr_ports) {
 | 
				
			||||||
        error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u",
 | 
					        error_setg(errp, "virtio-serial-bus: Out-of-range port id specified, "
 | 
				
			||||||
                     max_nr_ports - 1);
 | 
					                         "max. allowed: %u", max_nr_ports - 1);
 | 
				
			||||||
        return -1;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = vsc->init(port);
 | 
					    vsc->realize(dev, &err);
 | 
				
			||||||
    if (ret) {
 | 
					    if (err != NULL) {
 | 
				
			||||||
        return ret;
 | 
					        error_propagate(errp, err);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    port->elem.out_num = 0;
 | 
					    port->elem.out_num = 0;
 | 
				
			||||||
@ -868,14 +871,12 @@ static int virtser_port_qdev_init(DeviceState *qdev)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* Send an update to the guest about this new port added */
 | 
					    /* Send an update to the guest about this new port added */
 | 
				
			||||||
    virtio_notify_config(VIRTIO_DEVICE(port->vser));
 | 
					    virtio_notify_config(VIRTIO_DEVICE(port->vser));
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int virtser_port_qdev_exit(DeviceState *qdev)
 | 
					static void virtser_port_device_unrealize(DeviceState *dev, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
 | 
					    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
 | 
				
			||||||
    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 | 
					    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
 | 
				
			||||||
    VirtIOSerial *vser = port->vser;
 | 
					    VirtIOSerial *vser = port->vser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_bh_delete(port->bh);
 | 
					    qemu_bh_delete(port->bh);
 | 
				
			||||||
@ -883,10 +884,9 @@ static int virtser_port_qdev_exit(DeviceState *qdev)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    QTAILQ_REMOVE(&vser->ports, port, next);
 | 
					    QTAILQ_REMOVE(&vser->ports, port, next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (vsc->exit) {
 | 
					    if (vsc->unrealize) {
 | 
				
			||||||
        vsc->exit(port);
 | 
					        vsc->unrealize(dev, errp);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
 | 
					static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
 | 
				
			||||||
@ -971,10 +971,11 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
 | 
				
			|||||||
static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
 | 
					static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DeviceClass *k = DEVICE_CLASS(klass);
 | 
					    DeviceClass *k = DEVICE_CLASS(klass);
 | 
				
			||||||
    k->init = virtser_port_qdev_init;
 | 
					
 | 
				
			||||||
    set_bit(DEVICE_CATEGORY_INPUT, k->categories);
 | 
					    set_bit(DEVICE_CATEGORY_INPUT, k->categories);
 | 
				
			||||||
    k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
 | 
					    k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
 | 
				
			||||||
    k->exit = virtser_port_qdev_exit;
 | 
					    k->realize = virtser_port_device_realize;
 | 
				
			||||||
 | 
					    k->unrealize = virtser_port_device_unrealize;
 | 
				
			||||||
    k->unplug = qdev_simple_unplug_cb;
 | 
					    k->unplug = qdev_simple_unplug_cb;
 | 
				
			||||||
    k->props = virtser_props;
 | 
					    k->props = virtser_props;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 | 
				
			|||||||
common-obj-$(CONFIG_XILINX_AXI) += stream.o
 | 
					common-obj-$(CONFIG_XILINX_AXI) += stream.o
 | 
				
			||||||
common-obj-$(CONFIG_PTIMER) += ptimer.o
 | 
					common-obj-$(CONFIG_PTIMER) += ptimer.o
 | 
				
			||||||
common-obj-$(CONFIG_SOFTMMU) += sysbus.o
 | 
					common-obj-$(CONFIG_SOFTMMU) += sysbus.o
 | 
				
			||||||
 | 
					common-obj-$(CONFIG_SOFTMMU) += machine.o
 | 
				
			||||||
common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 | 
					common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 | 
				
			||||||
common-obj-$(CONFIG_SOFTMMU) += loader.o
 | 
					common-obj-$(CONFIG_SOFTMMU) += loader.o
 | 
				
			||||||
common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 | 
					common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										28
									
								
								hw/core/machine.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								hw/core/machine.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QEMU Machine
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2014 Red Hat Inc
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors:
 | 
				
			||||||
 | 
					 *   Marcel Apfelbaum <marcel.a@redhat.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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 "hw/boards.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const TypeInfo machine_info = {
 | 
				
			||||||
 | 
					    .name = TYPE_MACHINE,
 | 
				
			||||||
 | 
					    .parent = TYPE_OBJECT,
 | 
				
			||||||
 | 
					    .abstract = true,
 | 
				
			||||||
 | 
					    .class_size = sizeof(MachineClass),
 | 
				
			||||||
 | 
					    .instance_size = sizeof(MachineState),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void machine_register_types(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    type_register_static(&machine_info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type_init(machine_register_types)
 | 
				
			||||||
@ -501,6 +501,45 @@ static void bus_unparent(Object *obj)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool bus_get_realized(Object *obj, Error **err)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    BusState *bus = BUS(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return bus->realized;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bus_set_realized(Object *obj, bool value, Error **err)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    BusState *bus = BUS(obj);
 | 
				
			||||||
 | 
					    BusClass *bc = BUS_GET_CLASS(bus);
 | 
				
			||||||
 | 
					    Error *local_err = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (value && !bus->realized) {
 | 
				
			||||||
 | 
					        if (bc->realize) {
 | 
				
			||||||
 | 
					            bc->realize(bus, &local_err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (local_err != NULL) {
 | 
				
			||||||
 | 
					                goto error;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else if (!value && bus->realized) {
 | 
				
			||||||
 | 
					        if (bc->unrealize) {
 | 
				
			||||||
 | 
					            bc->unrealize(bus, &local_err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (local_err != NULL) {
 | 
				
			||||||
 | 
					                goto error;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bus->realized = value;
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    error_propagate(err, 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,
 | 
				
			||||||
                         DeviceState *parent, const char *name)
 | 
					                         DeviceState *parent, const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -677,6 +716,7 @@ static void device_set_realized(Object *obj, bool value, Error **err)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    DeviceState *dev = DEVICE(obj);
 | 
					    DeviceState *dev = DEVICE(obj);
 | 
				
			||||||
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
 | 
					    DeviceClass *dc = DEVICE_GET_CLASS(dev);
 | 
				
			||||||
 | 
					    BusState *bus;
 | 
				
			||||||
    Error *local_err = NULL;
 | 
					    Error *local_err = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (dev->hotplugged && !dc->hotpluggable) {
 | 
					    if (dev->hotplugged && !dc->hotpluggable) {
 | 
				
			||||||
@ -710,14 +750,30 @@ static void device_set_realized(Object *obj, bool value, Error **err)
 | 
				
			|||||||
                                           dev->instance_id_alias,
 | 
					                                           dev->instance_id_alias,
 | 
				
			||||||
                                           dev->alias_required_for_version);
 | 
					                                           dev->alias_required_for_version);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (local_err == NULL) {
 | 
				
			||||||
 | 
					            QLIST_FOREACH(bus, &dev->child_bus, sibling) {
 | 
				
			||||||
 | 
					                object_property_set_bool(OBJECT(bus), true, "realized",
 | 
				
			||||||
 | 
					                                         &local_err);
 | 
				
			||||||
 | 
					                if (local_err != NULL) {
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (dev->hotplugged && local_err == NULL) {
 | 
					        if (dev->hotplugged && local_err == NULL) {
 | 
				
			||||||
            device_reset(dev);
 | 
					            device_reset(dev);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else if (!value && dev->realized) {
 | 
					    } else if (!value && dev->realized) {
 | 
				
			||||||
        if (qdev_get_vmsd(dev)) {
 | 
					        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
 | 
				
			||||||
 | 
					            object_property_set_bool(OBJECT(bus), false, "realized",
 | 
				
			||||||
 | 
					                                     &local_err);
 | 
				
			||||||
 | 
					            if (local_err != NULL) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (qdev_get_vmsd(dev) && local_err == NULL) {
 | 
				
			||||||
            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
 | 
					            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (dc->unrealize) {
 | 
					        if (dc->unrealize && local_err == NULL) {
 | 
				
			||||||
            dc->unrealize(dev, &local_err);
 | 
					            dc->unrealize(dev, &local_err);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -735,7 +791,8 @@ static bool device_get_hotpluggable(Object *obj, Error **err)
 | 
				
			|||||||
    DeviceClass *dc = DEVICE_GET_CLASS(obj);
 | 
					    DeviceClass *dc = DEVICE_GET_CLASS(obj);
 | 
				
			||||||
    DeviceState *dev = DEVICE(obj);
 | 
					    DeviceState *dev = DEVICE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return dc->hotpluggable && dev->parent_bus->allow_hotplug;
 | 
					    return dc->hotpluggable && (dev->parent_bus == NULL ||
 | 
				
			||||||
 | 
					                                dev->parent_bus->allow_hotplug);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void device_initfn(Object *obj)
 | 
					static void device_initfn(Object *obj)
 | 
				
			||||||
@ -792,14 +849,6 @@ static void device_class_base_init(ObjectClass *class, void *data)
 | 
				
			|||||||
     * so do not propagate them to the subclasses.
 | 
					     * so do not propagate them to the subclasses.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    klass->props = NULL;
 | 
					    klass->props = NULL;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* by default all devices were considered as hotpluggable,
 | 
					 | 
				
			||||||
     * so with intent to check it in generic qdev_unplug() /
 | 
					 | 
				
			||||||
     * device_set_realized() functions make every device
 | 
					 | 
				
			||||||
     * hotpluggable. Devices that shouldn't be hotpluggable,
 | 
					 | 
				
			||||||
     * should override it in their class_init()
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    klass->hotpluggable = true;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void device_unparent(Object *obj)
 | 
					static void device_unparent(Object *obj)
 | 
				
			||||||
@ -809,13 +858,13 @@ static void device_unparent(Object *obj)
 | 
				
			|||||||
    QObject *event_data;
 | 
					    QObject *event_data;
 | 
				
			||||||
    bool have_realized = dev->realized;
 | 
					    bool have_realized = dev->realized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dev->realized) {
 | 
				
			||||||
 | 
					        object_property_set_bool(obj, false, "realized", NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    while (dev->num_child_bus) {
 | 
					    while (dev->num_child_bus) {
 | 
				
			||||||
        bus = QLIST_FIRST(&dev->child_bus);
 | 
					        bus = QLIST_FIRST(&dev->child_bus);
 | 
				
			||||||
        object_unparent(OBJECT(bus));
 | 
					        object_unparent(OBJECT(bus));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (dev->realized) {
 | 
					 | 
				
			||||||
        object_property_set_bool(obj, false, "realized", NULL);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (dev->parent_bus) {
 | 
					    if (dev->parent_bus) {
 | 
				
			||||||
        bus_remove_child(dev->parent_bus, dev);
 | 
					        bus_remove_child(dev->parent_bus, dev);
 | 
				
			||||||
        object_unref(OBJECT(dev->parent_bus));
 | 
					        object_unref(OBJECT(dev->parent_bus));
 | 
				
			||||||
@ -845,6 +894,14 @@ static void device_class_init(ObjectClass *class, void *data)
 | 
				
			|||||||
    class->unparent = device_unparent;
 | 
					    class->unparent = device_unparent;
 | 
				
			||||||
    dc->realize = device_realize;
 | 
					    dc->realize = device_realize;
 | 
				
			||||||
    dc->unrealize = device_unrealize;
 | 
					    dc->unrealize = device_unrealize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* by default all devices were considered as hotpluggable,
 | 
				
			||||||
 | 
					     * so with intent to check it in generic qdev_unplug() /
 | 
				
			||||||
 | 
					     * device_set_realized() functions make every device
 | 
				
			||||||
 | 
					     * hotpluggable. Devices that shouldn't be hotpluggable,
 | 
				
			||||||
 | 
					     * should override it in their class_init()
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    dc->hotpluggable = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void device_reset(DeviceState *dev)
 | 
					void device_reset(DeviceState *dev)
 | 
				
			||||||
@ -888,6 +945,8 @@ static void qbus_initfn(Object *obj)
 | 
				
			|||||||
    object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
 | 
					    object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
 | 
				
			||||||
                             TYPE_HOTPLUG_HANDLER,
 | 
					                             TYPE_HOTPLUG_HANDLER,
 | 
				
			||||||
                             (Object **)&bus->hotplug_handler, NULL);
 | 
					                             (Object **)&bus->hotplug_handler, NULL);
 | 
				
			||||||
 | 
					    object_property_add_bool(obj, "realized",
 | 
				
			||||||
 | 
					                             bus_get_realized, bus_set_realized, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *default_bus_get_fw_dev_path(DeviceState *dev)
 | 
					static char *default_bus_get_fw_dev_path(DeviceState *dev)
 | 
				
			||||||
 | 
				
			|||||||
@ -133,11 +133,12 @@ static const VMStateDescription vmstate_ads7846 = {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ads7846_init(SSISlave *dev)
 | 
					static int ads7846_init(SSISlave *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
 | 
					    DeviceState *dev = DEVICE(d);
 | 
				
			||||||
 | 
					    ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
 | 
					    qdev_init_gpio_out(dev, &s->interrupt, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->input[0] = ADS_TEMP0;	/* TEMP0 */
 | 
					    s->input[0] = ADS_TEMP0;	/* TEMP0 */
 | 
				
			||||||
    s->input[2] = ADS_VBAT;	/* VBAT */
 | 
					    s->input[2] = ADS_VBAT;	/* VBAT */
 | 
				
			||||||
 | 
				
			|||||||
@ -336,18 +336,19 @@ static const GraphicHwOps ssd0323_ops = {
 | 
				
			|||||||
    .gfx_update  = ssd0323_update_display,
 | 
					    .gfx_update  = ssd0323_update_display,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ssd0323_init(SSISlave *dev)
 | 
					static int ssd0323_init(SSISlave *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
 | 
					    DeviceState *dev = DEVICE(d);
 | 
				
			||||||
 | 
					    ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->col_end = 63;
 | 
					    s->col_end = 63;
 | 
				
			||||||
    s->row_end = 79;
 | 
					    s->row_end = 79;
 | 
				
			||||||
    s->con = graphic_console_init(DEVICE(dev), 0, &ssd0323_ops, s);
 | 
					    s->con = graphic_console_init(dev, 0, &ssd0323_ops, s);
 | 
				
			||||||
    qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
 | 
					    qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
 | 
					    qdev_init_gpio_in(dev, ssd0323_cd, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    register_savevm(&dev->qdev, "ssd0323_oled", -1, 1,
 | 
					    register_savevm(dev, "ssd0323_oled", -1, 1,
 | 
				
			||||||
                    ssd0323_save, ssd0323_load, s);
 | 
					                    ssd0323_save, ssd0323_load, s);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,8 @@
 | 
				
			|||||||
#include "hw/ssi.h"
 | 
					#include "hw/ssi.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    SSISlave ssidev;
 | 
					    SSISlave parent_obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_irq interrupt;
 | 
					    qemu_irq interrupt;
 | 
				
			||||||
    uint8_t tb1, rb2, rb3;
 | 
					    uint8_t tb1, rb2, rb3;
 | 
				
			||||||
    int cycle;
 | 
					    int cycle;
 | 
				
			||||||
@ -22,6 +23,14 @@ typedef struct {
 | 
				
			|||||||
    int inputs, com;
 | 
					    int inputs, com;
 | 
				
			||||||
} MAX111xState;
 | 
					} MAX111xState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TYPE_MAX_111X "max111x"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_111X(obj) \
 | 
				
			||||||
 | 
					    OBJECT_CHECK(MAX111xState, (obj), TYPE_MAX_111X)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TYPE_MAX_1110 "max1110"
 | 
				
			||||||
 | 
					#define TYPE_MAX_1111 "max1111"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Control-byte bitfields */
 | 
					/* Control-byte bitfields */
 | 
				
			||||||
#define CB_PD0		(1 << 0)
 | 
					#define CB_PD0		(1 << 0)
 | 
				
			||||||
#define CB_PD1		(1 << 1)
 | 
					#define CB_PD1		(1 << 1)
 | 
				
			||||||
@ -92,7 +101,7 @@ static void max111x_write(MAX111xState *s, uint32_t value)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static uint32_t max111x_transfer(SSISlave *dev, uint32_t value)
 | 
					static uint32_t max111x_transfer(SSISlave *dev, uint32_t value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
 | 
					    MAX111xState *s = MAX_111X(dev);
 | 
				
			||||||
    max111x_write(s, value);
 | 
					    max111x_write(s, value);
 | 
				
			||||||
    return max111x_read(s);
 | 
					    return max111x_read(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -103,7 +112,7 @@ static const VMStateDescription vmstate_max111x = {
 | 
				
			|||||||
    .minimum_version_id = 1,
 | 
					    .minimum_version_id = 1,
 | 
				
			||||||
    .minimum_version_id_old = 1,
 | 
					    .minimum_version_id_old = 1,
 | 
				
			||||||
    .fields      = (VMStateField[]) {
 | 
					    .fields      = (VMStateField[]) {
 | 
				
			||||||
        VMSTATE_SSI_SLAVE(ssidev, MAX111xState),
 | 
					        VMSTATE_SSI_SLAVE(parent_obj, MAX111xState),
 | 
				
			||||||
        VMSTATE_UINT8(tb1, MAX111xState),
 | 
					        VMSTATE_UINT8(tb1, MAX111xState),
 | 
				
			||||||
        VMSTATE_UINT8(rb2, MAX111xState),
 | 
					        VMSTATE_UINT8(rb2, MAX111xState),
 | 
				
			||||||
        VMSTATE_UINT8(rb3, MAX111xState),
 | 
					        VMSTATE_UINT8(rb3, MAX111xState),
 | 
				
			||||||
@ -115,11 +124,12 @@ static const VMStateDescription vmstate_max111x = {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int max111x_init(SSISlave *dev, int inputs)
 | 
					static int max111x_init(SSISlave *d, int inputs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
 | 
					    DeviceState *dev = DEVICE(d);
 | 
				
			||||||
 | 
					    MAX111xState *s = MAX_111X(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
 | 
					    qdev_init_gpio_out(dev, &s->interrupt, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->inputs = inputs;
 | 
					    s->inputs = inputs;
 | 
				
			||||||
    /* TODO: add a user interface for setting these */
 | 
					    /* TODO: add a user interface for setting these */
 | 
				
			||||||
@ -133,7 +143,7 @@ static int max111x_init(SSISlave *dev, int inputs)
 | 
				
			|||||||
    s->input[7] = 0x80;
 | 
					    s->input[7] = 0x80;
 | 
				
			||||||
    s->com = 0;
 | 
					    s->com = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vmstate_register(&dev->qdev, -1, &vmstate_max111x, s);
 | 
					    vmstate_register(dev, -1, &vmstate_max111x, s);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -149,23 +159,36 @@ static int max1111_init(SSISlave *dev)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void max111x_set_input(DeviceState *dev, int line, uint8_t value)
 | 
					void max111x_set_input(DeviceState *dev, int line, uint8_t value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, SSI_SLAVE_FROM_QDEV(dev));
 | 
					    MAX111xState *s = MAX_111X(dev);
 | 
				
			||||||
    assert(line >= 0 && line < s->inputs);
 | 
					    assert(line >= 0 && line < s->inputs);
 | 
				
			||||||
    s->input[line] = value;
 | 
					    s->input[line] = value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void max111x_class_init(ObjectClass *klass, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    k->transfer = max111x_transfer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const TypeInfo max111x_info = {
 | 
				
			||||||
 | 
					    .name          = TYPE_MAX_111X,
 | 
				
			||||||
 | 
					    .parent        = TYPE_SSI_SLAVE,
 | 
				
			||||||
 | 
					    .instance_size = sizeof(MAX111xState),
 | 
				
			||||||
 | 
					    .class_init    = max111x_class_init,
 | 
				
			||||||
 | 
					    .abstract      = true,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void max1110_class_init(ObjectClass *klass, void *data)
 | 
					static void max1110_class_init(ObjectClass *klass, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 | 
					    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    k->init = max1110_init;
 | 
					    k->init = max1110_init;
 | 
				
			||||||
    k->transfer = max111x_transfer;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const TypeInfo max1110_info = {
 | 
					static const TypeInfo max1110_info = {
 | 
				
			||||||
    .name          = "max1110",
 | 
					    .name          = TYPE_MAX_1110,
 | 
				
			||||||
    .parent        = TYPE_SSI_SLAVE,
 | 
					    .parent        = TYPE_MAX_111X,
 | 
				
			||||||
    .instance_size = sizeof(MAX111xState),
 | 
					 | 
				
			||||||
    .class_init    = max1110_class_init,
 | 
					    .class_init    = max1110_class_init,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -174,18 +197,17 @@ static void max1111_class_init(ObjectClass *klass, void *data)
 | 
				
			|||||||
    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 | 
					    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    k->init = max1111_init;
 | 
					    k->init = max1111_init;
 | 
				
			||||||
    k->transfer = max111x_transfer;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const TypeInfo max1111_info = {
 | 
					static const TypeInfo max1111_info = {
 | 
				
			||||||
    .name          = "max1111",
 | 
					    .name          = TYPE_MAX_1111,
 | 
				
			||||||
    .parent        = TYPE_SSI_SLAVE,
 | 
					    .parent        = TYPE_MAX_111X,
 | 
				
			||||||
    .instance_size = sizeof(MAX111xState),
 | 
					 | 
				
			||||||
    .class_init    = max1111_class_init,
 | 
					    .class_init    = max1111_class_init,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void max111x_register_types(void)
 | 
					static void max111x_register_types(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    type_register_static(&max111x_info);
 | 
				
			||||||
    type_register_static(&max1110_info);
 | 
					    type_register_static(&max1110_info);
 | 
				
			||||||
    type_register_static(&max1111_info);
 | 
					    type_register_static(&max1111_info);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										51
									
								
								hw/pci/pci.c
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								hw/pci/pci.c
									
									
									
									
									
								
							@ -48,7 +48,6 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 | 
				
			|||||||
static char *pcibus_get_dev_path(DeviceState *dev);
 | 
					static char *pcibus_get_dev_path(DeviceState *dev);
 | 
				
			||||||
static char *pcibus_get_fw_dev_path(DeviceState *dev);
 | 
					static char *pcibus_get_fw_dev_path(DeviceState *dev);
 | 
				
			||||||
static void pcibus_reset(BusState *qbus);
 | 
					static void pcibus_reset(BusState *qbus);
 | 
				
			||||||
static void pci_bus_finalize(Object *obj);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Property pci_props[] = {
 | 
					static Property pci_props[] = {
 | 
				
			||||||
    DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
 | 
					    DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
 | 
				
			||||||
@ -61,6 +60,34 @@ static Property pci_props[] = {
 | 
				
			|||||||
    DEFINE_PROP_END_OF_LIST()
 | 
					    DEFINE_PROP_END_OF_LIST()
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const VMStateDescription vmstate_pcibus = {
 | 
				
			||||||
 | 
					    .name = "PCIBUS",
 | 
				
			||||||
 | 
					    .version_id = 1,
 | 
				
			||||||
 | 
					    .minimum_version_id = 1,
 | 
				
			||||||
 | 
					    .minimum_version_id_old = 1,
 | 
				
			||||||
 | 
					    .fields      = (VMStateField[]) {
 | 
				
			||||||
 | 
					        VMSTATE_INT32_EQUAL(nirq, PCIBus),
 | 
				
			||||||
 | 
					        VMSTATE_VARRAY_INT32(irq_count, PCIBus,
 | 
				
			||||||
 | 
					                             nirq, 0, vmstate_info_int32,
 | 
				
			||||||
 | 
					                             int32_t),
 | 
				
			||||||
 | 
					        VMSTATE_END_OF_LIST()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void pci_bus_realize(BusState *qbus, Error **errp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PCIBus *bus = PCI_BUS(qbus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vmstate_register(NULL, -1, &vmstate_pcibus, bus);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void pci_bus_unrealize(BusState *qbus, Error **errp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PCIBus *bus = PCI_BUS(qbus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vmstate_unregister(NULL, &vmstate_pcibus, bus);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pci_bus_class_init(ObjectClass *klass, void *data)
 | 
					static void pci_bus_class_init(ObjectClass *klass, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    BusClass *k = BUS_CLASS(klass);
 | 
					    BusClass *k = BUS_CLASS(klass);
 | 
				
			||||||
@ -68,6 +95,8 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
 | 
				
			|||||||
    k->print_dev = pcibus_dev_print;
 | 
					    k->print_dev = pcibus_dev_print;
 | 
				
			||||||
    k->get_dev_path = pcibus_get_dev_path;
 | 
					    k->get_dev_path = pcibus_get_dev_path;
 | 
				
			||||||
    k->get_fw_dev_path = pcibus_get_fw_dev_path;
 | 
					    k->get_fw_dev_path = pcibus_get_fw_dev_path;
 | 
				
			||||||
 | 
					    k->realize = pci_bus_realize;
 | 
				
			||||||
 | 
					    k->unrealize = pci_bus_unrealize;
 | 
				
			||||||
    k->reset = pcibus_reset;
 | 
					    k->reset = pcibus_reset;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -75,7 +104,6 @@ static const TypeInfo pci_bus_info = {
 | 
				
			|||||||
    .name = TYPE_PCI_BUS,
 | 
					    .name = TYPE_PCI_BUS,
 | 
				
			||||||
    .parent = TYPE_BUS,
 | 
					    .parent = TYPE_BUS,
 | 
				
			||||||
    .instance_size = sizeof(PCIBus),
 | 
					    .instance_size = sizeof(PCIBus),
 | 
				
			||||||
    .instance_finalize = pci_bus_finalize,
 | 
					 | 
				
			||||||
    .class_init = pci_bus_class_init,
 | 
					    .class_init = pci_bus_class_init,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -95,17 +123,6 @@ static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static QLIST_HEAD(, PCIHostState) pci_host_bridges;
 | 
					static QLIST_HEAD(, PCIHostState) pci_host_bridges;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const VMStateDescription vmstate_pcibus = {
 | 
					 | 
				
			||||||
    .name = "PCIBUS",
 | 
					 | 
				
			||||||
    .version_id = 1,
 | 
					 | 
				
			||||||
    .minimum_version_id = 1,
 | 
					 | 
				
			||||||
    .minimum_version_id_old = 1,
 | 
					 | 
				
			||||||
    .fields      = (VMStateField []) {
 | 
					 | 
				
			||||||
        VMSTATE_INT32_EQUAL(nirq, PCIBus),
 | 
					 | 
				
			||||||
        VMSTATE_VARRAY_INT32(irq_count, PCIBus, nirq, 0, vmstate_info_int32, int32_t),
 | 
					 | 
				
			||||||
        VMSTATE_END_OF_LIST()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static int pci_bar(PCIDevice *d, int reg)
 | 
					static int pci_bar(PCIDevice *d, int reg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint8_t type;
 | 
					    uint8_t type;
 | 
				
			||||||
@ -299,8 +316,6 @@ static void pci_bus_init(PCIBus *bus, DeviceState *parent,
 | 
				
			|||||||
    QLIST_INIT(&bus->child);
 | 
					    QLIST_INIT(&bus->child);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pci_host_bus_register(bus, parent);
 | 
					    pci_host_bus_register(bus, parent);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    vmstate_register(NULL, -1, &vmstate_pcibus, bus);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool pci_bus_is_express(PCIBus *bus)
 | 
					bool pci_bus_is_express(PCIBus *bus)
 | 
				
			||||||
@ -369,12 +384,6 @@ int pci_bus_num(PCIBus *s)
 | 
				
			|||||||
    return s->parent_dev->config[PCI_SECONDARY_BUS];
 | 
					    return s->parent_dev->config[PCI_SECONDARY_BUS];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pci_bus_finalize(Object *obj)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    PCIBus *bus = PCI_BUS(obj);
 | 
					 | 
				
			||||||
    vmstate_unregister(NULL, &vmstate_pcibus, bus);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
 | 
					static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PCIDevice *s = container_of(pv, PCIDevice, config);
 | 
					    PCIDevice *s = container_of(pv, PCIDevice, config);
 | 
				
			||||||
 | 
				
			|||||||
@ -510,7 +510,6 @@ static int spapr_phb_init(SysBusDevice *s)
 | 
				
			|||||||
    DeviceState *dev = DEVICE(s);
 | 
					    DeviceState *dev = DEVICE(s);
 | 
				
			||||||
    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
 | 
					    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
 | 
				
			||||||
    PCIHostState *phb = PCI_HOST_BRIDGE(s);
 | 
					    PCIHostState *phb = PCI_HOST_BRIDGE(s);
 | 
				
			||||||
    const char *busname;
 | 
					 | 
				
			||||||
    char *namebuf;
 | 
					    char *namebuf;
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
    PCIBus *bus;
 | 
					    PCIBus *bus;
 | 
				
			||||||
@ -594,26 +593,8 @@ static int spapr_phb_init(SysBusDevice *s)
 | 
				
			|||||||
                             get_system_io(), 0, SPAPR_PCI_IO_WIN_SIZE);
 | 
					                             get_system_io(), 0, SPAPR_PCI_IO_WIN_SIZE);
 | 
				
			||||||
    memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
 | 
					    memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
 | 
				
			||||||
                                &sphb->iowindow);
 | 
					                                &sphb->iowindow);
 | 
				
			||||||
    /*
 | 
					
 | 
				
			||||||
     * Selecting a busname is more complex than you'd think, due to
 | 
					    bus = pci_register_bus(dev, NULL,
 | 
				
			||||||
     * interacting constraints.  If the user has specified an id
 | 
					 | 
				
			||||||
     * explicitly for the phb , then we want to use the qdev default
 | 
					 | 
				
			||||||
     * of naming the bus based on the bridge device (so the user can
 | 
					 | 
				
			||||||
     * then assign devices to it in the way they expect).  For the
 | 
					 | 
				
			||||||
     * first / default PCI bus (index=0) we want to use just "pci"
 | 
					 | 
				
			||||||
     * because libvirt expects there to be a bus called, simply,
 | 
					 | 
				
			||||||
     * "pci".  Otherwise, we use the same name as in the device tree,
 | 
					 | 
				
			||||||
     * since it's unique by construction, and makes the guest visible
 | 
					 | 
				
			||||||
     * BUID clear.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    if (dev->id) {
 | 
					 | 
				
			||||||
        busname = NULL;
 | 
					 | 
				
			||||||
    } else if (sphb->index == 0) {
 | 
					 | 
				
			||||||
        busname = "pci";
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        busname = sphb->dtbusname;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    bus = pci_register_bus(dev, busname,
 | 
					 | 
				
			||||||
                           pci_spapr_set_irq, pci_spapr_map_irq, sphb,
 | 
					                           pci_spapr_set_irq, pci_spapr_map_irq, sphb,
 | 
				
			||||||
                           &sphb->memspace, &sphb->iospace,
 | 
					                           &sphb->memspace, &sphb->iospace,
 | 
				
			||||||
                           PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
 | 
					                           PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
 | 
				
			||||||
 | 
				
			|||||||
@ -238,9 +238,10 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ssi_sd_init(SSISlave *dev)
 | 
					static int ssi_sd_init(SSISlave *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, dev);
 | 
					    DeviceState *dev = DEVICE(d);
 | 
				
			||||||
 | 
					    ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
 | 
				
			||||||
    DriveInfo *dinfo;
 | 
					    DriveInfo *dinfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->mode = SSI_SD_CMD;
 | 
					    s->mode = SSI_SD_CMD;
 | 
				
			||||||
@ -249,7 +250,7 @@ static int ssi_sd_init(SSISlave *dev)
 | 
				
			|||||||
    if (s->sd == NULL) {
 | 
					    if (s->sd == NULL) {
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    register_savevm(&dev->qdev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
 | 
					    register_savevm(dev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								hw/ssi/ssi.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								hw/ssi/ssi.c
									
									
									
									
									
								
							@ -15,7 +15,7 @@
 | 
				
			|||||||
#include "hw/ssi.h"
 | 
					#include "hw/ssi.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SSIBus {
 | 
					struct SSIBus {
 | 
				
			||||||
    BusState qbus;
 | 
					    BusState parent_obj;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TYPE_SSI_BUS "SSI"
 | 
					#define TYPE_SSI_BUS "SSI"
 | 
				
			||||||
@ -60,7 +60,7 @@ static int ssi_slave_init(DeviceState *dev)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (ssc->transfer_raw == ssi_transfer_raw_default &&
 | 
					    if (ssc->transfer_raw == ssi_transfer_raw_default &&
 | 
				
			||||||
            ssc->cs_polarity != SSI_CS_NONE) {
 | 
					            ssc->cs_polarity != SSI_CS_NONE) {
 | 
				
			||||||
        qdev_init_gpio_in(&s->qdev, ssi_cs_default, 1);
 | 
					        qdev_init_gpio_in(dev, ssi_cs_default, 1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ssc->init(s);
 | 
					    return ssc->init(s);
 | 
				
			||||||
@ -88,7 +88,7 @@ static const TypeInfo ssi_slave_info = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
DeviceState *ssi_create_slave_no_init(SSIBus *bus, const char *name)
 | 
					DeviceState *ssi_create_slave_no_init(SSIBus *bus, const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return qdev_create(&bus->qbus, name);
 | 
					    return qdev_create(BUS(bus), name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
 | 
					DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
 | 
				
			||||||
@ -108,11 +108,12 @@ SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
 | 
					uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    BusState *b = BUS(bus);
 | 
				
			||||||
    BusChild *kid;
 | 
					    BusChild *kid;
 | 
				
			||||||
    SSISlaveClass *ssc;
 | 
					    SSISlaveClass *ssc;
 | 
				
			||||||
    uint32_t r = 0;
 | 
					    uint32_t r = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
 | 
					    QTAILQ_FOREACH(kid, &b->children, sibling) {
 | 
				
			||||||
        SSISlave *slave = SSI_SLAVE(kid->child);
 | 
					        SSISlave *slave = SSI_SLAVE(kid->child);
 | 
				
			||||||
        ssc = SSI_SLAVE_GET_CLASS(slave);
 | 
					        ssc = SSI_SLAVE_GET_CLASS(slave);
 | 
				
			||||||
        r |= ssc->transfer_raw(slave, val);
 | 
					        r |= ssc->transfer_raw(slave, val);
 | 
				
			||||||
@ -156,7 +157,7 @@ static int ssi_auto_connect_slave(Object *child, void *opaque)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cs_line = qdev_get_gpio_in(DEVICE(dev), 0);
 | 
					    cs_line = qdev_get_gpio_in(DEVICE(dev), 0);
 | 
				
			||||||
    qdev_set_parent_bus(DEVICE(dev), &arg->bus->qbus);
 | 
					    qdev_set_parent_bus(DEVICE(dev), BUS(arg->bus));
 | 
				
			||||||
    **arg->cs_linep = cs_line;
 | 
					    **arg->cs_linep = cs_line;
 | 
				
			||||||
    (*arg->cs_linep)++;
 | 
					    (*arg->cs_linep)++;
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@
 | 
				
			|||||||
#include "sysemu/blockdev.h"
 | 
					#include "sysemu/blockdev.h"
 | 
				
			||||||
#include "sysemu/qemumachine.h"
 | 
					#include "sysemu/qemumachine.h"
 | 
				
			||||||
#include "hw/qdev.h"
 | 
					#include "hw/qdev.h"
 | 
				
			||||||
 | 
					#include "qom/object.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct QEMUMachineInitArgs {
 | 
					typedef struct QEMUMachineInitArgs {
 | 
				
			||||||
    const QEMUMachine *machine;
 | 
					    const QEMUMachine *machine;
 | 
				
			||||||
@ -50,9 +51,59 @@ struct QEMUMachine {
 | 
				
			|||||||
    const char *hw_version;
 | 
					    const char *hw_version;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TYPE_MACHINE_SUFFIX "-machine"
 | 
				
			||||||
int qemu_register_machine(QEMUMachine *m);
 | 
					int qemu_register_machine(QEMUMachine *m);
 | 
				
			||||||
QEMUMachine *find_default_machine(void);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern QEMUMachine *current_machine;
 | 
					#define TYPE_MACHINE "machine"
 | 
				
			||||||
 | 
					#define MACHINE(obj) \
 | 
				
			||||||
 | 
					    OBJECT_CHECK(MachineState, (obj), TYPE_MACHINE)
 | 
				
			||||||
 | 
					#define MACHINE_GET_CLASS(obj) \
 | 
				
			||||||
 | 
					    OBJECT_GET_CLASS(MachineClass, (obj), TYPE_MACHINE)
 | 
				
			||||||
 | 
					#define MACHINE_CLASS(klass) \
 | 
				
			||||||
 | 
					    OBJECT_CLASS_CHECK(MachineClass, (klass), TYPE_MACHINE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct MachineState MachineState;
 | 
				
			||||||
 | 
					typedef struct MachineClass MachineClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MachineClass *find_default_machine(void);
 | 
				
			||||||
 | 
					extern MachineState *current_machine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * MachineClass:
 | 
				
			||||||
 | 
					 * @qemu_machine: #QEMUMachine
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct MachineClass {
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    ObjectClass parent_class;
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QEMUMachine *qemu_machine;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * MachineState:
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct MachineState {
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    Object parent_obj;
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *accel;
 | 
				
			||||||
 | 
					    bool kernel_irqchip;
 | 
				
			||||||
 | 
					    int kvm_shadow_mem;
 | 
				
			||||||
 | 
					    char *kernel;
 | 
				
			||||||
 | 
					    char *initrd;
 | 
				
			||||||
 | 
					    char *append;
 | 
				
			||||||
 | 
					    char *dtb;
 | 
				
			||||||
 | 
					    char *dumpdtb;
 | 
				
			||||||
 | 
					    int phandle_start;
 | 
				
			||||||
 | 
					    char *dt_compatible;
 | 
				
			||||||
 | 
					    bool dump_guest_core;
 | 
				
			||||||
 | 
					    bool mem_merge;
 | 
				
			||||||
 | 
					    bool usb;
 | 
				
			||||||
 | 
					    char *firmware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QEMUMachineInitArgs init_args;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,8 @@ typedef int (*qdev_event)(DeviceState *dev);
 | 
				
			|||||||
typedef void (*qdev_resetfn)(DeviceState *dev);
 | 
					typedef void (*qdev_resetfn)(DeviceState *dev);
 | 
				
			||||||
typedef void (*DeviceRealize)(DeviceState *dev, Error **errp);
 | 
					typedef void (*DeviceRealize)(DeviceState *dev, Error **errp);
 | 
				
			||||||
typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
 | 
					typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
 | 
				
			||||||
 | 
					typedef void (*BusRealize)(BusState *bus, Error **errp);
 | 
				
			||||||
 | 
					typedef void (*BusUnrealize)(BusState *bus, Error **errp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct VMStateDescription;
 | 
					struct VMStateDescription;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -174,6 +176,9 @@ struct BusClass {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    char *(*get_fw_dev_path)(DeviceState *dev);
 | 
					    char *(*get_fw_dev_path)(DeviceState *dev);
 | 
				
			||||||
    void (*reset)(BusState *bus);
 | 
					    void (*reset)(BusState *bus);
 | 
				
			||||||
 | 
					    BusRealize realize;
 | 
				
			||||||
 | 
					    BusUnrealize unrealize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* maximum devices allowed on the bus, 0: no limit. */
 | 
					    /* maximum devices allowed on the bus, 0: no limit. */
 | 
				
			||||||
    int max_dev;
 | 
					    int max_dev;
 | 
				
			||||||
    /* number of automatically allocated bus ids (e.g. ide.0) */
 | 
					    /* number of automatically allocated bus ids (e.g. ide.0) */
 | 
				
			||||||
@ -199,6 +204,7 @@ struct BusState {
 | 
				
			|||||||
    int allow_hotplug;
 | 
					    int allow_hotplug;
 | 
				
			||||||
    HotplugHandler *hotplug_handler;
 | 
					    HotplugHandler *hotplug_handler;
 | 
				
			||||||
    int max_index;
 | 
					    int max_index;
 | 
				
			||||||
 | 
					    bool realized;
 | 
				
			||||||
    QTAILQ_HEAD(ChildrenHead, BusChild) children;
 | 
					    QTAILQ_HEAD(ChildrenHead, BusChild) children;
 | 
				
			||||||
    QLIST_ENTRY(BusState) sibling;
 | 
					    QLIST_ENTRY(BusState) sibling;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -56,13 +56,12 @@ typedef struct SSISlaveClass {
 | 
				
			|||||||
} SSISlaveClass;
 | 
					} SSISlaveClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SSISlave {
 | 
					struct SSISlave {
 | 
				
			||||||
    DeviceState qdev;
 | 
					    DeviceState parent_obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Chip select state */
 | 
					    /* Chip select state */
 | 
				
			||||||
    bool cs;
 | 
					    bool cs;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SSI_SLAVE_FROM_QDEV(dev) DO_UPCAST(SSISlave, qdev, dev)
 | 
					 | 
				
			||||||
#define FROM_SSI_SLAVE(type, dev) DO_UPCAST(type, ssidev, dev)
 | 
					#define FROM_SSI_SLAVE(type, dev) DO_UPCAST(type, ssidev, dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const VMStateDescription vmstate_ssi_slave;
 | 
					extern const VMStateDescription vmstate_ssi_slave;
 | 
				
			||||||
 | 
				
			|||||||
@ -81,15 +81,15 @@ typedef struct VirtIOSerialPortClass {
 | 
				
			|||||||
    bool is_console;
 | 
					    bool is_console;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * The per-port (or per-app) init function that's called when a
 | 
					     * The per-port (or per-app) realize function that's called when a
 | 
				
			||||||
     * new device is found on the bus.
 | 
					     * new device is found on the bus.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    int (*init)(VirtIOSerialPort *port);
 | 
					    DeviceRealize realize;
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Per-port exit function that's called when a port gets
 | 
					     * Per-port unrealize function that's called when a port gets
 | 
				
			||||||
     * hot-unplugged or removed.
 | 
					     * hot-unplugged or removed.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    int (*exit)(VirtIOSerialPort *port);
 | 
					    DeviceUnrealize unrealize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Callbacks for guest events */
 | 
					    /* Callbacks for guest events */
 | 
				
			||||||
        /* Guest opened/closed device. */
 | 
					        /* Guest opened/closed device. */
 | 
				
			||||||
 | 
				
			|||||||
@ -522,7 +522,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 | 
				
			|||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* create device, set properties */
 | 
					    /* create device */
 | 
				
			||||||
    dev = DEVICE(object_new(driver));
 | 
					    dev = DEVICE(object_new(driver));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (bus) {
 | 
					    if (bus) {
 | 
				
			||||||
@ -533,11 +533,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 | 
				
			|||||||
    if (id) {
 | 
					    if (id) {
 | 
				
			||||||
        dev->id = id;
 | 
					        dev->id = id;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (qemu_opt_foreach(opts, set_property, dev, 1) != 0) {
 | 
					
 | 
				
			||||||
        object_unparent(OBJECT(dev));
 | 
					 | 
				
			||||||
        object_unref(OBJECT(dev));
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (dev->id) {
 | 
					    if (dev->id) {
 | 
				
			||||||
        object_property_add_child(qdev_get_peripheral(), dev->id,
 | 
					        object_property_add_child(qdev_get_peripheral(), dev->id,
 | 
				
			||||||
                                  OBJECT(dev), NULL);
 | 
					                                  OBJECT(dev), NULL);
 | 
				
			||||||
@ -549,6 +545,13 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 | 
				
			|||||||
        g_free(name);
 | 
					        g_free(name);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* set properties */
 | 
				
			||||||
 | 
					    if (qemu_opt_foreach(opts, set_property, dev, 1) != 0) {
 | 
				
			||||||
 | 
					        object_unparent(OBJECT(dev));
 | 
				
			||||||
 | 
					        object_unref(OBJECT(dev));
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dev->opts = opts;
 | 
					    dev->opts = opts;
 | 
				
			||||||
    object_property_set_bool(OBJECT(dev), true, "realized", &err);
 | 
					    object_property_set_bool(OBJECT(dev), true, "realized", &err);
 | 
				
			||||||
    if (err != NULL) {
 | 
					    if (err != NULL) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										7
									
								
								qmp.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								qmp.c
									
									
									
									
									
								
							@ -114,8 +114,11 @@ void qmp_cpu(int64_t index, Error **errp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void qmp_cpu_add(int64_t id, Error **errp)
 | 
					void qmp_cpu_add(int64_t id, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (current_machine->hot_add_cpu) {
 | 
					    MachineClass *mc;
 | 
				
			||||||
        current_machine->hot_add_cpu(id, errp);
 | 
					
 | 
				
			||||||
 | 
					    mc = MACHINE_GET_CLASS(current_machine);
 | 
				
			||||||
 | 
					    if (mc->qemu_machine->hot_add_cpu) {
 | 
				
			||||||
 | 
					        mc->qemu_machine->hot_add_cpu(id, errp);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        error_setg(errp, "Not supported");
 | 
					        error_setg(errp, "Not supported");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								qom/object.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								qom/object.c
									
									
									
									
									
								
							@ -1293,6 +1293,7 @@ void object_property_add_str(Object *obj, const char *name,
 | 
				
			|||||||
                           void (*set)(Object *, const char *, Error **),
 | 
					                           void (*set)(Object *, const char *, Error **),
 | 
				
			||||||
                           Error **errp)
 | 
					                           Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Error *local_err = NULL;
 | 
				
			||||||
    StringProperty *prop = g_malloc0(sizeof(*prop));
 | 
					    StringProperty *prop = g_malloc0(sizeof(*prop));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    prop->get = get;
 | 
					    prop->get = get;
 | 
				
			||||||
@ -1302,7 +1303,11 @@ void object_property_add_str(Object *obj, const char *name,
 | 
				
			|||||||
                        get ? property_get_str : NULL,
 | 
					                        get ? property_get_str : NULL,
 | 
				
			||||||
                        set ? property_set_str : NULL,
 | 
					                        set ? property_set_str : NULL,
 | 
				
			||||||
                        property_release_str,
 | 
					                        property_release_str,
 | 
				
			||||||
                        prop, errp);
 | 
					                        prop, &local_err);
 | 
				
			||||||
 | 
					    if (local_err) {
 | 
				
			||||||
 | 
					        error_propagate(errp, local_err);
 | 
				
			||||||
 | 
					        g_free(prop);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct BoolProperty
 | 
					typedef struct BoolProperty
 | 
				
			||||||
@ -1349,6 +1354,7 @@ void object_property_add_bool(Object *obj, const char *name,
 | 
				
			|||||||
                              void (*set)(Object *, bool, Error **),
 | 
					                              void (*set)(Object *, bool, Error **),
 | 
				
			||||||
                              Error **errp)
 | 
					                              Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Error *local_err = NULL;
 | 
				
			||||||
    BoolProperty *prop = g_malloc0(sizeof(*prop));
 | 
					    BoolProperty *prop = g_malloc0(sizeof(*prop));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    prop->get = get;
 | 
					    prop->get = get;
 | 
				
			||||||
@ -1358,7 +1364,11 @@ void object_property_add_bool(Object *obj, const char *name,
 | 
				
			|||||||
                        get ? property_get_bool : NULL,
 | 
					                        get ? property_get_bool : NULL,
 | 
				
			||||||
                        set ? property_set_bool : NULL,
 | 
					                        set ? property_set_bool : NULL,
 | 
				
			||||||
                        property_release_bool,
 | 
					                        property_release_bool,
 | 
				
			||||||
                        prop, errp);
 | 
					                        prop, &local_err);
 | 
				
			||||||
 | 
					    if (local_err) {
 | 
				
			||||||
 | 
					        error_propagate(errp, local_err);
 | 
				
			||||||
 | 
					        g_free(prop);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *qdev_get_type(Object *obj, Error **errp)
 | 
					static char *qdev_get_type(Object *obj, Error **errp)
 | 
				
			||||||
 | 
				
			|||||||
@ -69,9 +69,24 @@ gcov-files-ipack-y += hw/ipack/ipack.c
 | 
				
			|||||||
check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF)
 | 
					check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF)
 | 
				
			||||||
gcov-files-ipack-y += hw/char/ipoctal232.c
 | 
					gcov-files-ipack-y += hw/char/ipoctal232.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check-qtest-virtioserial-y += tests/virtio-console-test$(EXESUF)
 | 
				
			||||||
 | 
					gcov-files-virtioserial-y += hw/char/virtio-console.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio.c
 | 
					gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio.c
 | 
				
			||||||
check-qtest-virtio-y += tests/virtio-net-test$(EXESUF)
 | 
					check-qtest-virtio-y += tests/virtio-net-test$(EXESUF)
 | 
				
			||||||
gcov-files-virtio-y += i386-softmmu/hw/net/virtio-net.c
 | 
					gcov-files-virtio-y += i386-softmmu/hw/net/virtio-net.c
 | 
				
			||||||
 | 
					check-qtest-virtio-y += tests/virtio-balloon-test$(EXESUF)
 | 
				
			||||||
 | 
					gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio-balloon.c
 | 
				
			||||||
 | 
					check-qtest-virtio-y += tests/virtio-blk-test$(EXESUF)
 | 
				
			||||||
 | 
					gcov-files-virtio-y += i386-softmmu/hw/block/virtio-blk.c
 | 
				
			||||||
 | 
					check-qtest-virtio-y += tests/virtio-rng-test$(EXESUF)
 | 
				
			||||||
 | 
					gcov-files-virtio-y += hw/virtio/virtio-rng.c
 | 
				
			||||||
 | 
					check-qtest-virtio-y += tests/virtio-scsi-test$(EXESUF)
 | 
				
			||||||
 | 
					gcov-files-virtio-y += i386-softmmu/hw/scsi/virtio-scsi.c
 | 
				
			||||||
 | 
					check-qtest-virtio-y += tests/virtio-serial-test$(EXESUF)
 | 
				
			||||||
 | 
					gcov-files-virtio-y += i386-softmmu/hw/char/virtio-serial-bus.c
 | 
				
			||||||
 | 
					check-qtest-virtio-y += $(check-qtest-virtioserial-y)
 | 
				
			||||||
 | 
					gcov-files-virtio-y += $(gcov-files-virtioserial-y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
check-qtest-pci-y += tests/e1000-test$(EXESUF)
 | 
					check-qtest-pci-y += tests/e1000-test$(EXESUF)
 | 
				
			||||||
gcov-files-pci-y += hw/net/e1000.c
 | 
					gcov-files-pci-y += hw/net/e1000.c
 | 
				
			||||||
@ -87,9 +102,9 @@ gcov-files-pci-y += hw/net/ne2000.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)
 | 
				
			||||||
gcov-files-pci-y += hw/char/tpci200.c
 | 
					gcov-files-pci-y += hw/ipack/tpci200.c
 | 
				
			||||||
check-qtest-pci-y += $(check-qtest-ipack-y)
 | 
					check-qtest-pci-y += $(check-qtest-ipack-y)
 | 
				
			||||||
gcov-files-pci-y += $(gcov-files-ipack-y) hw/ipack/tpci200.c
 | 
					gcov-files-pci-y += $(gcov-files-ipack-y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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)
 | 
				
			||||||
@ -129,6 +144,8 @@ check-qtest-arm-y = tests/tmp105-test$(EXESUF)
 | 
				
			|||||||
gcov-files-arm-y += hw/misc/tmp105.c
 | 
					gcov-files-arm-y += hw/misc/tmp105.c
 | 
				
			||||||
check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
 | 
					check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
 | 
				
			||||||
check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
 | 
					check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
 | 
				
			||||||
 | 
					check-qtest-ppc64-y += tests/spapr-phb-test$(EXESUF)
 | 
				
			||||||
 | 
					gcov-files-ppc64-y += ppc64-softmmu/hw/ppc/spapr_pci.c
 | 
				
			||||||
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
 | 
					check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
 | 
				
			||||||
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
 | 
					check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -225,6 +242,7 @@ libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
 | 
				
			|||||||
tests/rtc-test$(EXESUF): tests/rtc-test.o
 | 
					tests/rtc-test$(EXESUF): tests/rtc-test.o
 | 
				
			||||||
tests/m48t59-test$(EXESUF): tests/m48t59-test.o
 | 
					tests/m48t59-test$(EXESUF): tests/m48t59-test.o
 | 
				
			||||||
tests/endianness-test$(EXESUF): tests/endianness-test.o
 | 
					tests/endianness-test$(EXESUF): tests/endianness-test.o
 | 
				
			||||||
 | 
					tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
 | 
				
			||||||
tests/fdc-test$(EXESUF): tests/fdc-test.o
 | 
					tests/fdc-test$(EXESUF): tests/fdc-test.o
 | 
				
			||||||
tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
 | 
					tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
 | 
				
			||||||
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
 | 
					tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
 | 
				
			||||||
@ -239,7 +257,13 @@ tests/pcnet-test$(EXESUF): tests/pcnet-test.o
 | 
				
			|||||||
tests/eepro100-test$(EXESUF): tests/eepro100-test.o
 | 
					tests/eepro100-test$(EXESUF): tests/eepro100-test.o
 | 
				
			||||||
tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
 | 
					tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
 | 
				
			||||||
tests/ne2000-test$(EXESUF): tests/ne2000-test.o
 | 
					tests/ne2000-test$(EXESUF): tests/ne2000-test.o
 | 
				
			||||||
 | 
					tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o
 | 
				
			||||||
 | 
					tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o
 | 
				
			||||||
tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
 | 
					tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
 | 
				
			||||||
 | 
					tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o
 | 
				
			||||||
 | 
					tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o
 | 
				
			||||||
 | 
					tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o
 | 
				
			||||||
 | 
					tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o
 | 
				
			||||||
tests/tpci200-test$(EXESUF): tests/tpci200-test.o
 | 
					tests/tpci200-test$(EXESUF): tests/tpci200-test.o
 | 
				
			||||||
tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
 | 
					tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
 | 
				
			||||||
tests/qom-test$(EXESUF): tests/qom-test.o
 | 
					tests/qom-test$(EXESUF): tests/qom-test.o
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,7 @@
 | 
				
			|||||||
#include "qapi/qmp/json-parser.h"
 | 
					#include "qapi/qmp/json-parser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_IRQ 256
 | 
					#define MAX_IRQ 256
 | 
				
			||||||
 | 
					#define SOCKET_TIMEOUT 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QTestState *global_qtest;
 | 
					QTestState *global_qtest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,12 +79,16 @@ static int socket_accept(int sock)
 | 
				
			|||||||
    struct sockaddr_un addr;
 | 
					    struct sockaddr_un addr;
 | 
				
			||||||
    socklen_t addrlen;
 | 
					    socklen_t addrlen;
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					    struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT,
 | 
				
			||||||
 | 
					                               .tv_usec = 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout,
 | 
				
			||||||
 | 
					               sizeof(timeout));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    addrlen = sizeof(addr);
 | 
					    addrlen = sizeof(addr);
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
        ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
 | 
					        ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
 | 
				
			||||||
    } while (ret == -1 && errno == EINTR);
 | 
					    } while (ret == -1 && errno == EINTR);
 | 
				
			||||||
    g_assert_no_errno(ret);
 | 
					 | 
				
			||||||
    close(sock);
 | 
					    close(sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
@ -147,12 +152,16 @@ QTestState *qtest_init(const char *extra_args)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->fd = socket_accept(sock);
 | 
					    s->fd = socket_accept(sock);
 | 
				
			||||||
    s->qmp_fd = socket_accept(qmpsock);
 | 
					    if (s->fd >= 0) {
 | 
				
			||||||
 | 
					        s->qmp_fd = socket_accept(qmpsock);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    unlink(socket_path);
 | 
					    unlink(socket_path);
 | 
				
			||||||
    unlink(qmp_socket_path);
 | 
					    unlink(qmp_socket_path);
 | 
				
			||||||
    g_free(socket_path);
 | 
					    g_free(socket_path);
 | 
				
			||||||
    g_free(qmp_socket_path);
 | 
					    g_free(qmp_socket_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_assert(s->fd >= 0 && s->qmp_fd >= 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->rx = g_string_new("");
 | 
					    s->rx = g_string_new("");
 | 
				
			||||||
    for (i = 0; i < MAX_IRQ; i++) {
 | 
					    for (i = 0; i < MAX_IRQ; i++) {
 | 
				
			||||||
        s->irq_level[i] = false;
 | 
					        s->irq_level[i] = false;
 | 
				
			||||||
 | 
				
			|||||||
@ -32,8 +32,7 @@ static void test_device_add(void)
 | 
				
			|||||||
                   "}}");
 | 
					                   "}}");
 | 
				
			||||||
    g_assert(response);
 | 
					    g_assert(response);
 | 
				
			||||||
    error = qdict_get_qdict(response, "error");
 | 
					    error = qdict_get_qdict(response, "error");
 | 
				
			||||||
    g_assert(!strcmp(qdict_get_try_str(error, "desc") ?: "",
 | 
					    g_assert_cmpstr(qdict_get_try_str(error, "class"), ==, "GenericError");
 | 
				
			||||||
                     "Device needs media, but drive is empty"));
 | 
					 | 
				
			||||||
    QDECREF(response);
 | 
					    QDECREF(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Delete the drive */
 | 
					    /* Delete the drive */
 | 
				
			||||||
@ -42,7 +41,7 @@ static void test_device_add(void)
 | 
				
			|||||||
                   "   \"command-line\": \"drive_del drive0\""
 | 
					                   "   \"command-line\": \"drive_del drive0\""
 | 
				
			||||||
                   "}}");
 | 
					                   "}}");
 | 
				
			||||||
    g_assert(response);
 | 
					    g_assert(response);
 | 
				
			||||||
    g_assert(!strcmp(qdict_get_try_str(response, "return") ?: "(null)", ""));
 | 
					    g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "");
 | 
				
			||||||
    QDECREF(response);
 | 
					    QDECREF(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Try to re-add the drive.  This fails with duplicate IDs if a leaked
 | 
					    /* Try to re-add the drive.  This fails with duplicate IDs if a leaked
 | 
				
			||||||
@ -53,8 +52,7 @@ static void test_device_add(void)
 | 
				
			|||||||
                   "   \"command-line\": \"drive_add pci-addr=auto if=none,id=drive0\""
 | 
					                   "   \"command-line\": \"drive_add pci-addr=auto if=none,id=drive0\""
 | 
				
			||||||
                   "}}");
 | 
					                   "}}");
 | 
				
			||||||
    g_assert(response);
 | 
					    g_assert(response);
 | 
				
			||||||
    g_assert(!strcmp(qdict_get_try_str(response, "return") ?: "",
 | 
					    g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
 | 
				
			||||||
                     "OK\r\n"));
 | 
					 | 
				
			||||||
    QDECREF(response);
 | 
					    QDECREF(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qtest_end();
 | 
					    qtest_end();
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@
 | 
				
			|||||||
#include <glib.h>
 | 
					#include <glib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "libqtest.h"
 | 
					#include "libqtest.h"
 | 
				
			||||||
#include "qemu/osdep.h"
 | 
					#include "qemu/osdep.h"
 | 
				
			||||||
#include "qapi/qmp/types.h"
 | 
					#include "qapi/qmp/types.h"
 | 
				
			||||||
@ -43,6 +44,40 @@ static bool is_blacklisted(const char *arch, const char *mach)
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_properties(const char *path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *child_path;
 | 
				
			||||||
 | 
					    QDict *response, *tuple;
 | 
				
			||||||
 | 
					    QList *list;
 | 
				
			||||||
 | 
					    QListEntry *entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_test_message("Obtaining properties of %s", path);
 | 
				
			||||||
 | 
					    response = qmp("{ 'execute': 'qom-list',"
 | 
				
			||||||
 | 
					                   "  'arguments': { 'path': '%s' } }", path);
 | 
				
			||||||
 | 
					    g_assert(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_assert(qdict_haskey(response, "return"));
 | 
				
			||||||
 | 
					    list = qobject_to_qlist(qdict_get(response, "return"));
 | 
				
			||||||
 | 
					    QLIST_FOREACH_ENTRY(list, entry) {
 | 
				
			||||||
 | 
					        tuple = qobject_to_qdict(qlist_entry_obj(entry));
 | 
				
			||||||
 | 
					        if (strstart(qdict_get_str(tuple, "type"), "child<", NULL)) {
 | 
				
			||||||
 | 
					            child_path = g_strdup_printf("%s/%s",
 | 
				
			||||||
 | 
					                                         path, qdict_get_str(tuple, "name"));
 | 
				
			||||||
 | 
					            test_properties(child_path);
 | 
				
			||||||
 | 
					            g_free(child_path);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            const char *prop = qdict_get_str(tuple, "name");
 | 
				
			||||||
 | 
					            g_test_message("Testing property %s.%s", path, prop);
 | 
				
			||||||
 | 
					            response = qmp("{ 'execute': 'qom-get',"
 | 
				
			||||||
 | 
					                           "  'arguments': { 'path': '%s',"
 | 
				
			||||||
 | 
					                           "                 'property': '%s' } }",
 | 
				
			||||||
 | 
					                           path, prop);
 | 
				
			||||||
 | 
					            /* qom-get may fail but should not, e.g., segfault. */
 | 
				
			||||||
 | 
					            g_assert(response);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void test_machine(gconstpointer data)
 | 
					static void test_machine(gconstpointer data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *machine = data;
 | 
					    const char *machine = data;
 | 
				
			||||||
@ -51,8 +86,12 @@ static void test_machine(gconstpointer data)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    args = g_strdup_printf("-machine %s", machine);
 | 
					    args = g_strdup_printf("-machine %s", machine);
 | 
				
			||||||
    qtest_start(args);
 | 
					    qtest_start(args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test_properties("/machine");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = qmp("{ 'execute': 'quit' }");
 | 
					    response = qmp("{ 'execute': 'quit' }");
 | 
				
			||||||
    g_assert(qdict_haskey(response, "return"));
 | 
					    g_assert(qdict_haskey(response, "return"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qtest_end();
 | 
					    qtest_end();
 | 
				
			||||||
    g_free(args);
 | 
					    g_free(args);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										35
									
								
								tests/spapr-phb-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								tests/spapr-phb-test.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QTest testcase for SPAPR PHB
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors:
 | 
				
			||||||
 | 
					 *  Alexey Kardashevskiy <aik@ozlabs.ru>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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 "libqtest.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Tests only initialization so far. TODO: Replace with functional tests */
 | 
				
			||||||
 | 
					static void test_phb_device(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_test_init(&argc, &argv, NULL);
 | 
				
			||||||
 | 
					    qtest_add_func("/spapr-phb/device", test_phb_device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_start("-device " TYPE_SPAPR_PCI_HOST_BRIDGE ",index=100");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = g_test_run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								tests/virtio-balloon-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tests/virtio-balloon-test.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QTest testcase for VirtIO Balloon
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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("/virtio/balloon/pci/nop", pci_nop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_start("-device virtio-balloon-pci");
 | 
				
			||||||
 | 
					    ret = g_test_run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								tests/virtio-blk-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tests/virtio-blk-test.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QTest testcase for VirtIO Block Device
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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("/virtio/blk/pci/nop", pci_nop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_start("-drive id=drv0,if=none,file=/dev/null "
 | 
				
			||||||
 | 
					                "-device virtio-blk-pci,drive=drv0");
 | 
				
			||||||
 | 
					    ret = g_test_run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								tests/virtio-console-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tests/virtio-console-test.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QTest testcase for VirtIO Console
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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("/virtio/console/pci/nop", pci_nop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_start("-device virtio-serial-pci,id=vser0 "
 | 
				
			||||||
 | 
					                "-device virtconsole,bus=vser0.0");
 | 
				
			||||||
 | 
					    ret = g_test_run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								tests/virtio-rng-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tests/virtio-rng-test.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QTest testcase for VirtIO RNG
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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("/virtio/rng/pci/nop", pci_nop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_start("-device virtio-rng-pci");
 | 
				
			||||||
 | 
					    ret = g_test_run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								tests/virtio-scsi-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								tests/virtio-scsi-test.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QTest testcase for VirtIO SCSI
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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("/virtio/scsi/pci/nop", pci_nop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_start("-drive id=drv0,if=none,file=/dev/null "
 | 
				
			||||||
 | 
					                "-device virtio-scsi-pci,id=vscsi0 "
 | 
				
			||||||
 | 
					                "-device scsi-hd,bus=vscsi0.0,drive=drv0");
 | 
				
			||||||
 | 
					    ret = g_test_run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								tests/virtio-serial-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tests/virtio-serial-test.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QTest testcase for VirtIO Serial
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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("/virtio/serial/pci/nop", pci_nop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_start("-device virtio-serial-pci");
 | 
				
			||||||
 | 
					    ret = g_test_run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qtest_end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										129
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								vl.c
									
									
									
									
									
								
							@ -1571,54 +1571,82 @@ void pcmcia_info(Monitor *mon, const QDict *qdict)
 | 
				
			|||||||
/***********************************************************/
 | 
					/***********************************************************/
 | 
				
			||||||
/* machine registration */
 | 
					/* machine registration */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static QEMUMachine *first_machine = NULL;
 | 
					MachineState *current_machine;
 | 
				
			||||||
QEMUMachine *current_machine = NULL;
 | 
					
 | 
				
			||||||
 | 
					static void machine_class_init(ObjectClass *oc, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MachineClass *mc = MACHINE_CLASS(oc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mc->qemu_machine = data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int qemu_register_machine(QEMUMachine *m)
 | 
					int qemu_register_machine(QEMUMachine *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QEMUMachine **pm;
 | 
					    TypeInfo ti = {
 | 
				
			||||||
    pm = &first_machine;
 | 
					        .name       = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL),
 | 
				
			||||||
    while (*pm != NULL)
 | 
					        .parent     = TYPE_MACHINE,
 | 
				
			||||||
        pm = &(*pm)->next;
 | 
					        .class_init = machine_class_init,
 | 
				
			||||||
    m->next = NULL;
 | 
					        .class_data = (void *)m,
 | 
				
			||||||
    *pm = m;
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    type_register(&ti);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static QEMUMachine *find_machine(const char *name)
 | 
					static MachineClass *find_machine(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QEMUMachine *m;
 | 
					    GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
 | 
				
			||||||
 | 
					    MachineClass *mc = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(m = first_machine; m != NULL; m = m->next) {
 | 
					    for (el = machines; el; el = el->next) {
 | 
				
			||||||
        if (!strcmp(m->name, name))
 | 
					        MachineClass *temp = el->data;
 | 
				
			||||||
            return m;
 | 
					 | 
				
			||||||
        if (m->alias && !strcmp(m->alias, name))
 | 
					 | 
				
			||||||
            return m;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
QEMUMachine *find_default_machine(void)
 | 
					        if (!strcmp(temp->qemu_machine->name, name)) {
 | 
				
			||||||
{
 | 
					            mc = temp;
 | 
				
			||||||
    QEMUMachine *m;
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    for(m = first_machine; m != NULL; m = m->next) {
 | 
					        if (temp->qemu_machine->alias &&
 | 
				
			||||||
        if (m->is_default) {
 | 
					            !strcmp(temp->qemu_machine->alias, name)) {
 | 
				
			||||||
            return m;
 | 
					            mc = temp;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return NULL;
 | 
					
 | 
				
			||||||
 | 
					    g_slist_free(machines);
 | 
				
			||||||
 | 
					    return mc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MachineClass *find_default_machine(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
 | 
				
			||||||
 | 
					    MachineClass *mc = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (el = machines; el; el = el->next) {
 | 
				
			||||||
 | 
					        MachineClass *temp = el->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (temp->qemu_machine->is_default) {
 | 
				
			||||||
 | 
					            mc = temp;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_slist_free(machines);
 | 
				
			||||||
 | 
					    return mc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MachineInfoList *qmp_query_machines(Error **errp)
 | 
					MachineInfoList *qmp_query_machines(Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
 | 
				
			||||||
    MachineInfoList *mach_list = NULL;
 | 
					    MachineInfoList *mach_list = NULL;
 | 
				
			||||||
    QEMUMachine *m;
 | 
					    QEMUMachine *m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (m = first_machine; m; m = m->next) {
 | 
					    for (el = machines; el; el = el->next) {
 | 
				
			||||||
 | 
					        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 (m->is_default) {
 | 
				
			||||||
            info->has_is_default = true;
 | 
					            info->has_is_default = true;
 | 
				
			||||||
@ -1639,6 +1667,7 @@ MachineInfoList *qmp_query_machines(Error **errp)
 | 
				
			|||||||
        mach_list = entry;
 | 
					        mach_list = entry;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_slist_free(machines);
 | 
				
			||||||
    return mach_list;
 | 
					    return mach_list;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1832,8 +1861,12 @@ void qemu_devices_reset(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void qemu_system_reset(bool report)
 | 
					void qemu_system_reset(bool report)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (current_machine && current_machine->reset) {
 | 
					    MachineClass *mc;
 | 
				
			||||||
        current_machine->reset();
 | 
					
 | 
				
			||||||
 | 
					    mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (mc && mc->qemu_machine->reset) {
 | 
				
			||||||
 | 
					        mc->qemu_machine->reset();
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        qemu_devices_reset();
 | 
					        qemu_devices_reset();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -2605,24 +2638,29 @@ static int debugcon_parse(const char *devname)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static QEMUMachine *machine_parse(const char *name)
 | 
					static MachineClass *machine_parse(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QEMUMachine *m, *machine = NULL;
 | 
					    MachineClass *mc = NULL;
 | 
				
			||||||
 | 
					    GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (name) {
 | 
					    if (name) {
 | 
				
			||||||
        machine = find_machine(name);
 | 
					        mc = find_machine(name);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (machine) {
 | 
					    if (mc) {
 | 
				
			||||||
        return machine;
 | 
					        return mc;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    printf("Supported machines are:\n");
 | 
					    printf("Supported machines are:\n");
 | 
				
			||||||
    for (m = first_machine; m != NULL; m = m->next) {
 | 
					    for (el = machines; el; el = el->next) {
 | 
				
			||||||
 | 
					        MachineClass *mc = el->data;
 | 
				
			||||||
 | 
					        QEMUMachine *m = mc->qemu_machine;
 | 
				
			||||||
        if (m->alias) {
 | 
					        if (m->alias) {
 | 
				
			||||||
            printf("%-20s %s (alias of %s)\n", m->alias, m->desc, m->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", m->name, m->desc,
 | 
				
			||||||
               m->is_default ? " (default)" : "");
 | 
					               m->is_default ? " (default)" : "");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_slist_free(machines);
 | 
				
			||||||
    exit(!name || !is_help_option(name));
 | 
					    exit(!name || !is_help_option(name));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2871,6 +2909,7 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
    int optind;
 | 
					    int optind;
 | 
				
			||||||
    const char *optarg;
 | 
					    const char *optarg;
 | 
				
			||||||
    const char *loadvm = NULL;
 | 
					    const char *loadvm = NULL;
 | 
				
			||||||
 | 
					    MachineClass *machine_class;
 | 
				
			||||||
    QEMUMachine *machine;
 | 
					    QEMUMachine *machine;
 | 
				
			||||||
    const char *cpu_model;
 | 
					    const char *cpu_model;
 | 
				
			||||||
    const char *vga_model = "none";
 | 
					    const char *vga_model = "none";
 | 
				
			||||||
@ -2945,7 +2984,7 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
    os_setup_early_signal_handling();
 | 
					    os_setup_early_signal_handling();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    module_call_init(MODULE_INIT_MACHINE);
 | 
					    module_call_init(MODULE_INIT_MACHINE);
 | 
				
			||||||
    machine = find_default_machine();
 | 
					    machine_class = find_default_machine();
 | 
				
			||||||
    cpu_model = NULL;
 | 
					    cpu_model = NULL;
 | 
				
			||||||
    ram_size = 0;
 | 
					    ram_size = 0;
 | 
				
			||||||
    snapshot = 0;
 | 
					    snapshot = 0;
 | 
				
			||||||
@ -3011,7 +3050,7 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            switch(popt->index) {
 | 
					            switch(popt->index) {
 | 
				
			||||||
            case QEMU_OPTION_M:
 | 
					            case QEMU_OPTION_M:
 | 
				
			||||||
                machine = machine_parse(optarg);
 | 
					                machine_class = machine_parse(optarg);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case QEMU_OPTION_no_kvm_irqchip: {
 | 
					            case QEMU_OPTION_no_kvm_irqchip: {
 | 
				
			||||||
                olist = qemu_find_opts("machine");
 | 
					                olist = qemu_find_opts("machine");
 | 
				
			||||||
@ -3567,7 +3606,7 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                optarg = qemu_opt_get(opts, "type");
 | 
					                optarg = qemu_opt_get(opts, "type");
 | 
				
			||||||
                if (optarg) {
 | 
					                if (optarg) {
 | 
				
			||||||
                    machine = machine_parse(optarg);
 | 
					                    machine_class = machine_parse(optarg);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
             case QEMU_OPTION_no_kvm:
 | 
					             case QEMU_OPTION_no_kvm:
 | 
				
			||||||
@ -3873,11 +3912,17 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (machine == NULL) {
 | 
					    if (machine_class == NULL) {
 | 
				
			||||||
        fprintf(stderr, "No machine found.\n");
 | 
					        fprintf(stderr, "No machine found.\n");
 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    current_machine = MACHINE(object_new(object_class_get_name(
 | 
				
			||||||
 | 
					                          OBJECT_CLASS(machine_class))));
 | 
				
			||||||
 | 
					    object_property_add_child(object_get_root(), "machine",
 | 
				
			||||||
 | 
					                              OBJECT(current_machine), &error_abort);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    machine = machine_class->qemu_machine;
 | 
				
			||||||
    if (machine->hw_version) {
 | 
					    if (machine->hw_version) {
 | 
				
			||||||
        qemu_set_version(machine->hw_version);
 | 
					        qemu_set_version(machine->hw_version);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -4306,7 +4351,9 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
                                 .kernel_cmdline = kernel_cmdline,
 | 
					                                 .kernel_cmdline = kernel_cmdline,
 | 
				
			||||||
                                 .initrd_filename = initrd_filename,
 | 
					                                 .initrd_filename = initrd_filename,
 | 
				
			||||||
                                 .cpu_model = cpu_model };
 | 
					                                 .cpu_model = cpu_model };
 | 
				
			||||||
    machine->init(&args);
 | 
					
 | 
				
			||||||
 | 
					    current_machine->init_args = args;
 | 
				
			||||||
 | 
					    machine->init(¤t_machine->init_args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    audio_init();
 | 
					    audio_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -4314,8 +4361,6 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    set_numa_modes();
 | 
					    set_numa_modes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    current_machine = machine;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* init USB devices */
 | 
					    /* init USB devices */
 | 
				
			||||||
    if (usb_enabled(false)) {
 | 
					    if (usb_enabled(false)) {
 | 
				
			||||||
        if (foreach_device_config(DEV_USB, usb_parse) < 0)
 | 
					        if (foreach_device_config(DEV_USB, usb_parse) < 0)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user