1 /* BEGIN CSTYLED */ 2 3 /* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 4 */ 5 /* 6 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 7 * All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the 11 * "Software"), to deal in the Software without restriction, including 12 * without limitation the rights to use, copy, modify, merge, publish, 13 * distribute, sub license, and/or sell copies of the Software, and to 14 * permit persons to whom the Software is furnished to do so, subject to 15 * the following conditions: 16 * 17 * The above copyright notice and this permission notice (including the 18 * next paragraph) shall be included in all copies or substantial portions 19 * of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 24 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 25 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 27 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 * 29 */ 30 31 /* 32 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 33 * Use is subject to license terms. 34 */ 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 38 #include "drmP.h" 39 #include "drm.h" 40 #include "i915_drm.h" 41 #include "i915_drv.h" 42 43 #define IS_I965G(dev) (dev->pci_device == 0x2972 || \ 44 dev->pci_device == 0x2982 || \ 45 dev->pci_device == 0x2992 || \ 46 dev->pci_device == 0x29A2 || \ 47 dev->pci_device == 0x2A02 || \ 48 dev->pci_device == 0x2A12) 49 50 51 /* Really want an OS-independent resettable timer. Would like to have 52 * this loop run for (eg) 3 sec, but have the timer reset every time 53 * the head pointer changes, so that EBUSY only happens if the ring 54 * actually stalls for (eg) 3 seconds. 55 */ 56 /*ARGSUSED*/ 57 int i915_wait_ring(drm_device_t * dev, int n, const char *caller) 58 { 59 drm_i915_private_t *dev_priv = dev->dev_private; 60 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 61 u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 62 int i; 63 64 for (i = 0; i < 10000; i++) { 65 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 66 ring->space = ring->head - (ring->tail + 8); 67 if (ring->space < 0) 68 ring->space += ring->Size; 69 if (ring->space >= n) 70 return 0; 71 72 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 73 74 if (ring->head != last_head) 75 i = 0; 76 77 last_head = ring->head; 78 DRM_UDELAY(1); 79 } 80 81 return DRM_ERR(EBUSY); 82 } 83 84 void i915_kernel_lost_context(drm_device_t * dev) 85 { 86 drm_i915_private_t *dev_priv = dev->dev_private; 87 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 88 89 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 90 ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; 91 ring->space = ring->head - (ring->tail + 8); 92 if (ring->space < 0) 93 ring->space += ring->Size; 94 95 if (ring->head == ring->tail) 96 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; 97 } 98 99 static int i915_dma_cleanup(drm_device_t * dev) 100 { 101 /* Make sure interrupts are disabled here because the uninstall ioctl 102 * may not have been called from userspace and after dev_private 103 * is freed, it's too late. 104 */ 105 if (dev->irq) 106 (void) drm_irq_uninstall(dev); 107 108 if (dev->dev_private) { 109 drm_i915_private_t *dev_priv = 110 (drm_i915_private_t *) dev->dev_private; 111 112 if (dev_priv->ring.virtual_start) { 113 drm_core_ioremapfree(&dev_priv->ring.map, dev); 114 } 115 116 #if defined(__SOLARIS__) || defined(sun) 117 if (dev_priv->hw_status_page) { 118 drm_pci_free(dev); 119 #else 120 if (dev_priv->status_page_dmah) { 121 drm_pci_free(dev, dev_priv->status_page_dmah); 122 #endif 123 /* Need to rewrite hardware status page */ 124 I915_WRITE(0x02080, 0x1ffff000); 125 } 126 127 drm_free(dev->dev_private, sizeof(drm_i915_private_t), 128 DRM_MEM_DRIVER); 129 130 dev->dev_private = NULL; 131 } 132 133 return 0; 134 } 135 136 static int i915_initialize(drm_device_t * dev, 137 drm_i915_private_t * dev_priv, 138 drm_i915_init_t * init) 139 { 140 (void) memset(dev_priv, 0, sizeof(drm_i915_private_t)); 141 142 DRM_GETSAREA(); 143 if (!dev_priv->sarea) { 144 DRM_ERROR("can not find sarea!\n"); 145 dev->dev_private = (void *)dev_priv; 146 (void) i915_dma_cleanup(dev); 147 return DRM_ERR(EINVAL); 148 } 149 150 dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); 151 if (!dev_priv->mmio_map) { 152 dev->dev_private = (void *)dev_priv; 153 (void) i915_dma_cleanup(dev); 154 DRM_ERROR("can not find mmio map!\n"); 155 return DRM_ERR(EINVAL); 156 } 157 158 dev_priv->sarea_priv = (drm_i915_sarea_t *) 159 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); 160 161 dev_priv->ring.Start = init->ring_start; 162 dev_priv->ring.End = init->ring_end; 163 dev_priv->ring.Size = init->ring_size; 164 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; 165 166 dev_priv->ring.map.offset.off = (u_offset_t)init->ring_start; 167 dev_priv->ring.map.size = init->ring_size; 168 dev_priv->ring.map.type = 0; 169 dev_priv->ring.map.flags = 0; 170 dev_priv->ring.map.mtrr = 0; 171 172 drm_core_ioremap(&dev_priv->ring.map, dev); 173 174 if (dev_priv->ring.map.handle == NULL) { 175 dev->dev_private = (void *)dev_priv; 176 (void) i915_dma_cleanup(dev); 177 DRM_ERROR("can not ioremap virtual address for" 178 " ring buffer\n"); 179 return DRM_ERR(ENOMEM); 180 } 181 182 dev_priv->ring.virtual_start = (u8 *)dev_priv->ring.map.dev_addr; 183 184 dev_priv->cpp = init->cpp; 185 dev_priv->back_offset = init->back_offset; 186 dev_priv->front_offset = init->front_offset; 187 dev_priv->current_page = 0; 188 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 189 190 /* We are using separate values as placeholders for mechanisms for 191 * private backbuffer/depthbuffer usage. 192 */ 193 dev_priv->use_mi_batchbuffer_start = 0; 194 195 /* Allow hardware batchbuffers unless told otherwise. 196 */ 197 dev_priv->allow_batchbuffer = 1; 198 199 /* Program Hardware Status Page */ 200 #if defined(__SOLARIS__) || defined(sun) 201 dev_priv->hw_status_page = 202 drm_pci_alloc(dev, DRM_PAGE_SIZE, &dev_priv->dma_status_page); 203 #else 204 dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 205 0xffffffff); 206 #endif 207 208 #if defined(__SOLARIS__) || defined(sun) 209 if (!dev_priv->hw_status_page) { 210 #else 211 if (!dev_priv->status_page_dmah) { 212 #endif 213 dev->dev_private = (void *)dev_priv; 214 (void) i915_dma_cleanup(dev); 215 DRM_ERROR("Can not allocate hardware status page\n"); 216 return DRM_ERR(ENOMEM); 217 } 218 219 #if !defined(__SOLARIS__) && !defined(sun) 220 dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; 221 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; 222 #endif 223 (void) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 224 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 225 226 I915_WRITE(0x02080, dev_priv->dma_status_page); 227 DRM_DEBUG("Enabled hardware status page\n"); 228 229 dev->dev_private = (void *)dev_priv; 230 231 #ifdef I915_HAVE_BUFFER 232 drm_bo_driver_init(dev); 233 #endif 234 return 0; 235 } 236 237 static int i915_dma_resume(drm_device_t * dev) 238 { 239 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 240 241 DRM_DEBUG("%s\n", __FUNCTION__); 242 243 if (!dev_priv->sarea) { 244 DRM_ERROR("can not find sarea!\n"); 245 return DRM_ERR(EINVAL); 246 } 247 248 if (!dev_priv->mmio_map) { 249 DRM_ERROR("can not find mmio map!\n"); 250 return DRM_ERR(EINVAL); 251 } 252 253 if (dev_priv->ring.map.handle == NULL) { 254 DRM_ERROR("can not ioremap virtual address for" 255 " ring buffer\n"); 256 return DRM_ERR(ENOMEM); 257 } 258 259 /* Program Hardware Status Page */ 260 if (!dev_priv->hw_status_page) { 261 DRM_ERROR("Can not find hardware status page\n"); 262 return DRM_ERR(EINVAL); 263 } 264 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 265 266 I915_WRITE(0x02080, dev_priv->dma_status_page); 267 DRM_DEBUG("Enabled hardware status page\n"); 268 269 return 0; 270 } 271 272 /*ARGSUSED*/ 273 static int i915_dma_init(DRM_IOCTL_ARGS) 274 { 275 DRM_DEVICE; 276 drm_i915_private_t *dev_priv; 277 drm_i915_init_t init; 278 int retcode = 0; 279 280 DRM_COPY_FROM_USER_IOCTL(init, (drm_i915_init_t __user *) data, 281 sizeof(init)); 282 283 switch (init.func) { 284 case I915_INIT_DMA: 285 dev_priv = drm_alloc(sizeof(drm_i915_private_t), 286 DRM_MEM_DRIVER); 287 if (dev_priv == NULL) 288 return DRM_ERR(ENOMEM); 289 retcode = i915_initialize(dev, dev_priv, &init); 290 break; 291 case I915_CLEANUP_DMA: 292 retcode = i915_dma_cleanup(dev); 293 break; 294 case I915_RESUME_DMA: 295 retcode = i915_dma_resume(dev); 296 break; 297 default: 298 retcode = DRM_ERR(EINVAL); 299 break; 300 } 301 302 return retcode; 303 } 304 305 /* Implement basically the same security restrictions as hardware does 306 * for MI_BATCH_NON_SECURE. These can be made stricter at any time. 307 * 308 * Most of the calculations below involve calculating the size of a 309 * particular instruction. It's important to get the size right as 310 * that tells us where the next instruction to check is. Any illegal 311 * instruction detected will be given a size of zero, which is a 312 * signal to abort the rest of the buffer. 313 */ 314 static int do_validate_cmd(int cmd) 315 { 316 switch (((cmd >> 29) & 0x7)) { 317 case 0x0: 318 switch ((cmd >> 23) & 0x3f) { 319 case 0x0: 320 return 1; /* MI_NOOP */ 321 case 0x4: 322 return 1; /* MI_FLUSH */ 323 default: 324 return 0; /* disallow everything else */ 325 } 326 #ifndef __SUNPRO_C 327 break; 328 #endif 329 case 0x1: 330 return 0; /* reserved */ 331 case 0x2: 332 return (cmd & 0xff) + 2; /* 2d commands */ 333 case 0x3: 334 if (((cmd >> 24) & 0x1f) <= 0x18) 335 return 1; 336 337 switch ((cmd >> 24) & 0x1f) { 338 case 0x1c: 339 return 1; 340 case 0x1d: 341 switch ((cmd >> 16) & 0xff) { 342 case 0x3: 343 return (cmd & 0x1f) + 2; 344 case 0x4: 345 return (cmd & 0xf) + 2; 346 default: 347 return (cmd & 0xffff) + 2; 348 } 349 case 0x1e: 350 if (cmd & (1 << 23)) 351 return (cmd & 0xffff) + 1; 352 else 353 return 1; 354 case 0x1f: 355 if ((cmd & (1 << 23)) == 0) /* inline vertices */ 356 return (cmd & 0x1ffff) + 2; 357 else if (cmd & (1 << 17)) /* indirect random */ 358 if ((cmd & 0xffff) == 0) 359 return 0; /* unknown length, too hard */ 360 else 361 return (((cmd & 0xffff) + 1) / 2) + 1; 362 else 363 return 2; /* indirect sequential */ 364 default: 365 return 0; 366 } 367 default: 368 return 0; 369 } 370 371 #ifndef __SUNPRO_C 372 return 0; 373 #endif 374 } 375 376 static int validate_cmd(int cmd) 377 { 378 int ret = do_validate_cmd(cmd); 379 380 /* printk("validate_cmd( %x ): %d\n", cmd, ret); */ 381 382 return ret; 383 } 384 385 static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords, int mode) 386 { 387 drm_i915_private_t *dev_priv = dev->dev_private; 388 int i; 389 RING_LOCALS; 390 391 if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) 392 return DRM_ERR(EINVAL); 393 394 BEGIN_LP_RING((dwords+1)&~1); 395 396 for (i = 0; i < dwords;) { 397 int cmd, sz; 398 399 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) 400 return DRM_ERR(EINVAL); 401 402 403 if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) 404 return DRM_ERR(EINVAL); 405 406 OUT_RING(cmd); 407 408 while (++i, --sz) { 409 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], 410 sizeof(cmd))) { 411 return DRM_ERR(EINVAL); 412 } 413 OUT_RING(cmd); 414 } 415 } 416 417 if (dwords & 1) 418 OUT_RING(0); 419 420 ADVANCE_LP_RING(); 421 422 return 0; 423 } 424 425 static int i915_emit_box(drm_device_t * dev, 426 drm_clip_rect_t __user * boxes, 427 int i, int DR1, int DR4, int mode) 428 { 429 drm_i915_private_t *dev_priv = dev->dev_private; 430 drm_clip_rect_t box; 431 RING_LOCALS; 432 433 if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { 434 return DRM_ERR(EFAULT); 435 } 436 437 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { 438 DRM_ERROR("Bad box %d,%d..%d,%d\n", 439 box.x1, box.y1, box.x2, box.y2); 440 return DRM_ERR(EINVAL); 441 } 442 443 if (IS_I965G(dev)) { 444 BEGIN_LP_RING(4); 445 OUT_RING(GFX_OP_DRAWRECT_INFO_I965); 446 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 447 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 448 OUT_RING(DR4); 449 ADVANCE_LP_RING(); 450 } else { 451 BEGIN_LP_RING(6); 452 OUT_RING(GFX_OP_DRAWRECT_INFO); 453 OUT_RING(DR1); 454 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 455 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 456 OUT_RING(DR4); 457 OUT_RING(0); 458 ADVANCE_LP_RING(); 459 } 460 461 return 0; 462 } 463 464 /* XXX: Emitting the counter should really be moved to part of the IRQ 465 * emit. For now, do it in both places: 466 */ 467 468 static void i915_emit_breadcrumb(drm_device_t *dev) 469 { 470 drm_i915_private_t *dev_priv = dev->dev_private; 471 RING_LOCALS; 472 473 dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; 474 475 BEGIN_LP_RING(4); 476 OUT_RING(CMD_STORE_DWORD_IDX); 477 OUT_RING(20); 478 OUT_RING(dev_priv->counter); 479 OUT_RING(0); 480 ADVANCE_LP_RING(); 481 #ifdef I915_HAVE_FENCE 482 drm_fence_flush_old(dev, 0, dev_priv->counter); 483 #endif 484 } 485 486 487 int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush) 488 { 489 drm_i915_private_t *dev_priv = dev->dev_private; 490 uint32_t flush_cmd = CMD_MI_FLUSH; 491 RING_LOCALS; 492 493 flush_cmd |= flush; 494 495 i915_kernel_lost_context(dev); 496 497 BEGIN_LP_RING(4); 498 OUT_RING(flush_cmd); 499 OUT_RING(0); 500 OUT_RING(0); 501 OUT_RING(0); 502 ADVANCE_LP_RING(); 503 504 return 0; 505 } 506 507 static int i915_dispatch_cmdbuffer(drm_device_t * dev, 508 drm_i915_cmdbuffer_t * cmd, int mode) 509 { 510 int nbox = cmd->num_cliprects; 511 int i = 0, count, ret; 512 513 if (cmd->sz & 0x3) { 514 DRM_ERROR("alignment"); 515 return DRM_ERR(EINVAL); 516 } 517 518 i915_kernel_lost_context(dev); 519 520 count = nbox ? nbox : 1; 521 522 for (i = 0; i < count; i++) { 523 if (i < nbox) { 524 ret = i915_emit_box(dev, cmd->cliprects, i, 525 cmd->DR1, cmd->DR4, mode); 526 if (ret) 527 return ret; 528 } 529 530 ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4, mode); 531 if (ret) 532 return ret; 533 } 534 535 i915_emit_breadcrumb( dev ); 536 return 0; 537 } 538 539 static int i915_dispatch_batchbuffer(drm_device_t * dev, 540 drm_i915_batchbuffer_t * batch, int mode) 541 { 542 drm_i915_private_t *dev_priv = dev->dev_private; 543 drm_clip_rect_t __user *boxes = batch->cliprects; 544 int nbox = batch->num_cliprects; 545 int i = 0, count; 546 RING_LOCALS; 547 548 if ((batch->start | batch->used) & 0x7) { 549 DRM_ERROR("alignment"); 550 return DRM_ERR(EINVAL); 551 } 552 553 i915_kernel_lost_context(dev); 554 555 count = nbox ? nbox : 1; 556 557 for (i = 0; i < count; i++) { 558 if (i < nbox) { 559 int ret = i915_emit_box(dev, boxes, i, 560 batch->DR1, batch->DR4, mode); 561 if (ret) 562 return ret; 563 } 564 565 if (dev_priv->use_mi_batchbuffer_start) { 566 BEGIN_LP_RING(2); 567 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); 568 OUT_RING(batch->start | MI_BATCH_NON_SECURE); 569 ADVANCE_LP_RING(); 570 } else { 571 BEGIN_LP_RING(4); 572 OUT_RING(MI_BATCH_BUFFER); 573 OUT_RING(batch->start | MI_BATCH_NON_SECURE); 574 OUT_RING(batch->start + batch->used - 4); 575 OUT_RING(0); 576 ADVANCE_LP_RING(); 577 } 578 } 579 580 i915_emit_breadcrumb( dev ); 581 582 return 0; 583 } 584 585 static int i915_dispatch_flip(drm_device_t * dev) 586 { 587 drm_i915_private_t *dev_priv = dev->dev_private; 588 RING_LOCALS; 589 590 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 591 __FUNCTION__, 592 dev_priv->current_page, 593 dev_priv->sarea_priv->pf_current_page); 594 595 i915_kernel_lost_context(dev); 596 597 BEGIN_LP_RING(2); 598 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); 599 OUT_RING(0); 600 ADVANCE_LP_RING(); 601 602 BEGIN_LP_RING(6); 603 OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); 604 OUT_RING(0); 605 if (dev_priv->current_page == 0) { 606 OUT_RING(dev_priv->back_offset); 607 dev_priv->current_page = 1; 608 } else { 609 OUT_RING(dev_priv->front_offset); 610 dev_priv->current_page = 0; 611 } 612 OUT_RING(0); 613 ADVANCE_LP_RING(); 614 615 BEGIN_LP_RING(2); 616 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); 617 OUT_RING(0); 618 ADVANCE_LP_RING(); 619 620 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 621 622 BEGIN_LP_RING(4); 623 OUT_RING(CMD_STORE_DWORD_IDX); 624 OUT_RING(20); 625 OUT_RING(dev_priv->counter); 626 OUT_RING(0); 627 ADVANCE_LP_RING(); 628 #ifdef I915_HAVE_FENCE 629 drm_fence_flush_old(dev, 0, dev_priv->counter); 630 #endif 631 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 632 return 0; 633 } 634 635 static int i915_quiescent(drm_device_t * dev) 636 { 637 drm_i915_private_t *dev_priv = dev->dev_private; 638 639 i915_kernel_lost_context(dev); 640 return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); 641 } 642 643 /*ARGSUSED*/ 644 static int i915_flush_ioctl(DRM_IOCTL_ARGS) 645 { 646 DRM_DEVICE; 647 648 LOCK_TEST_WITH_RETURN(dev, filp); 649 650 return i915_quiescent(dev); 651 } 652 653 /*ARGSUSED*/ 654 static int i915_batchbuffer(DRM_IOCTL_ARGS) 655 { 656 DRM_DEVICE; 657 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 658 u32 *hw_status = dev_priv->hw_status_page; 659 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 660 dev_priv->sarea_priv; 661 drm_i915_batchbuffer_t batch; 662 int ret; 663 664 if (!dev_priv->allow_batchbuffer) { 665 DRM_ERROR("Batchbuffer ioctl disabled\n"); 666 return DRM_ERR(EINVAL); 667 } 668 669 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 670 drm_i915_batchbuffer32_t batchbuffer32_t; 671 672 DRM_COPY_FROM_USER_IOCTL(batchbuffer32_t, 673 (drm_i915_batchbuffer32_t __user *) data, 674 sizeof (drm_i915_batchbuffer32_t)); 675 676 batch.start = batchbuffer32_t.start; 677 batch.used = batchbuffer32_t.used; 678 batch.DR1 = batchbuffer32_t.DR1; 679 batch.DR4 = batchbuffer32_t.DR4; 680 batch.num_cliprects = batchbuffer32_t.num_cliprects; 681 batch.cliprects = (drm_clip_rect_t __user *) 682 (uintptr_t)batchbuffer32_t.cliprects; 683 } else 684 DRM_COPY_FROM_USER_IOCTL(batch, (drm_i915_batchbuffer_t __user *) data, 685 sizeof(batch)); 686 687 DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", 688 batch.start, batch.used, batch.num_cliprects); 689 690 LOCK_TEST_WITH_RETURN(dev, filp); 691 /* 692 693 if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects, 694 batch.num_cliprects * 695 sizeof(drm_clip_rect_t))) 696 return DRM_ERR(EFAULT); 697 */ 698 699 ret = i915_dispatch_batchbuffer(dev, &batch, mode); 700 701 sarea_priv->last_dispatch = (int)hw_status[5]; 702 return ret; 703 } 704 705 /*ARGSUSED*/ 706 static int i915_cmdbuffer(DRM_IOCTL_ARGS) 707 { 708 DRM_DEVICE; 709 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 710 u32 *hw_status = dev_priv->hw_status_page; 711 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 712 dev_priv->sarea_priv; 713 drm_i915_cmdbuffer_t cmdbuf; 714 int ret; 715 716 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 717 drm_i915_cmdbuffer32_t cmdbuffer32_t; 718 719 DRM_COPY_FROM_USER_IOCTL(cmdbuffer32_t, 720 (drm_i915_cmdbuffer32_t __user *) data, 721 sizeof (drm_i915_cmdbuffer32_t)); 722 723 cmdbuf.buf = (char __user *)(uintptr_t)cmdbuffer32_t.buf; 724 cmdbuf.sz = cmdbuffer32_t.sz; 725 cmdbuf.DR1 = cmdbuffer32_t.DR1; 726 cmdbuf.DR4 = cmdbuffer32_t.DR4; 727 cmdbuf.num_cliprects = cmdbuffer32_t.num_cliprects; 728 cmdbuf.cliprects = (drm_clip_rect_t __user *) 729 (uintptr_t)cmdbuffer32_t.cliprects; 730 } else 731 DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_i915_cmdbuffer_t __user *) data, 732 sizeof(cmdbuf)); 733 734 DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", 735 cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects); 736 737 LOCK_TEST_WITH_RETURN(dev, filp); 738 /* 739 740 if (cmdbuf.num_cliprects && 741 DRM_VERIFYAREA_READ(cmdbuf.cliprects, 742 cmdbuf.num_cliprects * 743 sizeof(drm_clip_rect_t))) { 744 DRM_ERROR("Fault accessing cliprects\n"); 745 return DRM_ERR(EFAULT); 746 } 747 */ 748 749 ret = i915_dispatch_cmdbuffer(dev, &cmdbuf, mode); 750 if (ret) { 751 DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); 752 return ret; 753 } 754 755 sarea_priv->last_dispatch = (int)hw_status[5]; 756 return 0; 757 } 758 759 static int i915_do_cleanup_pageflip(drm_device_t * dev) 760 { 761 drm_i915_private_t *dev_priv = dev->dev_private; 762 763 DRM_DEBUG("%s\n", __FUNCTION__); 764 if (dev_priv->current_page != 0) 765 (void) i915_dispatch_flip(dev); 766 767 return 0; 768 } 769 770 /*ARGSUSED*/ 771 static int i915_flip_bufs(DRM_IOCTL_ARGS) 772 { 773 DRM_DEVICE; 774 775 DRM_DEBUG("%s\n", __FUNCTION__); 776 777 LOCK_TEST_WITH_RETURN(dev, filp); 778 779 return i915_dispatch_flip(dev); 780 } 781 782 /*ARGSUSED*/ 783 static int i915_getparam(DRM_IOCTL_ARGS) 784 { 785 DRM_DEVICE; 786 drm_i915_private_t *dev_priv = dev->dev_private; 787 drm_i915_getparam_t param; 788 int value; 789 790 if (!dev_priv) { 791 DRM_ERROR("%s called with no initialization\n", __FUNCTION__); 792 return DRM_ERR(EINVAL); 793 } 794 795 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 796 drm_i915_getparam32_t getparam32_t; 797 798 DRM_COPY_FROM_USER_IOCTL(getparam32_t, 799 (drm_i915_getparam32_t __user *) data, 800 sizeof (drm_i915_getparam32_t)); 801 802 param.param = getparam32_t.param; 803 param.value = (int __user *)(uintptr_t)getparam32_t.value; 804 } else 805 DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_getparam_t __user *) data, 806 sizeof(param)); 807 808 switch (param.param) { 809 case I915_PARAM_IRQ_ACTIVE: 810 value = dev->irq ? 1 : 0; 811 break; 812 case I915_PARAM_ALLOW_BATCHBUFFER: 813 value = dev_priv->allow_batchbuffer ? 1 : 0; 814 break; 815 case I915_PARAM_LAST_DISPATCH: 816 value = READ_BREADCRUMB(dev_priv); 817 break; 818 default: 819 DRM_ERROR("Unknown parameter %d\n", param.param); 820 return DRM_ERR(EINVAL); 821 } 822 823 if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { 824 DRM_ERROR("i915_getparam failed\n"); 825 return DRM_ERR(EFAULT); 826 } 827 return 0; 828 } 829 830 /*ARGSUSED*/ 831 static int i915_setparam(DRM_IOCTL_ARGS) 832 { 833 DRM_DEVICE; 834 drm_i915_private_t *dev_priv = dev->dev_private; 835 drm_i915_setparam_t param; 836 837 if (!dev_priv) { 838 DRM_ERROR("%s called with no initialization\n", __FUNCTION__); 839 return DRM_ERR(EINVAL); 840 } 841 842 DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_setparam_t __user *) data, 843 sizeof(param)); 844 845 switch (param.param) { 846 case I915_SETPARAM_USE_MI_BATCHBUFFER_START: 847 dev_priv->use_mi_batchbuffer_start = param.value; 848 break; 849 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: 850 dev_priv->tex_lru_log_granularity = param.value; 851 break; 852 case I915_SETPARAM_ALLOW_BATCHBUFFER: 853 dev_priv->allow_batchbuffer = param.value; 854 break; 855 default: 856 DRM_ERROR("unknown parameter %d\n", param.param); 857 return DRM_ERR(EINVAL); 858 } 859 860 return 0; 861 } 862 863 /*ARGSUSED*/ 864 int i915_driver_load(drm_device_t *dev, unsigned long flags) 865 { 866 /* i915 has 4 more counters */ 867 dev->counters += 4; 868 dev->types[6] = _DRM_STAT_IRQ; 869 dev->types[7] = _DRM_STAT_PRIMARY; 870 dev->types[8] = _DRM_STAT_SECONDARY; 871 dev->types[9] = _DRM_STAT_DMA; 872 873 return 0; 874 } 875 876 void i915_driver_lastclose(drm_device_t * dev) 877 { 878 if (dev->dev_private) { 879 drm_i915_private_t *dev_priv = dev->dev_private; 880 i915_mem_takedown(&(dev_priv->agp_heap)); 881 } 882 (void) i915_dma_cleanup(dev); 883 } 884 885 void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) 886 { 887 if (dev->dev_private) { 888 drm_i915_private_t *dev_priv = dev->dev_private; 889 if (dev_priv->page_flipping) { 890 (void) i915_do_cleanup_pageflip(dev); 891 } 892 i915_mem_release(dev, filp, dev_priv->agp_heap); 893 } 894 } 895 896 extern drm_ioctl_desc_t i915_ioctls[]; 897 898 void i915_set_ioctl_desc(int n, drm_ioctl_t * func, 899 int auth_needed, int root_only, char *desc) 900 { 901 i915_ioctls[n].func = func; 902 i915_ioctls[n].auth_needed = auth_needed; 903 i915_ioctls[n].root_only = root_only; 904 i915_ioctls[n].desc = desc; 905 } 906 void 907 i915_init_ioctl_arrays(void) 908 { 909 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_INIT), 910 i915_dma_init, 1, 1, "i915_dma_init"); 911 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FLUSH), 912 i915_flush_ioctl, 1, 0, "i915_flush_ioctl"); 913 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FLIP), 914 i915_flip_bufs, 1, 0, "i915_flip_bufs"); 915 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_BATCHBUFFER), 916 i915_batchbuffer, 1, 0, "i915_batchbuffer"); 917 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_IRQ_EMIT), 918 i915_irq_emit, 1, 0, " i915_irq_emit"); 919 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_IRQ_WAIT), 920 i915_irq_wait, 1, 0, "i915_irq_wait"); 921 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_GETPARAM), 922 i915_getparam, 1, 0, "i915_getparam"); 923 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_SETPARAM), 924 i915_setparam, 1, 1, "i915_setparam"); 925 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_ALLOC), 926 i915_mem_alloc, 1, 0, "i915_mem_alloc"); 927 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FREE), 928 i915_mem_free, 1, 0, "i915_mem_free"); 929 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_INIT_HEAP), 930 i915_mem_init_heap, 1, 1, "i915_mem_init_heap"); 931 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_CMDBUFFER), 932 i915_cmdbuffer, 1, 0, "i915_cmdbuffer"); 933 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP), 934 i915_mem_destroy_heap, 1, 1, "i915_mem_destroy_heap"); 935 } 936 /** 937 * Determine if the device really is AGP or not. 938 * 939 * All Intel graphics chipsets are treated as AGP, even if they are really 940 * PCI-e. 941 * 942 * \param dev The device to be tested. 943 * 944 * \returns 945 * A value of 1 is always retured to indictate every i9x5 is AGP. 946 */ 947 /*ARGSUSED*/ 948 int i915_driver_device_is_agp(drm_device_t * dev) 949 { 950 return 1; 951 } 952