| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | #include "qemu-common.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "console.h"
 | 
					
						
							|  |  |  | #include "hw.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-12 14:24:50 +02:00
										 |  |  | #include "pci/pci.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | #include "vga_int.h"
 | 
					
						
							| 
									
										
										
										
											2011-09-20 17:14:40 +02:00
										 |  |  | #include "qemu-thread.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "ui/qemu-spice.h"
 | 
					
						
							|  |  |  | #include "ui/spice-display.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum qxl_mode { | 
					
						
							|  |  |  |     QXL_MODE_UNDEFINED, | 
					
						
							|  |  |  |     QXL_MODE_VGA, | 
					
						
							|  |  |  |     QXL_MODE_COMPAT, /* spice 0.4.x */ | 
					
						
							|  |  |  |     QXL_MODE_NATIVE, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-14 18:05:48 +02:00
										 |  |  | #ifndef QXL_VRAM64_RANGE_INDEX
 | 
					
						
							|  |  |  | #define QXL_VRAM64_RANGE_INDEX 4
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-20 12:20:58 +03:00
										 |  |  | #define QXL_UNDEFINED_IO UINT32_MAX
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-24 23:19:31 +02:00
										 |  |  | #define QXL_NUM_DIRTY_RECTS 64
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | typedef struct PCIQXLDevice { | 
					
						
							|  |  |  |     PCIDevice          pci; | 
					
						
							|  |  |  |     SimpleSpiceDisplay ssd; | 
					
						
							|  |  |  |     int                id; | 
					
						
							|  |  |  |     uint32_t           debug; | 
					
						
							|  |  |  |     uint32_t           guestdebug; | 
					
						
							|  |  |  |     uint32_t           cmdlog; | 
					
						
							| 
									
										
										
										
											2012-05-24 19:18:54 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     uint32_t           guest_bug; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  |     enum qxl_mode      mode; | 
					
						
							|  |  |  |     uint32_t           cmdflags; | 
					
						
							|  |  |  |     int                generation; | 
					
						
							|  |  |  |     uint32_t           revision; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int32_t            num_memslots; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-20 12:20:58 +03:00
										 |  |  |     uint32_t           current_async; | 
					
						
							|  |  |  |     QemuMutex          async_lock; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  |     struct guest_slots { | 
					
						
							|  |  |  |         QXLMemSlot     slot; | 
					
						
							|  |  |  |         void           *ptr; | 
					
						
							|  |  |  |         uint64_t       size; | 
					
						
							|  |  |  |         uint64_t       delta; | 
					
						
							|  |  |  |         uint32_t       active; | 
					
						
							|  |  |  |     } guest_slots[NUM_MEMSLOTS]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct guest_primary { | 
					
						
							|  |  |  |         QXLSurfaceCreate surface; | 
					
						
							|  |  |  |         uint32_t       commands; | 
					
						
							|  |  |  |         uint32_t       resized; | 
					
						
							| 
									
										
										
										
											2011-10-21 15:59:07 +02:00
										 |  |  |         int32_t        qxl_stride; | 
					
						
							|  |  |  |         uint32_t       abs_stride; | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  |         uint32_t       bits_pp; | 
					
						
							|  |  |  |         uint32_t       bytes_pp; | 
					
						
							| 
									
										
										
										
											2012-02-24 23:19:29 +02:00
										 |  |  |         uint8_t        *data; | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  |     } guest_primary; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct surfaces { | 
					
						
							| 
									
										
										
										
											2012-09-04 11:39:41 +02:00
										 |  |  |         QXLPHYSICAL    *cmds; | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  |         uint32_t       count; | 
					
						
							|  |  |  |         uint32_t       max; | 
					
						
							|  |  |  |     } guest_surfaces; | 
					
						
							|  |  |  |     QXLPHYSICAL        guest_cursor; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-22 11:16:25 +03:00
										 |  |  |     QXLPHYSICAL        guest_monitors_config; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-20 12:20:53 +03:00
										 |  |  |     QemuMutex          track_lock; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  |     /* thread signaling */ | 
					
						
							| 
									
										
										
										
											2011-09-20 17:14:40 +02:00
										 |  |  |     QemuThread         main; | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  |     int                pipe[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* ram pci bar */ | 
					
						
							|  |  |  |     QXLRam             *ram; | 
					
						
							|  |  |  |     VGACommonState     vga; | 
					
						
							|  |  |  |     uint32_t           num_free_res; | 
					
						
							|  |  |  |     QXLReleaseInfo     *last_release; | 
					
						
							|  |  |  |     uint32_t           last_release_offset; | 
					
						
							|  |  |  |     uint32_t           oom_running; | 
					
						
							| 
									
										
										
										
											2012-06-10 18:05:06 +03:00
										 |  |  |     uint32_t           vgamem_size; | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* rom pci bar */ | 
					
						
							|  |  |  |     QXLRom             shadow_rom; | 
					
						
							|  |  |  |     QXLRom             *rom; | 
					
						
							|  |  |  |     QXLModes           *modes; | 
					
						
							|  |  |  |     uint32_t           rom_size; | 
					
						
							| 
									
										
										
										
											2011-08-08 16:08:57 +03:00
										 |  |  |     MemoryRegion       rom_bar; | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* vram pci bar */ | 
					
						
							|  |  |  |     uint32_t           vram_size; | 
					
						
							| 
									
										
										
										
											2011-08-08 16:08:57 +03:00
										 |  |  |     MemoryRegion       vram_bar; | 
					
						
							| 
									
										
										
										
											2011-10-14 18:05:48 +02:00
										 |  |  |     uint32_t           vram32_size; | 
					
						
							|  |  |  |     MemoryRegion       vram32_bar; | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* io bar */ | 
					
						
							| 
									
										
										
										
											2011-08-08 16:08:57 +03:00
										 |  |  |     MemoryRegion       io_bar; | 
					
						
							| 
									
										
										
										
											2012-02-17 15:03:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* user-friendly properties (in megabytes) */ | 
					
						
							|  |  |  |     uint32_t          ram_size_mb; | 
					
						
							|  |  |  |     uint32_t          vram_size_mb; | 
					
						
							| 
									
										
										
										
											2011-10-14 18:05:48 +02:00
										 |  |  |     uint32_t          vram32_size_mb; | 
					
						
							| 
									
										
										
										
											2012-06-10 18:05:06 +03:00
										 |  |  |     uint32_t          vgamem_size_mb; | 
					
						
							| 
									
										
										
										
											2012-02-24 23:19:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* qxl_render_update state */ | 
					
						
							|  |  |  |     int                render_update_cookie_num; | 
					
						
							|  |  |  |     int                num_dirty_rects; | 
					
						
							|  |  |  |     QXLRect            dirty[QXL_NUM_DIRTY_RECTS]; | 
					
						
							|  |  |  |     QEMUBH            *update_area_bh; | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | } PCIQXLDevice; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PANIC_ON(x) if ((x)) {                         \
 | 
					
						
							|  |  |  |     printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \ | 
					
						
							| 
									
										
										
										
											2011-07-20 12:20:55 +03:00
										 |  |  |     abort();                                           \ | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define dprint(_qxl, _level, _fmt, ...)                                 \
 | 
					
						
							|  |  |  |     do {                                                                \ | 
					
						
							|  |  |  |         if (_qxl->debug >= _level) {                                    \ | 
					
						
							|  |  |  |             fprintf(stderr, "qxl-%d: ", _qxl->id);                      \ | 
					
						
							|  |  |  |             fprintf(stderr, _fmt, ## __VA_ARGS__);                      \ | 
					
						
							|  |  |  |         }                                                               \ | 
					
						
							|  |  |  |     } while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-22 11:16:25 +03:00
										 |  |  | #define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V12
 | 
					
						
							| 
									
										
										
										
											2011-07-20 12:21:00 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | /* qxl.c */ | 
					
						
							|  |  |  | void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); | 
					
						
							| 
									
										
										
										
											2012-05-24 12:38:12 +03:00
										 |  |  | void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...) | 
					
						
							|  |  |  |     GCC_FMT_ATTR(2, 3); | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-20 12:20:52 +03:00
										 |  |  | void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, | 
					
						
							|  |  |  |                            struct QXLRect *area, struct QXLRect *dirty_rects, | 
					
						
							|  |  |  |                            uint32_t num_dirty_rects, | 
					
						
							| 
									
										
										
										
											2011-07-20 12:20:58 +03:00
										 |  |  |                            uint32_t clear_dirty_region, | 
					
						
							| 
									
										
										
										
											2012-02-24 23:19:30 +02:00
										 |  |  |                            qxl_async_io async, QXLCookie *cookie); | 
					
						
							| 
									
										
										
										
											2011-07-20 12:20:52 +03:00
										 |  |  | void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, | 
					
						
							|  |  |  |                                uint32_t count); | 
					
						
							|  |  |  | void qxl_spice_oom(PCIQXLDevice *qxl); | 
					
						
							|  |  |  | void qxl_spice_reset_memslots(PCIQXLDevice *qxl); | 
					
						
							|  |  |  | void qxl_spice_reset_image_cache(PCIQXLDevice *qxl); | 
					
						
							|  |  |  | void qxl_spice_reset_cursor(PCIQXLDevice *qxl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | /* qxl-logger.c */ | 
					
						
							| 
									
										
										
										
											2012-04-25 12:13:18 +03:00
										 |  |  | int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id); | 
					
						
							|  |  |  | int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext); | 
					
						
							| 
									
										
										
										
											2010-04-27 11:50:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* qxl-render.c */ | 
					
						
							|  |  |  | void qxl_render_resize(PCIQXLDevice *qxl); | 
					
						
							|  |  |  | void qxl_render_update(PCIQXLDevice *qxl); | 
					
						
							| 
									
										
										
										
											2012-04-25 12:13:18 +03:00
										 |  |  | int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext); | 
					
						
							| 
									
										
										
										
											2012-02-24 23:19:31 +02:00
										 |  |  | void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie); | 
					
						
							|  |  |  | void qxl_render_update_area_bh(void *opaque); |