xfree86: Remove {set,undo}WC from VidMemInfo
Now that mapMem is gone this can never actually get called. Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
9db2af6f75
commit
ec0e29ed5b
|
@ -86,15 +86,8 @@ static int devMemFd = -1;
|
|||
#endif
|
||||
|
||||
#ifdef HAS_MTRR_SUPPORT
|
||||
static void *setWC(int, unsigned long, unsigned long, Bool, MessageType);
|
||||
static void undoWC(int, void *);
|
||||
static Bool cleanMTRR(void);
|
||||
#endif
|
||||
#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
|
||||
static void *NetBSDsetWC(int, unsigned long, unsigned long, Bool,
|
||||
MessageType);
|
||||
static void NetBSDundoWC(int, void *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if /dev/mem can be mmap'd. If it can't print a warning when
|
||||
|
@ -192,15 +185,8 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
|
|||
|
||||
#ifdef HAS_MTRR_SUPPORT
|
||||
if (useDevMem) {
|
||||
if (cleanMTRR()) {
|
||||
pVidMem->setWC = setWC;
|
||||
pVidMem->undoWC = undoWC;
|
||||
}
|
||||
cleanMTRR();
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
|
||||
pVidMem->setWC = NetBSDsetWC;
|
||||
pVidMem->undoWC = NetBSDundoWC;
|
||||
#endif
|
||||
pVidMem->initialised = TRUE;
|
||||
}
|
||||
|
@ -503,334 +489,4 @@ cleanMTRR()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct x_RangeRec {
|
||||
struct mem_range_desc mrd;
|
||||
Bool wasWC;
|
||||
struct x_RangeRec *next;
|
||||
} RangeRec, *RangePtr;
|
||||
|
||||
static void
|
||||
freeRangeList(RangePtr range)
|
||||
{
|
||||
RangePtr rp;
|
||||
|
||||
while (range) {
|
||||
rp = range;
|
||||
range = rp->next;
|
||||
free(rp);
|
||||
}
|
||||
}
|
||||
|
||||
static RangePtr
|
||||
dupRangeList(RangePtr list)
|
||||
{
|
||||
RangePtr new = NULL, rp, p;
|
||||
|
||||
rp = list;
|
||||
while (rp) {
|
||||
p = xnfalloc(sizeof(RangeRec));
|
||||
*p = *rp;
|
||||
p->next = new;
|
||||
new = p;
|
||||
rp = rp->next;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
static RangePtr
|
||||
sortRangeList(RangePtr list)
|
||||
{
|
||||
RangePtr rp1, rp2, copy, sorted = NULL, minp, prev, minprev;
|
||||
unsigned long minBase;
|
||||
|
||||
/* Sort by base address */
|
||||
rp1 = copy = dupRangeList(list);
|
||||
while (rp1) {
|
||||
minBase = rp1->mrd.mr_base;
|
||||
minp = rp1;
|
||||
minprev = NULL;
|
||||
prev = rp1;
|
||||
rp2 = rp1->next;
|
||||
while (rp2) {
|
||||
if (rp2->mrd.mr_base < minBase) {
|
||||
minBase = rp2->mrd.mr_base;
|
||||
minp = rp2;
|
||||
minprev = prev;
|
||||
}
|
||||
prev = rp2;
|
||||
rp2 = rp2->next;
|
||||
}
|
||||
if (minprev) {
|
||||
minprev->next = minp->next;
|
||||
rp1 = copy;
|
||||
}
|
||||
else {
|
||||
rp1 = minp->next;
|
||||
}
|
||||
minp->next = sorted;
|
||||
sorted = minp;
|
||||
}
|
||||
return sorted;
|
||||
}
|
||||
|
||||
/*
|
||||
* findRanges returns a list of ranges that overlap the specified range.
|
||||
*/
|
||||
|
||||
static void
|
||||
findRanges(unsigned long base, unsigned long size, RangePtr * ucp,
|
||||
RangePtr * wcp)
|
||||
{
|
||||
struct mem_range_desc *mrd;
|
||||
int nmr, i;
|
||||
RangePtr rp, *p;
|
||||
|
||||
if (!(mrd = getAllRanges(&nmr)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < nmr; i++) {
|
||||
if ((mrd[i].mr_flags & MDF_ACTIVE) &&
|
||||
mrd[i].mr_base < base + size &&
|
||||
mrd[i].mr_base + mrd[i].mr_len > base) {
|
||||
if (mrd[i].mr_flags & MDF_WRITECOMBINE)
|
||||
p = wcp;
|
||||
else if (mrd[i].mr_flags & MDF_UNCACHEABLE)
|
||||
p = ucp;
|
||||
else
|
||||
continue;
|
||||
rp = xnfalloc(sizeof(RangeRec));
|
||||
rp->mrd = mrd[i];
|
||||
rp->next = *p;
|
||||
*p = rp;
|
||||
}
|
||||
}
|
||||
free(mrd);
|
||||
}
|
||||
|
||||
/*
|
||||
* This checks if the existing overlapping ranges fully cover the requested
|
||||
* range. Is this overkill?
|
||||
*/
|
||||
|
||||
static Bool
|
||||
fullCoverage(unsigned long base, unsigned long size, RangePtr overlap)
|
||||
{
|
||||
RangePtr rp1, sorted = NULL;
|
||||
unsigned long end;
|
||||
|
||||
sorted = sortRangeList(overlap);
|
||||
/* Look for gaps */
|
||||
rp1 = sorted;
|
||||
end = base + size;
|
||||
while (rp1) {
|
||||
if (rp1->mrd.mr_base > base) {
|
||||
freeRangeList(sorted);
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
base = rp1->mrd.mr_base + rp1->mrd.mr_len;
|
||||
}
|
||||
if (base >= end) {
|
||||
freeRangeList(sorted);
|
||||
return TRUE;
|
||||
}
|
||||
rp1 = rp1->next;
|
||||
}
|
||||
freeRangeList(sorted);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void *
|
||||
addWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
|
||||
{
|
||||
RangePtr uc = NULL, wc = NULL, retlist = NULL;
|
||||
struct mem_range_desc mrd;
|
||||
struct mem_range_op mro;
|
||||
|
||||
findRanges(base, size, &uc, &wc);
|
||||
|
||||
/* See of the full range is already WC */
|
||||
if (!uc && fullCoverage(base, size, wc)) {
|
||||
xf86DrvMsg(screenNum, from,
|
||||
"Write-combining range (0x%lx,0x%lx) was already set\n",
|
||||
base, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Otherwise, try to add the new range */
|
||||
mrd.mr_base = base;
|
||||
mrd.mr_len = size;
|
||||
strcpy(mrd.mr_owner, X_MTRR_ID);
|
||||
mrd.mr_flags = MDF_WRITECOMBINE;
|
||||
mro.mo_desc = &mrd;
|
||||
mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
|
||||
if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
|
||||
xf86DrvMsg(screenNum, X_WARNING,
|
||||
"Failed to set write-combining range "
|
||||
"(0x%lx,0x%lx)\n", base, size);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
xf86DrvMsg(screenNum, from,
|
||||
"Write-combining range (0x%lx,0x%lx)\n", base, size);
|
||||
retlist = xnfalloc(sizeof(RangeRec));
|
||||
retlist->mrd = mrd;
|
||||
retlist->wasWC = FALSE;
|
||||
retlist->next = NULL;
|
||||
return retlist;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
delWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
|
||||
{
|
||||
RangePtr uc = NULL, wc = NULL, retlist = NULL;
|
||||
struct mem_range_desc mrd;
|
||||
struct mem_range_op mro;
|
||||
|
||||
findRanges(base, size, &uc, &wc);
|
||||
|
||||
/*
|
||||
* See of the full range is already not WC, or if there is full
|
||||
* coverage from UC ranges.
|
||||
*/
|
||||
if (!wc || fullCoverage(base, size, uc)) {
|
||||
xf86DrvMsg(screenNum, from,
|
||||
"Write-combining range (0x%lx,0x%lx) was already clear\n",
|
||||
base, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Otherwise, try to add the new range */
|
||||
mrd.mr_base = base;
|
||||
mrd.mr_len = size;
|
||||
strcpy(mrd.mr_owner, X_MTRR_ID);
|
||||
mrd.mr_flags = MDF_UNCACHEABLE;
|
||||
mro.mo_desc = &mrd;
|
||||
mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
|
||||
if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
|
||||
xf86DrvMsg(screenNum, X_WARNING,
|
||||
"Failed to remove write-combining range "
|
||||
"(0x%lx,0x%lx)\n", base, size);
|
||||
/* XXX Should then remove all of the overlapping WC ranges */
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
xf86DrvMsg(screenNum, from,
|
||||
"Removed Write-combining range (0x%lx,0x%lx)\n", base, size);
|
||||
retlist = xnfalloc(sizeof(RangeRec));
|
||||
retlist->mrd = mrd;
|
||||
retlist->wasWC = TRUE;
|
||||
retlist->next = NULL;
|
||||
return retlist;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
|
||||
MessageType from)
|
||||
{
|
||||
if (enable)
|
||||
return addWC(screenNum, base, size, from);
|
||||
else
|
||||
return delWC(screenNum, base, size, from);
|
||||
}
|
||||
|
||||
static void
|
||||
undoWC(int screenNum, void *list)
|
||||
{
|
||||
RangePtr rp;
|
||||
struct mem_range_op mro;
|
||||
Bool failed;
|
||||
|
||||
rp = list;
|
||||
while (rp) {
|
||||
#ifdef DEBUG
|
||||
ErrorF("Undo for (0x%lx,0x%lx), %d\n",
|
||||
(unsigned long) rp->mrd.mr_base,
|
||||
(unsigned long) rp->mrd.mr_len, rp->wasWC);
|
||||
#endif
|
||||
failed = FALSE;
|
||||
if (rp->wasWC) {
|
||||
mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
|
||||
rp->mrd.mr_flags = MDF_WRITECOMBINE;
|
||||
strcpy(rp->mrd.mr_owner, "unknown");
|
||||
}
|
||||
else {
|
||||
mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
|
||||
}
|
||||
mro.mo_desc = &rp->mrd;
|
||||
|
||||
if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
|
||||
if (!rp->wasWC) {
|
||||
mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
|
||||
rp->mrd.mr_flags = MDF_UNCACHEABLE;
|
||||
strcpy(rp->mrd.mr_owner, "unknown");
|
||||
if (ioctl(devMemFd, MEMRANGE_SET, &mro))
|
||||
failed = TRUE;
|
||||
}
|
||||
else
|
||||
failed = TRUE;
|
||||
}
|
||||
if (failed) {
|
||||
xf86DrvMsg(screenNum, X_WARNING,
|
||||
"Failed to restore MTRR range (0x%lx,0x%lx)\n",
|
||||
(unsigned long) rp->mrd.mr_base,
|
||||
(unsigned long) rp->mrd.mr_len);
|
||||
}
|
||||
rp = rp->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAS_MTRR_SUPPORT */
|
||||
|
||||
#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
|
||||
static void *
|
||||
NetBSDsetWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
|
||||
MessageType from)
|
||||
{
|
||||
struct mtrr *mtrrp;
|
||||
int n;
|
||||
|
||||
xf86DrvMsg(screenNum, X_WARNING,
|
||||
"%s MTRR %lx - %lx\n", enable ? "set" : "remove",
|
||||
base, (base + size));
|
||||
|
||||
mtrrp = xnfalloc(sizeof(struct mtrr));
|
||||
mtrrp->base = base;
|
||||
mtrrp->len = size;
|
||||
mtrrp->type = MTRR_TYPE_WC;
|
||||
|
||||
/*
|
||||
* MTRR_PRIVATE will make this MTRR get reset automatically
|
||||
* if this process exits, so we have no need for an explicit
|
||||
* cleanup operation when starting a new server.
|
||||
*/
|
||||
|
||||
if (enable)
|
||||
mtrrp->flags = MTRR_VALID | MTRR_PRIVATE;
|
||||
else
|
||||
mtrrp->flags = 0;
|
||||
n = 1;
|
||||
|
||||
if (i386_set_mtrr(mtrrp, &n) < 0) {
|
||||
free(mtrrp);
|
||||
return NULL;
|
||||
}
|
||||
return mtrrp;
|
||||
}
|
||||
|
||||
static void
|
||||
NetBSDundoWC(int screenNum, void *list)
|
||||
{
|
||||
struct mtrr *mtrrp = (struct mtrr *) list;
|
||||
int n;
|
||||
|
||||
if (mtrrp == NULL)
|
||||
return;
|
||||
n = 1;
|
||||
mtrrp->flags &= ~MTRR_VALID;
|
||||
i386_set_mtrr(mtrrp, &n);
|
||||
free(mtrrp);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -42,10 +42,6 @@
|
|||
#include "shared/xf86Axp.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAS_MTRR_SUPPORT
|
||||
#include <asm/mtrr.h>
|
||||
#endif
|
||||
|
||||
static Bool ExtendedEnabled = FALSE;
|
||||
|
||||
#ifdef __ia64__
|
||||
|
@ -95,265 +91,6 @@ static unsigned long hae_mask;
|
|||
static unsigned long bus_base;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_MTRR_SUPPORT
|
||||
|
||||
#define SPLIT_WC_REGIONS 1
|
||||
|
||||
static void *setWC(int, unsigned long, unsigned long, Bool, MessageType);
|
||||
static void undoWC(int, void *);
|
||||
|
||||
/* The file desc for /proc/mtrr. Once opened, left opened, and the mtrr
|
||||
driver will clean up when we exit. */
|
||||
#define MTRR_FD_UNOPENED (-1) /* We have yet to open /proc/mtrr */
|
||||
#define MTRR_FD_PROBLEM (-2) /* We tried to open /proc/mtrr, but had
|
||||
a problem. */
|
||||
static int mtrr_fd = MTRR_FD_UNOPENED;
|
||||
|
||||
/* Open /proc/mtrr. FALSE on failure. Will always fail on Linux 2.0,
|
||||
and will fail on Linux 2.2 with MTRR support configured out,
|
||||
so verbosity should be chosen appropriately. */
|
||||
static Bool
|
||||
mtrr_open(int verbosity)
|
||||
{
|
||||
/* Only report absence of /proc/mtrr once. */
|
||||
static Bool warned = FALSE;
|
||||
|
||||
if (mtrr_fd == MTRR_FD_UNOPENED) {
|
||||
mtrr_fd = open("/proc/mtrr", O_WRONLY);
|
||||
|
||||
if (mtrr_fd < 0)
|
||||
mtrr_fd = MTRR_FD_PROBLEM;
|
||||
}
|
||||
|
||||
if (mtrr_fd == MTRR_FD_PROBLEM) {
|
||||
/* To make sure we only ever warn once, need to check
|
||||
verbosity outside xf86MsgVerb */
|
||||
if (!warned && verbosity <= xf86GetVerbosity()) {
|
||||
xf86MsgVerb(X_WARNING, verbosity,
|
||||
"System lacks support for changing MTRRs\n");
|
||||
warned = TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* We maintain a list of WC regions for each physical mapping so they can
|
||||
* be undone when unmapping.
|
||||
*/
|
||||
|
||||
struct mtrr_wc_region {
|
||||
struct mtrr_sentry sentry;
|
||||
Bool added; /* added WC or removed it */
|
||||
struct mtrr_wc_region *next;
|
||||
};
|
||||
|
||||
static struct mtrr_wc_region *
|
||||
mtrr_cull_wc_region(int screenNum, unsigned long base, unsigned long size,
|
||||
MessageType from)
|
||||
{
|
||||
/* Some BIOS writers thought that setting wc over the mmio
|
||||
region of a graphics devices was a good idea. Try to fix
|
||||
it. */
|
||||
|
||||
struct mtrr_gentry gent;
|
||||
struct mtrr_wc_region *wcreturn = NULL, *wcr;
|
||||
int count, ret = 0;
|
||||
|
||||
/* Linux 2.0 users should not get a warning without -verbose */
|
||||
if (!mtrr_open(2))
|
||||
return NULL;
|
||||
|
||||
for (gent.regnum = 0;
|
||||
ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0; gent.regnum++) {
|
||||
if (gent.type != MTRR_TYPE_WRCOMB
|
||||
|| gent.base + gent.size <= base || base + size <= gent.base)
|
||||
continue;
|
||||
|
||||
/* Found an overlapping region. Delete it. */
|
||||
|
||||
wcr = malloc(sizeof(*wcr));
|
||||
if (!wcr)
|
||||
return NULL;
|
||||
wcr->sentry.base = gent.base;
|
||||
wcr->sentry.size = gent.size;
|
||||
wcr->sentry.type = MTRR_TYPE_WRCOMB;
|
||||
wcr->added = FALSE;
|
||||
|
||||
count = 3;
|
||||
while (count-- &&
|
||||
(ret = ioctl(mtrr_fd, MTRRIOC_KILL_ENTRY, &(wcr->sentry))) < 0);
|
||||
|
||||
if (ret >= 0) {
|
||||
xf86DrvMsg(screenNum, from,
|
||||
"Removed MMIO write-combining range "
|
||||
"(0x%lx,0x%lx)\n",
|
||||
(unsigned long) gent.base, (unsigned long) gent.size);
|
||||
wcr->next = wcreturn;
|
||||
wcreturn = wcr;
|
||||
gent.regnum--;
|
||||
}
|
||||
else {
|
||||
free(wcr);
|
||||
xf86DrvMsgVerb(screenNum, X_WARNING, 0,
|
||||
"Failed to remove MMIO "
|
||||
"write-combining range (0x%lx,0x%lx)\n",
|
||||
(unsigned long)gent.base, (unsigned long) gent.size);
|
||||
}
|
||||
}
|
||||
return wcreturn;
|
||||
}
|
||||
|
||||
static struct mtrr_wc_region *
|
||||
mtrr_remove_offending(int screenNum, unsigned long base, unsigned long size,
|
||||
MessageType from)
|
||||
{
|
||||
struct mtrr_gentry gent;
|
||||
struct mtrr_wc_region *wcreturn = NULL, **wcr;
|
||||
|
||||
if (!mtrr_open(2))
|
||||
return NULL;
|
||||
|
||||
wcr = &wcreturn;
|
||||
for (gent.regnum = 0;
|
||||
ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0; gent.regnum++) {
|
||||
if (gent.type == MTRR_TYPE_WRCOMB
|
||||
&& ((gent.base >= base && gent.base + gent.size < base + size) ||
|
||||
(gent.base > base && gent.base + gent.size <= base + size))) {
|
||||
*wcr = mtrr_cull_wc_region(screenNum, gent.base, gent.size, from);
|
||||
if (*wcr)
|
||||
gent.regnum--;
|
||||
while (*wcr) {
|
||||
wcr = &((*wcr)->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
return wcreturn;
|
||||
}
|
||||
|
||||
static struct mtrr_wc_region *
|
||||
mtrr_add_wc_region(int screenNum, unsigned long base, unsigned long size,
|
||||
MessageType from)
|
||||
{
|
||||
struct mtrr_wc_region **wcr, *wcreturn, *curwcr;
|
||||
|
||||
/*
|
||||
* There can be only one....
|
||||
*/
|
||||
|
||||
wcreturn = mtrr_remove_offending(screenNum, base, size, from);
|
||||
wcr = &wcreturn;
|
||||
while (*wcr) {
|
||||
wcr = &((*wcr)->next);
|
||||
}
|
||||
|
||||
/* Linux 2.0 should not warn, unless the user explicitly asks for
|
||||
WC. */
|
||||
|
||||
if (!mtrr_open(from == X_CONFIG ? 0 : 2))
|
||||
return wcreturn;
|
||||
|
||||
*wcr = curwcr = malloc(sizeof(**wcr));
|
||||
if (!curwcr)
|
||||
return wcreturn;
|
||||
|
||||
curwcr->sentry.base = base;
|
||||
curwcr->sentry.size = size;
|
||||
curwcr->sentry.type = MTRR_TYPE_WRCOMB;
|
||||
curwcr->added = TRUE;
|
||||
curwcr->next = NULL;
|
||||
|
||||
#if SPLIT_WC_REGIONS
|
||||
/*
|
||||
* Splits up the write-combining region if it is not aligned on a
|
||||
* size boundary.
|
||||
*/
|
||||
|
||||
{
|
||||
unsigned long lbase, d_size = 1;
|
||||
unsigned long n_size = size;
|
||||
unsigned long n_base = base;
|
||||
|
||||
for (lbase = n_base, d_size = 1; !(lbase & 1);
|
||||
lbase = lbase >> 1, d_size <<= 1);
|
||||
while (d_size > n_size)
|
||||
d_size = d_size >> 1;
|
||||
DebugF("WC_BASE: 0x%lx WC_END: 0x%lx\n", base, base + d_size - 1);
|
||||
n_base += d_size;
|
||||
n_size -= d_size;
|
||||
if (n_size) {
|
||||
xf86DrvMsgVerb(screenNum, X_INFO, 3, "Splitting WC range: "
|
||||
"base: 0x%lx, size: 0x%lx\n", base, size);
|
||||
curwcr->next = mtrr_add_wc_region(screenNum, n_base, n_size, from);
|
||||
}
|
||||
curwcr->sentry.size = d_size;
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
#endif /* SPLIT_WC_REGIONS */
|
||||
|
||||
if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &curwcr->sentry) >= 0) {
|
||||
/* Avoid printing on every VT switch */
|
||||
if (xf86ServerIsInitialising()) {
|
||||
xf86DrvMsg(screenNum, from,
|
||||
"Write-combining range (0x%lx,0x%lx)\n", base, size);
|
||||
}
|
||||
return wcreturn;
|
||||
}
|
||||
else {
|
||||
*wcr = curwcr->next;
|
||||
free(curwcr);
|
||||
|
||||
/* Don't complain about the VGA region: MTRR fixed
|
||||
regions aren't currently supported, but might be in
|
||||
the future. */
|
||||
if ((unsigned long) base >= 0x100000) {
|
||||
xf86DrvMsgVerb(screenNum, X_WARNING, 0,
|
||||
"Failed to set up write-combining range "
|
||||
"(0x%lx,0x%lx)\n", base, size);
|
||||
}
|
||||
return wcreturn;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mtrr_undo_wc_region(int screenNum, struct mtrr_wc_region *wcr)
|
||||
{
|
||||
struct mtrr_wc_region *p, *prev;
|
||||
|
||||
if (mtrr_fd >= 0) {
|
||||
p = wcr;
|
||||
while (p) {
|
||||
if (p->added)
|
||||
ioctl(mtrr_fd, MTRRIOC_DEL_ENTRY, &p->sentry);
|
||||
prev = p;
|
||||
p = p->next;
|
||||
free(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
|
||||
MessageType from)
|
||||
{
|
||||
if (enable)
|
||||
return mtrr_add_wc_region(screenNum, base, size, from);
|
||||
else
|
||||
return mtrr_cull_wc_region(screenNum, base, size, from);
|
||||
}
|
||||
|
||||
static void
|
||||
undoWC(int screenNum, void *regioninfo)
|
||||
{
|
||||
mtrr_undo_wc_region(screenNum, regioninfo);
|
||||
}
|
||||
|
||||
#endif /* HAS_MTRR_SUPPORT */
|
||||
|
||||
void
|
||||
xf86OSInitVidMem(VidMemInfoPtr pVidMem)
|
||||
{
|
||||
|
@ -375,10 +112,6 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
|
|||
}
|
||||
#endif /* __alpha__ */
|
||||
|
||||
#ifdef HAS_MTRR_SUPPORT
|
||||
pVidMem->setWC = setWC;
|
||||
pVidMem->undoWC = undoWC;
|
||||
#endif
|
||||
pVidMem->initialised = TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ xf86CheckMTRR(int ScreenNum)
|
|||
*/
|
||||
checkMtrrOption(vp);
|
||||
|
||||
if (vp->mtrrEnabled && vidMemInfo.setWC)
|
||||
if (vp->mtrrEnabled)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
|
|
|
@ -32,14 +32,8 @@
|
|||
#ifndef _XF86OSPRIV_H
|
||||
#define _XF86OSPRIV_H
|
||||
|
||||
typedef void *(*SetWCProcPtr) (int, unsigned long, unsigned long, Bool,
|
||||
MessageType);
|
||||
typedef void (*UndoWCProcPtr) (int, void *);
|
||||
|
||||
typedef struct {
|
||||
Bool initialised;
|
||||
SetWCProcPtr setWC;
|
||||
UndoWCProcPtr undoWC;
|
||||
Bool linearSupported;
|
||||
} VidMemInfo, *VidMemInfoPtr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user