/*
 * 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/qapi-visit-virtio.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 "system/block-backend.h"
#include "system/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;
}

bool qdev_prop_sanitize_s390x_loadparm(uint8_t *loadparm, const char *str,
                                       Error **errp)
{
    int i, len;

    len = strlen(str);
    if (len > 8) {
        error_setg(errp, "'loadparm' can only contain up to 8 characters");
        return false;
    }

    for (i = 0; i < len; i++) {
        uint8_t c = qemu_toupper(str[i]); /* mimic HMC */

        if (qemu_isalnum(c) || c == '.' || c == ' ') {
            loadparm[i] = c;
        } else {
            error_setg(errp,
                       "invalid character in 'loadparm': '%c' (ASCII 0x%02x)",
                       c, c);
            return false;
        }
    }

    return true;
}

/* --- drive --- */

static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    const 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);
    const 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");
            return;
        }

        blk_replace_bs(blk, bs, errp);
        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;

            ret = blk_insert_bs(blk, bs, errp);
            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);
    const Property *prop = opaque;
    BlockBackend **ptr = object_field_prop_ptr(obj, prop);

    if (*ptr) {
        blockdev_auto_del(*ptr);
        blk_detach_dev(*ptr, dev);
    }
}

const PropertyInfo qdev_prop_drive = {
    .type  = "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 = {
    .type  = "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)
{
    ERRP_GUARD();
    const 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)
{
    const Property *prop = opaque;
    CharBackend *be = object_field_prop_ptr(obj, prop);

    qemu_chr_fe_deinit(be, false);
}

const PropertyInfo qdev_prop_chr = {
    .type  = "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)
{
    const 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)
{
    const 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 = {
    .type  = "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)
{
    const 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)
{
    const 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, prop->name, str);
    g_free(str);
}

const PropertyInfo qdev_prop_netdev = {
    .type  = "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)
{
    const 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)
{
    const 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 = {
    .type = "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)
{
    const 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 = {
    .type  = "LostTickPolicy",
    .description = "Policy for handling lost ticks (discard/delay/slew)",
    .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)
{
    const Property *prop = opaque;
    uint32_t *ptr = object_field_prop_ptr(obj, prop);
    uint64_t value;

    if (!visit_type_size(v, name, &value, errp)) {
        return;
    }
    if (!check_block_size(name, value, errp)) {
        return;
    }
    *ptr = value;
}

const PropertyInfo qdev_prop_blocksize = {
    .type  = "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 = {
    .type = "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 = {
    .type = "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 = {
    .type = "FloppyDriveType",
    .description = "Floppy 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 = {
    .type = "MultiFDCompression",
    .description = "multifd_compression values"
                   " (none/zlib/zstd/qpl/uadk/qatzip)",
    .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 = {
    .type = "MigMode",
    .description = "Migration mode (normal/cpr-reboot)",
    .enum_table = &MigMode_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- GranuleMode --- */

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

const PropertyInfo qdev_prop_granule_mode = {
    .type = "GranuleMode",
    .description = "Granule page size (4k/8k/16k/64k/host)",
    .enum_table = &GranuleMode_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

const PropertyInfo qdev_prop_zero_page_detection = {
    .type = "ZeroPageDetection",
    .description = "Zero page detection (none/legacy/multifd)",
    .enum_table = &ZeroPageDetection_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)
{
    const 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",
                  range_lob(&rr->range), range_upb(&rr->range), 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)
{
    const Property *prop = opaque;
    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
    const char *endptr;
    uint64_t lob, upb;
    char *str;
    int ret;

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

    ret = qemu_strtou64(str, &endptr, 16, &lob);
    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, &upb);
    if (ret) {
        error_setg(errp, "end address of '%s'"
                   " must be a hexadecimal integer", name);
        goto out;
    }
    if (*endptr != ':') {
        goto separator_error;
    }

    range_set_bounds(&rr->range, lob, upb);

    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);
}

const PropertyInfo qdev_prop_reserved_region = {
    .type  = "str",
    .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)
{
    const Property *prop = opaque;
    g_autofree GenericAlternate *alt;
    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
    unsigned int slot, fn, n;
    g_autofree char *str = NULL;

    if (!visit_start_alternate(v, name, &alt, sizeof(*alt), errp)) {
        return;
    }

    switch (alt->type) {
    case QTYPE_QSTRING:
        if (!visit_type_str(v, name, &str, errp)) {
            goto out;
        }

        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;
        break;

    case QTYPE_QNUM:
        if (!visit_type_int32(v, name, &value, errp)) {
            goto out;
        }
        if (value < -1 || value > 255) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "a value between -1 and 255");
            goto out;
        }
        *ptr = value;
        break;

    default:
        error_setg(errp, "Invalid parameter type for '%s', expected int or str",
                   name ? name : "null");
        goto out;
    }

    goto out;

invalid:
    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
out:
    visit_end_alternate(v, (void **) &alt);
}

static int print_pci_devfn(Object *obj, const 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 = {
    .type  = "str",
    .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)
{
    const 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)
{
    const 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 = {
    .type = "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 = {
    .type = "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/32/64 -- */

static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    const 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;
    case QEMU_PCI_EXP_LNK_32GT:
        speed = PCIE_LINK_SPEED_32;
        break;
    case QEMU_PCI_EXP_LNK_64GT:
        speed = PCIE_LINK_SPEED_64;
        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)
{
    const 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;
    case PCIE_LINK_SPEED_32:
        *p = QEMU_PCI_EXP_LNK_32GT;
        break;
    case PCIE_LINK_SPEED_64:
        *p = QEMU_PCI_EXP_LNK_64GT;
        break;
    default:
        /* Unreachable */
        abort();
    }
}

const PropertyInfo qdev_prop_pcie_link_speed = {
    .type = "PCIELinkSpeed",
    .description = "2_5/5/8/16/32/64",
    .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)
{
    const 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)
{
    const 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 = {
    .type = "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)
{
    const Property *prop = opaque;
    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
    char buffer[UUID_STR_LEN];
    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)
{
    const 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 = {
    .type  = "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(S390CpuEntitlement) != sizeof(int));

const PropertyInfo qdev_prop_cpus390entitlement = {
    .type  = "S390CpuEntitlement",
    .description = "auto/low/medium/high (default medium)",
    .enum_table  = &S390CpuEntitlement_lookup,
    .get   = qdev_propinfo_get_enum,
    .set   = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- IOThreadVirtQueueMappingList --- */

static void get_iothread_vq_mapping_list(Object *obj, Visitor *v,
        const char *name, void *opaque, Error **errp)
{
    IOThreadVirtQueueMappingList **prop_ptr =
        object_field_prop_ptr(obj, opaque);

    visit_type_IOThreadVirtQueueMappingList(v, name, prop_ptr, errp);
}

static void set_iothread_vq_mapping_list(Object *obj, Visitor *v,
        const char *name, void *opaque, Error **errp)
{
    IOThreadVirtQueueMappingList **prop_ptr =
        object_field_prop_ptr(obj, opaque);
    IOThreadVirtQueueMappingList *list;

    if (!visit_type_IOThreadVirtQueueMappingList(v, name, &list, errp)) {
        return;
    }

    qapi_free_IOThreadVirtQueueMappingList(*prop_ptr);
    *prop_ptr = list;
}

static void release_iothread_vq_mapping_list(Object *obj,
        const char *name, void *opaque)
{
    IOThreadVirtQueueMappingList **prop_ptr =
        object_field_prop_ptr(obj, opaque);

    qapi_free_IOThreadVirtQueueMappingList(*prop_ptr);
    *prop_ptr = NULL;
}

const PropertyInfo qdev_prop_iothread_vq_mapping_list = {
    .type = "IOThreadVirtQueueMappingList",
    .description = "IOThread virtqueue mapping list [{\"iothread\":\"<id>\", "
                   "\"vqs\":[1,2,3,...]},...]",
    .get = get_iothread_vq_mapping_list,
    .set = set_iothread_vq_mapping_list,
    .release = release_iothread_vq_mapping_list,
};

/* --- Endian modes */

const PropertyInfo qdev_prop_endian_mode = {
    .type = "EndianMode",
    .description = "Endian mode, big/little/unspecified",
    .enum_table = &EndianMode_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

const PropertyInfo qdev_prop_vmapple_virtio_blk_variant = {
    .type  = "VMAppleVirtioBlkVariant",
    .description = "unspecified/root/aux",
    .enum_table  = &VMAppleVirtioBlkVariant_lookup,
    .get   = qdev_propinfo_get_enum,
    .set   = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- VirtIOGPUOutputList --- */

static void get_virtio_gpu_output_list(Object *obj, Visitor *v,
    const char *name, void *opaque, Error **errp)
{
    VirtIOGPUOutputList **prop_ptr =
        object_field_prop_ptr(obj, opaque);

    visit_type_VirtIOGPUOutputList(v, name, prop_ptr, errp);
}

static void set_virtio_gpu_output_list(Object *obj, Visitor *v,
    const char *name, void *opaque, Error **errp)
{
    VirtIOGPUOutputList **prop_ptr =
        object_field_prop_ptr(obj, opaque);
    VirtIOGPUOutputList *list;

    if (!visit_type_VirtIOGPUOutputList(v, name, &list, errp)) {
        return;
    }

    qapi_free_VirtIOGPUOutputList(*prop_ptr);
    *prop_ptr = list;
}

static void release_virtio_gpu_output_list(Object *obj,
    const char *name, void *opaque)
{
    VirtIOGPUOutputList **prop_ptr =
        object_field_prop_ptr(obj, opaque);

    qapi_free_VirtIOGPUOutputList(*prop_ptr);
    *prop_ptr = NULL;
}

const PropertyInfo qdev_prop_virtio_gpu_output_list = {
    .type = "VirtIOGPUOutputList",
    .description = "VirtIO GPU output list [{\"name\":\"<name>\"},...]",
    .get = get_virtio_gpu_output_list,
    .set = set_virtio_gpu_output_list,
    .release = release_virtio_gpu_output_list,
};
