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