1d514b0f3Smrg/*
2d514b0f3Smrg * Copyright 2008 Red Hat, Inc.
3d514b0f3Smrg *
4d514b0f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5d514b0f3Smrg * copy of this software and associated documentation files (the "Software"),
6d514b0f3Smrg * to deal in the Software without restriction, including without limitation
7d514b0f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub
8d514b0f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom
9d514b0f3Smrg * the Software is furnished to do so, subject to the following conditions:
10d514b0f3Smrg *
11d514b0f3Smrg * The above copyright notice and this permission notice (including the next
12d514b0f3Smrg * paragraph) shall be included in all copies or substantial portions of the
13d514b0f3Smrg * Software.
14d514b0f3Smrg *
15d514b0f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16d514b0f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17d514b0f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
18d514b0f3Smrg * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19d514b0f3Smrg * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20d514b0f3Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21d514b0f3Smrg */
22d514b0f3Smrg
23d514b0f3Smrg#ifndef QXL_H
24d514b0f3Smrg#define QXL_H
25d514b0f3Smrg
26d514b0f3Smrg#include <stdint.h>
27d514b0f3Smrg
28d514b0f3Smrg#include <spice/qxl_dev.h>
29d514b0f3Smrg#ifdef XSPICE
30d514b0f3Smrg#include <spice.h>
31d514b0f3Smrg#endif
32d514b0f3Smrg
33d514b0f3Smrg#include "compiler.h"
34d514b0f3Smrg#include "xf86.h"
35d514b0f3Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
36d514b0f3Smrg#include "xf86Resources.h"
37d514b0f3Smrg#endif
38d514b0f3Smrg#include "xf86Cursor.h"
39d514b0f3Smrg#include "xf86_OSproc.h"
40d514b0f3Smrg#ifdef XV
41d514b0f3Smrg#include "xf86xv.h"
42d514b0f3Smrg#endif
43d514b0f3Smrg#include "xf86Crtc.h"
44d514b0f3Smrg#include "shadow.h"
45d514b0f3Smrg#include "micmap.h"
46d514b0f3Smrg#include "uxa/uxa.h"
47d514b0f3Smrg
48d514b0f3Smrg#include "list.h"
49d514b0f3Smrg#ifndef XSPICE
50d514b0f3Smrg#ifdef XSERVER_PCIACCESS
51d514b0f3Smrg#include "pciaccess.h"
52d514b0f3Smrg#endif
53d514b0f3Smrg#ifdef XSERVER_PLATFORM_BUS
54d514b0f3Smrg#include "xf86platformBus.h"
55d514b0f3Smrg#endif
56d514b0f3Smrg#include "fb.h"
57d514b0f3Smrg#include "vgaHW.h"
58d514b0f3Smrg#endif /* XSPICE */
59d514b0f3Smrg
60d514b0f3Smrg#include "qxl_drmmode.h"
61d514b0f3Smrg
62d514b0f3Smrg#if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 11, 99, 903, 0))
63d514b0f3Smrgtypedef struct list xorg_list_t;
64d514b0f3Smrg#define xorg_list_init              list_init
65d514b0f3Smrg#define xorg_list_add               list_add
66d514b0f3Smrg#define xorg_list_del               list_del
67d514b0f3Smrg#define xorg_list_for_each_entry    list_for_each_entry
68d514b0f3Smrg#else
69d514b0f3Smrgtypedef struct xorg_list xorg_list_t;
70d514b0f3Smrg#endif
71d514b0f3Smrg
72d514b0f3Smrgstruct xf86_platform_device;
73d514b0f3Smrg
74d514b0f3Smrg#include "compat-api.h"
75d514b0f3Smrg#define hidden _X_HIDDEN
76d514b0f3Smrg
77d514b0f3Smrg#ifdef XSPICE
78d514b0f3Smrg#define QXL_NAME		"spiceqxl"
79d514b0f3Smrg#define QXL_DRIVER_NAME		"spiceqxl"
80d514b0f3Smrg#else
81d514b0f3Smrg#define QXL_NAME		"qxl"
82d514b0f3Smrg#define QXL_DRIVER_NAME		"qxl"
83d514b0f3Smrg#endif
84d514b0f3Smrg#define PCI_VENDOR_RED_HAT	0x1b36
85d514b0f3Smrg
86d514b0f3Smrg#define PCI_CHIP_QXL_0100	0x0100
87d514b0f3Smrg#define PCI_CHIP_QXL_01FF	0x01ff
88d514b0f3Smrg
89d514b0f3Smrg#pragma pack(push,1)
90d514b0f3Smrg
91d514b0f3Smrgstruct qxl_ring_header {
92d514b0f3Smrg    uint32_t num_items;
93d514b0f3Smrg    uint32_t prod;
94d514b0f3Smrg    uint32_t notify_on_prod;
95d514b0f3Smrg    uint32_t cons;
96d514b0f3Smrg    uint32_t notify_on_cons;
97d514b0f3Smrg};
98d514b0f3Smrg
99d514b0f3Smrg#pragma pack(pop)
100d514b0f3Smrgtypedef struct surface_cache_t surface_cache_t;
101d514b0f3Smrg
102d514b0f3Smrgtypedef struct _qxl_screen_t qxl_screen_t;
103d514b0f3Smrg
104d514b0f3Smrgtypedef struct
105d514b0f3Smrg{
106d514b0f3Smrg    uint8_t	generation;
107d514b0f3Smrg    uint64_t	start_phys_addr;
108d514b0f3Smrg    uint64_t	end_phys_addr;
109d514b0f3Smrg    uint64_t	start_virt_addr;
110d514b0f3Smrg    uint64_t	end_virt_addr;
111d514b0f3Smrg    uint64_t	high_bits;
112d514b0f3Smrg} qxl_memslot_t;
113d514b0f3Smrg
114d514b0f3Smrgtypedef struct qxl_surface_t qxl_surface_t;
115d514b0f3Smrg
116d514b0f3Smrg/*
117d514b0f3Smrg * Config Options
118d514b0f3Smrg */
119d514b0f3Smrg
120d514b0f3Smrgenum {
121d514b0f3Smrg    OPTION_ENABLE_IMAGE_CACHE = 0,
122d514b0f3Smrg    OPTION_ENABLE_FALLBACK_CACHE,
123d514b0f3Smrg    OPTION_ENABLE_SURFACES,
124d514b0f3Smrg    OPTION_DEBUG_RENDER_FALLBACKS,
125d514b0f3Smrg    OPTION_NUM_HEADS,
126d514b0f3Smrg    OPTION_SPICE_DEFERRED_FPS,
127d514b0f3Smrg#ifdef XSPICE
128d514b0f3Smrg    OPTION_SPICE_PORT,
129d514b0f3Smrg    OPTION_SPICE_TLS_PORT,
130d514b0f3Smrg    OPTION_SPICE_ADDR,
131d514b0f3Smrg    OPTION_SPICE_X509_DIR,
132d514b0f3Smrg    OPTION_SPICE_SASL,
133d514b0f3Smrg    OPTION_SPICE_AGENT_MOUSE,
134d514b0f3Smrg    OPTION_SPICE_DISABLE_TICKETING,
135d514b0f3Smrg    OPTION_SPICE_PASSWORD,
136d514b0f3Smrg    OPTION_SPICE_X509_KEY_FILE,
137d514b0f3Smrg    OPTION_SPICE_STREAMING_VIDEO,
138d514b0f3Smrg    OPTION_SPICE_PLAYBACK_COMPRESSION,
139d514b0f3Smrg    OPTION_SPICE_ZLIB_GLZ_WAN_COMPRESSION,
140d514b0f3Smrg    OPTION_SPICE_JPEG_WAN_COMPRESSION,
141d514b0f3Smrg    OPTION_SPICE_IMAGE_COMPRESSION,
142d514b0f3Smrg    OPTION_SPICE_DISABLE_COPY_PASTE,
143d514b0f3Smrg    OPTION_SPICE_IPV4_ONLY,
144d514b0f3Smrg    OPTION_SPICE_IPV6_ONLY,
145d514b0f3Smrg    OPTION_SPICE_X509_CERT_FILE,
146d514b0f3Smrg    OPTION_SPICE_X509_KEY_PASSWORD,
147d514b0f3Smrg    OPTION_SPICE_TLS_CIPHERS,
148d514b0f3Smrg    OPTION_SPICE_CACERT_FILE,
149d514b0f3Smrg    OPTION_SPICE_DH_FILE,
150d514b0f3Smrg    OPTION_SPICE_EXIT_ON_DISCONNECT,
151d514b0f3Smrg    OPTION_SPICE_PLAYBACK_FIFO_DIR,
152d514b0f3Smrg    OPTION_SPICE_VDAGENT_ENABLED,
153d514b0f3Smrg    OPTION_SPICE_VDAGENT_VIRTIO_PATH,
154d514b0f3Smrg    OPTION_SPICE_VDAGENT_UINPUT_PATH,
155d514b0f3Smrg    OPTION_SPICE_VDAGENT_UID,
156d514b0f3Smrg    OPTION_SPICE_VDAGENT_GID,
157d514b0f3Smrg    OPTION_FRAME_BUFFER_SIZE,
158d514b0f3Smrg    OPTION_SURFACE_BUFFER_SIZE,
159d514b0f3Smrg    OPTION_COMMAND_BUFFER_SIZE,
160d514b0f3Smrg    OPTION_SPICE_SMARTCARD_FILE,
161d514b0f3Smrg    OPTION_SPICE_VIDEO_CODECS,
162d514b0f3Smrg#endif
163d514b0f3Smrg    OPTION_COUNT,
164d514b0f3Smrg};
165d514b0f3Smrg
166d514b0f3Smrgenum {
167d514b0f3Smrg    QXL_DEVICE_PRIMARY_UNDEFINED,
168d514b0f3Smrg    QXL_DEVICE_PRIMARY_NONE,
169d514b0f3Smrg    QXL_DEVICE_PRIMARY_CREATED,
170d514b0f3Smrg};
171d514b0f3Smrg
172d514b0f3Smrgstruct qxl_bo;
173d514b0f3Smrg/*
174d514b0f3Smrg * for relocations
175d514b0f3Smrg * dst_bo + dst_offset are the bo and offset into which the reloc is being written,
176d514b0f3Smrg * src_bo is the bo who's offset is being relocated.
177d514b0f3Smrg */
178d514b0f3Smrgstruct qxl_bo_funcs {
179d514b0f3Smrg    struct qxl_bo *(*bo_alloc)(qxl_screen_t *qxl, unsigned long size, const char *name);
180d514b0f3Smrg    struct qxl_bo *(*cmd_alloc)(qxl_screen_t *qxl, unsigned long size, const char *name);
181d514b0f3Smrg    void *(*bo_map)(struct qxl_bo *bo);
182d514b0f3Smrg    void (*bo_unmap)(struct qxl_bo *bo);
183d514b0f3Smrg    void (*bo_decref)(qxl_screen_t *qxl, struct qxl_bo *bo);
184d514b0f3Smrg    void (*bo_incref)(qxl_screen_t *qxl, struct qxl_bo *bo);
185d514b0f3Smrg    void (*bo_output_bo_reloc)(qxl_screen_t *qxl, uint32_t dst_offset,
186d514b0f3Smrg			       struct qxl_bo *dst_bo, struct qxl_bo *src_bo);
187d514b0f3Smrg    void (*write_command)(qxl_screen_t *qxl, uint32_t type, struct qxl_bo *bo);
188d514b0f3Smrg    void (*update_area)(qxl_surface_t *surf, int x1, int y1, int x2, int y2);
189d514b0f3Smrg    struct qxl_bo *(*create_primary)(qxl_screen_t *qxl, uint32_t width, uint32_t height, int32_t stride, uint32_t format);
190d514b0f3Smrg    void (*destroy_primary)(qxl_screen_t *qxl, struct qxl_bo *primary_bo);
191d514b0f3Smrg
192d514b0f3Smrg    qxl_surface_t *(*create_surface)(qxl_screen_t *qxl, int width,
193d514b0f3Smrg				     int height, int bpp);
194d514b0f3Smrg    void (*destroy_surface)(qxl_surface_t *surf);
195d514b0f3Smrg
196d514b0f3Smrg    void (*bo_output_surf_reloc)(qxl_screen_t *qxl, uint32_t dst_offset,
197d514b0f3Smrg				 struct qxl_bo *dst_bo,
198d514b0f3Smrg				 qxl_surface_t *surf);
199d514b0f3Smrg  /* surface create / destroy */
200d514b0f3Smrg};
201d514b0f3Smrg
202d514b0f3Smrgvoid qxl_ums_setup_funcs(qxl_screen_t *qxl);
203d514b0f3Smrgvoid qxl_kms_setup_funcs(qxl_screen_t *qxl);
204d514b0f3Smrg
205d514b0f3Smrg/* ums specific functions */
206d514b0f3Smrgstruct qxl_bo *qxl_ums_surf_mem_alloc(qxl_screen_t *qxl, uint32_t size);
207d514b0f3Smrgstruct qxl_bo *qxl_ums_lookup_phy_addr(qxl_screen_t *qxl, uint64_t phy_addr);
208d514b0f3Smrg
209d514b0f3Smrgtypedef struct FrameTimer FrameTimer;
210d514b0f3Smrgtypedef void (*FrameTimerFunc)(void *opaque);
211d514b0f3Smrg
212d514b0f3Smrg#ifdef XF86DRM_MODE
213d514b0f3Smrg#define MAX_RELOCS 96
214d514b0f3Smrg#include "qxl_drm.h"
215d514b0f3Smrg
216d514b0f3Smrgstruct qxl_cmd_stream {
217d514b0f3Smrg  struct qxl_bo *reloc_bo[MAX_RELOCS];
218d514b0f3Smrg  int n_reloc_bos;
219d514b0f3Smrg  struct drm_qxl_reloc relocs[MAX_RELOCS];
220d514b0f3Smrg  int n_relocs;
221d514b0f3Smrg};
222d514b0f3Smrg#endif
223d514b0f3Smrg
224d514b0f3Smrgstruct _qxl_screen_t
225d514b0f3Smrg{
226d514b0f3Smrg    /* These are the names QXL uses */
227d514b0f3Smrg    void *			ram;	/* Command RAM */
228d514b0f3Smrg    void *			ram_physical;
229d514b0f3Smrg    void *			vram;	/* Surface RAM */
230d514b0f3Smrg    void *			vram_physical;
231d514b0f3Smrg    struct QXLRom *		rom;    /* Parameter RAM */
232d514b0f3Smrg
233d514b0f3Smrg    struct qxl_ring *		command_ring;
234d514b0f3Smrg    struct qxl_ring *		cursor_ring;
235d514b0f3Smrg    struct qxl_ring *		release_ring;
236d514b0f3Smrg
237d514b0f3Smrg    Bool                        screen_resources_created;
238d514b0f3Smrg    int                         device_primary;
239d514b0f3Smrg    struct qxl_bo *             primary_bo;
240d514b0f3Smrg    int				num_modes;
241d514b0f3Smrg    struct QXLMode *		modes;
242d514b0f3Smrg    int				io_base;
243d514b0f3Smrg    void *			surface0_area;
244d514b0f3Smrg    long			surface0_size;
245d514b0f3Smrg    long			vram_size;
246d514b0f3Smrg    long			ram_size;
247d514b0f3Smrg
248d514b0f3Smrg    DisplayModePtr              x_modes;
249d514b0f3Smrg
250d514b0f3Smrg    int				virtual_x;
251d514b0f3Smrg    int				virtual_y;
252d514b0f3Smrg
253d514b0f3Smrg    /* not the same as the heads mode for #head > 1 or virtual != head size */
254d514b0f3Smrg    struct QXLMode 		primary_mode;
255d514b0f3Smrg    qxl_surface_t *		primary;
256d514b0f3Smrg
257d514b0f3Smrg    struct QXLMonitorsConfig   *monitors_config;
258d514b0f3Smrg    int                         monitors_config_size;
259d514b0f3Smrg    int                         mem_size;
260d514b0f3Smrg
261d514b0f3Smrg    int				bytes_per_pixel;
262d514b0f3Smrg
263d514b0f3Smrg    /* Commands */
264d514b0f3Smrg    struct qxl_mem *		mem;   /* Context for qxl_alloc/free */
265d514b0f3Smrg
266d514b0f3Smrg    /* Surfaces */
267d514b0f3Smrg    struct qxl_mem *		surf_mem;  /* Context for qxl_surf_alloc/free */
268d514b0f3Smrg
269d514b0f3Smrg    EntityInfoPtr		entity;
270d514b0f3Smrg
271d514b0f3Smrg    int                         num_heads;
272d514b0f3Smrg    xf86CrtcPtr *               crtcs;
273d514b0f3Smrg    xf86OutputPtr *             outputs;
274d514b0f3Smrg
275d514b0f3Smrg#ifndef XSPICE
276d514b0f3Smrg#ifdef XSERVER_LIBPCIACCESS
277d514b0f3Smrg    struct pci_device *		pci;
278d514b0f3Smrg    struct pci_io_handle *	io;
279d514b0f3Smrg#else
280d514b0f3Smrg    pciVideoPtr			pci;
281d514b0f3Smrg    PCITAG			pci_tag;
282d514b0f3Smrg#endif
283d514b0f3Smrg    struct xf86_platform_device *platform_dev;
284d514b0f3Smrg    vgaRegRec                   vgaRegs;
285d514b0f3Smrg#endif /* XSPICE */
286d514b0f3Smrg
287d514b0f3Smrg    uxa_driver_t *		uxa;
288d514b0f3Smrg
289d514b0f3Smrg    CreateScreenResourcesProcPtr create_screen_resources;
290d514b0f3Smrg    CloseScreenProcPtr		close_screen;
291d514b0f3Smrg    CreateGCProcPtr		create_gc;
292d514b0f3Smrg    CopyWindowProcPtr		copy_window;
293d514b0f3Smrg
294d514b0f3Smrg    int16_t			cur_x;
295d514b0f3Smrg    int16_t			cur_y;
296d514b0f3Smrg    int16_t			hot_x;
297d514b0f3Smrg    int16_t			hot_y;
298d514b0f3Smrg
299d514b0f3Smrg    ScrnInfoPtr			pScrn;
300d514b0f3Smrg
301d514b0f3Smrg    qxl_memslot_t *		mem_slots;
302d514b0f3Smrg    uint8_t			n_mem_slots;
303d514b0f3Smrg
304d514b0f3Smrg    uint8_t			main_mem_slot;
305d514b0f3Smrg    uint8_t			slot_id_bits;
306d514b0f3Smrg    uint8_t			slot_gen_bits;
307d514b0f3Smrg    uint64_t			va_slot_mask;
308d514b0f3Smrg
309d514b0f3Smrg    uint8_t			vram_mem_slot;
310d514b0f3Smrg
311d514b0f3Smrg    surface_cache_t *		surface_cache;
312d514b0f3Smrg
313d514b0f3Smrg    /* Evacuated surfaces are stored here during VT switches */
314d514b0f3Smrg    void *			vt_surfaces;
315d514b0f3Smrg
316d514b0f3Smrg    OptionInfoRec	options[OPTION_COUNT + 1];
317d514b0f3Smrg
318d514b0f3Smrg    int				enable_image_cache;
319d514b0f3Smrg    int				enable_fallback_cache;
320d514b0f3Smrg    int				enable_surfaces;
321d514b0f3Smrg    int                         debug_render_fallbacks;
322d514b0f3Smrg
323d514b0f3Smrg    FrameTimer *        frames_timer;
324d514b0f3Smrg
325d514b0f3Smrg#ifdef XSPICE
326d514b0f3Smrg    /* XSpice specific */
327d514b0f3Smrg    struct QXLRom		shadow_rom;    /* Parameter RAM */
328d514b0f3Smrg    SpiceServer *       spice_server;
329d514b0f3Smrg    SpiceCoreInterface *core;
330d514b0f3Smrg
331d514b0f3Smrg    QXLWorker *         worker;
332d514b0f3Smrg    int                 worker_running;
333d514b0f3Smrg    QXLInstance         display_sin;
334d514b0f3Smrg    SpicePlaybackInstance playback_sin;
335d514b0f3Smrg    /* XSpice specific, dragged from the Device */
336d514b0f3Smrg    QXLReleaseInfo     *last_release;
337d514b0f3Smrg
338d514b0f3Smrg    uint32_t           cmdflags;
339d514b0f3Smrg    uint32_t           oom_running;
340d514b0f3Smrg    uint32_t           num_free_res; /* is having a release ring effective
341d514b0f3Smrg                                        for Xspice? */
342d514b0f3Smrg    /* This is only touched from red worker thread - do not access
343d514b0f3Smrg     * from Xorg threads. */
344d514b0f3Smrg    struct guest_primary {
345d514b0f3Smrg        QXLSurfaceCreate surface;
346d514b0f3Smrg        uint32_t       commands;
347d514b0f3Smrg        uint32_t       resized;
348d514b0f3Smrg        int32_t        stride;
349d514b0f3Smrg        uint32_t       bits_pp;
350d514b0f3Smrg        uint32_t       bytes_pp;
351d514b0f3Smrg        uint8_t        *data, *flipped;
352d514b0f3Smrg    } guest_primary;
353d514b0f3Smrg
354d514b0f3Smrg    char playback_fifo_dir[PATH_MAX];
355d514b0f3Smrg    void *playback_opaque;
356d514b0f3Smrg    char smartcard_file[PATH_MAX];
357d514b0f3Smrg#endif /* XSPICE */
358d514b0f3Smrg
359d514b0f3Smrg    uint32_t deferred_fps;
360d514b0f3Smrg    xorg_list_t ums_bos;
361d514b0f3Smrg    struct qxl_bo_funcs *bo_funcs;
362d514b0f3Smrg
363d514b0f3Smrg    Bool kms_enabled;
364d514b0f3Smrg#ifdef XF86DRM_MODE
365d514b0f3Smrg    drmmode_rec drmmode;
366d514b0f3Smrg    int drm_fd;
367d514b0f3Smrg    struct qxl_cmd_stream cmds;
368d514b0f3Smrg#endif
369d514b0f3Smrg
370d514b0f3Smrg};
371d514b0f3Smrg
372d514b0f3Smrgtypedef struct qxl_output_private {
373d514b0f3Smrg    qxl_screen_t *qxl;
374d514b0f3Smrg    int           head;
375d514b0f3Smrg    xf86OutputStatus status;
376d514b0f3Smrg} qxl_output_private;
377d514b0f3Smrg
378d514b0f3Smrgtypedef struct qxl_crtc_private {
379d514b0f3Smrg    qxl_screen_t *qxl;
380d514b0f3Smrg    int           head;
381d514b0f3Smrg    xf86OutputPtr output;
382d514b0f3Smrg} qxl_crtc_private;
383d514b0f3Smrg
384d514b0f3Smrgstatic inline uint64_t
385d514b0f3Smrgphysical_address (qxl_screen_t *qxl, void *virtual, uint8_t slot_id)
386d514b0f3Smrg{
387d514b0f3Smrg    qxl_memslot_t *p_slot = &(qxl->mem_slots[slot_id]);
388d514b0f3Smrg
389d514b0f3Smrg    return p_slot->high_bits | ((unsigned long)virtual - p_slot->start_virt_addr);
390d514b0f3Smrg}
391d514b0f3Smrg
392d514b0f3Smrgstatic inline void *
393d514b0f3Smrgvirtual_address (qxl_screen_t *qxl, void *physical, uint8_t slot_id)
394d514b0f3Smrg{
395d514b0f3Smrg    qxl_memslot_t *p_slot = &(qxl->mem_slots[slot_id]);
396d514b0f3Smrg    unsigned long virt;
397d514b0f3Smrg
398d514b0f3Smrg    virt = ((unsigned long)physical) & qxl->va_slot_mask;
399d514b0f3Smrg    virt += p_slot->start_virt_addr;
400d514b0f3Smrg
401d514b0f3Smrg    return (void *)virt;
402d514b0f3Smrg}
403d514b0f3Smrg
404d514b0f3Smrgstatic inline void *
405d514b0f3Smrgu64_to_pointer (uint64_t u)
406d514b0f3Smrg{
407d514b0f3Smrg    return (void *)(unsigned long)u;
408d514b0f3Smrg}
409d514b0f3Smrg
410d514b0f3Smrgstatic inline uint64_t
411d514b0f3Smrgpointer_to_u64 (void *p)
412d514b0f3Smrg{
413d514b0f3Smrg    return (uint64_t)(unsigned long)p;
414d514b0f3Smrg}
415d514b0f3Smrg
416d514b0f3Smrgstruct qxl_ring;
417d514b0f3Smrg
418d514b0f3Smrg/*
419d514b0f3Smrg * HW cursor
420d514b0f3Smrg */
421d514b0f3Smrgvoid              qxl_cursor_init        (ScreenPtr               pScreen);
422d514b0f3Smrg
423d514b0f3Smrg
424d514b0f3Smrg
425d514b0f3Smrg/*
426d514b0f3Smrg * Rings
427d514b0f3Smrg */
428d514b0f3Smrgstruct qxl_ring * qxl_ring_create      (struct qxl_ring_header *header,
429d514b0f3Smrg					int                     element_size,
430d514b0f3Smrg					int                     n_elements,
431d514b0f3Smrg					int                     prod_notify,
432d514b0f3Smrg					qxl_screen_t            *qxl);
433d514b0f3Smrgvoid              qxl_ring_push        (struct qxl_ring        *ring,
434d514b0f3Smrg					const void             *element);
435d514b0f3SmrgBool              qxl_ring_pop         (struct qxl_ring        *ring,
436d514b0f3Smrg					void                   *element);
437d514b0f3Smrgvoid              qxl_ring_wait_idle   (struct qxl_ring        *ring);
438d514b0f3Smrg
439d514b0f3Smrgvoid              qxl_ring_request_notify (struct qxl_ring *ring);
440d514b0f3Smrg
441d514b0f3Smrgint               qxl_ring_prod        (struct qxl_ring        *ring);
442d514b0f3Smrgint               qxl_ring_cons        (struct qxl_ring        *ring);
443d514b0f3Smrg
444d514b0f3Smrg/*
445d514b0f3Smrg * Surface
446d514b0f3Smrg */
447d514b0f3Smrgsurface_cache_t *   qxl_surface_cache_create (qxl_screen_t *qxl);
448d514b0f3Smrgqxl_surface_t *	    qxl_surface_cache_create_primary (qxl_screen_t *qxl,
449d514b0f3Smrg						struct QXLMode *mode);
450d514b0f3Smrgvoid *              qxl_surface_get_host_bits(qxl_surface_t *surface);
451d514b0f3Smrgqxl_surface_t *	    qxl_surface_create (qxl_screen_t *qxl,
452d514b0f3Smrg					int	      width,
453d514b0f3Smrg					int	      height,
454d514b0f3Smrg					int	      bpp);
455d514b0f3Smrgvoid
456d514b0f3Smrgqxl_surface_cache_sanity_check (surface_cache_t *qxl);
457d514b0f3Smrgvoid *
458d514b0f3Smrgqxl_surface_cache_evacuate_all (surface_cache_t *qxl);
459d514b0f3Smrgvoid
460d514b0f3Smrgqxl_surface_cache_replace_all (surface_cache_t *qxl, void *data);
461d514b0f3Smrg
462d514b0f3Smrgvoid		    qxl_surface_set_pixmap (qxl_surface_t *surface,
463d514b0f3Smrg					    PixmapPtr      pixmap);
464d514b0f3Smrg/* Call this to indicate that the server is done with the surface */
465d514b0f3Smrgvoid		    qxl_surface_kill (qxl_surface_t *surface);
466d514b0f3Smrg/* Call this when a notification comes back from the device
467d514b0f3Smrg * that the surface has been destroyed
468d514b0f3Smrg */
469d514b0f3Smrgvoid		    qxl_surface_recycle (surface_cache_t *cache, uint32_t id);
470d514b0f3Smrg
471d514b0f3Smrg/* send anything pending to the other side */
472d514b0f3Smrgvoid		    qxl_surface_flush (qxl_surface_t *surface);
473d514b0f3Smrg
474d514b0f3Smrg/* access */
475d514b0f3SmrgBool		    qxl_surface_prepare_access (qxl_surface_t *surface,
476d514b0f3Smrg						PixmapPtr      pixmap,
477d514b0f3Smrg						RegionPtr      region,
478d514b0f3Smrg						uxa_access_t   access);
479d514b0f3Smrgvoid		    qxl_surface_finish_access (qxl_surface_t *surface,
480d514b0f3Smrg					       PixmapPtr      pixmap);
481d514b0f3Smrg
482d514b0f3Smrg/* solid */
483d514b0f3SmrgBool		    qxl_surface_prepare_solid (qxl_surface_t *destination,
484d514b0f3Smrg					       Pixel	      fg);
485d514b0f3Smrgvoid		    qxl_surface_solid         (qxl_surface_t *destination,
486d514b0f3Smrg					       int	      x1,
487d514b0f3Smrg					       int	      y1,
488d514b0f3Smrg					       int	      x2,
489d514b0f3Smrg					       int	      y2);
490d514b0f3Smrg
491d514b0f3Smrg/* copy */
492d514b0f3SmrgBool		    qxl_surface_prepare_copy (qxl_surface_t *source,
493d514b0f3Smrg					      qxl_surface_t *dest);
494d514b0f3Smrgvoid		    qxl_surface_copy	     (qxl_surface_t *dest,
495d514b0f3Smrg					      int  src_x1, int src_y1,
496d514b0f3Smrg					      int  dest_x1, int dest_y1,
497d514b0f3Smrg					      int width, int height);
498d514b0f3SmrgBool		    qxl_surface_put_image    (qxl_surface_t *dest,
499d514b0f3Smrg					      int x, int y, int width, int height,
500d514b0f3Smrg					      const char *src, int src_pitch);
501d514b0f3Smrgvoid		    qxl_surface_unref        (surface_cache_t *cache,
502d514b0f3Smrg					      uint32_t surface_id);
503d514b0f3Smrg
504d514b0f3Smrg/* composite */
505d514b0f3SmrgBool		    qxl_surface_prepare_composite (int op,
506d514b0f3Smrg						   PicturePtr	src_picture,
507d514b0f3Smrg						   PicturePtr	mask_picture,
508d514b0f3Smrg						   PicturePtr   dst_picture,
509d514b0f3Smrg						   qxl_surface_t *src,
510d514b0f3Smrg						   qxl_surface_t *mask,
511d514b0f3Smrg						   qxl_surface_t *dest);
512d514b0f3Smrgvoid		   qxl_surface_composite (qxl_surface_t *dest,
513d514b0f3Smrg					  int src_x, int src_y,
514d514b0f3Smrg					  int mask_x, int mask_y,
515d514b0f3Smrg					  int dst_x, int dst_y,
516d514b0f3Smrg					  int width, int height);
517d514b0f3Smrg
518d514b0f3Smrg/* UXA */
519d514b0f3Smrg#if HAS_DEVPRIVATEKEYREC
520d514b0f3Smrgextern DevPrivateKeyRec uxa_pixmap_index;
521d514b0f3Smrg#else
522d514b0f3Smrgextern int uxa_pixmap_index;
523d514b0f3Smrg#endif
524d514b0f3SmrgBool
525d514b0f3Smrgqxl_uxa_init (qxl_screen_t *qxl, ScreenPtr screen);
526d514b0f3Smrg
527d514b0f3Smrgstatic inline qxl_surface_t *get_surface (PixmapPtr pixmap)
528d514b0f3Smrg{
529d514b0f3Smrg#if HAS_DEVPRIVATEKEYREC
530d514b0f3Smrg    return dixGetPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
531d514b0f3Smrg#else
532d514b0f3Smrg    return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
533d514b0f3Smrg#endif
534d514b0f3Smrg}
535d514b0f3Smrg
536d514b0f3Smrgstatic inline void set_surface (PixmapPtr pixmap, qxl_surface_t *surface)
537d514b0f3Smrg{
538d514b0f3Smrg    dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, surface);
539d514b0f3Smrg}
540d514b0f3Smrg
541d514b0f3Smrgstatic inline struct QXLRam *
542d514b0f3Smrgget_ram_header (qxl_screen_t *qxl)
543d514b0f3Smrg{
544d514b0f3Smrg    return (struct QXLRam *)
545d514b0f3Smrg	((uint8_t *)qxl->ram + qxl->rom->ram_header_offset);
546d514b0f3Smrg}
547d514b0f3Smrg
548d514b0f3Smrgvoid qxl_surface_upload_primary_regions(qxl_screen_t *qxl, PixmapPtr pixmap, RegionRec *r);
549d514b0f3Smrg
550d514b0f3Smrg/* ums randr code */
551d514b0f3Smrgvoid qxl_init_randr (ScrnInfoPtr pScrn, qxl_screen_t *qxl);
552d514b0f3Smrgvoid qxl_initialize_x_modes (qxl_screen_t *qxl, ScrnInfoPtr pScrn,
553d514b0f3Smrg                        unsigned int *max_x, unsigned int *max_y);
554d514b0f3Smrgvoid qxl_update_edid (qxl_screen_t *qxl);
555d514b0f3SmrgBool qxl_create_desired_modes (qxl_screen_t *qxl);
556d514b0f3Smrg
557d514b0f3SmrgBool qxl_resize_primary (qxl_screen_t *qxl, uint32_t width, uint32_t height);
558d514b0f3Smrgvoid qxl_io_monitors_config_async (qxl_screen_t *qxl);
559d514b0f3Smrgvoid qxl_allocate_monitors_config (qxl_screen_t *qxl);
560d514b0f3Smrg/*
561d514b0f3Smrg * Images
562d514b0f3Smrg */
563d514b0f3Smrgstruct qxl_bo *qxl_image_create     (qxl_screen_t           *qxl,
564d514b0f3Smrg				       const uint8_t          *data,
565d514b0f3Smrg				       int                     x,
566d514b0f3Smrg				       int                     y,
567d514b0f3Smrg				       int                     width,
568d514b0f3Smrg				       int                     height,
569d514b0f3Smrg				       int                     stride,
570d514b0f3Smrg				       int                     Bpp,
571d514b0f3Smrg				       Bool		       fallback);
572d514b0f3Smrgvoid              qxl_image_destroy    (qxl_screen_t           *qxl,
573d514b0f3Smrg				        struct qxl_bo *bo);
574d514b0f3Smrg
575d514b0f3Smrg/*
576d514b0f3Smrg * Malloc
577d514b0f3Smrg */
578d514b0f3Smrgvoid              qxl_mem_init(void);
579d514b0f3Smrgint		  qxl_handle_oom (qxl_screen_t *qxl);
580d514b0f3Smrgstruct qxl_mem *  qxl_mem_create       (void                   *base,
581d514b0f3Smrg					unsigned long           n_bytes);
582d514b0f3Smrgvoid              qxl_mem_dump_stats   (struct qxl_mem         *mem,
583d514b0f3Smrg					const char             *header);
584d514b0f3Smrgvoid              qxl_mem_free_all     (struct qxl_mem         *mem);
585d514b0f3Smrgint		   qxl_garbage_collect (qxl_screen_t *qxl);
586d514b0f3Smrg
587d514b0f3Smrgvoid qxl_reset_and_create_mem_slots (qxl_screen_t *qxl);
588d514b0f3Smrgvoid qxl_mark_mem_unverifiable (qxl_screen_t *qxl);
589d514b0f3Smrg#ifdef DEBUG_QXL_MEM
590d514b0f3Smrgvoid qxl_mem_unverifiable(struct qxl_mem *mem);
591d514b0f3Smrg#else
592d514b0f3Smrgstatic inline void qxl_mem_unverifiable(struct qxl_mem *mem) {}
593d514b0f3Smrg#endif
594d514b0f3Smrg
595d514b0f3Smrg/*
596d514b0f3Smrg * I/O port commands
597d514b0f3Smrg */
598d514b0f3Smrgvoid qxl_update_area(qxl_screen_t *qxl);
599d514b0f3Smrgvoid qxl_io_memslot_add(qxl_screen_t *qxl, uint8_t id);
600d514b0f3Smrgvoid qxl_io_create_primary(qxl_screen_t *qxl);
601d514b0f3Smrgvoid qxl_io_destroy_primary(qxl_screen_t *qxl);
602d514b0f3Smrgvoid qxl_io_notify_oom(qxl_screen_t *qxl);
603d514b0f3Smrgvoid qxl_io_flush_surfaces(qxl_screen_t *qxl);
604d514b0f3Smrgvoid qxl_io_destroy_all_surfaces (qxl_screen_t *qxl);
605d514b0f3Smrg
606d514b0f3Smrg#ifdef QXLDRV_RESIZABLE_SURFACE0
607d514b0f3Smrgvoid qxl_io_flush_release (qxl_screen_t *qxl);
608d514b0f3Smrg#endif
609d514b0f3Smrg
610d514b0f3SmrgBool qxl_pre_init_common(ScrnInfoPtr pScrn);
611d514b0f3SmrgBool qxl_fb_init (qxl_screen_t *qxl, ScreenPtr pScreen);
612d514b0f3SmrgBool qxl_screen_init_kms(SCREEN_INIT_ARGS_DECL);
613d514b0f3SmrgBool qxl_enter_vt_kms (VT_FUNC_ARGS_DECL);
614d514b0f3Smrgvoid qxl_leave_vt_kms (VT_FUNC_ARGS_DECL);
615d514b0f3Smrgvoid qxl_set_screen_pixmap_header (ScreenPtr pScreen);
616d514b0f3SmrgBool qxl_resize_primary_to_virtual (qxl_screen_t *qxl);
617d514b0f3Smrgvoid qxl_get_formats (int bpp, SpiceSurfaceFmt *format, pixman_format_code_t *pformat);
618d514b0f3Smrg
619d514b0f3Smrg#ifdef XF86DRM_MODE
620d514b0f3SmrgBool qxl_pre_init_kms(ScrnInfoPtr pScrn, int flags);
621d514b0f3SmrgBool qxl_kms_check_cap(qxl_screen_t *qxl, int cap);
622d514b0f3Smrguint32_t qxl_kms_bo_get_handle(struct qxl_bo *_bo);
623d514b0f3Smrg#else
624d514b0f3Smrgstatic inline Bool qxl_pre_init_kms(ScrnInfoPtr pScrn, int flags) { return FALSE; }
625d514b0f3Smrgstatic inline Bool qxl_kms_check_cap(qxl_screen_t *qxl, int cap) { return FALSE; }
626d514b0f3Smrg#endif
627d514b0f3Smrg
628d514b0f3Smrg#ifdef XSPICE
629d514b0f3Smrg/* device to spice-server, now xspice to spice-server */
630d514b0f3Smrgvoid ioport_write(qxl_screen_t *qxl, uint32_t io_port, uint32_t val);
631d514b0f3Smrg#else
632d514b0f3Smrgstatic inline void ioport_write(qxl_screen_t *qxl, int port, int val)
633d514b0f3Smrg{
634d514b0f3Smrg    pci_io_write8(qxl->io, port, val);
635d514b0f3Smrg}
636d514b0f3Smrg#endif
637d514b0f3Smrg
638d514b0f3Smrg#ifdef XSPICE
639d514b0f3Smrg
640d514b0f3Smrg#define MEMSLOT_GROUP 0
641d514b0f3Smrg#define NUM_MEMSLOTS_GROUPS 1
642d514b0f3Smrg
643d514b0f3Smrg// Taken from qemu's qxl.c, not sure the values make sense? we
644d514b0f3Smrg// only have a single slot, and it is never changed after being added,
645d514b0f3Smrg// so not a problem?
646d514b0f3Smrg#define NUM_MEMSLOTS 8
647d514b0f3Smrg#define MEMSLOT_GENERATION_BITS 8
648d514b0f3Smrg#define MEMSLOT_SLOT_BITS 1
649d514b0f3Smrg
650d514b0f3Smrg// qemu/cpu-all.h
651d514b0f3Smrg#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
652d514b0f3Smrg// qemu/target-i386/cpu.h
653d514b0f3Smrg#define TARGET_PAGE_BITS 12
654d514b0f3Smrg
655d514b0f3Smrg#define NUM_SURFACES 1024
656d514b0f3Smrg
657d514b0f3Smrg/* initializes if required and returns the server singleton */
658d514b0f3SmrgSpiceServer *xspice_get_spice_server(void);
659d514b0f3Smrg
660d514b0f3Smrg#endif /* XSPICE */
661d514b0f3Smrg
662d514b0f3Smrg#ifdef WITH_CHECK_POINT
663d514b0f3Smrg#define CHECK_POINT() ErrorF ("%s: %d  (%s)\n", __FILE__, __LINE__, __FUNCTION__);
664d514b0f3Smrg#else
665d514b0f3Smrg#define CHECK_POINT()
666d514b0f3Smrg#endif
667d514b0f3Smrg
668d514b0f3Smrg
669d514b0f3Smrg#endif // QXL_H
670