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