1 #include "qemu/osdep.h" 2 #include "qemu/cutils.h" 3 #include "net/net.h" 4 #include "hw/qdev-properties.h" 5 #include "qapi/error.h" 6 #include "hw/pci/pci.h" 7 #include "qapi/qapi-types-block.h" 8 #include "qapi/qapi-types-machine.h" 9 #include "qapi/qapi-types-misc.h" 10 #include "qapi/qmp/qerror.h" 11 #include "qemu/ctype.h" 12 #include "qemu/error-report.h" 13 #include "qapi/qapi-types-migration.h" 14 #include "hw/block/block.h" 15 #include "net/hub.h" 16 #include "qapi/visitor.h" 17 #include "chardev/char.h" 18 #include "qemu/uuid.h" 19 #include "qemu/units.h" 20 #include "qemu/cutils.h" 21 22 void qdev_prop_set_after_realize(DeviceState *dev, const char *name, 23 Error **errp) 24 { 25 if (dev->id) { 26 error_setg(errp, "Attempt to set property '%s' on device '%s' " 27 "(type '%s') after it was realized", name, dev->id, 28 object_get_typename(OBJECT(dev))); 29 } else { 30 error_setg(errp, "Attempt to set property '%s' on anonymous device " 31 "(type '%s') after it was realized", name, 32 object_get_typename(OBJECT(dev))); 33 } 34 } 35 36 void qdev_prop_allow_set_link_before_realize(const Object *obj, 37 const char *name, 38 Object *val, Error **errp) 39 { 40 DeviceState *dev = DEVICE(obj); 41 42 if (dev->realized) { 43 error_setg(errp, "Attempt to set link property '%s' on device '%s' " 44 "(type '%s') after it was realized", 45 name, dev->id, object_get_typename(obj)); 46 } 47 } 48 49 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) 50 { 51 void *ptr = dev; 52 ptr += prop->offset; 53 return ptr; 54 } 55 56 static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque, 57 Error **errp) 58 { 59 DeviceState *dev = DEVICE(obj); 60 Property *prop = opaque; 61 int *ptr = qdev_get_prop_ptr(dev, prop); 62 63 visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); 64 } 65 66 static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque, 67 Error **errp) 68 { 69 DeviceState *dev = DEVICE(obj); 70 Property *prop = opaque; 71 int *ptr = qdev_get_prop_ptr(dev, prop); 72 73 if (dev->realized) { 74 qdev_prop_set_after_realize(dev, name, errp); 75 return; 76 } 77 78 visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); 79 } 80 81 static void set_default_value_enum(ObjectProperty *op, const Property *prop) 82 { 83 object_property_set_default_str(op, 84 qapi_enum_lookup(prop->info->enum_table, prop->defval.i)); 85 } 86 87 /* Bit */ 88 89 static uint32_t qdev_get_prop_mask(Property *prop) 90 { 91 assert(prop->info == &qdev_prop_bit); 92 return 0x1 << prop->bitnr; 93 } 94 95 static void bit_prop_set(DeviceState *dev, Property *props, bool val) 96 { 97 uint32_t *p = qdev_get_prop_ptr(dev, props); 98 uint32_t mask = qdev_get_prop_mask(props); 99 if (val) { 100 *p |= mask; 101 } else { 102 *p &= ~mask; 103 } 104 } 105 106 static void prop_get_bit(Object *obj, Visitor *v, const char *name, 107 void *opaque, Error **errp) 108 { 109 DeviceState *dev = DEVICE(obj); 110 Property *prop = opaque; 111 uint32_t *p = qdev_get_prop_ptr(dev, prop); 112 bool value = (*p & qdev_get_prop_mask(prop)) != 0; 113 114 visit_type_bool(v, name, &value, errp); 115 } 116 117 static void prop_set_bit(Object *obj, Visitor *v, const char *name, 118 void *opaque, Error **errp) 119 { 120 DeviceState *dev = DEVICE(obj); 121 Property *prop = opaque; 122 bool value; 123 124 if (dev->realized) { 125 qdev_prop_set_after_realize(dev, name, errp); 126 return; 127 } 128 129 if (!visit_type_bool(v, name, &value, errp)) { 130 return; 131 } 132 bit_prop_set(dev, prop, value); 133 } 134 135 static void set_default_value_bool(ObjectProperty *op, const Property *prop) 136 { 137 object_property_set_default_bool(op, prop->defval.u); 138 } 139 140 const PropertyInfo qdev_prop_bit = { 141 .name = "bool", 142 .description = "on/off", 143 .get = prop_get_bit, 144 .set = prop_set_bit, 145 .set_default_value = set_default_value_bool, 146 }; 147 148 /* Bit64 */ 149 150 static uint64_t qdev_get_prop_mask64(Property *prop) 151 { 152 assert(prop->info == &qdev_prop_bit64); 153 return 0x1ull << prop->bitnr; 154 } 155 156 static void bit64_prop_set(DeviceState *dev, Property *props, bool val) 157 { 158 uint64_t *p = qdev_get_prop_ptr(dev, props); 159 uint64_t mask = qdev_get_prop_mask64(props); 160 if (val) { 161 *p |= mask; 162 } else { 163 *p &= ~mask; 164 } 165 } 166 167 static void prop_get_bit64(Object *obj, Visitor *v, const char *name, 168 void *opaque, Error **errp) 169 { 170 DeviceState *dev = DEVICE(obj); 171 Property *prop = opaque; 172 uint64_t *p = qdev_get_prop_ptr(dev, prop); 173 bool value = (*p & qdev_get_prop_mask64(prop)) != 0; 174 175 visit_type_bool(v, name, &value, errp); 176 } 177 178 static void prop_set_bit64(Object *obj, Visitor *v, const char *name, 179 void *opaque, Error **errp) 180 { 181 DeviceState *dev = DEVICE(obj); 182 Property *prop = opaque; 183 bool value; 184 185 if (dev->realized) { 186 qdev_prop_set_after_realize(dev, name, errp); 187 return; 188 } 189 190 if (!visit_type_bool(v, name, &value, errp)) { 191 return; 192 } 193 bit64_prop_set(dev, prop, value); 194 } 195 196 const 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 206 static 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 216 static 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 231 const 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 240 static 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 250 static 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 265 static void set_default_value_int(ObjectProperty *op, const Property *prop) 266 { 267 object_property_set_default_int(op, prop->defval.i); 268 } 269 270 static void set_default_value_uint(ObjectProperty *op, const Property *prop) 271 { 272 object_property_set_default_uint(op, prop->defval.u); 273 } 274 275 const 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 284 static 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 294 static 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 309 const 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 318 static 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 328 static 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 343 static 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 353 static 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 368 const 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 375 const 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 384 static 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 394 static 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 409 static 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 419 static 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 434 const 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 441 const 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 450 static 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 456 static 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 471 static 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 char *str; 478 479 if (dev->realized) { 480 qdev_prop_set_after_realize(dev, name, errp); 481 return; 482 } 483 484 if (!visit_type_str(v, name, &str, errp)) { 485 return; 486 } 487 g_free(*ptr); 488 *ptr = str; 489 } 490 491 const PropertyInfo qdev_prop_string = { 492 .name = "str", 493 .release = release_string, 494 .get = get_string, 495 .set = set_string, 496 }; 497 498 /* --- mac address --- */ 499 500 /* 501 * accepted syntax versions: 502 * 01:02:03:04:05:06 503 * 01-02-03-04-05-06 504 */ 505 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque, 506 Error **errp) 507 { 508 DeviceState *dev = DEVICE(obj); 509 Property *prop = opaque; 510 MACAddr *mac = qdev_get_prop_ptr(dev, prop); 511 char buffer[2 * 6 + 5 + 1]; 512 char *p = buffer; 513 514 snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x", 515 mac->a[0], mac->a[1], mac->a[2], 516 mac->a[3], mac->a[4], mac->a[5]); 517 518 visit_type_str(v, name, &p, errp); 519 } 520 521 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque, 522 Error **errp) 523 { 524 DeviceState *dev = DEVICE(obj); 525 Property *prop = opaque; 526 MACAddr *mac = qdev_get_prop_ptr(dev, prop); 527 int i, pos; 528 char *str; 529 const char *p; 530 531 if (dev->realized) { 532 qdev_prop_set_after_realize(dev, name, errp); 533 return; 534 } 535 536 if (!visit_type_str(v, name, &str, errp)) { 537 return; 538 } 539 540 for (i = 0, pos = 0; i < 6; i++, pos += 3) { 541 long val; 542 543 if (!qemu_isxdigit(str[pos])) { 544 goto inval; 545 } 546 if (!qemu_isxdigit(str[pos+1])) { 547 goto inval; 548 } 549 if (i == 5) { 550 if (str[pos+2] != '\0') { 551 goto inval; 552 } 553 } else { 554 if (str[pos+2] != ':' && str[pos+2] != '-') { 555 goto inval; 556 } 557 } 558 if (qemu_strtol(str + pos, &p, 16, &val) < 0 || val > 0xff) { 559 goto inval; 560 } 561 mac->a[i] = val; 562 } 563 g_free(str); 564 return; 565 566 inval: 567 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 568 g_free(str); 569 } 570 571 const PropertyInfo qdev_prop_macaddr = { 572 .name = "str", 573 .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56", 574 .get = get_mac, 575 .set = set_mac, 576 }; 577 578 /* --- Reserved Region --- */ 579 580 /* 581 * Accepted syntax: 582 * <low address>:<high address>:<type> 583 * where low/high addresses are uint64_t in hexadecimal 584 * and type is a non-negative decimal integer 585 */ 586 static void get_reserved_region(Object *obj, Visitor *v, const char *name, 587 void *opaque, Error **errp) 588 { 589 DeviceState *dev = DEVICE(obj); 590 Property *prop = opaque; 591 ReservedRegion *rr = qdev_get_prop_ptr(dev, prop); 592 char buffer[64]; 593 char *p = buffer; 594 int rc; 595 596 rc = snprintf(buffer, sizeof(buffer), "0x%"PRIx64":0x%"PRIx64":%u", 597 rr->low, rr->high, rr->type); 598 assert(rc < sizeof(buffer)); 599 600 visit_type_str(v, name, &p, errp); 601 } 602 603 static void set_reserved_region(Object *obj, Visitor *v, const char *name, 604 void *opaque, Error **errp) 605 { 606 DeviceState *dev = DEVICE(obj); 607 Property *prop = opaque; 608 ReservedRegion *rr = qdev_get_prop_ptr(dev, prop); 609 Error *local_err = NULL; 610 const char *endptr; 611 char *str; 612 int ret; 613 614 if (dev->realized) { 615 qdev_prop_set_after_realize(dev, name, errp); 616 return; 617 } 618 619 visit_type_str(v, name, &str, &local_err); 620 if (local_err) { 621 error_propagate(errp, local_err); 622 return; 623 } 624 625 ret = qemu_strtou64(str, &endptr, 16, &rr->low); 626 if (ret) { 627 error_setg(errp, "start address of '%s'" 628 " must be a hexadecimal integer", name); 629 goto out; 630 } 631 if (*endptr != ':') { 632 goto separator_error; 633 } 634 635 ret = qemu_strtou64(endptr + 1, &endptr, 16, &rr->high); 636 if (ret) { 637 error_setg(errp, "end address of '%s'" 638 " must be a hexadecimal integer", name); 639 goto out; 640 } 641 if (*endptr != ':') { 642 goto separator_error; 643 } 644 645 ret = qemu_strtoui(endptr + 1, &endptr, 10, &rr->type); 646 if (ret) { 647 error_setg(errp, "type of '%s'" 648 " must be a non-negative decimal integer", name); 649 } 650 goto out; 651 652 separator_error: 653 error_setg(errp, "reserved region fields must be separated with ':'"); 654 out: 655 g_free(str); 656 return; 657 } 658 659 const PropertyInfo qdev_prop_reserved_region = { 660 .name = "reserved_region", 661 .description = "Reserved Region, example: 0xFEE00000:0xFEEFFFFF:0", 662 .get = get_reserved_region, 663 .set = set_reserved_region, 664 }; 665 666 /* --- on/off/auto --- */ 667 668 const PropertyInfo qdev_prop_on_off_auto = { 669 .name = "OnOffAuto", 670 .description = "on/off/auto", 671 .enum_table = &OnOffAuto_lookup, 672 .get = get_enum, 673 .set = set_enum, 674 .set_default_value = set_default_value_enum, 675 }; 676 677 /* --- lost tick policy --- */ 678 679 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); 680 681 const PropertyInfo qdev_prop_losttickpolicy = { 682 .name = "LostTickPolicy", 683 .enum_table = &LostTickPolicy_lookup, 684 .get = get_enum, 685 .set = set_enum, 686 .set_default_value = set_default_value_enum, 687 }; 688 689 /* --- Block device error handling policy --- */ 690 691 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int)); 692 693 const PropertyInfo qdev_prop_blockdev_on_error = { 694 .name = "BlockdevOnError", 695 .description = "Error handling policy, " 696 "report/ignore/enospc/stop/auto", 697 .enum_table = &BlockdevOnError_lookup, 698 .get = get_enum, 699 .set = set_enum, 700 .set_default_value = set_default_value_enum, 701 }; 702 703 /* --- BIOS CHS translation */ 704 705 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int)); 706 707 const PropertyInfo qdev_prop_bios_chs_trans = { 708 .name = "BiosAtaTranslation", 709 .description = "Logical CHS translation algorithm, " 710 "auto/none/lba/large/rechs", 711 .enum_table = &BiosAtaTranslation_lookup, 712 .get = get_enum, 713 .set = set_enum, 714 .set_default_value = set_default_value_enum, 715 }; 716 717 /* --- FDC default drive types */ 718 719 const PropertyInfo qdev_prop_fdc_drive_type = { 720 .name = "FdcDriveType", 721 .description = "FDC drive type, " 722 "144/288/120/none/auto", 723 .enum_table = &FloppyDriveType_lookup, 724 .get = get_enum, 725 .set = set_enum, 726 .set_default_value = set_default_value_enum, 727 }; 728 729 /* --- MultiFDCompression --- */ 730 731 const PropertyInfo qdev_prop_multifd_compression = { 732 .name = "MultiFDCompression", 733 .description = "multifd_compression values, " 734 "none/zlib/zstd", 735 .enum_table = &MultiFDCompression_lookup, 736 .get = get_enum, 737 .set = set_enum, 738 .set_default_value = set_default_value_enum, 739 }; 740 741 /* --- pci address --- */ 742 743 /* 744 * bus-local address, i.e. "$slot" or "$slot.$fn" 745 */ 746 static void set_pci_devfn(Object *obj, Visitor *v, const char *name, 747 void *opaque, Error **errp) 748 { 749 DeviceState *dev = DEVICE(obj); 750 Property *prop = opaque; 751 int32_t value, *ptr = qdev_get_prop_ptr(dev, prop); 752 unsigned int slot, fn, n; 753 char *str; 754 755 if (dev->realized) { 756 qdev_prop_set_after_realize(dev, name, errp); 757 return; 758 } 759 760 if (!visit_type_str(v, name, &str, NULL)) { 761 if (!visit_type_int32(v, name, &value, errp)) { 762 return; 763 } 764 if (value < -1 || value > 255) { 765 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 766 name ? name : "null", "pci_devfn"); 767 return; 768 } 769 *ptr = value; 770 return; 771 } 772 773 if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { 774 fn = 0; 775 if (sscanf(str, "%x%n", &slot, &n) != 1) { 776 goto invalid; 777 } 778 } 779 if (str[n] != '\0' || fn > 7 || slot > 31) { 780 goto invalid; 781 } 782 *ptr = slot << 3 | fn; 783 g_free(str); 784 return; 785 786 invalid: 787 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 788 g_free(str); 789 } 790 791 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, 792 size_t len) 793 { 794 int32_t *ptr = qdev_get_prop_ptr(dev, prop); 795 796 if (*ptr == -1) { 797 return snprintf(dest, len, "<unset>"); 798 } else { 799 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7); 800 } 801 } 802 803 const PropertyInfo qdev_prop_pci_devfn = { 804 .name = "int32", 805 .description = "Slot and optional function number, example: 06.0 or 06", 806 .print = print_pci_devfn, 807 .get = get_int32, 808 .set = set_pci_devfn, 809 .set_default_value = set_default_value_int, 810 }; 811 812 /* --- 32bit unsigned int 'size' type --- */ 813 814 static void get_size32(Object *obj, Visitor *v, const char *name, void *opaque, 815 Error **errp) 816 { 817 DeviceState *dev = DEVICE(obj); 818 Property *prop = opaque; 819 uint32_t *ptr = qdev_get_prop_ptr(dev, prop); 820 uint64_t value = *ptr; 821 822 visit_type_size(v, name, &value, errp); 823 } 824 825 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque, 826 Error **errp) 827 { 828 DeviceState *dev = DEVICE(obj); 829 Property *prop = opaque; 830 uint32_t *ptr = qdev_get_prop_ptr(dev, prop); 831 uint64_t value; 832 833 if (dev->realized) { 834 qdev_prop_set_after_realize(dev, name, errp); 835 return; 836 } 837 838 if (!visit_type_size(v, name, &value, errp)) { 839 return; 840 } 841 842 if (value > UINT32_MAX) { 843 error_setg(errp, 844 "Property %s.%s doesn't take value %" PRIu64 845 " (maximum: %u)", 846 dev->id ? : "", name, value, UINT32_MAX); 847 return; 848 } 849 850 *ptr = value; 851 } 852 853 const PropertyInfo qdev_prop_size32 = { 854 .name = "size", 855 .get = get_size32, 856 .set = set_size32, 857 .set_default_value = set_default_value_uint, 858 }; 859 860 /* --- blocksize --- */ 861 862 /* lower limit is sector size */ 863 #define MIN_BLOCK_SIZE 512 864 #define MIN_BLOCK_SIZE_STR "512 B" 865 /* 866 * upper limit is arbitrary, 2 MiB looks sufficient for all sensible uses, and 867 * matches qcow2 cluster size limit 868 */ 869 #define MAX_BLOCK_SIZE (2 * MiB) 870 #define MAX_BLOCK_SIZE_STR "2 MiB" 871 872 static void set_blocksize(Object *obj, Visitor *v, const char *name, 873 void *opaque, Error **errp) 874 { 875 DeviceState *dev = DEVICE(obj); 876 Property *prop = opaque; 877 uint32_t *ptr = qdev_get_prop_ptr(dev, prop); 878 uint64_t value; 879 880 if (dev->realized) { 881 qdev_prop_set_after_realize(dev, name, errp); 882 return; 883 } 884 885 if (!visit_type_size(v, name, &value, errp)) { 886 return; 887 } 888 /* value of 0 means "unset" */ 889 if (value && (value < MIN_BLOCK_SIZE || value > MAX_BLOCK_SIZE)) { 890 error_setg(errp, 891 "Property %s.%s doesn't take value %" PRIu64 892 " (minimum: " MIN_BLOCK_SIZE_STR 893 ", maximum: " MAX_BLOCK_SIZE_STR ")", 894 dev->id ? : "", name, value); 895 return; 896 } 897 898 /* We rely on power-of-2 blocksizes for bitmasks */ 899 if ((value & (value - 1)) != 0) { 900 error_setg(errp, 901 "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2", 902 dev->id ?: "", name, (int64_t)value); 903 return; 904 } 905 906 *ptr = value; 907 } 908 909 const PropertyInfo qdev_prop_blocksize = { 910 .name = "size", 911 .description = "A power of two between " MIN_BLOCK_SIZE_STR 912 " and " MAX_BLOCK_SIZE_STR, 913 .get = get_size32, 914 .set = set_blocksize, 915 .set_default_value = set_default_value_uint, 916 }; 917 918 /* --- pci host address --- */ 919 920 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name, 921 void *opaque, Error **errp) 922 { 923 DeviceState *dev = DEVICE(obj); 924 Property *prop = opaque; 925 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); 926 char buffer[] = "ffff:ff:ff.f"; 927 char *p = buffer; 928 int rc = 0; 929 930 /* 931 * Catch "invalid" device reference from vfio-pci and allow the 932 * default buffer representing the non-existent device to be used. 933 */ 934 if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) { 935 rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d", 936 addr->domain, addr->bus, addr->slot, addr->function); 937 assert(rc == sizeof(buffer) - 1); 938 } 939 940 visit_type_str(v, name, &p, errp); 941 } 942 943 /* 944 * Parse [<domain>:]<bus>:<slot>.<func> 945 * if <domain> is not supplied, it's assumed to be 0. 946 */ 947 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name, 948 void *opaque, Error **errp) 949 { 950 DeviceState *dev = DEVICE(obj); 951 Property *prop = opaque; 952 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); 953 char *str, *p; 954 char *e; 955 unsigned long val; 956 unsigned long dom = 0, bus = 0; 957 unsigned int slot = 0, func = 0; 958 959 if (dev->realized) { 960 qdev_prop_set_after_realize(dev, name, errp); 961 return; 962 } 963 964 if (!visit_type_str(v, name, &str, errp)) { 965 return; 966 } 967 968 p = str; 969 val = strtoul(p, &e, 16); 970 if (e == p || *e != ':') { 971 goto inval; 972 } 973 bus = val; 974 975 p = e + 1; 976 val = strtoul(p, &e, 16); 977 if (e == p) { 978 goto inval; 979 } 980 if (*e == ':') { 981 dom = bus; 982 bus = val; 983 p = e + 1; 984 val = strtoul(p, &e, 16); 985 if (e == p) { 986 goto inval; 987 } 988 } 989 slot = val; 990 991 if (*e != '.') { 992 goto inval; 993 } 994 p = e + 1; 995 val = strtoul(p, &e, 10); 996 if (e == p) { 997 goto inval; 998 } 999 func = val; 1000 1001 if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) { 1002 goto inval; 1003 } 1004 1005 if (*e) { 1006 goto inval; 1007 } 1008 1009 addr->domain = dom; 1010 addr->bus = bus; 1011 addr->slot = slot; 1012 addr->function = func; 1013 1014 g_free(str); 1015 return; 1016 1017 inval: 1018 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 1019 g_free(str); 1020 } 1021 1022 const PropertyInfo qdev_prop_pci_host_devaddr = { 1023 .name = "str", 1024 .description = "Address (bus/device/function) of " 1025 "the host device, example: 04:10.0", 1026 .get = get_pci_host_devaddr, 1027 .set = set_pci_host_devaddr, 1028 }; 1029 1030 /* --- UUID --- */ 1031 1032 static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque, 1033 Error **errp) 1034 { 1035 DeviceState *dev = DEVICE(obj); 1036 Property *prop = opaque; 1037 QemuUUID *uuid = qdev_get_prop_ptr(dev, prop); 1038 char buffer[UUID_FMT_LEN + 1]; 1039 char *p = buffer; 1040 1041 qemu_uuid_unparse(uuid, buffer); 1042 1043 visit_type_str(v, name, &p, errp); 1044 } 1045 1046 #define UUID_VALUE_AUTO "auto" 1047 1048 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque, 1049 Error **errp) 1050 { 1051 DeviceState *dev = DEVICE(obj); 1052 Property *prop = opaque; 1053 QemuUUID *uuid = qdev_get_prop_ptr(dev, prop); 1054 char *str; 1055 1056 if (dev->realized) { 1057 qdev_prop_set_after_realize(dev, name, errp); 1058 return; 1059 } 1060 1061 if (!visit_type_str(v, name, &str, errp)) { 1062 return; 1063 } 1064 1065 if (!strcmp(str, UUID_VALUE_AUTO)) { 1066 qemu_uuid_generate(uuid); 1067 } else if (qemu_uuid_parse(str, uuid) < 0) { 1068 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 1069 } 1070 g_free(str); 1071 } 1072 1073 static void set_default_uuid_auto(ObjectProperty *op, const Property *prop) 1074 { 1075 object_property_set_default_str(op, UUID_VALUE_AUTO); 1076 } 1077 1078 const PropertyInfo qdev_prop_uuid = { 1079 .name = "str", 1080 .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO 1081 "\" for random value (default)", 1082 .get = get_uuid, 1083 .set = set_uuid, 1084 .set_default_value = set_default_uuid_auto, 1085 }; 1086 1087 /* --- support for array properties --- */ 1088 1089 /* Used as an opaque for the object properties we add for each 1090 * array element. Note that the struct Property must be first 1091 * in the struct so that a pointer to this works as the opaque 1092 * for the underlying element's property hooks as well as for 1093 * our own release callback. 1094 */ 1095 typedef struct { 1096 struct Property prop; 1097 char *propname; 1098 ObjectPropertyRelease *release; 1099 } ArrayElementProperty; 1100 1101 /* object property release callback for array element properties: 1102 * we call the underlying element's property release hook, and 1103 * then free the memory we allocated when we added the property. 1104 */ 1105 static void array_element_release(Object *obj, const char *name, void *opaque) 1106 { 1107 ArrayElementProperty *p = opaque; 1108 if (p->release) { 1109 p->release(obj, name, opaque); 1110 } 1111 g_free(p->propname); 1112 g_free(p); 1113 } 1114 1115 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, 1116 void *opaque, Error **errp) 1117 { 1118 /* Setter for the property which defines the length of a 1119 * variable-sized property array. As well as actually setting the 1120 * array-length field in the device struct, we have to create the 1121 * array itself and dynamically add the corresponding properties. 1122 */ 1123 DeviceState *dev = DEVICE(obj); 1124 Property *prop = opaque; 1125 uint32_t *alenptr = qdev_get_prop_ptr(dev, prop); 1126 void **arrayptr = (void *)dev + prop->arrayoffset; 1127 void *eltptr; 1128 const char *arrayname; 1129 int i; 1130 1131 if (dev->realized) { 1132 qdev_prop_set_after_realize(dev, name, errp); 1133 return; 1134 } 1135 if (*alenptr) { 1136 error_setg(errp, "array size property %s may not be set more than once", 1137 name); 1138 return; 1139 } 1140 if (!visit_type_uint32(v, name, alenptr, errp)) { 1141 return; 1142 } 1143 if (!*alenptr) { 1144 return; 1145 } 1146 1147 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix; 1148 * strip it off so we can get the name of the array itself. 1149 */ 1150 assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, 1151 strlen(PROP_ARRAY_LEN_PREFIX)) == 0); 1152 arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); 1153 1154 /* Note that it is the responsibility of the individual device's deinit 1155 * to free the array proper. 1156 */ 1157 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); 1158 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { 1159 char *propname = g_strdup_printf("%s[%d]", arrayname, i); 1160 ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1); 1161 arrayprop->release = prop->arrayinfo->release; 1162 arrayprop->propname = propname; 1163 arrayprop->prop.info = prop->arrayinfo; 1164 arrayprop->prop.name = propname; 1165 /* This ugly piece of pointer arithmetic sets up the offset so 1166 * that when the underlying get/set hooks call qdev_get_prop_ptr 1167 * they get the right answer despite the array element not actually 1168 * being inside the device struct. 1169 */ 1170 arrayprop->prop.offset = eltptr - (void *)dev; 1171 assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr); 1172 object_property_add(obj, propname, 1173 arrayprop->prop.info->name, 1174 arrayprop->prop.info->get, 1175 arrayprop->prop.info->set, 1176 array_element_release, 1177 arrayprop); 1178 } 1179 } 1180 1181 const PropertyInfo qdev_prop_arraylen = { 1182 .name = "uint32", 1183 .get = get_uint32, 1184 .set = set_prop_arraylen, 1185 .set_default_value = set_default_value_uint, 1186 }; 1187 1188 /* --- public helpers --- */ 1189 1190 static Property *qdev_prop_walk(Property *props, const char *name) 1191 { 1192 if (!props) { 1193 return NULL; 1194 } 1195 while (props->name) { 1196 if (strcmp(props->name, name) == 0) { 1197 return props; 1198 } 1199 props++; 1200 } 1201 return NULL; 1202 } 1203 1204 static Property *qdev_prop_find(DeviceState *dev, const char *name) 1205 { 1206 ObjectClass *class; 1207 Property *prop; 1208 1209 /* device properties */ 1210 class = object_get_class(OBJECT(dev)); 1211 do { 1212 prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name); 1213 if (prop) { 1214 return prop; 1215 } 1216 class = object_class_get_parent(class); 1217 } while (class != object_class_by_name(TYPE_DEVICE)); 1218 1219 return NULL; 1220 } 1221 1222 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, 1223 Property *prop, const char *value) 1224 { 1225 switch (ret) { 1226 case -EEXIST: 1227 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", 1228 object_get_typename(OBJECT(dev)), prop->name, value); 1229 break; 1230 default: 1231 case -EINVAL: 1232 error_setg(errp, QERR_PROPERTY_VALUE_BAD, 1233 object_get_typename(OBJECT(dev)), prop->name, value); 1234 break; 1235 case -ENOENT: 1236 error_setg(errp, "Property '%s.%s' can't find value '%s'", 1237 object_get_typename(OBJECT(dev)), prop->name, value); 1238 break; 1239 case 0: 1240 break; 1241 } 1242 } 1243 1244 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) 1245 { 1246 object_property_set_bool(OBJECT(dev), name, value, &error_abort); 1247 } 1248 1249 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) 1250 { 1251 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1252 } 1253 1254 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) 1255 { 1256 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1257 } 1258 1259 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) 1260 { 1261 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1262 } 1263 1264 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) 1265 { 1266 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1267 } 1268 1269 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) 1270 { 1271 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1272 } 1273 1274 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) 1275 { 1276 object_property_set_str(OBJECT(dev), name, value, &error_abort); 1277 } 1278 1279 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, 1280 const uint8_t *value) 1281 { 1282 char str[2 * 6 + 5 + 1]; 1283 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", 1284 value[0], value[1], value[2], value[3], value[4], value[5]); 1285 1286 object_property_set_str(OBJECT(dev), name, str, &error_abort); 1287 } 1288 1289 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) 1290 { 1291 Property *prop; 1292 1293 prop = qdev_prop_find(dev, name); 1294 object_property_set_str(OBJECT(dev), name, 1295 qapi_enum_lookup(prop->info->enum_table, value), 1296 &error_abort); 1297 } 1298 1299 static GPtrArray *global_props(void) 1300 { 1301 static GPtrArray *gp; 1302 1303 if (!gp) { 1304 gp = g_ptr_array_new(); 1305 } 1306 1307 return gp; 1308 } 1309 1310 void qdev_prop_register_global(GlobalProperty *prop) 1311 { 1312 g_ptr_array_add(global_props(), prop); 1313 } 1314 1315 const GlobalProperty *qdev_find_global_prop(DeviceState *dev, 1316 const char *name) 1317 { 1318 GPtrArray *props = global_props(); 1319 const GlobalProperty *p; 1320 int i; 1321 1322 for (i = 0; i < props->len; i++) { 1323 p = g_ptr_array_index(props, i); 1324 if (object_dynamic_cast(OBJECT(dev), p->driver) 1325 && !strcmp(p->property, name)) { 1326 return p; 1327 } 1328 } 1329 return NULL; 1330 } 1331 1332 int qdev_prop_check_globals(void) 1333 { 1334 int i, ret = 0; 1335 1336 for (i = 0; i < global_props()->len; i++) { 1337 GlobalProperty *prop; 1338 ObjectClass *oc; 1339 DeviceClass *dc; 1340 1341 prop = g_ptr_array_index(global_props(), i); 1342 if (prop->used) { 1343 continue; 1344 } 1345 oc = object_class_by_name(prop->driver); 1346 oc = object_class_dynamic_cast(oc, TYPE_DEVICE); 1347 if (!oc) { 1348 warn_report("global %s.%s has invalid class name", 1349 prop->driver, prop->property); 1350 ret = 1; 1351 continue; 1352 } 1353 dc = DEVICE_CLASS(oc); 1354 if (!dc->hotpluggable && !prop->used) { 1355 warn_report("global %s.%s=%s not used", 1356 prop->driver, prop->property, prop->value); 1357 ret = 1; 1358 continue; 1359 } 1360 } 1361 return ret; 1362 } 1363 1364 void qdev_prop_set_globals(DeviceState *dev) 1365 { 1366 object_apply_global_props(OBJECT(dev), global_props(), 1367 dev->hotplugged ? NULL : &error_fatal); 1368 } 1369 1370 /* --- 64bit unsigned int 'size' type --- */ 1371 1372 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque, 1373 Error **errp) 1374 { 1375 DeviceState *dev = DEVICE(obj); 1376 Property *prop = opaque; 1377 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1378 1379 visit_type_size(v, name, ptr, errp); 1380 } 1381 1382 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque, 1383 Error **errp) 1384 { 1385 DeviceState *dev = DEVICE(obj); 1386 Property *prop = opaque; 1387 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1388 1389 visit_type_size(v, name, ptr, errp); 1390 } 1391 1392 const PropertyInfo qdev_prop_size = { 1393 .name = "size", 1394 .get = get_size, 1395 .set = set_size, 1396 .set_default_value = set_default_value_uint, 1397 }; 1398 1399 /* --- object link property --- */ 1400 1401 static void create_link_property(ObjectClass *oc, Property *prop) 1402 { 1403 object_class_property_add_link(oc, prop->name, prop->link_type, 1404 prop->offset, 1405 qdev_prop_allow_set_link_before_realize, 1406 OBJ_PROP_LINK_STRONG); 1407 } 1408 1409 const PropertyInfo qdev_prop_link = { 1410 .name = "link", 1411 .create = create_link_property, 1412 }; 1413 1414 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */ 1415 1416 const PropertyInfo qdev_prop_off_auto_pcibar = { 1417 .name = "OffAutoPCIBAR", 1418 .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5", 1419 .enum_table = &OffAutoPCIBAR_lookup, 1420 .get = get_enum, 1421 .set = set_enum, 1422 .set_default_value = set_default_value_enum, 1423 }; 1424 1425 /* --- PCIELinkSpeed 2_5/5/8/16 -- */ 1426 1427 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name, 1428 void *opaque, Error **errp) 1429 { 1430 DeviceState *dev = DEVICE(obj); 1431 Property *prop = opaque; 1432 PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop); 1433 int speed; 1434 1435 switch (*p) { 1436 case QEMU_PCI_EXP_LNK_2_5GT: 1437 speed = PCIE_LINK_SPEED_2_5; 1438 break; 1439 case QEMU_PCI_EXP_LNK_5GT: 1440 speed = PCIE_LINK_SPEED_5; 1441 break; 1442 case QEMU_PCI_EXP_LNK_8GT: 1443 speed = PCIE_LINK_SPEED_8; 1444 break; 1445 case QEMU_PCI_EXP_LNK_16GT: 1446 speed = PCIE_LINK_SPEED_16; 1447 break; 1448 default: 1449 /* Unreachable */ 1450 abort(); 1451 } 1452 1453 visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp); 1454 } 1455 1456 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name, 1457 void *opaque, Error **errp) 1458 { 1459 DeviceState *dev = DEVICE(obj); 1460 Property *prop = opaque; 1461 PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop); 1462 int speed; 1463 1464 if (dev->realized) { 1465 qdev_prop_set_after_realize(dev, name, errp); 1466 return; 1467 } 1468 1469 if (!visit_type_enum(v, prop->name, &speed, prop->info->enum_table, 1470 errp)) { 1471 return; 1472 } 1473 1474 switch (speed) { 1475 case PCIE_LINK_SPEED_2_5: 1476 *p = QEMU_PCI_EXP_LNK_2_5GT; 1477 break; 1478 case PCIE_LINK_SPEED_5: 1479 *p = QEMU_PCI_EXP_LNK_5GT; 1480 break; 1481 case PCIE_LINK_SPEED_8: 1482 *p = QEMU_PCI_EXP_LNK_8GT; 1483 break; 1484 case PCIE_LINK_SPEED_16: 1485 *p = QEMU_PCI_EXP_LNK_16GT; 1486 break; 1487 default: 1488 /* Unreachable */ 1489 abort(); 1490 } 1491 } 1492 1493 const PropertyInfo qdev_prop_pcie_link_speed = { 1494 .name = "PCIELinkSpeed", 1495 .description = "2_5/5/8/16", 1496 .enum_table = &PCIELinkSpeed_lookup, 1497 .get = get_prop_pcielinkspeed, 1498 .set = set_prop_pcielinkspeed, 1499 .set_default_value = set_default_value_enum, 1500 }; 1501 1502 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */ 1503 1504 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name, 1505 void *opaque, Error **errp) 1506 { 1507 DeviceState *dev = DEVICE(obj); 1508 Property *prop = opaque; 1509 PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop); 1510 int width; 1511 1512 switch (*p) { 1513 case QEMU_PCI_EXP_LNK_X1: 1514 width = PCIE_LINK_WIDTH_1; 1515 break; 1516 case QEMU_PCI_EXP_LNK_X2: 1517 width = PCIE_LINK_WIDTH_2; 1518 break; 1519 case QEMU_PCI_EXP_LNK_X4: 1520 width = PCIE_LINK_WIDTH_4; 1521 break; 1522 case QEMU_PCI_EXP_LNK_X8: 1523 width = PCIE_LINK_WIDTH_8; 1524 break; 1525 case QEMU_PCI_EXP_LNK_X12: 1526 width = PCIE_LINK_WIDTH_12; 1527 break; 1528 case QEMU_PCI_EXP_LNK_X16: 1529 width = PCIE_LINK_WIDTH_16; 1530 break; 1531 case QEMU_PCI_EXP_LNK_X32: 1532 width = PCIE_LINK_WIDTH_32; 1533 break; 1534 default: 1535 /* Unreachable */ 1536 abort(); 1537 } 1538 1539 visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp); 1540 } 1541 1542 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name, 1543 void *opaque, Error **errp) 1544 { 1545 DeviceState *dev = DEVICE(obj); 1546 Property *prop = opaque; 1547 PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop); 1548 int width; 1549 1550 if (dev->realized) { 1551 qdev_prop_set_after_realize(dev, name, errp); 1552 return; 1553 } 1554 1555 if (!visit_type_enum(v, prop->name, &width, prop->info->enum_table, 1556 errp)) { 1557 return; 1558 } 1559 1560 switch (width) { 1561 case PCIE_LINK_WIDTH_1: 1562 *p = QEMU_PCI_EXP_LNK_X1; 1563 break; 1564 case PCIE_LINK_WIDTH_2: 1565 *p = QEMU_PCI_EXP_LNK_X2; 1566 break; 1567 case PCIE_LINK_WIDTH_4: 1568 *p = QEMU_PCI_EXP_LNK_X4; 1569 break; 1570 case PCIE_LINK_WIDTH_8: 1571 *p = QEMU_PCI_EXP_LNK_X8; 1572 break; 1573 case PCIE_LINK_WIDTH_12: 1574 *p = QEMU_PCI_EXP_LNK_X12; 1575 break; 1576 case PCIE_LINK_WIDTH_16: 1577 *p = QEMU_PCI_EXP_LNK_X16; 1578 break; 1579 case PCIE_LINK_WIDTH_32: 1580 *p = QEMU_PCI_EXP_LNK_X32; 1581 break; 1582 default: 1583 /* Unreachable */ 1584 abort(); 1585 } 1586 } 1587 1588 const PropertyInfo qdev_prop_pcie_link_width = { 1589 .name = "PCIELinkWidth", 1590 .description = "1/2/4/8/12/16/32", 1591 .enum_table = &PCIELinkWidth_lookup, 1592 .get = get_prop_pcielinkwidth, 1593 .set = set_prop_pcielinkwidth, 1594 .set_default_value = set_default_value_enum, 1595 }; 1596