/*
 * qdev property parsing
 * (parts specific for qemu-system-*)
 *
 * This file is based on code from hw/qdev-properties.c from
 * commit 074a86fccd185616469dfcdc0e157f438aebba18,
 * Copyright (c) Gerd Hoffmann <kraxel@redhat.com> and other contributors.
 *
 * 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 "qemu/osdep.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qapi/qapi-types-block.h"
#include "qapi/qapi-types-machine.h"
#include "qapi/qapi-types-migration.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ctype.h"
#include "qemu/cutils.h"
#include "qemu/units.h"
#include "qemu/uuid.h"
#include "qemu/error-report.h"
#include "qdev-prop-internal.h"

#include "audio/audio.h"
#include "chardev/char-fe.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "net/net.h"
#include "hw/pci/pci.h"
#include "hw/pci/pcie.h"
#include "hw/i386/x86.h"
#include "util/block-helpers.h"

static bool check_prop_still_unset(Object *obj, const char *name,
                                   const void *old_val, const char *new_val,
                                   bool allow_override, Error **errp)
{
    const GlobalProperty *prop = qdev_find_global_prop(obj, name);

    if (!old_val || (!prop && allow_override)) {
        return true;
    }

    if (prop) {
        error_setg(errp, "-global %s.%s=... conflicts with %s=%s",
                   prop->driver, prop->property, name, new_val);
    } else {
        /* Error message is vague, but a better one would be hard */
        error_setg(errp, "%s=%s conflicts, and override is not implemented",
                   name, new_val);
    }
    return false;
}


/* --- drive --- */

static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    Property *prop = opaque;
    void **ptr = object_field_prop_ptr(obj, prop);
    const char *value;
    char *p;

    if (*ptr) {
        value = blk_name(*ptr);
        if (!*value) {
            BlockDriverState *bs = blk_bs(*ptr);
            if (bs) {
                value = bdrv_get_node_name(bs);
            }
        }
    } else {
        value = "";
    }

    p = g_strdup(value);
    visit_type_str(v, name, &p, errp);
    g_free(p);
}

static void set_drive_helper(Object *obj, Visitor *v, const char *name,
                             void *opaque, bool iothread, Error **errp)
{
    DeviceState *dev = DEVICE(obj);
    Property *prop = opaque;
    void **ptr = object_field_prop_ptr(obj, prop);
    char *str;
    BlockBackend *blk;
    bool blk_created = false;
    int ret;
    BlockDriverState *bs;
    AioContext *ctx;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    if (!check_prop_still_unset(obj, name, *ptr, str, true, errp)) {
        return;
    }

    if (*ptr) {
        /* BlockBackend already exists. So, we want to change attached node */
        blk = *ptr;
        ctx = blk_get_aio_context(blk);
        bs = bdrv_lookup_bs(NULL, str, errp);
        if (!bs) {
            return;
        }

        if (ctx != bdrv_get_aio_context(bs)) {
            error_setg(errp, "Different aio context is not supported for new "
                       "node");
        }

        aio_context_acquire(ctx);
        blk_replace_bs(blk, bs, errp);
        aio_context_release(ctx);
        return;
    }

    if (!*str) {
        g_free(str);
        *ptr = NULL;
        return;
    }

    blk = blk_by_name(str);
    if (!blk) {
        bs = bdrv_lookup_bs(NULL, str, NULL);
        if (bs) {
            /*
             * If the device supports iothreads, it will make sure to move the
             * block node to the right AioContext if necessary (or fail if this
             * isn't possible because of other users). Devices that are not
             * aware of iothreads require their BlockBackends to be in the main
             * AioContext.
             */
            ctx = bdrv_get_aio_context(bs);
            blk = blk_new(iothread ? ctx : qemu_get_aio_context(),
                          0, BLK_PERM_ALL);
            blk_created = true;

            aio_context_acquire(ctx);
            ret = blk_insert_bs(blk, bs, errp);
            aio_context_release(ctx);

            if (ret < 0) {
                goto fail;
            }
        }
    }
    if (!blk) {
        error_setg(errp, "Property '%s.%s' can't find value '%s'",
                   object_get_typename(OBJECT(dev)), name, str);
        goto fail;
    }
    if (blk_attach_dev(blk, dev) < 0) {
        DriveInfo *dinfo = blk_legacy_dinfo(blk);

        if (dinfo && dinfo->type != IF_NONE) {
            error_setg(errp, "Drive '%s' is already in use because "
                       "it has been automatically connected to another "
                       "device (did you need 'if=none' in the drive options?)",
                       str);
        } else {
            error_setg(errp, "Drive '%s' is already in use by another device",
                       str);
        }
        goto fail;
    }

    *ptr = blk;

fail:
    if (blk_created) {
        /* If we need to keep a reference, blk_attach_dev() took it */
        blk_unref(blk);
    }

    g_free(str);
}

static void set_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    set_drive_helper(obj, v, name, opaque, false, errp);
}

static void set_drive_iothread(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
{
    set_drive_helper(obj, v, name, opaque, true, errp);
}

static void release_drive(Object *obj, const char *name, void *opaque)
{
    DeviceState *dev = DEVICE(obj);
    Property *prop = opaque;
    BlockBackend **ptr = object_field_prop_ptr(obj, prop);

    if (*ptr) {
        AioContext *ctx = blk_get_aio_context(*ptr);

        aio_context_acquire(ctx);
        blockdev_auto_del(*ptr);
        blk_detach_dev(*ptr, dev);
        aio_context_release(ctx);
    }
}

const PropertyInfo qdev_prop_drive = {
    .name  = "str",
    .description = "Node name or ID of a block device to use as a backend",
    .realized_set_allowed = true,
    .get   = get_drive,
    .set   = set_drive,
    .release = release_drive,
};

const PropertyInfo qdev_prop_drive_iothread = {
    .name  = "str",
    .description = "Node name or ID of a block device to use as a backend",
    .realized_set_allowed = true,
    .get   = get_drive,
    .set   = set_drive_iothread,
    .release = release_drive,
};

/* --- character device --- */

static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    CharBackend *be = object_field_prop_ptr(obj, opaque);
    char *p;

    p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
    visit_type_str(v, name, &p, errp);
    g_free(p);
}

static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    Property *prop = opaque;
    CharBackend *be = object_field_prop_ptr(obj, prop);
    Chardev *s;
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    /*
     * TODO Should this really be an error?  If no, the old value
     * needs to be released before we store the new one.
     */
    if (!check_prop_still_unset(obj, name, be->chr, str, false, errp)) {
        return;
    }

    if (!*str) {
        g_free(str);
        be->chr = NULL;
        return;
    }

    s = qemu_chr_find(str);
    if (s == NULL) {
        error_setg(errp, "Property '%s.%s' can't find value '%s'",
                   object_get_typename(obj), name, str);
    } else if (!qemu_chr_fe_init(be, s, errp)) {
        error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
                      object_get_typename(obj), name, str);
    }
    g_free(str);
}

static void release_chr(Object *obj, const char *name, void *opaque)
{
    Property *prop = opaque;
    CharBackend *be = object_field_prop_ptr(obj, prop);

    qemu_chr_fe_deinit(be, false);
}

const PropertyInfo qdev_prop_chr = {
    .name  = "str",
    .description = "ID of a chardev to use as a backend",
    .get   = get_chr,
    .set   = set_chr,
    .release = release_chr,
};

/* --- mac address --- */

/*
 * accepted syntax versions:
 *   01:02:03:04:05:06
 *   01-02-03-04-05-06
 */
static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    Property *prop = opaque;
    MACAddr *mac = object_field_prop_ptr(obj, prop);
    char buffer[2 * 6 + 5 + 1];
    char *p = buffer;

    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
             mac->a[0], mac->a[1], mac->a[2],
             mac->a[3], mac->a[4], mac->a[5]);

    visit_type_str(v, name, &p, errp);
}

static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    Property *prop = opaque;
    MACAddr *mac = object_field_prop_ptr(obj, prop);
    int i, pos;
    char *str;
    const char *p;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
        long val;

        if (!qemu_isxdigit(str[pos])) {
            goto inval;
        }
        if (!qemu_isxdigit(str[pos + 1])) {
            goto inval;
        }
        if (i == 5) {
            if (str[pos + 2] != '\0') {
                goto inval;
            }
        } else {
            if (str[pos + 2] != ':' && str[pos + 2] != '-') {
                goto inval;
            }
        }
        if (qemu_strtol(str + pos, &p, 16, &val) < 0 || val > 0xff) {
            goto inval;
        }
        mac->a[i] = val;
    }
    g_free(str);
    return;

inval:
    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    g_free(str);
}

const PropertyInfo qdev_prop_macaddr = {
    .name  = "str",
    .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
    .get   = get_mac,
    .set   = set_mac,
};

void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
                           const uint8_t *value)
{
    char str[2 * 6 + 5 + 1];
    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
             value[0], value[1], value[2], value[3], value[4], value[5]);

    object_property_set_str(OBJECT(dev), name, str, &error_abort);
}

/* --- netdev device --- */
static void get_netdev(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
    char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");

    visit_type_str(v, name, &p, errp);
    g_free(p);
}

static void set_netdev(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
    NetClientState **ncs = peers_ptr->ncs;
    NetClientState *peers[MAX_QUEUE_NUM];
    int queues, err = 0, i = 0;
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    queues = qemu_find_net_clients_except(str, peers,
                                          NET_CLIENT_DRIVER_NIC,
                                          MAX_QUEUE_NUM);
    if (queues == 0) {
        err = -ENOENT;
        goto out;
    }

    if (queues > MAX_QUEUE_NUM) {
        error_setg(errp, "queues of backend '%s'(%d) exceeds QEMU limitation(%d)",
                   str, queues, MAX_QUEUE_NUM);
        goto out;
    }

    for (i = 0; i < queues; i++) {
        if (peers[i]->peer) {
            err = -EEXIST;
            goto out;
        }

        /*
         * TODO Should this really be an error?  If no, the old value
         * needs to be released before we store the new one.
         */
        if (!check_prop_still_unset(obj, name, ncs[i], str, false, errp)) {
            goto out;
        }

        if (peers[i]->info->check_peer_type) {
            if (!peers[i]->info->check_peer_type(peers[i], obj->class, errp)) {
                goto out;
            }
        }

        ncs[i] = peers[i];
        ncs[i]->queue_index = i;
    }

    peers_ptr->queues = queues;

out:
    error_set_from_qdev_prop_error(errp, err, obj, name, str);
    g_free(str);
}

const PropertyInfo qdev_prop_netdev = {
    .name  = "str",
    .description = "ID of a netdev to use as a backend",
    .get   = get_netdev,
    .set   = set_netdev,
};


/* --- audiodev --- */
static void get_audiodev(Object *obj, Visitor *v, const char* name,
                         void *opaque, Error **errp)
{
    Property *prop = opaque;
    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
    char *p = g_strdup(audio_get_id(card));

    visit_type_str(v, name, &p, errp);
    g_free(p);
}

static void set_audiodev(Object *obj, Visitor *v, const char* name,
                         void *opaque, Error **errp)
{
    Property *prop = opaque;
    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
    AudioState *state;
    g_autofree char *str = NULL;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    state = audio_state_by_name(str, errp);
    if (state) {
        card->state = state;
    }
}

const PropertyInfo qdev_prop_audiodev = {
    .name = "str",
    .description = "ID of an audiodev to use as a backend",
    /* release done on shutdown */
    .get = get_audiodev,
    .set = set_audiodev,
};

bool qdev_prop_set_drive_err(DeviceState *dev, const char *name,
                             BlockBackend *value, Error **errp)
{
    const char *ref = "";

    if (value) {
        ref = blk_name(value);
        if (!*ref) {
            const BlockDriverState *bs = blk_bs(value);
            if (bs) {
                ref = bdrv_get_node_name(bs);
            }
        }
    }

    return object_property_set_str(OBJECT(dev), name, ref, errp);
}

void qdev_prop_set_drive(DeviceState *dev, const char *name,
                         BlockBackend *value)
{
    qdev_prop_set_drive_err(dev, name, value, &error_abort);
}

void qdev_prop_set_chr(DeviceState *dev, const char *name,
                       Chardev *value)
{
    assert(!value || value->label);
    object_property_set_str(OBJECT(dev), name, value ? value->label : "",
                            &error_abort);
}

void qdev_prop_set_netdev(DeviceState *dev, const char *name,
                          NetClientState *value)
{
    assert(!value || value->name);
    object_property_set_str(OBJECT(dev), name, value ? value->name : "",
                            &error_abort);
}

void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
{
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
    if (nd->netdev) {
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
    }
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
        object_property_find(OBJECT(dev), "vectors")) {
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
    }
    nd->instantiated = 1;
}

/* --- lost tick policy --- */

static void qdev_propinfo_set_losttickpolicy(Object *obj, Visitor *v,
                                             const char *name, void *opaque,
                                             Error **errp)
{
    Property *prop = opaque;
    int *ptr = object_field_prop_ptr(obj, prop);
    int value;

    if (!visit_type_enum(v, name, &value, prop->info->enum_table, errp)) {
        return;
    }

    if (value == LOST_TICK_POLICY_SLEW) {
        MachineState *ms = MACHINE(qdev_get_machine());

        if (!object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE)) {
            error_setg(errp,
                       "the 'slew' policy is only available for x86 machines");
            return;
        }
    }

    *ptr = value;
}

QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));

const PropertyInfo qdev_prop_losttickpolicy = {
    .name  = "LostTickPolicy",
    .enum_table  = &LostTickPolicy_lookup,
    .get   = qdev_propinfo_get_enum,
    .set   = qdev_propinfo_set_losttickpolicy,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- blocksize --- */

static void set_blocksize(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
{
    DeviceState *dev = DEVICE(obj);
    Property *prop = opaque;
    uint32_t *ptr = object_field_prop_ptr(obj, prop);
    uint64_t value;
    Error *local_err = NULL;

    if (!visit_type_size(v, name, &value, errp)) {
        return;
    }
    check_block_size(dev->id ? : "", name, value, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    *ptr = value;
}

const PropertyInfo qdev_prop_blocksize = {
    .name  = "size",
    .description = "A power of two between " MIN_BLOCK_SIZE_STR
                   " and " MAX_BLOCK_SIZE_STR,
    .get   = qdev_propinfo_get_size32,
    .set   = set_blocksize,
    .set_default_value = qdev_propinfo_set_default_value_uint,
};

/* --- Block device error handling policy --- */

QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));

const PropertyInfo qdev_prop_blockdev_on_error = {
    .name = "BlockdevOnError",
    .description = "Error handling policy, "
                   "report/ignore/enospc/stop/auto",
    .enum_table = &BlockdevOnError_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- BIOS CHS translation */

QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));

const PropertyInfo qdev_prop_bios_chs_trans = {
    .name = "BiosAtaTranslation",
    .description = "Logical CHS translation algorithm, "
                   "auto/none/lba/large/rechs",
    .enum_table = &BiosAtaTranslation_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- FDC default drive types */

const PropertyInfo qdev_prop_fdc_drive_type = {
    .name = "FdcDriveType",
    .description = "FDC drive type, "
                   "144/288/120/none/auto",
    .enum_table = &FloppyDriveType_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- MultiFDCompression --- */

const PropertyInfo qdev_prop_multifd_compression = {
    .name = "MultiFDCompression",
    .description = "multifd_compression values, "
                   "none/zlib/zstd",
    .enum_table = &MultiFDCompression_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- MigMode --- */

QEMU_BUILD_BUG_ON(sizeof(MigMode) != sizeof(int));

const PropertyInfo qdev_prop_mig_mode = {
    .name = "MigMode",
    .description = "mig_mode values, "
                   "normal",
    .enum_table = &MigMode_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- Reserved Region --- */

/*
 * Accepted syntax:
 *   <low address>:<high address>:<type>
 *   where low/high addresses are uint64_t in hexadecimal
 *   and type is a non-negative decimal integer
 */
static void get_reserved_region(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
{
    Property *prop = opaque;
    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
    char buffer[64];
    char *p = buffer;
    int rc;

    rc = snprintf(buffer, sizeof(buffer), "0x%"PRIx64":0x%"PRIx64":%u",
                  rr->low, rr->high, rr->type);
    assert(rc < sizeof(buffer));

    visit_type_str(v, name, &p, errp);
}

static void set_reserved_region(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
{
    Property *prop = opaque;
    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
    const char *endptr;
    char *str;
    int ret;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    ret = qemu_strtou64(str, &endptr, 16, &rr->low);
    if (ret) {
        error_setg(errp, "start address of '%s'"
                   " must be a hexadecimal integer", name);
        goto out;
    }
    if (*endptr != ':') {
        goto separator_error;
    }

    ret = qemu_strtou64(endptr + 1, &endptr, 16, &rr->high);
    if (ret) {
        error_setg(errp, "end address of '%s'"
                   " must be a hexadecimal integer", name);
        goto out;
    }
    if (*endptr != ':') {
        goto separator_error;
    }

    ret = qemu_strtoui(endptr + 1, &endptr, 10, &rr->type);
    if (ret) {
        error_setg(errp, "type of '%s'"
                   " must be a non-negative decimal integer", name);
    }
    goto out;

separator_error:
    error_setg(errp, "reserved region fields must be separated with ':'");
out:
    g_free(str);
    return;
}

const PropertyInfo qdev_prop_reserved_region = {
    .name  = "reserved_region",
    .description = "Reserved Region, example: 0xFEE00000:0xFEEFFFFF:0",
    .get   = get_reserved_region,
    .set   = set_reserved_region,
};

/* --- pci address --- */

/*
 * bus-local address, i.e. "$slot" or "$slot.$fn"
 */
static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
{
    Property *prop = opaque;
    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
    unsigned int slot, fn, n;
    char *str;

    if (!visit_type_str(v, name, &str, NULL)) {
        if (!visit_type_int32(v, name, &value, errp)) {
            return;
        }
        if (value < -1 || value > 255) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "a value between -1 and 255");
            return;
        }
        *ptr = value;
        return;
    }

    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
        fn = 0;
        if (sscanf(str, "%x%n", &slot, &n) != 1) {
            goto invalid;
        }
    }
    if (str[n] != '\0' || fn > 7 || slot > 31) {
        goto invalid;
    }
    *ptr = slot << 3 | fn;
    g_free(str);
    return;

invalid:
    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    g_free(str);
}

static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                           size_t len)
{
    int32_t *ptr = object_field_prop_ptr(obj, prop);

    if (*ptr == -1) {
        return snprintf(dest, len, "<unset>");
    } else {
        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
    }
}

const PropertyInfo qdev_prop_pci_devfn = {
    .name  = "int32",
    .description = "Slot and optional function number, example: 06.0 or 06",
    .print = print_pci_devfn,
    .get   = qdev_propinfo_get_int32,
    .set   = set_pci_devfn,
    .set_default_value = qdev_propinfo_set_default_value_int,
};

/* --- pci host address --- */

static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
    char buffer[] = "ffff:ff:ff.f";
    char *p = buffer;
    int rc = 0;

    /*
     * Catch "invalid" device reference from vfio-pci and allow the
     * default buffer representing the non-existent device to be used.
     */
    if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
        rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
                      addr->domain, addr->bus, addr->slot, addr->function);
        assert(rc == sizeof(buffer) - 1);
    }

    visit_type_str(v, name, &p, errp);
}

/*
 * Parse [<domain>:]<bus>:<slot>.<func>
 *   if <domain> is not supplied, it's assumed to be 0.
 */
static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
    char *str, *p;
    char *e;
    unsigned long val;
    unsigned long dom = 0, bus = 0;
    unsigned int slot = 0, func = 0;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    p = str;
    val = strtoul(p, &e, 16);
    if (e == p || *e != ':') {
        goto inval;
    }
    bus = val;

    p = e + 1;
    val = strtoul(p, &e, 16);
    if (e == p) {
        goto inval;
    }
    if (*e == ':') {
        dom = bus;
        bus = val;
        p = e + 1;
        val = strtoul(p, &e, 16);
        if (e == p) {
            goto inval;
        }
    }
    slot = val;

    if (*e != '.') {
        goto inval;
    }
    p = e + 1;
    val = strtoul(p, &e, 10);
    if (e == p) {
        goto inval;
    }
    func = val;

    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
        goto inval;
    }

    if (*e) {
        goto inval;
    }

    addr->domain = dom;
    addr->bus = bus;
    addr->slot = slot;
    addr->function = func;

    g_free(str);
    return;

inval:
    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    g_free(str);
}

const PropertyInfo qdev_prop_pci_host_devaddr = {
    .name = "str",
    .description = "Address (bus/device/function) of "
                   "the host device, example: 04:10.0",
    .get = get_pci_host_devaddr,
    .set = set_pci_host_devaddr,
};

/* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */

const PropertyInfo qdev_prop_off_auto_pcibar = {
    .name = "OffAutoPCIBAR",
    .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
    .enum_table = &OffAutoPCIBAR_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- PCIELinkSpeed 2_5/5/8/16 -- */

static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
    int speed;

    switch (*p) {
    case QEMU_PCI_EXP_LNK_2_5GT:
        speed = PCIE_LINK_SPEED_2_5;
        break;
    case QEMU_PCI_EXP_LNK_5GT:
        speed = PCIE_LINK_SPEED_5;
        break;
    case QEMU_PCI_EXP_LNK_8GT:
        speed = PCIE_LINK_SPEED_8;
        break;
    case QEMU_PCI_EXP_LNK_16GT:
        speed = PCIE_LINK_SPEED_16;
        break;
    default:
        /* Unreachable */
        abort();
    }

    visit_type_enum(v, name, &speed, prop->info->enum_table, errp);
}

static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
    int speed;

    if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
                         errp)) {
        return;
    }

    switch (speed) {
    case PCIE_LINK_SPEED_2_5:
        *p = QEMU_PCI_EXP_LNK_2_5GT;
        break;
    case PCIE_LINK_SPEED_5:
        *p = QEMU_PCI_EXP_LNK_5GT;
        break;
    case PCIE_LINK_SPEED_8:
        *p = QEMU_PCI_EXP_LNK_8GT;
        break;
    case PCIE_LINK_SPEED_16:
        *p = QEMU_PCI_EXP_LNK_16GT;
        break;
    default:
        /* Unreachable */
        abort();
    }
}

const PropertyInfo qdev_prop_pcie_link_speed = {
    .name = "PCIELinkSpeed",
    .description = "2_5/5/8/16",
    .enum_table = &PCIELinkSpeed_lookup,
    .get = get_prop_pcielinkspeed,
    .set = set_prop_pcielinkspeed,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */

static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
    int width;

    switch (*p) {
    case QEMU_PCI_EXP_LNK_X1:
        width = PCIE_LINK_WIDTH_1;
        break;
    case QEMU_PCI_EXP_LNK_X2:
        width = PCIE_LINK_WIDTH_2;
        break;
    case QEMU_PCI_EXP_LNK_X4:
        width = PCIE_LINK_WIDTH_4;
        break;
    case QEMU_PCI_EXP_LNK_X8:
        width = PCIE_LINK_WIDTH_8;
        break;
    case QEMU_PCI_EXP_LNK_X12:
        width = PCIE_LINK_WIDTH_12;
        break;
    case QEMU_PCI_EXP_LNK_X16:
        width = PCIE_LINK_WIDTH_16;
        break;
    case QEMU_PCI_EXP_LNK_X32:
        width = PCIE_LINK_WIDTH_32;
        break;
    default:
        /* Unreachable */
        abort();
    }

    visit_type_enum(v, name, &width, prop->info->enum_table, errp);
}

static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
    int width;

    if (!visit_type_enum(v, name, &width, prop->info->enum_table,
                         errp)) {
        return;
    }

    switch (width) {
    case PCIE_LINK_WIDTH_1:
        *p = QEMU_PCI_EXP_LNK_X1;
        break;
    case PCIE_LINK_WIDTH_2:
        *p = QEMU_PCI_EXP_LNK_X2;
        break;
    case PCIE_LINK_WIDTH_4:
        *p = QEMU_PCI_EXP_LNK_X4;
        break;
    case PCIE_LINK_WIDTH_8:
        *p = QEMU_PCI_EXP_LNK_X8;
        break;
    case PCIE_LINK_WIDTH_12:
        *p = QEMU_PCI_EXP_LNK_X12;
        break;
    case PCIE_LINK_WIDTH_16:
        *p = QEMU_PCI_EXP_LNK_X16;
        break;
    case PCIE_LINK_WIDTH_32:
        *p = QEMU_PCI_EXP_LNK_X32;
        break;
    default:
        /* Unreachable */
        abort();
    }
}

const PropertyInfo qdev_prop_pcie_link_width = {
    .name = "PCIELinkWidth",
    .description = "1/2/4/8/12/16/32",
    .enum_table = &PCIELinkWidth_lookup,
    .get = get_prop_pcielinkwidth,
    .set = set_prop_pcielinkwidth,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- UUID --- */

static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
{
    Property *prop = opaque;
    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
    char buffer[UUID_FMT_LEN + 1];
    char *p = buffer;

    qemu_uuid_unparse(uuid, buffer);

    visit_type_str(v, name, &p, errp);
}

#define UUID_VALUE_AUTO        "auto"

static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    Property *prop = opaque;
    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    if (!strcmp(str, UUID_VALUE_AUTO)) {
        qemu_uuid_generate(uuid);
    } else if (qemu_uuid_parse(str, uuid) < 0) {
        error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    }
    g_free(str);
}

static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
{
    object_property_set_default_str(op, UUID_VALUE_AUTO);
}

const PropertyInfo qdev_prop_uuid = {
    .name  = "str",
    .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
        "\" for random value (default)",
    .get   = get_uuid,
    .set   = set_uuid,
    .set_default_value = set_default_uuid_auto,
};

/* --- s390 cpu entitlement policy --- */

QEMU_BUILD_BUG_ON(sizeof(CpuS390Entitlement) != sizeof(int));

const PropertyInfo qdev_prop_cpus390entitlement = {
    .name  = "CpuS390Entitlement",
    .description = "low/medium (default)/high",
    .enum_table  = &CpuS390Entitlement_lookup,
    .get   = qdev_propinfo_get_enum,
    .set   = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};
