virtio-ramfb.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "qemu/osdep.h"
  2. #include "system/system.h"
  3. #include "hw/pci/pci.h"
  4. #include "ui/console.h"
  5. #include "hw/qdev-properties.h"
  6. #include "virtio-ramfb.h"
  7. #include "qapi/error.h"
  8. #include "qom/object.h"
  9. static int virtio_ramfb_get_flags(void *opaque)
  10. {
  11. VirtIORAMFBBase *vramfb = opaque;
  12. VirtIOGPUBase *g = vramfb->vgpu;
  13. if (g->hw_ops->get_flags) {
  14. return g->hw_ops->get_flags(g);
  15. } else {
  16. return 0;
  17. }
  18. }
  19. static void virtio_ramfb_invalidate_display(void *opaque)
  20. {
  21. VirtIORAMFBBase *vramfb = opaque;
  22. VirtIOGPUBase *g = vramfb->vgpu;
  23. if (g->enable) {
  24. g->hw_ops->invalidate(g);
  25. }
  26. }
  27. static void virtio_ramfb_text_update(void *opaque, console_ch_t *chardata)
  28. {
  29. VirtIORAMFBBase *vramfb = opaque;
  30. VirtIOGPUBase *g = vramfb->vgpu;
  31. if (g->hw_ops->text_update) {
  32. g->hw_ops->text_update(g, chardata);
  33. }
  34. }
  35. static void virtio_ramfb_update_display(void *opaque)
  36. {
  37. VirtIORAMFBBase *vramfb = opaque;
  38. VirtIOGPUBase *g = vramfb->vgpu;
  39. if (g->enable) {
  40. g->hw_ops->gfx_update(g);
  41. } else {
  42. ramfb_display_update(g->scanout[0].con, vramfb->ramfb);
  43. }
  44. }
  45. static void virtio_ramfb_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
  46. {
  47. VirtIORAMFBBase *vramfb = opaque;
  48. VirtIOGPUBase *g = vramfb->vgpu;
  49. if (g->hw_ops->ui_info) {
  50. g->hw_ops->ui_info(g, idx, info);
  51. }
  52. }
  53. static void virtio_ramfb_gl_block(void *opaque, bool block)
  54. {
  55. VirtIORAMFBBase *vramfb = opaque;
  56. VirtIOGPUBase *g = vramfb->vgpu;
  57. if (g->hw_ops->gl_block) {
  58. g->hw_ops->gl_block(g, block);
  59. }
  60. }
  61. static const GraphicHwOps virtio_ramfb_ops = {
  62. .get_flags = virtio_ramfb_get_flags,
  63. .invalidate = virtio_ramfb_invalidate_display,
  64. .gfx_update = virtio_ramfb_update_display,
  65. .text_update = virtio_ramfb_text_update,
  66. .ui_info = virtio_ramfb_ui_info,
  67. .gl_block = virtio_ramfb_gl_block,
  68. };
  69. static const VMStateDescription vmstate_virtio_ramfb = {
  70. .name = "virtio-ramfb",
  71. .version_id = 2,
  72. .minimum_version_id = 2,
  73. .fields = (VMStateField[]) {
  74. /* no pci stuff here, saving the virtio device will handle that */
  75. /* FIXME */
  76. VMSTATE_END_OF_LIST()
  77. }
  78. };
  79. /* RAMFB device wrapper around PCI device around virtio GPU */
  80. static void virtio_ramfb_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
  81. {
  82. VirtIORAMFBBase *vramfb = VIRTIO_RAMFB_BASE(vpci_dev);
  83. VirtIOGPUBase *g = vramfb->vgpu;
  84. int i;
  85. /* init virtio bits */
  86. virtio_pci_force_virtio_1(vpci_dev);
  87. if (!qdev_realize(DEVICE(g), BUS(&vpci_dev->bus), errp)) {
  88. return;
  89. }
  90. /* init ramfb */
  91. vramfb->ramfb = ramfb_setup(errp);
  92. graphic_console_set_hwops(g->scanout[0].con, &virtio_ramfb_ops, vramfb);
  93. for (i = 0; i < g->conf.max_outputs; i++) {
  94. object_property_set_link(OBJECT(g->scanout[i].con), "device",
  95. OBJECT(vpci_dev), &error_abort);
  96. }
  97. }
  98. static void virtio_ramfb_reset_hold(Object *obj, ResetType type)
  99. {
  100. VirtIORAMFBBase *dev = VIRTIO_RAMFB_BASE(obj);
  101. VirtIORAMFBBaseClass *klass = VIRTIO_RAMFB_BASE_GET_CLASS(dev);
  102. /* reset virtio-gpu */
  103. if (klass->parent_phases.hold) {
  104. klass->parent_phases.hold(obj, type);
  105. }
  106. }
  107. static const Property virtio_ramfb_base_properties[] = {
  108. DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy),
  109. };
  110. static void virtio_ramfb_base_class_init(ObjectClass *klass, void *data)
  111. {
  112. DeviceClass *dc = DEVICE_CLASS(klass);
  113. VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
  114. VirtIORAMFBBaseClass *v = VIRTIO_RAMFB_BASE_CLASS(klass);
  115. PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
  116. ResettableClass *rc = RESETTABLE_CLASS(klass);
  117. set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
  118. device_class_set_props(dc, virtio_ramfb_base_properties);
  119. dc->vmsd = &vmstate_virtio_ramfb;
  120. dc->hotpluggable = false;
  121. resettable_class_set_parent_phases(rc, NULL, virtio_ramfb_reset_hold, NULL,
  122. &v->parent_phases);
  123. k->realize = virtio_ramfb_realize;
  124. pcidev_k->class_id = PCI_CLASS_DISPLAY_OTHER;
  125. }
  126. static const TypeInfo virtio_ramfb_base_info = {
  127. .name = TYPE_VIRTIO_RAMFB_BASE,
  128. .parent = TYPE_VIRTIO_PCI,
  129. .instance_size = sizeof(VirtIORAMFBBase),
  130. .class_size = sizeof(VirtIORAMFBBaseClass),
  131. .class_init = virtio_ramfb_base_class_init,
  132. .abstract = true,
  133. };
  134. #define TYPE_VIRTIO_RAMFB "virtio-ramfb"
  135. typedef struct VirtIORAMFB VirtIORAMFB;
  136. DECLARE_INSTANCE_CHECKER(VirtIORAMFB, VIRTIO_RAMFB,
  137. TYPE_VIRTIO_RAMFB)
  138. struct VirtIORAMFB {
  139. VirtIORAMFBBase parent_obj;
  140. VirtIOGPU vdev;
  141. };
  142. static void virtio_ramfb_inst_initfn(Object *obj)
  143. {
  144. VirtIORAMFB *dev = VIRTIO_RAMFB(obj);
  145. virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
  146. TYPE_VIRTIO_GPU);
  147. VIRTIO_RAMFB_BASE(dev)->vgpu = VIRTIO_GPU_BASE(&dev->vdev);
  148. }
  149. static VirtioPCIDeviceTypeInfo virtio_ramfb_info = {
  150. .generic_name = TYPE_VIRTIO_RAMFB,
  151. .parent = TYPE_VIRTIO_RAMFB_BASE,
  152. .instance_size = sizeof(VirtIORAMFB),
  153. .instance_init = virtio_ramfb_inst_initfn,
  154. };
  155. static void virtio_ramfb_register_types(void)
  156. {
  157. type_register_static(&virtio_ramfb_base_info);
  158. virtio_pci_types_register(&virtio_ramfb_info);
  159. }
  160. type_init(virtio_ramfb_register_types)