diff options
author | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
commit | f4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch) | |
tree | 2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/programs/Xserver/hw/xfree86/os-support/pmax | |
parent | a840692edc9c6d19cd7c057f68e39c7d95eb767d (diff) | |
download | nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2 nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip |
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz
Keywords:
Imported nx-X11-3.1.0-1.tar.gz
into Git repository
Diffstat (limited to 'nx-X11/programs/Xserver/hw/xfree86/os-support/pmax')
7 files changed, 2269 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile new file mode 100644 index 000000000..37cc186c4 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile @@ -0,0 +1,48 @@ + +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile,v 1.11 2002/10/11 01:47:00 dawes Exp $ + +#include <Server.tmpl> + +MOUSESRC = pmax_mouse.c +MOUSEOBJ = pmax_mouse.o + +SRCS = pmax_devs.c pmax_init.c pmax_map.c pmax_pci.c pmax_ppc.c \ + bios_V4mmap.c VTsw_usl.c sysv_kbd.c std_kbdEv.c \ + posix_tty.c $(MOUSESRC) xqueue.c ioperm_noop.c \ + libc_wrapper.c stdResource.c stdPci.o sigiostubs.c pm_noop.c \ + kmod_noop.c agp_noop.c + +OBJS = pmax_devs.o pmax_init.o pmax_map.o pmax_pci.o pmax_ppc.o \ + bios_V4mmap.o VTsw_usl.o sysv_kbd.o std_kbdEv.o \ + posix_tty.o $(MOUSESRC) xqueue.o ioperm_noop.o \ + libc_wrapper.o stdResource.o stdPci.o sigiostubs.o pm_noop.o \ + kmod_noop.o agp_noop.o + + +INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86OSSRC)/bus -I. \ + -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I../sysv + +RESDEFINES = -DUSESTDRES + +DEFINES = $(RESDEFINES) + +SubdirLibraryRule($(OBJS)) +NormalLibraryObjectRule() + +LinkSourceFile(VTsw_usl.c,../shared) +LinkSourceFile(ioperm_noop.c,../shared) +LinkSourceFile(sysv_kbd.c,../shared) +LinkSourceFile(std_kbdEv.c,../shared) +LinkSourceFile(posix_tty.c,../shared) +LinkSourceFile(libc_wrapper.c,../shared) +LinkSourceFile(stdResource.c,../shared) +LinkSourceFile(stdPci.c,../shared) +LinkSourceFile(sigiostubs.c,../shared) +LinkSourceFile(pm_noop.c,../shared) +LinkSourceFile(kmod_noop.c,../shared) +LinkSourceFile(agp_noop.c,../shared) + +LinkSourceFile(bios_V4mmap.c,../sysv) +LinkSourceFile(xqueue.c,../sysv) + +DependTarget() diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c new file mode 100644 index 000000000..f221e0755 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c @@ -0,0 +1,126 @@ +/* + * Copyright 1998 by Concurrent Computer Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Concurrent Computer + * Corporation not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Concurrent Computer Corporation makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Copyright 1998 by Metro Link Incorporated + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Metro Link + * Incorporated not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Metro Link Incorporated makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * This module was derived in part from the original XFree86 + * sysv/sysv_io.c which contains the following copyright notice: + * + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany + * 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 + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Thomas Roell and David Dawes + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Thomas Roell and + * David Dawes makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THOMAS ROELL AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES BE LIABLE FOR + * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c,v 1.7 2002/10/11 01:40:36 dawes Exp $ */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +void +xf86SoundKbdBell(int loudness, int pitch, int duration) +{ + if (loudness && pitch) + { +#ifdef KDMKTONE + /* + * If we have KDMKTONE use it to avoid putting the server + * to sleep + */ + ioctl(xf86Info.consoleFd, KDMKTONE, + ((1193190 / pitch) & 0xffff) | + (((unsigned long)duration * + loudness / 50) << 16)); +#else + ioctl(xf86Info.consoleFd, KIOCSOUND, 1193180 / pitch); + usleep(xf86Info.bell_duration * loudness * 20); + ioctl(xf86Info.consoleFd, KIOCSOUND, 0); +#endif + } +} + +void +xf86SetKbdLeds(int leds) +{ +#if 0 /* used to be KBIO_SETMODE */ + ioctl(xf86Info.consoleFd, KBIO_SETMODE, KBM_AT); + ioctl(xf86Info.consoleFd, KDSETLED, leds); + ioctl(xf86Info.consoleFd, KBIO_SETMODE, KBM_XT); +#endif + + ioctl(xf86Info.consoleFd, KDSETLED, leds); +} + +#include "xf86OSKbd.h" + +Bool +xf86OSKbdPreInit(InputInfoPtr pInfo) +{ + return FALSE; +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c new file mode 100644 index 000000000..7da733d22 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c @@ -0,0 +1,473 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c,v 1.2.2.2 1998/07/18 17:53:54 dawes Exp $ */ +/* + * Copyright 1998 by Concurrent Computer Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Concurrent Computer + * Corporation not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Concurrent Computer Corporation makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Copyright 1998 by Metro Link Incorporated + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Metro Link + * Incorporated not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Metro Link Incorporated makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * This file was derived in part from the original XFree86 sysv OS + * support which contains the following copyright notice: + * + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany + * Copyright 1993 by David Wexelblat <dwex@goblin.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Thomas Roell and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Thomas Roell and + * David Wexelblat makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT BE LIABLE FOR + * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <sys/types.h> +#include <time.h> +#include <errno.h> + +#include <sys/prosrfs.h> +#include <sys/cpu.h> +#include <sys/ipl.h> + +#include <X11/X.h> +#include <X11/Xmd.h> + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +static Bool KeepTty = FALSE; +static Bool Protect0 = FALSE; +static Bool pmaxInitialized = FALSE; + +#define VT_DEFAULT -2 +#define VT_NONE -1 + +static int VTnum = VT_DEFAULT; + +extern void pmax_init_splmap(void); + +int pmax_sys_type; /* Also used by pmax_pci.c */ + +/* + * PowerMAXOS_sys_type() + * + * Determine type of PowerHawk, PowerStack, PowerMaxion, or NightHawk + */ +int +PowerMAXOS_sys_type(void) +{ + int fd; + procfile_t procfile; + + fd = open("/system/processor/0",O_RDONLY); + if (fd<0) { + FatalError("Cannot open '%s'\n", "/system/processor/0"); + } + + if (read(fd, &procfile, sizeof(procfile)) < 0) { + FatalError("Cannot read '%s'\n", "/system/processor/0"); + } + close(fd); + + return(procfile.cpu_model); +} + +void +pmaxInit(void) +{ + char *mach; + + if (pmaxInitialized) + return; + + pmaxInitialized = TRUE; + + /* + * Determine type of machine + */ + pmax_sys_type = PowerMAXOS_sys_type(); + switch(pmax_sys_type) { + + case MODEL_NH6400: + mach ="PowerMAXION (NH6400)"; + break; + + case MODEL_NH6408: + mach = "PowerMAXION (NH6408)"; + break; + + case MODEL_NH6800T: + mach = "TurboHawk"; + break; + + case MODEL_MPWR: + mach = "PowerStack"; + break; + + case MODEL_PH610: + mach = "PowerHawk 610"; + break; + + case MODEL_MPWR2: + mach = "PowerStack II (utah)"; + break; + + case MODEL_PH620: + mach = "PowerHawk 620"; + break; + + case MODEL_PH640: + mach = "PowerHawk 640"; + break; + + case MODEL_MMTX: + mach = "PowerStack II (MTX)"; + break; + + default: + FatalError("pmaxInit: Unknown/unsupported machine type 0x%x\n", + pmax_sys_type); + /*NOTREACHED*/ + } + + xf86Msg(X_INFO, "pmaxInit: Machine type: %s\n", mach); + + /* + * Map IPL hardware so that interrupts can be (temporarily) disabled + * (see pmax_video.c) + */ + pmax_init_splmap(); + + /* + * Now that we know the system type, initialize the + * pci access routines + */ + pciInit(); +} + +void +xf86OpenConsole() +{ + struct vt_mode VT; + char vtname[10]; + MessageType from = X_DEFAULT; + + if (serverGeneration == 1) + { + + /* check if we're run with euid==0 */ + if (geteuid() != 0) + { + FatalError("xf86OpenConsole: Server must be suid root\n"); + } + + /* Protect page 0 to help find NULL dereferencing */ + /* mprotect() doesn't seem to work */ + if (Protect0) + { + int fd = -1; + + if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0) + { + xf86Msg(X_WARNING, + "xf86OpenConsole: cannot open /dev/zero (%s)\n", + strerror(errno)); + } + else + { + if ((int)mmap(0, 0x1000, PROT_NONE, + MAP_FIXED | MAP_SHARED, fd, 0) == -1) + { + xf86Msg(X_WARNING, + "xf86OpenConsole: failed to protect page 0 (%s)\n", + strerror(errno)); + } + close(fd); + } + } + + pmaxInit(); /* Initialize OS specific functions */ + + /* + * setup the virtual terminal manager + */ + if (VTnum == VT_DEFAULT) { + int fd; + + /* + * No specific VT specified, so ask the vtl term mgr + * for the next available VT + */ + if ((fd = open("/dev/vt00",O_WRONLY,0)) < 0) { + xf86Msg(X_WARNING, + "xf86OpenConsole: Could not open /dev/vt00 (%s)\n", + strerror(errno)); + VTnum = VT_NONE; + } + else { + if (ioctl(fd, VT_OPENQRY, &VTnum) < 0) + { + xf86Msg(X_WARNING, + "xf86OpenConsole: Cannot find a free VT\n"); + VTnum = VT_NONE; + } + close(fd); + } + } else { + from = X_CMDLINE; + } + + xf86Info.vtno = VTnum; + + if (xf86Info.vtno == VT_NONE) + strcpy(vtname, "/dev/null"); + else + sprintf(vtname,"/dev/vt%02d",xf86Info.vtno); + + xf86Msg(from, "using VT \"%s\"\n\n", vtname); + + if (!KeepTty) + { + setpgrp(); + } + + if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) < 0) + { + FatalError("xf86OpenConsole: Cannot open %s (%s)\n", + vtname, strerror(errno)); + } + + if (xf86Info.vtno != VT_NONE) + { + /* change ownership of the vt */ + (void) chown(vtname, getuid(), getgid()); + + /* + * now get the VT + */ + if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); + } + if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); + } + if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0) + { + FatalError("xf86OpenConsole: VT_GETMODE failed\n"); + } + + signal(SIGUSR1, xf86VTRequest); + + VT.mode = VT_PROCESS; + VT.relsig = SIGUSR1; + VT.acqsig = SIGUSR1; + if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0) + { + FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n"); + } + if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) + { + FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n"); + } + } + } + else + { + /* serverGeneration != 1 */ + /* + * now get the VT + */ + if (xf86Info.vtno != VT_NONE) + { + if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); + } + if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); + } + /* + * If the server doesn't have the VT when the reset occurs, + * this is to make sure we don't continue until the activate + * signal is received. + */ + if (!xf86Screens[0]->vtSema) + sleep(5); + } + } + return; +} + +void xf86CloseConsole() +{ + struct vt_mode VT; + + if (xf86Info.vtno != VT_NONE) + { + +#if 0 + ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno); + ioctl(xf86Info.consoleFd, VT_WAITACTIVE, 0); +#endif + ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */ + if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) + { + VT.mode = VT_AUTO; + ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */ + } + } + + close(xf86Info.consoleFd); /* make the vt-manager happy */ + return; +} + +int xf86ProcessArgument(argc, argv, i) +int argc; +char *argv[]; +int i; +{ + /* + * Keep server from detaching from controlling tty. This is useful + * when debugging (so the server can receive keyboard signals. + */ + if (!strcmp(argv[i], "-keeptty")) + { + KeepTty = TRUE; + return(1); + } + + /* + * Prevent server from attemping to open a new VT in the "-novt" + * flag was specified. + */ + if (!strcmp(argv[i], "-novt")) + { + VTnum = VT_NONE; + return(1); + } + + /* + * Undocumented flag to protect page 0 from read/write to help + * catch NULL pointer dereferences. This is purely a debugging + * flag. + */ + if (!strcmp(argv[i], "-protect0")) + { + Protect0 = TRUE; + return(1); + } + + if ((argv[i][0] == 'v') && (argv[i][1] == 't')) + { + if (sscanf(argv[i], "vt%2d", &VTnum) == 0) + { + UseMsg(); + VTnum = VT_DEFAULT; + return(0); + } + return(1); + } + return(0); +} + +void xf86UseMsg() +{ + ErrorF("vtXX use the specified VT number\n"); + ErrorF("-keeptty "); + ErrorF("don't detach controlling tty (for debugging only)\n"); + ErrorF("-novt "); + ErrorF("don't allocate and open a new virtual terminal\n"); + return; +} + + +void +xf86_pmax_usleep(unsigned long n) +{ + struct timespec requested,remaining; + int rv; + + requested.tv_sec = n/1000000; + requested.tv_nsec = (n % 1000000) * 1000; + + while ((rv = nanosleep(&requested,&remaining)) < 0) { + if (errno != EINTR) + break; + + remaining = requested; /* structure assignment */ + } + + if (rv) { + ErrorF("xf86_pmax_usleep: nanosleep() failed: rv=%d, errno=%d\n", rv, errno); + } +} + +#ifndef usleep + +void +usleep(unsigned long n) +{ + xf86_pmax_usleep(n); +} + +#endif diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c new file mode 100644 index 000000000..36d3366a2 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c @@ -0,0 +1,239 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c,v 1.7 2000/06/27 14:27:31 tsi Exp $ */ +/* + * Copyright 1998 by Concurrent Computer Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Concurrent Computer + * Corporation not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Concurrent Computer Corporation makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Copyright 1998 by Metro Link Incorporated + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Metro Link + * Incorporated not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Metro Link Incorporated makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * This file was derived in part from the original XFree86 sysv OS + * support which contains the following copyright notice: + * + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany + * Copyright 1993 by David Wexelblat <dwex@goblin.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Thomas Roell and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Thomas Roell and + * David Wexelblat makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT BE LIABLE FOR + * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include "Pci.h" + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +/* + * Map an I/O region given its address (host POV) + */ +void * +pmax_iomap(unsigned long base, unsigned long len) +{ + int fd; + void *rv; + + if ((fd = open("/dev/iomem", O_RDWR)) < 0) + { + ErrorF("pmax_iomap: failed to open /dev/iomem (%s)\n", + strerror(errno)); + return(MAP_FAILED); + } + + rv = (void *)mmap((caddr_t)0, len, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, (off_t)base); + + close(fd); + return(rv); +} + +Bool +xf86LinearVidMem() +{ + return TRUE; +} + +extern void * pmax_iomap(unsigned long, unsigned long); + +pointer +xf86MapVidMem(int ScreenNum, int Region, pointer Base, unsigned long Size) +{ + ErrorF("%s: Not supported on this OS. Drivers should use xf86MapPciMem() instead\n", + "xf86MapVidMem"); + FatalError("%s: Cannot map [s=%x,a=%x]\n", "xf86MapVidMem", Size, Base); +} + + +pointer +xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, pointer Base, + unsigned long Size) +{ + pointer hostbase = pciBusAddrToHostAddr(Tag, Base); + pointer base; + + base = (pointer) pmax_iomap((unsigned long)hostbase, Size); + if (base == MAP_FAILED) { + xf86Msg(X_WARNING, + "xf86MapPciMem: Could not mmap PCI memory " + "[base=0x%x,hostbase=0x%x,size=%x] (%s)\n", + Base, hostbase, Size, strerror(errno)); + } + return((pointer)base); +} + + +/* ARGSUSED */ +void +xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + munmap(Base, Size); +} + +/* + * Read BIOS via mmap()ing /dev/iomem. + */ +/*ARGSUSED*/ +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, int Len) +{ + ErrorF("%s: Not supported on this OS. Drivers should use xf86ReadPciBIOS() instead\n", + "xf86ReadBIOS"); + FatalError("%s: Cannot read BIOS [base=0x%x,offset=0x%x,size=%d]\n", "xf86ReadBIOS", Base, Offset, Len); +} + +int +xf86ReadPciBIOS(unsigned long Base, unsigned long Offset, PCITAG Tag, + unsigned char *Buf, int Len) +{ + pointer hostbase = pciBusAddrToHostAddr(Tag, (void *)Base); + char *base; + int psize; + int mlen; + + psize = xf86getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); + base = pmax_iomap((unsigned long)hostbase, mlen); + if (base == MAP_FAILED) { + xf86Msg(X_WARNING, "xf86ReadPciBIOS: Could not mmap PCI memory" + " [base=0x%x,hostbase=0x%x,size=%x] (%s)\n", + Base, hostbase, mlen, strerror(errno)); + return(0); + } + + (void)memcpy(Buf, base + Offset, Len); + (void)munmap(base, mlen); + return(Len); +} + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +#include <sys/ipl.h> + +#ifndef PL_HI +#define PL_HI PL8 +#endif + +#ifndef PL_0 +#define PL_0 PL0 +#endif + +static void *spl_map_addr = NULL; + +void +pmax_init_splmap(void) +{ + spl_map_addr = spl_map(0); + if (!spl_map_addr) { + xf86Msg(X_WARNING, + "pmax_init_splmap: spl_map() failed. " + "Cannot bind to IPL register\n"); + xf86ErrorF("\tInterrupts cannot be disabled/enabled !!!\n"); + } +} + + +Bool +xf86DisableInterrupts() +{ + if (spl_map_addr) { + (void)spl_request(PL_HI,spl_map_addr); + return(TRUE); + } + + return(FALSE); +} + +void xf86EnableInterrupts() +{ + if (spl_map_addr) { + (void)spl_request(PL_0, spl_map_addr); + } +} + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c new file mode 100644 index 000000000..1568598c4 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c @@ -0,0 +1,60 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c,v 1.2 1999/09/04 13:04:46 dawes Exp $ */ + +/* + * Copyright 1999 by The XFree86 Project, Inc. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include "xf86.h" +#include "xf86Xinput.h" +#include "xf86OSmouse.h" +#include "xqueue.h" + +static int +SupportedInterfaces(void) +{ + /* XXX Need to check this. */ + return MSE_SERIAL | MSE_AUTO; +} + +static const char *internalNames[] = { + "Xqueue", + NULL +}; + +static const char ** +BuiltinNames(void) +{ + return internalNames; +} + +static Bool +CheckProtocol(const char *protocol) +{ + int i; + + for (i = 0; internalNames[i]; i++) + if (xf86NameCmp(protocol, internalNames[i]) == 0) + return TRUE; + return FALSE; +} + +OSMouseInfoPtr +xf86OSMouseInit(int flags) +{ + OSMouseInfoPtr p; + + p = xcalloc(sizeof(OSMouseInfoRec), 1); + if (!p) + return NULL; + p->SupportedInterfaces = SupportedInterfaces; + p->BuiltinNames = BuiltinNames; + p->CheckProtocol = CheckProtocol; + p->PreInit = XqueueMousePreInit; + return p; +} + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c new file mode 100644 index 000000000..21f20dff8 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c @@ -0,0 +1,1072 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c,v 1.6 2002/07/24 19:06:53 tsi Exp $ */ +/* + * Copyright 1998 by Concurrent Computer Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Concurrent Computer + * Corporation not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Concurrent Computer Corporation makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Copyright 1998 by Metro Link Incorporated + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Metro Link + * Incorporated not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Metro Link Incorporated makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <stdio.h> +#include "os.h" +#include "compiler.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "Pci.h" + +#include <sys/prosrfs.h> +#include <sys/cpu.h> + +/* + * Night Hawk 6400/6408 platform support + */ +#undef NH640X_PCI_MFDEV_SUPPORT +#undef NH640X_PCI_BRIDGE_SUPPORT + +static void nh640xPciInit(void); +static PCITAG nh640xPciFindNext(void); +static PCITAG nh640xPciFindFirst(void); +static CARD32 nh6400PciReadLong(PCITAG tag, int offset); +static void nh6400PciWriteLong(PCITAG tag, int offset, CARD32 val); +static ADDRESS nh6400BusToHostAddr(PCITAG tag, ADDRESS addr); +static ADDRESS nh6400HostToBusAddr(PCITAG tag, ADDRESS addr); +static CARD32 nh6408PciReadLong(PCITAG tag, int offset); +static void nh6408PciWriteLong(PCITAG tag, int offset, CARD32 val); +static ADDRESS nh6408BusToHostAddr(PCITAG tag, ADDRESS addr); +static ADDRESS nh6408HostToBusAddr(PCITAG tag, ADDRESS addr); + +static pciBusFuncs_t nh6400_pci_funcs = { + nh6400PciReadLong, + nh6400PciWriteLong, + nh6400HostToBusAddr, + nh6400BusToHostAddr +}; + +static pciBusFuncs_t nh6408_pci_funcs = { + nh6408PciReadLong, + nh6408PciWriteLong, + nh6408HostToBusAddr, + nh6408BusToHostAddr +}; + +/* + * NH640x CFG address and data register offsets from base + */ +#define NH6400_PCI_CFG_ADDR_REG_OFF 0 +#define NH6400_PCI_CFG_TYPE0_DATA_REG_OFF 0x40 +#define NH6400_PCI_CFG_TYPE1_DATA_REG_OFF 0x80 + +#define NH6408_PCI_CFG_ADDR_REG_OFF 0 +#define NH6408_PCI_CFG_DATA_REG_OFF 0x10000 + +/* + * Possible cfg addr values for NH640x GMEM PMC ports + */ +static unsigned long nh6400_pmc_cfgaddrs[] = { + PCI_CFGMECH1_TYPE0_CFGADDR(0,0,0) +}; + +/* + * Possible cfg addr values for devices on a secondary bus + * (e.g. behind DEC 21152 PCI-to-PCI bridge) + */ +static unsigned long dec_cfgaddrs[] = { + PCI_CFGMECH1_TYPE1_CFGADDR(1,0,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,1,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,2,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,3,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,4,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,5,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,6,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,7,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,8,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,9,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,10,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,11,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,12,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,13,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,14,0,0), + PCI_CFGMECH1_TYPE1_CFGADDR(1,15,0,0) +}; + +/* + * Data structure holding information about various nh640x PCI buses + */ +struct nh640x_pci_info { + int busnum; + int type; + unsigned long num_cfg_addrs; + unsigned long *cfg_addrs; + int primary_bus; + unsigned long cfgPhysBase; + unsigned long memBase; + unsigned long ioBase; + unsigned long ioSize; + unsigned char *cfgAddrReg; /* After mapping */ +}; + +/* Type */ +#define PRIMARY_PCI 0 +#define SECONDARY_PCI 1 + +static struct nh640x_pci_info nh6400_pci_info[] = { +/* pci4 */ { 4, PRIMARY_PCI, 1, nh6400_pmc_cfgaddrs, 0, 0xa0000000, 0xa1000000, 0, 0xa2000000 }, +/* pci12 */ { 12, SECONDARY_PCI, 16, dec_cfgaddrs, 4 }, +#if 0 +/* pci5 */ { 5, PRIMARY_PCI, 1, nh6400_pmc_cfgaddrs, 0, 0xb0000000, 0xb1000000, 0, 0xb2000000 }, +/* pci13 */ { 13, SECONDARY_PCI, 16, dec_cfgaddrs, 5 }, +#endif +}; + +#define NH6400_NUM_PCI_EXPANSION_BUSES (sizeof(nh6400_pci_info)/sizeof(struct nh640x_pci_info)) + +static struct nh640x_pci_info nh6408_pci_info[] = { +/* pci8 */ { 8, PRIMARY_PCI, 1, nh6400_pmc_cfgaddrs, 0, 0x98040000, 0x9a800000, 65536, 0xa0000000 }, +/* pci12 */ { 12, SECONDARY_PCI, 16, dec_cfgaddrs, 8, }, +#if 0 +/* pci9 */ { 9, PRIMARY_PCI, 1, nh6400_pmc_cfgaddrs, 0, 0x99040000, 0x9b800000, 65536, 0xb0000000 }, +/* pci13 */ { 13, SECONDARY_PCI, 16, dec_cfgaddrs, 9, }, +#endif +}; + +#define NH6408_NUM_PCI_EXPANSION_BUSES (sizeof(nh6408_pci_info)/sizeof(struct nh640x_pci_info)) + +extern unsigned long pmax_sys_type; + +#define MOTOPPC_IO_BASE 0x80000000L /* Start of PCI/ISA I/O region */ + +extern void * pmax_iomap(unsigned long, unsigned long); +extern unsigned long ioSize; +extern volatile unsigned char *ioBase; + +void +pmaxPciInit(void) +{ + extern void motoppcPciInit(void); + extern void nh640xPciInit(void); + extern void nh6800tPciInit(void); + + extern unsigned long motoPciMemBase; + extern unsigned long motoPciMemLen; + extern unsigned long motoPciMemBaseCPU; + + /* + * Determine type of machine + */ + switch(pmax_sys_type) { + case MODEL_NH6400: + case MODEL_NH6408: + nh640xPciInit(); + break; + + case MODEL_NH6800T: + nh6800tPciInit(); + break; + + case MODEL_PH620: + case MODEL_PH640: + case MODEL_MMTX: + motoPciMemBase = 0; + motoPciMemLen = 0x20000000; + motoPciMemBaseCPU = 0xa0000000; + /*FALLTHROUGH*/ + + case MODEL_MPWR: + case MODEL_PH610: + case MODEL_MPWR2: + motoppcPciInit(); + break; + + default: + FatalError("pmaxPciInit: Unsupported machine type\n"); + break; + } +} + +void +ppcPciIoMap(int pcibus) +{ + int primary_bus; + + if (ioBase != MAP_FAILED) + munmap((void*)ioBase,ioSize); + + if (!pciBusInfo[pcibus]) + return; + + primary_bus = pciBusInfo[pcibus]->primary_bus; + + if (!pciBusInfo[primary_bus]) + return; + + ioSize = min(pciBusInfo[primary_bus]->ppc_io_size, 64 * 1024); + if (ioSize) { + ioBase = (unsigned char *)pmax_iomap(pciBusInfo[primary_bus]->ppc_io_base, ioSize); + if (ioBase == MAP_FAILED) + ioSize = 0; + } +} + +static void +nh640xPciInit(void) +{ + int i,n; + struct nh640x_pci_info *infop; + pciBusFuncs_p functions; + + switch (pmax_sys_type) { + case MODEL_NH6400: + n = NH6400_NUM_PCI_EXPANSION_BUSES; + infop = nh6400_pci_info; + functions = &nh6400_pci_funcs; + break; + case MODEL_NH6408: + n = NH6408_NUM_PCI_EXPANSION_BUSES; + infop = nh6408_pci_info; + functions = &nh6408_pci_funcs; + break; + default: + FatalError("Unknown Power MAXION system type\n"); + /*NOTREACHED*/ + } + + /* + * Initialize entries in pciBusInfo[] table for each defined PCI bus. + * This table is actually sparse because undefined or inaccessible + * pci buses are left as NULL entries. Of course, pciFindNext() is + * aware of this convention, and will skip the undefined buses. + */ + for (i=0; i<n; infop++,i++) { + int bus = infop->busnum; + pciBusInfo_t *busp; + + if (pciBusInfo[bus]) + busp = pciBusInfo[bus]; + else + busp = xalloc(sizeof(pciBusInfo_t)); + + if (!busp) + FatalError("nh640xPciInit: xalloc failed\n"); + + /* Initialize pci bus info */ + busp->configMech = PCI_CFG_MECH_OTHER; + busp->numDevices = infop->num_cfg_addrs; + busp->secondary = (infop->type == SECONDARY_PCI ? TRUE : FALSE); + busp->primary_bus = infop->primary_bus; + busp->funcs = functions; + busp->pciBusPriv = infop; + + /* Initialize I/O base/size info */ + if (busp->secondary) { + pciBusInfo_t *pri_busp = pciBusInfo[busp->primary_bus]; + if (pri_busp) { + busp->ppc_io_base = pri_busp->ppc_io_base; + busp->ppc_io_size = pri_busp->ppc_io_size; + } + } + else if (infop->ioSize) { + busp->ppc_io_size = infop->ioSize; + busp->ppc_io_base = infop->ioBase; + } + + pciBusInfo[bus] = busp; + + /* + * Adjust pciNumBuses to reflect the highest defined entry in pciBusInfo + */ + if (pciNumBuses < bus) + pciNumBuses = bus + 1; + } + + pciFindFirstFP = nh640xPciFindFirst; + pciFindNextFP = nh640xPciFindNext; +} + +static PCITAG +nh640xPciFindNext(void) +{ + unsigned long devid, tmp; + unsigned char base_class, sub_class, sec_bus, pri_bus; + + for (;;) { + + if (pciBusNum == -1) { + /* + * Start at top of the order + */ + pciBusNum = 0; + pciFuncNum = 0; + pciDevNum = 0; + } + else { +#ifdef NH640X_PCI_MFDEV_SUPPORT + /* + * Somewhere in middle of order. Determine who's + * next up + */ + if (pciFuncNum == 0) { + /* + * Is current dev a multifunction device? + */ + if (pciMfDev(pciBusNum, pciDevNum)) + /* Probe for other functions */ + pciFuncNum = 1; + else + /* No more functions this device. Next device please */ + pciDevNum ++; + } + else if (++pciFuncNum >= 8) { + /* No more functions for this device. Next device please */ + pciFuncNum = 0; + pciDevNum ++; + } +#else /* NH640X_PCI_MFDEV_SUPPORT */ + pciDevNum++; +#endif /* NH640X_PCI_MFDEV_SUPPORT */ + + if (!pciBusInfo[pciBusNum] || pciDevNum >= pciBusInfo[pciBusNum]->numDevices) { + /* + * No more devices for this bus. Next bus please + */ + if (++pciBusNum >= pciNumBuses) + /* No more buses. All done for now */ + return(PCI_NOT_FOUND); + + pciDevNum = 0; + } + } + + if (!pciBusInfo[pciBusNum]) + continue; /* Undefined bus, next bus/device please */ + + /* + * At this point, pciBusNum, pciDevNum, and pciFuncNum have been + * advanced to the next device. Compute the tag, and read the + * device/vendor ID field. + */ + pciDeviceTag = PCI_MAKE_TAG(pciBusNum, pciDevNum, pciFuncNum); + devid = pciReadLong(pciDeviceTag, 0); + if (devid == 0xffffffff) + continue; /* Nobody home. Next device please */ + +#ifdef NH640X_PCI_BRIDGE_SUPPORT + /* + * Before checking for a specific devid, look for enabled + * PCI to PCI bridge devices. If one is found, create and + * initialize a bus info record (if one does not already exist). + */ + tmp = pciReadLong(pciDeviceTag, PCI_CLASS_CODE_REG); + base_class = PCI_EXTRACT_BASE_CLASS(tmp); + sub_class = PCI_EXTRACT_SUBCLASS(tmp); + if (base_class == PCI_CLASS_BRIDGE && sub_class == PCI_SUBCLASS_BRIDGE_PCI) { + tmp = pciReadLong(pciDeviceTag, PCI_BRIDGE_BUS_REG); + sec_bus = PCI_SECONDARY_BUS_EXTRACT(tmp); + pri_bus = PCI_PRIMARY_BUS_EXTRACT(tmp); + if (sec_bus > 0 && sec_bus < PCI_MAX_BUSES && pcibusInfo[pri_bus]) { + /* + * Found a secondary PCI bus + */ + if (!pciBusInfo[sec_bus]) { + pciBusInfo[sec_bus] = xalloc(sizeof(pciBusInfo_t)); + + if (!pciBusInfo[sec_bus]) + FatalError("nh640xPciFindNext: alloc failed\n!!!"); + } + + /* Copy parents settings... */ + *pciBusInfo[sec_bus] = *pcibusInfo[pri_bus]; + + /* ...but not everything same as parent */ + pciBusInfo[sec_bus]->primary_bus = pri_bus; + pciBusInfo[sec_bus]->secondary = TRUE; + pciBusInfo[sec_bus]->numDevices = 32; + + if (pciNumBuses < sec_num) + pciNumBuses = sec_num+1; + } + } +#endif /* NH640X_PCI_BRIDGE_SUPPORT */ + + /* + * Does this device match the requested devid after + * applying mask? + */ + if ((devid & pciDevidMask) == pciDevid) { + /* Yes - Return it. Otherwise, next device */ + + /* However, before returning it, try to map */ + /* I/O region for this PCI bus */ + ppcPciIoMap(PCI_BUS_FROM_TAG(pciDeviceTag)); + + return(pciDeviceTag); /* got a match */ + } + + } /* for */ + + /*NOTREACHED*/ +} + +static PCITAG +nh640xPciFindFirst(void) +{ + pciBusNum = -1; + return(nh640xPciFindNext()); +} + +static unsigned long +nh6400PciReadLong(PCITAG tag, int offset) +{ + unsigned long tmp; + char *base; + int devnum, bus, func, data_reg_offset, ndevs; + unsigned long cfgaddr; + pciBusInfo_t *busp, *pri_busp; + struct nh640x_pci_info *infop, *pri_infop; + + bus = PCI_BUS_FROM_TAG(tag); + devnum = PCI_DEV_FROM_TAG(tag); + func = PCI_FUNC_FROM_TAG(tag); + + xf86MsgVerb(3, X_INFO, + "nh6400PciReadLong: bus=%d, devnum=%d, func=%d, offset=0x%x\n", + bus, devnum, func, offset); + + if (bus >= pciNumBuses || !pciBusInfo[bus]) { + xf86Msg(X_WARNING, "nh6400PciReadLong: bus pci%d not defined!!!\n", + bus); + return(0xffffffff); + } + + busp = pciBusInfo[bus]; + infop = (struct nh640x_pci_info *)busp->pciBusPriv; + + if (busp->secondary) { + /* + * Secondary PCI bus behind a pci-to-pci bridge + */ + pri_busp = pciBusInfo[busp->primary_bus]; + pri_infop = (struct nh640x_pci_info *)pri_busp->pciBusPriv; + ndevs = 16; + data_reg_offset = NH6400_PCI_CFG_TYPE1_DATA_REG_OFF; /* For Type 1 cfg cycles */ + + if (!pri_busp) { + xf86Msg(X_WARNING, + "nh6400PciReadLong: pci%d's primary parent [pci%d] " + "is not defined!!!\n", bus, busp->primary_bus); + return(0xffffffff); + } + } + else { + pri_busp = busp; + pri_infop = infop; + ndevs = infop->num_cfg_addrs; + data_reg_offset = NH6400_PCI_CFG_TYPE0_DATA_REG_OFF; /* For Type 0 cfg cycles */ + } + + if (devnum >= ndevs) { + xf86Msg(X_WARNING, + "nh6400PciReadLong: devnum %d out of range for bus pci%d\n", + devnum, bus); + return(0xffffffff); + } + + /* + * Make sure the cfg address and data registers for this bus are mapped + * Secondary buses just use the primary parents addreses + */ + if (!infop->cfgAddrReg) { + if (!pri_infop->cfgAddrReg) { + pri_infop->cfgAddrReg = pmax_iomap(pri_infop->cfgPhysBase, 0x1000); + if (pri_infop->cfgAddrReg == MAP_FAILED) { + FatalError("nh6400PciReadLong: Cannot map PCI cfg regs @ 0x%08x\n", + pri_infop->cfgPhysBase); + /*NOTREACHED*/ + } + } + infop->cfgAddrReg = pri_infop->cfgAddrReg; + infop->cfgPhysBase = pri_infop->cfgPhysBase; + } + base = infop->cfgAddrReg; + + if (busp->secondary) { + /* cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(bus,devnum,func,offset); */ + cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(1,devnum,func,offset); /* Must use bus=1 for now - glb */ + } + else { + cfgaddr = infop->cfg_addrs[devnum] + offset; + } + + xf86MsgVerb(X_INFO, 3, + "nh6400PciReadLong: Writing cfgaddr=0x%x to 0x%x (phys=0x%x)\n", + cfgaddr, base, infop->cfgPhysBase); + + /* There may not be any OS interaction while interrupts are disabled */ + xf86DisableInterrupts(); + + *((unsigned long *)(base)) = pciByteSwap(cfgaddr); /* Set cfg address */ + eieio(); + + if (!badaddr(base + data_reg_offset, 4, 0)) { + tmp = *((unsigned long *)(base + data_reg_offset)); + eieio(); + } + + xf86EnableInterrupts(); + + xf86MsgVerb(X_INFO, 3, "nh6400PciReadLong: Read value=0x%x from 0x%x (phys=0x%x)\n", + pciByteSwap(tmp), base + data_reg_offset, infop->cfgPhysBase + data_reg_offset); + + return(pciByteSwap(tmp)); +} + +static void +nh6400PciWriteLong(PCITAG tag, int offset, unsigned long val) +{ + char *base; + int devnum, bus, func, data_reg_offset, ndevs; + unsigned long cfgaddr; + pciBusInfo_t *busp, *pri_busp; + struct nh640x_pci_info *infop, *pri_infop; + + bus = PCI_BUS_FROM_TAG(tag); + devnum = PCI_DEV_FROM_TAG(tag); + func = PCI_FUNC_FROM_TAG(tag); + + xf86MsgVerb(X_INFO, 3, + "nh6400PciWriteLong: bus=%d, devnum=%d, func=%d, offset=0x%x, " + val=0x%x\n", bus, devnum, func, offset, val); + + if (bus >= pciNumBuses || !pciBusInfo[bus]) { + xf86Msg(X_WARNING, "nh6400PciWriteLong: bus pci%d not defined!!!\n", + bus); + return; + } + busp = pciBusInfo[bus]; + infop = (struct nh640x_pci_info *)busp->pciBusPriv; + + if (busp->secondary) { + /* + * Secondary PCI bus behind a pci-to-pci bridge + */ + pri_busp = pciBusInfo[busp->primary_bus]; + pri_infop = (struct nh640x_pci_info *)pri_busp->pciBusPriv; + ndevs = 16; + data_reg_offset = NH6400_PCI_CFG_TYPE1_DATA_REG_OFF; /* For Type 1 cfg cycles */ + + if (!pri_busp) { + xf86Msg(X_WARNING, + "nh6400PciWriteLong: pci%d's primary parent [pci%d]" + " is not defined!!!\n", bus, busp->primary_bus); + return; + } + } + else { + pri_busp = busp; + pri_infop = infop; + ndevs = infop->num_cfg_addrs; + data_reg_offset = NH6400_PCI_CFG_TYPE0_DATA_REG_OFF; /* For Type 0 cfg cycles */ + } + + if (devnum >= ndevs) { + xf86Msg(X_WARNING, + "nh6400PciWriteLong: devnum %d out of range for bus pci%d\n", + devnum, bus); + return; + } + + /* + * Make sure the cfg address and data registers for this bus are mapped + * Secondary buses just use the primary parents addreses + */ + if (!infop->cfgAddrReg) { + if (!pri_infop->cfgAddrReg) { + pri_infop->cfgAddrReg = pmax_iomap(pri_infop->cfgPhysBase, 0x1000); + if (pri_infop->cfgAddrReg == MAP_FAILED) { + FatalError("nh6400PciWriteLong: Cannot map PCI cfg regs @ 0x%08x\n", + pri_infop->cfgPhysBase); + /*NOTREACHED*/ + } + } + infop->cfgAddrReg = pri_infop->cfgAddrReg; + infop->cfgPhysBase = pri_infop->cfgPhysBase; + } + base = infop->cfgAddrReg; + + if (busp->secondary) { + /* cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(bus,devnum,func,offset); */ + cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(1,devnum,func,offset); /* Must use bus=1 for now - glb */ + } + else { + cfgaddr = infop->cfg_addrs[devnum] + offset; + } + + xf86MsgVerb(X_INFO, 3, + "nh6400PciWriteLong: Writing cfgaddr=0x%x to 0x%x (phys=0x%x)\n", + cfgaddr, base, infop->cfgPhysBase); + + /* There may not be any OS interaction while interrupts are disabled */ + xf86DisableInterrupts(); + + *((unsigned long *)(base)) = pciByteSwap(cfgaddr); /* Set cfg address */ + eieio(); + + *((unsigned long *)(base + data_reg_offset)) = pciByteSwap(val); + eieio(); + + xf86EnableInterrupts(); + + xf86MsgVerb(X_INFO, 3, + "nh6400PciWriteLong: Wrote value=0x%x to 0x%x (phys=0x%x)\n", + val, base + data_reg_offset, + infop->cfgPhysBase + data_reg_offset); +} + +/* + * These next two functions are for debugging purposes only because + * the nh6400 does not translate passed to/from a PCI domain. However, + * we do do some bounds checking to make sure things are where they + * should be. + */ +static ADDRESS +nh6400BusToHostAddr(PCITAG tag, ADDRESS addr) +{ + unsigned long addr_l = (unsigned long)addr; + int bus = PCI_BUS_FROM_TAG(tag); + struct nh640x_pci_info *infop; + int pri_bus; + unsigned long membase; + + if (!pciBusInfo[bus]) + FatalError("nh6400BusToHostAddr: pci%d not defined!!\n", bus); + + if (pciBusInfo[bus]->secondary) { + pri_bus = pciBusInfo[bus]->primary_bus; + + if (!pciBusInfo[pri_bus]) + FatalError("nh6400BusToHostAddr: Primary bus pci%d not defined!!\n", pri_bus); + } + else + pri_bus = bus; + + infop = (struct nh640x_pci_info *)pciBusInfo[pri_bus]->pciBusPriv; + membase = infop->memBase; + + if (addr_l < 0x80000000) + /* + * NH6400 host memory addresses are 0-0x7fffffff + */ + return(addr); + + else if (addr_l >= membase && addr_l < membase + 0x0e000000) + /* + * NH6400 host can access PCI memory space addresses + * [memBase, memBase+0x0dffffff] + */ + return(addr); + else + /* Other addresses are not valid */ + FatalError("nh6400BusToHostAddr: Bus address 0x%x not visible to NH6400 host\n", + addr_l); + + /*NOTREACHED*/ +} + +static ADDRESS +nh6400HostToBusAddr(PCITAG tag, ADDRESS addr) +{ + unsigned long addr_l = (unsigned long) addr; + int bus = PCI_BUS_FROM_TAG(tag); + struct nh640x_pci_info *infop; + int pri_bus; + unsigned long membase; + + if (!pciBusInfo[bus]) + FatalError("nh6400HostToBusAddr: pci%d not defined!!\n", bus); + + if (pciBusInfo[bus]->secondary) { + pri_bus = pciBusInfo[bus]->primary_bus; + + if (!pciBusInfo[pri_bus]) + FatalError("nh6400HostToBusAddr: Primary bus pci%d not defined!!\n", pri_bus); + } + else + pri_bus = bus; + + infop = (struct nh640x_pci_info *)pciBusInfo[pri_bus]->pciBusPriv; + membase = infop->memBase; + + if (addr_l < 0x80000000) + /* + * NH6400 host memory addresses are 0-0x7fffffff + */ + return(addr); + + else if (addr_l >= membase && addr_l < membase + 0x0e000000) + /* + * NH6400 host can access PCI memory space addresses + * [memBase, memBase+0x0dffffff] + */ + return(addr); + else + /* Other addresses are not valid */ + FatalError("nh6400HostToBusAddr: Bus address 0x%x not visible to NH6400 host\n", + addr_l); + + /*NOTREACHED*/ +} + + +/* + * NH6408 platform support + */ +static unsigned long +nh6408PciReadLong(PCITAG tag, int offset) +{ + unsigned long tmp; + char *base; + int devnum, bus, func, ndevs; + unsigned long cfgaddr; + pciBusInfo_t *busp, *pri_busp; + struct nh640x_pci_info *infop, *pri_infop; + + bus = PCI_BUS_FROM_TAG(tag); + devnum = PCI_DEV_FROM_TAG(tag); + func = PCI_FUNC_FROM_TAG(tag); + + xf86MsgVerb(X_INFO, + "nh6408PciReadLong: bus=%d, devnum=%d, func=%d, offset=0x%x\n", + bus, devnum, func, offset); + + if (bus >= pciNumBuses || !pciBusInfo[bus]) { + xf86Msg(X_WARNING, "nh6408PciReadLong: bus pci%d not defined!!!\n", + bus); + return(0xffffffff); + } + + busp = pciBusInfo[bus]; + infop = (struct nh640x_pci_info *)busp->pciBusPriv; + + if (busp->secondary) { + /* + * Secondary PCI bus behind a pci-to-pci bridge + */ + pri_busp = pciBusInfo[busp->primary_bus]; + pri_infop = (struct nh640x_pci_info *)pri_busp->pciBusPriv; + ndevs = 16; + + if (!pri_busp) { + xf86Msg(X_WARNING, + "nh6408PciReadLong: pci%d's primary parent [pci%d] " + "is not defined!!!\n", bus, busp->primary_bus); + return(0xffffffff); + } + } + else { + pri_busp = busp; + pri_infop = infop; + ndevs = infop->num_cfg_addrs; + } + + if (devnum >= ndevs) { + xf86Msg(X_WARNING + "nh6408PciReadLong: devnum %d out of range for bus pci%d\n", + devnum, bus); + return(0xffffffff); + } + + /* + * Make sure the cfg address and data registers for this bus are mapped + * Secondary buses just use the primary parents addreses + */ + if (!infop->cfgAddrReg) { + if (!pri_infop->cfgAddrReg) { + pri_infop->cfgAddrReg = pmax_iomap(pri_infop->cfgPhysBase, 0x11000); + if (pri_infop->cfgAddrReg == MAP_FAILED) { + FatalError("nh6408PciReadLong: Cannot map PCI cfg regs @ 0x%08x\n", + pri_infop->cfgPhysBase); + /*NOTREACHED*/ + } + } + infop->cfgAddrReg = pri_infop->cfgAddrReg; + infop->cfgPhysBase = pri_infop->cfgPhysBase; + } + base = infop->cfgAddrReg; + + if (busp->secondary) { + /* cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(bus,devnum,func,offset); */ + cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(1,devnum,func,offset); /* Must use bus=1 for now - glb */ + } + else { + cfgaddr = infop->cfg_addrs[devnum] + offset; + } + + xf86MsgVerb(X_INFO, 3, + "nh6408PciReadLong: Writing cfgaddr=0x%x to 0x%x (phys=0x%x)\n", + cfgaddr, base, infop->cfgPhysBase); + + /* There may not be any OS interaction while interrupts are disabled */ + xf86DisableInterrupts(); + + *((unsigned long *)(base)) = pciByteSwap(cfgaddr); /* Set cfg address */ + eieio(); + + if (!badaddr(base + NH6408_PCI_CFG_DATA_REG_OFF, 4, 0)) { + tmp = *((unsigned long *)(base + NH6408_PCI_CFG_DATA_REG_OFF)); + eieio(); + } + + xf86EnableInterrupts(); + + xf86MsgVerb(X_INFO, 3, "nh6408PciReadLong: Read value=0x%x from 0x%x (phys=0x%x)\n", + pciByteSwap(tmp), + base + NH6408_PCI_CFG_DATA_REG_OFF, + infop->cfgPhysBase + NH6408_PCI_CFG_DATA_REG_OFF); + + return(pciByteSwap(tmp)); +} + +static void +nh6408PciWriteLong(PCITAG tag, int offset, unsigned long val) +{ + char *base; + int devnum, bus, func, ndevs; + unsigned long cfgaddr; + pciBusInfo_t *busp, *pri_busp; + struct nh640x_pci_info *infop, *pri_infop; + + bus = PCI_BUS_FROM_TAG(tag); + devnum = PCI_DEV_FROM_TAG(tag); + func = PCI_FUNC_FROM_TAG(tag); + + xf86MsgVerb(X_INFO, + "nh6408PciWriteLong: bus=%d, devnum=%d, func=%d, offset=0x%x, " + "val=0x%x\n", bus, devnum, func, offset, val); + + if (bus >= pciNumBuses || !pciBusInfo[bus]) { + xf86Msg(X_WARNING, "nh6408PciWriteLong: bus pci%d not defined!!!\n", + bus); + return; + } + + busp = pciBusInfo[bus]; + infop = (struct nh640x_pci_info *)busp->pciBusPriv; + + if (busp->secondary) { + /* + * Secondary PCI bus behind a pci-to-pci bridge + */ + pri_busp = pciBusInfo[busp->primary_bus]; + pri_infop = (struct nh640x_pci_info *)pri_busp->pciBusPriv; + ndevs = 16; + + if (!pri_busp) { + xf86Msg(X_WARNING, + "nh6408PciWriteLong: pci%d's primary parent [pci%d] " + is not defined!!!\n", bus, busp->primary_bus); + return; + } + } + else { + pri_busp = busp; + pri_infop = infop; + ndevs = infop->num_cfg_addrs; + } + + if (devnum >= ndevs) { + xf86Msg(X_WARNING, + "nh6408PciWriteLong: devnum %d out of range for bus pci%d\n", + devnum, bus); + return; + } + + /* + * Make sure the cfg address and data registers for this bus are mapped + * Secondary buses just use the primary parents addreses + */ + if (!infop->cfgAddrReg) { + if (!pri_infop->cfgAddrReg) { + pri_infop->cfgAddrReg = pmax_iomap(pri_infop->cfgPhysBase, 0x11000); + if (pri_infop->cfgAddrReg == MAP_FAILED) { + FatalError("nh6408PciWriteLong: Cannot map PCI cfg regs @ 0x%08x\n", + pri_infop->cfgPhysBase); + /*NOTREACHED*/ + } + } + infop->cfgAddrReg = pri_infop->cfgAddrReg; + infop->cfgPhysBase = pri_infop->cfgPhysBase; + } + base = infop->cfgAddrReg; + + if (busp->secondary) { + /* cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(bus,devnum,0,offset); */ + cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(1,devnum,0,offset); + } + else { + cfgaddr = infop->cfg_addrs[devnum] + offset; + } + + xf86MsgVerb(X_INFO, 3, + "nh6408PciWriteLong: Writing cfgaddr=0x%x to 0x%x (phys=0x%x)\n", + cfgaddr, base, infop->cfgPhysBase); + + /* There may not be any OS interaction while interrupts are disabled */ + xf86DisableInterrupts(); + + *((unsigned long *)(base)) = pciByteSwap(cfgaddr); /* Set cfg address */ + eieio(); + + *((unsigned long *)(base + NH6408_PCI_CFG_DATA_REG_OFF)) = pciByteSwap(val); + eieio(); + + xf86EnableInterrupts(); + + xf86MsgVerb(X_INFO, 3, + "nh6408PciWriteLong: Wrote value=0x%x to 0x%x (phys=0x%x)\n", + val, base + NH6408_PCI_CFG_DATA_REG_OFF, + infop->cfgPhysBase + NH6408_PCI_CFG_DATA_REG_OFF); +} + + +static ADDRESS +nh6408BusToHostAddr(PCITAG tag, ADDRESS addr) +{ + unsigned long addr_l = (unsigned long)addr; + int bus = PCI_BUS_FROM_TAG(tag); + int pri_bus; + struct nh640x_pci_info *infop; + unsigned long membase; + + if (!pciBusInfo[bus]) + FatalError("nh6408BusToHostAddr: pci%d not defined!!\n", bus); + + if (pciBusInfo[bus]->secondary) { + pri_bus = pciBusInfo[bus]->primary_bus; + + if (!pciBusInfo[pri_bus]) + FatalError("nh6408BusToHostAddr: Primary bus pci%d not defined!!\n", pri_bus); + } + else + pri_bus = bus; + + infop = (struct nh640x_pci_info *)pciBusInfo[pri_bus]->pciBusPriv; + membase = infop->memBase; + + if (addr_l < 0x10000000) + /* + * NH6408 host sees PCI memory space addresses 0-0x0fffffff + * at the primary PCI buses "memBase" [memBase, memBase+0x0fffffff] + */ + return((ADDRESS)(membase + addr_l)); + + else if (addr_l >= 0x80000000) + /* + * NH6408 host memory addresses 0-0x7fffffff are seen at + * 0x80000000-0xffffffff on PCI + */ + return((ADDRESS)(addr_l & 0x7fffffff)); + + else + /* Other addresses are not valid */ + FatalError("nh6408BusToHostAddr: Bus address 0x%x not visible to NH6408 host\n", + addr_l); + + /*NOTREACHED*/ +} + +static ADDRESS +nh6408HostToBusAddr(PCITAG tag, ADDRESS addr) +{ + unsigned long addr_l = (unsigned long)addr; + int bus = PCI_BUS_FROM_TAG(tag); + int pri_bus; + struct nh640x_pci_info *infop; + unsigned long membase; + + if (!pciBusInfo[bus]) + FatalError("nh6408HostToBusAddr: pci%d not defined!!\n", bus); + + if (pciBusInfo[bus]->secondary) { + pri_bus = pciBusInfo[bus]->primary_bus; + + if (!pciBusInfo[pri_bus]) + FatalError("nh6408HostToBusAddr: Primary bus pci%d not defined!!\n", pri_bus); + } + else + pri_bus = bus; + + infop = (struct nh640x_pci_info *)pciBusInfo[pri_bus]->pciBusPriv; + membase = infop->memBase; + + if (addr_l < 0x80000000) + /* + * NH6408 host memory addresses 0-0x7fffffff are seen at + * 0x80000000-0xffffffff on PCI + */ + return((ADDRESS)(addr_l | 0x80000000)); + + else if (addr_l >= membase && addr_l < (membase + 0x10000000)) + /* + * NH6408 host sees PCI memory space addresses 0-0x0fffffff + * at the primary PCI buses "memBase" [memBase, memBase+0x0fffffff] + */ + return((ADDRESS)(addr_l - membase)); + + else + /* Other addresses are not valid */ + FatalError("nh6408HostToBusAddr: Host address 0x%x not visible to pci%d\n", + addr_l, bus); + + /*NOTREACHED*/ +} + +/* + * NH6800 (Turbo) support + */ +static void +nh6800tPciInit(void) +{ + FatalError("nh6800tPciInit: NH6800TURBO not supported (yet)!!!\n"); +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c new file mode 100644 index 000000000..aa286d4ac --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c @@ -0,0 +1,251 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c,v 1.3 1998/07/25 16:56:56 dawes Exp $ */ +/* + * Copyright 1998 by Concurrent Computer Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Concurrent Computer + * Corporation not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Concurrent Computer Corporation makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Copyright 1998 by Metro Link Incorporated + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Metro Link + * Incorporated not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Metro Link Incorporated makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <sys/types.h> +#include <errno.h> + +#include <sys/prosrfs.h> +#include <sys/cpu.h> + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +volatile unsigned char *ioBase = MAP_FAILED; /* Also referenced by compiler.h */ +unsigned long ioSize = 0; + +#undef outb +#undef outw +#undef outl +#undef inb +#undef inw +#undef inl + +void +outb(unsigned int a, unsigned char b) +{ + if (ioBase == MAP_FAILED) { + ErrorF("outb(0x%04X, 0x%02X) fails. Uninitialized ioBase\n", a, b); + return; + } + + *((volatile unsigned char *)(ioBase + a)) = b; eieio(); +} + +void +outw(unsigned int a, unsigned short w) +{ + if (ioBase == MAP_FAILED) { + ErrorF("outw(0x%04X, 0x%04X) fails. Unitialized ioBase\n", a, w); + return; + } + + stw_brx(w,ioBase,a); eieio(); +} + +void +outl(unsigned int a, unsigned int l) +{ + if (ioBase == MAP_FAILED) { + ErrorF("outl(0x%04X, 0x%08X) fails. Unitialized ioBase\n", a, l); + return; + } + + stl_brx(l,ioBase,a); eieio(); +} + +unsigned char +inb(unsigned int a) +{ + unsigned char b; + + if (ioBase == MAP_FAILED) { + FatalError("%s(0x%04X) fails. Unitialized ioBase\n", "inb", a); + /*NOTREACHED*/ + } + + b = *((volatile unsigned char *)(ioBase + a)); + + return(b); +} + +unsigned short +inw(unsigned int a) +{ + unsigned short w; + + if (ioBase == MAP_FAILED) { + FatalError("%s(0x%04X) fails. Unitialized ioBase\n", "inw", a); + /*NOTREACHED*/ + } + + w = ldw_brx(ioBase,a); + return(w); +} + +unsigned int +inl(unsigned int a) +{ + unsigned int l; + + if (ioBase == MAP_FAILED) { + FatalError("%s(0x%04X) fails. Unitialized ioBase\n", "inl", a); + /*NOTREACHED*/ + } + + l = ldl_brx(ioBase, a); + return(l); +} + +#ifdef PPCIO_DEBUG + +void +debug_outb(unsigned int a, unsigned char b, int line, char *file) +{ + if (xf86Verbose > 3) + ErrorF("outb(0x%04X, 0x%02X) at line %d, file \"%s\"\n", a, b, line, file); + + outb(a,b); +} + +void +debug_outw(unsigned int a, unsigned short w, int line, char *file) +{ + if (xf86Verbose > 3) + ErrorF("outw(0x%04X, 0x%04X) at line %d, file \"%s\"\n", a, w, line, file); + + outw(a,w); +} + +void +debug_outl(unsigned int a, unsigned int l, int line, char *file) +{ + if (xf86Verbose > 3) + ErrorF("outl(0x%04X, 0x%08X) at line %d, file \"%s\"\n", a, l, line, file); + + outl(a,l); +} + + +unsigned char +debug_inb(unsigned int a, int line, char *file) +{ + unsigned char b; + + if (xf86Verbose > 4) + ErrorF("Calling %s(0x%04x) at line %d, file \"%s\" ...\n", "inb", a, line, file); + + b = inb(a); + + if (xf86Verbose > 3) + ErrorF("... %s(0x%04X) returns 0x%02X\n", "inb", a, b); + + return(b); +} + +unsigned short +debug_inw(unsigned int a, int line, char *file) +{ + unsigned short w; + + if (xf86Verbose > 4) + ErrorF("Calling %s(0x%04x) at line %d, file \"%s\" ...\n", "inw", a, line, file); + + w = inw(a); + + if (xf86Verbose > 3) + ErrorF("... %s(0x%04X) returns 0x%04X\n", "inw", a, w); + + return(w); +} + +unsigned int +debug_inl(unsigned int a, int line, char *file) +{ + unsigned int l; + + if (xf86Verbose > 4) + ErrorF("Calling %s(0x%04x) at line %d, file \"%s\" ...\n", "inl", a, line, file); + + l = inl(a); + + if (xf86Verbose > 3) + ErrorF("... %s(0x%04X) returns 0x%08X\n", "inl", a, l); + + return(l); +} + +#endif /* PPCIO_DEBUG */ + +/* + * This is neccessary on the PPC 604 (and 604e) because they have + * separate I and D caches and the caches must be manually synchronized + * when applying relocation to the instruction portion of loaded modules. + */ +#define LINESIZE 32 +#define CACHE_LINE(a) (((unsigned long)a) & ~(LINESIZE-1)) + +void +ppc_flush_icache(char *addr) +{ + /* Flush D-cache to memory */ + __inst_dcbf (addr, 0); + __inst_dcbf (addr, LINESIZE); + __inst_sync (); + + /* Invalidate I-cache */ + __inst_icbi (addr, 0); + __inst_icbi (addr, LINESIZE); + __inst_sync (); + __inst_isync (); +} |