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