mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2025-01-11 17:04:19 +01:00
Fix the AMD 751 AGP minidriver so that it works with my test code.
This commit is contained in:
parent
493031794a
commit
111618cb42
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=61501
@ -90,9 +90,13 @@ static devclass_t agp_devclass;
|
||||
|
||||
/* Helper functions for implementing chipset mini drivers. */
|
||||
|
||||
void
|
||||
agp_flush_cache()
|
||||
{
|
||||
#ifdef __i386__
|
||||
#define agp_flush_cache() wbinvd()
|
||||
wbinvd();
|
||||
#endif
|
||||
}
|
||||
|
||||
u_int8_t
|
||||
agp_find_caps(device_t dev)
|
||||
|
@ -49,20 +49,107 @@
|
||||
#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_vdir; /* virtual address of page dir */
|
||||
vm_offset_t ag_pdir; /* physical address of page dir */
|
||||
u_int32_t *ag_virtual; /* virtual address of gatt */
|
||||
};
|
||||
|
||||
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_gatt *gatt;
|
||||
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;
|
||||
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
gatt->ag_pdir = vtophys(gatt->ag_virtual);
|
||||
|
||||
/*
|
||||
* Map the pages of the GATT into the page directory.
|
||||
*/
|
||||
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] = 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)
|
||||
{
|
||||
@ -100,7 +187,7 @@ static int
|
||||
agp_amd_attach(device_t dev)
|
||||
{
|
||||
struct agp_amd_softc *sc = device_get_softc(dev);
|
||||
struct agp_gatt *gatt;
|
||||
struct agp_amd_gatt *gatt;
|
||||
int error, rid;
|
||||
|
||||
error = agp_generic_attach(dev);
|
||||
@ -121,7 +208,7 @@ agp_amd_attach(device_t dev)
|
||||
sc->initial_aperture = AGP_GET_APERTURE(dev);
|
||||
|
||||
for (;;) {
|
||||
gatt = agp_alloc_gatt(dev);
|
||||
gatt = agp_amd_alloc_gatt(dev);
|
||||
if (gatt)
|
||||
break;
|
||||
|
||||
@ -135,17 +222,24 @@ agp_amd_attach(device_t dev)
|
||||
sc->gatt = gatt;
|
||||
|
||||
/* Install the gatt. */
|
||||
WRITE4(AGP_AMD751_ATTBASE, gatt->ag_physical);
|
||||
WRITE4(AGP_AMD751_ATTBASE, gatt->ag_pdir);
|
||||
|
||||
/* Enable synchronisation between host and agp. */
|
||||
pci_write_config(dev, AGP_AMD751_MODECTRL, 0x80, 1);
|
||||
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 agp_generic_attach(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -166,7 +260,7 @@ agp_amd_detach(device_t dev)
|
||||
/* Put the aperture back the way it started. */
|
||||
AGP_SET_APERTURE(dev, sc->initial_aperture);
|
||||
|
||||
agp_free_gatt(sc->gatt);
|
||||
agp_amd_free_gatt(sc->gatt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,7 @@ struct agp_gatt {
|
||||
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_free_gatt(struct agp_gatt *gatt);
|
||||
|
@ -84,6 +84,11 @@
|
||||
#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.
|
||||
|
@ -90,9 +90,13 @@ static devclass_t agp_devclass;
|
||||
|
||||
/* Helper functions for implementing chipset mini drivers. */
|
||||
|
||||
void
|
||||
agp_flush_cache()
|
||||
{
|
||||
#ifdef __i386__
|
||||
#define agp_flush_cache() wbinvd()
|
||||
wbinvd();
|
||||
#endif
|
||||
}
|
||||
|
||||
u_int8_t
|
||||
agp_find_caps(device_t dev)
|
||||
|
@ -49,20 +49,107 @@
|
||||
#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_vdir; /* virtual address of page dir */
|
||||
vm_offset_t ag_pdir; /* physical address of page dir */
|
||||
u_int32_t *ag_virtual; /* virtual address of gatt */
|
||||
};
|
||||
|
||||
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_gatt *gatt;
|
||||
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;
|
||||
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
gatt->ag_pdir = vtophys(gatt->ag_virtual);
|
||||
|
||||
/*
|
||||
* Map the pages of the GATT into the page directory.
|
||||
*/
|
||||
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] = 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)
|
||||
{
|
||||
@ -100,7 +187,7 @@ static int
|
||||
agp_amd_attach(device_t dev)
|
||||
{
|
||||
struct agp_amd_softc *sc = device_get_softc(dev);
|
||||
struct agp_gatt *gatt;
|
||||
struct agp_amd_gatt *gatt;
|
||||
int error, rid;
|
||||
|
||||
error = agp_generic_attach(dev);
|
||||
@ -121,7 +208,7 @@ agp_amd_attach(device_t dev)
|
||||
sc->initial_aperture = AGP_GET_APERTURE(dev);
|
||||
|
||||
for (;;) {
|
||||
gatt = agp_alloc_gatt(dev);
|
||||
gatt = agp_amd_alloc_gatt(dev);
|
||||
if (gatt)
|
||||
break;
|
||||
|
||||
@ -135,17 +222,24 @@ agp_amd_attach(device_t dev)
|
||||
sc->gatt = gatt;
|
||||
|
||||
/* Install the gatt. */
|
||||
WRITE4(AGP_AMD751_ATTBASE, gatt->ag_physical);
|
||||
WRITE4(AGP_AMD751_ATTBASE, gatt->ag_pdir);
|
||||
|
||||
/* Enable synchronisation between host and agp. */
|
||||
pci_write_config(dev, AGP_AMD751_MODECTRL, 0x80, 1);
|
||||
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 agp_generic_attach(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -166,7 +260,7 @@ agp_amd_detach(device_t dev)
|
||||
/* Put the aperture back the way it started. */
|
||||
AGP_SET_APERTURE(dev, sc->initial_aperture);
|
||||
|
||||
agp_free_gatt(sc->gatt);
|
||||
agp_amd_free_gatt(sc->gatt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,7 @@ struct agp_gatt {
|
||||
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_free_gatt(struct agp_gatt *gatt);
|
||||
|
@ -84,6 +84,11 @@
|
||||
#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.
|
||||
|
Loading…
Reference in New Issue
Block a user