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 "', " 902 "it's not a power of 2", 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 const 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 if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0xffff || e == p) { 970 goto inval; 971 } 972 if (*e != ':') { 973 goto inval; 974 } 975 bus = val; 976 977 p = (char *)e + 1; 978 if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0x1f || e == p) { 979 goto inval; 980 } 981 if (*e == ':') { 982 dom = bus; 983 bus = val; 984 p = (char *)e + 1; 985 if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0x1f || e == p) { 986 goto inval; 987 } 988 } 989 slot = val; 990 991 if (*e != '.') { 992 goto inval; 993 } 994 p = (char *)e + 1; 995 if (qemu_strtoul(p, &e, 10, &val) < 0 || val > 7 || e == p) { 996 goto inval; 997 } 998 func = val; 999 1000 if (bus > 0xff) { 1001 goto inval; 1002 } 1003 1004 if (*e) { 1005 goto inval; 1006 } 1007 1008 addr->domain = dom; 1009 addr->bus = bus; 1010 addr->slot = slot; 1011 addr->function = func; 1012 1013 g_free(str); 1014 return; 1015 1016 inval: 1017 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 1018 g_free(str); 1019 } 1020 1021 const PropertyInfo qdev_prop_pci_host_devaddr = { 1022 .name = "str", 1023 .description = "Address (bus/device/function) of " 1024 "the host device, example: 04:10.0", 1025 .get = get_pci_host_devaddr, 1026 .set = set_pci_host_devaddr, 1027 }; 1028 1029 /* --- UUID --- */ 1030 1031 static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque, 1032 Error **errp) 1033 { 1034 DeviceState *dev = DEVICE(obj); 1035 Property *prop = opaque; 1036 QemuUUID *uuid = qdev_get_prop_ptr(dev, prop); 1037 char buffer[UUID_FMT_LEN + 1]; 1038 char *p = buffer; 1039 1040 qemu_uuid_unparse(uuid, buffer); 1041 1042 visit_type_str(v, name, &p, errp); 1043 } 1044 1045 #define UUID_VALUE_AUTO "auto" 1046 1047 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque, 1048 Error **errp) 1049 { 1050 DeviceState *dev = DEVICE(obj); 1051 Property *prop = opaque; 1052 QemuUUID *uuid = qdev_get_prop_ptr(dev, prop); 1053 char *str; 1054 1055 if (dev->realized) { 1056 qdev_prop_set_after_realize(dev, name, errp); 1057 return; 1058 } 1059 1060 if (!visit_type_str(v, name, &str, errp)) { 1061 return; 1062 } 1063 1064 if (!strcmp(str, UUID_VALUE_AUTO)) { 1065 qemu_uuid_generate(uuid); 1066 } else if (qemu_uuid_parse(str, uuid) < 0) { 1067 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 1068 } 1069 g_free(str); 1070 } 1071 1072 static void set_default_uuid_auto(ObjectProperty *op, const Property *prop) 1073 { 1074 object_property_set_default_str(op, UUID_VALUE_AUTO); 1075 } 1076 1077 const PropertyInfo qdev_prop_uuid = { 1078 .name = "str", 1079 .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO 1080 "\" for random value (default)", 1081 .get = get_uuid, 1082 .set = set_uuid, 1083 .set_default_value = set_default_uuid_auto, 1084 }; 1085 1086 /* --- support for array properties --- */ 1087 1088 /* Used as an opaque for the object properties we add for each 1089 * array element. Note that the struct Property must be first 1090 * in the struct so that a pointer to this works as the opaque 1091 * for the underlying element's property hooks as well as for 1092 * our own release callback. 1093 */ 1094 typedef struct { 1095 struct Property prop; 1096 char *propname; 1097 ObjectPropertyRelease *release; 1098 } ArrayElementProperty; 1099 1100 /* object property release callback for array element properties: 1101 * we call the underlying element's property release hook, and 1102 * then free the memory we allocated when we added the property. 1103 */ 1104 static void array_element_release(Object *obj, const char *name, void *opaque) 1105 { 1106 ArrayElementProperty *p = opaque; 1107 if (p->release) { 1108 p->release(obj, name, opaque); 1109 } 1110 g_free(p->propname); 1111 g_free(p); 1112 } 1113 1114 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, 1115 void *opaque, Error **errp) 1116 { 1117 /* Setter for the property which defines the length of a 1118 * variable-sized property array. As well as actually setting the 1119 * array-length field in the device struct, we have to create the 1120 * array itself and dynamically add the corresponding properties. 1121 */ 1122 DeviceState *dev = DEVICE(obj); 1123 Property *prop = opaque; 1124 uint32_t *alenptr = qdev_get_prop_ptr(dev, prop); 1125 void **arrayptr = (void *)dev + prop->arrayoffset; 1126 void *eltptr; 1127 const char *arrayname; 1128 int i; 1129 1130 if (dev->realized) { 1131 qdev_prop_set_after_realize(dev, name, errp); 1132 return; 1133 } 1134 if (*alenptr) { 1135 error_setg(errp, "array size property %s may not be set more than once", 1136 name); 1137 return; 1138 } 1139 if (!visit_type_uint32(v, name, alenptr, errp)) { 1140 return; 1141 } 1142 if (!*alenptr) { 1143 return; 1144 } 1145 1146 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix; 1147 * strip it off so we can get the name of the array itself. 1148 */ 1149 assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, 1150 strlen(PROP_ARRAY_LEN_PREFIX)) == 0); 1151 arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); 1152 1153 /* Note that it is the responsibility of the individual device's deinit 1154 * to free the array proper. 1155 */ 1156 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); 1157 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { 1158 char *propname = g_strdup_printf("%s[%d]", arrayname, i); 1159 ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1); 1160 arrayprop->release = prop->arrayinfo->release; 1161 arrayprop->propname = propname; 1162 arrayprop->prop.info = prop->arrayinfo; 1163 arrayprop->prop.name = propname; 1164 /* This ugly piece of pointer arithmetic sets up the offset so 1165 * that when the underlying get/set hooks call qdev_get_prop_ptr 1166 * they get the right answer despite the array element not actually 1167 * being inside the device struct. 1168 */ 1169 arrayprop->prop.offset = eltptr - (void *)dev; 1170 assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr); 1171 object_property_add(obj, propname, 1172 arrayprop->prop.info->name, 1173 arrayprop->prop.info->get, 1174 arrayprop->prop.info->set, 1175 array_element_release, 1176 arrayprop); 1177 } 1178 } 1179 1180 const PropertyInfo qdev_prop_arraylen = { 1181 .name = "uint32", 1182 .get = get_uint32, 1183 .set = set_prop_arraylen, 1184 .set_default_value = set_default_value_uint, 1185 }; 1186 1187 /* --- public helpers --- */ 1188 1189 static Property *qdev_prop_walk(Property *props, const char *name) 1190 { 1191 if (!props) { 1192 return NULL; 1193 } 1194 while (props->name) { 1195 if (strcmp(props->name, name) == 0) { 1196 return props; 1197 } 1198 props++; 1199 } 1200 return NULL; 1201 } 1202 1203 static Property *qdev_prop_find(DeviceState *dev, const char *name) 1204 { 1205 ObjectClass *class; 1206 Property *prop; 1207 1208 /* device properties */ 1209 class = object_get_class(OBJECT(dev)); 1210 do { 1211 prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name); 1212 if (prop) { 1213 return prop; 1214 } 1215 class = object_class_get_parent(class); 1216 } while (class != object_class_by_name(TYPE_DEVICE)); 1217 1218 return NULL; 1219 } 1220 1221 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, 1222 Property *prop, const char *value) 1223 { 1224 switch (ret) { 1225 case -EEXIST: 1226 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", 1227 object_get_typename(OBJECT(dev)), prop->name, value); 1228 break; 1229 default: 1230 case -EINVAL: 1231 error_setg(errp, QERR_PROPERTY_VALUE_BAD, 1232 object_get_typename(OBJECT(dev)), prop->name, value); 1233 break; 1234 case -ENOENT: 1235 error_setg(errp, "Property '%s.%s' can't find value '%s'", 1236 object_get_typename(OBJECT(dev)), prop->name, value); 1237 break; 1238 case 0: 1239 break; 1240 } 1241 } 1242 1243 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) 1244 { 1245 object_property_set_bool(OBJECT(dev), name, value, &error_abort); 1246 } 1247 1248 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) 1249 { 1250 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1251 } 1252 1253 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) 1254 { 1255 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1256 } 1257 1258 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) 1259 { 1260 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1261 } 1262 1263 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) 1264 { 1265 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1266 } 1267 1268 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) 1269 { 1270 object_property_set_int(OBJECT(dev), name, value, &error_abort); 1271 } 1272 1273 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) 1274 { 1275 object_property_set_str(OBJECT(dev), name, value, &error_abort); 1276 } 1277 1278 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, 1279 const uint8_t *value) 1280 { 1281 char str[2 * 6 + 5 + 1]; 1282 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", 1283 value[0], value[1], value[2], value[3], value[4], value[5]); 1284 1285 object_property_set_str(OBJECT(dev), name, str, &error_abort); 1286 } 1287 1288 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) 1289 { 1290 Property *prop; 1291 1292 prop = qdev_prop_find(dev, name); 1293 object_property_set_str(OBJECT(dev), name, 1294 qapi_enum_lookup(prop->info->enum_table, value), 1295 &error_abort); 1296 } 1297 1298 static GPtrArray *global_props(void) 1299 { 1300 static GPtrArray *gp; 1301 1302 if (!gp) { 1303 gp = g_ptr_array_new(); 1304 } 1305 1306 return gp; 1307 } 1308 1309 void qdev_prop_register_global(GlobalProperty *prop) 1310 { 1311 g_ptr_array_add(global_props(), prop); 1312 } 1313 1314 const GlobalProperty *qdev_find_global_prop(DeviceState *dev, 1315 const char *name) 1316 { 1317 GPtrArray *props = global_props(); 1318 const GlobalProperty *p; 1319 int i; 1320 1321 for (i = 0; i < props->len; i++) { 1322 p = g_ptr_array_index(props, i); 1323 if (object_dynamic_cast(OBJECT(dev), p->driver) 1324 && !strcmp(p->property, name)) { 1325 return p; 1326 } 1327 } 1328 return NULL; 1329 } 1330 1331 int qdev_prop_check_globals(void) 1332 { 1333 int i, ret = 0; 1334 1335 for (i = 0; i < global_props()->len; i++) { 1336 GlobalProperty *prop; 1337 ObjectClass *oc; 1338 DeviceClass *dc; 1339 1340 prop = g_ptr_array_index(global_props(), i); 1341 if (prop->used) { 1342 continue; 1343 } 1344 oc = object_class_by_name(prop->driver); 1345 oc = object_class_dynamic_cast(oc, TYPE_DEVICE); 1346 if (!oc) { 1347 warn_report("global %s.%s has invalid class name", 1348 prop->driver, prop->property); 1349 ret = 1; 1350 continue; 1351 } 1352 dc = DEVICE_CLASS(oc); 1353 if (!dc->hotpluggable && !prop->used) { 1354 warn_report("global %s.%s=%s not used", 1355 prop->driver, prop->property, prop->value); 1356 ret = 1; 1357 continue; 1358 } 1359 } 1360 return ret; 1361 } 1362 1363 void qdev_prop_set_globals(DeviceState *dev) 1364 { 1365 object_apply_global_props(OBJECT(dev), global_props(), 1366 dev->hotplugged ? NULL : &error_fatal); 1367 } 1368 1369 /* --- 64bit unsigned int 'size' type --- */ 1370 1371 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque, 1372 Error **errp) 1373 { 1374 DeviceState *dev = DEVICE(obj); 1375 Property *prop = opaque; 1376 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1377 1378 visit_type_size(v, name, ptr, errp); 1379 } 1380 1381 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque, 1382 Error **errp) 1383 { 1384 DeviceState *dev = DEVICE(obj); 1385 Property *prop = opaque; 1386 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1387 1388 visit_type_size(v, name, ptr, errp); 1389 } 1390 1391 const PropertyInfo qdev_prop_size = { 1392 .name = "size", 1393 .get = get_size, 1394 .set = set_size, 1395 .set_default_value = set_default_value_uint, 1396 }; 1397 1398 /* --- object link property --- */ 1399 1400 static void create_link_property(ObjectClass *oc, Property *prop) 1401 { 1402 object_class_property_add_link(oc, prop->name, prop->link_type, 1403 prop->offset, 1404 qdev_prop_allow_set_link_before_realize, 1405 OBJ_PROP_LINK_STRONG); 1406 } 1407 1408 const PropertyInfo qdev_prop_link = { 1409 .name = "link", 1410 .create = create_link_property, 1411 }; 1412 1413 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */ 1414 1415 const PropertyInfo qdev_prop_off_auto_pcibar = { 1416 .name = "OffAutoPCIBAR", 1417 .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5", 1418 .enum_table = &OffAutoPCIBAR_lookup, 1419 .get = get_enum, 1420 .set = set_enum, 1421 .set_default_value = set_default_value_enum, 1422 }; 1423 1424 /* --- PCIELinkSpeed 2_5/5/8/16 -- */ 1425 1426 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name, 1427 void *opaque, Error **errp) 1428 { 1429 DeviceState *dev = DEVICE(obj); 1430 Property *prop = opaque; 1431 PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop); 1432 int speed; 1433 1434 switch (*p) { 1435 case QEMU_PCI_EXP_LNK_2_5GT: 1436 speed = PCIE_LINK_SPEED_2_5; 1437 break; 1438 case QEMU_PCI_EXP_LNK_5GT: 1439 speed = PCIE_LINK_SPEED_5; 1440 break; 1441 case QEMU_PCI_EXP_LNK_8GT: 1442 speed = PCIE_LINK_SPEED_8; 1443 break; 1444 case QEMU_PCI_EXP_LNK_16GT: 1445 speed = PCIE_LINK_SPEED_16; 1446 break; 1447 default: 1448 /* Unreachable */ 1449 abort(); 1450 } 1451 1452 visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp); 1453 } 1454 1455 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name, 1456 void *opaque, Error **errp) 1457 { 1458 DeviceState *dev = DEVICE(obj); 1459 Property *prop = opaque; 1460 PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop); 1461 int speed; 1462 1463 if (dev->realized) { 1464 qdev_prop_set_after_realize(dev, name, errp); 1465 return; 1466 } 1467 1468 if (!visit_type_enum(v, prop->name, &speed, prop->info->enum_table, 1469 errp)) { 1470 return; 1471 } 1472 1473 switch (speed) { 1474 case PCIE_LINK_SPEED_2_5: 1475 *p = QEMU_PCI_EXP_LNK_2_5GT; 1476 break; 1477 case PCIE_LINK_SPEED_5: 1478 *p = QEMU_PCI_EXP_LNK_5GT; 1479 break; 1480 case PCIE_LINK_SPEED_8: 1481 *p = QEMU_PCI_EXP_LNK_8GT; 1482 break; 1483 case PCIE_LINK_SPEED_16: 1484 *p = QEMU_PCI_EXP_LNK_16GT; 1485 break; 1486 default: 1487 /* Unreachable */ 1488 abort(); 1489 } 1490 } 1491 1492 const PropertyInfo qdev_prop_pcie_link_speed = { 1493 .name = "PCIELinkSpeed", 1494 .description = "2_5/5/8/16", 1495 .enum_table = &PCIELinkSpeed_lookup, 1496 .get = get_prop_pcielinkspeed, 1497 .set = set_prop_pcielinkspeed, 1498 .set_default_value = set_default_value_enum, 1499 }; 1500 1501 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */ 1502 1503 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name, 1504 void *opaque, Error **errp) 1505 { 1506 DeviceState *dev = DEVICE(obj); 1507 Property *prop = opaque; 1508 PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop); 1509 int width; 1510 1511 switch (*p) { 1512 case QEMU_PCI_EXP_LNK_X1: 1513 width = PCIE_LINK_WIDTH_1; 1514 break; 1515 case QEMU_PCI_EXP_LNK_X2: 1516 width = PCIE_LINK_WIDTH_2; 1517 break; 1518 case QEMU_PCI_EXP_LNK_X4: 1519 width = PCIE_LINK_WIDTH_4; 1520 break; 1521 case QEMU_PCI_EXP_LNK_X8: 1522 width = PCIE_LINK_WIDTH_8; 1523 break; 1524 case QEMU_PCI_EXP_LNK_X12: 1525 width = PCIE_LINK_WIDTH_12; 1526 break; 1527 case QEMU_PCI_EXP_LNK_X16: 1528 width = PCIE_LINK_WIDTH_16; 1529 break; 1530 case QEMU_PCI_EXP_LNK_X32: 1531 width = PCIE_LINK_WIDTH_32; 1532 break; 1533 default: 1534 /* Unreachable */ 1535 abort(); 1536 } 1537 1538 visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp); 1539 } 1540 1541 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name, 1542 void *opaque, Error **errp) 1543 { 1544 DeviceState *dev = DEVICE(obj); 1545 Property *prop = opaque; 1546 PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop); 1547 int width; 1548 1549 if (dev->realized) { 1550 qdev_prop_set_after_realize(dev, name, errp); 1551 return; 1552 } 1553 1554 if (!visit_type_enum(v, prop->name, &width, prop->info->enum_table, 1555 errp)) { 1556 return; 1557 } 1558 1559 switch (width) { 1560 case PCIE_LINK_WIDTH_1: 1561 *p = QEMU_PCI_EXP_LNK_X1; 1562 break; 1563 case PCIE_LINK_WIDTH_2: 1564 *p = QEMU_PCI_EXP_LNK_X2; 1565 break; 1566 case PCIE_LINK_WIDTH_4: 1567 *p = QEMU_PCI_EXP_LNK_X4; 1568 break; 1569 case PCIE_LINK_WIDTH_8: 1570 *p = QEMU_PCI_EXP_LNK_X8; 1571 break; 1572 case PCIE_LINK_WIDTH_12: 1573 *p = QEMU_PCI_EXP_LNK_X12; 1574 break; 1575 case PCIE_LINK_WIDTH_16: 1576 *p = QEMU_PCI_EXP_LNK_X16; 1577 break; 1578 case PCIE_LINK_WIDTH_32: 1579 *p = QEMU_PCI_EXP_LNK_X32; 1580 break; 1581 default: 1582 /* Unreachable */ 1583 abort(); 1584 } 1585 } 1586 1587 const PropertyInfo qdev_prop_pcie_link_width = { 1588 .name = "PCIELinkWidth", 1589 .description = "1/2/4/8/12/16/32", 1590 .enum_table = &PCIELinkWidth_lookup, 1591 .get = get_prop_pcielinkwidth, 1592 .set = set_prop_pcielinkwidth, 1593 .set_default_value = set_default_value_enum, 1594 }; 1595