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