1/* 2 * Copyright 2008 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23/** \file qxl_driver.c 24 * \author Adam Jackson <ajax@redhat.com> 25 * \author Søren Sandmann <sandmann@redhat.com> 26 * 27 * This is qxl, a driver for the Qumranet paravirtualized graphics device 28 * in qemu. 29 */ 30 31#ifdef HAVE_CONFIG_H 32#include "config.h" 33#endif 34 35#include <unistd.h> 36#include <string.h> 37#include <stdio.h> 38#include <errno.h> 39#include <time.h> 40#include <stdlib.h> 41 42#include <xf86Crtc.h> 43#include <xf86RandR12.h> 44 45#include "qxl.h" 46#include "assert.h" 47#include "qxl_option_helpers.h" 48#include <spice/protocol.h> 49 50#ifdef XSPICE 51#include "spiceqxl_driver.h" 52#include "spiceqxl_main_loop.h" 53#include "spiceqxl_display.h" 54#include "spiceqxl_inputs.h" 55#include "spiceqxl_io_port.h" 56#include "spiceqxl_spice_server.h" 57#include "spiceqxl_audio.h" 58#include "spiceqxl_smartcard.h" 59#include "spiceqxl_vdagent.h" 60#endif /* XSPICE */ 61 62#include "dfps.h" 63 64extern void compat_init_scrn (ScrnInfoPtr); 65 66#define BREAKPOINT() do { __asm__ __volatile__ ("int $03"); } while (0) 67 68#ifdef XSPICE 69static char filter_str[] = "filter"; 70static char auto_str[] = "auto"; 71static char auto_glz_str[] = "auto_glz"; 72static char spice_vdagent_virtio_path_default[] = "/tmp/xspice-virtio"; 73static char spice_vdagent_uinput_path_default[] = "/tmp/xspice-uinput"; 74#endif 75static char driver_name[] = QXL_DRIVER_NAME; 76static const OptionInfoRec DefaultOptions[] = 77{ 78 { OPTION_ENABLE_IMAGE_CACHE, 79 "EnableImageCache", OPTV_BOOLEAN, { 1 }, FALSE }, 80 { OPTION_ENABLE_FALLBACK_CACHE, 81 "EnableFallbackCache", OPTV_BOOLEAN, { 1 }, FALSE }, 82 { OPTION_ENABLE_SURFACES, 83 "EnableSurfaces", OPTV_BOOLEAN, { 1 }, FALSE }, 84 { OPTION_DEBUG_RENDER_FALLBACKS, 85 "DebugRenderFallbacks", OPTV_BOOLEAN, { 0 }, FALSE }, 86 { OPTION_NUM_HEADS, 87 "NumHeads", OPTV_INTEGER, { 4 }, FALSE }, 88 { OPTION_SPICE_DEFERRED_FPS, 89 "SpiceDeferredFPS", OPTV_INTEGER, { 0 }, FALSE}, 90#ifdef XSPICE 91 { OPTION_SPICE_PORT, 92 "SpicePort", OPTV_INTEGER, {5900}, FALSE }, 93 { OPTION_SPICE_TLS_PORT, 94 "SpiceTlsPort", OPTV_INTEGER, {0}, FALSE}, 95 { OPTION_SPICE_ADDR, 96 "SpiceAddr", OPTV_STRING, {0}, FALSE}, 97 { OPTION_SPICE_X509_DIR, 98 "SpiceX509Dir", OPTV_STRING, {0}, FALSE}, 99 { OPTION_SPICE_SASL, 100 "SpiceSasl", OPTV_BOOLEAN, {0}, FALSE}, 101 { OPTION_SPICE_AGENT_MOUSE, 102 "SpiceAgentMouse", OPTV_BOOLEAN, {0}, TRUE }, 103 { OPTION_SPICE_DISABLE_TICKETING, 104 "SpiceDisableTicketing", OPTV_BOOLEAN, {0}, FALSE}, 105 { OPTION_SPICE_PASSWORD, 106 "SpicePassword", OPTV_STRING, {0}, FALSE}, 107 { OPTION_SPICE_X509_KEY_FILE, 108 "SpiceX509KeyFile", OPTV_STRING, {0}, FALSE}, 109 { OPTION_SPICE_STREAMING_VIDEO, 110 "SpiceStreamingVideo", OPTV_STRING, {.str = filter_str}, FALSE}, 111 { OPTION_SPICE_PLAYBACK_COMPRESSION, 112 "SpicePlaybackCompression", OPTV_BOOLEAN, {1}, FALSE}, 113 { OPTION_SPICE_ZLIB_GLZ_WAN_COMPRESSION, 114 "SpiceZlibGlzWanCompression", OPTV_STRING, {.str = auto_str}, FALSE}, 115 { OPTION_SPICE_JPEG_WAN_COMPRESSION, 116 "SpiceJpegWanCompression", OPTV_STRING, {.str = auto_str}, FALSE}, 117 { OPTION_SPICE_IMAGE_COMPRESSION, 118 "SpiceImageCompression", OPTV_STRING, {.str = auto_glz_str}, FALSE}, 119 { OPTION_SPICE_DISABLE_COPY_PASTE, 120 "SpiceDisableCopyPaste", OPTV_BOOLEAN, {0}, FALSE}, 121 { OPTION_SPICE_IPV4_ONLY, 122 "SpiceIPV4Only", OPTV_BOOLEAN, {0}, FALSE}, 123 { OPTION_SPICE_IPV6_ONLY, 124 "SpiceIPV6Only", OPTV_BOOLEAN, {0}, FALSE}, 125 { OPTION_SPICE_X509_CERT_FILE, 126 "SpiceX509CertFile", OPTV_STRING, {0}, FALSE}, 127 { OPTION_SPICE_X509_KEY_PASSWORD, 128 "SpiceX509KeyPassword", OPTV_STRING, {0}, FALSE}, 129 { OPTION_SPICE_TLS_CIPHERS, 130 "SpiceTlsCiphers", OPTV_STRING, {0}, FALSE}, 131 { OPTION_SPICE_CACERT_FILE, 132 "SpiceCacertFile", OPTV_STRING, {0}, FALSE}, 133 { OPTION_SPICE_DH_FILE, 134 "SpiceDhFile", OPTV_STRING, {0}, FALSE}, 135 { OPTION_SPICE_EXIT_ON_DISCONNECT, 136 "SpiceExitOnDisconnect", OPTV_BOOLEAN, {0}, FALSE}, 137 { OPTION_SPICE_PLAYBACK_FIFO_DIR, 138 "SpicePlaybackFIFODir", OPTV_STRING, {0}, FALSE}, 139 { OPTION_SPICE_VDAGENT_ENABLED, 140 "SpiceVdagentEnabled", OPTV_BOOLEAN, {0}, FALSE}, 141 { OPTION_SPICE_VDAGENT_VIRTIO_PATH, 142 "SpiceVdagentVirtioPath", OPTV_STRING, {.str = spice_vdagent_virtio_path_default}, FALSE}, 143 { OPTION_SPICE_VDAGENT_UINPUT_PATH, 144 "SpiceVdagentUinputPath", OPTV_STRING, {.str = spice_vdagent_uinput_path_default}, FALSE}, 145 { OPTION_SPICE_VDAGENT_UID, 146 "SpiceVdagentUid", OPTV_INTEGER, {0}, FALSE}, 147 { OPTION_SPICE_VDAGENT_GID, 148 "SpiceVdagentGid", OPTV_INTEGER, {0}, FALSE}, 149 { OPTION_FRAME_BUFFER_SIZE, 150 "FrameBufferSize", OPTV_INTEGER, {DEFAULT_FRAME_BUFFER_SIZE}, FALSE}, 151 { OPTION_SURFACE_BUFFER_SIZE, 152 "SurfaceBufferSize", OPTV_INTEGER, {DEFAULT_SURFACE_BUFFER_SIZE}, FALSE}, 153 { OPTION_COMMAND_BUFFER_SIZE, 154 "CommandBufferSize", OPTV_INTEGER, {DEFAULT_COMMAND_BUFFER_SIZE}, FALSE}, 155 { OPTION_SPICE_SMARTCARD_FILE, 156 "SpiceSmartcardFile", OPTV_STRING, {0}, FALSE}, 157 { OPTION_SPICE_VIDEO_CODECS, 158 "SpiceVideoCodecs", OPTV_STRING, {0}, FALSE}, 159#endif 160 161 { -1, NULL, OPTV_NONE, {0}, FALSE } 162}; 163 164static const OptionInfoRec * 165qxl_available_options (int chipid, int busid) 166{ 167 return DefaultOptions; 168} 169 170/* Having a single monitors config struct allocated on the device avoids any 171 * possible fragmentation. Since X is single threaded there is no danger 172 * in us changing it between issuing the io and getting the interrupt to signal 173 * spice-server is done reading it. 174 */ 175#define MAX_MONITORS_NUM 16 176 177void 178qxl_allocate_monitors_config (qxl_screen_t *qxl) 179{ 180 qxl->monitors_config = (QXLMonitorsConfig *)(void *) 181 ((unsigned long)qxl->ram + qxl->rom->ram_header_offset - qxl->monitors_config_size); 182} 183 184static Bool 185qxl_blank_screen (ScreenPtr pScreen, int mode) 186{ 187 return TRUE; 188} 189 190#ifdef XSPICE 191static void 192unmap_memory_helper (qxl_screen_t *qxl) 193{ 194 free (qxl->ram); 195 free (qxl->vram); 196 free (qxl->rom); 197} 198 199static void 200map_memory_helper (qxl_screen_t *qxl) 201{ 202 qxl->ram = calloc (qxl->ram_size, 1); 203 qxl->ram_physical = qxl->ram; 204 qxl->vram = calloc (qxl->vram_size, 1); 205 qxl->vram_physical = qxl->vram; 206 qxl->rom = calloc (ROM_SIZE, 1); 207 208 init_qxl_rom (qxl, ROM_SIZE); 209} 210 211#else /* Default */ 212 213static void 214unmap_memory_helper (qxl_screen_t *qxl) 215{ 216#ifdef XSERVER_LIBPCIACCESS 217 if (qxl->ram) 218 pci_device_unmap_range (qxl->pci, qxl->ram, qxl->pci->regions[0].size); 219 if (qxl->vram) 220 pci_device_unmap_range (qxl->pci, qxl->vram, qxl->pci->regions[1].size); 221 if (qxl->rom) 222 pci_device_unmap_range (qxl->pci, qxl->rom, qxl->pci->regions[2].size); 223 if (qxl->io) 224 pci_device_close_io (qxl->pci, qxl->io); 225#else 226 if (qxl->ram) 227 xf86UnMapVidMem (scrnIndex, qxl->ram, (1 << qxl->pci->size[0])); 228 if (qxl->vram) 229 xf86UnMapVidMem (scrnIndex, qxl->vram, (1 << qxl->pci->size[1])); 230 if (qxl->rom) 231 xf86UnMapVidMem (scrnIndex, qxl->rom, (1 << qxl->pci->size[2])); 232#endif 233} 234 235static void 236map_memory_helper (qxl_screen_t *qxl) 237{ 238#ifdef XSERVER_LIBPCIACCESS 239 pci_device_map_range (qxl->pci, qxl->pci->regions[0].base_addr, 240 qxl->pci->regions[0].size, 241 PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE, 242 &qxl->ram); 243 qxl->ram_physical = u64_to_pointer (qxl->pci->regions[0].base_addr); 244 qxl->ram_size = qxl->pci->regions[0].size; 245 246 pci_device_map_range (qxl->pci, qxl->pci->regions[1].base_addr, 247 qxl->pci->regions[1].size, 248 PCI_DEV_MAP_FLAG_WRITABLE, 249 &qxl->vram); 250 qxl->vram_physical = u64_to_pointer (qxl->pci->regions[1].base_addr); 251 qxl->vram_size = qxl->pci->regions[1].size; 252 253 pci_device_map_range (qxl->pci, qxl->pci->regions[2].base_addr, 254 qxl->pci->regions[2].size, 0, 255 (void **)&qxl->rom); 256 257 qxl->io = pci_device_open_io(qxl->pci, 258 qxl->pci->regions[3].base_addr, 259 qxl->pci->regions[3].size); 260 qxl->io_base = qxl->pci->regions[3].base_addr; 261#else 262 qxl->ram = xf86MapPciMem (scrnIndex, VIDMEM_FRAMEBUFFER, 263 qxl->pci_tag, qxl->pci->memBase[0], 264 (1 << qxl->pci->size[0])); 265 qxl->ram_physical = (void *)qxl->pci->memBase[0]; 266 267 qxl->vram = xf86MapPciMem (scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT, 268 qxl->pci_tag, qxl->pci->memBase[1], 269 (1 << qxl->pci->size[1])); 270 qxl->vram_physical = (void *)qxl->pci->memBase[1]; 271 qxl->vram_size = (1 << qxl->pci->size[1]); 272 273 qxl->rom = xf86MapPciMem (scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT, 274 qxl->pci_tag, qxl->pci->memBase[2], 275 (1 << qxl->pci->size[2])); 276 277 qxl->io_base = qxl->pci->ioBase[3]; 278#endif 279} 280 281#endif /* XSPICE */ 282 283static void 284qxl_unmap_memory (qxl_screen_t *qxl) 285{ 286#ifdef XSPICE 287 if (qxl->worker) 288 { 289 spice_server_vm_stop(qxl->spice_server); 290 qxl->worker_running = FALSE; 291 } 292#endif 293 294 if (qxl->mem) 295 { 296 qxl_mem_free_all (qxl->mem); 297 free(qxl->mem); 298 qxl->mem = NULL; 299 } 300 301 if (qxl->surf_mem) { 302 qxl_mem_free_all (qxl->surf_mem); 303 free(qxl->surf_mem); 304 qxl->surf_mem = NULL; 305 } 306 307 unmap_memory_helper (qxl); 308 qxl->ram = qxl->ram_physical = qxl->vram = qxl->rom = NULL; 309 310 qxl->num_modes = 0; 311 qxl->modes = NULL; 312} 313 314#ifdef QXLDRV_RESIZABLE_SURFACE0 315static void 316qxl_dump_ring_stat (qxl_screen_t *qxl) 317{ 318 int cmd_prod, cursor_prod, cmd_cons, cursor_cons; 319 int release_prod, release_cons; 320 321 cmd_prod = qxl_ring_prod (qxl->command_ring); 322 cursor_prod = qxl_ring_prod (qxl->cursor_ring); 323 cmd_cons = qxl_ring_cons (qxl->command_ring); 324 cursor_cons = qxl_ring_cons (qxl->cursor_ring); 325 release_prod = qxl_ring_prod (qxl->release_ring); 326 release_cons = qxl_ring_cons (qxl->release_ring); 327 328 ErrorF ("%s: Cmd %d/%d, Cur %d/%d, Rel %d/%d\n", 329 __func__, cmd_cons, cmd_prod, cursor_cons, cursor_prod, 330 release_cons, release_prod); 331} 332 333#endif 334 335/* To resize surface0 we need to ensure qxl->mem is empty. We can do that by: 336 * - fast: 337 * - ooming until command ring is empty. 338 * - flushing the release ring (>V10) 339 * - slow: calling update_area on all surfaces. 340 * This is done via already known code, so use that by default now. 341 */ 342static int 343qxl_resize_surface0 (qxl_screen_t *qxl, long surface0_size) 344{ 345 long ram_header_size = qxl->ram_size - qxl->rom->ram_header_offset; 346 long new_mem_size = qxl->ram_size - 347 (surface0_size + ram_header_size + qxl->monitors_config_size); 348 349 if (new_mem_size < 0) 350 { 351 ErrorF ("cannot resize surface0 to %ld, does not fit in BAR 0\n", 352 surface0_size); 353 return 0; 354 } 355 356 ErrorF ("resizing surface0 to %ld\n", surface0_size); 357 358 if (qxl->mem) 359 { 360#ifdef QXLDRV_RESIZABLE_SURFACE0 361 void *surfaces; 362 qxl_dump_ring_stat (qxl); 363 qxl_io_flush_surfaces (qxl); 364 surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache); 365 qxl_io_destroy_all_surfaces (qxl); // redundant? 366 qxl_io_flush_release (qxl); 367 qxl_dump_ring_stat (qxl); 368 qxl_surface_cache_replace_all (qxl->surface_cache, surfaces); 369#else 370 ErrorF ("resizing surface0 compiled out\n"); 371 return 0; 372#endif 373 } 374 375 /* surface0_area is still fixed to start of ram BAR */ 376 qxl->surface0_size = surface0_size; 377 378 qxl->mem_size = new_mem_size; 379 qxl->mem = qxl_mem_create ((void *)((unsigned long)qxl->surface0_area + qxl->surface0_size), 380 qxl->mem_size); 381 return 1; 382} 383 384static Bool 385qxl_map_memory (qxl_screen_t *qxl, int scrnIndex) 386{ 387 map_memory_helper (qxl); 388 389 if (!qxl->ram || !qxl->vram || !qxl->rom) 390 return FALSE; 391 392 xf86DrvMsg (scrnIndex, X_INFO, "framebuffer at %p (%d KB)\n", 393 qxl->ram, qxl->rom->surface0_area_size / 1024); 394 395 xf86DrvMsg (scrnIndex, X_INFO, "command ram at %p (%d KB)\n", 396 (void *)((unsigned long)qxl->ram + qxl->rom->surface0_area_size), 397 (qxl->rom->num_pages * getpagesize ()) / 1024); 398 399 xf86DrvMsg (scrnIndex, X_INFO, "vram at %p (%ld KB)\n", 400 qxl->vram, qxl->vram_size / 1024); 401 402 xf86DrvMsg (scrnIndex, X_INFO, "rom at %p\n", qxl->rom); 403 404 /* 405 * Keep a hole for MonitorsConfig. This is not part of QXLRam to ensure 406 * the driver can change it without affecting the driver/device ABI. 407 */ 408 qxl->monitors_config_size = (sizeof (QXLMonitorsConfig) + 409 sizeof (QXLHead) * MAX_MONITORS_NUM + getpagesize () - 1) 410 & ~(getpagesize () - 1); 411 qxl->num_modes = *(uint32_t *)((uint8_t *)qxl->rom + qxl->rom->modes_offset); 412 qxl->modes = (struct QXLMode *)(((uint8_t *)qxl->rom) + qxl->rom->modes_offset + 4); 413 qxl->surface0_area = qxl->ram; 414 qxl->surface0_size = 0; 415 qxl->mem = NULL; 416 if (!qxl_resize_surface0 (qxl, qxl->rom->surface0_area_size)) 417 return FALSE; 418 qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram), qxl->vram_size); 419 qxl_allocate_monitors_config (qxl); 420 421 return TRUE; 422} 423 424#ifdef XSPICE 425static void 426qxl_save_state (ScrnInfoPtr pScrn) 427{ 428} 429 430static void 431qxl_restore_state (ScrnInfoPtr pScrn) 432{ 433} 434 435#else /* QXL */ 436static void 437qxl_save_state (ScrnInfoPtr pScrn) 438{ 439 qxl_screen_t *qxl = pScrn->driverPrivate; 440 441 if (xf86IsPrimaryPci (qxl->pci)) 442 vgaHWSaveFonts (pScrn, &qxl->vgaRegs); 443} 444 445static void 446qxl_restore_state (ScrnInfoPtr pScrn) 447{ 448 qxl_screen_t *qxl = pScrn->driverPrivate; 449 450 if (xf86IsPrimaryPci (qxl->pci)) 451 vgaHWRestoreFonts (pScrn, &qxl->vgaRegs); 452} 453 454#endif /* XSPICE */ 455 456static Bool 457qxl_close_screen (CLOSE_SCREEN_ARGS_DECL) 458{ 459 ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen); 460 qxl_screen_t *qxl = pScrn->driverPrivate; 461 Bool result; 462 463 ErrorF ("Disabling FB access for %d\n", pScrn->scrnIndex); 464#ifndef XF86_SCRN_INTERFACE 465 pScrn->EnableDisableFBAccess (scrnIndex, FALSE); 466#else 467 pScrn->EnableDisableFBAccess (pScrn, FALSE); 468#endif 469 470 pScreen->CreateScreenResources = qxl->create_screen_resources; 471 pScreen->CloseScreen = qxl->close_screen; 472 473 result = pScreen->CloseScreen (CLOSE_SCREEN_ARGS); 474 475#ifndef XSPICE 476 if (!xf86IsPrimaryPci (qxl->pci) && qxl->primary) 477 qxl_reset_and_create_mem_slots (qxl); 478#endif 479 480 if (pScrn->vtSema) 481 { 482 qxl_restore_state (pScrn); 483 qxl_mark_mem_unverifiable (qxl); 484 qxl_unmap_memory (qxl); 485 } 486 pScrn->vtSema = FALSE; 487 488 return result; 489} 490 491void 492qxl_set_screen_pixmap_header (ScreenPtr pScreen) 493{ 494 ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen); 495 qxl_screen_t *qxl = pScrn->driverPrivate; 496 PixmapPtr pPixmap = pScreen->GetScreenPixmap (pScreen); 497 498 // TODO: don't ModifyPixmapHeader too early? 499 500 if (pPixmap) 501 { 502 pScreen->ModifyPixmapHeader (pPixmap, 503 qxl->primary_mode.x_res, qxl->primary_mode.y_res, 504 -1, -1, 505 qxl->primary_mode.x_res * qxl->bytes_per_pixel, 506 qxl_surface_get_host_bits(qxl->primary)); 507 } 508 else 509 { 510 ErrorF ("pix: %p;\n", pPixmap); 511 } 512} 513 514static qxl_surface_t * 515qxl_create_primary(qxl_screen_t *qxl) 516{ 517 struct QXLMode *pm = &qxl->primary_mode; 518 pm->id = 0x4242; 519 pm->x_res = qxl->virtual_x; 520 pm->y_res = qxl->virtual_y; 521 pm->bits = qxl->pScrn->bitsPerPixel; 522 pm->stride = qxl->virtual_x * pm->bits / 8; 523 pm->x_mili = 0; // TODO 524 pm->y_mili = 0; // TODO 525 pm->orientation = 0; // ? supported by us for single head usage? more TODO 526 527 return qxl_surface_cache_create_primary (qxl, &qxl->primary_mode); 528} 529 530Bool 531qxl_resize_primary_to_virtual (qxl_screen_t *qxl) 532{ 533 long new_surface0_size; 534 535 if ((qxl->primary_mode.x_res == qxl->virtual_x && 536 qxl->primary_mode.y_res == qxl->virtual_y) && 537 qxl->device_primary == QXL_DEVICE_PRIMARY_CREATED) 538 { 539 return TRUE; /* empty Success */ 540 } 541 542 ErrorF ("resizing primary to %dx%d\n", qxl->virtual_x, qxl->virtual_y); 543 544 if (!qxl->kms_enabled) { 545 new_surface0_size = 546 qxl->virtual_x * qxl->pScrn->bitsPerPixel / 8 * qxl->virtual_y; 547 548 if (new_surface0_size > qxl->surface0_size) 549 { 550 if (!qxl_resize_surface0 (qxl, new_surface0_size)) 551 { 552 ErrorF ("not resizing primary to virtual, leaving old virtual\n"); 553 return FALSE; 554 } 555 } 556 } 557 558 if (qxl->primary) 559 { 560 qxl_surface_kill (qxl->primary); 561 qxl_surface_cache_sanity_check (qxl->surface_cache); 562 qxl->bo_funcs->destroy_primary(qxl, qxl->primary_bo); 563 } 564 565 qxl->primary = qxl_create_primary(qxl); 566 qxl->bytes_per_pixel = (qxl->pScrn->bitsPerPixel + 7) / 8; 567 568 if (qxl->screen_resources_created) 569 { 570 ScreenPtr pScreen = qxl->pScrn->pScreen; 571 PixmapPtr root = pScreen->GetScreenPixmap (pScreen); 572 573 if (qxl->deferred_fps <= 0) 574 { 575 qxl_surface_t *surf; 576 577 if ((surf = get_surface (root))) 578 qxl_surface_kill (surf); 579 580 set_surface (root, qxl->primary); 581 } 582 583 qxl_set_screen_pixmap_header (pScreen); 584 } 585 586 ErrorF ("primary is %p\n", qxl->primary); 587 return TRUE; 588} 589 590Bool 591qxl_resize_primary (qxl_screen_t *qxl, uint32_t width, uint32_t height) 592{ 593 qxl->virtual_x = width; 594 qxl->virtual_y = height; 595 596 if (qxl->vt_surfaces) 597 { 598 ErrorF ("%s: ignoring resize due to not being in control of VT\n", 599 __FUNCTION__); 600 return FALSE; 601 } 602 return qxl_resize_primary_to_virtual (qxl); 603} 604 605static Bool 606qxl_switch_mode (SWITCH_MODE_ARGS_DECL) 607{ 608 SCRN_INFO_PTR (arg); 609 qxl_screen_t *qxl = pScrn->driverPrivate; 610 611 ErrorF ("Ignoring display mode, ensuring recreation of primary\n"); 612 613 return qxl_resize_primary_to_virtual (qxl); 614} 615 616static Bool 617qxl_create_screen_resources (ScreenPtr pScreen) 618{ 619 ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen); 620 qxl_screen_t * qxl = pScrn->driverPrivate; 621 Bool ret; 622 PixmapPtr pPixmap; 623 qxl_surface_t *surf; 624 625 pScreen->CreateScreenResources = qxl->create_screen_resources; 626 ret = pScreen->CreateScreenResources (pScreen); 627 pScreen->CreateScreenResources = qxl_create_screen_resources; 628 629 if (!ret) 630 return FALSE; 631 632 pPixmap = pScreen->GetScreenPixmap (pScreen); 633 634 if (qxl->deferred_fps <= 0) 635 { 636 qxl_set_screen_pixmap_header (pScreen); 637 638 if ((surf = get_surface (pPixmap))) 639 qxl_surface_kill (surf); 640 641 set_surface (pPixmap, qxl->primary); 642 } 643 644 qxl_create_desired_modes (qxl); 645 qxl_update_edid (qxl); 646 647 qxl->screen_resources_created = TRUE; 648 return TRUE; 649} 650 651#ifdef XSPICE 652 653static void 654spiceqxl_screen_init (ScrnInfoPtr pScrn, qxl_screen_t *qxl) 655{ 656 // Init spice 657 if (!qxl->spice_server) 658 { 659 qxl->spice_server = xspice_get_spice_server (); 660 xspice_set_spice_server_options (qxl->options); 661 qxl->core = basic_event_loop_init (); 662 if (spice_server_init (qxl->spice_server, qxl->core) < 0) { 663 ErrorF ("failed to initialize server\n"); 664 abort (); 665 } 666 qxl_add_spice_display_interface (qxl); 667 qxl_add_spice_playback_interface (qxl); 668 qxl_add_spice_smartcard_interface (qxl); 669 spiceqxl_vdagent_init (qxl); 670 } 671 else 672 { 673 /* Crashes result from invalid xorg_timer pointers in 674 our watch lists because Xorg clears all timers at server reset. 675 We would require a fairly substantial revamp of how the 676 spice server is started and operated to avoid this crash. */ 677 ErrorF("WARNING: XSPICE requires -noreset; crashes are now likely.\n"); 678 } 679 680 if (! qxl->worker_running) 681 { 682 xspice_register_handlers(); 683 spice_server_vm_start(qxl->spice_server); 684 qxl->worker_running = TRUE; 685 } 686} 687 688#endif 689 690Bool 691qxl_fb_init (qxl_screen_t *qxl, ScreenPtr pScreen) 692{ 693 ScrnInfoPtr pScrn = qxl->pScrn; 694 695 if (!fbScreenInit (pScreen, qxl_surface_get_host_bits(qxl->primary), 696 pScrn->virtualX, pScrn->virtualY, 697 pScrn->xDpi, pScrn->yDpi, pScrn->virtualX, 698 pScrn->bitsPerPixel)) 699 return FALSE; 700 701 fbPictureInit (pScreen, NULL, 0); 702 return TRUE; 703} 704 705static Bool 706qxl_screen_init (SCREEN_INIT_ARGS_DECL) 707{ 708 ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen); 709 qxl_screen_t * qxl = pScrn->driverPrivate; 710 struct QXLRam *ram_header; 711 VisualPtr visual; 712 713 CHECK_POINT (); 714 715 assert (qxl->pScrn == pScrn); 716 717 if (!qxl_map_memory (qxl, pScrn->scrnIndex)) 718 return FALSE; 719 720#ifdef XSPICE 721 spiceqxl_screen_init (pScrn, qxl); 722#endif 723 ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset); 724 725 printf ("ram_header at %d\n", qxl->rom->ram_header_offset); 726 printf ("surf0 size: %d\n", qxl->rom->surface0_area_size); 727 728 qxl_save_state (pScrn); 729 qxl_blank_screen (pScreen, SCREEN_SAVER_ON); 730 731 miClearVisualTypes (); 732 if (!miSetVisualTypes (pScrn->depth, miGetDefaultVisualMask (pScrn->depth), 733 pScrn->rgbBits, pScrn->defaultVisual)) 734 goto out; 735 if (!miSetPixmapDepths ()) 736 goto out; 737 738#if 0 739 ErrorF ("allocated %d x %d %p\n", pScrn->virtualX, pScrn->virtualY, qxl->fb); 740#endif 741 742 /* Set up resources */ 743 qxl_reset_and_create_mem_slots (qxl); 744 ErrorF ("done reset\n"); 745 746 qxl->surface_cache = qxl_surface_cache_create (qxl); 747 qxl->primary = qxl_create_primary(qxl); 748 749 if (!qxl_fb_init (qxl, pScreen)) 750 goto out; 751 752 visual = pScreen->visuals + pScreen->numVisuals; 753 while (--visual >= pScreen->visuals) 754 { 755 if ((visual->class | DynamicClass) == DirectColor) 756 { 757 visual->offsetRed = pScrn->offset.red; 758 visual->offsetGreen = pScrn->offset.green; 759 visual->offsetBlue = pScrn->offset.blue; 760 visual->redMask = pScrn->mask.red; 761 visual->greenMask = pScrn->mask.green; 762 visual->blueMask = pScrn->mask.blue; 763 } 764 } 765 766 qxl->command_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cmd_ring), 767 sizeof (struct QXLCommand), 768 QXL_COMMAND_RING_SIZE, QXL_IO_NOTIFY_CMD, qxl); 769 qxl->cursor_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cursor_ring), 770 sizeof (struct QXLCommand), 771 QXL_CURSOR_RING_SIZE, QXL_IO_NOTIFY_CURSOR, qxl); 772 qxl->release_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->release_ring), 773 sizeof (uint64_t), 774 QXL_RELEASE_RING_SIZE, 0, qxl); 775 776 /* xf86DPMSInit (pScreen, xf86DPMSSet, 0); */ 777 778 pScreen->SaveScreen = qxl_blank_screen; 779 780 qxl_uxa_init (qxl, pScreen); 781 782 uxa_set_fallback_debug (pScreen, qxl->debug_render_fallbacks); 783 784 DamageSetup (pScreen); 785 786 /* We need to set totalPixmapSize after setup_uxa and Damage, 787 as the privates size is not computed correctly until then 788 */ 789#if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 12, 99, 901, 0)) 790 pScreen->totalPixmapSize = BitmapBytePad ((sizeof (PixmapRec) + dixPrivatesSize (PRIVATE_PIXMAP) ) * 8); 791#else 792 pScreen->totalPixmapSize = BitmapBytePad((sizeof(PixmapRec) + 793 dixScreenSpecificPrivatesSize(pScreen, PRIVATE_PIXMAP) ) * 8); 794#endif 795 796 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 797 if (!miCreateDefColormap (pScreen)) 798 goto out; 799 800 qxl->create_screen_resources = pScreen->CreateScreenResources; 801 pScreen->CreateScreenResources = qxl_create_screen_resources; 802 803 qxl->close_screen = pScreen->CloseScreen; 804 pScreen->CloseScreen = qxl_close_screen; 805 806 qxl_cursor_init (pScreen); 807 808 CHECK_POINT (); 809 810 pScreen->width = qxl->primary_mode.x_res; 811 pScreen->height = qxl->primary_mode.y_res; 812 813 if (!xf86CrtcScreenInit (pScreen)) 814 return FALSE; 815 816 if (!qxl_resize_primary_to_virtual (qxl)) 817 return FALSE; 818 819 /* Note: this must be done after DamageSetup() because it calls 820 * _dixInitPrivates. And if that has been called, DamageSetup() 821 * will assert. 822 */ 823 if (!uxa_resources_init (pScreen)) 824 return FALSE; 825 CHECK_POINT (); 826 827 /* fake transform support, to allow agent to switch crtc mode */ 828 /* without X doing checks, see rrcrtc.c "Check screen size */ 829 /* bounds" */ 830 xf86RandR12SetTransformSupport (pScreen, TRUE); 831 832 if (qxl->deferred_fps) 833 dfps_start_ticker(qxl); 834 835 return TRUE; 836 837out: 838 return FALSE; 839} 840 841static Bool 842qxl_enter_vt (VT_FUNC_ARGS_DECL) 843{ 844 SCRN_INFO_PTR (arg); 845 qxl_screen_t *qxl = pScrn->driverPrivate; 846 847 qxl_save_state (pScrn); 848 849 qxl_reset_and_create_mem_slots (qxl); 850 851 if (!qxl_resize_primary_to_virtual (qxl)) 852 return FALSE; 853 854 if (qxl->mem) 855 { 856 qxl_mem_free_all (qxl->mem); 857 } 858 859 if (qxl->surf_mem) 860 qxl_mem_free_all (qxl->surf_mem); 861 862 if (qxl->vt_surfaces) 863 { 864 qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces); 865 866 qxl->vt_surfaces = NULL; 867 } 868 869 qxl_create_desired_modes (qxl); 870 871 pScrn->EnableDisableFBAccess (XF86_SCRN_ARG (pScrn), TRUE); 872 873 return TRUE; 874} 875 876static void 877qxl_leave_vt (VT_FUNC_ARGS_DECL) 878{ 879 SCRN_INFO_PTR (arg); 880 qxl_screen_t *qxl = pScrn->driverPrivate; 881 882 xf86_hide_cursors (pScrn); 883 884 pScrn->EnableDisableFBAccess (XF86_SCRN_ARG (pScrn), FALSE); 885 886 if (qxl->deferred_fps <= 0) 887 qxl->vt_surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache); 888 889 ioport_write (qxl, QXL_IO_RESET, 0); 890 891 qxl_restore_state (pScrn); 892 qxl->device_primary = QXL_DEVICE_PRIMARY_NONE; 893} 894 895static Bool 896qxl_color_setup (ScrnInfoPtr pScrn) 897{ 898 int scrnIndex = pScrn->scrnIndex; 899 Gamma gzeros = { 0.0, 0.0, 0.0 }; 900 rgb rzeros = { 0, 0, 0 }; 901 902 if (!xf86SetDepthBpp (pScrn, 0, 0, 0, Support32bppFb)) 903 return FALSE; 904 905 if (pScrn->depth != 15 && pScrn->depth != 24) 906 { 907 xf86DrvMsg (scrnIndex, X_ERROR, "Depth %d is not supported\n", 908 pScrn->depth); 909 return FALSE; 910 } 911 xf86PrintDepthBpp (pScrn); 912 913 if (!xf86SetWeight (pScrn, rzeros, rzeros)) 914 return FALSE; 915 916 if (!xf86SetDefaultVisual (pScrn, -1)) 917 return FALSE; 918 919 if (!xf86SetGamma (pScrn, gzeros)) 920 return FALSE; 921 922 return TRUE; 923} 924 925static void 926print_modes (qxl_screen_t *qxl, int scrnIndex) 927{ 928 int i; 929 930 for (i = 0; i < qxl->num_modes; ++i) 931 { 932 struct QXLMode *m = qxl->modes + i; 933 934 xf86DrvMsg (scrnIndex, X_INFO, 935 "%d: %dx%d, %d bits, stride %d, %dmm x %dmm, orientation %d\n", 936 m->id, m->x_res, m->y_res, m->bits, m->stride, m->x_mili, 937 m->y_mili, m->orientation); 938 } 939} 940 941#ifndef XSPICE 942static Bool 943qxl_check_device (ScrnInfoPtr pScrn, qxl_screen_t *qxl) 944{ 945 int scrnIndex = pScrn->scrnIndex; 946 struct QXLRom *rom = qxl->rom; 947 struct QXLRam *ram_header = (void *)((unsigned long)qxl->ram + rom->ram_header_offset); 948 949 CHECK_POINT (); 950 951 if (rom->magic != 0x4f525851) /* "QXRO" little-endian */ 952 { 953 xf86DrvMsg (scrnIndex, X_ERROR, "Bad ROM signature %x\n", rom->magic); 954 return FALSE; 955 } 956 957 xf86DrvMsg (scrnIndex, X_INFO, "Device version %d.%d\n", 958 rom->id, rom->update_id); 959 960 xf86DrvMsg (scrnIndex, X_INFO, "Compression level %d, log level %d\n", 961 rom->compression_level, 962 rom->log_level); 963 964 xf86DrvMsg (scrnIndex, X_INFO, "%d io pages at 0x%lx\n", 965 rom->num_pages, (unsigned long)qxl->ram); 966 967 xf86DrvMsg (scrnIndex, X_INFO, "RAM header offset: 0x%x\n", rom->ram_header_offset); 968 969 if (ram_header->magic != 0x41525851) /* "QXRA" little-endian */ 970 { 971 xf86DrvMsg (scrnIndex, X_ERROR, "Bad RAM signature %x at %p\n", 972 ram_header->magic, 973 &ram_header->magic); 974 return FALSE; 975 } 976 977 xf86DrvMsg (scrnIndex, X_INFO, "Correct RAM signature %x\n", 978 ram_header->magic); 979 return TRUE; 980} 981 982#endif /* !XSPICE */ 983 984Bool 985qxl_pre_init_common(ScrnInfoPtr pScrn) 986{ 987 int scrnIndex = pScrn->scrnIndex; 988 qxl_screen_t *qxl = pScrn->driverPrivate; 989 990 if (!qxl_color_setup (pScrn)) 991 goto out; 992 993 /* option parsing and card differentiation */ 994 xf86CollectOptions (pScrn, NULL); 995 memcpy (qxl->options, DefaultOptions, sizeof (DefaultOptions)); 996 xf86ProcessOptions (scrnIndex, pScrn->options, qxl->options); 997 998 qxl->enable_image_cache = 999 get_bool_option (qxl->options, OPTION_ENABLE_IMAGE_CACHE, "QXL_ENABLE_IMAGE_CACHE"); 1000 qxl->enable_fallback_cache = 1001 get_bool_option (qxl->options, OPTION_ENABLE_FALLBACK_CACHE, "QXL_ENABLE_FALLBACK_CACHE"); 1002 qxl->enable_surfaces = 1003 get_bool_option (qxl->options, OPTION_ENABLE_SURFACES, "QXL_ENABLE_SURFACES"); 1004 qxl->debug_render_fallbacks = 1005 get_bool_option (qxl->options, OPTION_DEBUG_RENDER_FALLBACKS, "QXL_DEBUG_RENDER_FALLBACKS"); 1006 qxl->num_heads = 1007 get_int_option (qxl->options, OPTION_NUM_HEADS, "QXL_NUM_HEADS"); 1008 if (qxl->num_heads == 0) { 1009 xf86DrvMsg (scrnIndex, X_INFO, "QXL_NUM_HEADS not configured, defaulting to 1\n"); 1010 qxl->num_heads = 1; 1011 } 1012 1013 qxl->deferred_fps = get_int_option(qxl->options, OPTION_SPICE_DEFERRED_FPS, "XSPICE_DEFERRED_FPS"); 1014 if (qxl->deferred_fps > 0) 1015 xf86DrvMsg(scrnIndex, X_INFO, "Deferred FPS: %d\n", qxl->deferred_fps); 1016 else 1017 xf86DrvMsg(scrnIndex, X_INFO, "Deferred Frames: Disabled\n"); 1018 1019 xf86DrvMsg (scrnIndex, X_INFO, "Offscreen Surfaces: %s\n", 1020 qxl->enable_surfaces ? "Enabled" : "Disabled"); 1021 xf86DrvMsg (scrnIndex, X_INFO, "Image Cache: %s\n", 1022 qxl->enable_image_cache ? "Enabled" : "Disabled"); 1023 xf86DrvMsg (scrnIndex, X_INFO, "Fallback Cache: %s\n", 1024 qxl->enable_fallback_cache ? "Enabled" : "Disabled"); 1025 1026 return TRUE; 1027out: 1028 return FALSE; 1029} 1030 1031static Bool 1032qxl_pre_init (ScrnInfoPtr pScrn, int flags) 1033{ 1034 int scrnIndex = pScrn->scrnIndex; 1035 qxl_screen_t *qxl = NULL; 1036 ClockRangePtr clockRanges = NULL; 1037 //int *linePitches = NULL; 1038 //DisplayModePtr mode; 1039 unsigned int max_x, max_y; 1040#ifdef XSPICE 1041 const char *playback_fifo_dir; 1042 const char *smartcard_file; 1043#endif 1044 1045 /* In X server 1.7.5, Xorg -configure will cause this 1046 * function to get called without a confScreen. 1047 */ 1048 if (!pScrn->confScreen) 1049 return FALSE; 1050 1051 CHECK_POINT (); 1052 1053 qxl_mem_init(); 1054 1055 /* zaphod mode is for suckers and i choose not to implement it */ 1056 if (xf86IsEntityShared (pScrn->entityList[0])) 1057 { 1058 xf86DrvMsg (scrnIndex, X_ERROR, "No Zaphod mode for you\n"); 1059 return FALSE; 1060 } 1061 1062 if (!pScrn->driverPrivate) 1063 pScrn->driverPrivate = xnfcalloc (sizeof (qxl_screen_t), 1); 1064 1065 qxl = pScrn->driverPrivate; 1066 qxl->device_primary = QXL_DEVICE_PRIMARY_UNDEFINED; 1067 qxl->pScrn = pScrn; 1068 qxl->x_modes = NULL; 1069 qxl->entity = xf86GetEntityInfo (pScrn->entityList[0]); 1070 qxl->kms_enabled = FALSE; 1071 xorg_list_init(&qxl->ums_bos); 1072 1073#ifndef XSPICE 1074 qxl->pci = xf86GetPciInfoForEntity (qxl->entity->index); 1075#ifndef XSERVER_LIBPCIACCESS 1076 qxl->pci_tag = pciTag (qxl->pci->bus, qxl->pci->device, qxl->pci->func); 1077#endif 1078 if (qxl->pci->revision < 4) 1079 { 1080 ErrorF ("Ignoring monitor config, device revision < 4\n"); 1081 } 1082#endif /* XSPICE */ 1083 pScrn->monitor = pScrn->confScreen->monitor; 1084 1085 qxl_ums_setup_funcs(qxl); 1086 1087 if (!qxl_pre_init_common(pScrn)) 1088 goto out; 1089 1090#ifdef XSPICE 1091 playback_fifo_dir = get_str_option(qxl->options, OPTION_SPICE_PLAYBACK_FIFO_DIR, 1092 "XSPICE_PLAYBACK_FIFO_DIR"); 1093 if (playback_fifo_dir) 1094 strncpy(qxl->playback_fifo_dir, playback_fifo_dir, sizeof(qxl->playback_fifo_dir)); 1095 else 1096 qxl->playback_fifo_dir[0] = '\0'; 1097 1098 smartcard_file = get_str_option(qxl->options, OPTION_SPICE_SMARTCARD_FILE, 1099 "XSPICE_SMARTCARD_FILE"); 1100 if (smartcard_file) 1101 strncpy(qxl->smartcard_file, smartcard_file, sizeof(qxl->smartcard_file)); 1102 else 1103 qxl->smartcard_file[0] = '\0'; 1104 1105 qxl->surface0_size = 1106 get_int_option (qxl->options, OPTION_FRAME_BUFFER_SIZE, "QXL_FRAME_BUFFER_SIZE") << 20L; 1107 qxl->vram_size = 1108 get_int_option (qxl->options, OPTION_SURFACE_BUFFER_SIZE, "QXL_SURFACE_BUFFER_SIZE") << 20L; 1109 qxl->ram_size = 1110 get_int_option (qxl->options, OPTION_COMMAND_BUFFER_SIZE, "QXL_COMMAND_BUFFER_SIZE") << 20L; 1111#endif 1112 1113 if (!qxl_map_memory (qxl, scrnIndex)) 1114 goto out; 1115 1116#ifndef XSPICE 1117 if (!qxl_check_device (pScrn, qxl)) 1118 goto out; 1119#else 1120 xspice_init_qxl_ram (qxl); /* initialize the rings */ 1121#endif 1122 1123#define DIV_ROUND_UP(n, a) (((n) + (a) - 1) / (a)) 1124#define BYTES_TO_KB(bytes) DIV_ROUND_UP(bytes, 1024) 1125#define PAGES_TO_KB(pages) ((pages) * getpagesize() / 1024) 1126 1127 pScrn->videoRam = PAGES_TO_KB(qxl->rom->num_pages) 1128 - BYTES_TO_KB(qxl->monitors_config_size); 1129 xf86DrvMsg (scrnIndex, X_INFO, "%d KB of video RAM\n", pScrn->videoRam); 1130 xf86DrvMsg (scrnIndex, X_INFO, "%d surfaces\n", qxl->rom->n_surfaces); 1131 1132 /* ddc stuff here */ 1133 1134 clockRanges = xnfcalloc (sizeof (ClockRange), 1); 1135 clockRanges->next = NULL; 1136 clockRanges->minClock = 10000; 1137 clockRanges->maxClock = 400000; 1138 clockRanges->clockIndex = -1; 1139 clockRanges->interlaceAllowed = clockRanges->doubleScanAllowed = 0; 1140 clockRanges->ClockMulFactor = clockRanges->ClockDivFactor = 1; 1141 pScrn->progClock = TRUE; 1142 1143 /* override QXL monitor stuff */ 1144 if (pScrn->monitor->nHsync <= 0) 1145 { 1146 pScrn->monitor->hsync[0].lo = 29.0; 1147 pScrn->monitor->hsync[0].hi = 160.0; 1148 pScrn->monitor->nHsync = 1; 1149 } 1150 if (pScrn->monitor->nVrefresh <= 0) 1151 { 1152 pScrn->monitor->vrefresh[0].lo = 50; 1153 pScrn->monitor->vrefresh[0].hi = 75; 1154 pScrn->monitor->nVrefresh = 1; 1155 } 1156 1157 qxl_initialize_x_modes (qxl, pScrn, &max_x, &max_y); 1158 1159 CHECK_POINT (); 1160 1161 xf86PruneDriverModes (pScrn); 1162 1163 qxl_init_randr (pScrn, qxl); 1164 1165 xf86SetDpi (pScrn, 0, 0); 1166 1167 if (!xf86LoadSubModule (pScrn, "fb") 1168#ifndef XSPICE 1169 || !xf86LoadSubModule (pScrn, "ramdac") 1170 || !xf86LoadSubModule (pScrn, "vgahw") 1171#endif 1172 ) 1173 { 1174 goto out; 1175 } 1176 1177 print_modes (qxl, scrnIndex); 1178 1179#ifndef XSPICE 1180 /* VGA hardware initialisation */ 1181 if (!vgaHWGetHWRec (pScrn)) 1182 return FALSE; 1183 vgaHWSetStdFuncs (VGAHWPTR (pScrn)); 1184#endif 1185 1186 /* hate */ 1187 qxl_unmap_memory (qxl); 1188 1189 CHECK_POINT (); 1190 1191 xf86DrvMsg (scrnIndex, X_INFO, "PreInit complete\n"); 1192#ifdef GIT_VERSION 1193 xf86DrvMsg (scrnIndex, X_INFO, "git commit %s\n", GIT_VERSION); 1194#endif 1195 return TRUE; 1196 1197out: 1198 if (clockRanges) 1199 free (clockRanges); 1200 if (qxl) 1201 free (qxl); 1202 1203 return FALSE; 1204} 1205 1206#ifndef XSPICE 1207#ifdef XSERVER_LIBPCIACCESS 1208enum qxl_class 1209{ 1210 CHIP_QXL_1, 1211}; 1212 1213static const struct pci_id_match qxl_device_match[] = { 1214 { 1215 PCI_VENDOR_RED_HAT, PCI_CHIP_QXL_0100, PCI_MATCH_ANY, PCI_MATCH_ANY, 1216 0x00000000, 0x00000000, CHIP_QXL_1 1217 }, 1218 { 1219 PCI_VENDOR_RED_HAT, PCI_CHIP_QXL_01FF, PCI_MATCH_ANY, PCI_MATCH_ANY, 1220 0x00000000, 0x00000000, CHIP_QXL_1 1221 }, 1222 1223 { 0 }, 1224}; 1225#endif 1226 1227static SymTabRec qxlChips[] = { 1228 { PCI_CHIP_QXL_0100, "QXL 1", }, 1229 { -1, NULL } 1230}; 1231 1232#ifndef XSERVER_LIBPCIACCESS 1233static PciChipsets qxlPciChips[] = { 1234 { PCI_CHIP_QXL_0100, PCI_CHIP_QXL_0100, RES_SHARED_VGA }, 1235 { -1, -1, RES_UNDEFINED } 1236}; 1237#endif 1238#endif /* !XSPICE */ 1239 1240static void 1241qxl_identify (int flags) 1242{ 1243#ifndef XSPICE 1244 xf86PrintChipsets ("qxl", "Driver for QXL virtual graphics", qxlChips); 1245#endif 1246} 1247 1248static void 1249qxl_init_scrn (ScrnInfoPtr pScrn, Bool kms) 1250{ 1251 pScrn->driverVersion = 0; 1252 pScrn->driverName = driver_name; 1253 pScrn->name = driver_name; 1254 1255 if (kms) { 1256#if !defined(XSPICE) && defined(XF86DRM_MODE) 1257 pScrn->PreInit = qxl_pre_init_kms; 1258 pScrn->ScreenInit = qxl_screen_init_kms; 1259 pScrn->EnterVT = qxl_enter_vt_kms; 1260 pScrn->LeaveVT = qxl_leave_vt_kms; 1261#endif 1262 } else { 1263 pScrn->PreInit = qxl_pre_init; 1264 pScrn->ScreenInit = qxl_screen_init; 1265 pScrn->EnterVT = qxl_enter_vt; 1266 pScrn->LeaveVT = qxl_leave_vt; 1267 } 1268 pScrn->SwitchMode = qxl_switch_mode; 1269 pScrn->ValidMode = NULL; 1270} 1271 1272#if defined(XF86DRM_MODE) && !defined(XSPICE) 1273static char * 1274CreatePCIBusID(const struct pci_device *dev) 1275{ 1276 char *busID; 1277 1278 if (asprintf(&busID, "pci:%04x:%02x:%02x.%d", 1279 dev->domain, dev->bus, dev->dev, dev->func) == -1) 1280 return NULL; 1281 1282 return busID; 1283} 1284 1285static Bool qxl_kernel_mode_enabled(ScrnInfoPtr pScrn, struct pci_device *pci_dev) 1286{ 1287 char *busIdString; 1288 int ret; 1289 1290 busIdString = CreatePCIBusID(pci_dev); 1291 ret = drmCheckModesettingSupported(busIdString); 1292 free(busIdString); 1293 if (ret) { 1294 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, 1295 "[KMS] drm report modesetting isn't supported.\n"); 1296 return FALSE; 1297 } 1298 1299 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, 1300 "[KMS] Kernel modesetting enabled.\n"); 1301 return TRUE; 1302} 1303#else 1304#define qxl_kernel_mode_enabled(x, y) FALSE 1305#endif 1306 1307#ifdef XSPICE 1308static Bool 1309qxl_probe (struct _DriverRec *drv, int flags) 1310{ 1311 ScrnInfoPtr pScrn; 1312 int entityIndex; 1313 EntityInfoPtr pEnt; 1314 GDevPtr* device; 1315 1316 if (flags & PROBE_DETECT) 1317 return TRUE; 1318 1319 pScrn = xf86AllocateScreen (drv, flags); 1320 qxl_init_scrn (pScrn, FALSE); 1321 1322 xf86MatchDevice (driver_name, &device); 1323 entityIndex = xf86ClaimNoSlot (drv, 0, device[0], TRUE); 1324 pEnt = xf86GetEntityInfo (entityIndex); 1325 pEnt->driver = drv; 1326 1327 xf86AddEntityToScreen (pScrn, entityIndex); 1328 1329 return TRUE; 1330} 1331 1332#else /* normal, not XSPICE */ 1333#ifndef XSERVER_LIBPCIACCESS 1334static Bool 1335qxl_probe (DriverPtr drv, int flags) 1336{ 1337 int i, numUsed; 1338 int numDevSections; 1339 int * usedChips; 1340 GDevPtr *devSections; 1341 1342 if ((numDevSections = xf86MatchDevice (QXL_NAME, &devSections)) <= 0) 1343 return FALSE; 1344 1345 if (!xf86GetPciVideoInfo ()) 1346 return FALSE; 1347 1348 numUsed = xf86MatchPciInstances (QXL_NAME, PCI_VENDOR_RED_HAT, 1349 qxlChips, qxlPciChips, 1350 devSections, numDevSections, 1351 drv, &usedChips); 1352 1353 xfree (devSections); 1354 1355 if (numUsed < 0) 1356 { 1357 xfree (usedChips); 1358 return FALSE; 1359 } 1360 1361 if (flags & PROBE_DETECT) 1362 { 1363 xfree (usedChips); 1364 return TRUE; 1365 } 1366 1367 for (i = 0; i < numUsed; i++) 1368 { 1369 ScrnInfoPtr pScrn = NULL; 1370 if ((pScrn = xf86ConfigPciEntity (pScrn, 0, usedChips[i], qxlPciChips, 1371 0, 0, 0, 0, 0))) 1372 qxl_init_scrn (pScrn, FALSE); 1373 } 1374 1375 xfree (usedChips); 1376 return TRUE; 1377} 1378 1379#else /* pciaccess */ 1380 1381static Bool 1382qxl_pci_probe (DriverPtr drv, int entity, struct pci_device *dev, intptr_t match) 1383{ 1384 qxl_screen_t *qxl; 1385 ScrnInfoPtr pScrn = xf86ConfigPciEntity (NULL, 0, entity, NULL, NULL, 1386 NULL, NULL, NULL, NULL); 1387 Bool kms = FALSE; 1388 1389 if (!pScrn) 1390 return FALSE; 1391 1392 if (dev) { 1393 if (qxl_kernel_mode_enabled(pScrn, dev)) { 1394 kms = TRUE; 1395 } 1396 } 1397 1398 if (!pScrn->driverPrivate) 1399 pScrn->driverPrivate = xnfcalloc (sizeof (qxl_screen_t), 1); 1400 qxl = pScrn->driverPrivate; 1401 qxl->pci = dev; 1402 1403 qxl_init_scrn (pScrn, kms); 1404 1405 return TRUE; 1406} 1407 1408#define qxl_probe NULL 1409 1410#endif 1411 1412#ifdef XSERVER_PLATFORM_BUS 1413static Bool 1414qxl_platform_probe(DriverPtr driver, int entity, int flags, 1415 struct xf86_platform_device *dev, intptr_t match_data) 1416{ 1417 qxl_screen_t *qxl; 1418 ScrnInfoPtr pScrn; 1419 int scrnFlag = 0; 1420 1421 if (!dev->pdev) 1422 return FALSE; 1423 1424 if (flags & PLATFORM_PROBE_GPU_SCREEN) 1425 scrnFlag = XF86_ALLOCATE_GPU_SCREEN; 1426 1427 pScrn = xf86AllocateScreen(driver, scrnFlag); 1428 if (!pScrn) 1429 return FALSE; 1430 1431 if (xf86IsEntitySharable(entity)) 1432 xf86SetEntityShared(entity); 1433 1434 xf86AddEntityToScreen(pScrn, entity); 1435 1436 qxl = pScrn->driverPrivate = xnfcalloc (sizeof (qxl_screen_t), 1); 1437 qxl->pci = dev->pdev; 1438 qxl->platform_dev = dev; 1439 1440 qxl_init_scrn (pScrn, qxl_kernel_mode_enabled(pScrn, dev->pdev)); 1441 1442 return TRUE; 1443} 1444#endif /* XSERVER_PLATFORM_BUS */ 1445 1446#endif /* XSPICE */ 1447 1448static Bool 1449qxl_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, void *data) 1450{ 1451 xorgHWFlags *hw_flags; 1452 1453 switch (op) { 1454 case GET_REQUIRED_HW_INTERFACES: 1455 hw_flags = data; 1456#ifdef XSPICE 1457 *hw_flags = HW_SKIP_CONSOLE; 1458#else 1459 *hw_flags = HW_IO | HW_MMIO; 1460#endif 1461 return TRUE; 1462#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0) 1463 case SUPPORTS_SERVER_FDS: 1464 return TRUE; 1465#endif 1466 default: 1467 return FALSE; 1468 } 1469} 1470 1471static DriverRec qxl_driver = { 1472 0, 1473 driver_name, 1474 qxl_identify, 1475 qxl_probe, 1476 qxl_available_options, 1477 NULL, 1478 0, 1479 qxl_driver_func, 1480#ifdef XSPICE 1481 NULL, 1482 NULL, 1483 NULL, 1484#else 1485#ifdef XSERVER_LIBPCIACCESS 1486 qxl_device_match, 1487 qxl_pci_probe, 1488#else 1489 NULL, 1490 NULL, 1491#endif 1492#ifdef XSERVER_PLATFORM_BUS 1493 qxl_platform_probe, 1494#else 1495 NULL, 1496#endif 1497#endif /* XSPICE */ 1498}; 1499 1500static pointer 1501qxl_setup (pointer module, pointer opts, int *errmaj, int *errmin) 1502{ 1503 static Bool loaded = FALSE; 1504 1505 if (!loaded) 1506 { 1507 loaded = TRUE; 1508 xf86AddDriver (&qxl_driver, module, HaveDriverFuncs); 1509#ifdef XSPICE 1510 xspice_add_input_drivers (module); 1511#endif 1512 return (void *)1; 1513 } 1514 else 1515 { 1516 if (errmaj) 1517 *errmaj = LDR_ONCEONLY; 1518 1519 return NULL; 1520 } 1521} 1522 1523static XF86ModuleVersionInfo qxl_module_info = 1524{ 1525 driver_name, 1526 MODULEVENDORSTRING, 1527 MODINFOSTRING1, 1528 MODINFOSTRING2, 1529 XORG_VERSION_CURRENT, 1530 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, 1531 ABI_CLASS_VIDEODRV, 1532 ABI_VIDEODRV_VERSION, 1533 MOD_CLASS_VIDEODRV, 1534 { 0, 0, 0, 0 } 1535}; 1536 1537_X_EXPORT XF86ModuleData 1538#ifdef XSPICE 1539spiceqxlModuleData 1540#else 1541qxlModuleData 1542#endif 1543= { 1544 &qxl_module_info, 1545 qxl_setup, 1546 NULL 1547}; 1548