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