summaryrefslogtreecommitdiff
path: root/hw/xfree86/os-support/linux
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/os-support/linux')
-rw-r--r--hw/xfree86/os-support/linux/lnx_init.c119
-rw-r--r--hw/xfree86/os-support/linux/lnx_io.c225
-rw-r--r--hw/xfree86/os-support/linux/lnx_jstk.c77
-rw-r--r--hw/xfree86/os-support/linux/lnx_video.c1370
4 files changed, 1203 insertions, 588 deletions
diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
index 1c0791abb..0ac8c6a8b 100644
--- a/hw/xfree86/os-support/linux/lnx_init.c
+++ b/hw/xfree86/os-support/linux/lnx_init.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c,v 3.7.2.3 1998/02/06 22:36:51 hohndel Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c,v 3.14 2001/10/31 22:50:30 tsi Exp $ */
/*
* Copyright 1992 by Orest Zborowski <obz@Kodak.com>
* Copyright 1993 by David Wexelblat <dwex@goblin.org>
@@ -23,18 +23,17 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
-/* $Xorg: lnx_init.c,v 1.3 2000/08/17 19:51:23 cpqbld Exp $ */
+/* $XConsortium: lnx_init.c /main/7 1996/10/23 18:46:30 kaleb $ */
#include "X.h"
#include "Xmd.h"
-#include "input.h"
-#include "scrnintstr.h"
#include "compiler.h"
#include "xf86.h"
-#include "xf86Procs.h"
+#include "xf86Priv.h"
#include "xf86_OSlib.h"
+#include "lnx.h"
#ifdef USE_DEV_FB
extern char *getenv(const char *);
@@ -46,52 +45,50 @@ static Bool KeepTty = FALSE;
static int VTnum = -1;
static int activeVT = -1;
-extern void xf86VTRequest(
-#if NeedFunctionPrototypes
- int
-#endif
-);
-
-void xf86OpenConsole()
+void
+xf86OpenConsole(void)
{
- int i, fd;
+ int i, fd = -1;
+ int result;
struct vt_mode VT;
char vtname[11];
struct vt_stat vts;
+ MessageType from = X_PROBED;
#ifdef USE_DEV_FB
struct fb_var_screeninfo var;
int fbfd;
#endif
+ char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
+ char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
if (serverGeneration == 1)
{
/* check if we're run with euid==0 */
if (geteuid() != 0)
{
- FatalError("xf86OpenConsole: Server must be running with root "
- "permissions\n"
- "You should be using Xwrapper to start the server or xdm.\n"
- "We strongly advise against making the server SUID root!\n");
+ FatalError("xf86OpenConsole: Server must be suid root\n");
}
/*
* setup the virtual terminal manager
*/
- if (VTnum != -1)
- {
+ if (VTnum != -1) {
xf86Info.vtno = VTnum;
- }
- else
- {
- if ((fd = open("/dev/tty0",O_WRONLY,0)) < 0)
+ from = X_CMDLINE;
+ } else {
+ i=0;
+ while (tty0[i] != NULL)
{
+ if ((fd = open(tty0[i],O_WRONLY,0)) >= 0)
+ break;
+ i++;
+ }
+ if (fd < 0)
FatalError(
"xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
strerror(errno));
- }
if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
- (xf86Info.vtno == -1))
- {
+ (xf86Info.vtno == -1)) {
FatalError("xf86OpenConsole: Cannot find a free VT\n");
}
close(fd);
@@ -107,21 +104,24 @@ void xf86OpenConsole()
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var))
FatalError("xf86OpenConsole: Unable to get screen info\n");
#endif
- ErrorF("(using VT number %d)\n\n", xf86Info.vtno);
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
- sprintf(vtname,"/dev/tty%d",xf86Info.vtno); /* /dev/tty1-64 */
-
- xf86Config(FALSE); /* Read XF86Config */
-
- if (!KeepTty)
- {
+ if (!KeepTty) {
setpgrp();
}
- if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) < 0)
- {
- FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
- vtname, strerror(errno));
+ i=0;
+ while (vcs[i] != NULL)
+ {
+ sprintf(vtname, vcs[i], xf86Info.vtno); /* /dev/tty1-64 */
+ if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) >= 0)
+ break;
+ i++;
+ }
+
+ if (xf86Info.consoleFd < 0) {
+ FatalError("xf86OpenConsole: Cannot open virtual console %d (%s)\n",
+ xf86Info.vtno, strerror(errno));
}
/* change ownership of the vt */
@@ -131,7 +131,7 @@ void xf86OpenConsole()
* the current VT device we're running on is not "console", we want
* to grab all consoles too
*
- * Why is this needed?
+ * Why is this needed??
*/
chown("/dev/tty0", getuid(), getgid());
@@ -159,17 +159,21 @@ void xf86OpenConsole()
/*
* now get the VT
*/
- if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ SYSCALL(result = ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno));
+ if (result != 0)
{
- ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n");
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
}
- if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ SYSCALL(result =
+ ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno));
+ if (result != 0)
{
- ErrorF("xf86OpenConsole: VT_WAITACTIVE failed\n");
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
}
- if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+ SYSCALL(result = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
+ if (result < 0)
{
- FatalError ("xf86OpenConsole: VT_GETMODE failed\n");
+ FatalError("xf86OpenConsole: VT_GETMODE failed\n");
}
signal(SIGUSR1, xf86VTRequest);
@@ -185,6 +189,10 @@ void xf86OpenConsole()
{
FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
}
+
+ /* we really should have a InitOSInputDevices() function instead
+ * of Init?$#*&Device(). So I just place it here */
+
#ifdef USE_DEV_FB
/* copy info to new console */
var.yoffset=0;
@@ -200,19 +208,23 @@ void xf86OpenConsole()
/*
* now get the VT
*/
- if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ SYSCALL(result = ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno));
+ if (result != 0)
{
- ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n");
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
}
- if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ SYSCALL(result =
+ ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno));
+ if (result != 0)
{
- ErrorF("xf86OpenConsole: VT_WAITACTIVE failed\n");
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
}
}
return;
}
-void xf86CloseConsole()
+void
+xf86CloseConsole()
{
struct vt_mode VT;
@@ -238,10 +250,8 @@ void xf86CloseConsole()
return;
}
-int xf86ProcessArgument (argc, argv, i)
-int argc;
-char *argv[];
-int i;
+int
+xf86ProcessArgument(int argc, char *argv[], int i)
{
/*
* Keep server from detaching from controlling tty. This is useful
@@ -265,7 +275,8 @@ int i;
return(0);
}
-void xf86UseMsg()
+void
+xf86UseMsg()
{
ErrorF("vtXX use the specified VT number\n");
ErrorF("-keeptty ");
diff --git a/hw/xfree86/os-support/linux/lnx_io.c b/hw/xfree86/os-support/linux/lnx_io.c
index 57a2979c5..741b9a279 100644
--- a/hw/xfree86/os-support/linux/lnx_io.c
+++ b/hw/xfree86/os-support/linux/lnx_io.c
@@ -1,7 +1,7 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c,v 3.3 1996/12/23 06:50:01 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c,v 3.24 2002/10/20 21:45:27 tsi Exp $ */
/*
* Copyright 1992 by Orest Zborowski <obz@Kodak.com>
- * Copyright 1993 by David Dawes <dawes@physics.su.oz.au>
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -23,23 +23,21 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
-/* $Xorg: lnx_io.c,v 1.3 2000/08/17 19:51:23 cpqbld Exp $ */
+/* $XConsortium: lnx_io.c /main/8 1996/10/19 18:06:28 kaleb $ */
#define NEED_EVENTS
#include "X.h"
-#include "Xproto.h"
-#include "inputstr.h"
-#include "scrnintstr.h"
#include "compiler.h"
-#include "xf86Procs.h"
+#include "xf86.h"
+#include "xf86Priv.h"
#include "xf86_OSlib.h"
-void xf86SoundKbdBell(loudness, pitch, duration)
-int loudness;
-int pitch;
-int duration;
+#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
{
if (loudness && pitch)
{
@@ -50,20 +48,100 @@ int duration;
}
}
-void xf86SetKbdLeds(leds)
-int leds;
+void
+xf86SetKbdLeds(int leds)
{
- ioctl(xf86Info.consoleFd, KDSETLED, leds);
+ ioctl(xf86Info.consoleFd, KDSETLED, leds);
}
-int xf86GetKbdLeds()
+int
+xf86GetKbdLeds()
{
- int leds;
+ int leds = 0;
- ioctl(xf86Info.consoleFd, KDGETLED, &leds);
+ ioctl(xf86Info.consoleFd, KDGETLED, &leds);
return(leds);
}
+/* kbd rate stuff based on kbdrate.c from Rik Faith <faith@cs.unc.edu> et.al.
+ * from util-linux-2.9t package */
+
+#include <linux/kd.h>
+#ifdef __sparc__
+#include <asm/param.h>
+#include <asm/kbio.h>
+#endif
+
+/* Deal with spurious kernel header change */
+#if defined(LINUX_VERSION_CODE) && defined(KERNEL_VERSION)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,42)
+# define rate period
+# endif
+#endif
+
+static int
+KDKBDREP_ioctl_ok(int rate, int delay) {
+#if defined(KDKBDREP) && !defined(__sparc__)
+ /* This ioctl is defined in <linux/kd.h> but is not
+ implemented anywhere - must be in some m68k patches. */
+ struct kbd_repeat kbdrep_s;
+
+ /* don't change, just test */
+ kbdrep_s.rate = -1;
+ kbdrep_s.delay = -1;
+ if (ioctl( 0, KDKBDREP, &kbdrep_s )) {
+ return 0;
+ }
+
+ /* do the change */
+ if (rate == 0) /* switch repeat off */
+ kbdrep_s.rate = 0;
+ else
+ kbdrep_s.rate = 10000 / rate; /* convert cps to msec */
+ if (kbdrep_s.rate < 1)
+ kbdrep_s.rate = 1;
+ kbdrep_s.delay = delay;
+ if (kbdrep_s.delay < 1)
+ kbdrep_s.delay = 1;
+
+ if (ioctl( 0, KDKBDREP, &kbdrep_s )) {
+ return 0;
+ }
+
+ return 1; /* success! */
+#else /* no KDKBDREP */
+ return 0;
+#endif /* KDKBDREP */
+}
+
+static int
+KIOCSRATE_ioctl_ok(int rate, int delay) {
+#ifdef KIOCSRATE
+ struct kbd_rate kbdrate_s;
+ int fd;
+
+ fd = open("/dev/kbd", O_RDONLY);
+ if (fd == -1)
+ return 0;
+
+ kbdrate_s.rate = (rate + 5) / 10; /* must be integer, so round up */
+ kbdrate_s.delay = delay * HZ / 1000; /* convert ms to Hz */
+ if (kbdrate_s.rate > 50)
+ kbdrate_s.rate = 50;
+
+ if (ioctl( fd, KIOCSRATE, &kbdrate_s ))
+ return 0;
+
+ close( fd );
+
+ return 1;
+#else /* no KIOCSRATE */
+ return 0;
+#endif /* KIOCSRATE */
+}
+
+#undef rate
+
#if NeedFunctionPrototypes
void xf86SetKbdRepeat(char rad)
#else
@@ -71,23 +149,101 @@ void xf86SetKbdRepeat(rad)
char rad;
#endif
{
- return;
+#ifdef __sparc__
+ int rate = 500; /* Default rate */
+ int delay = 200; /* Default delay */
+#else
+ int rate = 300; /* Default rate */
+ int delay = 250; /* Default delay */
+#endif
+
+#if defined(__alpha__) || defined (__i386__) || defined(__ia64__)
+ int i;
+ int timeout;
+ int value = 0x7f; /* Maximum delay with slowest rate */
+
+ static int valid_rates[] = { 300, 267, 240, 218, 200, 185, 171, 160, 150,
+ 133, 120, 109, 100, 92, 86, 80, 75, 67,
+ 60, 55, 50, 46, 43, 40, 37, 33, 30, 27,
+ 25, 23, 21, 20 };
+#define RATE_COUNT (sizeof( valid_rates ) / sizeof( int ))
+
+ static int valid_delays[] = { 250, 500, 750, 1000 };
+#define DELAY_COUNT (sizeof( valid_delays ) / sizeof( int ))
+#endif
+
+ if (xf86Info.kbdRate >= 0)
+ rate = xf86Info.kbdRate * 10;
+ if (xf86Info.kbdDelay >= 0)
+ delay = xf86Info.kbdDelay;
+
+
+ if(KDKBDREP_ioctl_ok(rate, delay)) /* m68k? */
+ return;
+
+ if(KIOCSRATE_ioctl_ok(rate, delay)) /* sparc? */
+ return;
+
+ if (xf86IsPc98())
+ return;
+
+#if defined(__alpha__) || defined (__i386__) || defined(__ia64__)
+
+ /* The ioport way */
+
+ for (i = 0; i < RATE_COUNT; i++)
+ if (rate >= valid_rates[i]) {
+ value &= 0x60;
+ value |= i;
+ break;
+ }
+
+ for (i = 0; i < DELAY_COUNT; i++)
+ if (delay <= valid_delays[i]) {
+ value &= 0x1f;
+ value |= i << 5;
+ break;
+ }
+
+ timeout = KBC_TIMEOUT;
+ while (((inb(0x64) & 2) == 2) && --timeout)
+ usleep(1000); /* wait */
+
+ if (timeout == 0)
+ return;
+
+ outb(0x60, 0xf3); /* set typematic rate */
+ while (((inb(0x64) & 2) == 2) && --timeout)
+ usleep(1000); /* wait */
+
+ usleep(10000);
+ outb(0x60, value);
+
+#endif /* __alpha__ || __i386__ || __ia64__ */
}
static int kbdtrans;
static struct termios kbdtty;
-void xf86KbdInit()
+void
+xf86KbdInit()
{
ioctl (xf86Info.consoleFd, KDGKBMODE, &kbdtrans);
tcgetattr (xf86Info.consoleFd, &kbdtty);
}
-int xf86KbdOn()
+int
+xf86KbdOn()
{
struct termios nTty;
+#ifdef __powerpc__
+ if (xf86Info.kbdCustomKeycodes)
+ ioctl(xf86Info.consoleFd, KDSKBMODE, K_MEDIUMRAW);
+ else
+#endif
ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW);
+
nTty = kbdtty;
nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
nTty.c_oflag = 0;
@@ -101,36 +257,11 @@ int xf86KbdOn()
return(xf86Info.consoleFd);
}
-int xf86KbdOff()
+int
+xf86KbdOff()
{
ioctl(xf86Info.consoleFd, KDSKBMODE, kbdtrans);
tcsetattr(xf86Info.consoleFd, TCSANOW, &kbdtty);
return(xf86Info.consoleFd);
}
-void xf86MouseInit(mouse)
-MouseDevPtr mouse;
-{
- return;
-}
-
-int xf86MouseOn(mouse)
-MouseDevPtr mouse;
-{
- if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
- {
- if (xf86AllowMouseOpenFail) {
- ErrorF("Cannot open mouse (%s) - Continuing...\n",
- strerror(errno));
- return(-2);
- }
- FatalError("Cannot open mouse (%s)\n", strerror(errno));
- }
-
- xf86SetupMouse(mouse);
-
- /* Flush any pending input */
- tcflush(mouse->mseFd, TCIFLUSH);
-
- return(mouse->mseFd);
-}
diff --git a/hw/xfree86/os-support/linux/lnx_jstk.c b/hw/xfree86/os-support/linux/lnx_jstk.c
index ea308c159..2423bd45e 100644
--- a/hw/xfree86/os-support/linux/lnx_jstk.c
+++ b/hw/xfree86/os-support/linux/lnx_jstk.c
@@ -1,4 +1,4 @@
-/* $Xorg: lnx_jstk.c,v 1.3 2000/08/17 19:51:23 cpqbld Exp $ */
+/* $XConsortium: lnx_jstk.c /main/7 1996/02/21 17:51:36 kaleb $ */
/* Id: lnx_jstk.c,v 1.1 1995/12/20 14:06:09 lepied Exp */
/*
* Copyright 1995 by Frederic Lepied, France. <fred@sugix.frmug.fr.net>
@@ -23,19 +23,31 @@
*
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_jstk.c,v 3.6 1996/12/23 06:50:02 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_jstk.c,v 3.13 1998/07/25 16:56:43 dawes Exp $ */
-static const char rcs_id[] = "$Xorg: lnx_jstk.c,v 1.1 1995/12/20 14:06:09 lepied Exp";
+static const char rcs_id[] = "Id: lnx_jstk.c,v 1.1 1995/12/20 14:06:09 lepied Exp";
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#define inline __inline__
#include <linux/joystick.h>
#include <fcntl.h>
#include <sys/ioctl.h>
-extern int errno;
+#ifdef XFree86LOADER
+#include "xf86.h"
+#include "xf86_ansic.h"
+#endif
+
+#if !defined(JSIOCGTIMELIMIT)
+/* make 2.1.x joystick.h backward compatable */
+#define JSIOCGTIMELIMIT JS_GET_TIMELIMIT
+#define JSIOCSTIMELIMIT JS_SET_TIMELIMIT
+#define js_status JS_DATA_TYPE
+#endif
+
/***********************************************************************
*
@@ -50,33 +62,30 @@ int
xf86JoystickOn(char *name, int *timeout, int *centerX, int *centerY)
{
int fd;
- struct JS_DATA_TYPE js;
- extern int xf86Verbose;
+ struct js_status js;
#ifdef DEBUG
ErrorF("xf86JoystickOn %s\n", name);
#endif
- if ((fd = open(name, O_RDWR | O_NDELAY)) < 0)
+ if ((fd = open(name, O_RDWR | O_NDELAY, 0)) < 0)
{
- ErrorF("Cannot open joystick '%s' (%s)\n", name,
- strerror(errno));
+ xf86Msg(X_WARNING, "Cannot open joystick '%s' (%s)\n", name,
+ strerror(errno));
return -1;
}
if (*timeout == 0) {
- if (ioctl (fd, JS_GET_TIMELIMIT, timeout) == -1) {
- Error("joystick JS_GET_TIMELIMIT ioctl");
+ if (ioctl (fd, JSIOCGTIMELIMIT, timeout) == -1) {
+ Error("joystick JSIOCGTIMELIMIT ioctl");
}
else {
- if (xf86Verbose) {
- ErrorF("(--) Joystick: timeout value = %d\n", *timeout);
- }
+ xf86Msg(X_CONFIG, "Joystick: timeout value = %d\n", *timeout);
}
}
else {
- if (ioctl(fd, JS_SET_TIMELIMIT, timeout) == -1) {
- Error("joystick JS_SET_TIMELIMIT ioctl");
+ if (ioctl(fd, JSIOCSTIMELIMIT, timeout) == -1) {
+ Error("joystick JSIOCSTIMELIMIT ioctl");
}
}
@@ -84,17 +93,13 @@ xf86JoystickOn(char *name, int *timeout, int *centerX, int *centerY)
read(fd, &js, JS_RETURN);
if (*centerX < 0) {
*centerX = js.x;
- if (xf86Verbose) {
- ErrorF("(--) Joystick: CenterX set to %d\n", *centerX);
- }
+ xf86Msg(X_CONFIG, "Joystick: CenterX set to %d\n", *centerX);
}
if (*centerY < 0) {
*centerY = js.y;
- if (xf86Verbose) {
- ErrorF("(--) Joystick: CenterY set to %d\n", *centerY);
- }
+ xf86Msg(X_CONFIG, "Joystick: CenterY set to %d\n", *centerY);
}
-
+
return fd;
}
@@ -123,9 +128,7 @@ xf86JoystickInit()
*/
int
-xf86JoystickOff(fd, doclose)
-int *fd;
-int doclose;
+xf86JoystickOff(int *fd, int doclose)
{
int oldfd;
@@ -146,14 +149,10 @@ int doclose;
*/
int
-xf86JoystickGetState(fd, x, y, buttons)
-int fd;
-int *x;
-int *y;
-int *buttons;
+xf86JoystickGetState(int fd, int *x, int *y, int *buttons)
{
- struct JS_DATA_TYPE js;
- int status;
+ struct js_status js;
+ int status;
status = read(fd, &js, JS_RETURN);
@@ -170,4 +169,16 @@ int *buttons;
return 1;
}
+#ifdef XFree86LOADER
+/*
+ * Entry point for XFree86 Loader
+ */
+void
+linux_jstkModuleInit(pointer *data, INT32 *magic)
+{
+ *magic = MAGIC_DONE;
+ *data = NULL;
+}
+#endif
+
/* end of lnx_jstk.c */
diff --git a/hw/xfree86/os-support/linux/lnx_video.c b/hw/xfree86/os-support/linux/lnx_video.c
index a29db8251..107d5595e 100644
--- a/hw/xfree86/os-support/linux/lnx_video.c
+++ b/hw/xfree86/os-support/linux/lnx_video.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c,v 3.13.2.1 1997/05/11 05:04:25 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c,v 3.64 2003/02/17 15:29:22 dawes Exp $ */
/*
* Copyright 1992 by Orest Zborowski <obz@Kodak.com>
* Copyright 1993 by David Wexelblat <dwex@goblin.org>
@@ -23,7 +23,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
-/* $Xorg: lnx_video.c,v 1.3 2000/08/17 19:51:23 cpqbld Exp $ */
+/* $XConsortium: lnx_video.c /main/9 1996/10/19 18:06:34 kaleb $ */
#include "X.h"
#include "input.h"
@@ -32,603 +32,1065 @@
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
-
+#include "xf86OSpriv.h"
+#include "lnx.h"
#ifdef __alpha__
+#include "xf86Axp.h"
+#endif
-/*
- * The Jensen lacks dense memory, thus we have to address the bus via
- * the sparse addressing scheme.
- *
- * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996
- */
-
-#ifdef TEST_JENSEN_CODE /* define to test the Sparse addressing on a non-Jensen */
-#define SPARSE (5)
-#define isJensen (1)
-#else
-#define isJensen (!_bus_base())
-#define SPARSE (7)
+#ifdef HAS_MTRR_SUPPORT
+#include <asm/mtrr.h>
#endif
-#define BUS_BASE (isJensen ? _bus_base_sparse() : _bus_base())
-#define JENSEN_SHIFT(x) (isJensen ? ((long)x<<SPARSE) : (long)x)
-#else
-#define BUS_BASE 0
-#define JENSEN_SHIFT(x) (x)
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
#endif
-/***************************************************************************/
-/* Video Memory Mapping section */
-/***************************************************************************/
+static Bool ExtendedEnabled = FALSE;
+
+#ifdef __ia64__
+
+#include "compiler.h"
+#include <sys/io.h>
+
+#elif !defined(__powerpc__) && \
+ !defined(__mc68000__) && \
+ !defined(__sparc__) && \
+ !defined(__mips__)
/*
- * Unfortunatly mmap without MAP_FIXED only works the first time :-(
- * This is now fixed in pl13 ALPHA, but still seems to have problems.
+ * Due to conflicts with "compiler.h", don't rely on <sys/io.h> to declare
+ * these.
*/
-#undef ONLY_MMAP_FIXED_WORKS
+extern int ioperm(unsigned long __from, unsigned long __num, int __turn_on);
+extern int iopl(int __level);
-#ifdef ONLY_MMAP_FIXED_WORKS
-static pointer AllocAddress[MAXSCREENS][NUM_REGIONS];
#endif
-#if 0
-static struct xf86memMap {
- int offset;
- int memSize;
-} xf86memMaps[MAXSCREENS];
-#endif
+#ifdef __alpha__
-pointer xf86MapVidMem(ScreenNum, Region, Base, Size)
-int ScreenNum;
-int Region;
-pointer Base;
-unsigned long Size;
-{
- pointer base;
- int fd;
+# ifdef LIBC_IS_FIXED
+extern void sethae(unsigned long hae);
+# else
+# include <unistd.h>
+# define sethae(x) syscall(301,x);
+# endif
-#ifdef ONLY_MMAP_FIXED_WORKS
-#ifdef __alpha__
- FatalError("xf86MapVidMem: Unexpected code for Alpha (pagesize=8k!)\n");
-#endif
- AllocAddress[ScreenNum][Region] = (pointer)xalloc(Size + 0x1000);
- if (AllocAddress[ScreenNum][Region] == NULL)
- {
- FatalError("xf86MapVidMem: can't alloc framebuffer space\n");
- }
- base = (pointer)(((unsigned int)AllocAddress[ScreenNum][Region]
- & ~0xFFF) + 0x1000);
- if ((fd = open("/dev/mem", O_RDWR)) < 0)
- {
- FatalError("xf86MapVidMem: failed to open /dev/mem (%s)\n",
- strerror(errno));
- }
- base = (pointer)mmap((caddr_t)base, Size, PROT_READ|PROT_WRITE,
- MAP_FIXED|MAP_SHARED, fd, (off_t)Base);
-#else
- if ((fd = open("/dev/mem", O_RDWR)) < 0)
- {
- FatalError("xf86MapVidMem: failed to open /dev/mem (%s)\n",
- strerror(errno));
- }
- /* This requirers linux-0.99.pl10 or above */
- base = (pointer)mmap((caddr_t)0, JENSEN_SHIFT(Size),
- PROT_READ|PROT_WRITE,
- MAP_SHARED, fd,
- (off_t)(JENSEN_SHIFT((off_t)Base) + BUS_BASE));
-#endif
- close(fd);
- if ((long)base == -1)
- {
- FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
- strerror(errno));
- }
-#if 0
- xf86memMaps[ScreenNum].offset = (int) Base;
- xf86memMaps[ScreenNum].memSize = Size;
-#endif
- return base;
-}
+/* define to test the Sparse addressing on a non-Jensen */
+# ifdef TEST_JENSEN_CODE
+# define isJensen (1)
+# else
+# define isJensen (axpSystem == JENSEN)
+# endif
-#if 0
-void xf86GetVidMemData(ScreenNum, Base, Size)
-int ScreenNum;
-int *Base;
-int *Size;
-{
- *Base = xf86memMaps[ScreenNum].offset;
- *Size = xf86memMaps[ScreenNum].memSize;
-}
-#endif
+# define BUS_BASE bus_base
-void xf86UnMapVidMem(ScreenNum, Region, Base, Size)
-int ScreenNum;
-int Region;
-pointer Base;
-unsigned long Size;
-{
- munmap((caddr_t)JENSEN_SHIFT(Base), JENSEN_SHIFT(Size));
-#ifdef ONLY_MMAP_FIXED_WORKS
- xfree(AllocAddress[ScreenNum][Region]);
-#endif
-}
+#else
-Bool xf86LinearVidMem()
-{
- return(TRUE);
-}
+#define BUS_BASE (0)
+
+#endif /* __alpha__ */
/***************************************************************************/
-/* I/O Permissions section */
+/* Video Memory Mapping section */
/***************************************************************************/
-/*
- * Linux handles regular (<= 0x3ff) ports with the TSS I/O bitmap, and
- * extended ports with the iopl() system call.
- *
- * For testing, it's useful to enable only the ports we need, but for
- * production purposes, it's faster to enable all ports.
- */
-#define ALWAYS_USE_EXTENDED
+static pointer mapVidMem(int, unsigned long, unsigned long, int);
+static void unmapVidMem(int, pointer, unsigned long);
+#if defined (__alpha__)
+static pointer mapVidMemSparse(int, unsigned long, unsigned long, int);
+extern axpDevice lnxGetAXP(void);
+static void unmapVidMemSparse(int, pointer, unsigned long);
+# if defined(JENSEN_SUPPORT)
+static pointer mapVidMemJensen(int, unsigned long, unsigned long, int);
+static void unmapVidMemJensen(int, pointer, unsigned long);
+# endif
+static axpDevice axpSystem = -1;
+static Bool needSparse;
+static unsigned long hae_thresh;
+static unsigned long hae_mask;
+static unsigned long bus_base;
+static unsigned long sparse_size;
+#endif
-#ifdef ALWAYS_USE_EXTENDED
+#ifdef HAS_MTRR_SUPPORT
-static Bool ScreenEnabled[MAXSCREENS];
-static Bool ExtendedEnabled = FALSE;
-static Bool InitDone = FALSE;
+#define SPLIT_WC_REGIONS 1
-void xf86ClearIOPortList(ScreenNum)
-int ScreenNum;
-{
- if (!InitDone)
- {
- int i;
+static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType);
+static void undoWC(int, pointer);
+
+/* 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;
- for (i = 0; i < MAXSCREENS; i++)
- ScreenEnabled[i] = FALSE;
- InitDone = TRUE;
+/* 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;
+
+ char **fn;
+ static char *mtrr_files[] = {
+ "/dev/cpu/mtrr", /* Possible future name */
+ "/proc/mtrr", /* Current name */
+ NULL
+ };
+
+ if (mtrr_fd == MTRR_FD_UNOPENED) {
+ /* So open it. */
+ for (fn = mtrr_files; mtrr_fd < 0 && *fn; fn++)
+ mtrr_fd = open(*fn, O_WRONLY);
+
+ if (mtrr_fd < 0)
+ mtrr_fd = MTRR_FD_PROBLEM;
}
- return;
-}
+ 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;
+ }
-void xf86AddIOPorts(ScreenNum, NumPorts, Ports)
-int ScreenNum;
-int NumPorts;
-unsigned *Ports;
-{
- return;
+ return FALSE;
+ }
+ else
+ return TRUE;
}
-void xf86EnableIOPorts(ScreenNum)
-int ScreenNum;
-{
- int i;
+/*
+ * We maintain a list of WC regions for each physical mapping so they can
+ * be undone when unmapping.
+ */
- ScreenEnabled[ScreenNum] = TRUE;
+struct mtrr_wc_region {
+ struct mtrr_sentry sentry;
+ Bool added; /* added WC or removed it */
+ struct mtrr_wc_region * next;
+};
- if (ExtendedEnabled)
- return;
-
-#ifndef __mc68000__
- if (iopl(3))
- FatalError("%s: Failed to set IOPL for I/O\n",
- "xf86EnableIOPorts");
-#endif
- ExtendedEnabled = TRUE;
+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;
+ char buf[20];
+ struct mtrr_wc_region *wcreturn = NULL, *wcr;
+
+ /* 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;
- return;
+ /* Found an overlapping region. Delete it. */
+
+ wcr = xalloc(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;
+
+ /* There is now a nicer ioctl-based way to do this,
+ but it isn't in current kernels. */
+ snprintf(buf, sizeof(buf), "disable=%u\n", gent.regnum);
+
+ if (write(mtrr_fd, buf, strlen(buf)) >= 0) {
+ xf86DrvMsg(screenNum, from,
+ "Removed MMIO write-combining range "
+ "(0x%lx,0x%lx)\n",
+ gent.base, gent.size);
+ wcr->next = wcreturn;
+ wcreturn = wcr;
+ } else {
+ xfree(wcr);
+ xf86DrvMsgVerb(screenNum, X_WARNING, 0,
+ "Failed to remove MMIO "
+ "write-combining range (0x%lx,0x%lx)\n",
+ gent.base, gent.size);
+ }
+ }
+ return wcreturn;
}
-void xf86DisableIOPorts(ScreenNum)
-int ScreenNum;
+
+static struct mtrr_wc_region *
+mtrr_add_wc_region(int screenNum, unsigned long base, unsigned long size,
+ MessageType from)
{
- int i;
+ struct mtrr_wc_region *wcr;
- ScreenEnabled[ScreenNum] = FALSE;
+ /* Linux 2.0 should not warn, unless the user explicitly asks for
+ WC. */
+ if (!mtrr_open(from == X_CONFIG ? 0 : 2))
+ return NULL;
- if (!ExtendedEnabled)
- return;
+ wcr = xalloc(sizeof(*wcr));
+ if (!wcr)
+ return NULL;
- for (i = 0; i < MAXSCREENS; i++)
- if (ScreenEnabled[i])
- return;
+ wcr->sentry.base = base;
+ wcr->sentry.size = size;
+ wcr->sentry.type = MTRR_TYPE_WRCOMB;
+ wcr->added = TRUE;
+ wcr->next = NULL;
-#ifndef __mc68000__
- iopl(0);
-#endif
- ExtendedEnabled = FALSE;
+#if SPLIT_WC_REGIONS
+ /*
+ * Splits up the write-combining region if it is not aligned on a
+ * size boundary.
+ */
- return;
+ {
+ 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;
+#ifdef DEBUG
+ ErrorF("WC_BASE: 0x%lx WC_END: 0x%lx\n",base,base+d_size-1);
+#endif
+ 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);
+ wcr->next = mtrr_add_wc_region(screenNum, n_base, n_size,from);
+ }
+ wcr->sentry.size = d_size;
+ }
+
+ /*****************************************************************/
+#endif /* SPLIT_WC_REGIONS */
+
+ if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &wcr->sentry) >= 0) {
+ /* Avoid printing on every VT switch */
+ if (xf86ServerIsInitialising()) {
+ xf86DrvMsg(screenNum, from,
+ "Write-combining range (0x%lx,0x%lx)\n",
+ base, size);
+ }
+ return wcr;
+ }
+ else {
+ xfree(wcr);
+
+ /* 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 NULL;
+ }
}
-#else /* !ALWAYS_USE_EXTENDED */
-
-static unsigned *EnabledPorts[MAXSCREENS];
-static int NumEnabledPorts[MAXSCREENS];
-static Bool ScreenEnabled[MAXSCREENS];
-static Bool ExtendedPorts[MAXSCREENS];
-static Bool ExtendedEnabled = FALSE;
-static Bool InitDone = FALSE;
-
-void xf86ClearIOPortList(ScreenNum)
-int ScreenNum;
+static void
+mtrr_undo_wc_region(int screenNum, struct mtrr_wc_region *wcr)
{
- if (!InitDone)
- {
- xf86InitPortLists(EnabledPorts, NumEnabledPorts,
- ScreenEnabled, ExtendedPorts, MAXSCREENS);
- InitDone = TRUE;
- return;
+ 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;
+ xfree(prev);
+ }
}
- ExtendedPorts[ScreenNum] = FALSE;
- if (EnabledPorts[ScreenNum] != (unsigned *)NULL)
- xfree(EnabledPorts[ScreenNum]);
- EnabledPorts[ScreenNum] = (unsigned *)NULL;
- NumEnabledPorts[ScreenNum] = 0;
}
-void xf86AddIOPorts(ScreenNum, NumPorts, Ports)
-int ScreenNum;
-int NumPorts;
-unsigned *Ports;
+static pointer
+setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
+ MessageType from)
{
- int i;
-
- if (!InitDone)
- {
- FatalError("xf86AddIOPorts: I/O control lists not initialised\n");
- }
- EnabledPorts[ScreenNum] = (unsigned *)xrealloc(EnabledPorts[ScreenNum],
- (NumEnabledPorts[ScreenNum]+NumPorts)*sizeof(unsigned));
- for (i = 0; i < NumPorts; i++)
- {
- EnabledPorts[ScreenNum][NumEnabledPorts[ScreenNum] + i] =
- Ports[i];
- if (Ports[i] > 0x3FF)
- ExtendedPorts[ScreenNum] = TRUE;
- }
- NumEnabledPorts[ScreenNum] += NumPorts;
+ if (enable)
+ return mtrr_add_wc_region(screenNum, base, size, from);
+ else
+ return mtrr_cull_wc_region(screenNum, base, size, from);
}
-void xf86EnableIOPorts(ScreenNum)
-int ScreenNum;
+static void
+undoWC(int screenNum, pointer regioninfo)
{
- int i;
+ mtrr_undo_wc_region(screenNum, regioninfo);
+}
- if (ScreenEnabled[ScreenNum])
- return;
+#endif /* HAS_MTRR_SUPPORT */
- for (i = 0; i < MAXSCREENS; i++)
- {
- if (ExtendedPorts[i] && (ScreenEnabled[i] || i == ScreenNum))
- {
-#ifndef __mc68000__
- if (iopl(3))
- {
- FatalError("%s: Failed to set IOPL for extended I/O\n",
- "xf86EnableIOPorts");
- }
-#endif
- ExtendedEnabled = TRUE;
- break;
- }
- }
- /* Extended I/O was used, but not any more */
- if (ExtendedEnabled && i == MAXSCREENS)
- {
-#ifndef __mc68000__
- iopl(0);
-#endif
- ExtendedEnabled = FALSE;
+void
+xf86OSInitVidMem(VidMemInfoPtr pVidMem)
+{
+ pVidMem->linearSupported = TRUE;
+#ifdef __alpha__
+ if (axpSystem == -1) {
+ axpSystem = lnxGetAXP();
+ if ((needSparse = (_bus_base_sparse() > 0))) {
+ hae_thresh = xf86AXPParams[axpSystem].hae_thresh;
+ hae_mask = xf86AXPParams[axpSystem].hae_mask;
+ sparse_size = xf86AXPParams[axpSystem].size;
+ }
+ bus_base = _bus_base();
}
- /*
- * Turn on non-extended ports even when using extended I/O
- * so they are there if extended I/O gets turned off when it's no
- * longer needed.
- */
- for (i = 0; i < NumEnabledPorts[ScreenNum]; i++)
- {
- unsigned port = EnabledPorts[ScreenNum][i];
+ if (isJensen) {
+# ifndef JENSEN_SUPPORT
+ FatalError("Jensen is not supported any more\n"
+ "If you are intereseted in fixing Jensen support\n"
+ "please contact xfree86@xfree86.org\n");
+# else
+ xf86Msg(X_INFO,"Machine type is Jensen\n");
+ pVidMem->mapMem = mapVidMemJensen;
+ pVidMem->unmapMem = unmapVidMemJensen;
+# endif /* JENSEN_SUPPORT */
+ } else if (needSparse) {
+ xf86Msg(X_INFO,"Machine needs sparse mapping\n");
+ pVidMem->mapMem = mapVidMemSparse;
+ pVidMem->unmapMem = unmapVidMemSparse;
+ } else {
+ xf86Msg(X_INFO,"Machine type has 8/16 bit access\n");
+ pVidMem->mapMem = mapVidMem;
+ pVidMem->unmapMem = unmapVidMem;
+ }
+#else
+ pVidMem->mapMem = mapVidMem;
+ pVidMem->unmapMem = unmapVidMem;
+#endif /* __alpha__ */
- if (port > 0x3FF)
- continue;
- if (xf86CheckPorts(port, EnabledPorts, NumEnabledPorts,
- ScreenEnabled, MAXSCREENS))
- {
- if (ioperm(port, 1, TRUE) < 0)
- {
- FatalError("%s: Failed to enable I/O port 0x%x (%s)\n",
- "xf86EnableIOPorts", port, strerror(errno));
- }
- }
- }
- ScreenEnabled[ScreenNum] = TRUE;
- return;
+#ifdef HAS_MTRR_SUPPORT
+ pVidMem->setWC = setWC;
+ pVidMem->undoWC = undoWC;
+#endif
+ pVidMem->initialised = TRUE;
}
-void xf86DisableIOPorts(ScreenNum)
-int ScreenNum;
+#ifdef __sparc__
+/* Basically, you simply cannot do this on Sparc. You have to do something portable
+ * like use /dev/fb* or mmap() on /proc/bus/pci/X/Y nodes. -DaveM
+ */
+static pointer mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
+{
+ return NULL;
+}
+#else
+static pointer
+mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
{
- int i;
+ pointer base;
+ int fd;
+ int mapflags = MAP_SHARED;
+ memType realBase, alignOff;
+
+ realBase = Base & ~(getpagesize() - 1);
+ alignOff = Base - realBase;
+#ifdef DEBUG
+ ErrorF("base: %lx, realBase: %lx, alignOff: %lx \n",
+ Base,realBase,alignOff);
+#endif
+
+#if defined(__ia64__)
+#ifndef MAP_WRITECOMBINED
+#define MAP_WRITECOMBINED 0x00010000
+#endif
+#ifndef MAP_NONCACHED
+#define MAP_NONCACHED 0x00020000
+#endif
+ if(flags & VIDMEM_FRAMEBUFFER)
+ mapflags |= MAP_WRITECOMBINED;
+ else
+ mapflags |= MAP_NONCACHED;
+#endif
- if (!ScreenEnabled[ScreenNum])
- return;
+#if defined(__ia64__)
+ /* this will disappear when people upgrade their kernels */
+ if ((fd = open(DEV_MEM, O_RDWR|O_SYNC)) < 0)
+#else
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0)
+#endif
+ {
+ FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n",
+ strerror(errno));
+ }
+ /* This requires linux-0.99.pl10 or above */
+ base = mmap((caddr_t)0, Size + alignOff,
+ PROT_READ|PROT_WRITE,
+ mapflags, fd,
+ (off_t)(off_t)realBase + BUS_BASE);
+ close(fd);
+ if (base == MAP_FAILED) {
+ FatalError("xf86MapVidMem: Could not mmap framebuffer"
+ " (0x%08x,0x%x) (%s)\n", Base, Size,
+ strerror(errno));
+ }
+#ifdef DEBUG
+ ErrorF("base: %lx aligned base: %lx\n",base, base + alignOff);
+#endif
+ return (char *)base + alignOff;
+}
+#endif /* !(__sparc__) */
+
+static void
+unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ memType alignOff = (memType)Base
+ - ((memType)Base & ~(getpagesize() - 1));
+
+#ifdef DEBUG
+ ErrorF("alignment offset: %lx\n",alignOff);
+#endif
+ munmap((caddr_t)((memType)Base - alignOff), (Size + alignOff));
+}
- ScreenEnabled[ScreenNum] = FALSE;
- for (i = 0; i < MAXSCREENS; i++)
- {
- if (ScreenEnabled[i] && ExtendedPorts[i])
- break;
- }
- if (ExtendedEnabled && i == MAXSCREENS)
- {
-#ifndef __mc68000__
- iopl(0);
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+#if defined(__powerpc__)
+volatile unsigned char *ioBase = NULL;
+
+#ifndef __NR_pciconfig_iobase
+#define __NR_pciconfig_iobase 200
#endif
- ExtendedEnabled = FALSE;
- }
- for (i = 0; i < NumEnabledPorts[ScreenNum]; i++)
- {
- unsigned port = EnabledPorts[ScreenNum][i];
- if (port > 0x3FF)
- continue;
+#endif
- if (xf86CheckPorts(port, EnabledPorts, NumEnabledPorts,
- ScreenEnabled, MAXSCREENS))
- {
- ioperm(port, 1, FALSE);
+void
+xf86EnableIO(void)
+{
+#if defined(__powerpc__)
+ int fd;
+ unsigned int ioBase_phys;
+#endif
+
+ if (ExtendedEnabled)
+ return;
+
+#if defined(__powerpc__)
+ ioBase_phys = syscall(__NR_pciconfig_iobase, 2, 0, 0);
+
+ fd = open("/dev/mem", O_RDWR);
+ if (ioBase == NULL) {
+ ioBase = (volatile unsigned char *)mmap(0, 0x20000,
+ PROT_READ|PROT_WRITE, MAP_SHARED, fd,
+ ioBase_phys);
+/* Should this be fatal or just a warning? */
+#if 0
+ if (ioBase == MAP_FAILED) {
+ FatalError(
+ "xf86EnableIOPorts: Failed to map iobase (%s)\n",
+ strerror(errno));
}
+#endif
}
+ close(fd);
+#elif !defined(__mc68000__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__hppa__)
+ if (ioperm(0, 1024, 1) || iopl(3))
+ FatalError("xf86EnableIOPorts: Failed to set IOPL for I/O\n");
+# if !defined(__alpha__)
+ ioperm(0x40,4,0); /* trap access to the timer chip */
+ ioperm(0x60,4,0); /* trap access to the keyboard controller */
+# endif
+#endif
+ ExtendedEnabled = TRUE;
+
return;
}
-#endif /* ALWAYS_USE_EXTENDED */
-
-void xf86DisableIOPrivs()
+void
+xf86DisableIO(void)
{
-#ifndef __mc68000__
- if (ExtendedEnabled)
- iopl(0);
+ if (!ExtendedEnabled)
+ return;
+#if defined(__powerpc__)
+ munmap(ioBase, 0x20000);
+ ioBase = NULL;
+#elif !defined(__mc68000__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__hppa__)
+ iopl(0);
+ ioperm(0, 1024, 0);
#endif
+ ExtendedEnabled = FALSE;
+
return;
}
+
/***************************************************************************/
/* Interrupt Handling section */
/***************************************************************************/
-Bool xf86DisableInterrupts()
+/* XXX The #ifdefs should be made simpler. */
+
+Bool
+xf86DisableInterrupts()
{
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__) && !defined(__ia64__) && !defined(__sh__) && !defined(__hppa__)
if (!ExtendedEnabled)
-#ifndef __mc68000__
- if (iopl(3))
+ if (iopl(3) || ioperm(0, 1024, 1))
return (FALSE);
#endif
-#if defined(__alpha__) || defined(__mc68000__)
-#else
-#ifdef __GNUC__
- __asm__ __volatile__("cli");
+#if defined(__alpha__) || defined(__mc68000__) || defined(__powerpc__) || defined(__sparc__) || defined(__mips__) || defined(__arm__) || defined(__sh__) || defined(__ia64__) || defined(__hppa__)
#else
+# ifdef __GNUC__
+# if defined(__ia64__)
+# if 0
+ __asm__ __volatile__ (";; rsm psr.i;; srlz.d" ::: "memory");
+# endif
+# else
+ __asm__ __volatile__("cli");
+# endif
+# else
asm("cli");
+# endif
#endif
-#endif
-#ifndef __mc68000__
- if (!ExtendedEnabled)
- iopl(0);
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__ia64__) && !defined(__hppa__)
+ if (!ExtendedEnabled) {
+ iopl(0);
+ ioperm(0, 1024, 0);
+ }
+
#endif
return (TRUE);
}
-void xf86EnableInterrupts()
+void
+xf86EnableInterrupts()
{
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__) && !defined(__ia64__) && !defined(__sh__) && !defined(__hppa__)
if (!ExtendedEnabled)
-#ifndef __mc68000__
- if (iopl(3))
+ if (iopl(3) || ioperm(0, 1024, 1))
return;
#endif
-#if defined(__alpha__) || defined(__mc68000__)
-#else
-#ifdef __GNUC__
- __asm__ __volatile__("sti");
+#if defined(__alpha__) || defined(__mc68000__) || defined(__powerpc__) || defined(__sparc__) || defined(__mips__) || defined(__arm__) || defined(__sh__) || defined(__ia64__) || defined(__hppa__)
#else
+# ifdef __GNUC__
+# if defined(__ia64__)
+# if 0
+ __asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory");
+# endif
+# else
+ __asm__ __volatile__("sti");
+# endif
+# else
asm("sti");
+# endif
#endif
-#endif
-#ifndef __mc68000__
- if (!ExtendedEnabled)
- iopl(0);
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__ia64__) && !defined(__hppa__)
+ if (!ExtendedEnabled) {
+ iopl(0);
+ ioperm(0, 1024, 0);
+ }
#endif
return;
}
-#if defined(__alpha__)
+#if defined (__alpha__)
-static int xf86SparseShift = 5; /* default to all but JENSEN */
+#define vuip volatile unsigned int *
-pointer xf86MapVidMemSparse(ScreenNum, Region, Base, Size)
-int ScreenNum;
-int Region;
-pointer Base;
-unsigned long Size;
+extern int readDense8(pointer Base, register unsigned long Offset);
+extern int readDense16(pointer Base, register unsigned long Offset);
+extern int readDense32(pointer Base, register unsigned long Offset);
+extern void
+writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDense8(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDense16(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDense32(int Value, pointer Base, register unsigned long Offset);
+
+static int readSparse8(pointer Base, register unsigned long Offset);
+static int readSparse16(pointer Base, register unsigned long Offset);
+static int readSparse32(pointer Base, register unsigned long Offset);
+static void
+writeSparseNB8(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseNB16(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseNB32(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparse8(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparse16(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparse32(int Value, pointer Base, register unsigned long Offset);
+
+#define DENSE_BASE 0x2ff00000000UL
+#define SPARSE_BASE 0x30000000000UL
+
+static unsigned long msb_set = 0;
+
+static pointer
+mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
{
- pointer base;
- int fd;
+ int fd;
+ unsigned long ret, rets = 0;
+
+ static Bool was_here = FALSE;
+
+ if (!was_here) {
+ was_here = TRUE;
+
+ xf86WriteMmio8 = writeSparse8;
+ xf86WriteMmio16 = writeSparse16;
+ xf86WriteMmio32 = writeSparse32;
+ xf86WriteMmioNB8 = writeSparseNB8;
+ xf86WriteMmioNB16 = writeSparseNB16;
+ xf86WriteMmioNB32 = writeSparseNB32;
+ xf86ReadMmio8 = readSparse8;
+ xf86ReadMmio16 = readSparse16;
+ xf86ReadMmio32 = readSparse32;
+ }
+
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0) {
+ FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n",
+ strerror(errno));
+ }
+
+#if 0
+ xf86Msg(X_INFO,"mapVidMemSparse: try Base 0x%lx size 0x%lx flags 0x%x\n",
+ Base, Size, flags);
+#endif
- if (!_bus_base()) xf86SparseShift = 7; /* Uh, oh, JENSEN... */
+ /* This requirers linux-0.99.pl10 or above */
+
+ /*
+ * Always do DENSE mmap, since read32/write32 currently require it.
+ */
+ ret = (unsigned long)mmap((caddr_t)(DENSE_BASE + Base), Size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd,
+ (off_t) (bus_base + Base));
+
+ /*
+ * Do SPARSE mmap only when MMIO and not MMIO_32BIT, or FRAMEBUFFER
+ * and SPARSE (which should require the use of read/write macros).
+ *
+ * By not SPARSE mmapping an 8MB framebuffer, we can save approx. 256K
+ * bytes worth of pagetable (32 pages).
+ */
+ if (((flags & VIDMEM_MMIO) && !(flags & VIDMEM_MMIO_32BIT)) ||
+ ((flags & VIDMEM_FRAMEBUFFER) && (flags & VIDMEM_SPARSE)))
+ {
+ rets = (unsigned long)mmap((caddr_t)(SPARSE_BASE + (Base << 5)),
+ Size << 5, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd,
+ (off_t) _bus_base_sparse() + (Base << 5));
+ }
- Size <<= xf86SparseShift;
- Base = (pointer)((unsigned long)Base << xf86SparseShift);
+ close(fd);
+
+ if (ret == (unsigned long)MAP_FAILED) {
+ FatalError("xf86MapVidMemSparse: Could not (dense) mmap fb (%s)\n",
+ strerror(errno));
+ }
- if ((fd = open("/dev/mem", O_RDWR)) < 0)
+ if (((flags & VIDMEM_MMIO) && !(flags & VIDMEM_MMIO_32BIT)) ||
+ ((flags & VIDMEM_FRAMEBUFFER) && (flags & VIDMEM_SPARSE)))
+ {
+ if (rets == (unsigned long)MAP_FAILED ||
+ rets != (SPARSE_BASE + (Base << 5)))
{
- FatalError("xf86MapVidMem: failed to open /dev/mem (%s)\n",
- strerror(errno));
+ FatalError("mapVidMemSparse: Could not (sparse) mmap fb (%s)\n",
+ strerror(errno));
}
- /* This requirers linux-0.99.pl10 or above */
- base = (pointer)mmap((caddr_t)0, Size,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, fd,
- (off_t)Base + _bus_base_sparse());
- close(fd);
- if ((long)base == -1)
- {
- FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
- strerror(errno));
+ }
+
+#if 1
+ if (rets)
+ xf86Msg(X_INFO,"mapVidMemSparse: mapped Base 0x%lx size 0x%lx"
+ " to DENSE at 0x%lx and SPARSE at 0x%lx\n",
+ Base, Size, ret, rets);
+ else
+ xf86Msg(X_INFO,"mapVidMemSparse: mapped Base 0x%lx size 0x%lx"
+ " to DENSE only at 0x%lx\n",
+ Base, Size, ret);
+
+#endif
+ return (pointer) ret;
+}
+
+static void
+unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size)
+{
+ unsigned long Offset = (unsigned long)Base - DENSE_BASE;
+#if 1
+ xf86Msg(X_INFO,"unmapVidMemSparse: unmapping Base 0x%lx Size 0x%lx\n",
+ Base, Size);
+#endif
+ /* Unmap DENSE always. */
+ munmap((caddr_t)Base, Size);
+
+ /* Unmap SPARSE always, and ignore error in case we did not map it. */
+ munmap((caddr_t)(SPARSE_BASE + (Offset << 5)), Size << 5);
+}
+
+static int
+readSparse8(pointer Base, register unsigned long Offset)
+{
+ register unsigned long result, shift;
+ register unsigned long msb;
+
+ mem_barrier();
+ Offset += (unsigned long)Base - DENSE_BASE;
+ shift = (Offset & 0x3) << 3;
+ if (Offset >= (hae_thresh)) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
}
- return base;
+ }
+
+ mem_barrier();
+ result = *(vuip) (SPARSE_BASE + (Offset << 5));
+ result >>= shift;
+ return 0xffUL & result;
}
-void xf86UnMapVidMemSparse(ScreenNum, Region, Base, Size)
-int ScreenNum;
-int Region;
-pointer Base;
-unsigned long Size;
+static int
+readSparse16(pointer Base, register unsigned long Offset)
{
- Size <<= xf86SparseShift;
+ register unsigned long result, shift;
+ register unsigned long msb;
+
+ mem_barrier();
+ Offset += (unsigned long)Base - DENSE_BASE;
+ shift = (Offset & 0x2) << 3;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
+ }
- munmap((caddr_t)Base, Size);
+ mem_barrier();
+ result = *(vuip)(SPARSE_BASE + (Offset<<5) + (1<<(5-2)));
+ result >>= shift;
+ return 0xffffUL & result;
}
-#define vuip volatile unsigned int *
+static int
+readSparse32(pointer Base, register unsigned long Offset)
+{
+ /* NOTE: this is really using DENSE. */
+ mem_barrier();
+ return *(vuip)((unsigned long)Base+(Offset));
+}
-extern void sethae(unsigned long hae);
+static void
+writeSparse8(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned long msb;
+ register unsigned int b = Value & 0xffU;
+
+ write_mem_barrier();
+ Offset += (unsigned long)Base - DENSE_BASE;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
+ }
+
+ write_mem_barrier();
+ *(vuip) (SPARSE_BASE + (Offset << 5)) = b * 0x01010101;
+}
-int xf86ReadSparse8(Base, Offset)
-pointer Base;
-unsigned long Offset;
+static void
+writeSparse16(int Value, pointer Base, register unsigned long Offset)
{
- unsigned long result, shift;
- unsigned long msb = 0;
+ register unsigned long msb;
+ register unsigned int w = Value & 0xffffU;
+
+ write_mem_barrier();
+ Offset += (unsigned long)Base - DENSE_BASE;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
+ }
- shift = (Offset & 0x3) * 8;
- if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000UL;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
+ write_mem_barrier();
+ *(vuip)(SPARSE_BASE + (Offset<<5) + (1<<(5-2))) = w * 0x00010001;
+}
+
+static void
+writeSparse32(int Value, pointer Base, register unsigned long Offset)
+{
+ /* NOTE: this is really using DENSE. */
+ write_mem_barrier();
+ *(vuip)((unsigned long)Base + (Offset)) = Value;
+ return;
+}
+
+static void
+writeSparseNB8(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned long msb;
+ register unsigned int b = Value & 0xffU;
+
+ Offset += (unsigned long)Base - DENSE_BASE;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
}
- result = *(vuip) ((unsigned long)Base + (Offset << xf86SparseShift));
- if (msb)
- sethae(0);
+ *(vuip) (SPARSE_BASE + (Offset << 5)) = b * 0x01010101;
+}
+
+static void
+writeSparseNB16(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned long msb;
+ register unsigned int w = Value & 0xffffU;
+
+ Offset += (unsigned long)Base - DENSE_BASE;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
+ }
+ *(vuip)(SPARSE_BASE+(Offset<<5)+(1<<(5-2))) = w * 0x00010001;
+}
+
+static void
+writeSparseNB32(int Value, pointer Base, register unsigned long Offset)
+{
+ /* NOTE: this is really using DENSE. */
+ *(vuip)((unsigned long)Base + (Offset)) = Value;
+ return;
+}
+
+void (*xf86WriteMmio8)(int Value, pointer Base, unsigned long Offset)
+ = writeDense8;
+void (*xf86WriteMmio16)(int Value, pointer Base, unsigned long Offset)
+ = writeDense16;
+void (*xf86WriteMmio32)(int Value, pointer Base, unsigned long Offset)
+ = writeDense32;
+void (*xf86WriteMmioNB8)(int Value, pointer Base, unsigned long Offset)
+ = writeDenseNB8;
+void (*xf86WriteMmioNB16)(int Value, pointer Base, unsigned long Offset)
+ = writeDenseNB16;
+void (*xf86WriteMmioNB32)(int Value, pointer Base, unsigned long Offset)
+ = writeDenseNB32;
+int (*xf86ReadMmio8)(pointer Base, unsigned long Offset)
+ = readDense8;
+int (*xf86ReadMmio16)(pointer Base, unsigned long Offset)
+ = readDense16;
+int (*xf86ReadMmio32)(pointer Base, unsigned long Offset)
+ = readDense32;
+
+#ifdef JENSEN_SUPPORT
+
+static int
+readSparseJensen8(pointer Base, register unsigned long Offset);
+static int
+readSparseJensen16(pointer Base, register unsigned long Offset);
+static int
+readSparseJensen32(pointer Base, register unsigned long Offset);
+static void
+writeSparseJensen8(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensen16(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensen32(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensenNB8(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensenNB16(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensenNB32(int Value, pointer Base, register unsigned long Offset);
+
+/*
+ * The Jensen lacks dense memory, thus we have to address the bus via
+ * the sparse addressing scheme.
+ *
+ * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996
+ */
+
+#ifdef TEST_JENSEN_CODE
+#define SPARSE (5)
+#else
+#define SPARSE (7)
+#endif
+
+#define JENSEN_SHIFT(x) ((long)x<<SPARSE)
+
+static pointer
+mapVidMemJensen(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
+{
+ pointer base;
+ int fd;
+
+ xf86WriteMmio8 = writeSparseJensen8;
+ xf86WriteMmio16 = writeSparseJensen16;
+ xf86WriteMmio32 = writeSparseJensen32;
+ xf86WriteMmioNB8 = writeSparseJensenNB8;
+ xf86WriteMmioNB16 = writeSparseJensenNB16;
+ xf86WriteMmioNB32 = writeSparseJensenNB32;
+ xf86ReadMmio8 = readSparseJensen8;
+ xf86ReadMmio16 = readSparseJensen16;
+ xf86ReadMmio32 = readSparseJensen32;
+
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0) {
+ FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n",
+ strerror(errno));
+ }
+ /* This requires linux-0.99.pl10 or above */
+ base = mmap((caddr_t)0, JENSEN_SHIFT(Size),
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd,
+ (off_t)(JENSEN_SHIFT((off_t)Base) + _bus_base_sparse()));
+ close(fd);
+ if (base == MAP_FAILED) {
+ FatalError("xf86MapVidMem: Could not mmap framebuffer"
+ " (0x%08x,0x%x) (%s)\n", Base, Size,
+ strerror(errno));
+ }
+ return base;
+}
+
+static void
+unmapVidMemJensen(int ScreenNum, pointer Base, unsigned long Size)
+{
+ munmap((caddr_t)Base, JENSEN_SHIFT(Size));
+}
+
+static int
+readSparseJensen8(pointer Base, register unsigned long Offset)
+{
+ register unsigned long result, shift;
+
+ mem_barrier();
+ shift = (Offset & 0x3) << 3;
+
+ result = *(vuip) ((unsigned long)Base + (Offset << SPARSE));
+
result >>= shift;
return 0xffUL & result;
}
-int xf86ReadSparse16(Base, Offset)
-pointer Base;
-unsigned long Offset;
+static int
+readSparseJensen16(pointer Base, register unsigned long Offset)
{
- unsigned long result, shift;
- unsigned long msb = 0;
+ register unsigned long result, shift;
+
+ mem_barrier();
+ shift = (Offset & 0x2) << 3;
+
+ result = *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(1<<(SPARSE-2)));
- shift = (Offset & 0x2) * 8;
- if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000UL;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
- }
- result = *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(1<<(xf86SparseShift-2)));
- if (msb)
- sethae(0);
result >>= shift;
return 0xffffUL & result;
}
-int xf86ReadSparse32(Base, Offset)
-pointer Base;
-unsigned long Offset;
+static int
+readSparseJensen32(pointer Base, register unsigned long Offset)
{
- unsigned long result;
- unsigned long msb = 0;
+ register unsigned long result;
+
+ mem_barrier();
+ result = *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(3<<(SPARSE-2)));
- if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000UL;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
- }
- result = *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(3<<(xf86SparseShift-2)));
- if (msb)
- sethae(0);
return result;
}
-void xf86WriteSparse8(Value, Base, Offset)
-int Value;
-pointer Base;
-unsigned long Offset;
+static void
+writeSparseJensen8(int Value, pointer Base, register unsigned long Offset)
{
- unsigned long msb = 0;
- unsigned int b = Value & 0xffU;
+ register unsigned int b = Value & 0xffU;
- if (xf86SparseShift != 7) { /* not JENSEN */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
- }
- *(vuip) ((unsigned long)Base + (Offset << xf86SparseShift)) = b * 0x01010101;
- if (msb)
- sethae(0);
+ write_mem_barrier();
+ *(vuip) ((unsigned long)Base + (Offset << SPARSE)) = b * 0x01010101;
}
-void xf86WriteSparse16(Value, Base, Offset)
-int Value;
-pointer Base;
-unsigned long Offset;
+static void
+writeSparseJensen16(int Value, pointer Base, register unsigned long Offset)
{
- unsigned long msb = 0;
- unsigned int w = Value & 0xffffU;
+ register unsigned int w = Value & 0xffffU;
- if (xf86SparseShift != 7) { /* not JENSEN */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
- }
- *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(1<<(xf86SparseShift-2))) =
+ write_mem_barrier();
+ *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(1<<(SPARSE-2))) =
w * 0x00010001;
- if (msb)
- sethae(0);
}
-void xf86WriteSparse32(Value, Base, Offset)
-int Value;
-pointer Base;
-unsigned long Offset;
+static void
+writeSparseJensen32(int Value, pointer Base, register unsigned long Offset)
{
- unsigned long msb = 0;
+ write_mem_barrier();
+ *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(3<<(SPARSE-2))) = Value;
+}
- if (xf86SparseShift != 7) { /* not JENSEN */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
- }
- *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(3<<(xf86SparseShift-2))) = Value;
- if (msb)
- sethae(0);
+static void
+writeSparseJensenNB8(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned int b = Value & 0xffU;
+
+ *(vuip) ((unsigned long)Base + (Offset << SPARSE)) = b * 0x01010101;
}
+
+static void
+writeSparseJensenNB16(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned int w = Value & 0xffffU;
+
+ *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(1<<(SPARSE-2))) =
+ w * 0x00010001;
+}
+
+static void
+writeSparseJensenNB32(int Value, pointer Base, register unsigned long Offset)
+{
+ *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(3<<(SPARSE-2))) = Value;
+}
+#endif /* JENSEN_SUPPORT */
+
#endif /* __alpha__ */