Move the agp(4) driver from sys/pci to sys/dev/agp. __FreeBSD_version was

bumped to 800004 to note the change though userland apps should not be
affected since they use <sys/agpio.h> rather than the headers in
sys/dev/agp.

Discussed with:	anholt
Repocopy by:	simon
This commit is contained in:
John Baldwin 2007-11-12 21:51:38 +00:00
parent a4cc298ac9
commit dbac8ff400
36 changed files with 59 additions and 5942 deletions

View File

@ -423,6 +423,8 @@ dev/advansys/adw_pci.c optional adw pci
dev/advansys/adwcam.c optional adw
dev/advansys/adwlib.c optional adw
dev/advansys/adwmcode.c optional adw
dev/agp/agp.c optional agp pci
dev/agp/agp_if.m optional agp pci
dev/aha/aha.c optional aha
dev/aha/aha_isa.c optional aha isa
dev/aha/aha_mca.c optional aha mca
@ -2002,8 +2004,6 @@ opencrypto/deflate.c optional crypto
opencrypto/rmd160.c optional crypto | ipsec
opencrypto/skipjack.c optional crypto
opencrypto/xform.c optional crypto
pci/agp.c optional agp pci
pci/agp_if.m optional agp pci
pci/alpm.c optional alpm pci
pci/amdpm.c optional amdpm pci | nfpm pci
pci/amdsmb.c optional amdsmb pci

View File

@ -138,6 +138,9 @@ amd64/pci/pci_cfgreg.c optional pci
crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
dev/acpica/acpi_if.m standard
dev/agp/agp_amd64.c optional agp
dev/agp/agp_i810.c optional agp
dev/agp/agp_intel.c optional agp
dev/arcmsr/arcmsr.c optional arcmsr pci
dev/asmc/asmc.c optional asmc isa
dev/atkbdc/atkbd.c optional atkbd atkbdc
@ -205,9 +208,6 @@ dev/wpi/if_wpi.c optional wpi
isa/syscons_isa.c optional sc
isa/vga_isa.c optional vga
kern/link_elf_obj.c standard
pci/agp_amd64.c optional agp
pci/agp_i810.c optional agp
pci/agp_intel.c optional agp
#
# IA32 binary support
#

View File

@ -141,6 +141,15 @@ crypto/via/padlock.c optional padlock
crypto/via/padlock_cipher.c optional padlock
crypto/via/padlock_hash.c optional padlock
dev/advansys/adv_isa.c optional adv isa
dev/agp/agp_ali.c optional agp
dev/agp/agp_amd.c optional agp
dev/agp/agp_amd64.c optional agp
dev/agp/agp_ati.c optional agp
dev/agp/agp_i810.c optional agp
dev/agp/agp_intel.c optional agp
dev/agp/agp_nvidia.c optional agp
dev/agp/agp_sis.c optional agp
dev/agp/agp_via.c optional agp
dev/aic/aic_isa.c optional aic isa
dev/arcmsr/arcmsr.c optional arcmsr pci
dev/ar/if_ar.c optional ar
@ -447,15 +456,6 @@ libkern/qdivrem.c standard
libkern/ucmpdi2.c standard
libkern/udivdi3.c standard
libkern/umoddi3.c standard
pci/agp_ali.c optional agp
pci/agp_amd.c optional agp
pci/agp_amd64.c optional agp
pci/agp_ati.c optional agp
pci/agp_i810.c optional agp
pci/agp_intel.c optional agp
pci/agp_nvidia.c optional agp
pci/agp_sis.c optional agp
pci/agp_via.c optional agp
i386/xbox/xbox.c optional xbox
i386/xbox/xboxfb.c optional xboxfb
dev/fb/boot_font.c optional xboxfb

View File

@ -98,6 +98,13 @@ bf_enc.o optional crypto | ipsec \
compile-with "${CC} -c -I$S/crypto/blowfish/arch/i386 ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}" \
no-implicit-rule
crypto/des/arch/i386/des_enc.S optional crypto | ipsec | netsmb
dev/agp/agp_ali.c optional agp
dev/agp/agp_amd.c optional agp
dev/agp/agp_i810.c optional agp
dev/agp/agp_intel.c optional agp
dev/agp/agp_nvidia.c optional agp
dev/agp/agp_sis.c optional agp
dev/agp/agp_via.c optional agp
dev/aic/aic_cbus.c optional aic isa
dev/ar/if_ar.c optional ar
dev/ar/if_ar_pci.c optional ar pci
@ -340,10 +347,3 @@ pc98/pc98/canbus.c optional canbus
pc98/pc98/canbus_if.m optional canbus
pc98/pc98/machdep.c standard
pc98/pc98/pc98_machdep.c standard
pci/agp_ali.c optional agp
pci/agp_amd.c optional agp
pci/agp_i810.c optional agp
pci/agp_intel.c optional agp
pci/agp_nvidia.c optional agp
pci/agp_sis.c optional agp
pci/agp_via.c optional agp

View File

@ -321,7 +321,7 @@ ${_src}:
.endfor
.endif
MFILES?= dev/acpica/acpi_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \
MFILES?= dev/acpica/acpi_if.m dev/agp/agp_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \
dev/iicbus/iicbb_if.m dev/iicbus/iicbus_if.m \
dev/mmc/mmcbr_if.m dev/mmc/mmcbus_if.m \
dev/mii/miibus_if.m dev/ofw/ofw_bus_if.m \
@ -333,7 +333,7 @@ MFILES?= dev/acpica/acpi_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \
dev/sound/midi/synth_if.m dev/usb/usb_if.m isa/isa_if.m \
kern/bus_if.m kern/cpufreq_if.m kern/device_if.m kern/serdev_if.m \
libkern/iconv_converter_if.m opencrypto/cryptodev_if.m \
pc98/pc98/canbus_if.m pci/agp_if.m
pc98/pc98/canbus_if.m
.for _srcsrc in ${MFILES}
.for _ext in c h

View File

@ -42,11 +42,11 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpvar.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpvar.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -39,10 +39,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -39,10 +39,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -39,10 +39,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -41,10 +41,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -45,10 +45,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -32,7 +32,7 @@
# The AGP interface is used internally to the agp driver to isolate the
# differences between various AGP chipsets into chipset mini drivers. It
# should not be used outside the AGP driver. The kernel api for accessing
# AGP functionality is described in <pci/agpvar.h>
# AGP functionality is described in <dev/agp/agpvar.h>
#
INTERFACE agp;
@ -80,7 +80,7 @@ METHOD void flush_tlb {
#
# Enable the agp hardware with the relavent mode. The mode bits are
# defined in <pci/agpreg.h>
# defined in <dev/agp/agpreg.h>
#
METHOD int enable {
device_t dev;

View File

@ -39,10 +39,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -51,10 +51,10 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#endif
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -39,10 +39,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -39,10 +39,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/agp/agppriv.h>
#include <dev/agp/agpreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>

View File

@ -34,7 +34,7 @@
*/
#include <sys/agpio.h>
#include <pci/agpvar.h>
#include <dev/agp/agpvar.h>
#define AGP_DEBUGxx

View File

@ -87,7 +87,7 @@ int agp_release(device_t dev);
/*
* Enable the agp hardware with the relavent mode. The mode bits are
* defined in <pci/agpreg.h>
* defined in <dev/agp/agpreg.h>
*/
int agp_enable(device_t dev, u_int32_t mode);

View File

@ -77,7 +77,11 @@ typedef struct drm_file drm_file_t;
#if defined(__FreeBSD__)
#include <sys/rman.h>
#include <sys/memrange.h>
#if __FreeBSD_version >= 800004
#include <dev/agp/agpvar.h>
#else
#include <pci/agpvar.h>
#endif
#include <sys/agpio.h>
#if __FreeBSD_version >= 500000
#include <sys/mutex.h>

View File

@ -37,7 +37,11 @@ __FBSDID("$FreeBSD$");
#include "dev/drm/drmP.h"
#ifdef __FreeBSD__
#if __FreeBSD_version >= 800004
#include <dev/agp/agpreg.h>
#else
#include <pci/agpreg.h>
#endif
#include <dev/pci/pcireg.h>
#endif

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../pci
.PATH: ${.CURDIR}/../../dev/agp
KMOD= agp
SRCS= agp.c agp_if.c
@ -16,7 +16,7 @@ SRCS+= agp_amd64.c agp_i810.c
.endif
SRCS+= device_if.h bus_if.h agp_if.h pci_if.h
SRCS+= opt_bus.h
MFILES= kern/device_if.m kern/bus_if.m pci/agp_if.m dev/pci/pci_if.m
MFILES= kern/device_if.m kern/bus_if.m dev/agp/agp_if.m dev/pci/pci_if.m
WERROR=
EXPORT_SYMS= agp_find_device \

View File

@ -1,975 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/ioccom.h>
#include <sys/agpio.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpvar.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
#include <vm/pmap.h>
#include <machine/md_var.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
MODULE_VERSION(agp, 1);
MALLOC_DEFINE(M_AGP, "agp", "AGP data structures");
/* agp_drv.c */
static d_open_t agp_open;
static d_close_t agp_close;
static d_ioctl_t agp_ioctl;
static d_mmap_t agp_mmap;
static struct cdevsw agp_cdevsw = {
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
.d_open = agp_open,
.d_close = agp_close,
.d_ioctl = agp_ioctl,
.d_mmap = agp_mmap,
.d_name = "agp",
};
static devclass_t agp_devclass;
#define KDEV2DEV(kdev) devclass_get_device(agp_devclass, minor(kdev))
/* Helper functions for implementing chipset mini drivers. */
void
agp_flush_cache()
{
#if defined(__i386__) || defined(__amd64__)
wbinvd();
#endif
}
u_int8_t
agp_find_caps(device_t dev)
{
int capreg;
if (pci_find_extcap(dev, PCIY_AGP, &capreg) != 0)
capreg = 0;
return (capreg);
}
/*
* Find an AGP display device (if any).
*/
static device_t
agp_find_display(void)
{
devclass_t pci = devclass_find("pci");
device_t bus, dev = 0;
device_t *kids;
int busnum, numkids, i;
for (busnum = 0; busnum < devclass_get_maxunit(pci); busnum++) {
bus = devclass_get_device(pci, busnum);
if (!bus)
continue;
device_get_children(bus, &kids, &numkids);
for (i = 0; i < numkids; i++) {
dev = kids[i];
if (pci_get_class(dev) == PCIC_DISPLAY
&& pci_get_subclass(dev) == PCIS_DISPLAY_VGA)
if (agp_find_caps(dev)) {
free(kids, M_TEMP);
return dev;
}
}
free(kids, M_TEMP);
}
return 0;
}
struct agp_gatt *
agp_alloc_gatt(device_t dev)
{
u_int32_t apsize = AGP_GET_APERTURE(dev);
u_int32_t entries = apsize >> AGP_PAGE_SHIFT;
struct agp_gatt *gatt;
if (bootverbose)
device_printf(dev,
"allocating GATT for aperture of size %dM\n",
apsize / (1024*1024));
if (entries == 0) {
device_printf(dev, "bad aperture size\n");
return NULL;
}
gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
if (!gatt)
return 0;
gatt->ag_entries = entries;
gatt->ag_virtual = contigmalloc(entries * sizeof(u_int32_t), M_AGP, 0,
0, ~0, PAGE_SIZE, 0);
if (!gatt->ag_virtual) {
if (bootverbose)
device_printf(dev, "contiguous allocation failed\n");
free(gatt, M_AGP);
return 0;
}
bzero(gatt->ag_virtual, entries * sizeof(u_int32_t));
gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual);
agp_flush_cache();
return gatt;
}
void
agp_free_gatt(struct agp_gatt *gatt)
{
contigfree(gatt->ag_virtual,
gatt->ag_entries * sizeof(u_int32_t), M_AGP);
free(gatt, M_AGP);
}
static u_int agp_max[][2] = {
{0, 0},
{32, 4},
{64, 28},
{128, 96},
{256, 204},
{512, 440},
{1024, 942},
{2048, 1920},
{4096, 3932}
};
#define agp_max_size (sizeof(agp_max) / sizeof(agp_max[0]))
/**
* Sets the PCI resource which represents the AGP aperture.
*
* If not called, the default AGP aperture resource of AGP_APBASE will
* be used. Must be called before agp_generic_attach().
*/
void
agp_set_aperture_resource(device_t dev, int rid)
{
struct agp_softc *sc = device_get_softc(dev);
sc->as_aperture_rid = rid;
}
int
agp_generic_attach(device_t dev)
{
struct agp_softc *sc = device_get_softc(dev);
int i;
u_int memsize;
/*
* Find and map the aperture, RF_SHAREABLE for DRM but not RF_ACTIVE
* because the kernel doesn't need to map it.
*/
if (sc->as_aperture_rid == 0)
sc->as_aperture_rid = AGP_APBASE;
sc->as_aperture = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->as_aperture_rid, RF_SHAREABLE);
if (!sc->as_aperture)
return ENOMEM;
/*
* Work out an upper bound for agp memory allocation. This
* uses a heurisitc table from the Linux driver.
*/
memsize = ptoa(Maxmem) >> 20;
for (i = 0; i < agp_max_size; i++) {
if (memsize <= agp_max[i][0])
break;
}
if (i == agp_max_size) i = agp_max_size - 1;
sc->as_maxmem = agp_max[i][1] << 20U;
/*
* The lock is used to prevent re-entry to
* agp_generic_bind_memory() since that function can sleep.
*/
mtx_init(&sc->as_lock, "agp lock", NULL, MTX_DEF);
/*
* Initialise stuff for the userland device.
*/
agp_devclass = devclass_find("agp");
TAILQ_INIT(&sc->as_memory);
sc->as_nextid = 1;
sc->as_devnode = make_dev(&agp_cdevsw,
device_get_unit(dev),
UID_ROOT,
GID_WHEEL,
0600,
"agpgart");
return 0;
}
void
agp_free_cdev(device_t dev)
{
struct agp_softc *sc = device_get_softc(dev);
destroy_dev(sc->as_devnode);
}
void
agp_free_res(device_t dev)
{
struct agp_softc *sc = device_get_softc(dev);
bus_release_resource(dev, SYS_RES_MEMORY, sc->as_aperture_rid,
sc->as_aperture);
mtx_destroy(&sc->as_lock);
agp_flush_cache();
}
int
agp_generic_detach(device_t dev)
{
agp_free_cdev(dev);
agp_free_res(dev);
return 0;
}
/**
* Default AGP aperture size detection which simply returns the size of
* the aperture's PCI resource.
*/
int
agp_generic_get_aperture(device_t dev)
{
struct agp_softc *sc = device_get_softc(dev);
return rman_get_size(sc->as_aperture);
}
/**
* Default AGP aperture size setting function, which simply doesn't allow
* changes to resource size.
*/
int
agp_generic_set_aperture(device_t dev, u_int32_t aperture)
{
u_int32_t current_aperture;
current_aperture = AGP_GET_APERTURE(dev);
if (current_aperture != aperture)
return EINVAL;
else
return 0;
}
/*
* This does the enable logic for v3, with the same topology
* restrictions as in place for v2 -- one bus, one device on the bus.
*/
static int
agp_v3_enable(device_t dev, device_t mdev, u_int32_t mode)
{
u_int32_t tstatus, mstatus;
u_int32_t command;
int rq, sba, fw, rate, arqsz, cal;
tstatus = pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4);
mstatus = pci_read_config(mdev, agp_find_caps(mdev) + AGP_STATUS, 4);
/* Set RQ to the min of mode, tstatus and mstatus */
rq = AGP_MODE_GET_RQ(mode);
if (AGP_MODE_GET_RQ(tstatus) < rq)
rq = AGP_MODE_GET_RQ(tstatus);
if (AGP_MODE_GET_RQ(mstatus) < rq)
rq = AGP_MODE_GET_RQ(mstatus);
/*
* ARQSZ - Set the value to the maximum one.
* Don't allow the mode register to override values.
*/
arqsz = AGP_MODE_GET_ARQSZ(mode);
if (AGP_MODE_GET_ARQSZ(tstatus) > rq)
rq = AGP_MODE_GET_ARQSZ(tstatus);
if (AGP_MODE_GET_ARQSZ(mstatus) > rq)
rq = AGP_MODE_GET_ARQSZ(mstatus);
/* Calibration cycle - don't allow override by mode register */
cal = AGP_MODE_GET_CAL(tstatus);
if (AGP_MODE_GET_CAL(mstatus) < cal)
cal = AGP_MODE_GET_CAL(mstatus);
/* SBA must be supported for AGP v3. */
sba = 1;
/* Set FW if all three support it. */
fw = (AGP_MODE_GET_FW(tstatus)
& AGP_MODE_GET_FW(mstatus)
& AGP_MODE_GET_FW(mode));
/* Figure out the max rate */
rate = (AGP_MODE_GET_RATE(tstatus)
& AGP_MODE_GET_RATE(mstatus)
& AGP_MODE_GET_RATE(mode));
if (rate & AGP_MODE_V3_RATE_8x)
rate = AGP_MODE_V3_RATE_8x;
else
rate = AGP_MODE_V3_RATE_4x;
if (bootverbose)
device_printf(dev, "Setting AGP v3 mode %d\n", rate * 4);
pci_write_config(dev, agp_find_caps(dev) + AGP_COMMAND, 0, 4);
/* Construct the new mode word and tell the hardware */
command = 0;
command = AGP_MODE_SET_RQ(0, rq);
command = AGP_MODE_SET_ARQSZ(command, arqsz);
command = AGP_MODE_SET_CAL(command, cal);
command = AGP_MODE_SET_SBA(command, sba);
command = AGP_MODE_SET_FW(command, fw);
command = AGP_MODE_SET_RATE(command, rate);
command = AGP_MODE_SET_MODE_3(command, 1);
command = AGP_MODE_SET_AGP(command, 1);
pci_write_config(dev, agp_find_caps(dev) + AGP_COMMAND, command, 4);
pci_write_config(mdev, agp_find_caps(mdev) + AGP_COMMAND, command, 4);
return 0;
}
static int
agp_v2_enable(device_t dev, device_t mdev, u_int32_t mode)
{
u_int32_t tstatus, mstatus;
u_int32_t command;
int rq, sba, fw, rate;
tstatus = pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4);
mstatus = pci_read_config(mdev, agp_find_caps(mdev) + AGP_STATUS, 4);
/* Set RQ to the min of mode, tstatus and mstatus */
rq = AGP_MODE_GET_RQ(mode);
if (AGP_MODE_GET_RQ(tstatus) < rq)
rq = AGP_MODE_GET_RQ(tstatus);
if (AGP_MODE_GET_RQ(mstatus) < rq)
rq = AGP_MODE_GET_RQ(mstatus);
/* Set SBA if all three can deal with SBA */
sba = (AGP_MODE_GET_SBA(tstatus)
& AGP_MODE_GET_SBA(mstatus)
& AGP_MODE_GET_SBA(mode));
/* Similar for FW */
fw = (AGP_MODE_GET_FW(tstatus)
& AGP_MODE_GET_FW(mstatus)
& AGP_MODE_GET_FW(mode));
/* Figure out the max rate */
rate = (AGP_MODE_GET_RATE(tstatus)
& AGP_MODE_GET_RATE(mstatus)
& AGP_MODE_GET_RATE(mode));
if (rate & AGP_MODE_V2_RATE_4x)
rate = AGP_MODE_V2_RATE_4x;
else if (rate & AGP_MODE_V2_RATE_2x)
rate = AGP_MODE_V2_RATE_2x;
else
rate = AGP_MODE_V2_RATE_1x;
if (bootverbose)
device_printf(dev, "Setting AGP v2 mode %d\n", rate);
/* Construct the new mode word and tell the hardware */
command = 0;
command = AGP_MODE_SET_RQ(0, rq);
command = AGP_MODE_SET_SBA(command, sba);
command = AGP_MODE_SET_FW(command, fw);
command = AGP_MODE_SET_RATE(command, rate);
command = AGP_MODE_SET_AGP(command, 1);
pci_write_config(dev, agp_find_caps(dev) + AGP_COMMAND, command, 4);
pci_write_config(mdev, agp_find_caps(mdev) + AGP_COMMAND, command, 4);
return 0;
}
int
agp_generic_enable(device_t dev, u_int32_t mode)
{
device_t mdev = agp_find_display();
u_int32_t tstatus, mstatus;
if (!mdev) {
AGP_DPF("can't find display\n");
return ENXIO;
}
tstatus = pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4);
mstatus = pci_read_config(mdev, agp_find_caps(mdev) + AGP_STATUS, 4);
/*
* Check display and bridge for AGP v3 support. AGP v3 allows
* more variety in topology than v2, e.g. multiple AGP devices
* attached to one bridge, or multiple AGP bridges in one
* system. This doesn't attempt to address those situations,
* but should work fine for a classic single AGP slot system
* with AGP v3.
*/
if (AGP_MODE_GET_MODE_3(mode) &&
AGP_MODE_GET_MODE_3(tstatus) &&
AGP_MODE_GET_MODE_3(mstatus))
return (agp_v3_enable(dev, mdev, mode));
else
return (agp_v2_enable(dev, mdev, mode));
}
struct agp_memory *
agp_generic_alloc_memory(device_t dev, int type, vm_size_t size)
{
struct agp_softc *sc = device_get_softc(dev);
struct agp_memory *mem;
if ((size & (AGP_PAGE_SIZE - 1)) != 0)
return 0;
if (sc->as_allocated + size > sc->as_maxmem)
return 0;
if (type != 0) {
printf("agp_generic_alloc_memory: unsupported type %d\n",
type);
return 0;
}
mem = malloc(sizeof *mem, M_AGP, M_WAITOK);
mem->am_id = sc->as_nextid++;
mem->am_size = size;
mem->am_type = 0;
mem->am_obj = vm_object_allocate(OBJT_DEFAULT, atop(round_page(size)));
mem->am_physical = 0;
mem->am_offset = 0;
mem->am_is_bound = 0;
TAILQ_INSERT_TAIL(&sc->as_memory, mem, am_link);
sc->as_allocated += size;
return mem;
}
int
agp_generic_free_memory(device_t dev, struct agp_memory *mem)
{
struct agp_softc *sc = device_get_softc(dev);
if (mem->am_is_bound)
return EBUSY;
sc->as_allocated -= mem->am_size;
TAILQ_REMOVE(&sc->as_memory, mem, am_link);
vm_object_deallocate(mem->am_obj);
free(mem, M_AGP);
return 0;
}
int
agp_generic_bind_memory(device_t dev, struct agp_memory *mem,
vm_offset_t offset)
{
struct agp_softc *sc = device_get_softc(dev);
vm_offset_t i, j, k;
vm_page_t m;
int error;
/* Do some sanity checks first. */
if (offset < 0 || (offset & (AGP_PAGE_SIZE - 1)) != 0 ||
offset + mem->am_size > AGP_GET_APERTURE(dev)) {
device_printf(dev, "binding memory at bad offset %#x\n",
(int)offset);
return EINVAL;
}
/*
* Allocate the pages early, before acquiring the lock,
* because vm_page_grab() used with VM_ALLOC_RETRY may
* block and we can't hold a mutex while blocking.
*/
VM_OBJECT_LOCK(mem->am_obj);
for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
/*
* Find a page from the object and wire it
* down. This page will be mapped using one or more
* entries in the GATT (assuming that PAGE_SIZE >=
* AGP_PAGE_SIZE. If this is the first call to bind,
* the pages will be allocated and zeroed.
*/
m = vm_page_grab(mem->am_obj, OFF_TO_IDX(i),
VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
AGP_DPF("found page pa=%#x\n", VM_PAGE_TO_PHYS(m));
}
VM_OBJECT_UNLOCK(mem->am_obj);
mtx_lock(&sc->as_lock);
if (mem->am_is_bound) {
device_printf(dev, "memory already bound\n");
error = EINVAL;
VM_OBJECT_LOCK(mem->am_obj);
goto bad;
}
/*
* Bind the individual pages and flush the chipset's
* TLB.
*/
VM_OBJECT_LOCK(mem->am_obj);
for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i));
/*
* Install entries in the GATT, making sure that if
* AGP_PAGE_SIZE < PAGE_SIZE and mem->am_size is not
* aligned to PAGE_SIZE, we don't modify too many GATT
* entries.
*/
for (j = 0; j < PAGE_SIZE && i + j < mem->am_size;
j += AGP_PAGE_SIZE) {
vm_offset_t pa = VM_PAGE_TO_PHYS(m) + j;
AGP_DPF("binding offset %#x to pa %#x\n",
offset + i + j, pa);
error = AGP_BIND_PAGE(dev, offset + i + j, pa);
if (error) {
/*
* Bail out. Reverse all the mappings
* and unwire the pages.
*/
vm_page_wakeup(m);
for (k = 0; k < i + j; k += AGP_PAGE_SIZE)
AGP_UNBIND_PAGE(dev, offset + k);
goto bad;
}
}
vm_page_wakeup(m);
}
VM_OBJECT_UNLOCK(mem->am_obj);
/*
* Flush the cpu cache since we are providing a new mapping
* for these pages.
*/
agp_flush_cache();
/*
* Make sure the chipset gets the new mappings.
*/
AGP_FLUSH_TLB(dev);
mem->am_offset = offset;
mem->am_is_bound = 1;
mtx_unlock(&sc->as_lock);
return 0;
bad:
mtx_unlock(&sc->as_lock);
VM_OBJECT_LOCK_ASSERT(mem->am_obj, MA_OWNED);
for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i));
vm_page_lock_queues();
vm_page_unwire(m, 0);
vm_page_unlock_queues();
}
VM_OBJECT_UNLOCK(mem->am_obj);
return error;
}
int
agp_generic_unbind_memory(device_t dev, struct agp_memory *mem)
{
struct agp_softc *sc = device_get_softc(dev);
vm_page_t m;
int i;
mtx_lock(&sc->as_lock);
if (!mem->am_is_bound) {
device_printf(dev, "memory is not bound\n");
mtx_unlock(&sc->as_lock);
return EINVAL;
}
/*
* Unbind the individual pages and flush the chipset's
* TLB. Unwire the pages so they can be swapped.
*/
for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
AGP_UNBIND_PAGE(dev, mem->am_offset + i);
VM_OBJECT_LOCK(mem->am_obj);
for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
m = vm_page_lookup(mem->am_obj, atop(i));
vm_page_lock_queues();
vm_page_unwire(m, 0);
vm_page_unlock_queues();
}
VM_OBJECT_UNLOCK(mem->am_obj);
agp_flush_cache();
AGP_FLUSH_TLB(dev);
mem->am_offset = 0;
mem->am_is_bound = 0;
mtx_unlock(&sc->as_lock);
return 0;
}
/* Helper functions for implementing user/kernel api */
static int
agp_acquire_helper(device_t dev, enum agp_acquire_state state)
{
struct agp_softc *sc = device_get_softc(dev);
if (sc->as_state != AGP_ACQUIRE_FREE)
return EBUSY;
sc->as_state = state;
return 0;
}
static int
agp_release_helper(device_t dev, enum agp_acquire_state state)
{
struct agp_softc *sc = device_get_softc(dev);
if (sc->as_state == AGP_ACQUIRE_FREE)
return 0;
if (sc->as_state != state)
return EBUSY;
sc->as_state = AGP_ACQUIRE_FREE;
return 0;
}
static struct agp_memory *
agp_find_memory(device_t dev, int id)
{
struct agp_softc *sc = device_get_softc(dev);
struct agp_memory *mem;
AGP_DPF("searching for memory block %d\n", id);
TAILQ_FOREACH(mem, &sc->as_memory, am_link) {
AGP_DPF("considering memory block %d\n", mem->am_id);
if (mem->am_id == id)
return mem;
}
return 0;
}
/* Implementation of the userland ioctl api */
static int
agp_info_user(device_t dev, agp_info *info)
{
struct agp_softc *sc = device_get_softc(dev);
bzero(info, sizeof *info);
info->bridge_id = pci_get_devid(dev);
info->agp_mode =
pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4);
info->aper_base = rman_get_start(sc->as_aperture);
info->aper_size = AGP_GET_APERTURE(dev) >> 20;
info->pg_total = info->pg_system = sc->as_maxmem >> AGP_PAGE_SHIFT;
info->pg_used = sc->as_allocated >> AGP_PAGE_SHIFT;
return 0;
}
static int
agp_setup_user(device_t dev, agp_setup *setup)
{
return AGP_ENABLE(dev, setup->agp_mode);
}
static int
agp_allocate_user(device_t dev, agp_allocate *alloc)
{
struct agp_memory *mem;
mem = AGP_ALLOC_MEMORY(dev,
alloc->type,
alloc->pg_count << AGP_PAGE_SHIFT);
if (mem) {
alloc->key = mem->am_id;
alloc->physical = mem->am_physical;
return 0;
} else {
return ENOMEM;
}
}
static int
agp_deallocate_user(device_t dev, int id)
{
struct agp_memory *mem = agp_find_memory(dev, id);;
if (mem) {
AGP_FREE_MEMORY(dev, mem);
return 0;
} else {
return ENOENT;
}
}
static int
agp_bind_user(device_t dev, agp_bind *bind)
{
struct agp_memory *mem = agp_find_memory(dev, bind->key);
if (!mem)
return ENOENT;
return AGP_BIND_MEMORY(dev, mem, bind->pg_start << AGP_PAGE_SHIFT);
}
static int
agp_unbind_user(device_t dev, agp_unbind *unbind)
{
struct agp_memory *mem = agp_find_memory(dev, unbind->key);
if (!mem)
return ENOENT;
return AGP_UNBIND_MEMORY(dev, mem);
}
static int
agp_open(struct cdev *kdev, int oflags, int devtype, struct thread *td)
{
device_t dev = KDEV2DEV(kdev);
struct agp_softc *sc = device_get_softc(dev);
if (!sc->as_isopen) {
sc->as_isopen = 1;
device_busy(dev);
}
return 0;
}
static int
agp_close(struct cdev *kdev, int fflag, int devtype, struct thread *td)
{
device_t dev = KDEV2DEV(kdev);
struct agp_softc *sc = device_get_softc(dev);
struct agp_memory *mem;
/*
* Clear the GATT and force release on last close
*/
while ((mem = TAILQ_FIRST(&sc->as_memory)) != 0) {
if (mem->am_is_bound)
AGP_UNBIND_MEMORY(dev, mem);
AGP_FREE_MEMORY(dev, mem);
}
if (sc->as_state == AGP_ACQUIRE_USER)
agp_release_helper(dev, AGP_ACQUIRE_USER);
sc->as_isopen = 0;
device_unbusy(dev);
return 0;
}
static int
agp_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int fflag, struct thread *td)
{
device_t dev = KDEV2DEV(kdev);
switch (cmd) {
case AGPIOC_INFO:
return agp_info_user(dev, (agp_info *) data);
case AGPIOC_ACQUIRE:
return agp_acquire_helper(dev, AGP_ACQUIRE_USER);
case AGPIOC_RELEASE:
return agp_release_helper(dev, AGP_ACQUIRE_USER);
case AGPIOC_SETUP:
return agp_setup_user(dev, (agp_setup *)data);
case AGPIOC_ALLOCATE:
return agp_allocate_user(dev, (agp_allocate *)data);
case AGPIOC_DEALLOCATE:
return agp_deallocate_user(dev, *(int *) data);
case AGPIOC_BIND:
return agp_bind_user(dev, (agp_bind *)data);
case AGPIOC_UNBIND:
return agp_unbind_user(dev, (agp_unbind *)data);
}
return EINVAL;
}
static int
agp_mmap(struct cdev *kdev, vm_offset_t offset, vm_paddr_t *paddr, int prot)
{
device_t dev = KDEV2DEV(kdev);
struct agp_softc *sc = device_get_softc(dev);
if (offset > AGP_GET_APERTURE(dev))
return -1;
*paddr = rman_get_start(sc->as_aperture) + offset;
return 0;
}
/* Implementation of the kernel api */
device_t
agp_find_device()
{
device_t *children, child;
int i, count;
if (!agp_devclass)
return NULL;
if (devclass_get_devices(agp_devclass, &children, &count) != 0)
return NULL;
child = NULL;
for (i = 0; i < count; i++) {
if (device_is_attached(children[i])) {
child = children[i];
break;
}
}
free(children, M_TEMP);
return child;
}
enum agp_acquire_state
agp_state(device_t dev)
{
struct agp_softc *sc = device_get_softc(dev);
return sc->as_state;
}
void
agp_get_info(device_t dev, struct agp_info *info)
{
struct agp_softc *sc = device_get_softc(dev);
info->ai_mode =
pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4);
info->ai_aperture_base = rman_get_start(sc->as_aperture);
info->ai_aperture_size = rman_get_size(sc->as_aperture);
info->ai_memory_allowed = sc->as_maxmem;
info->ai_memory_used = sc->as_allocated;
}
int
agp_acquire(device_t dev)
{
return agp_acquire_helper(dev, AGP_ACQUIRE_KERNEL);
}
int
agp_release(device_t dev)
{
return agp_release_helper(dev, AGP_ACQUIRE_KERNEL);
}
int
agp_enable(device_t dev, u_int32_t mode)
{
return AGP_ENABLE(dev, mode);
}
void *agp_alloc_memory(device_t dev, int type, vm_size_t bytes)
{
return (void *) AGP_ALLOC_MEMORY(dev, type, bytes);
}
void agp_free_memory(device_t dev, void *handle)
{
struct agp_memory *mem = (struct agp_memory *) handle;
AGP_FREE_MEMORY(dev, mem);
}
int agp_bind_memory(device_t dev, void *handle, vm_offset_t offset)
{
struct agp_memory *mem = (struct agp_memory *) handle;
return AGP_BIND_MEMORY(dev, mem, offset);
}
int agp_unbind_memory(device_t dev, void *handle)
{
struct agp_memory *mem = (struct agp_memory *) handle;
return AGP_UNBIND_MEMORY(dev, mem);
}
void agp_memory_info(device_t dev, void *handle, struct
agp_memory_info *mi)
{
struct agp_memory *mem = (struct agp_memory *) handle;
mi->ami_size = mem->am_size;
mi->ami_physical = mem->am_physical;
mi->ami_offset = mem->am_offset;
mi->ami_is_bound = mem->am_is_bound;
}

View File

@ -1,273 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/pmap.h>
struct agp_ali_softc {
struct agp_softc agp;
u_int32_t initial_aperture; /* aperture size at startup */
struct agp_gatt *gatt;
};
static const char*
agp_ali_match(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE
|| pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
return NULL;
if (agp_find_caps(dev) == 0)
return NULL;
switch (pci_get_devid(dev)) {
case 0x167110b9:
return ("Ali M1671 host to AGP bridge");
case 0x154110b9:
return ("Ali M1541 host to AGP bridge");
case 0x162110b9:
return ("Ali M1621 host to AGP bridge");
};
return NULL;
}
static int
agp_ali_probe(device_t dev)
{
const char *desc;
if (resource_disabled("agp", device_get_unit(dev)))
return (ENXIO);
desc = agp_ali_match(dev);
if (desc) {
device_set_desc(dev, desc);
return BUS_PROBE_DEFAULT;
}
return ENXIO;
}
static int
agp_ali_attach(device_t dev)
{
struct agp_ali_softc *sc = device_get_softc(dev);
struct agp_gatt *gatt;
int error;
u_int32_t attbase;
error = agp_generic_attach(dev);
if (error)
return error;
sc->initial_aperture = AGP_GET_APERTURE(dev);
if (sc->initial_aperture == 0) {
device_printf(dev, "bad initial aperture size, disabling\n");
return ENXIO;
}
for (;;) {
gatt = agp_alloc_gatt(dev);
if (gatt)
break;
/*
* Probably contigmalloc failure. Try reducing the
* aperture so that the gatt size reduces.
*/
if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
agp_generic_detach(dev);
return ENOMEM;
}
}
sc->gatt = gatt;
/* Install the gatt. */
attbase = pci_read_config(dev, AGP_ALI_ATTBASE, 4);
pci_write_config(dev, AGP_ALI_ATTBASE, gatt->ag_physical |
(attbase & 0xfff), 4);
/* Enable the TLB. */
pci_write_config(dev, AGP_ALI_TLBCTRL, 0x10, 1);
return 0;
}
static int
agp_ali_detach(device_t dev)
{
struct agp_ali_softc *sc = device_get_softc(dev);
u_int32_t attbase;
agp_free_cdev(dev);
/* Disable the TLB.. */
pci_write_config(dev, AGP_ALI_TLBCTRL, 0x90, 1);
/* Put the aperture back the way it started. */
AGP_SET_APERTURE(dev, sc->initial_aperture);
attbase = pci_read_config(dev, AGP_ALI_ATTBASE, 4);
pci_write_config(dev, AGP_ALI_ATTBASE, attbase & 0xfff, 4);
agp_free_gatt(sc->gatt);
agp_free_res(dev);
return 0;
}
#define M 1024*1024
static u_int32_t agp_ali_table[] = {
0, /* 0 - invalid */
1, /* 1 - invalid */
2, /* 2 - invalid */
4*M, /* 3 - invalid */
8*M, /* 4 - invalid */
0, /* 5 - invalid */
16*M, /* 6 - invalid */
32*M, /* 7 - invalid */
64*M, /* 8 - invalid */
128*M, /* 9 - invalid */
256*M, /* 10 - invalid */
};
#define agp_ali_table_size (sizeof(agp_ali_table) / sizeof(agp_ali_table[0]))
static u_int32_t
agp_ali_get_aperture(device_t dev)
{
/*
* The aperture size is derived from the low bits of attbase.
* I'm not sure this is correct..
*/
int i = pci_read_config(dev, AGP_ALI_ATTBASE, 4) & 0xf;
if (i >= agp_ali_table_size)
return 0;
return agp_ali_table[i];
}
static int
agp_ali_set_aperture(device_t dev, u_int32_t aperture)
{
int i;
u_int32_t attbase;
for (i = 0; i < agp_ali_table_size; i++)
if (agp_ali_table[i] == aperture)
break;
if (i == agp_ali_table_size)
return EINVAL;
attbase = pci_read_config(dev, AGP_ALI_ATTBASE, 4);
pci_write_config(dev, AGP_ALI_ATTBASE, (attbase & ~0xf) | i, 4);
return 0;
}
static int
agp_ali_bind_page(device_t dev, int offset, vm_offset_t physical)
{
struct agp_ali_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
return 0;
}
static int
agp_ali_unbind_page(device_t dev, int offset)
{
struct agp_ali_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
return 0;
}
static void
agp_ali_flush_tlb(device_t dev)
{
pci_write_config(dev, AGP_ALI_TLBCTRL, 0x90, 1);
pci_write_config(dev, AGP_ALI_TLBCTRL, 0x10, 1);
}
static device_method_t agp_ali_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_ali_probe),
DEVMETHOD(device_attach, agp_ali_attach),
DEVMETHOD(device_detach, agp_ali_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* AGP interface */
DEVMETHOD(agp_get_aperture, agp_ali_get_aperture),
DEVMETHOD(agp_set_aperture, agp_ali_set_aperture),
DEVMETHOD(agp_bind_page, agp_ali_bind_page),
DEVMETHOD(agp_unbind_page, agp_ali_unbind_page),
DEVMETHOD(agp_flush_tlb, agp_ali_flush_tlb),
DEVMETHOD(agp_enable, agp_generic_enable),
DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
DEVMETHOD(agp_free_memory, agp_generic_free_memory),
DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
{ 0, 0 }
};
static driver_t agp_ali_driver = {
"agp",
agp_ali_methods,
sizeof(struct agp_ali_softc),
};
static devclass_t agp_devclass;
DRIVER_MODULE(agp_ali, hostb, agp_ali_driver, agp_devclass, 0, 0);
MODULE_DEPEND(agp_ali, agp, 1, 1, 1);
MODULE_DEPEND(agp_ali, pci, 1, 1, 1);

View File

@ -1,417 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
MALLOC_DECLARE(M_AGP);
#define READ2(off) bus_space_read_2(sc->bst, sc->bsh, off)
#define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off)
#define WRITE2(off,v) bus_space_write_2(sc->bst, sc->bsh, off, v)
#define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v)
struct agp_amd_gatt {
u_int32_t ag_entries;
u_int32_t *ag_virtual; /* virtual address of gatt */
vm_offset_t ag_physical;
u_int32_t *ag_vdir; /* virtual address of page dir */
vm_offset_t ag_pdir; /* physical address of page dir */
};
struct agp_amd_softc {
struct agp_softc agp;
struct resource *regs; /* memory mapped control registers */
bus_space_tag_t bst; /* bus_space tag */
bus_space_handle_t bsh; /* bus_space handle */
u_int32_t initial_aperture; /* aperture size at startup */
struct agp_amd_gatt *gatt;
};
static struct agp_amd_gatt *
agp_amd_alloc_gatt(device_t dev)
{
u_int32_t apsize = AGP_GET_APERTURE(dev);
u_int32_t entries = apsize >> AGP_PAGE_SHIFT;
struct agp_amd_gatt *gatt;
int i, npages, pdir_offset;
if (bootverbose)
device_printf(dev,
"allocating GATT for aperture of size %dM\n",
apsize / (1024*1024));
gatt = malloc(sizeof(struct agp_amd_gatt), M_AGP, M_NOWAIT);
if (!gatt)
return 0;
/*
* The AMD751 uses a page directory to map a non-contiguous
* gatt so we don't need to use contigmalloc.
* Malloc individual gatt pages and map them into the page
* directory.
*/
gatt->ag_entries = entries;
gatt->ag_virtual = malloc(entries * sizeof(u_int32_t),
M_AGP, M_NOWAIT);
if (!gatt->ag_virtual) {
if (bootverbose)
device_printf(dev, "allocation failed\n");
free(gatt, M_AGP);
return 0;
}
bzero(gatt->ag_virtual, entries * sizeof(u_int32_t));
/*
* Allocate the page directory.
*/
gatt->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT);
if (!gatt->ag_vdir) {
if (bootverbose)
device_printf(dev,
"failed to allocate page directory\n");
free(gatt->ag_virtual, M_AGP);
free(gatt, M_AGP);
return 0;
}
bzero(gatt->ag_vdir, AGP_PAGE_SIZE);
gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir);
if(bootverbose)
device_printf(dev, "gatt -> ag_pdir %#lx\n",
(u_long)gatt->ag_pdir);
/*
* Allocate the gatt pages
*/
gatt->ag_entries = entries;
if(bootverbose)
device_printf(dev, "allocating GATT for %d AGP page entries\n",
gatt->ag_entries);
gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual);
/*
* Map the pages of the GATT into the page directory.
*
* The GATT page addresses are mapped into the directory offset by
* an amount dependent on the base address of the aperture. This
* is and offset into the page directory, not an offset added to
* the addresses of the gatt pages.
*/
pdir_offset = pci_read_config(dev, AGP_AMD751_APBASE, 4) >> 22;
npages = ((entries * sizeof(u_int32_t) + AGP_PAGE_SIZE - 1)
>> AGP_PAGE_SHIFT);
for (i = 0; i < npages; i++) {
vm_offset_t va;
vm_offset_t pa;
va = ((vm_offset_t) gatt->ag_virtual) + i * AGP_PAGE_SIZE;
pa = vtophys(va);
gatt->ag_vdir[i + pdir_offset] = pa | 1;
}
/*
* Make sure the chipset can see everything.
*/
agp_flush_cache();
return gatt;
}
static void
agp_amd_free_gatt(struct agp_amd_gatt *gatt)
{
free(gatt->ag_virtual, M_AGP);
free(gatt->ag_vdir, M_AGP);
free(gatt, M_AGP);
}
static const char*
agp_amd_match(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE
|| pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
return NULL;
if (agp_find_caps(dev) == 0)
return NULL;
switch (pci_get_devid(dev)) {
case 0x70061022:
return ("AMD 751 host to AGP bridge");
case 0x700e1022:
return ("AMD 761 host to AGP bridge");
case 0x700c1022:
return ("AMD 762 host to AGP bridge");
};
return NULL;
}
static int
agp_amd_probe(device_t dev)
{
const char *desc;
if (resource_disabled("agp", device_get_unit(dev)))
return (ENXIO);
desc = agp_amd_match(dev);
if (desc) {
device_set_desc(dev, desc);
return BUS_PROBE_DEFAULT;
}
return ENXIO;
}
static int
agp_amd_attach(device_t dev)
{
struct agp_amd_softc *sc = device_get_softc(dev);
struct agp_amd_gatt *gatt;
int error, rid;
error = agp_generic_attach(dev);
if (error)
return error;
rid = AGP_AMD751_REGISTERS;
sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->regs) {
agp_generic_detach(dev);
return ENOMEM;
}
sc->bst = rman_get_bustag(sc->regs);
sc->bsh = rman_get_bushandle(sc->regs);
sc->initial_aperture = AGP_GET_APERTURE(dev);
for (;;) {
gatt = agp_amd_alloc_gatt(dev);
if (gatt)
break;
/*
* Probably contigmalloc failure. Try reducing the
* aperture so that the gatt size reduces.
*/
if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2))
return ENOMEM;
}
sc->gatt = gatt;
/* Install the gatt. */
WRITE4(AGP_AMD751_ATTBASE, gatt->ag_pdir);
/* Enable synchronisation between host and agp. */
pci_write_config(dev,
AGP_AMD751_MODECTRL,
AGP_AMD751_MODECTRL_SYNEN, 1);
/* Set indexing mode for two-level and enable page dir cache */
pci_write_config(dev,
AGP_AMD751_MODECTRL2,
AGP_AMD751_MODECTRL2_GPDCE, 1);
/* Enable the TLB and flush */
WRITE2(AGP_AMD751_STATUS,
READ2(AGP_AMD751_STATUS) | AGP_AMD751_STATUS_GCE);
AGP_FLUSH_TLB(dev);
return 0;
}
static int
agp_amd_detach(device_t dev)
{
struct agp_amd_softc *sc = device_get_softc(dev);
agp_free_cdev(dev);
/* Disable the TLB.. */
WRITE2(AGP_AMD751_STATUS,
READ2(AGP_AMD751_STATUS) & ~AGP_AMD751_STATUS_GCE);
/* Disable host-agp sync */
pci_write_config(dev, AGP_AMD751_MODECTRL, 0x00, 1);
/* Clear the GATT base */
WRITE4(AGP_AMD751_ATTBASE, 0);
/* Put the aperture back the way it started. */
AGP_SET_APERTURE(dev, sc->initial_aperture);
agp_amd_free_gatt(sc->gatt);
agp_free_res(dev);
bus_release_resource(dev, SYS_RES_MEMORY,
AGP_AMD751_REGISTERS, sc->regs);
return 0;
}
static u_int32_t
agp_amd_get_aperture(device_t dev)
{
int vas;
/*
* The aperture size is equal to 32M<<vas.
*/
vas = (pci_read_config(dev, AGP_AMD751_APCTRL, 1) & 0x06) >> 1;
return (32*1024*1024) << vas;
}
static int
agp_amd_set_aperture(device_t dev, u_int32_t aperture)
{
int vas;
/*
* Check for a power of two and make sure its within the
* programmable range.
*/
if (aperture & (aperture - 1)
|| aperture < 32*1024*1024
|| aperture > 2U*1024*1024*1024)
return EINVAL;
vas = ffs(aperture / 32*1024*1024) - 1;
/*
* While the size register is bits 1-3 of APCTRL, bit 0 must be
* set for the size value to be 'valid'
*/
pci_write_config(dev, AGP_AMD751_APCTRL,
(((pci_read_config(dev, AGP_AMD751_APCTRL, 1) & ~0x06)
| ((vas << 1) | 1))), 1);
return 0;
}
static int
agp_amd_bind_page(device_t dev, int offset, vm_offset_t physical)
{
struct agp_amd_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 1;
/* invalidate the cache */
AGP_FLUSH_TLB(dev);
return 0;
}
static int
agp_amd_unbind_page(device_t dev, int offset)
{
struct agp_amd_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
return 0;
}
static void
agp_amd_flush_tlb(device_t dev)
{
struct agp_amd_softc *sc = device_get_softc(dev);
/* Set the cache invalidate bit and wait for the chipset to clear */
WRITE4(AGP_AMD751_TLBCTRL, 1);
do {
DELAY(1);
} while (READ4(AGP_AMD751_TLBCTRL));
}
static device_method_t agp_amd_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_amd_probe),
DEVMETHOD(device_attach, agp_amd_attach),
DEVMETHOD(device_detach, agp_amd_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* AGP interface */
DEVMETHOD(agp_get_aperture, agp_amd_get_aperture),
DEVMETHOD(agp_set_aperture, agp_amd_set_aperture),
DEVMETHOD(agp_bind_page, agp_amd_bind_page),
DEVMETHOD(agp_unbind_page, agp_amd_unbind_page),
DEVMETHOD(agp_flush_tlb, agp_amd_flush_tlb),
DEVMETHOD(agp_enable, agp_generic_enable),
DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
DEVMETHOD(agp_free_memory, agp_generic_free_memory),
DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
{ 0, 0 }
};
static driver_t agp_amd_driver = {
"agp",
agp_amd_methods,
sizeof(struct agp_amd_softc),
};
static devclass_t agp_devclass;
DRIVER_MODULE(agp_amd, hostb, agp_amd_driver, agp_devclass, 0, 0);
MODULE_DEPEND(agp_amd, agp, 1, 1, 1);
MODULE_DEPEND(agp_amd, pci, 1, 1, 1);

View File

@ -1,517 +0,0 @@
/*-
* Copyright (c) 2004, 2005 Jung-uk Kim <jkim@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
/* XXX */
extern void pci_cfgregwrite(int, int, int, int, uint32_t, int);
extern uint32_t pci_cfgregread(int, int, int, int, int);
static void agp_amd64_apbase_fixup(device_t);
static void agp_amd64_uli_init(device_t);
static int agp_amd64_uli_set_aperture(device_t, uint32_t);
static int agp_amd64_nvidia_match(uint16_t);
static void agp_amd64_nvidia_init(device_t);
static int agp_amd64_nvidia_set_aperture(device_t, uint32_t);
static int agp_amd64_via_match(void);
static void agp_amd64_via_init(device_t);
static int agp_amd64_via_set_aperture(device_t, uint32_t);
MALLOC_DECLARE(M_AGP);
#define AMD64_MAX_MCTRL 8
struct agp_amd64_softc {
struct agp_softc agp;
uint32_t initial_aperture;
struct agp_gatt *gatt;
uint32_t apbase;
int mctrl[AMD64_MAX_MCTRL];
int n_mctrl;
int via_agp;
};
static const char*
agp_amd64_match(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_HOST ||
agp_find_caps(dev) == 0)
return (NULL);
switch (pci_get_devid(dev)) {
case 0x74541022:
return ("AMD 8151 AGP graphics tunnel");
case 0x07551039:
return ("SiS 755 host to AGP bridge");
case 0x07601039:
return ("SiS 760 host to AGP bridge");
case 0x168910b9:
return ("ULi M1689 AGP Controller");
case 0x00d110de:
if (agp_amd64_nvidia_match(0x00d2))
return (NULL);
return ("NVIDIA nForce3 AGP Controller");
case 0x00e110de:
if (agp_amd64_nvidia_match(0x00e2))
return (NULL);
return ("NVIDIA nForce3-250 AGP Controller");
case 0x02041106:
return ("VIA 8380 host to PCI bridge");
case 0x02381106:
return ("VIA 3238 host to PCI bridge");
case 0x02821106:
return ("VIA K8T800Pro host to PCI bridge");
case 0x31881106:
return ("VIA 8385 host to PCI bridge");
};
return (NULL);
}
static int
agp_amd64_nvidia_match(uint16_t devid)
{
/* XXX nForce3 requires secondary AGP bridge at 0:11:0. */
if (pci_cfgregread(0, 11, 0, PCIR_CLASS, 1) != PCIC_BRIDGE ||
pci_cfgregread(0, 11, 0, PCIR_SUBCLASS, 1) != PCIS_BRIDGE_PCI ||
pci_cfgregread(0, 11, 0, PCIR_VENDOR, 2) != 0x10de ||
pci_cfgregread(0, 11, 0, PCIR_DEVICE, 2) != devid)
return (ENXIO);
return (0);
}
static int
agp_amd64_via_match(void)
{
/* XXX Some VIA bridge requires secondary AGP bridge at 0:1:0. */
if (pci_cfgregread(0, 1, 0, PCIR_CLASS, 1) != PCIC_BRIDGE ||
pci_cfgregread(0, 1, 0, PCIR_SUBCLASS, 1) != PCIS_BRIDGE_PCI ||
pci_cfgregread(0, 1, 0, PCIR_VENDOR, 2) != 0x1106 ||
pci_cfgregread(0, 1, 0, PCIR_DEVICE, 2) != 0xb188 ||
(pci_cfgregread(0, 1, 0, AGP_VIA_AGPSEL, 1) & 2))
return (0);
return (1);
}
static int
agp_amd64_probe(device_t dev)
{
const char *desc;
if (resource_disabled("agp", device_get_unit(dev)))
return (ENXIO);
if ((desc = agp_amd64_match(dev))) {
device_set_desc(dev, desc);
return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
static int
agp_amd64_attach(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
struct agp_gatt *gatt;
int i, n, error;
for (i = 0, n = 0; i < PCI_SLOTMAX && n < AMD64_MAX_MCTRL; i++)
if (pci_cfgregread(0, i, 3, 0, 4) == 0x11031022) {
sc->mctrl[n] = i;
n++;
}
if (n == 0)
return (ENXIO);
sc->n_mctrl = n;
if (bootverbose)
device_printf(dev, "%d Miscellaneous Control unit(s) found.\n",
sc->n_mctrl);
if ((error = agp_generic_attach(dev)))
return (error);
sc->initial_aperture = AGP_GET_APERTURE(dev);
for (;;) {
gatt = agp_alloc_gatt(dev);
if (gatt)
break;
/*
* Probably contigmalloc failure. Try reducing the
* aperture so that the gatt size reduces.
*/
if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
agp_generic_detach(dev);
return (ENOMEM);
}
}
sc->gatt = gatt;
switch (pci_get_vendor(dev)) {
case 0x10b9: /* ULi */
agp_amd64_uli_init(dev);
if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture))
return (ENXIO);
break;
case 0x10de: /* nVidia */
agp_amd64_nvidia_init(dev);
if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture))
return (ENXIO);
break;
case 0x1106: /* VIA */
sc->via_agp = agp_amd64_via_match();
if (sc->via_agp) {
agp_amd64_via_init(dev);
if (agp_amd64_via_set_aperture(dev,
sc->initial_aperture))
return (ENXIO);
}
break;
}
/* Install the gatt and enable aperture. */
for (i = 0; i < sc->n_mctrl; i++) {
pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_ATTBASE,
(uint32_t)(gatt->ag_physical >> 8) & AGP_AMD64_ATTBASE_MASK,
4);
pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_APCTRL,
(pci_cfgregread(0, sc->mctrl[i], 3, AGP_AMD64_APCTRL, 4) |
AGP_AMD64_APCTRL_GARTEN) &
~(AGP_AMD64_APCTRL_DISGARTCPU | AGP_AMD64_APCTRL_DISGARTIO),
4);
}
agp_flush_cache();
return (0);
}
static int
agp_amd64_detach(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
int i;
agp_free_cdev(dev);
for (i = 0; i < sc->n_mctrl; i++)
pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_APCTRL,
pci_cfgregread(0, sc->mctrl[i], 3, AGP_AMD64_APCTRL, 4) &
~AGP_AMD64_APCTRL_GARTEN, 4);
AGP_SET_APERTURE(dev, sc->initial_aperture);
agp_free_gatt(sc->gatt);
agp_free_res(dev);
return (0);
}
static uint32_t agp_amd64_table[] = {
0x02000000, /* 32 MB */
0x04000000, /* 64 MB */
0x08000000, /* 128 MB */
0x10000000, /* 256 MB */
0x20000000, /* 512 MB */
0x40000000, /* 1024 MB */
0x80000000, /* 2048 MB */
};
#define AGP_AMD64_TABLE_SIZE \
(sizeof(agp_amd64_table) / sizeof(agp_amd64_table[0]))
static uint32_t
agp_amd64_get_aperture(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
uint32_t i;
i = (pci_cfgregread(0, sc->mctrl[0], 3, AGP_AMD64_APCTRL, 4) &
AGP_AMD64_APCTRL_SIZE_MASK) >> 1;
if (i >= AGP_AMD64_TABLE_SIZE)
return (0);
return (agp_amd64_table[i]);
}
static int
agp_amd64_set_aperture(device_t dev, uint32_t aperture)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
uint32_t i;
int j;
for (i = 0; i < AGP_AMD64_TABLE_SIZE; i++)
if (agp_amd64_table[i] == aperture)
break;
if (i >= AGP_AMD64_TABLE_SIZE)
return (EINVAL);
for (j = 0; j < sc->n_mctrl; j++)
pci_cfgregwrite(0, sc->mctrl[j], 3, AGP_AMD64_APCTRL,
(pci_cfgregread(0, sc->mctrl[j], 3, AGP_AMD64_APCTRL, 4) &
~(AGP_AMD64_APCTRL_SIZE_MASK)) | (i << 1), 4);
switch (pci_get_vendor(dev)) {
case 0x10b9: /* ULi */
return (agp_amd64_uli_set_aperture(dev, aperture));
break;
case 0x10de: /* nVidia */
return (agp_amd64_nvidia_set_aperture(dev, aperture));
break;
case 0x1106: /* VIA */
if (sc->via_agp)
return (agp_amd64_via_set_aperture(dev, aperture));
break;
}
return (0);
}
static int
agp_amd64_bind_page(device_t dev, int offset, vm_offset_t physical)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return (EINVAL);
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] =
(physical & 0xfffff000) | ((physical >> 28) & 0x00000ff0) | 3;
return (0);
}
static int
agp_amd64_unbind_page(device_t dev, int offset)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return (EINVAL);
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
return (0);
}
static void
agp_amd64_flush_tlb(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
int i;
for (i = 0; i < sc->n_mctrl; i++)
pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_CACHECTRL,
pci_cfgregread(0, sc->mctrl[i], 3, AGP_AMD64_CACHECTRL, 4) |
AGP_AMD64_CACHECTRL_INVGART, 4);
}
static void
agp_amd64_apbase_fixup(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
uint32_t apbase;
int i;
sc->apbase = rman_get_start(sc->agp.as_aperture);
apbase = (sc->apbase >> 25) & AGP_AMD64_APBASE_MASK;
for (i = 0; i < sc->n_mctrl; i++)
pci_cfgregwrite(0, sc->mctrl[i], 3,
AGP_AMD64_APBASE, apbase, 4);
}
static void
agp_amd64_uli_init(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
agp_amd64_apbase_fixup(dev);
pci_write_config(dev, AGP_AMD64_ULI_APBASE,
(pci_read_config(dev, AGP_AMD64_ULI_APBASE, 4) & 0x0000000f) |
sc->apbase, 4);
pci_write_config(dev, AGP_AMD64_ULI_HTT_FEATURE, sc->apbase, 4);
}
static int
agp_amd64_uli_set_aperture(device_t dev, uint32_t aperture)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
switch (aperture) {
case 0x02000000: /* 32 MB */
case 0x04000000: /* 64 MB */
case 0x08000000: /* 128 MB */
case 0x10000000: /* 256 MB */
break;
default:
return (EINVAL);
}
pci_write_config(dev, AGP_AMD64_ULI_ENU_SCR,
sc->apbase + aperture - 1, 4);
return (0);
}
static void
agp_amd64_nvidia_init(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
agp_amd64_apbase_fixup(dev);
pci_write_config(dev, AGP_AMD64_NVIDIA_0_APBASE,
(pci_read_config(dev, AGP_AMD64_NVIDIA_0_APBASE, 4) & 0x0000000f) |
sc->apbase, 4);
pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APBASE1, sc->apbase, 4);
pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APBASE2, sc->apbase, 4);
}
static int
agp_amd64_nvidia_set_aperture(device_t dev, uint32_t aperture)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
uint32_t apsize;
switch (aperture) {
case 0x02000000: apsize = 0x0f; break; /* 32 MB */
case 0x04000000: apsize = 0x0e; break; /* 64 MB */
case 0x08000000: apsize = 0x0c; break; /* 128 MB */
case 0x10000000: apsize = 0x08; break; /* 256 MB */
case 0x20000000: apsize = 0x00; break; /* 512 MB */
default:
return (EINVAL);
}
pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APSIZE,
(pci_cfgregread(0, 11, 0, AGP_AMD64_NVIDIA_1_APSIZE, 4) &
0xfffffff0) | apsize, 4);
pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APLIMIT1,
sc->apbase + aperture - 1, 4);
pci_cfgregwrite(0, 11, 0, AGP_AMD64_NVIDIA_1_APLIMIT2,
sc->apbase + aperture - 1, 4);
return (0);
}
static void
agp_amd64_via_init(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
agp_amd64_apbase_fixup(dev);
pci_cfgregwrite(0, 1, 0, AGP3_VIA_ATTBASE, sc->gatt->ag_physical, 4);
pci_cfgregwrite(0, 1, 0, AGP3_VIA_GARTCTRL,
pci_cfgregread(0, 1, 0, AGP3_VIA_ATTBASE, 4) | 0x180, 4);
}
static int
agp_amd64_via_set_aperture(device_t dev, uint32_t aperture)
{
uint32_t apsize;
apsize = ((aperture - 1) >> 20) ^ 0xff;
if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture)
return (EINVAL);
pci_cfgregwrite(0, 1, 0, AGP3_VIA_APSIZE, apsize, 1);
return (0);
}
static device_method_t agp_amd64_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_amd64_probe),
DEVMETHOD(device_attach, agp_amd64_attach),
DEVMETHOD(device_detach, agp_amd64_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* AGP interface */
DEVMETHOD(agp_get_aperture, agp_amd64_get_aperture),
DEVMETHOD(agp_set_aperture, agp_amd64_set_aperture),
DEVMETHOD(agp_bind_page, agp_amd64_bind_page),
DEVMETHOD(agp_unbind_page, agp_amd64_unbind_page),
DEVMETHOD(agp_flush_tlb, agp_amd64_flush_tlb),
DEVMETHOD(agp_enable, agp_generic_enable),
DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
DEVMETHOD(agp_free_memory, agp_generic_free_memory),
DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
{ 0, 0 }
};
static driver_t agp_amd64_driver = {
"agp",
agp_amd64_methods,
sizeof(struct agp_amd64_softc),
};
static devclass_t agp_devclass;
DRIVER_MODULE(agp_amd64, hostb, agp_amd64_driver, agp_devclass, 0, 0);
MODULE_DEPEND(agp_amd64, agp, 1, 1, 1);
MODULE_DEPEND(agp_amd64, pci, 1, 1, 1);

View File

@ -1,386 +0,0 @@
/*-
* Copyright (c) 2005 Eric Anholt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Based on reading the Linux 2.6.8.1 driver by Dave Jones.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
MALLOC_DECLARE(M_AGP);
#define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off)
#define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v)
struct agp_ati_softc {
struct agp_softc agp;
struct resource *regs; /* memory mapped control registers */
bus_space_tag_t bst; /* bus_space tag */
bus_space_handle_t bsh; /* bus_space handle */
u_int32_t initial_aperture; /* aperture size at startup */
char is_rs300;
/* The GATT */
u_int32_t ag_entries;
u_int32_t *ag_virtual; /* virtual address of gatt */
u_int32_t *ag_vdir; /* virtual address of page dir */
vm_offset_t ag_pdir; /* physical address of page dir */
};
static const char*
agp_ati_match(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
return NULL;
if (agp_find_caps(dev) == 0)
return NULL;
switch (pci_get_devid(dev)) {
case 0xcab01002:
return ("ATI RS100 AGP bridge");
case 0xcab21002:
return ("ATI RS200 AGP bridge");
case 0xcbb21002:
return ("ATI RS200M AGP bridge");
case 0xcab31002:
return ("ATI RS250 AGP bridge");
case 0x58301002:
return ("ATI RS300_100 AGP bridge");
case 0x58311002:
return ("ATI RS300_133 AGP bridge");
case 0x58321002:
return ("ATI RS300_166 AGP bridge");
case 0x58331002:
return ("ATI RS300_200 AGP bridge");
};
return NULL;
}
static int
agp_ati_probe(device_t dev)
{
const char *desc;
desc = agp_ati_match(dev);
if (desc) {
device_set_desc(dev, desc);
return 0;
}
return ENXIO;
}
static int
agp_ati_alloc_gatt(device_t dev)
{
struct agp_ati_softc *sc = device_get_softc(dev);
u_int32_t apsize = AGP_GET_APERTURE(dev);
u_int32_t entries = apsize >> AGP_PAGE_SHIFT;
u_int32_t apbase_offset;
int i;
/* Alloc the GATT -- pointers to pages of AGP memory */
sc->ag_entries = entries;
sc->ag_virtual = malloc(entries * sizeof(u_int32_t), M_AGP,
M_NOWAIT | M_ZERO);
if (sc->ag_virtual == NULL) {
if (bootverbose)
device_printf(dev, "aperture allocation failed\n");
return ENOMEM;
}
/* Alloc the page directory -- pointers to each page of the GATT */
sc->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT | M_ZERO);
if (sc->ag_vdir == NULL) {
if (bootverbose)
device_printf(dev, "pagedir allocation failed\n");
free(sc->ag_virtual, M_AGP);
return ENOMEM;
}
sc->ag_pdir = vtophys((vm_offset_t)sc->ag_vdir);
apbase_offset = pci_read_config(dev, AGP_APBASE, 4) >> 22;
/* Fill in the pagedir's pointers to GATT pages */
for (i = 0; i < sc->ag_entries / 1024; i++) {
vm_offset_t va;
vm_offset_t pa;
va = ((vm_offset_t)sc->ag_virtual) + i * AGP_PAGE_SIZE;
pa = vtophys(va);
sc->ag_vdir[apbase_offset + i] = pa | 1;
}
/*
* Make sure the chipset can see everything.
*/
agp_flush_cache();
return 0;
}
static int
agp_ati_attach(device_t dev)
{
struct agp_ati_softc *sc = device_get_softc(dev);
int error, rid;
u_int32_t temp;
u_int32_t apsize_reg, agpmode_reg;
error = agp_generic_attach(dev);
if (error)
return error;
switch (pci_get_devid(dev)) {
case 0xcab01002: /* ATI RS100 AGP bridge */
case 0xcab21002: /* ATI RS200 AGP bridge */
case 0xcbb21002: /* ATI RS200M AGP bridge */
case 0xcab31002: /* ATI RS250 AGP bridge */
sc->is_rs300 = 0;
apsize_reg = ATI_RS100_APSIZE;
agpmode_reg = ATI_RS100_IG_AGPMODE;
break;
case 0x58301002: /* ATI RS300_100 AGP bridge */
case 0x58311002: /* ATI RS300_133 AGP bridge */
case 0x58321002: /* ATI RS300_166 AGP bridge */
case 0x58331002: /* ATI RS300_200 AGP bridge */
sc->is_rs300 = 1;
apsize_reg = ATI_RS300_APSIZE;
agpmode_reg = ATI_RS300_IG_AGPMODE;
break;
default:
/* Unknown chipset */
return EINVAL;
};
rid = ATI_GART_MMADDR;
sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (!sc->regs) {
agp_generic_detach(dev);
return ENOMEM;
}
sc->bst = rman_get_bustag(sc->regs);
sc->bsh = rman_get_bushandle(sc->regs);
sc->initial_aperture = AGP_GET_APERTURE(dev);
for (;;) {
if (agp_ati_alloc_gatt(dev) == 0)
break;
/*
* Probably contigmalloc failure. Try reducing the
* aperture so that the gatt size reduces.
*/
if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2))
return ENOMEM;
}
temp = pci_read_config(dev, apsize_reg, 4);
pci_write_config(dev, apsize_reg, temp | 1, 4);
pci_write_config(dev, agpmode_reg, 0x20000, 4);
WRITE4(ATI_GART_FEATURE_ID, 0x00060000);
temp = pci_read_config(dev, 4, 4); /* XXX: Magic reg# */
pci_write_config(dev, 4, temp | (1 << 14), 4);
WRITE4(ATI_GART_BASE, sc->ag_pdir);
AGP_FLUSH_TLB(dev);
return 0;
}
static int
agp_ati_detach(device_t dev)
{
struct agp_ati_softc *sc = device_get_softc(dev);
u_int32_t apsize_reg, temp;
agp_free_cdev(dev);
if (sc->is_rs300)
apsize_reg = ATI_RS300_APSIZE;
else
apsize_reg = ATI_RS100_APSIZE;
/* Clear the GATT base */
WRITE4(ATI_GART_BASE, 0);
/* Put the aperture back the way it started. */
AGP_SET_APERTURE(dev, sc->initial_aperture);
temp = pci_read_config(dev, apsize_reg, 4);
pci_write_config(dev, apsize_reg, temp & ~1, 4);
free(sc->ag_vdir, M_AGP);
free(sc->ag_virtual, M_AGP);
bus_release_resource(dev, SYS_RES_MEMORY, ATI_GART_MMADDR, sc->regs);
agp_free_res(dev);
return 0;
}
static u_int32_t
agp_ati_get_aperture(device_t dev)
{
struct agp_ati_softc *sc = device_get_softc(dev);
int size_value;
if (sc->is_rs300)
size_value = pci_read_config(dev, ATI_RS300_APSIZE, 4);
else
size_value = pci_read_config(dev, ATI_RS100_APSIZE, 4);
size_value = (size_value & 0x0000000e) >> 1;
size_value = (32 * 1024 * 1024) << size_value;
return size_value;
}
static int
agp_ati_set_aperture(device_t dev, u_int32_t aperture)
{
struct agp_ati_softc *sc = device_get_softc(dev);
int size_value;
u_int32_t apsize_reg;
if (sc->is_rs300)
apsize_reg = ATI_RS300_APSIZE;
else
apsize_reg = ATI_RS100_APSIZE;
size_value = pci_read_config(dev, apsize_reg, 4);
size_value &= ~0x0000000e;
size_value |= (ffs(aperture / (32 * 1024 * 1024)) - 1) << 1;
pci_write_config(dev, apsize_reg, size_value, 4);
return 0;
}
static int
agp_ati_bind_page(device_t dev, int offset, vm_offset_t physical)
{
struct agp_ati_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 1;
return 0;
}
static int
agp_ati_unbind_page(device_t dev, int offset)
{
struct agp_ati_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
return 0;
}
static void
agp_ati_flush_tlb(device_t dev)
{
struct agp_ati_softc *sc = device_get_softc(dev);
/* Set the cache invalidate bit and wait for the chipset to clear */
WRITE4(ATI_GART_CACHE_CNTRL, 1);
(void)READ4(ATI_GART_CACHE_CNTRL);
}
static device_method_t agp_ati_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_ati_probe),
DEVMETHOD(device_attach, agp_ati_attach),
DEVMETHOD(device_detach, agp_ati_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* AGP interface */
DEVMETHOD(agp_get_aperture, agp_ati_get_aperture),
DEVMETHOD(agp_set_aperture, agp_ati_set_aperture),
DEVMETHOD(agp_bind_page, agp_ati_bind_page),
DEVMETHOD(agp_unbind_page, agp_ati_unbind_page),
DEVMETHOD(agp_flush_tlb, agp_ati_flush_tlb),
DEVMETHOD(agp_enable, agp_generic_enable),
DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
DEVMETHOD(agp_free_memory, agp_generic_free_memory),
DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
{ 0, 0 }
};
static driver_t agp_ati_driver = {
"agp",
agp_ati_methods,
sizeof(struct agp_ati_softc),
};
static devclass_t agp_devclass;
DRIVER_MODULE(agp_ati, hostb, agp_ati_driver, agp_devclass, 0, 0);
MODULE_DEPEND(agp_ati, agp, 1, 1, 1);
MODULE_DEPEND(agp_ati, pci, 1, 1, 1);

File diff suppressed because it is too large Load Diff

View File

@ -1,134 +0,0 @@
#-
# Copyright (c) 2000 Doug Rabson
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
#
#include <sys/bus.h>
#
# The AGP interface is used internally to the agp driver to isolate the
# differences between various AGP chipsets into chipset mini drivers. It
# should not be used outside the AGP driver. The kernel api for accessing
# AGP functionality is described in <pci/agpvar.h>
#
INTERFACE agp;
#
# Return the current aperture size.
#
METHOD u_int32_t get_aperture {
device_t dev;
};
#
# Set the size of the aperture. Return EINVAL on error or 0 on success.
#
METHOD int set_aperture {
device_t dev;
u_int32_t aperture;
};
#
# Bind a single page in the AGP aperture to a given physical address.
# The offset is a byte offset within the aperture which must be
# aligned to an AGP page boundary.
#
METHOD int bind_page {
device_t dev;
vm_offset_t offset;
vm_offset_t physical;
};
#
# Unbind a single page in the AGP aperture.
#
METHOD int unbind_page {
device_t dev;
vm_offset_t offset;
};
#
# Flush the GATT TLB. This is used after a call to bind_page to
# ensure that any mappings cached in the chipset are discarded.
#
METHOD void flush_tlb {
device_t dev;
};
#
# Enable the agp hardware with the relavent mode. The mode bits are
# defined in <pci/agpreg.h>
#
METHOD int enable {
device_t dev;
u_int32_t mode;
};
#
# Allocate memory of a given type. The type is a chipset-specific
# code which is used by certain integrated agp graphics chips
# (basically just the i810 for now) to access special features of
# the chipset. An opaque handle representing the memory region is
# returned and can be used as an argument to free_memory, bind_memory
# and unbind_memory.
#
# The size is specified in bytes but must be a multiple of the AGP
# page size.
#
METHOD struct agp_memory * alloc_memory {
device_t dev;
int type;
vm_size_t size;
};
#
# Free a memory region previously allocated with alloc_memory. Return
# EBUSY if the memory is bound.
#
METHOD int free_memory {
device_t dev;
struct agp_memory *mem;
};
#
# Bind a memory region to a specific byte offset within the chipset's
# AGP aperture. This effectively defines a range of contiguous
# physical address which alias the (possibly uncontiguous) pages in
# the memory region.
#
METHOD int bind_memory {
device_t dev;
struct agp_memory *mem;
vm_offset_t offset;
};
#
# Unbind a memory region bound with bind_memory.
#
METHOD int unbind_memory {
device_t dev;
struct agp_memory *handle;
};

View File

@ -1,439 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/pmap.h>
#define MAX_APSIZE 0x3f /* 256 MB */
struct agp_intel_softc {
struct agp_softc agp;
u_int32_t initial_aperture; /* aperture size at startup */
struct agp_gatt *gatt;
u_int aperture_mask;
u_int32_t current_aperture; /* current aperture size */
};
static const char*
agp_intel_match(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE
|| pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
return (NULL);
if (agp_find_caps(dev) == 0)
return (NULL);
switch (pci_get_devid(dev)) {
/* Intel -- vendor 0x8086 */
case 0x71808086:
return ("Intel 82443LX (440 LX) host to PCI bridge");
case 0x71908086:
return ("Intel 82443BX (440 BX) host to PCI bridge");
case 0x71a08086:
return ("Intel 82443GX host to PCI bridge");
case 0x71a18086:
return ("Intel 82443GX host to AGP bridge");
case 0x11308086:
return ("Intel 82815 (i815 GMCH) host to PCI bridge");
case 0x25008086:
case 0x25018086:
return ("Intel 82820 host to AGP bridge");
case 0x35758086:
return ("Intel 82830 host to AGP bridge");
case 0x1a218086:
return ("Intel 82840 host to AGP bridge");
case 0x1a308086:
return ("Intel 82845 host to AGP bridge");
case 0x25308086:
return ("Intel 82850 host to AGP bridge");
case 0x33408086:
return ("Intel 82855 host to AGP bridge");
case 0x25318086:
return ("Intel 82860 host to AGP bridge");
case 0x25708086:
return ("Intel 82865 host to AGP bridge");
case 0x255d8086:
return ("Intel E7205 host to AGP bridge");
case 0x25508086:
return ("Intel E7505 host to AGP bridge");
case 0x25788086:
return ("Intel 82875P host to AGP bridge");
case 0x25608086:
return ("Intel 82845G host to AGP bridge");
case 0x35808086:
return ("Intel 82855GM host to AGP bridge");
};
return (NULL);
}
static int
agp_intel_probe(device_t dev)
{
const char *desc;
if (resource_disabled("agp", device_get_unit(dev)))
return (ENXIO);
desc = agp_intel_match(dev);
if (desc) {
device_set_desc(dev, desc);
return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
static void
agp_intel_commit_gatt(device_t dev)
{
struct agp_intel_softc *sc;
u_int32_t type;
u_int32_t value;
sc = device_get_softc(dev);
type = pci_get_devid(dev);
/* Install the gatt. */
pci_write_config(dev, AGP_INTEL_ATTBASE, sc->gatt->ag_physical, 4);
/* Enable the GLTB and setup the control register. */
switch (type) {
case 0x71908086: /* 440LX/EX */
pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2080, 4);
break;
case 0x71808086: /* 440BX */
/*
* XXX: Should be 0xa080? Bit 9 is undefined, and
* bit 13 being on and bit 15 being clear is illegal.
*/
pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2280, 4);
break;
default:
value = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4);
pci_write_config(dev, AGP_INTEL_AGPCTRL, value | 0x80, 4);
}
/* Enable aperture accesses. */
switch (type) {
case 0x25008086: /* i820 */
case 0x25018086: /* i820 */
pci_write_config(dev, AGP_INTEL_I820_RDCR,
(pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
| (1 << 1)), 1);
break;
case 0x1a308086: /* i845 */
case 0x25608086: /* i845G */
case 0x33408086: /* i855 */
case 0x35808086: /* i855GM */
case 0x25708086: /* i865 */
case 0x25788086: /* i875P */
pci_write_config(dev, AGP_INTEL_I845_AGPM,
(pci_read_config(dev, AGP_INTEL_I845_AGPM, 1)
| (1 << 1)), 1);
break;
case 0x1a218086: /* i840 */
case 0x25308086: /* i850 */
case 0x25318086: /* i860 */
case 0x255d8086: /* E7205 */
case 0x25508086: /* E7505 */
pci_write_config(dev, AGP_INTEL_MCHCFG,
(pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
| (1 << 9)), 2);
break;
default: /* Intel Generic (maybe) */
pci_write_config(dev, AGP_INTEL_NBXCFG,
(pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
& ~(1 << 10)) | (1 << 9), 4);
}
/* Clear errors. */
switch (type) {
case 0x1a218086: /* i840 */
pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0xc000, 2);
break;
case 0x25008086: /* i820 */
case 0x25018086: /* i820 */
case 0x1a308086: /* i845 */
case 0x25608086: /* i845G */
case 0x25308086: /* i850 */
case 0x33408086: /* i855 */
case 0x25318086: /* i860 */
case 0x25708086: /* i865 */
case 0x25788086: /* i875P */
case 0x255d8086: /* E7205 */
case 0x25508086: /* E7505 */
pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0x00ff, 2);
break;
default: /* Intel Generic (maybe) */
pci_write_config(dev, AGP_INTEL_ERRSTS + 1, 7, 1);
}
}
static int
agp_intel_attach(device_t dev)
{
struct agp_intel_softc *sc;
struct agp_gatt *gatt;
u_int32_t value;
int error;
sc = device_get_softc(dev);
error = agp_generic_attach(dev);
if (error)
return (error);
/* Determine maximum supported aperture size. */
value = pci_read_config(dev, AGP_INTEL_APSIZE, 1);
pci_write_config(dev, AGP_INTEL_APSIZE, MAX_APSIZE, 1);
sc->aperture_mask = pci_read_config(dev, AGP_INTEL_APSIZE, 1) &
MAX_APSIZE;
pci_write_config(dev, AGP_INTEL_APSIZE, value, 1);
sc->current_aperture = sc->initial_aperture = AGP_GET_APERTURE(dev);
for (;;) {
gatt = agp_alloc_gatt(dev);
if (gatt)
break;
/*
* Probably contigmalloc failure. Try reducing the
* aperture so that the gatt size reduces.
*/
if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
agp_generic_detach(dev);
return (ENOMEM);
}
}
sc->gatt = gatt;
agp_intel_commit_gatt(dev);
return (0);
}
static int
agp_intel_detach(device_t dev)
{
struct agp_intel_softc *sc;
u_int32_t reg;
sc = device_get_softc(dev);
agp_free_cdev(dev);
/* Disable aperture accesses. */
switch (pci_get_devid(dev)) {
case 0x25008086: /* i820 */
case 0x25018086: /* i820 */
reg = pci_read_config(dev, AGP_INTEL_I820_RDCR, 1) & ~(1 << 1);
printf("%s: set RDCR to %02x\n", __func__, reg & 0xff);
pci_write_config(dev, AGP_INTEL_I820_RDCR, reg, 1);
break;
case 0x1a308086: /* i845 */
case 0x25608086: /* i845G */
case 0x33408086: /* i855 */
case 0x35808086: /* i855GM */
case 0x25708086: /* i865 */
case 0x25788086: /* i875P */
reg = pci_read_config(dev, AGP_INTEL_I845_AGPM, 1) & ~(1 << 1);
printf("%s: set AGPM to %02x\n", __func__, reg & 0xff);
pci_write_config(dev, AGP_INTEL_I845_AGPM, reg, 1);
break;
case 0x1a218086: /* i840 */
case 0x25308086: /* i850 */
case 0x25318086: /* i860 */
case 0x255d8086: /* E7205 */
case 0x25508086: /* E7505 */
reg = pci_read_config(dev, AGP_INTEL_MCHCFG, 2) & ~(1 << 9);
printf("%s: set MCHCFG to %x04\n", __func__, reg & 0xffff);
pci_write_config(dev, AGP_INTEL_MCHCFG, reg, 2);
break;
default: /* Intel Generic (maybe) */
reg = pci_read_config(dev, AGP_INTEL_NBXCFG, 4) & ~(1 << 9);
printf("%s: set NBXCFG to %08x\n", __func__, reg);
pci_write_config(dev, AGP_INTEL_NBXCFG, reg, 4);
}
pci_write_config(dev, AGP_INTEL_ATTBASE, 0, 4);
AGP_SET_APERTURE(dev, sc->initial_aperture);
agp_free_gatt(sc->gatt);
agp_free_res(dev);
return (0);
}
static int
agp_intel_resume(device_t dev)
{
struct agp_intel_softc *sc;
sc = device_get_softc(dev);
AGP_SET_APERTURE(dev, sc->current_aperture);
agp_intel_commit_gatt(dev);
return (bus_generic_resume(dev));
}
static u_int32_t
agp_intel_get_aperture(device_t dev)
{
struct agp_intel_softc *sc;
u_int32_t apsize;
sc = device_get_softc(dev);
apsize = pci_read_config(dev, AGP_INTEL_APSIZE, 1) & sc->aperture_mask;
/*
* The size is determined by the number of low bits of
* register APBASE which are forced to zero. The low 22 bits
* are always forced to zero and each zero bit in the apsize
* field just read forces the corresponding bit in the 27:22
* to be zero. We calculate the aperture size accordingly.
*/
return ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1);
}
static int
agp_intel_set_aperture(device_t dev, u_int32_t aperture)
{
struct agp_intel_softc *sc;
u_int32_t apsize;
sc = device_get_softc(dev);
/*
* Reverse the magic from get_aperture.
*/
apsize = ((aperture - 1) >> 22) ^ sc->aperture_mask;
/*
* Double check for sanity.
*/
if ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1 != aperture)
return (EINVAL);
sc->current_aperture = apsize;
pci_write_config(dev, AGP_INTEL_APSIZE, apsize, 1);
return (0);
}
static int
agp_intel_bind_page(device_t dev, int offset, vm_offset_t physical)
{
struct agp_intel_softc *sc;
sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return (EINVAL);
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 0x17;
return (0);
}
static int
agp_intel_unbind_page(device_t dev, int offset)
{
struct agp_intel_softc *sc;
sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return (EINVAL);
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
return (0);
}
static void
agp_intel_flush_tlb(device_t dev)
{
u_int32_t val;
val = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4);
pci_write_config(dev, AGP_INTEL_AGPCTRL, val & ~(1 << 7), 4);
pci_write_config(dev, AGP_INTEL_AGPCTRL, val, 4);
}
static device_method_t agp_intel_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_intel_probe),
DEVMETHOD(device_attach, agp_intel_attach),
DEVMETHOD(device_detach, agp_intel_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, agp_intel_resume),
/* AGP interface */
DEVMETHOD(agp_get_aperture, agp_intel_get_aperture),
DEVMETHOD(agp_set_aperture, agp_intel_set_aperture),
DEVMETHOD(agp_bind_page, agp_intel_bind_page),
DEVMETHOD(agp_unbind_page, agp_intel_unbind_page),
DEVMETHOD(agp_flush_tlb, agp_intel_flush_tlb),
DEVMETHOD(agp_enable, agp_generic_enable),
DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
DEVMETHOD(agp_free_memory, agp_generic_free_memory),
DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
{ 0, 0 }
};
static driver_t agp_intel_driver = {
"agp",
agp_intel_methods,
sizeof(struct agp_intel_softc),
};
static devclass_t agp_devclass;
DRIVER_MODULE(agp_intel, hostb, agp_intel_driver, agp_devclass, 0, 0);
MODULE_DEPEND(agp_intel, agp, 1, 1, 1);
MODULE_DEPEND(agp_intel, pci, 1, 1, 1);

View File

@ -1,462 +0,0 @@
/*-
* Copyright (c) 2003 Matthew N. Dodd <winter@jurai.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Written using information gleaned from the
* NVIDIA nForce/nForce2 AGPGART Linux Kernel Patch.
*/
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#if __FreeBSD_version < 500000
#include "opt_pci.h"
#endif
#if __FreeBSD_version > 500000
#include <sys/mutex.h>
#include <sys/proc.h>
#endif
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#define NVIDIA_VENDORID 0x10de
#define NVIDIA_DEVICEID_NFORCE 0x01a4
#define NVIDIA_DEVICEID_NFORCE2 0x01e0
struct agp_nvidia_softc {
struct agp_softc agp;
u_int32_t initial_aperture; /* aperture size at startup */
struct agp_gatt * gatt;
device_t dev; /* AGP Controller */
device_t mc1_dev; /* Memory Controller */
device_t mc2_dev; /* Memory Controller */
device_t bdev; /* Bridge */
u_int32_t wbc_mask;
int num_dirs;
int num_active_entries;
off_t pg_offset;
};
static const char *agp_nvidia_match(device_t dev);
static int agp_nvidia_probe(device_t);
static int agp_nvidia_attach(device_t);
static int agp_nvidia_detach(device_t);
static u_int32_t agp_nvidia_get_aperture(device_t);
static int agp_nvidia_set_aperture(device_t, u_int32_t);
static int agp_nvidia_bind_page(device_t, int, vm_offset_t);
static int agp_nvidia_unbind_page(device_t, int);
static int nvidia_init_iorr(u_int32_t, u_int32_t);
static const char *
agp_nvidia_match (device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_HOST ||
pci_get_vendor(dev) != NVIDIA_VENDORID)
return (NULL);
switch (pci_get_device(dev)) {
case NVIDIA_DEVICEID_NFORCE:
return ("NVIDIA nForce AGP Controller");
case NVIDIA_DEVICEID_NFORCE2:
return ("NVIDIA nForce2 AGP Controller");
}
return (NULL);
}
static int
agp_nvidia_probe (device_t dev)
{
const char *desc;
if (resource_disabled("agp", device_get_unit(dev)))
return (ENXIO);
desc = agp_nvidia_match(dev);
if (desc) {
device_set_desc(dev, desc);
return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
static int
agp_nvidia_attach (device_t dev)
{
struct agp_nvidia_softc *sc = device_get_softc(dev);
struct agp_gatt *gatt;
u_int32_t apbase;
u_int32_t aplimit;
u_int32_t temp;
int size;
int i;
int error;
switch (pci_get_device(dev)) {
case NVIDIA_DEVICEID_NFORCE:
sc->wbc_mask = 0x00010000;
break;
case NVIDIA_DEVICEID_NFORCE2:
sc->wbc_mask = 0x80000000;
break;
default:
device_printf(dev, "Bad chip id\n");
return (ENODEV);
}
/* AGP Controller */
sc->dev = dev;
/* Memory Controller 1 */
sc->mc1_dev = pci_find_bsf(pci_get_bus(dev), 0, 1);
if (sc->mc1_dev == NULL) {
device_printf(dev,
"Unable to find NVIDIA Memory Controller 1.\n");
return (ENODEV);
}
/* Memory Controller 2 */
sc->mc2_dev = pci_find_bsf(pci_get_bus(dev), 0, 2);
if (sc->mc2_dev == NULL) {
device_printf(dev,
"Unable to find NVIDIA Memory Controller 2.\n");
return (ENODEV);
}
/* AGP Host to PCI Bridge */
sc->bdev = pci_find_bsf(pci_get_bus(dev), 30, 0);
if (sc->bdev == NULL) {
device_printf(dev,
"Unable to find NVIDIA AGP Host to PCI Bridge.\n");
return (ENODEV);
}
error = agp_generic_attach(dev);
if (error)
return (error);
sc->initial_aperture = AGP_GET_APERTURE(dev);
for (;;) {
gatt = agp_alloc_gatt(dev);
if (gatt)
break;
/*
* Probably contigmalloc failure. Try reducing the
* aperture so that the gatt size reduces.
*/
if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2))
goto fail;
}
sc->gatt = gatt;
apbase = rman_get_start(sc->agp.as_aperture);
aplimit = apbase + AGP_GET_APERTURE(dev) - 1;
pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_APBASE, apbase, 4);
pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_APLIMIT, aplimit, 4);
pci_write_config(sc->bdev, AGP_NVIDIA_3_APBASE, apbase, 4);
pci_write_config(sc->bdev, AGP_NVIDIA_3_APLIMIT, aplimit, 4);
error = nvidia_init_iorr(apbase, AGP_GET_APERTURE(dev));
if (error) {
device_printf(dev, "Failed to setup IORRs\n");
goto fail;
}
/* directory size is 64k */
size = AGP_GET_APERTURE(dev) / 1024 / 1024;
sc->num_dirs = size / 64;
sc->num_active_entries = (size == 32) ? 16384 : ((size * 1024) / 4);
sc->pg_offset = 0;
if (sc->num_dirs == 0) {
sc->num_dirs = 1;
sc->num_active_entries /= (64 / size);
sc->pg_offset = (apbase & (64 * 1024 * 1024 - 1) &
~(AGP_GET_APERTURE(dev) - 1)) / PAGE_SIZE;
}
/* (G)ATT Base Address */
for (i = 0; i < 8; i++) {
pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_ATTBASE(i),
(sc->gatt->ag_physical +
(i % sc->num_dirs) * 64 * 1024) | 1, 4);
}
/* GTLB Control */
temp = pci_read_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, 4);
pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, temp | 0x11, 4);
/* GART Control */
temp = pci_read_config(sc->dev, AGP_NVIDIA_0_APSIZE, 4);
pci_write_config(sc->dev, AGP_NVIDIA_0_APSIZE, temp | 0x100, 4);
return (0);
fail:
agp_generic_detach(dev);
return (ENOMEM);
}
static int
agp_nvidia_detach (device_t dev)
{
struct agp_nvidia_softc *sc = device_get_softc(dev);
u_int32_t temp;
agp_free_cdev(dev);
/* GART Control */
temp = pci_read_config(sc->dev, AGP_NVIDIA_0_APSIZE, 4);
pci_write_config(sc->dev, AGP_NVIDIA_0_APSIZE, temp & ~(0x100), 4);
/* GTLB Control */
temp = pci_read_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, 4);
pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, temp & ~(0x11), 4);
/* Put the aperture back the way it started. */
AGP_SET_APERTURE(dev, sc->initial_aperture);
/* restore iorr for previous aperture size */
nvidia_init_iorr(rman_get_start(sc->agp.as_aperture),
sc->initial_aperture);
agp_free_gatt(sc->gatt);
agp_free_res(dev);
return (0);
}
static u_int32_t
agp_nvidia_get_aperture(device_t dev)
{
switch (pci_read_config(dev, AGP_NVIDIA_0_APSIZE, 1) & 0x0f) {
case 0: return (512 * 1024 * 1024); break;
case 8: return (256 * 1024 * 1024); break;
case 12: return (128 * 1024 * 1024); break;
case 14: return (64 * 1024 * 1024); break;
case 15: return (32 * 1024 * 1024); break;
default:
device_printf(dev, "Invalid aperture setting 0x%x",
pci_read_config(dev, AGP_NVIDIA_0_APSIZE, 1));
return 0;
}
}
static int
agp_nvidia_set_aperture(device_t dev, u_int32_t aperture)
{
u_int8_t val;
u_int8_t key;
switch (aperture) {
case (512 * 1024 * 1024): key = 0; break;
case (256 * 1024 * 1024): key = 8; break;
case (128 * 1024 * 1024): key = 12; break;
case (64 * 1024 * 1024): key = 14; break;
case (32 * 1024 * 1024): key = 15; break;
default:
device_printf(dev, "Invalid aperture size (%dMb)\n",
aperture / 1024 / 1024);
return (EINVAL);
}
val = pci_read_config(dev, AGP_NVIDIA_0_APSIZE, 1);
pci_write_config(dev, AGP_NVIDIA_0_APSIZE, ((val & ~0x0f) | key), 1);
return (0);
}
static int
agp_nvidia_bind_page(device_t dev, int offset, vm_offset_t physical)
{
struct agp_nvidia_softc *sc = device_get_softc(dev);
u_int32_t index;
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return (EINVAL);
index = (sc->pg_offset + offset) >> AGP_PAGE_SHIFT;
sc->gatt->ag_virtual[index] = physical | 1;
return (0);
}
static int
agp_nvidia_unbind_page(device_t dev, int offset)
{
struct agp_nvidia_softc *sc = device_get_softc(dev);
u_int32_t index;
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return (EINVAL);
index = (sc->pg_offset + offset) >> AGP_PAGE_SHIFT;
sc->gatt->ag_virtual[index] = 0;
return (0);
}
static int
agp_nvidia_flush_tlb (device_t dev, int offset)
{
struct agp_nvidia_softc *sc;
u_int32_t wbc_reg, temp;
volatile u_int32_t *ag_virtual;
int i;
sc = (struct agp_nvidia_softc *)device_get_softc(dev);
if (sc->wbc_mask) {
wbc_reg = pci_read_config(sc->mc1_dev, AGP_NVIDIA_1_WBC, 4);
wbc_reg |= sc->wbc_mask;
pci_write_config(sc->mc1_dev, AGP_NVIDIA_1_WBC, wbc_reg, 4);
/* Wait no more than 3 seconds. */
for (i = 0; i < 3000; i++) {
wbc_reg = pci_read_config(sc->mc1_dev,
AGP_NVIDIA_1_WBC, 4);
if ((sc->wbc_mask & wbc_reg) == 0)
break;
else
DELAY(1000);
}
if (i == 3000)
device_printf(dev,
"TLB flush took more than 3 seconds.\n");
}
ag_virtual = (volatile u_int32_t *)sc->gatt->ag_virtual;
/* Flush TLB entries. */
for(i = 0; i < 32 + 1; i++)
temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)];
for(i = 0; i < 32 + 1; i++)
temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)];
return (0);
}
#define SYSCFG 0xC0010010
#define IORR_BASE0 0xC0010016
#define IORR_MASK0 0xC0010017
#define AMD_K7_NUM_IORR 2
static int
nvidia_init_iorr(u_int32_t addr, u_int32_t size)
{
quad_t base, mask, sys;
u_int32_t iorr_addr, free_iorr_addr;
/* Find the iorr that is already used for the addr */
/* If not found, determine the uppermost available iorr */
free_iorr_addr = AMD_K7_NUM_IORR;
for(iorr_addr = 0; iorr_addr < AMD_K7_NUM_IORR; iorr_addr++) {
base = rdmsr(IORR_BASE0 + 2 * iorr_addr);
mask = rdmsr(IORR_MASK0 + 2 * iorr_addr);
if ((base & 0xfffff000ULL) == (addr & 0xfffff000))
break;
if ((mask & 0x00000800ULL) == 0)
free_iorr_addr = iorr_addr;
}
if (iorr_addr >= AMD_K7_NUM_IORR) {
iorr_addr = free_iorr_addr;
if (iorr_addr >= AMD_K7_NUM_IORR)
return (EINVAL);
}
base = (addr & ~0xfff) | 0x18;
mask = (0xfULL << 32) | ((~(size - 1)) & 0xfffff000) | 0x800;
wrmsr(IORR_BASE0 + 2 * iorr_addr, base);
wrmsr(IORR_MASK0 + 2 * iorr_addr, mask);
sys = rdmsr(SYSCFG);
sys |= 0x00100000ULL;
wrmsr(SYSCFG, sys);
return (0);
}
static device_method_t agp_nvidia_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_nvidia_probe),
DEVMETHOD(device_attach, agp_nvidia_attach),
DEVMETHOD(device_detach, agp_nvidia_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* AGP interface */
DEVMETHOD(agp_get_aperture, agp_nvidia_get_aperture),
DEVMETHOD(agp_set_aperture, agp_nvidia_set_aperture),
DEVMETHOD(agp_bind_page, agp_nvidia_bind_page),
DEVMETHOD(agp_unbind_page, agp_nvidia_unbind_page),
DEVMETHOD(agp_flush_tlb, agp_nvidia_flush_tlb),
DEVMETHOD(agp_enable, agp_generic_enable),
DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
DEVMETHOD(agp_free_memory, agp_generic_free_memory),
DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
{ 0, 0 }
};
static driver_t agp_nvidia_driver = {
"agp",
agp_nvidia_methods,
sizeof(struct agp_nvidia_softc),
};
static devclass_t agp_devclass;
DRIVER_MODULE(agp_nvidia, hostb, agp_nvidia_driver, agp_devclass, 0, 0);
MODULE_DEPEND(agp_nvidia, agp, 1, 1, 1);
MODULE_DEPEND(agp_nvidia, pci, 1, 1, 1);

View File

@ -1,293 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/pmap.h>
struct agp_sis_softc {
struct agp_softc agp;
u_int32_t initial_aperture; /* aperture size at startup */
struct agp_gatt *gatt;
};
static const char*
agp_sis_match(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE
|| pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
return NULL;
if (agp_find_caps(dev) == 0)
return NULL;
switch (pci_get_devid(dev)) {
case 0x00011039:
return ("SiS 5591 host to AGP bridge");
case 0x05301039:
return ("SiS 530 host to AGP bridge");
case 0x05401039:
return ("SiS 540 host to AGP bridge");
case 0x05501039:
return ("SiS 550 host to AGP bridge");
case 0x06201039:
return ("SiS 620 host to AGP bridge");
case 0x06301039:
return ("SiS 630 host to AGP bridge");
case 0x06451039:
return ("SiS 645 host to AGP bridge");
case 0x06461039:
return ("SiS 645DX host to AGP bridge");
case 0x06481039:
return ("SiS 648 host to AGP bridge");
case 0x06501039:
return ("SiS 650 host to AGP bridge");
case 0x06511039:
return ("SiS 651 host to AGP bridge");
case 0x06551039:
return ("SiS 655 host to AGP bridge");
case 0x06611039:
return ("SiS 661 host to AGP bridge");
case 0x07301039:
return ("SiS 730 host to AGP bridge");
case 0x07351039:
return ("SiS 735 host to AGP bridge");
case 0x07401039:
return ("SiS 740 host to AGP bridge");
case 0x07411039:
return ("SiS 741 host to AGP bridge");
case 0x07451039:
return ("SiS 745 host to AGP bridge");
case 0x07461039:
return ("SiS 746 host to AGP bridge");
};
return NULL;
}
static int
agp_sis_probe(device_t dev)
{
const char *desc;
if (resource_disabled("agp", device_get_unit(dev)))
return (ENXIO);
desc = agp_sis_match(dev);
if (desc) {
device_set_desc(dev, desc);
return BUS_PROBE_DEFAULT;
}
return ENXIO;
}
static int
agp_sis_attach(device_t dev)
{
struct agp_sis_softc *sc = device_get_softc(dev);
struct agp_gatt *gatt;
int error;
error = agp_generic_attach(dev);
if (error)
return error;
sc->initial_aperture = AGP_GET_APERTURE(dev);
for (;;) {
gatt = agp_alloc_gatt(dev);
if (gatt)
break;
/*
* Probably contigmalloc failure. Try reducing the
* aperture so that the gatt size reduces.
*/
if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
agp_generic_detach(dev);
return ENOMEM;
}
}
sc->gatt = gatt;
/* Install the gatt. */
pci_write_config(dev, AGP_SIS_ATTBASE, gatt->ag_physical, 4);
/* Enable the aperture. */
pci_write_config(dev, AGP_SIS_WINCTRL,
pci_read_config(dev, AGP_SIS_WINCTRL, 1) | 3, 1);
/*
* Enable the TLB and make it automatically invalidate entries
* when the GATT is written.
*/
pci_write_config(dev, AGP_SIS_TLBCTRL, 0x05, 1);
return 0;
}
static int
agp_sis_detach(device_t dev)
{
struct agp_sis_softc *sc = device_get_softc(dev);
agp_free_cdev(dev);
/* Disable the aperture.. */
pci_write_config(dev, AGP_SIS_WINCTRL,
pci_read_config(dev, AGP_SIS_WINCTRL, 1) & ~3, 1);
/* and the TLB. */
pci_write_config(dev, AGP_SIS_TLBCTRL, 0, 1);
/* Put the aperture back the way it started. */
AGP_SET_APERTURE(dev, sc->initial_aperture);
agp_free_gatt(sc->gatt);
agp_free_res(dev);
return 0;
}
static u_int32_t
agp_sis_get_aperture(device_t dev)
{
int gws;
/*
* The aperture size is equal to 4M<<gws.
*/
gws = (pci_read_config(dev, AGP_SIS_WINCTRL, 1) & 0x70) >> 4;
return (4*1024*1024) << gws;
}
static int
agp_sis_set_aperture(device_t dev, u_int32_t aperture)
{
int gws;
/*
* Check for a power of two and make sure its within the
* programmable range.
*/
if (aperture & (aperture - 1)
|| aperture < 4*1024*1024
|| aperture > 256*1024*1024)
return EINVAL;
gws = ffs(aperture / 4*1024*1024) - 1;
pci_write_config(dev, AGP_SIS_WINCTRL,
((pci_read_config(dev, AGP_SIS_WINCTRL, 1) & ~0x70)
| gws << 4), 1);
return 0;
}
static int
agp_sis_bind_page(device_t dev, int offset, vm_offset_t physical)
{
struct agp_sis_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
return 0;
}
static int
agp_sis_unbind_page(device_t dev, int offset)
{
struct agp_sis_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
return 0;
}
static void
agp_sis_flush_tlb(device_t dev)
{
pci_write_config(dev, AGP_SIS_TLBFLUSH, 0x02, 1);
}
static device_method_t agp_sis_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_sis_probe),
DEVMETHOD(device_attach, agp_sis_attach),
DEVMETHOD(device_detach, agp_sis_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* AGP interface */
DEVMETHOD(agp_get_aperture, agp_sis_get_aperture),
DEVMETHOD(agp_set_aperture, agp_sis_set_aperture),
DEVMETHOD(agp_bind_page, agp_sis_bind_page),
DEVMETHOD(agp_unbind_page, agp_sis_unbind_page),
DEVMETHOD(agp_flush_tlb, agp_sis_flush_tlb),
DEVMETHOD(agp_enable, agp_generic_enable),
DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
DEVMETHOD(agp_free_memory, agp_generic_free_memory),
DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
{ 0, 0 }
};
static driver_t agp_sis_driver = {
"agp",
agp_sis_methods,
sizeof(struct agp_sis_softc),
};
static devclass_t agp_devclass;
DRIVER_MODULE(agp_sis, hostb, agp_sis_driver, agp_devclass, 0, 0);
MODULE_DEPEND(agp_sis, agp, 1, 1, 1);
MODULE_DEPEND(agp_sis, pci, 1, 1, 1);

View File

@ -1,427 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <pci/agppriv.h>
#include <pci/agpreg.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/pmap.h>
#define REG_GARTCTRL 0
#define REG_APSIZE 1
#define REG_ATTBASE 2
struct agp_via_softc {
struct agp_softc agp;
u_int32_t initial_aperture; /* aperture size at startup */
struct agp_gatt *gatt;
int *regs;
};
static int via_v2_regs[] = { AGP_VIA_GARTCTRL, AGP_VIA_APSIZE,
AGP_VIA_ATTBASE };
static int via_v3_regs[] = { AGP3_VIA_GARTCTRL, AGP3_VIA_APSIZE,
AGP3_VIA_ATTBASE };
static const char*
agp_via_match(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE
|| pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
return NULL;
if (agp_find_caps(dev) == 0)
return NULL;
switch (pci_get_devid(dev)) {
case 0x01981106:
return ("VIA 8763 (P4X600) host to PCI bridge");
case 0x02591106:
return ("VIA PM800/PN800/PM880/PN880 host to PCI bridge");
case 0x02691106:
return ("VIA KT880 host to PCI bridge");
case 0x02961106:
return ("VIA 3296 (P4M800) host to PCI bridge");
case 0x03051106:
return ("VIA 82C8363 (Apollo KT133x/KM133) host to PCI bridge");
case 0x03241106:
return ("VIA VT3324 (CX700) host to PCI bridge");
case 0x03911106:
return ("VIA 8371 (Apollo KX133) host to PCI bridge");
case 0x05011106:
return ("VIA 8501 (Apollo MVP4) host to PCI bridge");
case 0x05971106:
return ("VIA 82C597 (Apollo VP3) host to PCI bridge");
case 0x05981106:
return ("VIA 82C598 (Apollo MVP3) host to PCI bridge");
case 0x06011106:
return ("VIA 8601 (Apollo ProMedia/PLE133Ta) host to PCI bridge");
case 0x06051106:
return ("VIA 82C694X (Apollo Pro 133A) host to PCI bridge");
case 0x06911106:
return ("VIA 82C691 (Apollo Pro) host to PCI bridge");
case 0x30911106:
return ("VIA 8633 (Pro 266) host to PCI bridge");
case 0x30991106:
return ("VIA 8367 (KT266/KY266x/KT333) host to PCI bridge");
case 0x31011106:
return ("VIA 8653 (Pro266T) host to PCI bridge");
case 0x31121106:
return ("VIA 8361 (KLE133) host to PCI bridge");
case 0x31161106:
return ("VIA XM266 (PM266/KM266) host to PCI bridge");
case 0x31231106:
return ("VIA 862x (CLE266) host to PCI bridge");
case 0x31281106:
return ("VIA 8753 (P4X266) host to PCI bridge");
case 0x31481106:
return ("VIA 8703 (P4M266x/P4N266) host to PCI bridge");
case 0x31561106:
return ("VIA XN266 (Apollo Pro266) host to PCI bridge");
case 0x31681106:
return ("VIA 8754 (PT800) host to PCI bridge");
case 0x31891106:
return ("VIA 8377 (Apollo KT400/KT400A/KT600) host to PCI bridge");
case 0x32051106:
return ("VIA 8235/8237 (Apollo KM400/KM400A) host to PCI bridge");
case 0x32081106:
return ("VIA 8783 (PT890) host to PCI bridge");
case 0x32581106:
return ("VIA PT880 host to PCI bridge");
case 0xb1981106:
return ("VIA VT83xx/VT87xx/KTxxx/Px8xx host to PCI bridge");
};
return NULL;
}
static int
agp_via_probe(device_t dev)
{
const char *desc;
if (resource_disabled("agp", device_get_unit(dev)))
return (ENXIO);
desc = agp_via_match(dev);
if (desc) {
device_set_desc(dev, desc);
return BUS_PROBE_DEFAULT;
}
return ENXIO;
}
static int
agp_via_attach(device_t dev)
{
struct agp_via_softc *sc = device_get_softc(dev);
struct agp_gatt *gatt;
int error;
u_int32_t agpsel;
/* XXX: This should be keying off of whether the bridge is AGP3 capable,
* rather than a bunch of device ids for chipsets that happen to do 8x.
*/
switch (pci_get_devid(dev)) {
case 0x01981106:
case 0x02591106:
case 0x02691106:
case 0x02961106:
case 0x03241106:
case 0x31231106:
case 0x31681106:
case 0x31891106:
case 0x32051106:
case 0x32581106:
case 0xb1981106:
/* The newer VIA chipsets will select the AGP version based on
* what AGP versions the card supports. We still have to
* program it using the v2 registers if it has chosen to use
* compatibility mode.
*/
agpsel = pci_read_config(dev, AGP_VIA_AGPSEL, 1);
if ((agpsel & (1 << 1)) == 0)
sc->regs = via_v3_regs;
else
sc->regs = via_v2_regs;
break;
default:
sc->regs = via_v2_regs;
break;
}
error = agp_generic_attach(dev);
if (error)
return error;
sc->initial_aperture = AGP_GET_APERTURE(dev);
for (;;) {
gatt = agp_alloc_gatt(dev);
if (gatt)
break;
/*
* Probably contigmalloc failure. Try reducing the
* aperture so that the gatt size reduces.
*/
if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
agp_generic_detach(dev);
return ENOMEM;
}
}
sc->gatt = gatt;
if (sc->regs == via_v2_regs) {
/* Install the gatt. */
pci_write_config(dev, sc->regs[REG_ATTBASE], gatt->ag_physical | 3, 4);
/* Enable the aperture. */
pci_write_config(dev, sc->regs[REG_GARTCTRL], 0x0f, 4);
} else {
u_int32_t gartctrl;
/* Install the gatt. */
pci_write_config(dev, sc->regs[REG_ATTBASE], gatt->ag_physical, 4);
/* Enable the aperture. */
gartctrl = pci_read_config(dev, sc->regs[REG_ATTBASE], 4);
pci_write_config(dev, sc->regs[REG_GARTCTRL], gartctrl | (3 << 7), 4);
}
device_printf(dev, "aperture size is %dM\n",
sc->initial_aperture / 1024 / 1024);
return 0;
}
static int
agp_via_detach(device_t dev)
{
struct agp_via_softc *sc = device_get_softc(dev);
agp_free_cdev(dev);
pci_write_config(dev, sc->regs[REG_GARTCTRL], 0, 4);
pci_write_config(dev, sc->regs[REG_ATTBASE], 0, 4);
AGP_SET_APERTURE(dev, sc->initial_aperture);
agp_free_gatt(sc->gatt);
agp_free_res(dev);
return 0;
}
static u_int32_t
agp_via_get_aperture(device_t dev)
{
struct agp_via_softc *sc = device_get_softc(dev);
u_int32_t apsize;
if (sc->regs == via_v2_regs) {
apsize = pci_read_config(dev, sc->regs[REG_APSIZE], 1) & 0x1f;
/*
* The size is determined by the number of low bits of
* register APBASE which are forced to zero. The low 20 bits
* are always forced to zero and each zero bit in the apsize
* field just read forces the corresponding bit in the 27:20
* to be zero. We calculate the aperture size accordingly.
*/
return (((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1;
} else {
apsize = pci_read_config(dev, sc->regs[REG_APSIZE], 2) & 0xfff;
switch (apsize) {
case 0x800:
return 0x80000000;
case 0xc00:
return 0x40000000;
case 0xe00:
return 0x20000000;
case 0xf00:
return 0x10000000;
case 0xf20:
return 0x08000000;
case 0xf30:
return 0x04000000;
case 0xf38:
return 0x02000000;
default:
device_printf(dev, "Invalid aperture setting 0x%x",
pci_read_config(dev, sc->regs[REG_APSIZE], 2));
return 0;
}
}
}
static int
agp_via_set_aperture(device_t dev, u_int32_t aperture)
{
struct agp_via_softc *sc = device_get_softc(dev);
u_int32_t apsize, key, val;
if (sc->regs == via_v2_regs) {
/*
* Reverse the magic from get_aperture.
*/
apsize = ((aperture - 1) >> 20) ^ 0xff;
/*
* Double check for sanity.
*/
if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture)
return EINVAL;
pci_write_config(dev, sc->regs[REG_APSIZE], apsize, 1);
} else {
switch (aperture) {
case 0x80000000:
key = 0x800;
break;
case 0x40000000:
key = 0xc00;
break;
case 0x20000000:
key = 0xe00;
break;
case 0x10000000:
key = 0xf00;
break;
case 0x08000000:
key = 0xf20;
break;
case 0x04000000:
key = 0xf30;
break;
case 0x02000000:
key = 0xf38;
break;
default:
device_printf(dev, "Invalid aperture size (%dMb)\n",
aperture / 1024 / 1024);
return EINVAL;
}
val = pci_read_config(dev, sc->regs[REG_APSIZE], 2);
pci_write_config(dev, sc->regs[REG_APSIZE],
((val & ~0xfff) | key), 2);
}
return 0;
}
static int
agp_via_bind_page(device_t dev, int offset, vm_offset_t physical)
{
struct agp_via_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
return 0;
}
static int
agp_via_unbind_page(device_t dev, int offset)
{
struct agp_via_softc *sc = device_get_softc(dev);
if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
return EINVAL;
sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
return 0;
}
static void
agp_via_flush_tlb(device_t dev)
{
struct agp_via_softc *sc = device_get_softc(dev);
u_int32_t gartctrl;
if (sc->regs == via_v2_regs) {
pci_write_config(dev, sc->regs[REG_GARTCTRL], 0x8f, 4);
pci_write_config(dev, sc->regs[REG_GARTCTRL], 0x0f, 4);
} else {
gartctrl = pci_read_config(dev, sc->regs[REG_GARTCTRL], 4);
pci_write_config(dev, sc->regs[REG_GARTCTRL], gartctrl &
~(1 << 7), 4);
pci_write_config(dev, sc->regs[REG_GARTCTRL], gartctrl, 4);
}
}
static device_method_t agp_via_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_via_probe),
DEVMETHOD(device_attach, agp_via_attach),
DEVMETHOD(device_detach, agp_via_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* AGP interface */
DEVMETHOD(agp_get_aperture, agp_via_get_aperture),
DEVMETHOD(agp_set_aperture, agp_via_set_aperture),
DEVMETHOD(agp_bind_page, agp_via_bind_page),
DEVMETHOD(agp_unbind_page, agp_via_unbind_page),
DEVMETHOD(agp_flush_tlb, agp_via_flush_tlb),
DEVMETHOD(agp_enable, agp_generic_enable),
DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
DEVMETHOD(agp_free_memory, agp_generic_free_memory),
DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
{ 0, 0 }
};
static driver_t agp_via_driver = {
"agp",
agp_via_methods,
sizeof(struct agp_via_softc),
};
static devclass_t agp_devclass;
DRIVER_MODULE(agp_via, hostb, agp_via_driver, agp_devclass, 0, 0);
MODULE_DEPEND(agp_via, agp, 1, 1, 1);
MODULE_DEPEND(agp_via, pci, 1, 1, 1);

View File

@ -1,112 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _PCI_AGPPRIV_H_
#define _PCI_AGPPRIV_H_
/*
* This file *must not* be included by code outside the agp driver itself.
*/
#include <sys/agpio.h>
#include <pci/agpvar.h>
#define AGP_DEBUGxx
#ifdef AGP_DEBUG
#define AGP_DPF(x...) do { \
printf("agp: "); \
printf(##x); \
} while (0)
#else
#define AGP_DPF(x...) do {} while (0)
#endif
#include "agp_if.h"
/*
* Data structure to describe an AGP memory allocation.
*/
TAILQ_HEAD(agp_memory_list, agp_memory);
struct agp_memory {
TAILQ_ENTRY(agp_memory) am_link; /* wiring for the tailq */
int am_id; /* unique id for block */
vm_size_t am_size; /* number of bytes allocated */
int am_type; /* chipset specific type */
struct vm_object *am_obj; /* VM object owning pages */
vm_offset_t am_physical; /* bogus hack for i810 */
vm_offset_t am_offset; /* page offset if bound */
int am_is_bound; /* non-zero if bound */
};
/*
* All chipset drivers must have this at the start of their softc.
*/
struct agp_softc {
struct resource *as_aperture; /* location of aperture */
int as_aperture_rid;
u_int32_t as_maxmem; /* allocation upper bound */
u_int32_t as_allocated; /* amount allocated */
enum agp_acquire_state as_state;
struct agp_memory_list as_memory; /* list of allocated memory */
int as_nextid; /* next memory block id */
int as_isopen; /* user device is open */
struct cdev *as_devnode; /* from make_dev */
struct mtx as_lock; /* lock for access to GATT */
};
struct agp_gatt {
u_int32_t ag_entries;
u_int32_t *ag_virtual;
vm_offset_t ag_physical;
};
void agp_flush_cache(void);
u_int8_t agp_find_caps(device_t dev);
struct agp_gatt *agp_alloc_gatt(device_t dev);
void agp_set_aperture_resource(device_t dev, int rid);
void agp_free_cdev(device_t dev);
void agp_free_gatt(struct agp_gatt *gatt);
void agp_free_res(device_t dev);
int agp_generic_attach(device_t dev);
int agp_generic_detach(device_t dev);
int agp_generic_get_aperture(device_t dev);
int agp_generic_set_aperture(device_t dev,
u_int32_t aperture);
int agp_generic_enable(device_t dev, u_int32_t mode);
struct agp_memory *agp_generic_alloc_memory(device_t dev, int type,
vm_size_t size);
int agp_generic_free_memory(device_t dev,
struct agp_memory *mem);
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);
#endif /* !_PCI_AGPPRIV_H_ */

View File

@ -1,328 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _PCI_AGPREG_H_
#define _PCI_AGPREG_H_
/*
* Offsets for various AGP configuration registers.
*/
#define AGP_APBASE PCIR_BAR(0)
/*
* Offsets from the AGP Capability pointer.
*/
#define AGP_CAPID 0x0
#define AGP_STATUS 0x4
#define AGP_COMMAND 0x8
#define AGP_STATUS_AGP3 0x0008
#define AGP_STATUS_RQ_MASK 0xff000000
#define AGP_COMMAND_RQ_MASK 0xff000000
#define AGP_STATUS_ARQSZ_MASK 0xe000
#define AGP_COMMAND_ARQSZ_MASK 0xe000
#define AGP_STATUS_CAL_MASK 0x1c00
#define AGP_COMMAND_CAL_MASK 0x1c00
#define AGP_STATUS_ISOCH 0x10000
#define AGP_STATUS_SBA 0x0200
#define AGP_STATUS_ITA_COH 0x0100
#define AGP_STATUS_GART64 0x0080
#define AGP_STATUS_HTRANS 0x0040
#define AGP_STATUS_64BIT 0x0020
#define AGP_STATUS_FW 0x0010
#define AGP_COMMAND_RQ_MASK 0xff000000
#define AGP_COMMAND_ARQSZ_MASK 0xe000
#define AGP_COMMAND_CAL_MASK 0x1c00
#define AGP_COMMAND_SBA 0x0200
#define AGP_COMMAND_AGP 0x0100
#define AGP_COMMAND_GART64 0x0080
#define AGP_COMMAND_64BIT 0x0020
#define AGP_COMMAND_FW 0x0010
/*
* Config offsets for Intel AGP chipsets.
*/
#define AGP_INTEL_NBXCFG 0x50
#define AGP_INTEL_ERRSTS 0x91
#define AGP_INTEL_AGPCTRL 0xb0
#define AGP_INTEL_APSIZE 0xb4
#define AGP_INTEL_ATTBASE 0xb8
/*
* Config offsets for Intel i8xx/E7xxx AGP chipsets.
*/
#define AGP_INTEL_MCHCFG 0x50
#define AGP_INTEL_I820_RDCR 0x51
#define AGP_INTEL_I845_AGPM 0x51
#define AGP_INTEL_I8XX_ERRSTS 0xc8
/*
* Config offsets for VIA AGP 2.x chipsets.
*/
#define AGP_VIA_GARTCTRL 0x80
#define AGP_VIA_APSIZE 0x84
#define AGP_VIA_ATTBASE 0x88
/*
* Config offsets for VIA AGP 3.0 chipsets.
*/
#define AGP3_VIA_GARTCTRL 0x90
#define AGP3_VIA_APSIZE 0x94
#define AGP3_VIA_ATTBASE 0x98
#define AGP_VIA_AGPSEL 0xfd
/*
* Config offsets for SiS AGP chipsets.
*/
#define AGP_SIS_ATTBASE 0x90
#define AGP_SIS_WINCTRL 0x94
#define AGP_SIS_TLBCTRL 0x97
#define AGP_SIS_TLBFLUSH 0x98
/*
* Config offsets for Ali AGP chipsets.
*/
#define AGP_ALI_AGPCTRL 0xb8
#define AGP_ALI_ATTBASE 0xbc
#define AGP_ALI_TLBCTRL 0xc0
/*
* Config offsets for the AMD 751 chipset.
*/
#define AGP_AMD751_APBASE 0x10
#define AGP_AMD751_REGISTERS 0x14
#define AGP_AMD751_APCTRL 0xac
#define AGP_AMD751_MODECTRL 0xb0
#define AGP_AMD751_MODECTRL_SYNEN 0x80
#define AGP_AMD751_MODECTRL2 0xb2
#define AGP_AMD751_MODECTRL2_G1LM 0x01
#define AGP_AMD751_MODECTRL2_GPDCE 0x02
#define AGP_AMD751_MODECTRL2_NGSE 0x08
/*
* Memory mapped register offsets for AMD 751 chipset.
*/
#define AGP_AMD751_CAPS 0x00
#define AGP_AMD751_CAPS_EHI 0x0800
#define AGP_AMD751_CAPS_P2P 0x0400
#define AGP_AMD751_CAPS_MPC 0x0200
#define AGP_AMD751_CAPS_VBE 0x0100
#define AGP_AMD751_CAPS_REV 0x00ff
#define AGP_AMD751_STATUS 0x02
#define AGP_AMD751_STATUS_P2PS 0x0800
#define AGP_AMD751_STATUS_GCS 0x0400
#define AGP_AMD751_STATUS_MPS 0x0200
#define AGP_AMD751_STATUS_VBES 0x0100
#define AGP_AMD751_STATUS_P2PE 0x0008
#define AGP_AMD751_STATUS_GCE 0x0004
#define AGP_AMD751_STATUS_VBEE 0x0001
#define AGP_AMD751_ATTBASE 0x04
#define AGP_AMD751_TLBCTRL 0x0c
/*
* Config registers for i810 device 0
*/
#define AGP_I810_SMRAM 0x70
#define AGP_I810_SMRAM_GMS 0xc0
#define AGP_I810_SMRAM_GMS_DISABLED 0x00
#define AGP_I810_SMRAM_GMS_ENABLED_0 0x40
#define AGP_I810_SMRAM_GMS_ENABLED_512 0x80
#define AGP_I810_SMRAM_GMS_ENABLED_1024 0xc0
#define AGP_I810_MISCC 0x72
#define AGP_I810_MISCC_WINSIZE 0x0001
#define AGP_I810_MISCC_WINSIZE_64 0x0000
#define AGP_I810_MISCC_WINSIZE_32 0x0001
#define AGP_I810_MISCC_PLCK 0x0008
#define AGP_I810_MISCC_PLCK_UNLOCKED 0x0000
#define AGP_I810_MISCC_PLCK_LOCKED 0x0008
#define AGP_I810_MISCC_WPTC 0x0030
#define AGP_I810_MISCC_WPTC_NOLIMIT 0x0000
#define AGP_I810_MISCC_WPTC_62 0x0010
#define AGP_I810_MISCC_WPTC_50 0x0020
#define AGP_I810_MISCC_WPTC_37 0x0030
#define AGP_I810_MISCC_RPTC 0x00c0
#define AGP_I810_MISCC_RPTC_NOLIMIT 0x0000
#define AGP_I810_MISCC_RPTC_62 0x0040
#define AGP_I810_MISCC_RPTC_50 0x0080
#define AGP_I810_MISCC_RPTC_37 0x00c0
/*
* Config registers for i810 device 1
*/
#define AGP_I810_GMADR 0x10
#define AGP_I810_MMADR 0x14
/*
* Memory mapped register offsets for i810 chipset.
*/
#define AGP_I810_PGTBL_CTL 0x2020
/**
* This field determines the actual size of the global GTT on the 965
* and G33
*/
#define AGP_I810_PGTBL_SIZE_MASK 0x0000000e
#define AGP_I810_PGTBL_SIZE_512KB (0 << 1)
#define AGP_I810_PGTBL_SIZE_256KB (1 << 1)
#define AGP_I810_PGTBL_SIZE_128KB (2 << 1)
#define AGP_I810_DRT 0x3000
#define AGP_I810_DRT_UNPOPULATED 0x00
#define AGP_I810_DRT_POPULATED 0x01
#define AGP_I810_GTT 0x10000
/*
* Config registers for i830MG device 0
*/
#define AGP_I830_GCC1 0x52
#define AGP_I830_GCC1_DEV2 0x08
#define AGP_I830_GCC1_DEV2_ENABLED 0x00
#define AGP_I830_GCC1_DEV2_DISABLED 0x08
#define AGP_I830_GCC1_GMS 0xf0 /* Top bit reserved pre-G33 */
#define AGP_I830_GCC1_GMS_STOLEN_512 0x20
#define AGP_I830_GCC1_GMS_STOLEN_1024 0x30
#define AGP_I830_GCC1_GMS_STOLEN_8192 0x40
#define AGP_I830_GCC1_GMASIZE 0x01
#define AGP_I830_GCC1_GMASIZE_64 0x01
#define AGP_I830_GCC1_GMASIZE_128 0x00
/*
* Config registers for 852GM/855GM/865G device 0
*/
#define AGP_I855_GCC1 0x52
#define AGP_I855_GCC1_DEV2 0x08
#define AGP_I855_GCC1_DEV2_ENABLED 0x00
#define AGP_I855_GCC1_DEV2_DISABLED 0x08
#define AGP_I855_GCC1_GMS 0x70
#define AGP_I855_GCC1_GMS_STOLEN_0M 0x00
#define AGP_I855_GCC1_GMS_STOLEN_1M 0x10
#define AGP_I855_GCC1_GMS_STOLEN_4M 0x20
#define AGP_I855_GCC1_GMS_STOLEN_8M 0x30
#define AGP_I855_GCC1_GMS_STOLEN_16M 0x40
#define AGP_I855_GCC1_GMS_STOLEN_32M 0x50
/*
* 852GM/855GM variant identification
*/
#define AGP_I85X_CAPID 0x44
#define AGP_I85X_VARIANT_MASK 0x7
#define AGP_I85X_VARIANT_SHIFT 5
#define AGP_I855_GME 0x0
#define AGP_I855_GM 0x4
#define AGP_I852_GME 0x2
#define AGP_I852_GM 0x5
/*
* 915G registers
*/
#define AGP_I915_GMADR 0x18
#define AGP_I915_MMADR 0x10
#define AGP_I915_GTTADR 0x1C
#define AGP_I915_GCC1_GMS_STOLEN_48M 0x60
#define AGP_I915_GCC1_GMS_STOLEN_64M 0x70
#define AGP_I915_DEVEN 0x54
#define AGP_I915_DEVEN_D2F0 0x08
#define AGP_I915_DEVEN_D2F0_ENABLED 0x08
#define AGP_I915_DEVEN_D2F0_DISABLED 0x00
#define AGP_I915_MSAC 0x62
#define AGP_I915_MSAC_GMASIZE 0x02
#define AGP_I915_MSAC_GMASIZE_128 0x02
#define AGP_I915_MSAC_GMASIZE_256 0x00
/*
* G965 registers
*/
#define AGP_I965_GTTMMADR 0x10
#define AGP_I965_MSAC 0x62
#define AGP_I965_MSAC_GMASIZE_128 0x00
#define AGP_I965_MSAC_GMASIZE_256 0x02
#define AGP_I965_MSAC_GMASIZE_512 0x06
/*
* G33 registers
*/
#define AGP_G33_GCC1_GMS_STOLEN_128M 0x80
#define AGP_G33_GCC1_GMS_STOLEN_256M 0x90
/*
* NVIDIA nForce/nForce2 registers
*/
#define AGP_NVIDIA_0_APBASE 0x10
#define AGP_NVIDIA_0_APSIZE 0x80
#define AGP_NVIDIA_1_WBC 0xf0
#define AGP_NVIDIA_2_GARTCTRL 0xd0
#define AGP_NVIDIA_2_APBASE 0xd8
#define AGP_NVIDIA_2_APLIMIT 0xdc
#define AGP_NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4)
#define AGP_NVIDIA_3_APBASE 0x50
#define AGP_NVIDIA_3_APLIMIT 0x54
/*
* AMD64 GART registers
*/
#define AGP_AMD64_APCTRL 0x90
#define AGP_AMD64_APBASE 0x94
#define AGP_AMD64_ATTBASE 0x98
#define AGP_AMD64_CACHECTRL 0x9c
#define AGP_AMD64_APCTRL_GARTEN 0x00000001
#define AGP_AMD64_APCTRL_SIZE_MASK 0x0000000e
#define AGP_AMD64_APCTRL_DISGARTCPU 0x00000010
#define AGP_AMD64_APCTRL_DISGARTIO 0x00000020
#define AGP_AMD64_APCTRL_DISWLKPRB 0x00000040
#define AGP_AMD64_APBASE_MASK 0x00007fff
#define AGP_AMD64_ATTBASE_MASK 0xfffffff0
#define AGP_AMD64_CACHECTRL_INVGART 0x00000001
#define AGP_AMD64_CACHECTRL_PTEERR 0x00000002
/*
* NVIDIA nForce3 registers
*/
#define AGP_AMD64_NVIDIA_0_APBASE 0x10
#define AGP_AMD64_NVIDIA_1_APBASE1 0x50
#define AGP_AMD64_NVIDIA_1_APLIMIT1 0x54
#define AGP_AMD64_NVIDIA_1_APSIZE 0xa8
#define AGP_AMD64_NVIDIA_1_APBASE2 0xd8
#define AGP_AMD64_NVIDIA_1_APLIMIT2 0xdc
/*
* ULi M1689 registers
*/
#define AGP_AMD64_ULI_APBASE 0x10
#define AGP_AMD64_ULI_HTT_FEATURE 0x50
#define AGP_AMD64_ULI_ENU_SCR 0x54
/*
* ATI IGP registers
*/
#define ATI_GART_MMADDR 0x14
#define ATI_RS100_APSIZE 0xac
#define ATI_RS100_IG_AGPMODE 0xb0
#define ATI_RS300_APSIZE 0xf8
#define ATI_RS300_IG_AGPMODE 0xfc
#define ATI_GART_FEATURE_ID 0x00
#define ATI_GART_BASE 0x04
#define ATI_GART_CACHE_CNTRL 0x0c
#endif /* !_PCI_AGPREG_H_ */

View File

@ -1,125 +0,0 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _PCI_AGPVAR_H_
#define _PCI_AGPVAR_H_
/*
* The AGP chipset can be acquired by user or kernel code. If the
* chipset has already been acquired, it cannot be acquired by another
* user until the previous user has released it.
*/
enum agp_acquire_state {
AGP_ACQUIRE_FREE,
AGP_ACQUIRE_USER,
AGP_ACQUIRE_KERNEL
};
/*
* This structure is used to query the state of the AGP system.
*/
struct agp_info {
u_int32_t ai_mode;
vm_offset_t ai_aperture_base;
vm_size_t ai_aperture_size;
vm_size_t ai_memory_allowed;
vm_size_t ai_memory_used;
u_int32_t ai_devid;
};
struct agp_memory_info {
vm_size_t ami_size; /* size in bytes */
vm_offset_t ami_physical; /* bogus hack for i810 */
vm_offset_t ami_offset; /* page offset if bound */
int ami_is_bound; /* non-zero if bound */
};
/*
* Find the AGP device and return it.
*/
device_t agp_find_device(void);
/*
* Return the current owner of the AGP chipset.
*/
enum agp_acquire_state agp_state(device_t dev);
/*
* Query the state of the AGP system.
*/
void agp_get_info(device_t dev, struct agp_info *info);
/*
* Acquire the AGP chipset for use by the kernel. Returns EBUSY if the
* AGP chipset is already acquired by another user.
*/
int agp_acquire(device_t dev);
/*
* Release the AGP chipset.
*/
int agp_release(device_t dev);
/*
* Enable the agp hardware with the relavent mode. The mode bits are
* defined in <pci/agpreg.h>
*/
int agp_enable(device_t dev, u_int32_t mode);
/*
* Allocate physical memory suitable for mapping into the AGP
* aperture. The value returned is an opaque handle which can be
* passed to agp_bind(), agp_unbind() or agp_deallocate().
*/
void *agp_alloc_memory(device_t dev, int type, vm_size_t bytes);
/*
* Free memory which was allocated with agp_allocate().
*/
void agp_free_memory(device_t dev, void *handle);
/*
* Bind memory allocated with agp_allocate() at a given offset within
* the AGP aperture. Returns EINVAL if the memory is already bound or
* the offset is not at an AGP page boundary.
*/
int agp_bind_memory(device_t dev, void *handle, vm_offset_t offset);
/*
* Unbind memory from the AGP aperture. Returns EINVAL if the memory
* is not bound.
*/
int agp_unbind_memory(device_t dev, void *handle);
/*
* Retrieve information about a memory block allocated with
* agp_alloc_memory().
*/
void agp_memory_info(device_t dev, void *handle, struct agp_memory_info *mi);
#endif /* !_PCI_AGPVAR_H_ */

View File

@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 800003 /* Master, propagated to newvers */
#define __FreeBSD_version 800004 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>