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