xref: /openbmc/qemu/hw/display/qxl.h (revision 9468484fe904ab4691de6d9c34616667f377ceac)
147b43a1fSPaolo Bonzini #ifndef HW_QXL_H
2175de524SMarkus Armbruster #define HW_QXL_H
347b43a1fSPaolo Bonzini 
4edf5ca5dSMarkus Armbruster #include "hw/pci/pci_device.h"
547b43a1fSPaolo Bonzini #include "vga_int.h"
647b43a1fSPaolo Bonzini #include "qemu/thread.h"
747b43a1fSPaolo Bonzini 
847b43a1fSPaolo Bonzini #include "ui/qemu-spice.h"
947b43a1fSPaolo Bonzini #include "ui/spice-display.h"
10db1015e9SEduardo Habkost #include "qom/object.h"
1147b43a1fSPaolo Bonzini 
1247b43a1fSPaolo Bonzini enum qxl_mode {
1347b43a1fSPaolo Bonzini     QXL_MODE_UNDEFINED,
1447b43a1fSPaolo Bonzini     QXL_MODE_VGA,
1547b43a1fSPaolo Bonzini     QXL_MODE_COMPAT, /* spice 0.4.x */
1647b43a1fSPaolo Bonzini     QXL_MODE_NATIVE,
1747b43a1fSPaolo Bonzini };
1847b43a1fSPaolo Bonzini 
1947b43a1fSPaolo Bonzini #ifndef QXL_VRAM64_RANGE_INDEX
2047b43a1fSPaolo Bonzini #define QXL_VRAM64_RANGE_INDEX 4
2147b43a1fSPaolo Bonzini #endif
2247b43a1fSPaolo Bonzini 
2347b43a1fSPaolo Bonzini #define QXL_UNDEFINED_IO UINT32_MAX
2447b43a1fSPaolo Bonzini 
2547b43a1fSPaolo Bonzini #define QXL_NUM_DIRTY_RECTS 64
2647b43a1fSPaolo Bonzini 
279efc2d8dSGerd Hoffmann #define QXL_PAGE_BITS 12
289efc2d8dSGerd Hoffmann #define QXL_PAGE_SIZE (1 << QXL_PAGE_BITS);
299efc2d8dSGerd Hoffmann 
30db1015e9SEduardo Habkost struct PCIQXLDevice {
3147b43a1fSPaolo Bonzini     PCIDevice          pci;
32848696bfSKirill Batuzov     PortioList         vga_port_list;
3347b43a1fSPaolo Bonzini     SimpleSpiceDisplay ssd;
3447b43a1fSPaolo Bonzini     int                id;
3560e94e43SGerd Hoffmann     bool               have_vga;
3647b43a1fSPaolo Bonzini     uint32_t           debug;
3747b43a1fSPaolo Bonzini     uint32_t           guestdebug;
3847b43a1fSPaolo Bonzini     uint32_t           cmdlog;
3947b43a1fSPaolo Bonzini 
4047b43a1fSPaolo Bonzini     uint32_t           guest_bug;
4147b43a1fSPaolo Bonzini 
4247b43a1fSPaolo Bonzini     enum qxl_mode      mode;
4347b43a1fSPaolo Bonzini     uint32_t           cmdflags;
4447b43a1fSPaolo Bonzini     uint32_t           revision;
4547b43a1fSPaolo Bonzini 
4647b43a1fSPaolo Bonzini     int32_t            num_memslots;
4747b43a1fSPaolo Bonzini 
4847b43a1fSPaolo Bonzini     uint32_t           current_async;
4947b43a1fSPaolo Bonzini     QemuMutex          async_lock;
5047b43a1fSPaolo Bonzini 
5147b43a1fSPaolo Bonzini     struct guest_slots {
5247b43a1fSPaolo Bonzini         QXLMemSlot     slot;
533cb5158fSGerd Hoffmann         MemoryRegion   *mr;
543cb5158fSGerd Hoffmann         uint64_t       offset;
5547b43a1fSPaolo Bonzini         uint64_t       size;
5647b43a1fSPaolo Bonzini         uint64_t       delta;
5747b43a1fSPaolo Bonzini         uint32_t       active;
5847b43a1fSPaolo Bonzini     } guest_slots[NUM_MEMSLOTS];
5947b43a1fSPaolo Bonzini 
6047b43a1fSPaolo Bonzini     struct guest_primary {
6147b43a1fSPaolo Bonzini         QXLSurfaceCreate surface;
6247b43a1fSPaolo Bonzini         uint32_t       commands;
6347b43a1fSPaolo Bonzini         uint32_t       resized;
6447b43a1fSPaolo Bonzini         int32_t        qxl_stride;
6547b43a1fSPaolo Bonzini         uint32_t       abs_stride;
6647b43a1fSPaolo Bonzini         uint32_t       bits_pp;
6747b43a1fSPaolo Bonzini         uint32_t       bytes_pp;
6847b43a1fSPaolo Bonzini         uint8_t        *data;
6947b43a1fSPaolo Bonzini     } guest_primary;
7047b43a1fSPaolo Bonzini 
7147b43a1fSPaolo Bonzini     struct surfaces {
7247b43a1fSPaolo Bonzini         QXLPHYSICAL    *cmds;
7347b43a1fSPaolo Bonzini         uint32_t       count;
7447b43a1fSPaolo Bonzini         uint32_t       max;
7547b43a1fSPaolo Bonzini     } guest_surfaces;
7647b43a1fSPaolo Bonzini     QXLPHYSICAL        guest_cursor;
7747b43a1fSPaolo Bonzini 
7847b43a1fSPaolo Bonzini     QXLPHYSICAL        guest_monitors_config;
79979f7ef8SGerd Hoffmann     uint32_t           guest_head0_width;
80979f7ef8SGerd Hoffmann     uint32_t           guest_head0_height;
8147b43a1fSPaolo Bonzini 
8247b43a1fSPaolo Bonzini     QemuMutex          track_lock;
8347b43a1fSPaolo Bonzini 
8447b43a1fSPaolo Bonzini     /* thread signaling */
854a46c99cSGerd Hoffmann     QEMUBH             *update_irq;
8647b43a1fSPaolo Bonzini 
8747b43a1fSPaolo Bonzini     /* ram pci bar */
8847b43a1fSPaolo Bonzini     QXLRam             *ram;
8947b43a1fSPaolo Bonzini     VGACommonState     vga;
9047b43a1fSPaolo Bonzini     uint32_t           num_free_res;
9147b43a1fSPaolo Bonzini     QXLReleaseInfo     *last_release;
9247b43a1fSPaolo Bonzini     uint32_t           last_release_offset;
9347b43a1fSPaolo Bonzini     uint32_t           oom_running;
9447b43a1fSPaolo Bonzini     uint32_t           vgamem_size;
9547b43a1fSPaolo Bonzini 
9647b43a1fSPaolo Bonzini     /* rom pci bar */
9747b43a1fSPaolo Bonzini     QXLRom             shadow_rom;
9847b43a1fSPaolo Bonzini     QXLRom             *rom;
9947b43a1fSPaolo Bonzini     QXLModes           *modes;
10047b43a1fSPaolo Bonzini     uint32_t           rom_size;
10147b43a1fSPaolo Bonzini     MemoryRegion       rom_bar;
102567161fdSFrediano Ziglio     uint16_t           max_outputs;
10347b43a1fSPaolo Bonzini 
10447b43a1fSPaolo Bonzini     /* vram pci bar */
105de1b9b85SGerd Hoffmann     uint64_t           vram_size;
10647b43a1fSPaolo Bonzini     MemoryRegion       vram_bar;
107de1b9b85SGerd Hoffmann     uint64_t           vram32_size;
10847b43a1fSPaolo Bonzini     MemoryRegion       vram32_bar;
10947b43a1fSPaolo Bonzini 
11047b43a1fSPaolo Bonzini     /* io bar */
11147b43a1fSPaolo Bonzini     MemoryRegion       io_bar;
11247b43a1fSPaolo Bonzini 
11347b43a1fSPaolo Bonzini     /* user-friendly properties (in megabytes) */
11447b43a1fSPaolo Bonzini     uint32_t          ram_size_mb;
11547b43a1fSPaolo Bonzini     uint32_t          vram_size_mb;
11647b43a1fSPaolo Bonzini     uint32_t          vram32_size_mb;
11747b43a1fSPaolo Bonzini     uint32_t          vgamem_size_mb;
1186f663d7bSGerd Hoffmann     uint32_t          xres;
1196f663d7bSGerd Hoffmann     uint32_t          yres;
12047b43a1fSPaolo Bonzini 
12147b43a1fSPaolo Bonzini     /* qxl_render_update state */
12247b43a1fSPaolo Bonzini     int                render_update_cookie_num;
12347b43a1fSPaolo Bonzini     int                num_dirty_rects;
12447b43a1fSPaolo Bonzini     QXLRect            dirty[QXL_NUM_DIRTY_RECTS];
12547b43a1fSPaolo Bonzini     QEMUBH            *update_area_bh;
126db1015e9SEduardo Habkost };
12747b43a1fSPaolo Bonzini 
128c69f6c7dSGonglei #define TYPE_PCI_QXL "pci-qxl"
1298063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(PCIQXLDevice, PCI_QXL)
130c69f6c7dSGonglei 
13147b43a1fSPaolo Bonzini #define PANIC_ON(x) if ((x)) {                         \
132a89f364aSAlistair Francis     printf("%s: PANIC %s failed\n", __func__, #x); \
13347b43a1fSPaolo Bonzini     abort();                                           \
13447b43a1fSPaolo Bonzini }
13547b43a1fSPaolo Bonzini 
13647b43a1fSPaolo Bonzini #define dprint(_qxl, _level, _fmt, ...)                                 \
13747b43a1fSPaolo Bonzini     do {                                                                \
13847b43a1fSPaolo Bonzini         if (_qxl->debug >= _level) {                                    \
13947b43a1fSPaolo Bonzini             fprintf(stderr, "qxl-%d: ", _qxl->id);                      \
14047b43a1fSPaolo Bonzini             fprintf(stderr, _fmt, ## __VA_ARGS__);                      \
14147b43a1fSPaolo Bonzini         }                                                               \
14247b43a1fSPaolo Bonzini     } while (0)
14347b43a1fSPaolo Bonzini 
144ed71c09fSGerd Hoffmann #define QXL_DEFAULT_REVISION (QXL_REVISION_STABLE_V12 + 1)
14547b43a1fSPaolo Bonzini 
14647b43a1fSPaolo Bonzini /* qxl.c */
147b1901de8SPhilippe Mathieu-Daudé /**
148b1901de8SPhilippe Mathieu-Daudé  * qxl_phys2virt: Get a pointer within a PCI VRAM memory region.
149b1901de8SPhilippe Mathieu-Daudé  *
150b1901de8SPhilippe Mathieu-Daudé  * @qxl: QXL device
151b1901de8SPhilippe Mathieu-Daudé  * @phys: physical offset of buffer within the VRAM
152b1901de8SPhilippe Mathieu-Daudé  * @group_id: memory slot group
1538efec0efSPhilippe Mathieu-Daudé  * @size: size of the buffer
154b1901de8SPhilippe Mathieu-Daudé  *
155b1901de8SPhilippe Mathieu-Daudé  * Returns a host pointer to a buffer placed at offset @phys within the
156b1901de8SPhilippe Mathieu-Daudé  * active slot @group_id of the PCI VGA RAM memory region associated with
1576dbbf055SPhilippe Mathieu-Daudé  * the @qxl device. If the slot is inactive, or the offset + size are out
158b1901de8SPhilippe Mathieu-Daudé  * of the memory region, returns NULL.
159b1901de8SPhilippe Mathieu-Daudé  *
160b1901de8SPhilippe Mathieu-Daudé  * Use with care; by the time this function returns, the returned pointer is
161b1901de8SPhilippe Mathieu-Daudé  * not protected by RCU anymore.  If the caller is not within an RCU critical
162*a4a411fbSStefan Hajnoczi  * section and does not hold the BQL, it must have other means of
163b1901de8SPhilippe Mathieu-Daudé  * protecting the pointer, such as a reference to the region that includes
164b1901de8SPhilippe Mathieu-Daudé  * the incoming ram_addr_t.
165b1901de8SPhilippe Mathieu-Daudé  *
166b1901de8SPhilippe Mathieu-Daudé  */
1678efec0efSPhilippe Mathieu-Daudé void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id,
1688efec0efSPhilippe Mathieu-Daudé                     size_t size);
16947b43a1fSPaolo Bonzini void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
1709edc6313SMarc-André Lureau     G_GNUC_PRINTF(2, 3);
17147b43a1fSPaolo Bonzini 
17247b43a1fSPaolo Bonzini void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
17347b43a1fSPaolo Bonzini                            struct QXLRect *area, struct QXLRect *dirty_rects,
17447b43a1fSPaolo Bonzini                            uint32_t num_dirty_rects,
17547b43a1fSPaolo Bonzini                            uint32_t clear_dirty_region,
17647b43a1fSPaolo Bonzini                            qxl_async_io async, QXLCookie *cookie);
17747b43a1fSPaolo Bonzini void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
17847b43a1fSPaolo Bonzini                                uint32_t count);
17947b43a1fSPaolo Bonzini void qxl_spice_oom(PCIQXLDevice *qxl);
18047b43a1fSPaolo Bonzini void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
18147b43a1fSPaolo Bonzini void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
18247b43a1fSPaolo Bonzini void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
18347b43a1fSPaolo Bonzini 
18447b43a1fSPaolo Bonzini /* qxl-logger.c */
18547b43a1fSPaolo Bonzini int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
18647b43a1fSPaolo Bonzini int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
18747b43a1fSPaolo Bonzini 
18847b43a1fSPaolo Bonzini /* qxl-render.c */
18947b43a1fSPaolo Bonzini void qxl_render_resize(PCIQXLDevice *qxl);
19047b43a1fSPaolo Bonzini void qxl_render_update(PCIQXLDevice *qxl);
19147b43a1fSPaolo Bonzini int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
19247b43a1fSPaolo Bonzini void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie);
19347b43a1fSPaolo Bonzini void qxl_render_update_area_bh(void *opaque);
19447b43a1fSPaolo Bonzini 
19547b43a1fSPaolo Bonzini #endif
196