aboutsummaryrefslogtreecommitdiff
path: root/graphics/utah-glx
diff options
context:
space:
mode:
authorMaxim Sobolev <sobomax@FreeBSD.org>2000-11-08 11:19:39 +0000
committerMaxim Sobolev <sobomax@FreeBSD.org>2000-11-08 11:19:39 +0000
commit1c63df741c56103647fd318578117b7ccbd73818 (patch)
tree6a9bd7851a9f6c628248286ed8aceb03f36b80c5 /graphics/utah-glx
parentda6242698dd8210973de3f9a486ae90c370d5362 (diff)
downloadports-1c63df741c56103647fd318578117b7ccbd73818.tar.gz
ports-1c63df741c56103647fd318578117b7ccbd73818.zip
Add MTRR support.
PR: 21901 Submitted by: Alexander N. Kabaev <ak03@gte.com>
Notes
Notes: svn path=/head/; revision=34912
Diffstat (limited to 'graphics/utah-glx')
-rw-r--r--graphics/utah-glx/Makefile1
-rw-r--r--graphics/utah-glx/files/patch-af29
-rw-r--r--graphics/utah-glx/files/patch-ag364
-rw-r--r--graphics/utah-glx/files/patch-ah20
4 files changed, 412 insertions, 2 deletions
diff --git a/graphics/utah-glx/Makefile b/graphics/utah-glx/Makefile
index 3c6b0bcf211f..af82b044de02 100644
--- a/graphics/utah-glx/Makefile
+++ b/graphics/utah-glx/Makefile
@@ -7,6 +7,7 @@
PORTNAME= utah-glx
PORTVERSION= 0.9.20000824
+PORTREVISION= 1
CATEGORIES= graphics
MASTER_SITES= ${MASTER_SITE_LOCAL}
MASTER_SITE_SUBDIR= sobomax
diff --git a/graphics/utah-glx/files/patch-af b/graphics/utah-glx/files/patch-af
index 39dde9437d15..05954672444e 100644
--- a/graphics/utah-glx/files/patch-af
+++ b/graphics/utah-glx/files/patch-af
@@ -1,5 +1,30 @@
---- configure.in.orig Fri Jun 23 12:23:13 2000
-+++ configure.in Fri Jun 23 12:30:06 2000
+--- configure.in.orig Thu Aug 24 09:53:45 2000
++++ configure.in Mon Oct 9 21:39:56 2000
+@@ -846,19 +846,19 @@
+ AC_HEADER_STDC
+ AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h unistd.h floatingpoint.h \
+ sys/types.h sys/mman.h sys/perm.h asm/sigcontext.h)
+-AC_CHECK_HEADER(asm/mtrr.h,
++AC_CHECK_HEADER(sys/memrange.h,
+ [
+ if test "$enable_mtrr" = "no"
+ then
+ echo "disabling mtrr (manual override)"
+ cflags="$cflags -DNO_MTRR"
+ else
+- dnl For some reason, some <asm/mtrr.h> files are incomplete
++ dnl For some reason, some <sys/memrange.h> files are incomplete
+ dnl Verify the validity of the file here
+- AC_MSG_CHECKING(validity of asm/mtrr.h)
++ AC_MSG_CHECKING(validity of sys/memrange.h)
+ AC_EGREP_CPP([GLX_maGiC_VALID],[
+-#include <asm/mtrr.h>
+-#ifdef MTRRIOC_ADD_ENTRY
++#include <sys/memrange.h>
++#ifdef MDF_WRITECOMBINE
+ GLX_maGiC_VALID
+ #endif
+ ],
@@ -879,7 +879,7 @@
])
diff --git a/graphics/utah-glx/files/patch-ag b/graphics/utah-glx/files/patch-ag
new file mode 100644
index 000000000000..f73242728f07
--- /dev/null
+++ b/graphics/utah-glx/files/patch-ag
@@ -0,0 +1,364 @@
+--- servGL/hwglx/common/hw_mtrr.c.orig Mon Oct 9 21:42:30 2000
++++ servGL/hwglx/common/hw_mtrr.c Mon Oct 9 21:42:55 2000
+@@ -1,4 +1,3 @@
+-
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <unistd.h>
+@@ -7,13 +6,15 @@
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <signal.h>
++#include <sys/ioctl.h>
+
+ #include "glx_symbols.h"
+ #include "hwlog.h"
+
+-
+ #ifndef NO_MTRR
+
++#ifdef linux
++
+ #define MTRR_NEED_STRINGS
+ #include <errno.h>
+ #include <asm/mtrr.h>
+@@ -237,6 +238,339 @@
+ sentry.base, sentry.size );
+ }
+ }
++
++#endif
++
++#if defined(__FreeBSD__) || defined(__NetBSD__)
++
++#ifndef __NetBSD__
++#include <sys/memrange.h>
++#else
++#include "memrange.h"
++#endif
++#define X_MTRR_ID "XFree86"
++
++typedef struct x_RangeRec {
++ struct mem_range_desc mrd;
++ int wasWC;
++ struct x_RangeRec * next;
++} RangeRec, *RangePtr;
++
++static RangePtr savedRangeList = NULL;
++static int devMemFd = -1;
++
++/*
++ * getAllRanges returns the full list of memory ranges with attributes set.
++ */
++
++static struct mem_range_desc *
++getAllRanges(int *nmr)
++{
++ struct mem_range_desc *mrd;
++ struct mem_range_op mro;
++
++ /*
++ * Find how many ranges there are. If this fails, then the kernel
++ * probably doesn't have MTRR *support.
++ */
++ mro.mo_arg[0] = 0;
++ if (ioctl(devMemFd, MEMRANGE_GET, &mro))
++ return NULL;
++ *nmr = mro.mo_arg[0];
++ mrd = (struct mem_range_desc *)xalloc(*nmr * sizeof(struct mem_range_desc));
++ mro.mo_arg[0] = *nmr;
++ mro.mo_desc = mrd;
++ if (ioctl(devMemFd, MEMRANGE_GET, &mro)) {
++ xfree(mrd);
++ return NULL;
++ }
++ return mrd;
++}
++
++static void
++freeRangeList(RangePtr range)
++{
++ RangePtr rp;
++
++ while (range) {
++ rp = range;
++ range = rp->next;
++ xfree(rp);
++ }
++}
++
++static RangePtr
++dupRangeList(RangePtr list)
++{
++ RangePtr new = NULL, rp, p;
++
++ rp = list;
++ while (rp) {
++ p = (RangePtr)xalloc(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 = (RangePtr)xalloc(sizeof(RangeRec));
++ rp->mrd = mrd[i];
++ rp->next = *p;
++ *p = rp;
++ }
++ }
++ xfree(mrd);
++}
++
++/*
++ * This checks if the existing overlapping ranges fully cover the requested
++ * range. Is this overkill?
++ */
++
++static int
++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 1;
++ }
++ rp1 = rp1->next;
++ }
++ freeRangeList(sorted);
++ return 0;
++}
++
++static RangePtr
++addWC(unsigned long base, unsigned long size)
++{
++ 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)) {
++ hwMsg(1, "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)) {
++ hwError("Failed to set write-combining range "
++ "(0x%lx,0x%lx)\n", base, size);
++ return NULL;
++ } else {
++ hwMsg(1, "Write-combining range (0x%lx,0x%lx)\n", base, size);
++ retlist = (RangePtr)xalloc(sizeof(RangeRec));
++ retlist->mrd = mrd;
++ retlist->wasWC = FALSE;
++ retlist->next = NULL;
++ return retlist;
++ }
++}
++
++static void
++undoWC(RangePtr rp)
++{
++ struct mem_range_op mro;
++ int failed;
++
++ while (rp) {
++ hwMsg(1,"Undo for (0x%lx,0x%lx), %d\n",
++ (unsigned long)rp->mrd.mr_base,
++ (unsigned long)rp->mrd.mr_len, rp->wasWC);
++ 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) {
++ hwError("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;
++ }
++}
++
++static int
++cleanMTRR()
++{
++ struct mem_range_desc *mrd;
++ struct mem_range_op mro;
++ int nmr, i;
++
++ /* This shouldn't happen */
++ if (devMemFd < 0)
++ return FALSE;
++
++ if (!(mrd = getAllRanges(&nmr)))
++ return FALSE;
++
++ for (i = 0; i < nmr; i++) {
++ if (strcmp(mrd[i].mr_owner, X_MTRR_ID) == 0 &&
++ (mrd[i].mr_flags & MDF_ACTIVE)) {
++ hwMsg( 1,"Clean for (0x%lx,0x%lx)\n",
++ (unsigned long)mrd[i].mr_base,
++ (unsigned long)mrd[i].mr_len);
++ if (mrd[i].mr_flags & MDF_FIXACTIVE) {
++ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
++ mrd[i].mr_flags = MDF_UNCACHEABLE;
++ } else {
++ mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
++ }
++ mro.mo_desc = mrd + i;
++ ioctl(devMemFd, MEMRANGE_SET, &mro);
++ }
++ }
++ xfree(mrd);
++ return TRUE;
++}
++
++static void CloseMTRR( void )
++{
++ undoWC(savedRangeList);
++ close(devMemFd);
++}
++
++static void OpenMTRR( void )
++{
++ if ( ( devMemFd = open( "/dev/mem", O_RDWR, 0 ) ) == -1 )
++ {
++ hwError( "Error opening /dev/mem: %s\n", strerror( errno ) );
++ hwError( "MTRR not enabled\n" );
++ return;
++ }
++
++ if ( !cleanMTRR() ) {
++ close(devMemFd);
++ devMemFd = -1;
++ return;
++ }
++
++ atexit( CloseMTRR );
++}
++
++void SetWriteCombining( long physical, int bytes )
++{
++ RangePtr rp;
++
++ if ( devMemFd < 0 ) {
++ OpenMTRR();
++ }
++
++ if ( devMemFd < 0 ) {
++ return;
++ }
++
++ rp = addWC(physical, bytes);
++
++ if ( NULL != rp ) {
++ rp->next = savedRangeList;
++ savedRangeList = rp;
++ }
++}
++
++
++#endif /* end of BSD MTRR support */
+
+ /*
+ * FlushWriteCombining
diff --git a/graphics/utah-glx/files/patch-ah b/graphics/utah-glx/files/patch-ah
new file mode 100644
index 000000000000..fff204b6df5b
--- /dev/null
+++ b/graphics/utah-glx/files/patch-ah
@@ -0,0 +1,20 @@
+--- servGL/hwglx/mga/mgadirect.c.orig Mon Oct 9 21:47:35 2000
++++ servGL/hwglx/mga/mgadirect.c Mon Oct 9 21:48:18 2000
+@@ -62,17 +62,6 @@
+ #include "glx_clients.h"
+ #include "glx_init.h"
+
+-#ifndef NO_MTRR
+-#define MTRR_NEED_STRINGS
+-#include <errno.h>
+-#include <asm/mtrr.h>
+-#include <fcntl.h>
+-#include <sys/ioctl.h>
+-#include <unistd.h>
+-int mtrr;
+-void mgaCloseMTRR();
+-#endif
+-
+ #include "xf86_OSproc.h"
+
+