empty_slot.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * QEMU Empty Slot
  3. *
  4. * The empty_slot device emulates known to a bus but not connected devices.
  5. *
  6. * Copyright (c) 2010 Artyom Tarasenko
  7. *
  8. * This code is licensed under the GNU GPL v2 or (at your option) any later
  9. * version.
  10. */
  11. #include "qemu/osdep.h"
  12. #include "hw/sysbus.h"
  13. #include "hw/qdev-properties.h"
  14. #include "hw/misc/empty_slot.h"
  15. #include "qapi/error.h"
  16. #include "trace.h"
  17. #define TYPE_EMPTY_SLOT "empty_slot"
  18. #define EMPTY_SLOT(obj) OBJECT_CHECK(EmptySlot, (obj), TYPE_EMPTY_SLOT)
  19. typedef struct EmptySlot {
  20. SysBusDevice parent_obj;
  21. MemoryRegion iomem;
  22. char *name;
  23. uint64_t size;
  24. } EmptySlot;
  25. static uint64_t empty_slot_read(void *opaque, hwaddr addr,
  26. unsigned size)
  27. {
  28. EmptySlot *s = EMPTY_SLOT(opaque);
  29. trace_empty_slot_write(addr, size << 1, 0, size, s->name);
  30. return 0;
  31. }
  32. static void empty_slot_write(void *opaque, hwaddr addr,
  33. uint64_t val, unsigned size)
  34. {
  35. EmptySlot *s = EMPTY_SLOT(opaque);
  36. trace_empty_slot_write(addr, size << 1, val, size, s->name);
  37. }
  38. static const MemoryRegionOps empty_slot_ops = {
  39. .read = empty_slot_read,
  40. .write = empty_slot_write,
  41. .endianness = DEVICE_NATIVE_ENDIAN,
  42. };
  43. void empty_slot_init(const char *name, hwaddr addr, uint64_t slot_size)
  44. {
  45. if (slot_size > 0) {
  46. /* Only empty slots larger than 0 byte need handling. */
  47. DeviceState *dev;
  48. dev = qdev_new(TYPE_EMPTY_SLOT);
  49. qdev_prop_set_uint64(dev, "size", slot_size);
  50. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  51. sysbus_mmio_map_overlap(SYS_BUS_DEVICE(dev), 0, addr, -10000);
  52. }
  53. }
  54. static void empty_slot_realize(DeviceState *dev, Error **errp)
  55. {
  56. EmptySlot *s = EMPTY_SLOT(dev);
  57. if (s->name == NULL) {
  58. s->name = g_strdup("empty-slot");
  59. }
  60. memory_region_init_io(&s->iomem, OBJECT(s), &empty_slot_ops, s,
  61. s->name, s->size);
  62. sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
  63. }
  64. static Property empty_slot_properties[] = {
  65. DEFINE_PROP_UINT64("size", EmptySlot, size, 0),
  66. DEFINE_PROP_STRING("name", EmptySlot, name),
  67. DEFINE_PROP_END_OF_LIST(),
  68. };
  69. static void empty_slot_class_init(ObjectClass *klass, void *data)
  70. {
  71. DeviceClass *dc = DEVICE_CLASS(klass);
  72. dc->realize = empty_slot_realize;
  73. device_class_set_props(dc, empty_slot_properties);
  74. set_bit(DEVICE_CATEGORY_MISC, dc->categories);
  75. }
  76. static const TypeInfo empty_slot_info = {
  77. .name = TYPE_EMPTY_SLOT,
  78. .parent = TYPE_SYS_BUS_DEVICE,
  79. .instance_size = sizeof(EmptySlot),
  80. .class_init = empty_slot_class_init,
  81. };
  82. static void empty_slot_register_types(void)
  83. {
  84. type_register_static(&empty_slot_info);
  85. }
  86. type_init(empty_slot_register_types)