1 /*- 2 * Copyright (c) 2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: src/sys/pci/agp.c,v 1.3.2.4 2002/08/11 19:58:12 alc Exp $ 27 * $DragonFly: src/sys/dev/agp/agp.c,v 1.26 2006/12/22 23:26:14 swildner Exp $ 28 */ 29 30 #include "opt_bus.h" 31 #include "opt_pci.h" 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/device.h> 36 #include <sys/conf.h> 37 #include <sys/malloc.h> 38 #include <sys/kernel.h> 39 #include <sys/bus.h> 40 #include <sys/ioccom.h> 41 #include <sys/agpio.h> 42 #include <sys/lock.h> 43 #include <sys/proc.h> 44 #include <sys/rman.h> 45 46 #include <bus/pci/pcivar.h> 47 #include <bus/pci/pcireg.h> 48 #include "agppriv.h" 49 #include "agpvar.h" 50 #include "agpreg.h" 51 52 #include <vm/vm.h> 53 #include <vm/vm_object.h> 54 #include <vm/vm_page.h> 55 #include <vm/vm_pageout.h> 56 #include <vm/pmap.h> 57 58 #include <machine/md_var.h> 59 60 MODULE_VERSION(agp, 1); 61 62 MALLOC_DEFINE(M_AGP, "agp", "AGP data structures"); 63 64 #define CDEV_MAJOR 148 65 /* agp_drv.c */ 66 static d_open_t agp_open; 67 static d_close_t agp_close; 68 static d_ioctl_t agp_ioctl; 69 static d_mmap_t agp_mmap; 70 71 static struct dev_ops agp_ops = { 72 { "agp", CDEV_MAJOR, D_TTY }, 73 .d_open = agp_open, 74 .d_close = agp_close, 75 .d_ioctl = agp_ioctl, 76 .d_mmap = agp_mmap, 77 }; 78 79 static devclass_t agp_devclass; 80 #define KDEV2DEV(kdev) devclass_get_device(agp_devclass, minor(kdev)) 81 82 /* Helper functions for implementing chipset mini drivers. */ 83 84 void 85 agp_flush_cache(void) 86 { 87 #ifdef __i386__ 88 wbinvd(); 89 #endif 90 } 91 92 u_int8_t 93 agp_find_caps(device_t dev) 94 { 95 u_int32_t status; 96 u_int8_t ptr, next; 97 98 /* 99 * Check the CAP_LIST bit of the PCI status register first. 100 */ 101 status = pci_read_config(dev, PCIR_STATUS, 2); 102 if (!(status & 0x10)) 103 return 0; 104 105 /* 106 * Traverse the capabilities list. 107 */ 108 for (ptr = pci_read_config(dev, AGP_CAPPTR, 1); 109 ptr != 0; 110 ptr = next) { 111 u_int32_t capid = pci_read_config(dev, ptr, 4); 112 next = AGP_CAPID_GET_NEXT_PTR(capid); 113 114 /* 115 * If this capability entry ID is 2, then we are done. 116 */ 117 if (AGP_CAPID_GET_CAP_ID(capid) == 2) 118 return ptr; 119 } 120 121 return 0; 122 } 123 124 /* 125 * Find an AGP display device (if any). 126 */ 127 static device_t 128 agp_find_display(void) 129 { 130 devclass_t pci = devclass_find("pci"); 131 device_t bus, dev = 0; 132 device_t *kids; 133 int busnum, numkids, i; 134 135 for (busnum = 0; busnum < devclass_get_maxunit(pci); busnum++) { 136 bus = devclass_get_device(pci, busnum); 137 if (!bus) 138 continue; 139 device_get_children(bus, &kids, &numkids); 140 for (i = 0; i < numkids; i++) { 141 dev = kids[i]; 142 if (pci_get_class(dev) == PCIC_DISPLAY 143 && pci_get_subclass(dev) == PCIS_DISPLAY_VGA) 144 if (agp_find_caps(dev)) { 145 kfree(kids, M_TEMP); 146 return dev; 147 } 148 149 } 150 kfree(kids, M_TEMP); 151 } 152 153 return 0; 154 } 155 156 struct agp_gatt * 157 agp_alloc_gatt(device_t dev) 158 { 159 u_int32_t apsize = AGP_GET_APERTURE(dev); 160 u_int32_t entries = apsize >> AGP_PAGE_SHIFT; 161 struct agp_gatt *gatt; 162 163 if (bootverbose) 164 device_printf(dev, 165 "allocating GATT for aperture of size %dM\n", 166 apsize / (1024*1024)); 167 168 if (entries == 0) { 169 device_printf(dev, "bad aperture size\n"); 170 return NULL; 171 } 172 173 gatt = kmalloc(sizeof(struct agp_gatt), M_AGP, M_INTWAIT); 174 gatt->ag_entries = entries; 175 gatt->ag_virtual = contigmalloc(entries * sizeof(u_int32_t), M_AGP, 176 M_WAITOK, 0, ~0, PAGE_SIZE, 0); 177 if (!gatt->ag_virtual) { 178 if (bootverbose) 179 device_printf(dev, "contiguous allocation failed\n"); 180 kfree(gatt, M_AGP); 181 return 0; 182 } 183 bzero(gatt->ag_virtual, entries * sizeof(u_int32_t)); 184 gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual); 185 agp_flush_cache(); 186 187 return gatt; 188 } 189 190 void 191 agp_free_gatt(struct agp_gatt *gatt) 192 { 193 contigfree(gatt->ag_virtual, 194 gatt->ag_entries * sizeof(u_int32_t), M_AGP); 195 kfree(gatt, M_AGP); 196 } 197 198 static int agp_max[][2] = { 199 {0, 0}, 200 {32, 4}, 201 {64, 28}, 202 {128, 96}, 203 {256, 204}, 204 {512, 440}, 205 {1024, 942}, 206 {2048, 1920}, 207 {4096, 3932} 208 }; 209 #define agp_max_size (sizeof(agp_max) / sizeof(agp_max[0])) 210 211 int 212 agp_generic_attach(device_t dev) 213 { 214 struct agp_softc *sc = device_get_softc(dev); 215 int rid, memsize, i; 216 217 /* 218 * Find and map the aperture. 219 */ 220 rid = AGP_APBASE; 221 sc->as_aperture = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 222 0, ~0, 1, RF_ACTIVE); 223 if (!sc->as_aperture) 224 return ENOMEM; 225 226 /* 227 * Work out an upper bound for agp memory allocation. This 228 * uses a heurisitc table from the Linux driver. 229 */ 230 memsize = ptoa(Maxmem) >> 20; 231 for (i = 0; i < agp_max_size; i++) { 232 if (memsize <= agp_max[i][0]) 233 break; 234 } 235 if (i == agp_max_size) i = agp_max_size - 1; 236 sc->as_maxmem = agp_max[i][1] << 20U; 237 238 /* 239 * The lock is used to prevent re-entry to 240 * agp_generic_bind_memory() since that function can sleep. 241 */ 242 lockinit(&sc->as_lock, "agplk", 0, 0); 243 244 /* 245 * Initialise stuff for the userland device. 246 */ 247 agp_devclass = devclass_find("agp"); 248 TAILQ_INIT(&sc->as_memory); 249 sc->as_nextid = 1; 250 251 dev_ops_add(&agp_ops, -1, device_get_unit(dev)); 252 make_dev(&agp_ops, device_get_unit(dev), UID_ROOT, GID_WHEEL, 253 0600, "agpgart"); 254 255 return 0; 256 } 257 258 int 259 agp_generic_detach(device_t dev) 260 { 261 struct agp_softc *sc = device_get_softc(dev); 262 263 bus_release_resource(dev, SYS_RES_MEMORY, AGP_APBASE, sc->as_aperture); 264 agp_flush_cache(); 265 dev_ops_remove(&agp_ops, -1, device_get_unit(dev)); 266 return 0; 267 } 268 269 /* 270 * This does the enable logic for v3, with the same topology 271 * restrictions as in place for v2 -- one bus, one device on the bus. 272 */ 273 static int 274 agp_v3_enable(device_t dev, device_t mdev, u_int32_t mode) 275 { 276 u_int32_t tstatus, mstatus; 277 u_int32_t command; 278 int rq, sba, fw, rate, arqsz, cal; 279 280 tstatus = pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4); 281 mstatus = pci_read_config(mdev, agp_find_caps(mdev) + AGP_STATUS, 4); 282 283 /* Set RQ to the min of mode, tstatus and mstatus */ 284 rq = AGP_MODE_GET_RQ(mode); 285 if (AGP_MODE_GET_RQ(tstatus) < rq) 286 rq = AGP_MODE_GET_RQ(tstatus); 287 if (AGP_MODE_GET_RQ(mstatus) < rq) 288 rq = AGP_MODE_GET_RQ(mstatus); 289 290 /* 291 * ARQSZ - Set the value to the maximum one. 292 * Don't allow the mode register to override values. 293 */ 294 arqsz = AGP_MODE_GET_ARQSZ(mode); 295 if (AGP_MODE_GET_ARQSZ(tstatus) > rq) 296 rq = AGP_MODE_GET_ARQSZ(tstatus); 297 if (AGP_MODE_GET_ARQSZ(mstatus) > rq) 298 rq = AGP_MODE_GET_ARQSZ(mstatus); 299 300 /* Calibration cycle - don't allow override by mode register */ 301 cal = AGP_MODE_GET_CAL(tstatus); 302 if (AGP_MODE_GET_CAL(mstatus) < cal) 303 cal = AGP_MODE_GET_CAL(mstatus); 304 305 /* SBA must be supported for AGP v3. */ 306 sba = 1; 307 308 /* Set FW if all three support it. */ 309 fw = (AGP_MODE_GET_FW(tstatus) 310 & AGP_MODE_GET_FW(mstatus) 311 & AGP_MODE_GET_FW(mode)); 312 313 /* Figure out the max rate */ 314 rate = (AGP_MODE_GET_RATE(tstatus) 315 & AGP_MODE_GET_RATE(mstatus) 316 & AGP_MODE_GET_RATE(mode)); 317 if (rate & AGP_MODE_V3_RATE_8x) 318 rate = AGP_MODE_V3_RATE_8x; 319 else 320 rate = AGP_MODE_V3_RATE_4x; 321 if (bootverbose) 322 device_printf(dev, "Setting AGP v3 mode %d\n", rate * 4); 323 324 pci_write_config(dev, agp_find_caps(dev) + AGP_COMMAND, 0, 4); 325 326 /* Construct the new mode word and tell the hardware */ 327 command = AGP_MODE_SET_RQ(0, rq); 328 command = AGP_MODE_SET_ARQSZ(command, arqsz); 329 command = AGP_MODE_SET_CAL(command, cal); 330 command = AGP_MODE_SET_SBA(command, sba); 331 command = AGP_MODE_SET_FW(command, fw); 332 command = AGP_MODE_SET_RATE(command, rate); 333 command = AGP_MODE_SET_AGP(command, 1); 334 pci_write_config(dev, agp_find_caps(dev) + AGP_COMMAND, command, 4); 335 pci_write_config(mdev, agp_find_caps(mdev) + AGP_COMMAND, command, 4); 336 337 return 0; 338 } 339 340 static int 341 agp_v2_enable(device_t dev, device_t mdev, u_int32_t mode) 342 { 343 u_int32_t tstatus, mstatus; 344 u_int32_t command; 345 int rq, sba, fw, rate; 346 347 tstatus = pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4); 348 mstatus = pci_read_config(mdev, agp_find_caps(mdev) + AGP_STATUS, 4); 349 350 /* Set RQ to the min of mode, tstatus and mstatus */ 351 rq = AGP_MODE_GET_RQ(mode); 352 if (AGP_MODE_GET_RQ(tstatus) < rq) 353 rq = AGP_MODE_GET_RQ(tstatus); 354 if (AGP_MODE_GET_RQ(mstatus) < rq) 355 rq = AGP_MODE_GET_RQ(mstatus); 356 357 /* Set SBA if all three can deal with SBA */ 358 sba = (AGP_MODE_GET_SBA(tstatus) 359 & AGP_MODE_GET_SBA(mstatus) 360 & AGP_MODE_GET_SBA(mode)); 361 362 /* Similar for FW */ 363 fw = (AGP_MODE_GET_FW(tstatus) 364 & AGP_MODE_GET_FW(mstatus) 365 & AGP_MODE_GET_FW(mode)); 366 367 /* Figure out the max rate */ 368 rate = (AGP_MODE_GET_RATE(tstatus) 369 & AGP_MODE_GET_RATE(mstatus) 370 & AGP_MODE_GET_RATE(mode)); 371 if (rate & AGP_MODE_V2_RATE_4x) 372 rate = AGP_MODE_V2_RATE_4x; 373 else if (rate & AGP_MODE_V2_RATE_2x) 374 rate = AGP_MODE_V2_RATE_2x; 375 else 376 rate = AGP_MODE_V2_RATE_1x; 377 if (bootverbose) 378 device_printf(dev, "Setting AGP v2 mode %d\n", rate); 379 380 /* Construct the new mode word and tell the hardware */ 381 command = AGP_MODE_SET_RQ(0, rq); 382 command = AGP_MODE_SET_SBA(command, sba); 383 command = AGP_MODE_SET_FW(command, fw); 384 command = AGP_MODE_SET_RATE(command, rate); 385 command = AGP_MODE_SET_AGP(command, 1); 386 pci_write_config(dev, agp_find_caps(dev) + AGP_COMMAND, command, 4); 387 pci_write_config(mdev, agp_find_caps(mdev) + AGP_COMMAND, command, 4); 388 389 return 0; 390 } 391 392 int 393 agp_generic_enable(device_t dev, u_int32_t mode) 394 { 395 device_t mdev = agp_find_display(); 396 u_int32_t tstatus, mstatus; 397 398 if (!mdev) { 399 AGP_DPF("can't find display\n"); 400 return ENXIO; 401 } 402 403 tstatus = pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4); 404 mstatus = pci_read_config(mdev, agp_find_caps(mdev) + AGP_STATUS, 4); 405 406 /* 407 * Check display and bridge for AGP v3 support. AGP v3 allows 408 * more variety in topology than v2, e.g. multiple AGP devices 409 * attached to one bridge, or multiple AGP bridges in one 410 * system. This doesn't attempt to address those situations, 411 * but should work fine for a classic single AGP slot system 412 * with AGP v3. 413 */ 414 if (AGP_MODE_GET_MODE_3(tstatus) && AGP_MODE_GET_MODE_3(mstatus)) 415 return (agp_v3_enable(dev, mdev, mode)); 416 else 417 return (agp_v2_enable(dev, mdev, mode)); 418 } 419 420 struct agp_memory * 421 agp_generic_alloc_memory(device_t dev, int type, vm_size_t size) 422 { 423 struct agp_softc *sc = device_get_softc(dev); 424 struct agp_memory *mem; 425 426 if ((size & (AGP_PAGE_SIZE - 1)) != 0) 427 return 0; 428 429 if (sc->as_allocated + size > sc->as_maxmem) 430 return 0; 431 432 if (type != 0) { 433 kprintf("agp_generic_alloc_memory: unsupported type %d\n", 434 type); 435 return 0; 436 } 437 438 mem = kmalloc(sizeof *mem, M_AGP, M_INTWAIT); 439 mem->am_id = sc->as_nextid++; 440 mem->am_size = size; 441 mem->am_type = 0; 442 mem->am_obj = vm_object_allocate(OBJT_DEFAULT, atop(round_page(size))); 443 mem->am_physical = 0; 444 mem->am_offset = 0; 445 mem->am_is_bound = 0; 446 TAILQ_INSERT_TAIL(&sc->as_memory, mem, am_link); 447 sc->as_allocated += size; 448 449 return mem; 450 } 451 452 int 453 agp_generic_free_memory(device_t dev, struct agp_memory *mem) 454 { 455 struct agp_softc *sc = device_get_softc(dev); 456 457 if (mem->am_is_bound) 458 return EBUSY; 459 460 sc->as_allocated -= mem->am_size; 461 TAILQ_REMOVE(&sc->as_memory, mem, am_link); 462 vm_object_deallocate(mem->am_obj); 463 kfree(mem, M_AGP); 464 return 0; 465 } 466 467 int 468 agp_generic_bind_memory(device_t dev, struct agp_memory *mem, 469 vm_offset_t offset) 470 { 471 struct agp_softc *sc = device_get_softc(dev); 472 vm_offset_t i, j, k; 473 vm_page_t m; 474 int error; 475 476 lockmgr(&sc->as_lock, LK_EXCLUSIVE); 477 478 if (mem->am_is_bound) { 479 device_printf(dev, "memory already bound\n"); 480 lockmgr(&sc->as_lock, LK_RELEASE); 481 return EINVAL; 482 } 483 484 if (offset < 0 485 || (offset & (AGP_PAGE_SIZE - 1)) != 0 486 || offset + mem->am_size > AGP_GET_APERTURE(dev)) { 487 device_printf(dev, "binding memory at bad offset %#x,%#x,%#x\n", 488 (int) offset, (int)mem->am_size, 489 (int)AGP_GET_APERTURE(dev)); 490 kprintf("Check BIOS's aperature size vs X\n"); 491 lockmgr(&sc->as_lock, LK_RELEASE); 492 return EINVAL; 493 } 494 495 /* 496 * Bind the individual pages and flush the chipset's 497 * TLB. 498 */ 499 for (i = 0; i < mem->am_size; i += PAGE_SIZE) { 500 /* 501 * Find a page from the object and wire it 502 * down. This page will be mapped using one or more 503 * entries in the GATT (assuming that PAGE_SIZE >= 504 * AGP_PAGE_SIZE. If this is the first call to bind, 505 * the pages will be allocated and zeroed. 506 */ 507 m = vm_page_grab(mem->am_obj, OFF_TO_IDX(i), 508 VM_ALLOC_NORMAL | VM_ALLOC_ZERO | VM_ALLOC_RETRY); 509 if ((m->flags & PG_ZERO) == 0) 510 vm_page_zero_fill(m); 511 AGP_DPF("found page pa=%#x\n", VM_PAGE_TO_PHYS(m)); 512 vm_page_wire(m); 513 514 /* 515 * Install entries in the GATT, making sure that if 516 * AGP_PAGE_SIZE < PAGE_SIZE and mem->am_size is not 517 * aligned to PAGE_SIZE, we don't modify too many GATT 518 * entries. 519 */ 520 for (j = 0; j < PAGE_SIZE && i + j < mem->am_size; 521 j += AGP_PAGE_SIZE) { 522 vm_offset_t pa = VM_PAGE_TO_PHYS(m) + j; 523 AGP_DPF("binding offset %#x to pa %#x\n", 524 offset + i + j, pa); 525 error = AGP_BIND_PAGE(dev, offset + i + j, pa); 526 if (error) { 527 /* 528 * Bail out. Reverse all the mappings 529 * and unwire the pages. 530 */ 531 vm_page_wakeup(m); 532 for (k = 0; k < i + j; k += AGP_PAGE_SIZE) 533 AGP_UNBIND_PAGE(dev, offset + k); 534 for (k = 0; k <= i; k += PAGE_SIZE) { 535 m = vm_page_lookup(mem->am_obj, 536 OFF_TO_IDX(k)); 537 vm_page_unwire(m, 0); 538 } 539 lockmgr(&sc->as_lock, LK_RELEASE); 540 return error; 541 } 542 } 543 vm_page_wakeup(m); 544 } 545 546 /* 547 * Flush the cpu cache since we are providing a new mapping 548 * for these pages. 549 */ 550 agp_flush_cache(); 551 552 /* 553 * Make sure the chipset gets the new mappings. 554 */ 555 AGP_FLUSH_TLB(dev); 556 557 mem->am_offset = offset; 558 mem->am_is_bound = 1; 559 560 lockmgr(&sc->as_lock, LK_RELEASE); 561 562 return 0; 563 } 564 565 int 566 agp_generic_unbind_memory(device_t dev, struct agp_memory *mem) 567 { 568 struct agp_softc *sc = device_get_softc(dev); 569 vm_page_t m; 570 int i; 571 572 lockmgr(&sc->as_lock, LK_EXCLUSIVE); 573 574 if (!mem->am_is_bound) { 575 device_printf(dev, "memory is not bound\n"); 576 lockmgr(&sc->as_lock, LK_RELEASE); 577 return EINVAL; 578 } 579 580 581 /* 582 * Unbind the individual pages and flush the chipset's 583 * TLB. Unwire the pages so they can be swapped. 584 */ 585 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 586 AGP_UNBIND_PAGE(dev, mem->am_offset + i); 587 for (i = 0; i < mem->am_size; i += PAGE_SIZE) { 588 m = vm_page_lookup(mem->am_obj, atop(i)); 589 vm_page_unwire(m, 0); 590 } 591 592 agp_flush_cache(); 593 AGP_FLUSH_TLB(dev); 594 595 mem->am_offset = 0; 596 mem->am_is_bound = 0; 597 598 lockmgr(&sc->as_lock, LK_RELEASE); 599 600 return 0; 601 } 602 603 /* Helper functions for implementing user/kernel api */ 604 605 static int 606 agp_acquire_helper(device_t dev, enum agp_acquire_state state) 607 { 608 struct agp_softc *sc = device_get_softc(dev); 609 610 if (sc->as_state != AGP_ACQUIRE_FREE) 611 return EBUSY; 612 sc->as_state = state; 613 614 return 0; 615 } 616 617 static int 618 agp_release_helper(device_t dev, enum agp_acquire_state state) 619 { 620 struct agp_softc *sc = device_get_softc(dev); 621 622 if (sc->as_state == AGP_ACQUIRE_FREE) 623 return 0; 624 625 if (sc->as_state != state) 626 return EBUSY; 627 628 sc->as_state = AGP_ACQUIRE_FREE; 629 return 0; 630 } 631 632 static struct agp_memory * 633 agp_find_memory(device_t dev, int id) 634 { 635 struct agp_softc *sc = device_get_softc(dev); 636 struct agp_memory *mem; 637 638 AGP_DPF("searching for memory block %d\n", id); 639 TAILQ_FOREACH(mem, &sc->as_memory, am_link) { 640 AGP_DPF("considering memory block %d\n", mem->am_id); 641 if (mem->am_id == id) 642 return mem; 643 } 644 return 0; 645 } 646 647 /* Implementation of the userland ioctl api */ 648 649 static int 650 agp_info_user(device_t dev, agp_info *info) 651 { 652 struct agp_softc *sc = device_get_softc(dev); 653 654 bzero(info, sizeof *info); 655 info->bridge_id = pci_get_devid(dev); 656 info->agp_mode = 657 pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4); 658 info->aper_base = rman_get_start(sc->as_aperture); 659 info->aper_size = AGP_GET_APERTURE(dev) >> 20; 660 info->pg_total = info->pg_system = sc->as_maxmem >> AGP_PAGE_SHIFT; 661 info->pg_used = sc->as_allocated >> AGP_PAGE_SHIFT; 662 663 return 0; 664 } 665 666 static int 667 agp_setup_user(device_t dev, agp_setup *setup) 668 { 669 return AGP_ENABLE(dev, setup->agp_mode); 670 } 671 672 static int 673 agp_allocate_user(device_t dev, agp_allocate *alloc) 674 { 675 struct agp_memory *mem; 676 677 mem = AGP_ALLOC_MEMORY(dev, 678 alloc->type, 679 alloc->pg_count << AGP_PAGE_SHIFT); 680 if (mem) { 681 alloc->key = mem->am_id; 682 alloc->physical = mem->am_physical; 683 return 0; 684 } else { 685 return ENOMEM; 686 } 687 } 688 689 static int 690 agp_deallocate_user(device_t dev, int id) 691 { 692 struct agp_memory *mem = agp_find_memory(dev, id); 693 694 if (mem) { 695 AGP_FREE_MEMORY(dev, mem); 696 return 0; 697 } else { 698 return ENOENT; 699 } 700 } 701 702 static int 703 agp_bind_user(device_t dev, agp_bind *bind) 704 { 705 struct agp_memory *mem = agp_find_memory(dev, bind->key); 706 707 if (!mem) 708 return ENOENT; 709 710 return AGP_BIND_MEMORY(dev, mem, bind->pg_start << AGP_PAGE_SHIFT); 711 } 712 713 static int 714 agp_unbind_user(device_t dev, agp_unbind *unbind) 715 { 716 struct agp_memory *mem = agp_find_memory(dev, unbind->key); 717 718 if (!mem) 719 return ENOENT; 720 721 return AGP_UNBIND_MEMORY(dev, mem); 722 } 723 724 static int 725 agp_open(struct dev_open_args *ap) 726 { 727 cdev_t kdev = ap->a_head.a_dev; 728 device_t dev = KDEV2DEV(kdev); 729 struct agp_softc *sc = device_get_softc(dev); 730 731 if (!sc->as_isopen) { 732 sc->as_isopen = 1; 733 device_busy(dev); 734 } 735 736 return 0; 737 } 738 739 static int 740 agp_close(struct dev_close_args *ap) 741 { 742 cdev_t kdev = ap->a_head.a_dev; 743 device_t dev = KDEV2DEV(kdev); 744 struct agp_softc *sc = device_get_softc(dev); 745 struct agp_memory *mem; 746 747 /* 748 * Clear the GATT and force release on last close 749 */ 750 while ((mem = TAILQ_FIRST(&sc->as_memory)) != 0) { 751 if (mem->am_is_bound) 752 AGP_UNBIND_MEMORY(dev, mem); 753 AGP_FREE_MEMORY(dev, mem); 754 } 755 if (sc->as_state == AGP_ACQUIRE_USER) 756 agp_release_helper(dev, AGP_ACQUIRE_USER); 757 sc->as_isopen = 0; 758 device_unbusy(dev); 759 760 return 0; 761 } 762 763 static int 764 agp_ioctl(struct dev_ioctl_args *ap) 765 { 766 cdev_t kdev = ap->a_head.a_dev; 767 device_t dev = KDEV2DEV(kdev); 768 769 switch (ap->a_cmd) { 770 case AGPIOC_INFO: 771 return agp_info_user(dev, (agp_info *)ap->a_data); 772 773 case AGPIOC_ACQUIRE: 774 return agp_acquire_helper(dev, AGP_ACQUIRE_USER); 775 776 case AGPIOC_RELEASE: 777 return agp_release_helper(dev, AGP_ACQUIRE_USER); 778 779 case AGPIOC_SETUP: 780 return agp_setup_user(dev, (agp_setup *)ap->a_data); 781 782 case AGPIOC_ALLOCATE: 783 return agp_allocate_user(dev, (agp_allocate *)ap->a_data); 784 785 case AGPIOC_DEALLOCATE: 786 return agp_deallocate_user(dev, *(int *)ap->a_data); 787 788 case AGPIOC_BIND: 789 return agp_bind_user(dev, (agp_bind *)ap->a_data); 790 791 case AGPIOC_UNBIND: 792 return agp_unbind_user(dev, (agp_unbind *)ap->a_data); 793 794 } 795 796 return EINVAL; 797 } 798 799 static int 800 agp_mmap(struct dev_mmap_args *ap) 801 { 802 cdev_t kdev = ap->a_head.a_dev; 803 device_t dev = KDEV2DEV(kdev); 804 struct agp_softc *sc = device_get_softc(dev); 805 806 if (ap->a_offset > AGP_GET_APERTURE(dev)) 807 return EINVAL; 808 ap->a_result = atop(rman_get_start(sc->as_aperture) + ap->a_offset); 809 return(0); 810 } 811 812 /* Implementation of the kernel api */ 813 814 device_t 815 agp_find_device(void) 816 { 817 if (!agp_devclass) 818 return 0; 819 return devclass_get_device(agp_devclass, 0); 820 } 821 822 enum agp_acquire_state 823 agp_state(device_t dev) 824 { 825 struct agp_softc *sc = device_get_softc(dev); 826 return sc->as_state; 827 } 828 829 void 830 agp_get_info(device_t dev, struct agp_info *info) 831 { 832 struct agp_softc *sc = device_get_softc(dev); 833 834 info->ai_mode = 835 pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4); 836 info->ai_aperture_base = rman_get_start(sc->as_aperture); 837 info->ai_aperture_size = (rman_get_end(sc->as_aperture) 838 - rman_get_start(sc->as_aperture)) + 1; 839 info->ai_aperture_va = (vm_offset_t) rman_get_virtual(sc->as_aperture); 840 info->ai_memory_allowed = sc->as_maxmem; 841 info->ai_memory_used = sc->as_allocated; 842 } 843 844 int 845 agp_acquire(device_t dev) 846 { 847 return agp_acquire_helper(dev, AGP_ACQUIRE_KERNEL); 848 } 849 850 int 851 agp_release(device_t dev) 852 { 853 return agp_release_helper(dev, AGP_ACQUIRE_KERNEL); 854 } 855 856 int 857 agp_enable(device_t dev, u_int32_t mode) 858 { 859 return AGP_ENABLE(dev, mode); 860 } 861 862 void *agp_alloc_memory(device_t dev, int type, vm_size_t bytes) 863 { 864 return (void *) AGP_ALLOC_MEMORY(dev, type, bytes); 865 } 866 867 void agp_free_memory(device_t dev, void *handle) 868 { 869 struct agp_memory *mem = (struct agp_memory *) handle; 870 AGP_FREE_MEMORY(dev, mem); 871 } 872 873 int agp_bind_memory(device_t dev, void *handle, vm_offset_t offset) 874 { 875 struct agp_memory *mem = (struct agp_memory *) handle; 876 return AGP_BIND_MEMORY(dev, mem, offset); 877 } 878 879 int agp_unbind_memory(device_t dev, void *handle) 880 { 881 struct agp_memory *mem = (struct agp_memory *) handle; 882 return AGP_UNBIND_MEMORY(dev, mem); 883 } 884 885 void agp_memory_info(device_t dev, void *handle, struct 886 agp_memory_info *mi) 887 { 888 struct agp_memory *mem = (struct agp_memory *) handle; 889 890 mi->ami_size = mem->am_size; 891 mi->ami_physical = mem->am_physical; 892 mi->ami_offset = mem->am_offset; 893 mi->ami_is_bound = mem->am_is_bound; 894 } 895