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