36#include <sys/malloc.h>
37#include <sys/kernel.h>
38#include <sys/module.h>
41#include <sys/ioccom.h>
46#include <sys/rwlock.h>
51#include <dev/pci/pcivar.h>
52#include <dev/pci/pcireg.h>
55#include <vm/vm_extern.h>
56#include <vm/vm_kern.h>
57#include <vm/vm_param.h>
58#include <vm/vm_object.h>
59#include <vm/vm_page.h>
60#include <vm/vm_pageout.h>
63#include <machine/bus.h>
64#include <machine/resource.h>
78 .d_version = D_VERSION,
79 .d_flags = D_NEEDGIANT,
96 if (pci_find_cap(dev, PCIY_AGP, &capreg) != 0)
107 devclass_t pci = devclass_find(
"pci");
108 device_t bus, dev = 0;
110 int busnum, numkids, i;
112 for (busnum = 0; busnum < devclass_get_maxunit(pci); busnum++) {
113 bus = devclass_get_device(pci, busnum);
116 if (device_get_children(bus, &kids, &numkids) != 0)
118 for (i = 0; i < numkids; i++) {
120 if (pci_get_class(dev) == PCIC_DISPLAY
121 && pci_get_subclass(dev) == PCIS_DISPLAY_VGA)
137 u_int32_t apsize = AGP_GET_APERTURE(dev);
138 u_int32_t entries = apsize >> AGP_PAGE_SHIFT;
143 "allocating GATT for aperture of size %dM\n",
144 apsize / (1024*1024));
147 device_printf(dev,
"bad aperture size\n");
151 gatt = malloc(
sizeof(
struct agp_gatt), M_AGP, M_NOWAIT);
156 gatt->
ag_virtual = (
void *)kmem_alloc_contig(entries *
157 sizeof(u_int32_t), M_NOWAIT | M_ZERO, 0, ~0, PAGE_SIZE, 0,
158 VM_MEMATTR_WRITE_COMBINING);
161 device_printf(dev,
"contiguous allocation failed\n");
189#define AGP_MAX_SIZE nitems(agp_max)
200 struct agp_softc *sc = device_get_softc(dev);
208 struct make_dev_args mdargs;
209 struct agp_softc *sc = device_get_softc(dev);
222 sc->
as_aperture = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
232 memsize = ptoa(realmem) >> 20;
245 mtx_init(&sc->
as_lock,
"agp lock", NULL, MTX_DEF);
256 make_dev_args_init(&mdargs);
258 mdargs.mda_uid = UID_ROOT;
259 mdargs.mda_gid = GID_WHEEL;
260 mdargs.mda_mode = 0600;
261 mdargs.mda_si_drv1 = sc;
262 mdargs.mda_si_drv2 = NULL;
264 unit = device_get_unit(dev);
265 error = make_dev_s(&mdargs, &sc->
as_devnode,
"agpgart%d", unit);
271 (void)make_dev_alias_p(MAKEDEV_CHECKNAME,
284 struct agp_softc *sc = device_get_softc(dev);
294 struct agp_softc *sc = device_get_softc(dev);
318 struct agp_softc *sc = device_get_softc(dev);
330 u_int32_t current_aperture;
332 current_aperture = AGP_GET_APERTURE(dev);
346 u_int32_t tstatus, mstatus;
348 int rq, sba, fw, rate, arqsz, cal;
354 rq = AGP_MODE_GET_RQ(
mode);
355 if (AGP_MODE_GET_RQ(tstatus) < rq)
356 rq = AGP_MODE_GET_RQ(tstatus);
357 if (AGP_MODE_GET_RQ(mstatus) < rq)
358 rq = AGP_MODE_GET_RQ(mstatus);
364 arqsz = AGP_MODE_GET_ARQSZ(
mode);
365 if (AGP_MODE_GET_ARQSZ(tstatus) > rq)
366 rq = AGP_MODE_GET_ARQSZ(tstatus);
367 if (AGP_MODE_GET_ARQSZ(mstatus) > rq)
368 rq = AGP_MODE_GET_ARQSZ(mstatus);
371 cal = AGP_MODE_GET_CAL(tstatus);
372 if (AGP_MODE_GET_CAL(mstatus) < cal)
373 cal = AGP_MODE_GET_CAL(mstatus);
379 fw = (AGP_MODE_GET_FW(tstatus)
380 & AGP_MODE_GET_FW(mstatus)
381 & AGP_MODE_GET_FW(
mode));
384 rate = (AGP_MODE_GET_RATE(tstatus)
385 & AGP_MODE_GET_RATE(mstatus)
386 & AGP_MODE_GET_RATE(
mode));
387 if (rate & AGP_MODE_V3_RATE_8x)
388 rate = AGP_MODE_V3_RATE_8x;
390 rate = AGP_MODE_V3_RATE_4x;
392 device_printf(dev,
"Setting AGP v3 mode %d\n", rate * 4);
398 command = AGP_MODE_SET_RQ(0, rq);
399 command = AGP_MODE_SET_ARQSZ(command, arqsz);
400 command = AGP_MODE_SET_CAL(command, cal);
401 command = AGP_MODE_SET_SBA(command, sba);
402 command = AGP_MODE_SET_FW(command, fw);
403 command = AGP_MODE_SET_RATE(command, rate);
404 command = AGP_MODE_SET_MODE_3(command, 1);
405 command = AGP_MODE_SET_AGP(command, 1);
415 u_int32_t tstatus, mstatus;
417 int rq, sba, fw, rate;
423 rq = AGP_MODE_GET_RQ(
mode);
424 if (AGP_MODE_GET_RQ(tstatus) < rq)
425 rq = AGP_MODE_GET_RQ(tstatus);
426 if (AGP_MODE_GET_RQ(mstatus) < rq)
427 rq = AGP_MODE_GET_RQ(mstatus);
430 sba = (AGP_MODE_GET_SBA(tstatus)
431 & AGP_MODE_GET_SBA(mstatus)
432 & AGP_MODE_GET_SBA(
mode));
435 fw = (AGP_MODE_GET_FW(tstatus)
436 & AGP_MODE_GET_FW(mstatus)
437 & AGP_MODE_GET_FW(
mode));
440 rate = (AGP_MODE_GET_RATE(tstatus)
441 & AGP_MODE_GET_RATE(mstatus)
442 & AGP_MODE_GET_RATE(
mode));
443 if (rate & AGP_MODE_V2_RATE_4x)
444 rate = AGP_MODE_V2_RATE_4x;
445 else if (rate & AGP_MODE_V2_RATE_2x)
446 rate = AGP_MODE_V2_RATE_2x;
448 rate = AGP_MODE_V2_RATE_1x;
450 device_printf(dev,
"Setting AGP v2 mode %d\n", rate);
454 command = AGP_MODE_SET_RQ(0, rq);
455 command = AGP_MODE_SET_SBA(command, sba);
456 command = AGP_MODE_SET_FW(command, fw);
457 command = AGP_MODE_SET_RATE(command, rate);
458 command = AGP_MODE_SET_AGP(command, 1);
469 u_int32_t tstatus, mstatus;
472 AGP_DPF(
"can't find display\n");
487 if (AGP_MODE_GET_MODE_3(
mode) &&
488 AGP_MODE_GET_MODE_3(tstatus) &&
489 AGP_MODE_GET_MODE_3(mstatus))
498 struct agp_softc *sc = device_get_softc(dev);
501 if ((
size & (AGP_PAGE_SIZE - 1)) != 0)
508 printf(
"agp_generic_alloc_memory: unsupported type %d\n",
513 mem = malloc(
sizeof *
mem, M_AGP, M_WAITOK);
517 mem->
am_obj = vm_object_allocate(OBJT_DEFAULT, atop(round_page(
size)));
530 struct agp_softc *sc = device_get_softc(dev);
546 struct agp_softc *sc = device_get_softc(dev);
552 if ((
offset & (AGP_PAGE_SIZE - 1)) != 0 ||
554 device_printf(dev,
"binding memory at bad offset %#x\n",
565 for (i = 0; i <
mem->
am_size; i += PAGE_SIZE) {
573 m = vm_page_grab(
mem->
am_obj, OFF_TO_IDX(i),
574 VM_ALLOC_WIRED | VM_ALLOC_ZERO);
575 AGP_DPF(
"found page pa=%#jx\n", (uintmax_t)VM_PAGE_TO_PHYS(m));
582 device_printf(dev,
"memory already bound\n");
594 for (i = 0; i <
mem->
am_size; i += PAGE_SIZE) {
595 m = vm_page_lookup(
mem->
am_obj, OFF_TO_IDX(i));
603 for (j = 0; j < PAGE_SIZE && i + j <
mem->
am_size;
604 j += AGP_PAGE_SIZE) {
605 vm_offset_t pa = VM_PAGE_TO_PHYS(m) + j;
606 AGP_DPF(
"binding offset %#jx to pa %#jx\n",
607 (uintmax_t)
offset + i + j, (uintmax_t)pa);
608 error = AGP_BIND_PAGE(dev,
offset + i + j, pa);
614 for (k = 0; k < i + j; k += AGP_PAGE_SIZE)
615 AGP_UNBIND_PAGE(dev,
offset + k);
637 for (k = 0; k <
mem->
am_size; k += PAGE_SIZE) {
638 m = vm_page_lookup(
mem->
am_obj, OFF_TO_IDX(k));
641 vm_page_unwire(m, PQ_INACTIVE);
651 struct agp_softc *sc = device_get_softc(dev);
658 device_printf(dev,
"memory is not bound\n");
667 for (i = 0; i <
mem->
am_size; i += AGP_PAGE_SIZE)
673 for (i = 0; i <
mem->
am_size; i += PAGE_SIZE) {
674 m = vm_page_lookup(
mem->
am_obj, atop(i));
675 vm_page_unwire(m, PQ_INACTIVE);
692 struct agp_softc *sc = device_get_softc(dev);
704 struct agp_softc *sc = device_get_softc(dev);
719 struct agp_softc *sc = device_get_softc(dev);
722 AGP_DPF(
"searching for memory block %d\n",
id);
736 struct agp_softc *sc = device_get_softc(dev);
738 bzero(info,
sizeof *info);
739 info->bridge_id = pci_get_devid(dev);
746 info->aper_size = AGP_GET_APERTURE(dev) >> 20;
747 info->pg_total = info->pg_system = sc->
as_maxmem >> AGP_PAGE_SHIFT;
756 return AGP_ENABLE(dev, setup->agp_mode);
764 mem = AGP_ALLOC_MEMORY(dev,
766 alloc->pg_count << AGP_PAGE_SHIFT);
782 AGP_FREE_MEMORY(dev,
mem);
797 return AGP_BIND_MEMORY(dev,
mem, bind->pg_start << AGP_PAGE_SHIFT);
808 return AGP_UNBIND_MEMORY(dev,
mem);
815 return (AGP_CHIPSET_FLUSH(dev));
819agp_open(
struct cdev *kdev,
int oflags,
int devtype,
struct thread *td)
821 device_t dev = kdev->si_drv1;
822 struct agp_softc *sc = device_get_softc(dev);
833agp_close(
struct cdev *kdev,
int fflag,
int devtype,
struct thread *td)
835 device_t dev = kdev->si_drv1;
836 struct agp_softc *sc = device_get_softc(dev);
844 AGP_UNBIND_MEMORY(dev,
mem);
845 AGP_FREE_MEMORY(dev,
mem);
856agp_ioctl(
struct cdev *kdev, u_long cmd, caddr_t data,
int fflag,
struct thread *td)
858 device_t dev = kdev->si_drv1;
873 case AGPIOC_ALLOCATE:
876 case AGPIOC_DEALLOCATE:
885 case AGPIOC_CHIPSET_FLUSH:
894 int prot, vm_memattr_t *memattr)
896 device_t dev = kdev->si_drv1;
897 struct agp_softc *sc = device_get_softc(dev);
899 if (
offset > AGP_GET_APERTURE(dev))
912 device_t *children, child;
917 if (devclass_get_devices(
agp_devclass, &children, &count) != 0)
920 for (i = 0; i < count; i++) {
921 if (device_is_attached(children[i])) {
926 free(children, M_TEMP);
933 struct agp_softc *sc = device_get_softc(dev);
940 struct agp_softc *sc = device_get_softc(dev);
968 return AGP_ENABLE(dev,
mode);
973 return (
void *) AGP_ALLOC_MEMORY(dev,
type, bytes);
979 AGP_FREE_MEMORY(dev,
mem);
985 return AGP_BIND_MEMORY(dev,
mem,
offset);
991 return AGP_UNBIND_MEMORY(dev,
mem);
1010 vm_offset_t i, j, k, pa;
1014 if ((
size & (AGP_PAGE_SIZE - 1)) != 0 ||
1015 (
offset & (AGP_PAGE_SIZE - 1)) != 0)
1018 sc = device_get_softc(dev);
1021 for (i = 0; i <
size; i += PAGE_SIZE) {
1022 m = pages[OFF_TO_IDX(i)];
1023 KASSERT(vm_page_wired(m),
1024 (
"agp_bind_pages: page %p hasn't been wired", m));
1032 for (j = 0; j < PAGE_SIZE && i + j <
size; j += AGP_PAGE_SIZE) {
1033 pa = VM_PAGE_TO_PHYS(m) + j;
1034 AGP_DPF(
"binding offset %#jx to pa %#jx\n",
1035 (uintmax_t)
offset + i + j, (uintmax_t)pa);
1036 error = AGP_BIND_PAGE(dev,
offset + i + j, pa);
1041 for (k = 0; k < i + j; k += AGP_PAGE_SIZE)
1042 AGP_UNBIND_PAGE(dev,
offset + k);
1062 if ((
size & (AGP_PAGE_SIZE - 1)) != 0 ||
1063 (
offset & (AGP_PAGE_SIZE - 1)) != 0)
1066 sc = device_get_softc(dev);
1069 for (i = 0; i <
size; i += AGP_PAGE_SIZE)
1070 AGP_UNBIND_PAGE(dev,
offset + i);
static int agp_chipset_flush(device_t dev)
void agp_memory_info(device_t dev, void *handle, struct agp_memory_info *mi)
int agp_release(device_t dev)
static struct cdevsw agp_cdevsw
void agp_set_aperture_resource(device_t dev, int rid)
static device_t agp_find_display(void)
int agp_generic_set_aperture(device_t dev, u_int32_t aperture)
static int agp_v3_enable(device_t dev, device_t mdev, u_int32_t mode)
static int agp_bind_user(device_t dev, agp_bind *bind)
static u_int agp_max[][2]
static int agp_deallocate_user(device_t dev, int id)
static int agp_allocate_user(device_t dev, agp_allocate *alloc)
struct agp_memory * agp_generic_alloc_memory(device_t dev, int type, vm_size_t size)
int agp_bind_memory(device_t dev, void *handle, vm_offset_t offset)
device_t agp_find_device()
void agp_free_memory(device_t dev, void *handle)
int agp_generic_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset)
int agp_generic_unbind_memory(device_t dev, struct agp_memory *mem)
static int agp_v2_enable(device_t dev, device_t mdev, u_int32_t mode)
int agp_unbind_memory(device_t dev, void *handle)
static d_close_t agp_close
int agp_generic_detach(device_t dev)
static struct agp_memory * agp_find_memory(device_t dev, int id)
static int agp_info_user(device_t dev, agp_info *info)
int agp_generic_attach(device_t dev)
int agp_acquire(device_t dev)
int agp_generic_free_memory(device_t dev, struct agp_memory *mem)
static int agp_setup_user(device_t dev, agp_setup *setup)
u_int8_t agp_find_caps(device_t dev)
u_int32_t agp_generic_get_aperture(device_t dev)
void agp_free_res(device_t dev)
void agp_free_cdev(device_t dev)
void * agp_alloc_memory(device_t dev, int type, vm_size_t bytes)
void agp_free_gatt(struct agp_gatt *gatt)
enum agp_acquire_state agp_state(device_t dev)
void agp_get_info(device_t dev, struct agp_info *info)
int agp_bind_pages(device_t dev, vm_page_t *pages, vm_size_t size, vm_offset_t offset)
static devclass_t agp_devclass
static int agp_release_helper(device_t dev, enum agp_acquire_state state)
MALLOC_DEFINE(M_AGP, "agp", "AGP data structures")
int agp_unbind_pages(device_t dev, vm_size_t size, vm_offset_t offset)
static d_ioctl_t agp_ioctl
struct agp_gatt * agp_alloc_gatt(device_t dev)
static int agp_acquire_helper(device_t dev, enum agp_acquire_state state)
int agp_generic_enable(device_t dev, u_int32_t mode)
static int agp_unbind_user(device_t dev, agp_unbind *unbind)
int agp_enable(device_t dev, u_int32_t mode)
struct agp_memory * handle
vm_size_t ai_memory_allowed
vm_size_t ai_aperture_size
vm_offset_t ai_aperture_base
struct vm_object * am_obj
struct cdev * as_devalias
struct resource * as_aperture
enum agp_acquire_state as_state
struct agp_memory_list as_memory