agp.c (d9a447559bc04121f7c6682e64abe67efa154864) agp.c (89f6b8632cc94bca2738b4fcc26e1189ef4f5dde)
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

--- 27 unchanged lines hidden (view full) ---

36#include <sys/module.h>
37#include <sys/bus.h>
38#include <sys/conf.h>
39#include <sys/ioccom.h>
40#include <sys/agpio.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/proc.h>
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

--- 27 unchanged lines hidden (view full) ---

36#include <sys/module.h>
37#include <sys/bus.h>
38#include <sys/conf.h>
39#include <sys/ioccom.h>
40#include <sys/agpio.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/proc.h>
44#include <sys/rwlock.h>
44
45#include <dev/agp/agppriv.h>
46#include <dev/agp/agpvar.h>
47#include <dev/agp/agpreg.h>
48#include <dev/pci/pcivar.h>
49#include <dev/pci/pcireg.h>
50
51#include <vm/vm.h>

--- 487 unchanged lines hidden (view full) ---

539 return EINVAL;
540 }
541
542 /*
543 * Allocate the pages early, before acquiring the lock,
544 * because vm_page_grab() may sleep and we can't hold a mutex
545 * while sleeping.
546 */
45
46#include <dev/agp/agppriv.h>
47#include <dev/agp/agpvar.h>
48#include <dev/agp/agpreg.h>
49#include <dev/pci/pcivar.h>
50#include <dev/pci/pcireg.h>
51
52#include <vm/vm.h>

--- 487 unchanged lines hidden (view full) ---

540 return EINVAL;
541 }
542
543 /*
544 * Allocate the pages early, before acquiring the lock,
545 * because vm_page_grab() may sleep and we can't hold a mutex
546 * while sleeping.
547 */
547 VM_OBJECT_LOCK(mem->am_obj);
548 VM_OBJECT_WLOCK(mem->am_obj);
548 for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
549 /*
550 * Find a page from the object and wire it
551 * down. This page will be mapped using one or more
552 * entries in the GATT (assuming that PAGE_SIZE >=
553 * AGP_PAGE_SIZE. If this is the first call to bind,
554 * the pages will be allocated and zeroed.
555 */
556 m = vm_page_grab(mem->am_obj, OFF_TO_IDX(i),
557 VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
558 AGP_DPF("found page pa=%#jx\n", (uintmax_t)VM_PAGE_TO_PHYS(m));
559 }
549 for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
550 /*
551 * Find a page from the object and wire it
552 * down. This page will be mapped using one or more
553 * entries in the GATT (assuming that PAGE_SIZE >=
554 * AGP_PAGE_SIZE. If this is the first call to bind,
555 * the pages will be allocated and zeroed.
556 */
557 m = vm_page_grab(mem->am_obj, OFF_TO_IDX(i),
558 VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
559 AGP_DPF("found page pa=%#jx\n", (uintmax_t)VM_PAGE_TO_PHYS(m));
560 }
560 VM_OBJECT_UNLOCK(mem->am_obj);
561 VM_OBJECT_WUNLOCK(mem->am_obj);
561
562 mtx_lock(&sc->as_lock);
563
564 if (mem->am_is_bound) {
565 device_printf(dev, "memory already bound\n");
566 error = EINVAL;
562
563 mtx_lock(&sc->as_lock);
564
565 if (mem->am_is_bound) {
566 device_printf(dev, "memory already bound\n");
567 error = EINVAL;
567 VM_OBJECT_LOCK(mem->am_obj);
568 VM_OBJECT_WLOCK(mem->am_obj);
568 i = 0;
569 goto bad;
570 }
571
572 /*
573 * Bind the individual pages and flush the chipset's
574 * TLB.
575 */
569 i = 0;
570 goto bad;
571 }
572
573 /*
574 * Bind the individual pages and flush the chipset's
575 * TLB.
576 */
576 VM_OBJECT_LOCK(mem->am_obj);
577 VM_OBJECT_WLOCK(mem->am_obj);
577 for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
578 m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i));
579
580 /*
581 * Install entries in the GATT, making sure that if
582 * AGP_PAGE_SIZE < PAGE_SIZE and mem->am_size is not
583 * aligned to PAGE_SIZE, we don't modify too many GATT
584 * entries.

--- 11 unchanged lines hidden (view full) ---

596 */
597 for (k = 0; k < i + j; k += AGP_PAGE_SIZE)
598 AGP_UNBIND_PAGE(dev, offset + k);
599 goto bad;
600 }
601 }
602 vm_page_wakeup(m);
603 }
578 for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
579 m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i));
580
581 /*
582 * Install entries in the GATT, making sure that if
583 * AGP_PAGE_SIZE < PAGE_SIZE and mem->am_size is not
584 * aligned to PAGE_SIZE, we don't modify too many GATT
585 * entries.

--- 11 unchanged lines hidden (view full) ---

597 */
598 for (k = 0; k < i + j; k += AGP_PAGE_SIZE)
599 AGP_UNBIND_PAGE(dev, offset + k);
600 goto bad;
601 }
602 }
603 vm_page_wakeup(m);
604 }
604 VM_OBJECT_UNLOCK(mem->am_obj);
605 VM_OBJECT_WUNLOCK(mem->am_obj);
605
606 /*
607 * Flush the cpu cache since we are providing a new mapping
608 * for these pages.
609 */
610 agp_flush_cache();
611
612 /*

--- 4 unchanged lines hidden (view full) ---

617 mem->am_offset = offset;
618 mem->am_is_bound = 1;
619
620 mtx_unlock(&sc->as_lock);
621
622 return 0;
623bad:
624 mtx_unlock(&sc->as_lock);
606
607 /*
608 * Flush the cpu cache since we are providing a new mapping
609 * for these pages.
610 */
611 agp_flush_cache();
612
613 /*

--- 4 unchanged lines hidden (view full) ---

618 mem->am_offset = offset;
619 mem->am_is_bound = 1;
620
621 mtx_unlock(&sc->as_lock);
622
623 return 0;
624bad:
625 mtx_unlock(&sc->as_lock);
625 VM_OBJECT_LOCK_ASSERT(mem->am_obj, MA_OWNED);
626 VM_OBJECT_ASSERT_WLOCKED(mem->am_obj);
626 for (k = 0; k < mem->am_size; k += PAGE_SIZE) {
627 m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(k));
628 if (k >= i)
629 vm_page_wakeup(m);
630 vm_page_lock(m);
631 vm_page_unwire(m, 0);
632 vm_page_unlock(m);
633 }
627 for (k = 0; k < mem->am_size; k += PAGE_SIZE) {
628 m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(k));
629 if (k >= i)
630 vm_page_wakeup(m);
631 vm_page_lock(m);
632 vm_page_unwire(m, 0);
633 vm_page_unlock(m);
634 }
634 VM_OBJECT_UNLOCK(mem->am_obj);
635 VM_OBJECT_WUNLOCK(mem->am_obj);
635
636 return error;
637}
638
639int
640agp_generic_unbind_memory(device_t dev, struct agp_memory *mem)
641{
642 struct agp_softc *sc = device_get_softc(dev);

--- 10 unchanged lines hidden (view full) ---

653
654
655 /*
656 * Unbind the individual pages and flush the chipset's
657 * TLB. Unwire the pages so they can be swapped.
658 */
659 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
660 AGP_UNBIND_PAGE(dev, mem->am_offset + i);
636
637 return error;
638}
639
640int
641agp_generic_unbind_memory(device_t dev, struct agp_memory *mem)
642{
643 struct agp_softc *sc = device_get_softc(dev);

--- 10 unchanged lines hidden (view full) ---

654
655
656 /*
657 * Unbind the individual pages and flush the chipset's
658 * TLB. Unwire the pages so they can be swapped.
659 */
660 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
661 AGP_UNBIND_PAGE(dev, mem->am_offset + i);
661 VM_OBJECT_LOCK(mem->am_obj);
662 VM_OBJECT_WLOCK(mem->am_obj);
662 for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
663 m = vm_page_lookup(mem->am_obj, atop(i));
664 vm_page_lock(m);
665 vm_page_unwire(m, 0);
666 vm_page_unlock(m);
667 }
663 for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
664 m = vm_page_lookup(mem->am_obj, atop(i));
665 vm_page_lock(m);
666 vm_page_unwire(m, 0);
667 vm_page_unlock(m);
668 }
668 VM_OBJECT_UNLOCK(mem->am_obj);
669 VM_OBJECT_WUNLOCK(mem->am_obj);
669
670 agp_flush_cache();
671 AGP_FLUSH_TLB(dev);
672
673 mem->am_offset = 0;
674 mem->am_is_bound = 0;
675
676 mtx_unlock(&sc->as_lock);

--- 321 unchanged lines hidden ---
670
671 agp_flush_cache();
672 AGP_FLUSH_TLB(dev);
673
674 mem->am_offset = 0;
675 mem->am_is_bound = 0;
676
677 mtx_unlock(&sc->as_lock);

--- 321 unchanged lines hidden ---