qemu/hw/core/qdev-properties.c
<<
>>
Prefs
   1#include "qemu/osdep.h"
   2#include "net/net.h"
   3#include "hw/qdev.h"
   4#include "qapi/error.h"
   5#include "hw/pci/pci.h"
   6#include "qapi/qmp/qerror.h"
   7#include "qemu/error-report.h"
   8#include "hw/block/block.h"
   9#include "net/hub.h"
  10#include "qapi/visitor.h"
  11#include "chardev/char.h"
  12#include "qemu/uuid.h"
  13
  14void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
  15                                  Error **errp)
  16{
  17    if (dev->id) {
  18        error_setg(errp, "Attempt to set property '%s' on device '%s' "
  19                   "(type '%s') after it was realized", name, dev->id,
  20                   object_get_typename(OBJECT(dev)));
  21    } else {
  22        error_setg(errp, "Attempt to set property '%s' on anonymous device "
  23                   "(type '%s') after it was realized", name,
  24                   object_get_typename(OBJECT(dev)));
  25    }
  26}
  27
  28void qdev_prop_allow_set_link_before_realize(const Object *obj,
  29                                             const char *name,
  30                                             Object *val, Error **errp)
  31{
  32    DeviceState *dev = DEVICE(obj);
  33
  34    if (dev->realized) {
  35        error_setg(errp, "Attempt to set link property '%s' on device '%s' "
  36                   "(type '%s') after it was realized",
  37                   name, dev->id, object_get_typename(obj));
  38    }
  39}
  40
  41void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
  42{
  43    void *ptr = dev;
  44    ptr += prop->offset;
  45    return ptr;
  46}
  47
  48static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque,
  49                     Error **errp)
  50{
  51    DeviceState *dev = DEVICE(obj);
  52    Property *prop = opaque;
  53    int *ptr = qdev_get_prop_ptr(dev, prop);
  54
  55    visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
  56}
  57
  58static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
  59                     Error **errp)
  60{
  61    DeviceState *dev = DEVICE(obj);
  62    Property *prop = opaque;
  63    int *ptr = qdev_get_prop_ptr(dev, prop);
  64
  65    if (dev->realized) {
  66        qdev_prop_set_after_realize(dev, name, errp);
  67        return;
  68    }
  69
  70    visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
  71}
  72
  73static void set_default_value_enum(Object *obj, const Property *prop)
  74{
  75    object_property_set_str(obj,
  76                            qapi_enum_lookup(prop->info->enum_table,
  77                                             prop->defval.i),
  78                            prop->name, &error_abort);
  79}
  80
  81/* Bit */
  82
  83static uint32_t qdev_get_prop_mask(Property *prop)
  84{
  85    assert(prop->info == &qdev_prop_bit);
  86    return 0x1 << prop->bitnr;
  87}
  88
  89static void bit_prop_set(DeviceState *dev, Property *props, bool val)
  90{
  91    uint32_t *p = qdev_get_prop_ptr(dev, props);
  92    uint32_t mask = qdev_get_prop_mask(props);
  93    if (val) {
  94        *p |= mask;
  95    } else {
  96        *p &= ~mask;
  97    }
  98}
  99
 100static void prop_get_bit(Object *obj, Visitor *v, const char *name,
 101                         void *opaque, Error **errp)
 102{
 103    DeviceState *dev = DEVICE(obj);
 104    Property *prop = opaque;
 105    uint32_t *p = qdev_get_prop_ptr(dev, prop);
 106    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 107
 108    visit_type_bool(v, name, &value, errp);
 109}
 110
 111static void prop_set_bit(Object *obj, Visitor *v, const char *name,
 112                         void *opaque, Error **errp)
 113{
 114    DeviceState *dev = DEVICE(obj);
 115    Property *prop = opaque;
 116    Error *local_err = NULL;
 117    bool value;
 118
 119    if (dev->realized) {
 120        qdev_prop_set_after_realize(dev, name, errp);
 121        return;
 122    }
 123
 124    visit_type_bool(v, name, &value, &local_err);
 125    if (local_err) {
 126        error_propagate(errp, local_err);
 127        return;
 128    }
 129    bit_prop_set(dev, prop, value);
 130}
 131
 132static void set_default_value_bool(Object *obj, const Property *prop)
 133{
 134    object_property_set_bool(obj, prop->defval.u, prop->name, &error_abort);
 135}
 136
 137const PropertyInfo qdev_prop_bit = {
 138    .name  = "bool",
 139    .description = "on/off",
 140    .get   = prop_get_bit,
 141    .set   = prop_set_bit,
 142    .set_default_value = set_default_value_bool,
 143};
 144
 145/* Bit64 */
 146
 147static uint64_t qdev_get_prop_mask64(Property *prop)
 148{
 149    assert(prop->info == &qdev_prop_bit64);
 150    return 0x1ull << prop->bitnr;
 151}
 152
 153static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
 154{
 155    uint64_t *p = qdev_get_prop_ptr(dev, props);
 156    uint64_t mask = qdev_get_prop_mask64(props);
 157    if (val) {
 158        *p |= mask;
 159    } else {
 160        *p &= ~mask;
 161    }
 162}
 163
 164static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
 165                           void *opaque, Error **errp)
 166{
 167    DeviceState *dev = DEVICE(obj);
 168    Property *prop = opaque;
 169    uint64_t *p = qdev_get_prop_ptr(dev, prop);
 170    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 171
 172    visit_type_bool(v, name, &value, errp);
 173}
 174
 175static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
 176                           void *opaque, Error **errp)
 177{
 178    DeviceState *dev = DEVICE(obj);
 179    Property *prop = opaque;
 180    Error *local_err = NULL;
 181    bool value;
 182
 183    if (dev->realized) {
 184        qdev_prop_set_after_realize(dev, name, errp);
 185        return;
 186    }
 187
 188    visit_type_bool(v, name, &value, &local_err);
 189    if (local_err) {
 190        error_propagate(errp, local_err);
 191        return;
 192    }
 193    bit64_prop_set(dev, prop, value);
 194}
 195
 196const PropertyInfo qdev_prop_bit64 = {
 197    .name  = "bool",
 198    .description = "on/off",
 199    .get   = prop_get_bit64,
 200    .set   = prop_set_bit64,
 201    .set_default_value = set_default_value_bool,
 202};
 203
 204/* --- bool --- */
 205
 206static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 207                     Error **errp)
 208{
 209    DeviceState *dev = DEVICE(obj);
 210    Property *prop = opaque;
 211    bool *ptr = qdev_get_prop_ptr(dev, prop);
 212
 213    visit_type_bool(v, name, ptr, errp);
 214}
 215
 216static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 217                     Error **errp)
 218{
 219    DeviceState *dev = DEVICE(obj);
 220    Property *prop = opaque;
 221    bool *ptr = qdev_get_prop_ptr(dev, prop);
 222
 223    if (dev->realized) {
 224        qdev_prop_set_after_realize(dev, name, errp);
 225        return;
 226    }
 227
 228    visit_type_bool(v, name, ptr, errp);
 229}
 230
 231const PropertyInfo qdev_prop_bool = {
 232    .name  = "bool",
 233    .get   = get_bool,
 234    .set   = set_bool,
 235    .set_default_value = set_default_value_bool,
 236};
 237
 238/* --- 8bit integer --- */
 239
 240static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 241                      Error **errp)
 242{
 243    DeviceState *dev = DEVICE(obj);
 244    Property *prop = opaque;
 245    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
 246
 247    visit_type_uint8(v, name, ptr, errp);
 248}
 249
 250static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 251                      Error **errp)
 252{
 253    DeviceState *dev = DEVICE(obj);
 254    Property *prop = opaque;
 255    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
 256
 257    if (dev->realized) {
 258        qdev_prop_set_after_realize(dev, name, errp);
 259        return;
 260    }
 261
 262    visit_type_uint8(v, name, ptr, errp);
 263}
 264
 265static void set_default_value_int(Object *obj, const Property *prop)
 266{
 267    object_property_set_int(obj, prop->defval.i, prop->name, &error_abort);
 268}
 269
 270static void set_default_value_uint(Object *obj, const Property *prop)
 271{
 272    object_property_set_uint(obj, prop->defval.u, prop->name, &error_abort);
 273}
 274
 275const PropertyInfo qdev_prop_uint8 = {
 276    .name  = "uint8",
 277    .get   = get_uint8,
 278    .set   = set_uint8,
 279    .set_default_value = set_default_value_uint,
 280};
 281
 282/* --- 16bit integer --- */
 283
 284static void get_uint16(Object *obj, Visitor *v, const char *name,
 285                       void *opaque, Error **errp)
 286{
 287    DeviceState *dev = DEVICE(obj);
 288    Property *prop = opaque;
 289    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
 290
 291    visit_type_uint16(v, name, ptr, errp);
 292}
 293
 294static void set_uint16(Object *obj, Visitor *v, const char *name,
 295                       void *opaque, Error **errp)
 296{
 297    DeviceState *dev = DEVICE(obj);
 298    Property *prop = opaque;
 299    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
 300
 301    if (dev->realized) {
 302        qdev_prop_set_after_realize(dev, name, errp);
 303        return;
 304    }
 305
 306    visit_type_uint16(v, name, ptr, errp);
 307}
 308
 309const PropertyInfo qdev_prop_uint16 = {
 310    .name  = "uint16",
 311    .get   = get_uint16,
 312    .set   = set_uint16,
 313    .set_default_value = set_default_value_uint,
 314};
 315
 316/* --- 32bit integer --- */
 317
 318static void get_uint32(Object *obj, Visitor *v, const char *name,
 319                       void *opaque, Error **errp)
 320{
 321    DeviceState *dev = DEVICE(obj);
 322    Property *prop = opaque;
 323    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
 324
 325    visit_type_uint32(v, name, ptr, errp);
 326}
 327
 328static void set_uint32(Object *obj, Visitor *v, const char *name,
 329                       void *opaque, Error **errp)
 330{
 331    DeviceState *dev = DEVICE(obj);
 332    Property *prop = opaque;
 333    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
 334
 335    if (dev->realized) {
 336        qdev_prop_set_after_realize(dev, name, errp);
 337        return;
 338    }
 339
 340    visit_type_uint32(v, name, ptr, errp);
 341}
 342
 343static void get_int32(Object *obj, Visitor *v, const char *name, void *opaque,
 344                      Error **errp)
 345{
 346    DeviceState *dev = DEVICE(obj);
 347    Property *prop = opaque;
 348    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 349
 350    visit_type_int32(v, name, ptr, errp);
 351}
 352
 353static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
 354                      Error **errp)
 355{
 356    DeviceState *dev = DEVICE(obj);
 357    Property *prop = opaque;
 358    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 359
 360    if (dev->realized) {
 361        qdev_prop_set_after_realize(dev, name, errp);
 362        return;
 363    }
 364
 365    visit_type_int32(v, name, ptr, errp);
 366}
 367
 368const PropertyInfo qdev_prop_uint32 = {
 369    .name  = "uint32",
 370    .get   = get_uint32,
 371    .set   = set_uint32,
 372    .set_default_value = set_default_value_uint,
 373};
 374
 375const PropertyInfo qdev_prop_int32 = {
 376    .name  = "int32",
 377    .get   = get_int32,
 378    .set   = set_int32,
 379    .set_default_value = set_default_value_int,
 380};
 381
 382/* --- 64bit integer --- */
 383
 384static void get_uint64(Object *obj, Visitor *v, const char *name,
 385                       void *opaque, Error **errp)
 386{
 387    DeviceState *dev = DEVICE(obj);
 388    Property *prop = opaque;
 389    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 390
 391    visit_type_uint64(v, name, ptr, errp);
 392}
 393
 394static void set_uint64(Object *obj, Visitor *v, const char *name,
 395                       void *opaque, Error **errp)
 396{
 397    DeviceState *dev = DEVICE(obj);
 398    Property *prop = opaque;
 399    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 400
 401    if (dev->realized) {
 402        qdev_prop_set_after_realize(dev, name, errp);
 403        return;
 404    }
 405
 406    visit_type_uint64(v, name, ptr, errp);
 407}
 408
 409static void get_int64(Object *obj, Visitor *v, const char *name,
 410                      void *opaque, Error **errp)
 411{
 412    DeviceState *dev = DEVICE(obj);
 413    Property *prop = opaque;
 414    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
 415
 416    visit_type_int64(v, name, ptr, errp);
 417}
 418
 419static void set_int64(Object *obj, Visitor *v, const char *name,
 420                      void *opaque, Error **errp)
 421{
 422    DeviceState *dev = DEVICE(obj);
 423    Property *prop = opaque;
 424    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
 425
 426    if (dev->realized) {
 427        qdev_prop_set_after_realize(dev, name, errp);
 428        return;
 429    }
 430
 431    visit_type_int64(v, name, ptr, errp);
 432}
 433
 434const PropertyInfo qdev_prop_uint64 = {
 435    .name  = "uint64",
 436    .get   = get_uint64,
 437    .set   = set_uint64,
 438    .set_default_value = set_default_value_uint,
 439};
 440
 441const PropertyInfo qdev_prop_int64 = {
 442    .name  = "int64",
 443    .get   = get_int64,
 444    .set   = set_int64,
 445    .set_default_value = set_default_value_int,
 446};
 447
 448/* --- string --- */
 449
 450static void release_string(Object *obj, const char *name, void *opaque)
 451{
 452    Property *prop = opaque;
 453    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
 454}
 455
 456static void get_string(Object *obj, Visitor *v, const char *name,
 457                       void *opaque, Error **errp)
 458{
 459    DeviceState *dev = DEVICE(obj);
 460    Property *prop = opaque;
 461    char **ptr = qdev_get_prop_ptr(dev, prop);
 462
 463    if (!*ptr) {
 464        char *str = (char *)"";
 465        visit_type_str(v, name, &str, errp);
 466    } else {
 467        visit_type_str(v, name, ptr, errp);
 468    }
 469}
 470
 471static void set_string(Object *obj, Visitor *v, const char *name,
 472                       void *opaque, Error **errp)
 473{
 474    DeviceState *dev = DEVICE(obj);
 475    Property *prop = opaque;
 476    char **ptr = qdev_get_prop_ptr(dev, prop);
 477    Error *local_err = NULL;
 478    char *str;
 479
 480    if (dev->realized) {
 481        qdev_prop_set_after_realize(dev, name, errp);
 482        return;
 483    }
 484
 485    visit_type_str(v, name, &str, &local_err);
 486    if (local_err) {
 487        error_propagate(errp, local_err);
 488        return;
 489    }
 490    g_free(*ptr);
 491    *ptr = str;
 492}
 493
 494const PropertyInfo qdev_prop_string = {
 495    .name  = "str",
 496    .release = release_string,
 497    .get   = get_string,
 498    .set   = set_string,
 499};
 500
 501/* --- pointer --- */
 502
 503/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
 504const PropertyInfo qdev_prop_ptr = {
 505    .name  = "ptr",
 506};
 507
 508/* --- mac address --- */
 509
 510/*
 511 * accepted syntax versions:
 512 *   01:02:03:04:05:06
 513 *   01-02-03-04-05-06
 514 */
 515static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 516                    Error **errp)
 517{
 518    DeviceState *dev = DEVICE(obj);
 519    Property *prop = opaque;
 520    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
 521    char buffer[2 * 6 + 5 + 1];
 522    char *p = buffer;
 523
 524    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
 525             mac->a[0], mac->a[1], mac->a[2],
 526             mac->a[3], mac->a[4], mac->a[5]);
 527
 528    visit_type_str(v, name, &p, errp);
 529}
 530
 531static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 532                    Error **errp)
 533{
 534    DeviceState *dev = DEVICE(obj);
 535    Property *prop = opaque;
 536    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
 537    Error *local_err = NULL;
 538    int i, pos;
 539    char *str, *p;
 540
 541    if (dev->realized) {
 542        qdev_prop_set_after_realize(dev, name, errp);
 543        return;
 544    }
 545
 546    visit_type_str(v, name, &str, &local_err);
 547    if (local_err) {
 548        error_propagate(errp, local_err);
 549        return;
 550    }
 551
 552    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
 553        if (!qemu_isxdigit(str[pos])) {
 554            goto inval;
 555        }
 556        if (!qemu_isxdigit(str[pos+1])) {
 557            goto inval;
 558        }
 559        if (i == 5) {
 560            if (str[pos+2] != '\0') {
 561                goto inval;
 562            }
 563        } else {
 564            if (str[pos+2] != ':' && str[pos+2] != '-') {
 565                goto inval;
 566            }
 567        }
 568        mac->a[i] = strtol(str+pos, &p, 16);
 569    }
 570    g_free(str);
 571    return;
 572
 573inval:
 574    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 575    g_free(str);
 576}
 577
 578const PropertyInfo qdev_prop_macaddr = {
 579    .name  = "str",
 580    .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
 581    .get   = get_mac,
 582    .set   = set_mac,
 583};
 584
 585/* --- on/off/auto --- */
 586
 587const PropertyInfo qdev_prop_on_off_auto = {
 588    .name = "OnOffAuto",
 589    .description = "on/off/auto",
 590    .enum_table = &OnOffAuto_lookup,
 591    .get = get_enum,
 592    .set = set_enum,
 593    .set_default_value = set_default_value_enum,
 594};
 595
 596/* --- lost tick policy --- */
 597
 598QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 599
 600const PropertyInfo qdev_prop_losttickpolicy = {
 601    .name  = "LostTickPolicy",
 602    .enum_table  = &LostTickPolicy_lookup,
 603    .get   = get_enum,
 604    .set   = set_enum,
 605    .set_default_value = set_default_value_enum,
 606};
 607
 608/* --- Block device error handling policy --- */
 609
 610QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
 611
 612const PropertyInfo qdev_prop_blockdev_on_error = {
 613    .name = "BlockdevOnError",
 614    .description = "Error handling policy, "
 615                   "report/ignore/enospc/stop/auto",
 616    .enum_table = &BlockdevOnError_lookup,
 617    .get = get_enum,
 618    .set = set_enum,
 619    .set_default_value = set_default_value_enum,
 620};
 621
 622/* --- BIOS CHS translation */
 623
 624QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
 625
 626const PropertyInfo qdev_prop_bios_chs_trans = {
 627    .name = "BiosAtaTranslation",
 628    .description = "Logical CHS translation algorithm, "
 629                   "auto/none/lba/large/rechs",
 630    .enum_table = &BiosAtaTranslation_lookup,
 631    .get = get_enum,
 632    .set = set_enum,
 633    .set_default_value = set_default_value_enum,
 634};
 635
 636/* --- FDC default drive types */
 637
 638const PropertyInfo qdev_prop_fdc_drive_type = {
 639    .name = "FdcDriveType",
 640    .description = "FDC drive type, "
 641                   "144/288/120/none/auto",
 642    .enum_table = &FloppyDriveType_lookup,
 643    .get = get_enum,
 644    .set = set_enum,
 645    .set_default_value = set_default_value_enum,
 646};
 647
 648/* --- pci address --- */
 649
 650/*
 651 * bus-local address, i.e. "$slot" or "$slot.$fn"
 652 */
 653static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
 654                          void *opaque, Error **errp)
 655{
 656    DeviceState *dev = DEVICE(obj);
 657    Property *prop = opaque;
 658    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
 659    unsigned int slot, fn, n;
 660    Error *local_err = NULL;
 661    char *str;
 662
 663    if (dev->realized) {
 664        qdev_prop_set_after_realize(dev, name, errp);
 665        return;
 666    }
 667
 668    visit_type_str(v, name, &str, &local_err);
 669    if (local_err) {
 670        error_free(local_err);
 671        local_err = NULL;
 672        visit_type_int32(v, name, &value, &local_err);
 673        if (local_err) {
 674            error_propagate(errp, local_err);
 675        } else if (value < -1 || value > 255) {
 676            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
 677                       name ? name : "null", "pci_devfn");
 678        } else {
 679            *ptr = value;
 680        }
 681        return;
 682    }
 683
 684    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
 685        fn = 0;
 686        if (sscanf(str, "%x%n", &slot, &n) != 1) {
 687            goto invalid;
 688        }
 689    }
 690    if (str[n] != '\0' || fn > 7 || slot > 31) {
 691        goto invalid;
 692    }
 693    *ptr = slot << 3 | fn;
 694    g_free(str);
 695    return;
 696
 697invalid:
 698    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 699    g_free(str);
 700}
 701
 702static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
 703                           size_t len)
 704{
 705    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 706
 707    if (*ptr == -1) {
 708        return snprintf(dest, len, "<unset>");
 709    } else {
 710        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
 711    }
 712}
 713
 714const PropertyInfo qdev_prop_pci_devfn = {
 715    .name  = "int32",
 716    .description = "Slot and optional function number, example: 06.0 or 06",
 717    .print = print_pci_devfn,
 718    .get   = get_int32,
 719    .set   = set_pci_devfn,
 720    .set_default_value = set_default_value_int,
 721};
 722
 723/* --- blocksize --- */
 724
 725static void set_blocksize(Object *obj, Visitor *v, const char *name,
 726                          void *opaque, Error **errp)
 727{
 728    DeviceState *dev = DEVICE(obj);
 729    Property *prop = opaque;
 730    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
 731    Error *local_err = NULL;
 732    const int64_t min = 512;
 733    const int64_t max = 32768;
 734
 735    if (dev->realized) {
 736        qdev_prop_set_after_realize(dev, name, errp);
 737        return;
 738    }
 739
 740    visit_type_uint16(v, name, &value, &local_err);
 741    if (local_err) {
 742        error_propagate(errp, local_err);
 743        return;
 744    }
 745    /* value of 0 means "unset" */
 746    if (value && (value < min || value > max)) {
 747        error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
 748                   dev->id ? : "", name, (int64_t)value, min, max);
 749        return;
 750    }
 751
 752    /* We rely on power-of-2 blocksizes for bitmasks */
 753    if ((value & (value - 1)) != 0) {
 754        error_setg(errp,
 755                  "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
 756                  dev->id ?: "", name, (int64_t)value);
 757        return;
 758    }
 759
 760    *ptr = value;
 761}
 762
 763const PropertyInfo qdev_prop_blocksize = {
 764    .name  = "uint16",
 765    .description = "A power of two between 512 and 32768",
 766    .get   = get_uint16,
 767    .set   = set_blocksize,
 768    .set_default_value = set_default_value_uint,
 769};
 770
 771/* --- pci host address --- */
 772
 773static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 774                                 void *opaque, Error **errp)
 775{
 776    DeviceState *dev = DEVICE(obj);
 777    Property *prop = opaque;
 778    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
 779    char buffer[] = "ffff:ff:ff.f";
 780    char *p = buffer;
 781    int rc = 0;
 782
 783    /*
 784     * Catch "invalid" device reference from vfio-pci and allow the
 785     * default buffer representing the non-existent device to be used.
 786     */
 787    if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
 788        rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
 789                      addr->domain, addr->bus, addr->slot, addr->function);
 790        assert(rc == sizeof(buffer) - 1);
 791    }
 792
 793    visit_type_str(v, name, &p, errp);
 794}
 795
 796/*
 797 * Parse [<domain>:]<bus>:<slot>.<func>
 798 *   if <domain> is not supplied, it's assumed to be 0.
 799 */
 800static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 801                                 void *opaque, Error **errp)
 802{
 803    DeviceState *dev = DEVICE(obj);
 804    Property *prop = opaque;
 805    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
 806    Error *local_err = NULL;
 807    char *str, *p;
 808    char *e;
 809    unsigned long val;
 810    unsigned long dom = 0, bus = 0;
 811    unsigned int slot = 0, func = 0;
 812
 813    if (dev->realized) {
 814        qdev_prop_set_after_realize(dev, name, errp);
 815        return;
 816    }
 817
 818    visit_type_str(v, name, &str, &local_err);
 819    if (local_err) {
 820        error_propagate(errp, local_err);
 821        return;
 822    }
 823
 824    p = str;
 825    val = strtoul(p, &e, 16);
 826    if (e == p || *e != ':') {
 827        goto inval;
 828    }
 829    bus = val;
 830
 831    p = e + 1;
 832    val = strtoul(p, &e, 16);
 833    if (e == p) {
 834        goto inval;
 835    }
 836    if (*e == ':') {
 837        dom = bus;
 838        bus = val;
 839        p = e + 1;
 840        val = strtoul(p, &e, 16);
 841        if (e == p) {
 842            goto inval;
 843        }
 844    }
 845    slot = val;
 846
 847    if (*e != '.') {
 848        goto inval;
 849    }
 850    p = e + 1;
 851    val = strtoul(p, &e, 10);
 852    if (e == p) {
 853        goto inval;
 854    }
 855    func = val;
 856
 857    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
 858        goto inval;
 859    }
 860
 861    if (*e) {
 862        goto inval;
 863    }
 864
 865    addr->domain = dom;
 866    addr->bus = bus;
 867    addr->slot = slot;
 868    addr->function = func;
 869
 870    g_free(str);
 871    return;
 872
 873inval:
 874    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 875    g_free(str);
 876}
 877
 878const PropertyInfo qdev_prop_pci_host_devaddr = {
 879    .name = "str",
 880    .description = "Address (bus/device/function) of "
 881                   "the host device, example: 04:10.0",
 882    .get = get_pci_host_devaddr,
 883    .set = set_pci_host_devaddr,
 884};
 885
 886/* --- UUID --- */
 887
 888static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 889                     Error **errp)
 890{
 891    DeviceState *dev = DEVICE(obj);
 892    Property *prop = opaque;
 893    QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
 894    char buffer[UUID_FMT_LEN + 1];
 895    char *p = buffer;
 896
 897    qemu_uuid_unparse(uuid, buffer);
 898
 899    visit_type_str(v, name, &p, errp);
 900}
 901
 902#define UUID_VALUE_AUTO        "auto"
 903
 904static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 905                    Error **errp)
 906{
 907    DeviceState *dev = DEVICE(obj);
 908    Property *prop = opaque;
 909    QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
 910    Error *local_err = NULL;
 911    char *str;
 912
 913    if (dev->realized) {
 914        qdev_prop_set_after_realize(dev, name, errp);
 915        return;
 916    }
 917
 918    visit_type_str(v, name, &str, &local_err);
 919    if (local_err) {
 920        error_propagate(errp, local_err);
 921        return;
 922    }
 923
 924    if (!strcmp(str, UUID_VALUE_AUTO)) {
 925        qemu_uuid_generate(uuid);
 926    } else if (qemu_uuid_parse(str, uuid) < 0) {
 927        error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 928    }
 929    g_free(str);
 930}
 931
 932static void set_default_uuid_auto(Object *obj, const Property *prop)
 933{
 934    object_property_set_str(obj, UUID_VALUE_AUTO, prop->name, &error_abort);
 935}
 936
 937const PropertyInfo qdev_prop_uuid = {
 938    .name  = "str",
 939    .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
 940        "\" for random value (default)",
 941    .get   = get_uuid,
 942    .set   = set_uuid,
 943    .set_default_value = set_default_uuid_auto,
 944};
 945
 946/* --- support for array properties --- */
 947
 948/* Used as an opaque for the object properties we add for each
 949 * array element. Note that the struct Property must be first
 950 * in the struct so that a pointer to this works as the opaque
 951 * for the underlying element's property hooks as well as for
 952 * our own release callback.
 953 */
 954typedef struct {
 955    struct Property prop;
 956    char *propname;
 957    ObjectPropertyRelease *release;
 958} ArrayElementProperty;
 959
 960/* object property release callback for array element properties:
 961 * we call the underlying element's property release hook, and
 962 * then free the memory we allocated when we added the property.
 963 */
 964static void array_element_release(Object *obj, const char *name, void *opaque)
 965{
 966    ArrayElementProperty *p = opaque;
 967    if (p->release) {
 968        p->release(obj, name, opaque);
 969    }
 970    g_free(p->propname);
 971    g_free(p);
 972}
 973
 974static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
 975                              void *opaque, Error **errp)
 976{
 977    /* Setter for the property which defines the length of a
 978     * variable-sized property array. As well as actually setting the
 979     * array-length field in the device struct, we have to create the
 980     * array itself and dynamically add the corresponding properties.
 981     */
 982    DeviceState *dev = DEVICE(obj);
 983    Property *prop = opaque;
 984    uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
 985    void **arrayptr = (void *)dev + prop->arrayoffset;
 986    Error *local_err = NULL;
 987    void *eltptr;
 988    const char *arrayname;
 989    int i;
 990
 991    if (dev->realized) {
 992        qdev_prop_set_after_realize(dev, name, errp);
 993        return;
 994    }
 995    if (*alenptr) {
 996        error_setg(errp, "array size property %s may not be set more than once",
 997                   name);
 998        return;
 999    }
1000    visit_type_uint32(v, name, alenptr, &local_err);
1001    if (local_err) {
1002        error_propagate(errp, local_err);
1003        return;
1004    }
1005    if (!*alenptr) {
1006        return;
1007    }
1008
1009    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
1010     * strip it off so we can get the name of the array itself.
1011     */
1012    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
1013                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
1014    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
1015
1016    /* Note that it is the responsibility of the individual device's deinit
1017     * to free the array proper.
1018     */
1019    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
1020    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
1021        char *propname = g_strdup_printf("%s[%d]", arrayname, i);
1022        ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
1023        arrayprop->release = prop->arrayinfo->release;
1024        arrayprop->propname = propname;
1025        arrayprop->prop.info = prop->arrayinfo;
1026        arrayprop->prop.name = propname;
1027        /* This ugly piece of pointer arithmetic sets up the offset so
1028         * that when the underlying get/set hooks call qdev_get_prop_ptr
1029         * they get the right answer despite the array element not actually
1030         * being inside the device struct.
1031         */
1032        arrayprop->prop.offset = eltptr - (void *)dev;
1033        assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
1034        object_property_add(obj, propname,
1035                            arrayprop->prop.info->name,
1036                            arrayprop->prop.info->get,
1037                            arrayprop->prop.info->set,
1038                            array_element_release,
1039                            arrayprop, &local_err);
1040        if (local_err) {
1041            error_propagate(errp, local_err);
1042            return;
1043        }
1044    }
1045}
1046
1047const PropertyInfo qdev_prop_arraylen = {
1048    .name = "uint32",
1049    .get = get_uint32,
1050    .set = set_prop_arraylen,
1051    .set_default_value = set_default_value_uint,
1052};
1053
1054/* --- public helpers --- */
1055
1056static Property *qdev_prop_walk(Property *props, const char *name)
1057{
1058    if (!props) {
1059        return NULL;
1060    }
1061    while (props->name) {
1062        if (strcmp(props->name, name) == 0) {
1063            return props;
1064        }
1065        props++;
1066    }
1067    return NULL;
1068}
1069
1070static Property *qdev_prop_find(DeviceState *dev, const char *name)
1071{
1072    ObjectClass *class;
1073    Property *prop;
1074
1075    /* device properties */
1076    class = object_get_class(OBJECT(dev));
1077    do {
1078        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
1079        if (prop) {
1080            return prop;
1081        }
1082        class = object_class_get_parent(class);
1083    } while (class != object_class_by_name(TYPE_DEVICE));
1084
1085    return NULL;
1086}
1087
1088void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1089                                    Property *prop, const char *value)
1090{
1091    switch (ret) {
1092    case -EEXIST:
1093        error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
1094                  object_get_typename(OBJECT(dev)), prop->name, value);
1095        break;
1096    default:
1097    case -EINVAL:
1098        error_setg(errp, QERR_PROPERTY_VALUE_BAD,
1099                   object_get_typename(OBJECT(dev)), prop->name, value);
1100        break;
1101    case -ENOENT:
1102        error_setg(errp, "Property '%s.%s' can't find value '%s'",
1103                  object_get_typename(OBJECT(dev)), prop->name, value);
1104        break;
1105    case 0:
1106        break;
1107    }
1108}
1109
1110void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1111{
1112    object_property_set_bool(OBJECT(dev), value, name, &error_abort);
1113}
1114
1115void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1116{
1117    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1118}
1119
1120void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1121{
1122    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1123}
1124
1125void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1126{
1127    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1128}
1129
1130void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1131{
1132    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1133}
1134
1135void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1136{
1137    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1138}
1139
1140void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1141{
1142    object_property_set_str(OBJECT(dev), value, name, &error_abort);
1143}
1144
1145void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
1146                           const uint8_t *value)
1147{
1148    char str[2 * 6 + 5 + 1];
1149    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1150             value[0], value[1], value[2], value[3], value[4], value[5]);
1151
1152    object_property_set_str(OBJECT(dev), str, name, &error_abort);
1153}
1154
1155void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1156{
1157    Property *prop;
1158
1159    prop = qdev_prop_find(dev, name);
1160    object_property_set_str(OBJECT(dev),
1161                            qapi_enum_lookup(prop->info->enum_table, value),
1162                            name, &error_abort);
1163}
1164
1165void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1166{
1167    Property *prop;
1168    void **ptr;
1169
1170    prop = qdev_prop_find(dev, name);
1171    assert(prop && prop->info == &qdev_prop_ptr);
1172    ptr = qdev_get_prop_ptr(dev, prop);
1173    *ptr = value;
1174}
1175
1176static GList *global_props;
1177
1178void qdev_prop_register_global(GlobalProperty *prop)
1179{
1180    global_props = g_list_append(global_props, prop);
1181}
1182
1183void register_compat_prop(const char *driver,
1184                          const char *property,
1185                          const char *value)
1186{
1187    GlobalProperty *p = g_new0(GlobalProperty, 1);
1188
1189    /* Any compat_props must never cause error */
1190    p->errp = &error_abort;
1191    p->driver = driver;
1192    p->property = property;
1193    p->value = value;
1194    qdev_prop_register_global(p);
1195}
1196
1197void register_compat_props_array(GlobalProperty *prop)
1198{
1199    for (; prop && prop->driver; prop++) {
1200        register_compat_prop(prop->driver, prop->property, prop->value);
1201    }
1202}
1203
1204void qdev_prop_register_global_list(GlobalProperty *props)
1205{
1206    int i;
1207
1208    for (i = 0; props[i].driver != NULL; i++) {
1209        qdev_prop_register_global(props+i);
1210    }
1211}
1212
1213int qdev_prop_check_globals(void)
1214{
1215    GList *l;
1216    int ret = 0;
1217
1218    for (l = global_props; l; l = l->next) {
1219        GlobalProperty *prop = l->data;
1220        ObjectClass *oc;
1221        DeviceClass *dc;
1222        if (prop->used) {
1223            continue;
1224        }
1225        if (!prop->user_provided) {
1226            continue;
1227        }
1228        oc = object_class_by_name(prop->driver);
1229        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1230        if (!oc) {
1231            warn_report("global %s.%s has invalid class name",
1232                        prop->driver, prop->property);
1233            ret = 1;
1234            continue;
1235        }
1236        dc = DEVICE_CLASS(oc);
1237        if (!dc->hotpluggable && !prop->used) {
1238            warn_report("global %s.%s=%s not used",
1239                        prop->driver, prop->property, prop->value);
1240            ret = 1;
1241            continue;
1242        }
1243    }
1244    return ret;
1245}
1246
1247void qdev_prop_set_globals(DeviceState *dev)
1248{
1249    GList *l;
1250
1251    for (l = global_props; l; l = l->next) {
1252        GlobalProperty *prop = l->data;
1253        Error *err = NULL;
1254
1255        if (object_dynamic_cast(OBJECT(dev), prop->driver) == NULL) {
1256            continue;
1257        }
1258        prop->used = true;
1259        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
1260        if (err != NULL) {
1261            error_prepend(&err, "can't apply global %s.%s=%s: ",
1262                          prop->driver, prop->property, prop->value);
1263            if (!dev->hotplugged && prop->errp) {
1264                error_propagate(prop->errp, err);
1265            } else {
1266                assert(prop->user_provided);
1267                warn_report_err(err);
1268            }
1269        }
1270    }
1271}
1272
1273/* --- 64bit unsigned int 'size' type --- */
1274
1275static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1276                     Error **errp)
1277{
1278    DeviceState *dev = DEVICE(obj);
1279    Property *prop = opaque;
1280    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1281
1282    visit_type_size(v, name, ptr, errp);
1283}
1284
1285static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1286                     Error **errp)
1287{
1288    DeviceState *dev = DEVICE(obj);
1289    Property *prop = opaque;
1290    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1291
1292    visit_type_size(v, name, ptr, errp);
1293}
1294
1295const PropertyInfo qdev_prop_size = {
1296    .name  = "size",
1297    .get = get_size,
1298    .set = set_size,
1299    .set_default_value = set_default_value_uint,
1300};
1301
1302/* --- object link property --- */
1303
1304static void create_link_property(Object *obj, Property *prop, Error **errp)
1305{
1306    Object **child = qdev_get_prop_ptr(DEVICE(obj), prop);
1307
1308    object_property_add_link(obj, prop->name, prop->link_type,
1309                             child,
1310                             qdev_prop_allow_set_link_before_realize,
1311                             OBJ_PROP_LINK_STRONG,
1312                             errp);
1313}
1314
1315const PropertyInfo qdev_prop_link = {
1316    .name = "link",
1317    .create = create_link_property,
1318};
1319
1320/* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */
1321
1322const PropertyInfo qdev_prop_off_auto_pcibar = {
1323    .name = "OffAutoPCIBAR",
1324    .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
1325    .enum_table = &OffAutoPCIBAR_lookup,
1326    .get = get_enum,
1327    .set = set_enum,
1328    .set_default_value = set_default_value_enum,
1329};
1330