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