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